From 36e3247d205f1c8d7ea98dbfae9ef93caea0ade0 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 12 Dec 2013 03:07:35 +0100 Subject: [PATCH 001/146] Based on openssh-6.4p1-3.fc20 --- gsi-openssh.spec | 5 ++++- gsisshd-keygen | 9 +++++---- gsisshd.sysconfig | 8 +++++--- openssh-6.3p1-redhat.patch | 12 ++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d2b1396..ef16f84 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ %global ldap 1 %global openssh_ver 6.4p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -491,6 +491,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Wed Dec 11 2013 Mattias Ellert - 6.4p1-2 +- Based on openssh-6.4p1-3.fc20 + * Tue Nov 26 2013 Mattias Ellert - 6.4p1-1 - Based on openssh-6.4p1-2.fc20 diff --git a/gsisshd-keygen b/gsisshd-keygen index c944449..d8e19f3 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -4,7 +4,7 @@ # # The creation is controlled by the $AUTOCREATE_SERVER_KEYS environment # variable. -AUTOCREATE_SERVER_KEYS=RSAONLY +AUTOCREATE_SERVER_KEYS=NODSA # source function library . /etc/rc.d/init.d/functions @@ -96,7 +96,7 @@ do_ecdsa_keygen() { rm -f $ECDSA_KEY if test ! -f $ECDSA_KEY && $KEYGEN -q -t ecdsa -f $ECDSA_KEY -C '' -N '' >&/dev/null; then chgrp ssh_keys $ECDSA_KEY - chmod 600 $ECDSA_KEY + chmod 640 $ECDSA_KEY chmod 644 $ECDSA_KEY.pub if [ -x /sbin/restorecon ]; then /sbin/restorecon $ECDSA_KEY.pub @@ -115,8 +115,9 @@ do_ecdsa_keygen() { if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then do_rsa_keygen if [ "x${AUTOCREATE_SERVER_KEYS}" != xRSAONLY ]; then - do_rsa1_keygen - do_dsa_keygen do_ecdsa_keygen + if [ "x${AUTOCREATE_SERVER_KEYS}" != xNODSA ]; then + do_dsa_keygen + fi fi fi diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 9a30a83..ddd7744 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -1,9 +1,11 @@ # Configuration file for the sshd service. -# The server keys are automatically generated if they ommited -# to change the automatic creation uncomment the approprite -# line. The default is RSAONLY +# The server keys are automatically generated if they omitted +# to change the automatic creation uncomment the appropriate +# line. The default is NODSA which means rsa and ecdsa keys are +# generated. +# AUTOCREATE_SERVER_KEYS=NODSA # AUTOCREATE_SERVER_KEYS=RSAONLY # AUTOCREATE_SERVER_KEYS=NO # AUTOCREATE_SERVER_KEYS=YES diff --git a/openssh-6.3p1-redhat.patch b/openssh-6.3p1-redhat.patch index 5b1ec1d..d85244d 100644 --- a/openssh-6.3p1-redhat.patch +++ b/openssh-6.3p1-redhat.patch @@ -58,6 +58,18 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 +@@ -21,9 +25,9 @@ + # HostKey for protocol version 1 + #HostKey /etc/ssh/ssh_host_key + # HostKeys for protocol version 2 +-#HostKey /etc/ssh/ssh_host_rsa_key ++HostKey /etc/ssh/ssh_host_rsa_key + #HostKey /etc/ssh/ssh_host_dsa_key +-#HostKey /etc/ssh/ssh_host_ecdsa_key ++HostKey /etc/ssh/ssh_host_ecdsa_key + + # Lifetime and size of ephemeral version 1 server key + #KeyRegenerationInterval 1h @@ -35,6 +39,7 @@ # Logging # obsoletes QuietMode and FascistLogging From 08237287277e85da2dca7c4c2a7b904eef8f52f6 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Sat, 7 Jun 2014 13:51:35 -0500 Subject: [PATCH 002/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ef16f84..dde3923 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -34,7 +34,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -491,6 +491,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Sat Jun 07 2014 Fedora Release Engineering - 6.4p1-2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + * Wed Dec 11 2013 Mattias Ellert - 6.4p1-2 - Based on openssh-6.4p1-3.fc20 From a60f428d3d3da6791ccba09a671ab84dfc69fab4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 10 Jul 2014 20:14:43 +0200 Subject: [PATCH 003/146] Based on openssh-6.4p1-4.fc20 --- gsi-openssh.spec | 28 ++- gsisshd-keygen.service | 2 +- openssh-6.1p1-log-usepam-no.patch | 2 +- openssh-6.3p1-fips.patch | 32 ++-- openssh-6.3p1-gsskex.patch | 2 +- openssh-6.3p1-redhat.patch | 2 +- openssh-6.4p1-CLOCK_BOOTTIME.patch | 29 ++++ openssh-6.4p1-CVE-2014-2653.patch | 80 +++++++++ openssh-6.4p1-FIPS-mode-SP800-131A.patch | 206 +++++++++++++++++++++++ openssh-6.4p1-fromto-remote.patch | 16 ++ openssh-6.4p1-gsissh.patch | 4 +- openssh-6.4p1-ignore-bad-env-var.patch | 37 ++++ openssh-6.4p1-legacy-ssh-copy-id.patch | 57 +++++++ 13 files changed, 474 insertions(+), 23 deletions(-) create mode 100644 openssh-6.4p1-CLOCK_BOOTTIME.patch create mode 100644 openssh-6.4p1-CVE-2014-2653.patch create mode 100644 openssh-6.4p1-FIPS-mode-SP800-131A.patch create mode 100644 openssh-6.4p1-fromto-remote.patch create mode 100644 openssh-6.4p1-ignore-bad-env-var.patch create mode 100644 openssh-6.4p1-legacy-ssh-copy-id.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index dde3923..b2247a7 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,12 +29,12 @@ %global ldap 1 %global openssh_ver 6.4p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -129,6 +129,19 @@ Patch901: openssh-6.3p1-kuserok.patch Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch # increase the size of the Diffie-Hellman groups (#1010607) Patch903: openssh-6.3p1-increase-size-of-DF-groups.patch +# FIPS mode - adjust the key echange DH groups and ssh-keygen according to SP800-131A (#1001748) +Patch904: openssh-6.4p1-FIPS-mode-SP800-131A.patch +# Run ssh-copy-id in the legacy mode when SSH_COPY_ID_LEGACY variable is set (#969375 +Patch905: openssh-6.4p1-legacy-ssh-copy-id.patch +# Use tty allocation for a remote scp (#985650) +Patch906: openssh-6.4p1-fromto-remote.patch +# Try CLOCK_BOOTTIME with fallback (#1091992) +Patch907: openssh-6.4p1-CLOCK_BOOTTIME.patch +# Prevents a server from skipping SSHFP lookup and forcing a new-hostkey +# dialog by offering only certificate keys. (#1081338) +Patch908: openssh-6.4p1-CVE-2014-2653.patch +# ignore environment variables with embedded '=' or '\0' characters (#1077843) +Patch909: openssh-6.4p1-ignore-bad-env-var.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.4p1.patch @@ -278,6 +291,12 @@ This version of OpenSSH has been modified to support GSI authentication. %patch901 -p1 -b .kuserok %patch902 -p1 -b .ccache_name %patch903 -p1 -b .dh +%patch904 -p1 -b .SP800-131A +%patch905 -p1 -b .legacy-ssh-copy-id +%patch906 -p1 -b .fromto-remote +%patch907 -p1 -b .CLOCK_BOOTTIME +%patch908 -p1 -b .CVE-2014-2653 +%patch909 -p1 -b .bad-env-var %patch98 -p1 -b .gsi @@ -449,7 +468,7 @@ getent passwd sshd >/dev/null || \ %defattr(-,root,root) %doc CREDITS ChangeLog INSTALL LICENCE LICENSE.globus_usage OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh -%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli %attr(0755,root,root) %{_bindir}/gsissh-keygen %attr(0644,root,root) %{_mandir}/man1/gsissh-keygen.1* %attr(0755,root,root) %dir %{_libexecdir}/gsissh @@ -491,6 +510,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Thu Jul 10 2014 Mattias Ellert - 6.4p1-3 +- Based on openssh-6.4p1-4.fc20 + * Sat Jun 07 2014 Fedora Release Engineering - 6.4p1-2.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild diff --git a/gsisshd-keygen.service b/gsisshd-keygen.service index 6bd2c4f..5cb78e3 100644 --- a/gsisshd-keygen.service +++ b/gsisshd-keygen.service @@ -1,7 +1,7 @@ [Unit] Description=gsissh Server Key Generation ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key -ConditionPathExists=|!/etc/gsissh/ssh_host_dsa_key +ConditionPathExists=|!/etc/gsissh/ssh_host_ecdsa_key [Service] ExecStart=/usr/sbin/gsisshd-keygen diff --git a/openssh-6.1p1-log-usepam-no.patch b/openssh-6.1p1-log-usepam-no.patch index 4ed52b1..64cec2c 100644 --- a/openssh-6.1p1-log-usepam-no.patch +++ b/openssh-6.1p1-log-usepam-no.patch @@ -15,7 +15,7 @@ diff -up openssh-6.1p1/sshd.c.log-usepam-no openssh-6.1p1/sshd.c diff -up openssh-6.1p1/sshd_config.log-usepam-no openssh-6.1p1/sshd_config --- openssh-6.1p1/sshd_config.log-usepam-no 2012-09-14 20:54:58.514255748 +0200 +++ openssh-6.1p1/sshd_config 2012-09-14 20:54:58.551255954 +0200 -@@ -95,6 +95,8 @@ GSSAPICleanupCredentials yes +@@ -95,6 +95,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'. diff --git a/openssh-6.3p1-fips.patch b/openssh-6.3p1-fips.patch index acf4e82..6a5a332 100644 --- a/openssh-6.3p1-fips.patch +++ b/openssh-6.3p1-fips.patch @@ -527,9 +527,9 @@ diff -up openssh-6.3p1/sshconnect2.c.fips openssh-6.3p1/sshconnect2.c if (options.hostkeyalgorithms != NULL) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = options.hostkeyalgorithms; -diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.fips 2013-10-11 22:24:32.842031223 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-11 22:24:32.873031077 +0200 +diff -up openssh-6.4p1/sshd.c.fips openssh-6.4p1/sshd.c +--- openssh-6.4p1/sshd.c.fips 2014-01-27 16:20:12.751358484 +0100 ++++ openssh-6.4p1/sshd.c 2014-01-27 16:21:12.961052163 +0100 @@ -76,6 +76,8 @@ #include #include @@ -539,22 +539,26 @@ diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c #include "openbsd-compat/openssl-compat.h" #ifdef HAVE_SECUREWARE -@@ -1450,6 +1452,14 @@ main(int ac, char **av) +@@ -1450,6 +1452,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); + SSLeay_add_all_algorithms(); + if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) -+ if (FIPS_mode()) -+ fatal("FIPS integrity verification test failed."); ++ if (! FIPSCHECK_verify(NULL, NULL)) { ++ openlog(__progname, LOG_PID, LOG_AUTHPRIV); ++ if (FIPS_mode()) { ++ syslog(LOG_CRIT, "FIPS integrity verification test failed."); ++ cleanup_exit(255); ++ } + else -+ logit("FIPS integrity verification test failed."); -+ ++ syslog(LOG_INFO, "FIPS integrity verification test failed."); ++ closelog(); ++ } /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1601,8 +1611,6 @@ main(int ac, char **av) +@@ -1601,8 +1615,6 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -563,7 +567,7 @@ diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c /* If requested, redirect the logs to the specified logfile. */ if (logfile != NULL) { log_redirect_stderr_to(logfile); -@@ -1773,6 +1781,10 @@ main(int ac, char **av) +@@ -1773,6 +1785,10 @@ main(int ac, char **av) debug("private host key: #%d type %d %s", i, keytype, key_type(key ? key : pubkey)); } @@ -574,7 +578,7 @@ diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; -@@ -1936,6 +1948,10 @@ main(int ac, char **av) +@@ -1936,6 +1952,10 @@ main(int ac, char **av) /* Initialize the random number generator. */ arc4random_stir(); @@ -585,7 +589,7 @@ diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2498,6 +2514,9 @@ do_ssh2_kex(void) +@@ -2498,6 +2518,9 @@ do_ssh2_kex(void) if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; @@ -595,7 +599,7 @@ diff -up openssh-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c } myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2507,6 +2526,9 @@ do_ssh2_kex(void) +@@ -2507,6 +2530,9 @@ do_ssh2_kex(void) if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; diff --git a/openssh-6.3p1-gsskex.patch b/openssh-6.3p1-gsskex.patch index eefd792..0c54d38 100644 --- a/openssh-6.3p1-gsskex.patch +++ b/openssh-6.3p1-gsskex.patch @@ -2892,7 +2892,7 @@ diff -up openssh-6.3p1/sshd_config.gsskex openssh-6.3p1/sshd_config @@ -92,6 +92,8 @@ ChallengeResponseAuthentication no GSSAPIAuthentication yes #GSSAPICleanupCredentials yes - GSSAPICleanupCredentials yes + GSSAPICleanupCredentials no +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no diff --git a/openssh-6.3p1-redhat.patch b/openssh-6.3p1-redhat.patch index d85244d..98df47d 100644 --- a/openssh-6.3p1-redhat.patch +++ b/openssh-6.3p1-redhat.patch @@ -96,7 +96,7 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config #GSSAPIAuthentication no +GSSAPIAuthentication yes #GSSAPICleanupCredentials yes -+GSSAPICleanupCredentials yes ++GSSAPICleanupCredentials no # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/openssh-6.4p1-CLOCK_BOOTTIME.patch b/openssh-6.4p1-CLOCK_BOOTTIME.patch new file mode 100644 index 0000000..1073a77 --- /dev/null +++ b/openssh-6.4p1-CLOCK_BOOTTIME.patch @@ -0,0 +1,29 @@ +--- a/misc.c ++++ b/misc.c +@@ -865,17 +865,24 @@ ms_to_timeval(struct timeval *tv, int ms + time_t + monotime(void) + { +-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) ++#if defined(HAVE_CLOCK_GETTIME) && \ ++ (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) + struct timespec ts; + static int gettime_failed = 0; + + if (!gettime_failed) { ++#if defined(CLOCK_BOOTTIME) ++ if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) ++ return (ts.tv_sec); ++#endif ++#if defined(CLOCK_MONOTONIC) + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + return (ts.tv_sec); ++#endif + debug3("clock_gettime: %s", strerror(errno)); + gettime_failed = 1; + } +-#endif ++#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ + + return time(NULL); + } diff --git a/openssh-6.4p1-CVE-2014-2653.patch b/openssh-6.4p1-CVE-2014-2653.patch new file mode 100644 index 0000000..27f3fa3 --- /dev/null +++ b/openssh-6.4p1-CVE-2014-2653.patch @@ -0,0 +1,80 @@ +diff --git a/ChangeLog b/ChangeLog +index 29d70ec..a0fb67e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,14 @@ ++20140420 ++ - djm@cvs.openbsd.org 2014/04/01 03:34:10 ++ [sshconnect.c] ++ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any ++ certificate keys to plain keys and attempt SSHFP resolution. ++ ++ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey ++ dialog by offering only certificate keys. ++ ++ Reported by mcv21 AT cam.ac.uk ++ + 20131010 + - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 + [dh.c dh.h] +diff --git a/sshconnect.c b/sshconnect.c +index ddc167e..4d8c718 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -1136,30 +1136,40 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) + { + int flags = 0; + char *fp; ++ Key *plain = NULL; + + fp = key_selected_fingerprint(host_key, SSH_FP_HEX); + debug("Server host key: %s %s%s", key_type(host_key), + key_fingerprint_prefix(), fp); + free(fp); + +- /* XXX certs are not yet supported for DNS */ +- if (!key_is_cert(host_key) && options.verify_host_key_dns && +- verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { +- if (flags & DNS_VERIFY_FOUND) { +- +- if (options.verify_host_key_dns == 1 && +- flags & DNS_VERIFY_MATCH && +- flags & DNS_VERIFY_SECURE) +- return 0; +- +- if (flags & DNS_VERIFY_MATCH) { +- matching_host_key_dns = 1; +- } else { +- warn_changed_key(host_key); +- error("Update the SSHFP RR in DNS with the new " +- "host key to get rid of this message."); ++ if (options.verify_host_key_dns) { ++ /* ++ * XXX certs are not yet supported for DNS, so downgrade ++ * them and try the plain key. ++ */ ++ plain = key_from_private(host_key); ++ if (key_is_cert(plain)) ++ key_drop_cert(plain); ++ if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { ++ if (flags & DNS_VERIFY_FOUND) { ++ if (options.verify_host_key_dns == 1 && ++ flags & DNS_VERIFY_MATCH && ++ flags & DNS_VERIFY_SECURE) { ++ key_free(plain); ++ return 0; ++ } ++ if (flags & DNS_VERIFY_MATCH) { ++ matching_host_key_dns = 1; ++ } else { ++ warn_changed_key(plain); ++ error("Update the SSHFP RR in DNS " ++ "with the new host key to get rid " ++ "of this message."); ++ } + } + } ++ key_free(plain); + } + + return check_host_key(host, hostaddr, options.port, host_key, RDRW, diff --git a/openssh-6.4p1-FIPS-mode-SP800-131A.patch b/openssh-6.4p1-FIPS-mode-SP800-131A.patch new file mode 100644 index 0000000..cf632d8 --- /dev/null +++ b/openssh-6.4p1-FIPS-mode-SP800-131A.patch @@ -0,0 +1,206 @@ +diff --git a/dh.h b/dh.h +index 48f7b68..9ff39f4 100644 +--- a/dh.h ++++ b/dh.h +@@ -45,6 +45,7 @@ int dh_estimate(int); + + /* Min and max values from RFC4419. */ + #define DH_GRP_MIN 1024 ++#define DH_GRP_MIN_FIPS 2048 + #define DH_GRP_MAX 8192 + + /* +diff --git a/kex.c b/kex.c +index a468805..3a0eb16 100644 +--- a/kex.c ++++ b/kex.c +@@ -34,6 +34,7 @@ + #include + + #include ++#include + + #include "xmalloc.h" + #include "ssh2.h" +@@ -93,6 +94,20 @@ static const struct kexalg kexalgs[] = { + { NULL, -1, -1, NULL}, + }; + ++static const struct kexalg kexalgs_fips[] = { ++ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 }, ++ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 }, ++#ifdef HAVE_EVP_SHA256 ++ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 }, ++#endif ++#ifdef OPENSSL_HAS_ECC ++ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 }, ++ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, ++ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, ++#endif ++ { NULL, -1, -1, NULL}, ++}; ++ + char * + kex_alg_list(void) + { +@@ -116,7 +131,7 @@ kex_alg_by_name(const char *name) + { + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { + if (strcmp(k->name, name) == 0) + return k; + #ifdef GSSAPI +@@ -141,7 +156,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/kexecdhc.c b/kexecdhc.c +index 6193836..d435f1f 100644 +--- a/kexecdhc.c ++++ b/kexecdhc.c +@@ -154,6 +154,7 @@ kexecdh_client(Kex *kex) + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); ++ memset(hash, 0, hashlen); + kex_finish(kex); + } + #else /* OPENSSL_HAS_ECC */ +diff --git a/kexecdhs.c b/kexecdhs.c +index 3a580aa..9a06905 100644 +--- a/kexecdhs.c ++++ b/kexecdhs.c +@@ -155,6 +155,7 @@ kexecdh_server(Kex *kex) + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); ++ memset(hash, 0, hashlen); + kex_finish(kex); + } + #else /* OPENSSL_HAS_ECC */ +diff --git a/kexgexc.c b/kexgexc.c +index 5a3be20..a931b6e 100644 +--- a/kexgexc.c ++++ b/kexgexc.c +@@ -26,6 +26,8 @@ + + #include "includes.h" + ++#include ++ + #include + + #include +@@ -64,13 +66,13 @@ kexgex_client(Kex *kex) + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); +- min = DH_GRP_MIN; ++ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + max = DH_GRP_MAX; + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); + } else { + /* New GEX request */ +- min = DH_GRP_MIN; ++ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); +diff --git a/kexgexs.c b/kexgexs.c +index 4e473fc..2ed49bd 100644 +--- a/kexgexs.c ++++ b/kexgexs.c +@@ -76,16 +76,16 @@ kexgex_server(Kex *kex) + omin = min = packet_get_int(); + onbits = nbits = packet_get_int(); + omax = max = packet_get_int(); +- min = MAX(DH_GRP_MIN, min); ++ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); +- nbits = MAX(DH_GRP_MIN, nbits); ++ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); + break; + case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); + onbits = nbits = packet_get_int(); + /* unused for old GEX */ +- omin = min = DH_GRP_MIN; ++ omin = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + omax = max = DH_GRP_MAX; + break; + default: +diff --git a/myproposal.h b/myproposal.h +index ee69ea2..1b68c5b 100644 +--- a/myproposal.h ++++ b/myproposal.h +@@ -72,6 +72,12 @@ + "diffie-hellman-group14-sha1," \ + "diffie-hellman-group1-sha1" + ++#define KEX_DEFAULT_KEX_FIPS \ ++ KEX_ECDH_METHODS \ ++ KEX_SHA256_METHODS \ ++ "diffie-hellman-group-exchange-sha1," \ ++ "diffie-hellman-group14-sha1" ++ + #define KEX_DEFAULT_PK_ALG \ + HOSTKEY_ECDSA_CERT_METHODS \ + "ssh-rsa-cert-v01@openssh.com," \ +diff --git a/ssh-keygen.c b/ssh-keygen.c +index cac6762..2569016 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -183,8 +183,14 @@ type_bits_valid(int type, u_int32_t *bitsp) + fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); + exit(1); + } +- if (type == KEY_DSA && *bitsp != 1024) ++ if (type == KEY_DSA && FIPS_mode()) ++ fatal("DSA keys are not allowed in FIPS mode"); ++ else if (type == KEY_DSA && *bitsp != 1024) + fatal("DSA keys must be 1024 bits"); ++ else if (type == KEY_RSA && bits < DEFAULT_BITS && FIPS_mode()) { ++ fprintf(stderr, "RSA keys must be at least %d bits in FIPS mode\n", DEFAULT_BITS); ++ exit(1); ++ } + else if (type != KEY_ECDSA && *bitsp < 768) + fatal("Key must at least be 768 bits"); + else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) +diff --git a/sshconnect2.c b/sshconnect2.c +index 7e48880..3179d82 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -231,6 +231,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; ++ else if (FIPS_mode()) ++ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; + + #ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the +diff --git a/sshd.c b/sshd.c +index 11adbf6..f5e98bc 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2605,6 +2605,8 @@ do_ssh2_kex(void) + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; ++ else if (FIPS_mode()) ++ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; + + if (options.rekey_limit || options.rekey_interval) + packet_set_rekey_limits((u_int32_t)options.rekey_limit, diff --git a/openssh-6.4p1-fromto-remote.patch b/openssh-6.4p1-fromto-remote.patch new file mode 100644 index 0000000..4a7d849 --- /dev/null +++ b/openssh-6.4p1-fromto-remote.patch @@ -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]); diff --git a/openssh-6.4p1-gsissh.patch b/openssh-6.4p1-gsissh.patch index edd513a..0e23d7f 100644 --- a/openssh-6.4p1-gsissh.patch +++ b/openssh-6.4p1-gsissh.patch @@ -2253,7 +2253,7 @@ diff -Nur openssh-6.4p1.orig/sshd.c openssh-6.4p1/sshd.c diff -Nur openssh-6.4p1.orig/sshd_config openssh-6.4p1/sshd_config --- openssh-6.4p1.orig/sshd_config 2013-11-26 14:25:47.983371579 +0100 +++ openssh-6.4p1/sshd_config 2013-11-26 14:26:35.183803047 +0100 -@@ -89,12 +89,11 @@ +@@ -89,12 +89,12 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2262,7 +2262,7 @@ diff -Nur openssh-6.4p1.orig/sshd_config openssh-6.4p1/sshd_config +#GSSAPIAuthentication yes +#GSSAPIDelegateCredentials yes #GSSAPICleanupCredentials yes --GSSAPICleanupCredentials yes + GSSAPICleanupCredentials no #GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no +#GSSAPIKeyExchange yes diff --git a/openssh-6.4p1-ignore-bad-env-var.patch b/openssh-6.4p1-ignore-bad-env-var.patch new file mode 100644 index 0000000..3bb49c2 --- /dev/null +++ b/openssh-6.4p1-ignore-bad-env-var.patch @@ -0,0 +1,37 @@ +diff -U0 openssh-6.4p1/ChangeLog.bad-env-var openssh-6.4p1/ChangeLog +--- openssh-6.4p1/ChangeLog.bad-env-var 2014-03-19 21:37:36.270509907 +0100 ++++ openssh-6.4p1/ChangeLog 2014-03-19 21:37:36.276509878 +0100 +@@ -0,0 +1,7 @@ ++20140304 ++ - OpenBSD CVS Sync ++ - djm@cvs.openbsd.org 2014/03/03 22:22:30 ++ [session.c] ++ ignore enviornment variables with embedded '=' or '\0' characters; ++ spotted by Jann Horn; ok deraadt@ ++ +diff -up openssh-6.4p1/session.c.bad-env-var openssh-6.4p1/session.c +--- openssh-6.4p1/session.c.bad-env-var 2014-03-19 21:37:36.233510090 +0100 ++++ openssh-6.4p1/session.c 2014-03-19 21:37:36.277509873 +0100 +@@ -990,6 +990,11 @@ child_set_env(char ***envp, u_int *envsi + u_int envsize; + u_int i, namelen; + ++ if (strchr(name, '=') != NULL) { ++ error("Invalid environment variable \"%.100s\"", name); ++ return; ++ } ++ + /* + * If we're passed an uninitialized list, allocate a single null + * entry before continuing. +@@ -2255,8 +2260,8 @@ session_env_req(Session *s) + char *name, *val; + u_int name_len, val_len, i; + +- name = packet_get_string(&name_len); +- val = packet_get_string(&val_len); ++ name = packet_get_cstring(&name_len); ++ val = packet_get_cstring(&val_len); + packet_check_eom(); + + /* Don't set too many environment variables */ diff --git a/openssh-6.4p1-legacy-ssh-copy-id.patch b/openssh-6.4p1-legacy-ssh-copy-id.patch new file mode 100644 index 0000000..ba8d949 --- /dev/null +++ b/openssh-6.4p1-legacy-ssh-copy-id.patch @@ -0,0 +1,57 @@ +diff -up openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id.1 +--- openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id 2013-03-22 00:17:37.000000000 +0100 ++++ openssh-6.4p1/contrib/ssh-copy-id.1 2014-01-28 17:12:49.197542425 +0100 +@@ -180,6 +180,19 @@ should prove enlightening (N.B. the mode + .Fl W + option, rather than + .Xr nc 1 ) . ++.Sh ENVIRONMENT ++.Bl -tag -width Ds ++.Pp ++.It Pa SSH_COPY_ID_LEGACY ++If the ++.Cm SSH_COPY_ID_LEGACY ++environment variable is set, the ++.Nm ++is run in a legacy mode. In this mode, the ++.Nm ++doesn't check an existence of a private key and doesn't do remote checks ++of the remote server versions or if public keys are already installed. ++.El + .Sh "SEE ALSO" + .Xr ssh 1 , + .Xr ssh-agent 1 , +diff -up openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id +--- openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id 2013-06-05 14:48:45.000000000 +0200 ++++ openssh-6.4p1/contrib/ssh-copy-id 2014-01-28 17:11:51.538833032 +0100 +@@ -77,7 +77,7 @@ use_id_file() { + PUB_ID_FILE="$L_ID_FILE.pub" + fi + +- PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) ++ [ "x$SSH_COPY_ID_LEGACY" != "x" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) + + # check that the files are readable + for f in $PUB_ID_FILE $PRIV_ID_FILE ; do +@@ -243,7 +243,7 @@ populate_new_ids() { + printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 + } + +-REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | ++[ "x$SSH_COPY_ID_LEGACY" != "x" ] || REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | + sed -ne 's/.*remote software version //p') + + case "$REMOTE_VERSION" in +@@ -268,7 +268,11 @@ case "$REMOTE_VERSION" in + ;; + *) + # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect +- populate_new_ids 0 ++ if [ "x$SSH_COPY_ID_LEGACY" != "x" ]; then ++ NEW_IDS=`eval "$GET_ID"` ++ else ++ populate_new_ids 0 ++ fi + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " + umask 077 ; + mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; From 0ae19bf766992f0feb2d5e64a1a7bd813018141b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 16 Jul 2014 07:05:09 +0200 Subject: [PATCH 004/146] Based on openssh-6.6.1p1-2.fc21 --- gsi-openssh.spec | 92 +- gsisshd-keygen | 55 +- gsisshd-keygen.service | 3 + gsisshd.pam | 4 + gsisshd.service | 3 +- gsisshd.sysconfig | 14 +- gsisshd@.service | 2 +- openssh-5.5p1-x11.patch | 7 +- ...sh-5.8p2-remove-stale-control-socket.patch | 13 - openssh-5.9p1-randclean.patch | 13 - ...210618256bbf5f4f71b2887ff186fd451736.patch | 177 +++ openssh-6.3p1-fips.patch | 611 -------- ...ssh-6.3p1-increase-size-of-DF-groups.patch | 65 - openssh-6.4p1-FIPS-mode-SP800-131A.patch | 206 --- openssh-6.4p1-ignore-bad-env-var.patch | 37 - ...patch => openssh-6.6p1-CVE-2014-2653.patch | 12 +- ...patch => openssh-6.6p1-allow-ip-opts.patch | 19 +- ...1-audit.patch => openssh-6.6p1-audit.patch | 453 +++--- ....patch => openssh-6.6p1-ctr-cavstest.patch | 89 +- ...tropy.patch => openssh-6.6p1-entropy.patch | 141 +- ...t.patch => openssh-6.6p1-fingerprint.patch | 115 +- openssh-6.6p1-fips.patch | 808 +++++++++++ ...krb.patch => openssh-6.6p1-force_krb.patch | 52 +- ...gsissh.patch => openssh-6.6p1-gsissh.patch | 545 +++---- ...gsskex.patch => openssh-6.6p1-gsskex.patch | 745 +++++----- ...keycat.patch => openssh-6.6p1-keycat.patch | 138 +- ...yperm.patch => openssh-6.6p1-keyperm.patch | 22 +- ...serok.patch => openssh-6.6p1-kuserok.patch | 73 +- ...3p1-ldap.patch => openssh-6.6p1-ldap.patch | 1269 +++++++++-------- ...patch => openssh-6.6p1-log-usepam-no.patch | 20 +- ...tch => openssh-6.6p1-privsep-selinux.patch | 68 +- ...redhat.patch => openssh-6.6p1-redhat.patch | 102 +- ...-mls.patch => openssh-6.6p1-role-mls.patch | 559 ++++---- sources | 2 +- 34 files changed, 3325 insertions(+), 3209 deletions(-) delete mode 100644 openssh-5.8p2-remove-stale-control-socket.patch delete mode 100644 openssh-5.9p1-randclean.patch create mode 100644 openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch delete mode 100644 openssh-6.3p1-fips.patch delete mode 100644 openssh-6.3p1-increase-size-of-DF-groups.patch delete mode 100644 openssh-6.4p1-FIPS-mode-SP800-131A.patch delete mode 100644 openssh-6.4p1-ignore-bad-env-var.patch rename openssh-6.4p1-CVE-2014-2653.patch => openssh-6.6p1-CVE-2014-2653.patch (91%) rename openssh-5.2p1-allow-ip-opts.patch => openssh-6.6p1-allow-ip-opts.patch (74%) rename openssh-6.4p1-audit.patch => openssh-6.6p1-audit.patch (82%) rename openssh-6.3p1-ctr-cavstest.patch => openssh-6.6p1-ctr-cavstest.patch (90%) rename openssh-6.2p1-entropy.patch => openssh-6.6p1-entropy.patch (70%) rename openssh-6.3p1-fingerprint.patch => openssh-6.6p1-fingerprint.patch (78%) create mode 100644 openssh-6.6p1-fips.patch rename openssh-6.3p1-force_krb.patch => openssh-6.6p1-force_krb.patch (84%) rename openssh-6.4p1-gsissh.patch => openssh-6.6p1-gsissh.patch (87%) rename openssh-6.3p1-gsskex.patch => openssh-6.6p1-gsskex.patch (79%) rename openssh-6.3p1-keycat.patch => openssh-6.6p1-keycat.patch (72%) rename openssh-5.8p1-keyperm.patch => openssh-6.6p1-keyperm.patch (56%) rename openssh-6.3p1-kuserok.patch => openssh-6.6p1-kuserok.patch (67%) rename openssh-6.3p1-ldap.patch => openssh-6.6p1-ldap.patch (95%) rename openssh-6.1p1-log-usepam-no.patch => openssh-6.6p1-log-usepam-no.patch (54%) rename openssh-6.3p1-privsep-selinux.patch => openssh-6.6p1-privsep-selinux.patch (51%) rename openssh-6.3p1-redhat.patch => openssh-6.6p1-redhat.patch (72%) rename openssh-6.3p1-role-mls.patch => openssh-6.6p1-role-mls.patch (66%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index b2247a7..cd35f65 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,8 +28,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 6.4p1 -%global openssh_rel 3 +%global openssh_ver 6.6.1p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -38,7 +38,8 @@ Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html -Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +# Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-6.6p1.tar.gz Source2: gsisshd.pam Source7: gsisshd.sysconfig Source9: gsisshd@.service @@ -51,7 +52,7 @@ Source99: README.sshd-and-gsisshd #? Patch100: openssh-6.3p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1872 -Patch101: openssh-6.3p1-fingerprint.patch +Patch101: openssh-6.6p1-fingerprint.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 #https://bugzilla.redhat.com/show_bug.cgi?id=735889 Patch102: openssh-5.8p1-getaddrinfo.patch @@ -59,28 +60,24 @@ Patch102: openssh-5.8p1-getaddrinfo.patch Patch103: openssh-5.8p1-packet.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 -Patch200: openssh-6.4p1-audit.patch +Patch200: openssh-6.6p1-audit.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch400: openssh-6.3p1-role-mls.patch +Patch400: openssh-6.6p1-role-mls.patch #https://bugzilla.redhat.com/show_bug.cgi?id=781634 -Patch404: openssh-6.3p1-privsep-selinux.patch +Patch404: openssh-6.6p1-privsep-selinux.patch #?-- unwanted child :( -Patch501: openssh-6.3p1-ldap.patch +Patch501: openssh-6.6p1-ldap.patch #? -Patch502: openssh-6.3p1-keycat.patch +Patch502: openssh-6.6p1-keycat.patch #http6://bugzilla.mindrot.org/show_bug.cgi?id=1644 -Patch601: openssh-5.2p1-allow-ip-opts.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1701 -Patch602: openssh-5.9p1-randclean.patch +Patch601: openssh-6.6p1-allow-ip-opts.patch #http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/crypto/dist/ssh/Attic/sftp-glob.c.diff?r1=1.13&r2=1.13.12.1&f=h Patch603: openssh-5.8p1-glob.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1893 -Patch604: openssh-5.8p1-keyperm.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1329 (WONTFIX) -Patch605: openssh-5.8p2-remove-stale-control-socket.patch +Patch604: openssh-6.6p1-keyperm.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1925 Patch606: openssh-5.9p1-ipv6man.patch #? @@ -91,46 +88,42 @@ Patch608: openssh-6.1p1-askpass-ld.patch Patch609: openssh-5.5p1-x11.patch #? -Patch700: openssh-6.3p1-fips.patch +Patch700: openssh-6.6p1-fips.patch #? -Patch701: openssh-5.6p1-exit-deadlock.patch +# drop? Patch701: openssh-5.6p1-exit-deadlock.patch #? Patch702: openssh-5.1p1-askpass-progress.patch #? Patch703: openssh-4.3p2-askpass-grab-info.patch -#? -Patch704: openssh-5.9p1-edns.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=205842 +# drop? Patch704: openssh-5.9p1-edns.patch #? Patch705: openssh-5.1p1-scp-manpage.patch #? Patch706: openssh-5.8p1-localdomain.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) -Patch707: openssh-6.3p1-redhat.patch +Patch707: openssh-6.6p1-redhat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :) -Patch708: openssh-6.2p1-entropy.patch +Patch708: openssh-6.6p1-entropy.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) Patch709: openssh-6.2p1-vendor.patch # warn users for unsupported UsePAM=no (#757545) -Patch711: openssh-6.1p1-log-usepam-no.patch +Patch711: openssh-6.6p1-log-usepam-no.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.3p1-ctr-cavstest.patch +Patch713: openssh-6.6p1-ctr-cavstest.patch #http://www.sxw.org.uk/computing/patches/openssh.html #changed cache storage type - #848228 -Patch800: openssh-6.3p1-gsskex.patch +Patch800: openssh-6.6p1-gsskex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html -Patch801: openssh-6.3p1-force_krb.patch +Patch801: openssh-6.6p1-force_krb.patch Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch901: openssh-6.3p1-kuserok.patch +Patch901: openssh-6.6p1-kuserok.patch # use default_ccache_name from /etc/krb5.conf (#991186) Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch -# increase the size of the Diffie-Hellman groups (#1010607) -Patch903: openssh-6.3p1-increase-size-of-DF-groups.patch -# FIPS mode - adjust the key echange DH groups and ssh-keygen according to SP800-131A (#1001748) -Patch904: openssh-6.4p1-FIPS-mode-SP800-131A.patch # Run ssh-copy-id in the legacy mode when SSH_COPY_ID_LEGACY variable is set (#969375 Patch905: openssh-6.4p1-legacy-ssh-copy-id.patch # Use tty allocation for a remote scp (#985650) @@ -139,13 +132,14 @@ Patch906: openssh-6.4p1-fromto-remote.patch Patch907: openssh-6.4p1-CLOCK_BOOTTIME.patch # Prevents a server from skipping SSHFP lookup and forcing a new-hostkey # dialog by offering only certificate keys. (#1081338) -Patch908: openssh-6.4p1-CVE-2014-2653.patch -# ignore environment variables with embedded '=' or '\0' characters (#1077843) -Patch909: openssh-6.4p1-ignore-bad-env-var.patch +Patch908: openssh-6.6p1-CVE-2014-2653.patch +# OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 key exchange incorrectly +# Disable the curve25519 KEX when speaking to OpenSSH 6.5 or 6.6 +Patch909: openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.4p1.patch -Patch98: openssh-6.4p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch +Patch98: openssh-6.6p1-gsissh.patch License: BSD Group: Applications/Internet @@ -241,15 +235,13 @@ securely connect to your SSH server. This version of OpenSSH has been modified to support GSI authentication. %prep -%setup -q -n openssh-%{version} +%setup -q -n openssh-6.6p1 -%patch100 -p1 -b .coverity +# rework %patch100 -p1 -b .coverity %patch101 -p1 -b .fingerprint -%patch102 -p1 -b .getaddrinfo +# investigate %patch102 -p1 -b .getaddrinfo %patch103 -p1 -b .packet -%patch200 -p1 -b .audit - %if %{WITH_SELINUX} %patch400 -p1 -b .role-mls %patch404 -p1 -b .privsep-selinux @@ -261,21 +253,19 @@ This version of OpenSSH has been modified to support GSI authentication. %patch502 -p1 -b .keycat %patch601 -p1 -b .ip-opts -%patch602 -p1 -b .randclean %patch603 -p1 -b .glob %patch604 -p1 -b .keyperm -%patch605 -p1 -b .remove_stale %patch606 -p1 -b .ipv6man %patch607 -p1 -b .sigpipe %patch608 -p1 -b .askpass-ld %patch609 -p1 -b .x11 -%patch700 -p1 -b .fips -%patch701 -p1 -b .exit-deadlock +# drop? %patch701 -p1 -b .exit-deadlock %patch702 -p1 -b .progress %patch703 -p1 -b .grab-info -%patch704 -p1 -b .edns -%patch705 -p1 -b .manpage +# investigate - https://bugzilla.redhat.com/show_bug.cgi?id=205842 +# probably not needed anymore %patch704 -p1 -b .edns +# drop it %patch705 -p1 -b .manpage %patch706 -p1 -b .localdomain %patch707 -p1 -b .redhat %patch708 -p1 -b .entropy @@ -290,13 +280,14 @@ This version of OpenSSH has been modified to support GSI authentication. %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok %patch902 -p1 -b .ccache_name -%patch903 -p1 -b .dh -%patch904 -p1 -b .SP800-131A %patch905 -p1 -b .legacy-ssh-copy-id %patch906 -p1 -b .fromto-remote %patch907 -p1 -b .CLOCK_BOOTTIME %patch908 -p1 -b .CVE-2014-2653 -%patch909 -p1 -b .bad-env-var +%patch909 -p1 -b .6.6.1 + +%patch200 -p1 -b .audit +%patch700 -p1 -b .fips %patch98 -p1 -b .gsi @@ -510,6 +501,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Wed Jul 16 2014 Mattias Ellert - 6.6.1p1-1 +- Based on openssh-6.6.1p1-2.fc21 + * Thu Jul 10 2014 Mattias Ellert - 6.4p1-3 - Based on openssh-6.4p1-4.fc20 diff --git a/gsisshd-keygen b/gsisshd-keygen index d8e19f3..80134db 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -4,7 +4,7 @@ # # The creation is controlled by the $AUTOCREATE_SERVER_KEYS environment # variable. -AUTOCREATE_SERVER_KEYS=NODSA +AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519" # source function library . /etc/rc.d/init.d/functions @@ -15,6 +15,7 @@ RSA1_KEY=/etc/gsissh/ssh_host_key RSA_KEY=/etc/gsissh/ssh_host_rsa_key DSA_KEY=/etc/gsissh/ssh_host_dsa_key ECDSA_KEY=/etc/gsissh/ssh_host_ecdsa_key +ED25519_KEY=/etc/gsissh/ssh_host_ed25519_key # pull in sysconfig settings [ -f /etc/sysconfig/gsisshd ] && . /etc/sysconfig/gsisshd @@ -36,7 +37,7 @@ do_rsa1_keygen() { chmod 640 $RSA1_KEY chmod 644 $RSA1_KEY.pub if [ -x /sbin/restorecon ]; then - /sbin/restorecon $RSA1_KEY.pub + /sbin/restorecon $RSA1_KEY{,.pub} fi success $"RSA1 key generation" echo @@ -57,7 +58,7 @@ do_rsa_keygen() { chmod 640 $RSA_KEY chmod 644 $RSA_KEY.pub if [ -x /sbin/restorecon ]; then - /sbin/restorecon $RSA_KEY.pub + /sbin/restorecon $RSA_KEY{,.pub} fi success $"RSA key generation" echo @@ -78,7 +79,7 @@ do_dsa_keygen() { chmod 640 $DSA_KEY chmod 644 $DSA_KEY.pub if [ -x /sbin/restorecon ]; then - /sbin/restorecon $DSA_KEY.pub + /sbin/restorecon $DSA_KEY{,.pub} fi success $"DSA key generation" echo @@ -99,7 +100,7 @@ do_ecdsa_keygen() { chmod 640 $ECDSA_KEY chmod 644 $ECDSA_KEY.pub if [ -x /sbin/restorecon ]; then - /sbin/restorecon $ECDSA_KEY.pub + /sbin/restorecon $ECDSA_KEY{,.pub} fi success $"ECDSA key generation" echo @@ -111,13 +112,43 @@ do_ecdsa_keygen() { fi } -# Create keys if necessary -if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then - do_rsa_keygen - if [ "x${AUTOCREATE_SERVER_KEYS}" != xRSAONLY ]; then - do_ecdsa_keygen - if [ "x${AUTOCREATE_SERVER_KEYS}" != xNODSA ]; then - do_dsa_keygen +do_ed25519_keygen() { + if [ ! -s $ED25519_KEY ]; then + echo -n $"Generating SSH2 ED25519 host key: " + rm -f $ED25519_KEY + if test ! -f $ED25519_KEY && $KEYGEN -q -t ed25519 -f $ED25519_KEY -C '' -N '' >&/dev/null; then + chgrp ssh_keys $ED25519_KEY + chmod 640 $ED25519_KEY + chmod 644 $ED25519_KEY.pub + if [ -x /sbin/restorecon ]; then + /sbin/restorecon $ED25519_KEY{,.pub} + fi + success $"ED25519 key generation" + echo + else + failure $"ED25519 key generation" + echo + exit 1 fi fi +} + +if [ "x${AUTOCREATE_SERVER_KEYS}" == "xNO" ]; then + exit 0 fi + +# legacy options +case $AUTOCREATE_SERVER_KEYS in + NODSA) AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519";; + RSAONLY) AUTOCREATE_SERVER_KEYS="RSA";; + YES) AUTOCREATE_SERVER_KEYS="DSA RSA ECDSA ED25519";; +esac + +for KEY in $AUTOCREATE_SERVER_KEYS; do + case $KEY in + DSA) do_dsa_keygen;; + RSA) do_rsa_keygen;; + ECDSA) do_ecdsa_keygen;; + ED25519) do_ed25519_keygen;; + esac +done diff --git a/gsisshd-keygen.service b/gsisshd-keygen.service index 5cb78e3..a8e99a3 100644 --- a/gsisshd-keygen.service +++ b/gsisshd-keygen.service @@ -2,7 +2,10 @@ Description=gsissh Server Key Generation ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key ConditionPathExists=|!/etc/gsissh/ssh_host_ecdsa_key +ConditionPathExists=|!/etc/gsissh/ssh_host_ec25519_key +PartOf=gsisshd.service gsisshd.socket [Service] ExecStart=/usr/sbin/gsisshd-keygen Type=oneshot +RemainAfterExit=yes diff --git a/gsisshd.pam b/gsisshd.pam index af19ec0..766aa93 100644 --- a/gsisshd.pam +++ b/gsisshd.pam @@ -2,6 +2,8 @@ auth required pam_sepermit.so auth substack password-auth auth include postlogin +# Used with polkit to reauthorize users in remote sessions +-auth optional pam_reauthorize.so prepare account required pam_nologin.so account include password-auth password include password-auth @@ -13,3 +15,5 @@ session required pam_selinux.so open env_params session optional pam_keyinit.so force revoke session include password-auth session include postlogin +# Used with polkit to reauthorize users in remote sessions +-session optional pam_reauthorize.so prepare diff --git a/gsisshd.service b/gsisshd.service index 2d685f9..634f7a9 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -1,10 +1,9 @@ [Unit] Description=gsissh server daemon -After=syslog.target network.target auditd.service +After=network.target gsisshd-keygen.service [Service] EnvironmentFile=/etc/sysconfig/gsisshd -ExecStartPre=/usr/sbin/gsisshd-keygen ExecStart=/usr/sbin/gsisshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index ddd7744..e666ab9 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -1,14 +1,12 @@ # Configuration file for the sshd service. -# The server keys are automatically generated if they omitted -# to change the automatic creation uncomment the appropriate -# line. The default is NODSA which means rsa and ecdsa keys are -# generated. +# The server keys are automatically generated if they are missing. +# To change the automatic creation uncomment and change the appropriate +# line. Accepted key types are: DSA RSA ECDSA ED25519. +# The default is "RSA ECDSA ED25519" -# AUTOCREATE_SERVER_KEYS=NODSA -# AUTOCREATE_SERVER_KEYS=RSAONLY -# AUTOCREATE_SERVER_KEYS=NO -# AUTOCREATE_SERVER_KEYS=YES +# AUTOCREATE_SERVER_KEYS="" +# AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519" # Do not change this option unless you have hardware random # generator and you REALLY know what you are doing diff --git a/gsisshd@.service b/gsisshd@.service index 2030d9f..a4b88ba 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -1,7 +1,7 @@ [Unit] Description=gsissh per-connection server daemon Wants=gsisshd-keygen.service -After=auditd.service gsisshd-keygen.service +After=gsisshd-keygen.service [Service] EnvironmentFile=-/etc/sysconfig/gsisshd diff --git a/openssh-5.5p1-x11.patch b/openssh-5.5p1-x11.patch index cac5d5e..70a3c85 100644 --- a/openssh-5.5p1-x11.patch +++ b/openssh-5.5p1-x11.patch @@ -28,16 +28,13 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c return -1; } -@@ -3207,8 +3210,21 @@ static int +@@ -3207,8 +3210,18 @@ static int connect_local_xsocket(u_int dnr) { char buf[1024]; - snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); - return connect_local_xsocket_path(buf); -+ int len; -+#ifdef linux -+ int ret; -+#endif ++ int len, ret; + len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr); +#ifdef linux + /* try abstract socket first */ diff --git a/openssh-5.8p2-remove-stale-control-socket.patch b/openssh-5.8p2-remove-stale-control-socket.patch deleted file mode 100644 index 4a25d9e..0000000 --- a/openssh-5.8p2-remove-stale-control-socket.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up openssh-5.8p2/mux.c.remove_stale openssh-5.8p2/mux.c ---- openssh-5.8p2/mux.c.remove_stale 2011-01-14 02:01:32.000000000 +0100 -+++ openssh-5.8p2/mux.c 2011-06-09 15:27:42.556360291 +0200 -@@ -1867,6 +1867,9 @@ muxclient(const char *path) - unlink(path); - } else if (errno == ENOENT) { - debug("Control socket \"%.100s\" does not exist", path); -+ } else if (errno == ECONNREFUSED) { -+ debug("Removing stale control socket \"%.100s\"", path); -+ unlink(path); - } else { - error("Control socket connect(%.100s): %s", path, - strerror(errno)); diff --git a/openssh-5.9p1-randclean.patch b/openssh-5.9p1-randclean.patch deleted file mode 100644 index a2c5d33..0000000 --- a/openssh-5.9p1-randclean.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up openssh-5.9p0/entropy.c.randclean openssh-5.9p0/entropy.c ---- openssh-5.9p0/entropy.c.randclean 2011-08-30 13:52:45.000000000 +0200 -+++ openssh-5.9p0/entropy.c 2011-08-30 13:57:44.630111338 +0200 -@@ -217,6 +217,9 @@ seed_rng(void) - fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); - -+ /* clean the PRNG status when exiting the program */ -+ atexit(RAND_cleanup); -+ - #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { - debug3("RNG is ready, skipping seeding"); diff --git a/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch b/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch new file mode 100644 index 0000000..44da114 --- /dev/null +++ b/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch @@ -0,0 +1,177 @@ +From 5618210618256bbf5f4f71b2887ff186fd451736 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Sun, 20 Apr 2014 13:44:47 +1000 +Subject: [PATCH] - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c + version.h] OpenSSH 6.5 and 6.6 sometimes encode a value used in the + curve25519 key exchange incorrectly, causing connection failures about + 0.2% of the time when this method is used against a peer that implements + the method properly. + + Fix the problem and disable the curve25519 KEX when speaking to + OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 + to enable the compatability code. +--- + ChangeLog | 11 +++++++++++ + bufaux.c | 5 ++++- + compat.c | 17 ++++++++++++++++- + compat.h | 2 ++ + sshconnect2.c | 2 ++ + sshd.c | 3 +++ + version.h | 2 +- + 7 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1603a07..928999d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,13 +1,23 @@ + 20140420 +- - djm@cvs.openbsd.org 2014/04/01 03:34:10 +- [sshconnect.c] +- When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any +- certificate keys to plain keys and attempt SSHFP resolution. +- +- Prevents a server from skipping SSHFP lookup and forcing a new-hostkey +- dialog by offering only certificate keys. +- +- Reported by mcv21 AT cam.ac.uk ++ - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] ++ OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 ++ key exchange incorrectly, causing connection failures about 0.2% of ++ the time when this method is used against a peer that implements ++ the method properly. ++ ++ Fix the problem and disable the curve25519 KEX when speaking to ++ OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 ++ to enable the compatability code. ++ ++ - djm@cvs.openbsd.org 2014/04/01 03:34:10 ++ [sshconnect.c] ++ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any ++ certificate keys to plain keys and attempt SSHFP resolution. ++ ++ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey ++ dialog by offering only certificate keys. ++ ++ Reported by mcv21 AT cam.ac.uk + + 20140313 + - (djm) Release OpenSSH 6.6 +diff --git a/bufaux.c b/bufaux.c +index e24b5fc..f6a6f2a 100644 +--- a/bufaux.c ++++ b/bufaux.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */ ++/* $OpenBSD: bufaux.c,v 1.57 2014/04/16 23:22:45 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -372,6 +372,9 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) + + if (l > 8 * 1024) + fatal("%s: length %u too long", __func__, l); ++ /* Skip leading zero bytes */ ++ for (; l > 0 && *s == 0; l--, s++) ++ ; + p = buf = xmalloc(l + 1); + /* + * If most significant bit is set then prepend a zero byte to +diff --git a/compat.c b/compat.c +index 9d9fabe..2709dc5 100644 +--- a/compat.c ++++ b/compat.c +@@ -95,6 +95,9 @@ compat_datafellows(const char *version) + { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, + { "OpenSSH_4*", 0 }, + { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, ++ { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH}, ++ { "OpenSSH_6.5*," ++ "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD}, + { "OpenSSH*", SSH_NEW_OPENSSH }, + { "*MindTerm*", 0 }, + { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| +@@ -251,7 +254,6 @@ compat_cipher_proposal(char *cipher_prop) + return cipher_prop; + } + +- + char * + compat_pkalg_proposal(char *pkalg_prop) + { +@@ -265,3 +267,16 @@ compat_pkalg_proposal(char *pkalg_prop) + return pkalg_prop; + } + ++char * ++compat_kex_proposal(char *kex_prop) ++{ ++ if (!(datafellows & SSH_BUG_CURVE25519PAD)) ++ return kex_prop; ++ debug2("%s: original KEX proposal: %s", __func__, kex_prop); ++ kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org"); ++ debug2("%s: compat KEX proposal: %s", __func__, kex_prop); ++ if (*kex_prop == '\0') ++ fatal("No supported key exchange algorithms found"); ++ return kex_prop; ++} ++ +diff --git a/compat.h b/compat.h +index b174fa1..a6c3f3d 100644 +--- a/compat.h ++++ b/compat.h +@@ -59,6 +59,7 @@ + #define SSH_BUG_RFWD_ADDR 0x02000000 + #define SSH_NEW_OPENSSH 0x04000000 + #define SSH_BUG_DYNAMIC_RPORT 0x08000000 ++#define SSH_BUG_CURVE25519PAD 0x10000000 + + void enable_compat13(void); + void enable_compat20(void); +@@ -66,6 +67,7 @@ void compat_datafellows(const char *); + int proto_spec(const char *); + char *compat_cipher_proposal(char *); + char *compat_pkalg_proposal(char *); ++char *compat_kex_proposal(char *); + + extern int compat13; + extern int compat20; +diff --git a/sshconnect2.c b/sshconnect2.c +index bb9292f..b00658b 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -220,6 +220,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; ++ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( ++ myproposal[PROPOSAL_KEX_ALGS]); + + #ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the +diff --git a/sshd.c b/sshd.c +index e4e406e..512c7ed 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2488,6 +2488,9 @@ do_ssh2_kex(void) + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; + ++ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( ++ myproposal[PROPOSAL_KEX_ALGS]); ++ + if (options.rekey_limit || options.rekey_interval) + packet_set_rekey_limits((u_int32_t)options.rekey_limit, + (time_t)options.rekey_interval); +diff --git a/version.h b/version.h +index a1579ac..a33e77c 100644 +--- a/version.h ++++ b/version.h +@@ -1,6 +1,6 @@ + /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ + +-#define SSH_VERSION "OpenSSH_6.6" ++#define SSH_VERSION "OpenSSH_6.6.1" + + #define SSH_PORTABLE "p1" + #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-6.3p1-fips.patch b/openssh-6.3p1-fips.patch deleted file mode 100644 index 6a5a332..0000000 --- a/openssh-6.3p1-fips.patch +++ /dev/null @@ -1,611 +0,0 @@ -diff -up openssh-6.3p1/Makefile.in.fips openssh-6.3p1/Makefile.in ---- openssh-6.3p1/Makefile.in.fips 2013-10-11 22:24:32.850031186 +0200 -+++ openssh-6.3p1/Makefile.in 2013-10-11 22:24:32.870031092 +0200 -@@ -147,25 +147,25 @@ libssh.a: $(LIBSSH_OBJS) - $(RANLIB) $@ - - ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) -- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) -+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) - - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o -- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o -- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o -- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o -- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -177,7 +177,7 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh - $(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS) - - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o -- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-6.3p1/auth-rsa.c.fips openssh-6.3p1/auth-rsa.c ---- openssh-6.3p1/auth-rsa.c.fips 2013-10-24 15:43:46.019999906 +0200 -+++ openssh-6.3p1/auth-rsa.c 2013-10-24 15:44:09.262890686 +0200 -@@ -240,7 +240,7 @@ rsa_key_allowed_in_file(struct passwd *p - "actual %d vs. announced %d.", - file, linenum, BN_num_bits(key->rsa->n), bits); - -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); - debug("matching key found: file %s, line %lu %s %s", - file, linenum, key_type(key), fp); - free(fp); -diff -up openssh-6.3p1/auth2-pubkey.c.fips openssh-6.3p1/auth2-pubkey.c ---- openssh-6.3p1/auth2-pubkey.c.fips 2013-10-24 15:39:05.008319990 +0200 -+++ openssh-6.3p1/auth2-pubkey.c 2013-10-24 15:39:05.029319892 +0200 -@@ -209,7 +209,7 @@ pubkey_auth_info(Authctxt *authctxt, con - - if (key_is_cert(key)) { - fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); - auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", - key_type(key), key->cert->key_id, - (unsigned long long)key->cert->serial, -@@ -217,7 +217,7 @@ pubkey_auth_info(Authctxt *authctxt, con - extra == NULL ? "" : ", ", extra == NULL ? "" : extra); - free(fp); - } else { -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); - auth_info(authctxt, "%s %s%s%s", key_type(key), fp, - extra == NULL ? "" : ", ", extra == NULL ? "" : extra); - free(fp); -diff -up openssh-6.3p1/authfile.c.fips openssh-6.3p1/authfile.c ---- openssh-6.3p1/authfile.c.fips 2013-10-11 22:24:32.857031153 +0200 -+++ openssh-6.3p1/authfile.c 2013-10-11 22:24:32.870031092 +0200 -@@ -148,8 +148,14 @@ key_private_rsa1_to_blob(Key *key, Buffe - /* Allocate space for the private part of the key in the buffer. */ - cp = buffer_append_space(&encrypted, buffer_len(&buffer)); - -- cipher_set_key_string(&ciphercontext, cipher, passphrase, -- CIPHER_ENCRYPT); -+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, -+ CIPHER_ENCRYPT) < 0) { -+ error("cipher_set_key_string failed."); -+ buffer_free(&encrypted); -+ buffer_free(&buffer); -+ return 0; -+ } -+ - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); - cipher_cleanup(&ciphercontext); -@@ -472,8 +478,13 @@ key_parse_private_rsa1(Buffer *blob, con - cp = buffer_append_space(&decrypted, buffer_len(©)); - - /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ -- cipher_set_key_string(&ciphercontext, cipher, passphrase, -- CIPHER_DECRYPT); -+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, -+ CIPHER_DECRYPT) < 0) { -+ error("cipher_set_key_string failed."); -+ buffer_free(&decrypted); -+ goto fail; -+ } -+ - cipher_crypt(&ciphercontext, cp, - buffer_ptr(©), buffer_len(©), 0, 0); - cipher_cleanup(&ciphercontext); -diff -up openssh-6.3p1/cipher-ctr.c.fips openssh-6.3p1/cipher-ctr.c ---- openssh-6.3p1/cipher-ctr.c.fips 2013-06-02 00:07:32.000000000 +0200 -+++ openssh-6.3p1/cipher-ctr.c 2013-10-11 22:24:32.870031092 +0200 -@@ -138,7 +138,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-6.3p1/cipher.c.fips openssh-6.3p1/cipher.c ---- openssh-6.3p1/cipher.c.fips 2013-10-11 22:24:32.820031327 +0200 -+++ openssh-6.3p1/cipher.c 2013-10-11 22:24:32.871031087 +0200 -@@ -40,6 +40,7 @@ - #include - - #include -+#include - - #include - #include -@@ -86,6 +87,27 @@ static const struct Cipher ciphers[] = { - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } - }; - -+static const struct Cipher fips_ciphers[] = { -+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, -+ { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -+ { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, -+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, -+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, -+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, -+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, -+ { "rijndael-cbc@lysator.liu.se", -+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, -+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, -+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, -+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, -+#ifdef OPENSSL_HAVE_EVPGCM -+ { "aes128-gcm@openssh.com", -+ SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, -+ { "aes256-gcm@openssh.com", -+ SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, -+#endif -+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } -+}; - /*--*/ - - /* Returns a comma-separated list of supported ciphers. */ -@@ -96,7 +118,7 @@ cipher_alg_list(void) - size_t nlen, rlen = 0; - const Cipher *c; - -- for (c = ciphers; c->name != NULL; c++) { -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { - if (c->number != SSH_CIPHER_SSH2) - continue; - if (ret != NULL) -@@ -161,7 +183,7 @@ const Cipher * - cipher_by_name(const char *name) - { - const Cipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcmp(c->name, name) == 0) - return c; - return NULL; -@@ -171,7 +193,7 @@ const Cipher * - cipher_by_number(int id) - { - const Cipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (c->number == id) - return c; - return NULL; -@@ -215,7 +237,7 @@ cipher_number(const char *name) - const Cipher *c; - if (name == NULL) - return -1; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcasecmp(c->name, name) == 0) - return c->number; - return -1; -@@ -374,14 +396,15 @@ cipher_cleanup(CipherContext *cc) - * passphrase and using the resulting 16 bytes as the key. - */ - --void -+int - cipher_set_key_string(CipherContext *cc, const Cipher *cipher, - const char *passphrase, int do_encrypt) - { - MD5_CTX md; - u_char digest[16]; - -- MD5_Init(&md); -+ if (MD5_Init(&md) <= 0) -+ return -1; - MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); - MD5_Final(digest, &md); - -@@ -389,6 +412,7 @@ cipher_set_key_string(CipherContext *cc, - - memset(digest, 0, sizeof(digest)); - memset(&md, 0, sizeof(md)); -+ return 0; - } - - /* -diff -up openssh-6.3p1/cipher.h.fips openssh-6.3p1/cipher.h ---- openssh-6.3p1/cipher.h.fips 2013-10-11 22:24:32.820031327 +0200 -+++ openssh-6.3p1/cipher.h 2013-10-11 22:24:32.871031087 +0200 -@@ -92,7 +92,7 @@ void cipher_init(CipherContext *, const - void cipher_crypt(CipherContext *, u_char *, const u_char *, - u_int, u_int, u_int); - void cipher_cleanup(CipherContext *); --void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); -+int cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); - u_int cipher_blocksize(const Cipher *); - u_int cipher_keylen(const Cipher *); - u_int cipher_authlen(const Cipher *); -diff -up openssh-6.3p1/key.c.fips openssh-6.3p1/key.c ---- openssh-6.3p1/key.c.fips 2013-10-11 22:24:32.821031322 +0200 -+++ openssh-6.3p1/key.c 2013-10-11 22:24:32.871031087 +0200 -@@ -40,6 +40,7 @@ - #include - - #include -+#include - #include - - #include -@@ -606,9 +607,13 @@ key_fingerprint_selection(void) - char *env; - - if (!rv_defined) { -- env = getenv("SSH_FINGERPRINT_TYPE"); -- rv = (env && !strcmp (env, "sha")) ? -- SSH_FP_SHA1 : SSH_FP_MD5; -+ if (FIPS_mode()) -+ rv = SSH_FP_SHA1; -+ else { -+ env = getenv("SSH_FINGERPRINT_TYPE"); -+ rv = (env && !strcmp (env, "sha")) ? -+ SSH_FP_SHA1 : SSH_FP_MD5; -+ } - rv_defined = 1; - } - return rv; -diff -up openssh-6.3p1/mac.c.fips openssh-6.3p1/mac.c ---- openssh-6.3p1/mac.c.fips 2013-10-11 22:24:32.821031322 +0200 -+++ openssh-6.3p1/mac.c 2013-10-11 22:25:35.394737186 +0200 -@@ -28,6 +28,7 @@ - #include - - #include -+#include - - #include - #include -@@ -60,7 +61,7 @@ struct macalg { - int etm; /* Encrypt-then-MAC */ - }; - --static const struct macalg macs[] = { -+static const struct macalg all_macs[] = { - /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ - { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, - { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, -@@ -91,6 +92,18 @@ static const struct macalg macs[] = { - { NULL, 0, NULL, 0, 0, 0, 0 } - }; - -+static const struct macalg fips_macs[] = { -+ { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, -+ { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 }, -+#ifdef HAVE_EVP_SHA256 -+ { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 }, -+ { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 }, -+ { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 }, -+ { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 }, -+#endif -+ { NULL, 0, NULL, 0, 0, 0, 0 } -+}; -+ - /* Returns a comma-separated list of supported MACs. */ - char * - mac_alg_list(void) -@@ -99,7 +112,7 @@ mac_alg_list(void) - size_t nlen, rlen = 0; - const struct macalg *m; - -- for (m = macs; m->name != NULL; m++) { -+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { - if (ret != NULL) - ret[rlen++] = '\n'; - nlen = strlen(m->name); -@@ -136,7 +149,7 @@ mac_setup(Mac *mac, char *name) - { - const struct macalg *m; - -- for (m = macs; m->name != NULL; m++) { -+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { - if (strcmp(name, m->name) != 0) - continue; - if (mac != NULL) -diff -up openssh-6.3p1/myproposal.h.fips openssh-6.3p1/myproposal.h ---- openssh-6.3p1/myproposal.h.fips 2013-06-11 04:10:02.000000000 +0200 -+++ openssh-6.3p1/myproposal.h 2013-10-11 22:24:32.872031082 +0200 -@@ -114,6 +114,19 @@ - #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" - #define KEX_DEFAULT_LANG "" - -+#define KEX_FIPS_ENCRYPT \ -+ "aes128-ctr,aes192-ctr,aes256-ctr," \ -+ "aes128-cbc,3des-cbc," \ -+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" -+#ifdef HAVE_EVP_SHA256 -+#define KEX_FIPS_MAC \ -+ "hmac-sha1," \ -+ "hmac-sha2-256," \ -+ "hmac-sha2-512" -+#else -+#define KEX_FIPS_MAC \ -+ "hmac-sha1" -+#endif - - static char *myproposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, -diff -up openssh-6.3p1/openbsd-compat/bsd-arc4random.c.fips openssh-6.3p1/openbsd-compat/bsd-arc4random.c ---- openssh-6.3p1/openbsd-compat/bsd-arc4random.c.fips 2010-03-25 22:52:02.000000000 +0100 -+++ openssh-6.3p1/openbsd-compat/bsd-arc4random.c 2013-10-11 22:24:32.872031082 +0200 -@@ -37,25 +37,18 @@ - #define REKEY_BYTES (1 << 24) - - static int rc4_ready = 0; --static RC4_KEY rc4; - - unsigned int - arc4random(void) - { - unsigned int r = 0; -- static int first_time = 1; -+ void *rp = &r; - -- if (rc4_ready <= 0) { -- if (first_time) -- seed_rng(); -- first_time = 0; -+ if (!rc4_ready) { - arc4random_stir(); - } -+ RAND_bytes(rp, sizeof(r)); - -- RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); -- -- rc4_ready -= sizeof(r); -- - return(r); - } - -@@ -63,24 +56,11 @@ void - arc4random_stir(void) - { - unsigned char rand_buf[SEED_SIZE]; -- int i; - -- memset(&rc4, 0, sizeof(rc4)); - if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) - fatal("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); -- RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); -- -- /* -- * Discard early keystream, as per recommendations in: -- * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps -- */ -- for(i = 0; i <= 256; i += sizeof(rand_buf)) -- RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); -- -- memset(rand_buf, 0, sizeof(rand_buf)); -- -- rc4_ready = REKEY_BYTES; -+ rc4_ready = 1; - } - #endif /* !HAVE_ARC4RANDOM */ - -diff -up openssh-6.3p1/ssh-keygen.c.fips openssh-6.3p1/ssh-keygen.c ---- openssh-6.3p1/ssh-keygen.c.fips 2013-10-24 15:45:06.055623916 +0200 -+++ openssh-6.3p1/ssh-keygen.c 2013-10-24 15:45:36.906478986 +0200 -@@ -730,7 +730,7 @@ do_download(struct passwd *pw) - enum fp_type fptype; - char *fp, *ra; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : (FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - pkcs11_init(0); -@@ -740,7 +740,7 @@ do_download(struct passwd *pw) - for (i = 0; i < nkeys; i++) { - if (print_fingerprint) { - fp = key_fingerprint(keys[i], fptype, rep); -- ra = key_fingerprint(keys[i], SSH_FP_MD5, -+ ra = key_fingerprint(keys[i], FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, - SSH_FP_RANDOMART); - printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), - fp, key_type(keys[i])); -diff -up openssh-6.3p1/ssh.c.fips openssh-6.3p1/ssh.c ---- openssh-6.3p1/ssh.c.fips 2013-07-25 03:55:53.000000000 +0200 -+++ openssh-6.3p1/ssh.c 2013-10-11 22:24:32.872031082 +0200 -@@ -73,6 +73,8 @@ - - #include - #include -+#include -+#include - #include "openbsd-compat/openssl-compat.h" - #include "openbsd-compat/sys-queue.h" - -@@ -253,6 +255,13 @@ main(int ac, char **av) - sanitise_stdfd(); - - __progname = ssh_get_progname(av[0]); -+ SSLeay_add_all_algorithms(); -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) -+ if (FIPS_mode()) -+ fatal("FIPS integrity verification test failed."); -+ else -+ logit("FIPS integrity verification test failed."); - - #ifndef HAVE_SETPROCTITLE - /* Prepare for later setproctitle emulation */ -@@ -330,6 +339,9 @@ main(int ac, char **av) - "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { - switch (opt) { - case '1': -+ if (FIPS_mode()) { -+ fatal("Protocol 1 not allowed in the FIPS mode."); -+ } - options.protocol = SSH_PROTO_1; - break; - case '2': -@@ -647,7 +659,6 @@ main(int ac, char **av) - if (!host) - usage(); - -- OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - - /* Initialize the command to execute on remote host. */ -@@ -748,6 +759,10 @@ main(int ac, char **av) - - seed_rng(); - -+ if (FIPS_mode()) { -+ logit("FIPS mode initialized"); -+ } -+ - if (options.user == NULL) - options.user = xstrdup(pw->pw_name); - -@@ -816,6 +831,12 @@ main(int ac, char **av) - - timeout_ms = options.connection_timeout * 1000; - -+ if (FIPS_mode()) { -+ options.protocol &= SSH_PROTO_2; -+ if (options.protocol == 0) -+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); -+ } -+ - /* Open a connection to the remote host. */ - if (ssh_connect(host, &hostaddr, options.port, - options.address_family, options.connection_attempts, &timeout_ms, -diff -up openssh-6.3p1/sshconnect2.c.fips openssh-6.3p1/sshconnect2.c ---- openssh-6.3p1/sshconnect2.c.fips 2013-10-11 22:24:32.810031374 +0200 -+++ openssh-6.3p1/sshconnect2.c 2013-10-11 22:24:32.873031077 +0200 -@@ -44,6 +44,8 @@ - #include - #endif - -+#include -+ - #include "openbsd-compat/sys-queue.h" - - #include "xmalloc.h" -@@ -170,6 +172,10 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; -+ - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -185,7 +191,11 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } -+ - if (options.hostkeyalgorithms != NULL) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - options.hostkeyalgorithms; -diff -up openssh-6.4p1/sshd.c.fips openssh-6.4p1/sshd.c ---- openssh-6.4p1/sshd.c.fips 2014-01-27 16:20:12.751358484 +0100 -+++ openssh-6.4p1/sshd.c 2014-01-27 16:21:12.961052163 +0100 -@@ -76,6 +76,8 @@ - #include - #include - #include -+#include -+#include - #include "openbsd-compat/openssl-compat.h" - - #ifdef HAVE_SECUREWARE -@@ -1450,6 +1452,18 @@ main(int ac, char **av) - #endif - __progname = ssh_get_progname(av[0]); - -+ SSLeay_add_all_algorithms(); -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) { -+ openlog(__progname, LOG_PID, LOG_AUTHPRIV); -+ if (FIPS_mode()) { -+ syslog(LOG_CRIT, "FIPS integrity verification test failed."); -+ cleanup_exit(255); -+ } -+ else -+ syslog(LOG_INFO, "FIPS integrity verification test failed."); -+ closelog(); -+ } - /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ - saved_argc = ac; - rexec_argc = ac; -@@ -1601,8 +1615,6 @@ main(int ac, char **av) - else - closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); - -- OpenSSL_add_all_algorithms(); -- - /* If requested, redirect the logs to the specified logfile. */ - if (logfile != NULL) { - log_redirect_stderr_to(logfile); -@@ -1773,6 +1785,10 @@ main(int ac, char **av) - debug("private host key: #%d type %d %s", i, keytype, - key_type(key ? key : pubkey)); - } -+ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { -+ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); -+ options.protocol &= ~SSH_PROTO_1; -+ } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; -@@ -1936,6 +1952,10 @@ main(int ac, char **av) - /* Initialize the random number generator. */ - arc4random_stir(); - -+ if (FIPS_mode()) { -+ logit("FIPS mode initialized"); -+ } -+ - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - if (chdir("/") == -1) -@@ -2498,6 +2518,9 @@ do_ssh2_kex(void) - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2507,6 +2530,9 @@ do_ssh2_kex(void) - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } - if (options.compression == COMP_NONE) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = diff --git a/openssh-6.3p1-increase-size-of-DF-groups.patch b/openssh-6.3p1-increase-size-of-DF-groups.patch deleted file mode 100644 index 941aa72..0000000 --- a/openssh-6.3p1-increase-size-of-DF-groups.patch +++ /dev/null @@ -1,65 +0,0 @@ -diff -U0 openssh-6.3p1/ChangeLog.df openssh-6.3p1/ChangeLog ---- openssh-6.3p1/ChangeLog.df 2013-10-23 22:38:03.476272461 +0200 -+++ openssh-6.3p1/ChangeLog 2013-10-23 22:39:46.051788366 +0200 -@@ -0,0 +1,8 @@ -+20131010 -+ - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 -+ [dh.c dh.h] -+ Increase the size of the Diffie-Hellman groups requested for a each -+ symmetric key size. New values from NIST Special Publication 800-57 with -+ the upper limit specified by RFC4419. Pointed out by Peter Backes, ok -+ djm@. -+ -diff -up openssh-6.3p1/dh.c.df openssh-6.3p1/dh.c ---- openssh-6.3p1/dh.c.df 2013-07-18 08:12:07.000000000 +0200 -+++ openssh-6.3p1/dh.c 2013-10-23 22:38:03.476272461 +0200 -@@ -1,4 +1,4 @@ --/* $OpenBSD: dh.c,v 1.51 2013/07/02 12:31:43 markus Exp $ */ -+/* $OpenBSD: dh.c,v 1.52 2013/10/08 11:42:13 dtucker Exp $ */ - /* - * Copyright (c) 2000 Niels Provos. All rights reserved. - * -@@ -352,17 +352,20 @@ dh_new_group14(void) - - /* - * Estimates the group order for a Diffie-Hellman group that has an -- * attack complexity approximately the same as O(2**bits). Estimate -- * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) -+ * attack complexity approximately the same as O(2**bits). -+ * Values from NIST Special Publication 800-57: Recommendation for Key -+ * Management Part 1 (rev 3) limited by the recommended maximum value -+ * from RFC4419 section 3. - */ - - int - dh_estimate(int bits) - { -- -+ if (bits <= 112) -+ return 2048; - if (bits <= 128) -- return (1024); /* O(2**86) */ -+ return 3072; - if (bits <= 192) -- return (2048); /* O(2**116) */ -- return (4096); /* O(2**156) */ -+ return 7680; -+ return 8192; - } -diff -up openssh-6.3p1/dh.h.df openssh-6.3p1/dh.h ---- openssh-6.3p1/dh.h.df 2008-06-29 14:47:04.000000000 +0200 -+++ openssh-6.3p1/dh.h 2013-10-23 22:38:03.476272461 +0200 -@@ -1,4 +1,4 @@ --/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */ -+/* $OpenBSD: dh.h,v 1.11 2013/10/08 11:42:13 dtucker Exp $ */ - - /* - * Copyright (c) 2000 Niels Provos. All rights reserved. -@@ -43,6 +43,7 @@ int dh_pub_is_valid(DH *, BIGNUM *); - - int dh_estimate(int); - -+/* Min and max values from RFC4419. */ - #define DH_GRP_MIN 1024 - #define DH_GRP_MAX 8192 - diff --git a/openssh-6.4p1-FIPS-mode-SP800-131A.patch b/openssh-6.4p1-FIPS-mode-SP800-131A.patch deleted file mode 100644 index cf632d8..0000000 --- a/openssh-6.4p1-FIPS-mode-SP800-131A.patch +++ /dev/null @@ -1,206 +0,0 @@ -diff --git a/dh.h b/dh.h -index 48f7b68..9ff39f4 100644 ---- a/dh.h -+++ b/dh.h -@@ -45,6 +45,7 @@ int dh_estimate(int); - - /* Min and max values from RFC4419. */ - #define DH_GRP_MIN 1024 -+#define DH_GRP_MIN_FIPS 2048 - #define DH_GRP_MAX 8192 - - /* -diff --git a/kex.c b/kex.c -index a468805..3a0eb16 100644 ---- a/kex.c -+++ b/kex.c -@@ -34,6 +34,7 @@ - #include - - #include -+#include - - #include "xmalloc.h" - #include "ssh2.h" -@@ -93,6 +94,20 @@ static const struct kexalg kexalgs[] = { - { NULL, -1, -1, NULL}, - }; - -+static const struct kexalg kexalgs_fips[] = { -+ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 }, -+ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 }, -+#ifdef HAVE_EVP_SHA256 -+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 }, -+#endif -+#ifdef OPENSSL_HAS_ECC -+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 }, -+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, -+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, -+#endif -+ { NULL, -1, -1, NULL}, -+}; -+ - char * - kex_alg_list(void) - { -@@ -116,7 +131,7 @@ kex_alg_by_name(const char *name) - { - const struct kexalg *k; - -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { - if (strcmp(k->name, name) == 0) - return k; - #ifdef GSSAPI -@@ -141,7 +156,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/kexecdhc.c b/kexecdhc.c -index 6193836..d435f1f 100644 ---- a/kexecdhc.c -+++ b/kexecdhc.c -@@ -154,6 +154,7 @@ kexecdh_client(Kex *kex) - - kex_derive_keys(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); -+ memset(hash, 0, hashlen); - kex_finish(kex); - } - #else /* OPENSSL_HAS_ECC */ -diff --git a/kexecdhs.c b/kexecdhs.c -index 3a580aa..9a06905 100644 ---- a/kexecdhs.c -+++ b/kexecdhs.c -@@ -155,6 +155,7 @@ kexecdh_server(Kex *kex) - - kex_derive_keys(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); -+ memset(hash, 0, hashlen); - kex_finish(kex); - } - #else /* OPENSSL_HAS_ECC */ -diff --git a/kexgexc.c b/kexgexc.c -index 5a3be20..a931b6e 100644 ---- a/kexgexc.c -+++ b/kexgexc.c -@@ -26,6 +26,8 @@ - - #include "includes.h" - -+#include -+ - #include - - #include -@@ -64,13 +66,13 @@ kexgex_client(Kex *kex) - /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); -- min = DH_GRP_MIN; -+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - max = DH_GRP_MAX; - - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); - } else { - /* New GEX request */ -- min = DH_GRP_MIN; -+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); -diff --git a/kexgexs.c b/kexgexs.c -index 4e473fc..2ed49bd 100644 ---- a/kexgexs.c -+++ b/kexgexs.c -@@ -76,16 +76,16 @@ kexgex_server(Kex *kex) - omin = min = packet_get_int(); - onbits = nbits = packet_get_int(); - omax = max = packet_get_int(); -- min = MAX(DH_GRP_MIN, min); -+ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); -- nbits = MAX(DH_GRP_MIN, nbits); -+ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); - nbits = MIN(DH_GRP_MAX, nbits); - break; - case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - onbits = nbits = packet_get_int(); - /* unused for old GEX */ -- omin = min = DH_GRP_MIN; -+ omin = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - omax = max = DH_GRP_MAX; - break; - default: -diff --git a/myproposal.h b/myproposal.h -index ee69ea2..1b68c5b 100644 ---- a/myproposal.h -+++ b/myproposal.h -@@ -72,6 +72,12 @@ - "diffie-hellman-group14-sha1," \ - "diffie-hellman-group1-sha1" - -+#define KEX_DEFAULT_KEX_FIPS \ -+ KEX_ECDH_METHODS \ -+ KEX_SHA256_METHODS \ -+ "diffie-hellman-group-exchange-sha1," \ -+ "diffie-hellman-group14-sha1" -+ - #define KEX_DEFAULT_PK_ALG \ - HOSTKEY_ECDSA_CERT_METHODS \ - "ssh-rsa-cert-v01@openssh.com," \ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index cac6762..2569016 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -183,8 +183,14 @@ type_bits_valid(int type, u_int32_t *bitsp) - fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); - exit(1); - } -- if (type == KEY_DSA && *bitsp != 1024) -+ if (type == KEY_DSA && FIPS_mode()) -+ fatal("DSA keys are not allowed in FIPS mode"); -+ else if (type == KEY_DSA && *bitsp != 1024) - fatal("DSA keys must be 1024 bits"); -+ else if (type == KEY_RSA && bits < DEFAULT_BITS && FIPS_mode()) { -+ fprintf(stderr, "RSA keys must be at least %d bits in FIPS mode\n", DEFAULT_BITS); -+ exit(1); -+ } - else if (type != KEY_ECDSA && *bitsp < 768) - fatal("Key must at least be 768 bits"); - else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) -diff --git a/sshconnect2.c b/sshconnect2.c -index 7e48880..3179d82 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -231,6 +231,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - } - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; -+ else if (FIPS_mode()) -+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; - - #ifdef GSSAPI - /* If we've got GSSAPI algorithms, then we also support the -diff --git a/sshd.c b/sshd.c -index 11adbf6..f5e98bc 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2605,6 +2605,8 @@ do_ssh2_kex(void) - } - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; -+ else if (FIPS_mode()) -+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; - - if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits((u_int32_t)options.rekey_limit, diff --git a/openssh-6.4p1-ignore-bad-env-var.patch b/openssh-6.4p1-ignore-bad-env-var.patch deleted file mode 100644 index 3bb49c2..0000000 --- a/openssh-6.4p1-ignore-bad-env-var.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -U0 openssh-6.4p1/ChangeLog.bad-env-var openssh-6.4p1/ChangeLog ---- openssh-6.4p1/ChangeLog.bad-env-var 2014-03-19 21:37:36.270509907 +0100 -+++ openssh-6.4p1/ChangeLog 2014-03-19 21:37:36.276509878 +0100 -@@ -0,0 +1,7 @@ -+20140304 -+ - OpenBSD CVS Sync -+ - djm@cvs.openbsd.org 2014/03/03 22:22:30 -+ [session.c] -+ ignore enviornment variables with embedded '=' or '\0' characters; -+ spotted by Jann Horn; ok deraadt@ -+ -diff -up openssh-6.4p1/session.c.bad-env-var openssh-6.4p1/session.c ---- openssh-6.4p1/session.c.bad-env-var 2014-03-19 21:37:36.233510090 +0100 -+++ openssh-6.4p1/session.c 2014-03-19 21:37:36.277509873 +0100 -@@ -990,6 +990,11 @@ child_set_env(char ***envp, u_int *envsi - u_int envsize; - u_int i, namelen; - -+ if (strchr(name, '=') != NULL) { -+ error("Invalid environment variable \"%.100s\"", name); -+ return; -+ } -+ - /* - * If we're passed an uninitialized list, allocate a single null - * entry before continuing. -@@ -2255,8 +2260,8 @@ session_env_req(Session *s) - char *name, *val; - u_int name_len, val_len, i; - -- name = packet_get_string(&name_len); -- val = packet_get_string(&val_len); -+ name = packet_get_cstring(&name_len); -+ val = packet_get_cstring(&val_len); - packet_check_eom(); - - /* Don't set too many environment variables */ diff --git a/openssh-6.4p1-CVE-2014-2653.patch b/openssh-6.6p1-CVE-2014-2653.patch similarity index 91% rename from openssh-6.4p1-CVE-2014-2653.patch rename to openssh-6.6p1-CVE-2014-2653.patch index 27f3fa3..c3bd0a1 100644 --- a/openssh-6.4p1-CVE-2014-2653.patch +++ b/openssh-6.6p1-CVE-2014-2653.patch @@ -1,5 +1,5 @@ diff --git a/ChangeLog b/ChangeLog -index 29d70ec..a0fb67e 100644 +index 38de846..1603a07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ @@ -14,14 +14,14 @@ index 29d70ec..a0fb67e 100644 + + Reported by mcv21 AT cam.ac.uk + - 20131010 - - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 - [dh.c dh.h] + 20140313 + - (djm) Release OpenSSH 6.6 + diff --git a/sshconnect.c b/sshconnect.c -index ddc167e..4d8c718 100644 +index 394cca8..e636f33 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -1136,30 +1136,40 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) +@@ -1219,30 +1219,40 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { int flags = 0; char *fp; diff --git a/openssh-5.2p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch similarity index 74% rename from openssh-5.2p1-allow-ip-opts.patch rename to openssh-6.6p1-allow-ip-opts.patch index 96aaab1..e56d8aa 100644 --- a/openssh-5.2p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -1,7 +1,8 @@ -diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c ---- openssh-5.2p1/canohost.c.ip-opts 2009-02-14 06:28:21.000000000 +0100 -+++ openssh-5.2p1/canohost.c 2009-09-01 15:31:29.000000000 +0200 -@@ -169,12 +169,27 @@ check_ip_options(int sock, char *ipaddr) +diff --git a/canohost.c b/canohost.c +index a61a8c9..97ce58c 100644 +--- a/canohost.c ++++ b/canohost.c +@@ -165,12 +165,29 @@ check_ip_options(int sock, char *ipaddr) option_size = sizeof(options); if (getsockopt(sock, ipproto, IP_OPTIONS, options, &option_size) >= 0 && option_size != 0) { @@ -18,8 +19,12 @@ diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c + case 1: + ++i; + break; -+ case 131: -+ case 137: ++ case 130: ++ case 133: ++ case 134: ++ i += options[i + 1]; ++ break; ++ default: + /* Fail, fatally, if we detect either loose or strict + * source routing options. */ + text[0] = '\0'; @@ -28,8 +33,6 @@ diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c + " %2.2x", options[i]); + fatal("Connection from %.100s with IP options:%.800s", + ipaddr, text); -+ default: -+ i += options[i + 1]; + } + } while (i < option_size); } diff --git a/openssh-6.4p1-audit.patch b/openssh-6.6p1-audit.patch similarity index 82% rename from openssh-6.4p1-audit.patch rename to openssh-6.6p1-audit.patch index 77a6fa4..f205436 100644 --- a/openssh-6.4p1-audit.patch +++ b/openssh-6.6p1-audit.patch @@ -1,19 +1,22 @@ -diff -up openssh-6.3p1/Makefile.in.audit openssh-6.3p1/Makefile.in ---- openssh-6.3p1/Makefile.in.audit 2013-06-11 03:26:10.000000000 +0200 -+++ openssh-6.3p1/Makefile.in 2013-10-07 15:53:34.246717277 +0200 -@@ -73,7 +73,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ - kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- jpake.o schnorr.o ssh-pkcs11.o krl.o -+ jpake.o schnorr.o ssh-pkcs11.o krl.o auditstub.o +diff --git a/Makefile.in b/Makefile.in +index 2ad26ff..3bb7f00 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -82,7 +82,8 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + ssh-pkcs11.o krl.o smult_curve25519_ref.o \ + kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest-openssl.o hmac.o \ +- sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o ++ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ ++ auditstub.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ -diff -up openssh-6.3p1/audit-bsm.c.audit openssh-6.3p1/audit-bsm.c ---- openssh-6.3p1/audit-bsm.c.audit 2012-02-24 00:40:43.000000000 +0100 -+++ openssh-6.3p1/audit-bsm.c 2013-10-07 15:53:34.246717277 +0200 -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, +diff --git a/audit-bsm.c b/audit-bsm.c +index 6135591..5160869 100644 +--- a/audit-bsm.c ++++ b/audit-bsm.c +@@ -375,10 +375,23 @@ audit_connection_from(const char *host, int port) #endif } @@ -38,7 +41,7 @@ diff -up openssh-6.3p1/audit-bsm.c.audit openssh-6.3p1/audit-bsm.c } void -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li +@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) /* not implemented */ } @@ -92,9 +95,10 @@ diff -up openssh-6.3p1/audit-bsm.c.audit openssh-6.3p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-6.3p1/audit-linux.c.audit openssh-6.3p1/audit-linux.c ---- openssh-6.3p1/audit-linux.c.audit 2011-01-17 11:15:30.000000000 +0100 -+++ openssh-6.3p1/audit-linux.c 2013-10-07 15:53:34.246717277 +0200 +diff --git a/audit-linux.c b/audit-linux.c +index b3ee2f4..946f7fa 100644 +--- a/audit-linux.c ++++ b/audit-linux.c @@ -35,13 +35,24 @@ #include "log.h" @@ -123,7 +127,7 @@ diff -up openssh-6.3p1/audit-linux.c.audit openssh-6.3p1/audit-linux.c { int audit_fd, rc, saved_errno; -@@ -49,11 +60,11 @@ linux_audit_record_event(int uid, const +@@ -49,11 +60,11 @@ linux_audit_record_event(int uid, const char *username, if (audit_fd < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) @@ -138,7 +142,7 @@ diff -up openssh-6.3p1/audit-linux.c.audit openssh-6.3p1/audit-linux.c NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -65,35 +76,150 @@ linux_audit_record_event(int uid, const +@@ -65,35 +76,150 @@ linux_audit_record_event(int uid, const char *username, if ((rc == -EPERM) && (geteuid() != 0)) rc = 0; errno = saved_errno; @@ -481,9 +485,10 @@ diff -up openssh-6.3p1/audit-linux.c.audit openssh-6.3p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c ---- openssh-6.3p1/audit.c.audit 2011-01-17 11:15:30.000000000 +0100 -+++ openssh-6.3p1/audit.c 2013-10-07 15:53:34.246717277 +0200 +diff --git a/audit.c b/audit.c +index ced57fa..b806f03 100644 +--- a/audit.c ++++ b/audit.c @@ -28,6 +28,7 @@ #include @@ -561,7 +566,7 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li +@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -655,9 +660,10 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.3p1/audit.h.audit openssh-6.3p1/audit.h ---- openssh-6.3p1/audit.h.audit 2011-01-17 11:15:30.000000000 +0100 -+++ openssh-6.3p1/audit.h 2013-10-07 15:53:34.246717277 +0200 +diff --git a/audit.h b/audit.h +index 92ede5b..a2dc3ff 100644 +--- a/audit.h ++++ b/audit.h @@ -28,6 +28,7 @@ # define _SSH_AUDIT_H @@ -693,9 +699,11 @@ diff -up openssh-6.3p1/audit.h.audit openssh-6.3p1/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh-6.3p1/auditstub.c.audit openssh-6.3p1/auditstub.c ---- openssh-6.3p1/auditstub.c.audit 2013-10-07 15:53:34.247717272 +0200 -+++ openssh-6.3p1/auditstub.c 2013-10-07 15:53:34.247717272 +0200 +diff --git a/auditstub.c b/auditstub.c +new file mode 100644 +index 0000000..45817e0 +--- /dev/null ++++ b/auditstub.c @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -747,13 +755,14 @@ diff -up openssh-6.3p1/auditstub.c.audit openssh-6.3p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-6.3p1/auth-rsa.c.audit openssh-6.3p1/auth-rsa.c ---- openssh-6.3p1/auth-rsa.c.audit 2013-07-18 08:12:44.000000000 +0200 -+++ openssh-6.3p1/auth-rsa.c 2013-10-07 15:53:34.247717272 +0200 -@@ -92,7 +92,10 @@ auth_rsa_verify_response(Key *key, BIGNU +diff --git a/auth-rsa.c b/auth-rsa.c +index 5dad6c3..f225b0b 100644 +--- a/auth-rsa.c ++++ b/auth-rsa.c +@@ -93,7 +93,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) { u_char buf[32], mdbuf[16]; - MD5_CTX md; + struct ssh_digest_ctx *md; - int len; + int len, rv; +#ifdef SSH_AUDIT_EVENTS @@ -762,8 +771,8 @@ diff -up openssh-6.3p1/auth-rsa.c.audit openssh-6.3p1/auth-rsa.c /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -@@ -113,12 +116,18 @@ auth_rsa_verify_response(Key *key, BIGNU - MD5_Final(mdbuf, &md); +@@ -117,12 +120,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) + ssh_digest_free(md); /* Verify that the response is the original challenge. */ - if (timingsafe_bcmp(response, mdbuf, 16) != 0) { @@ -786,10 +795,11 @@ diff -up openssh-6.3p1/auth-rsa.c.audit openssh-6.3p1/auth-rsa.c } /* -diff -up openssh-6.3p1/auth.h.audit openssh-6.3p1/auth.h ---- openssh-6.3p1/auth.h.audit 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/auth.h 2013-10-07 16:02:38.629171107 +0200 -@@ -187,6 +187,7 @@ void abandon_challenge_response(Authctxt +diff --git a/auth.h b/auth.h +index 4605588..f9d191c 100644 +--- a/auth.h ++++ b/auth.h +@@ -186,6 +186,7 @@ void abandon_challenge_response(Authctxt *); char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -797,7 +807,7 @@ diff -up openssh-6.3p1/auth.h.audit openssh-6.3p1/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -204,6 +205,7 @@ Key *get_hostkey_private_by_type(int); +@@ -203,6 +204,7 @@ Key *get_hostkey_private_by_type(int); int get_hostkey_index(Key *); int ssh1_session_key(BIGNUM *); void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int); @@ -805,10 +815,11 @@ diff -up openssh-6.3p1/auth.h.audit openssh-6.3p1/auth.h /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-6.3p1/auth2-hostbased.c.audit openssh-6.3p1/auth2-hostbased.c ---- openssh-6.3p1/auth2-hostbased.c.audit 2013-10-07 15:53:34.223717384 +0200 -+++ openssh-6.3p1/auth2-hostbased.c 2013-10-07 15:53:34.247717272 +0200 -@@ -123,7 +123,7 @@ userauth_hostbased(Authctxt *authctxt) +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index 95d678e..48aede4 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -137,7 +137,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && @@ -817,7 +828,7 @@ diff -up openssh-6.3p1/auth2-hostbased.c.audit openssh-6.3p1/auth2-hostbased.c buffer_len(&b))) == 1) authenticated = 1; -@@ -140,6 +140,18 @@ done: +@@ -154,6 +154,18 @@ done: return authenticated; } @@ -836,10 +847,11 @@ diff -up openssh-6.3p1/auth2-hostbased.c.audit openssh-6.3p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-6.3p1/auth2-pubkey.c.audit openssh-6.3p1/auth2-pubkey.c ---- openssh-6.3p1/auth2-pubkey.c.audit 2013-10-07 15:53:34.224717379 +0200 -+++ openssh-6.3p1/auth2-pubkey.c 2013-10-08 15:11:42.282436972 +0200 -@@ -152,7 +152,7 @@ userauth_pubkey(Authctxt *authctxt) +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index cb0f931..6d1c872 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -160,7 +160,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && @@ -848,7 +860,7 @@ diff -up openssh-6.3p1/auth2-pubkey.c.audit openssh-6.3p1/auth2-pubkey.c buffer_len(&b))) == 1) authenticated = 1; buffer_free(&b); -@@ -223,6 +223,18 @@ pubkey_auth_info(Authctxt *authctxt, con +@@ -231,6 +231,18 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) free(extra); } @@ -867,10 +879,11 @@ diff -up openssh-6.3p1/auth2-pubkey.c.audit openssh-6.3p1/auth2-pubkey.c static int match_principals_option(const char *principal_list, struct KeyCert *cert) { -diff -up openssh-6.3p1/auth2.c.audit openssh-6.3p1/auth2.c ---- openssh-6.3p1/auth2.c.audit 2013-06-01 23:41:51.000000000 +0200 -+++ openssh-6.3p1/auth2.c 2013-10-07 15:53:34.248717268 +0200 -@@ -245,9 +245,6 @@ input_userauth_request(int type, u_int32 +diff --git a/auth2.c b/auth2.c +index 0f52b68..472a5b2 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); @@ -880,10 +893,11 @@ diff -up openssh-6.3p1/auth2.c.audit openssh-6.3p1/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-6.3p1/cipher.c.audit openssh-6.3p1/cipher.c ---- openssh-6.3p1/cipher.c.audit 2013-10-07 15:53:34.248717268 +0200 -+++ openssh-6.3p1/cipher.c 2013-10-07 16:06:51.117971891 +0200 -@@ -55,18 +55,6 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi +diff --git a/cipher.c b/cipher.c +index 53d9b4f..226e56d 100644 +--- a/cipher.c ++++ b/cipher.c +@@ -57,20 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_bf(void); extern const EVP_CIPHER *evp_ssh1_3des(void); extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); @@ -895,17 +909,20 @@ diff -up openssh-6.3p1/cipher.c.audit openssh-6.3p1/cipher.c - u_int iv_len; /* defaults to block_size */ - u_int auth_len; - u_int discard_len; -- u_int cbc_mode; +- u_int flags; +-#define CFLAG_CBC (1<<0) +-#define CFLAG_CHACHAPOLY (1<<1) - const EVP_CIPHER *(*evptype)(void); -}; - static const struct Cipher ciphers[] = { { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-6.3p1/cipher.h.audit openssh-6.3p1/cipher.h ---- openssh-6.3p1/cipher.h.audit 2013-04-23 11:24:32.000000000 +0200 -+++ openssh-6.3p1/cipher.h 2013-10-07 15:53:34.248717268 +0200 -@@ -61,7 +61,18 @@ +diff --git a/cipher.h b/cipher.h +index 133d2e7..d41758e 100644 +--- a/cipher.h ++++ b/cipher.h +@@ -63,7 +63,20 @@ typedef struct Cipher Cipher; typedef struct CipherContext CipherContext; @@ -918,25 +935,28 @@ diff -up openssh-6.3p1/cipher.h.audit openssh-6.3p1/cipher.h + u_int iv_len; /* defaults to block_size */ + u_int auth_len; + u_int discard_len; -+ u_int cbc_mode; ++ u_int flags; ++#define CFLAG_CBC (1<<0) ++#define CFLAG_CHACHAPOLY (1<<1) + const EVP_CIPHER *(*evptype)(void); +}; + struct CipherContext { int plaintext; int encrypt; -diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c ---- openssh-6.3p1/kex.c.audit 2013-06-01 23:31:18.000000000 +0200 -+++ openssh-6.3p1/kex.c 2013-10-07 15:53:34.249717264 +0200 -@@ -49,6 +49,7 @@ - #include "dispatch.h" +diff --git a/kex.c b/kex.c +index bce2ab8..bc3e53e 100644 +--- a/kex.c ++++ b/kex.c +@@ -50,6 +50,7 @@ #include "monitor.h" #include "roaming.h" + #include "digest.h" +#include "audit.h" - #if OPENSSL_VERSION_NUMBER >= 0x00907000L - # if defined(HAVE_EVP_SHA256) -@@ -341,9 +342,13 @@ static void + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -366,9 +367,13 @@ static void choose_enc(Enc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -951,7 +971,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) fatal("matching cipher is not supported: %s", name); enc->name = name; -@@ -359,9 +364,13 @@ static void +@@ -384,9 +389,13 @@ static void choose_mac(Mac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -966,7 +986,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c if (mac_setup(mac, name) < 0) fatal("unsupported mac %s", name); /* truncate the key */ -@@ -376,8 +385,12 @@ static void +@@ -401,8 +410,12 @@ static void choose_comp(Comp *comp, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -980,7 +1000,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -492,6 +505,9 @@ kex_choose_conf(Kex *kex) +@@ -517,6 +530,9 @@ kex_choose_conf(Kex *kex) newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); @@ -990,7 +1010,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c } choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], -@@ -656,3 +672,34 @@ dump_digest(char *msg, u_char *digest, i +@@ -702,3 +718,34 @@ dump_digest(char *msg, u_char *digest, int len) fprintf(stderr, "\n"); } #endif @@ -1025,22 +1045,24 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} + -diff -up openssh-6.3p1/kex.h.audit openssh-6.3p1/kex.h ---- openssh-6.3p1/kex.h.audit 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/kex.h 2013-10-07 15:53:34.249717264 +0200 -@@ -162,6 +162,8 @@ void kexgex_server(Kex *); - void kexecdh_client(Kex *); - void kexecdh_server(Kex *); +diff --git a/kex.h b/kex.h +index 313bb51..c643250 100644 +--- a/kex.h ++++ b/kex.h +@@ -182,6 +182,8 @@ void kexgss_client(Kex *); + void kexgss_server(Kex *); + #endif +void newkeys_destroy(Newkeys *newkeys); + void kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); -diff -up openssh-6.3p1/key.c.audit openssh-6.3p1/key.c ---- openssh-6.3p1/key.c.audit 2013-10-07 15:53:34.224717379 +0200 -+++ openssh-6.3p1/key.c 2013-10-07 15:53:34.249717264 +0200 -@@ -1773,6 +1773,30 @@ key_demote(const Key *k) +diff --git a/key.c b/key.c +index 900b9e3..62f3edb 100644 +--- a/key.c ++++ b/key.c +@@ -1925,6 +1925,33 @@ key_demote(const Key *k) } int @@ -1061,6 +1083,9 @@ diff -up openssh-6.3p1/key.c.audit openssh-6.3p1/key.c + case KEY_ECDSA: + return EC_KEY_get0_private_key(k->ecdsa) != NULL; +#endif ++ case KEY_ED25519_CERT: ++ case KEY_ED25519: ++ return (k->ed25519_pk != NULL); + default: + fatal("key_is_private: bad key type %d", k->type); + return 1; @@ -1071,21 +1096,23 @@ diff -up openssh-6.3p1/key.c.audit openssh-6.3p1/key.c key_is_cert(const Key *k) { if (k == NULL) -diff -up openssh-6.3p1/key.h.audit openssh-6.3p1/key.h ---- openssh-6.3p1/key.h.audit 2013-10-07 15:53:34.224717379 +0200 -+++ openssh-6.3p1/key.h 2013-10-07 15:53:34.249717264 +0200 -@@ -110,6 +110,7 @@ Key *key_generate(int, u_int); +diff --git a/key.h b/key.h +index d51ed81..8f61605 100644 +--- a/key.h ++++ b/key.h +@@ -118,6 +118,7 @@ Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_type_from_name(char *); int key_is_cert(const Key *); +int key_is_private(const Key *k); + int key_type_is_cert(int); int key_type_plain(int); int key_to_certified(Key *, int); - int key_drop_cert(Key *); -diff -up openssh-6.3p1/mac.c.audit openssh-6.3p1/mac.c ---- openssh-6.3p1/mac.c.audit 2013-06-06 00:12:37.000000000 +0200 -+++ openssh-6.3p1/mac.c 2013-10-07 15:53:34.250717259 +0200 -@@ -224,6 +224,20 @@ mac_clear(Mac *mac) +diff --git a/mac.c b/mac.c +index 0977572..9388af4 100644 +--- a/mac.c ++++ b/mac.c +@@ -222,6 +222,20 @@ mac_clear(Mac *mac) mac->umac_ctx = NULL; } @@ -1106,26 +1133,28 @@ diff -up openssh-6.3p1/mac.c.audit openssh-6.3p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-6.3p1/mac.h.audit openssh-6.3p1/mac.h ---- openssh-6.3p1/mac.h.audit 2013-04-23 11:24:32.000000000 +0200 -+++ openssh-6.3p1/mac.h 2013-10-07 15:53:34.250717259 +0200 +diff --git a/mac.h b/mac.h +index fbe18c4..7dc7f43 100644 +--- a/mac.h ++++ b/mac.h @@ -29,3 +29,4 @@ int mac_setup(Mac *, char *); int mac_init(Mac *); u_char *mac_compute(Mac *, u_int32_t, u_char *, int); void mac_clear(Mac *); +void mac_destroy(Mac *); -diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c ---- openssh-6.3p1/monitor.c.audit 2013-10-07 15:53:34.217717411 +0200 -+++ openssh-6.3p1/monitor.c 2013-10-08 15:10:38.270726936 +0200 -@@ -98,6 +98,7 @@ - #include "jpake.h" +diff --git a/monitor.c b/monitor.c +index aa70945..bdabe21 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -97,6 +97,7 @@ + #include "ssh2.h" #include "roaming.h" #include "authfd.h" +#include "audit.h" #ifdef GSSAPI static Gssctxt *gsscontext = NULL; -@@ -114,6 +115,8 @@ extern Buffer auth_debug; +@@ -113,6 +114,8 @@ extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; @@ -1134,7 +1163,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c /* State exported from the child */ struct { -@@ -186,6 +189,11 @@ int mm_answer_gss_checkmic(int, Buffer * +@@ -185,6 +188,11 @@ int mm_answer_gss_updatecreds(int, Buffer *); #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); @@ -1146,7 +1175,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c #endif static int monitor_read_log(struct monitor *); -@@ -237,6 +245,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -239,6 +247,10 @@ struct mon_table mon_dispatch_proto20[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1157,7 +1186,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -273,6 +285,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -274,6 +286,11 @@ struct mon_table mon_dispatch_postauth20[] = { #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1169,7 +1198,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -304,6 +321,10 @@ struct mon_table mon_dispatch_proto15[] +@@ -305,6 +322,10 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1180,7 +1209,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -315,6 +336,11 @@ struct mon_table mon_dispatch_postauth15 +@@ -316,6 +337,11 @@ struct mon_table mon_dispatch_postauth15[] = { #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, @@ -1192,7 +1221,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -1365,9 +1391,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1390,9 +1416,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1204,7 +1233,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1375,6 +1403,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1400,6 +1428,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1213,7 +1242,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1395,7 +1425,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1420,7 +1450,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1232,7 +1261,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1448,6 +1488,12 @@ mm_session_close(Session *s) +@@ -1473,6 +1513,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1245,7 +1274,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c session_unused(s->self); } -@@ -1728,6 +1774,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1753,6 +1799,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1254,7 +1283,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1770,11 +1818,43 @@ mm_answer_audit_command(int socket, Buff +@@ -1795,11 +1843,43 @@ mm_answer_audit_command(int socket, Buffer *m) { u_int len; char *cmd; @@ -1299,7 +1328,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c free(cmd); return (0); } -@@ -1910,11 +1990,13 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1943,11 +2023,13 @@ mm_get_keystate(struct monitor *pmonitor) blob = buffer_get_string(&m, &bloblen); current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); @@ -1313,7 +1342,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c free(blob); /* Now get sequence numbers for the packets */ -@@ -1960,6 +2042,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1993,6 +2075,21 @@ mm_get_keystate(struct monitor *pmonitor) } buffer_free(&m); @@ -1335,11 +1364,10 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c } -@@ -2361,3 +2458,86 @@ mm_answer_jpake_check_confirm(int sock, - } +@@ -2274,3 +2371,85 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) { + + #endif /* GSSAPI */ - #endif /* JPAKE */ -+ +#ifdef SSH_AUDIT_EVENTS +int +mm_answer_audit_unsupported_body(int sock, Buffer *m) @@ -1422,10 +1450,11 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.3p1/monitor.h.audit openssh-6.3p1/monitor.h ---- openssh-6.3p1/monitor.h.audit 2012-12-02 23:53:21.000000000 +0100 -+++ openssh-6.3p1/monitor.h 2013-10-07 15:53:34.251717254 +0200 -@@ -68,7 +68,13 @@ enum monitor_reqtype { +diff --git a/monitor.h b/monitor.h +index ff79fbb..6dfb234 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, @@ -1440,10 +1469,11 @@ diff -up openssh-6.3p1/monitor.h.audit openssh-6.3p1/monitor.h }; -diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c ---- openssh-6.4p1/monitor_wrap.c.audit 2013-11-08 13:26:47.062595006 +0100 -+++ openssh-6.4p1/monitor_wrap.c 2013-11-08 13:26:47.089594877 +0100 -@@ -433,7 +433,7 @@ mm_key_allowed(enum mm_keytype type, cha +diff --git a/monitor_wrap.c b/monitor_wrap.c +index d1e1caa..6df236a 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -450,7 +450,7 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) */ int @@ -1452,7 +1482,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c { Buffer m; u_char *blob; -@@ -447,6 +447,7 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -464,6 +464,7 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) return (0); buffer_init(&m); @@ -1460,7 +1490,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -464,6 +465,19 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -481,6 +482,19 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) return (verified); } @@ -1480,7 +1510,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c /* Export key state after authentication */ Newkeys * mm_newkeys_from_blob(u_char *blob, int blen) -@@ -642,12 +656,14 @@ mm_send_keystate(struct monitor *monitor +@@ -659,12 +673,14 @@ mm_send_keystate(struct monitor *monitor) fatal("%s: conversion of newkeys failed", __func__); buffer_put_string(&m, blob, bloblen); @@ -1495,7 +1525,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c free(blob); packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); -@@ -1191,10 +1207,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -1208,10 +1224,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1508,7 +1538,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -1202,6 +1219,26 @@ mm_audit_run_command(const char *command +@@ -1219,6 +1236,26 @@ mm_audit_run_command(const char *command) buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1535,11 +1565,10 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1453,3 +1490,72 @@ mm_jpake_check_confirm(const BIGNUM *k, - return success; - } - #endif /* JPAKE */ -+ +@@ -1354,3 +1391,71 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) + + #endif /* GSSAPI */ + +#ifdef SSH_AUDIT_EVENTS +void +mm_audit_unsupported_body(int what) @@ -1608,10 +1637,11 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.3p1/monitor_wrap.h.audit openssh-6.3p1/monitor_wrap.h ---- openssh-6.3p1/monitor_wrap.h.audit 2011-06-20 06:42:23.000000000 +0200 -+++ openssh-6.3p1/monitor_wrap.h 2013-10-07 15:53:34.252717250 +0200 -@@ -49,7 +49,8 @@ int mm_key_allowed(enum mm_keytype, char +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 93929e0..4cf0c78 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char *, char *, Key *); int mm_user_key_allowed(struct passwd *, Key *); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); @@ -1621,7 +1651,7 @@ diff -up openssh-6.3p1/monitor_wrap.h.audit openssh-6.3p1/monitor_wrap.h int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); BIGNUM *mm_auth_rsa_generate_challenge(Key *); -@@ -74,7 +75,12 @@ void mm_sshpam_free_ctx(void *); +@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); @@ -1635,9 +1665,10 @@ diff -up openssh-6.3p1/monitor_wrap.h.audit openssh-6.3p1/monitor_wrap.h #endif struct Session; -diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c ---- openssh-6.3p1/packet.c.audit 2013-10-07 15:53:34.231717347 +0200 -+++ openssh-6.3p1/packet.c 2013-10-07 16:08:00.764639577 +0200 +diff --git a/packet.c b/packet.c +index 660a9fc..f5b122b 100644 +--- a/packet.c ++++ b/packet.c @@ -61,6 +61,7 @@ #include @@ -1695,7 +1726,7 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c } /* Sets remote side protocol flags. */ -@@ -735,6 +746,25 @@ packet_send1(void) +@@ -736,6 +747,25 @@ packet_send1(void) */ } @@ -1721,31 +1752,15 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c void set_newkeys(int mode) { -@@ -760,21 +790,9 @@ set_newkeys(int mode) +@@ -761,6 +791,7 @@ set_newkeys(int mode) } if (active_state->newkeys[mode] != NULL) { debug("set_newkeys: rekeying"); + audit_session_key_free(mode); cipher_cleanup(cc); -- enc = &active_state->newkeys[mode]->enc; -- mac = &active_state->newkeys[mode]->mac; -- comp = &active_state->newkeys[mode]->comp; -- mac_clear(mac); -- memset(enc->iv, 0, enc->iv_len); -- memset(enc->key, 0, enc->key_len); -- memset(mac->key, 0, mac->key_len); -- free(enc->name); -- free(enc->iv); -- free(enc->key); -- free(mac->name); -- free(mac->key); -- free(comp->name); -- free(active_state->newkeys[mode]); -+ newkeys_destroy_and_free(active_state->newkeys[mode]); - } - active_state->newkeys[mode] = kex_get_newkeys(mode); - if (active_state->newkeys[mode] == NULL) -@@ -2003,6 +2021,47 @@ packet_get_newkeys(int mode) + enc = &active_state->newkeys[mode]->enc; + mac = &active_state->newkeys[mode]->mac; +@@ -2011,6 +2042,47 @@ packet_get_newkeys(int mode) return (void *)active_state->newkeys[mode]; } @@ -1793,7 +1808,7 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c /* * Save the state for the real connection, and use a separate state when * resuming a suspended connection. -@@ -2010,18 +2069,12 @@ packet_get_newkeys(int mode) +@@ -2018,18 +2090,12 @@ packet_get_newkeys(int mode) void packet_backup_state(void) { @@ -1813,7 +1828,7 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c } /* -@@ -2038,9 +2091,7 @@ packet_restore_state(void) +@@ -2046,9 +2112,7 @@ packet_restore_state(void) backup_state = active_state; active_state = tmp; active_state->connection_in = backup_state->connection_in; @@ -1823,7 +1838,7 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c len = buffer_len(&backup_state->input); if (len > 0) { buf = buffer_ptr(&backup_state->input); -@@ -2048,4 +2099,10 @@ packet_restore_state(void) +@@ -2056,4 +2120,10 @@ packet_restore_state(void) buffer_clear(&backup_state->input); add_recv_bytes(len); } @@ -1834,18 +1849,20 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c + backup_state = NULL; } + -diff -up openssh-6.3p1/packet.h.audit openssh-6.3p1/packet.h ---- openssh-6.3p1/packet.h.audit 2013-07-18 08:12:45.000000000 +0200 -+++ openssh-6.3p1/packet.h 2013-10-07 15:53:34.252717250 +0200 +diff --git a/packet.h b/packet.h +index f8edf85..c36c812 100644 +--- a/packet.h ++++ b/packet.h @@ -124,4 +124,5 @@ void packet_restore_state(void); void *packet_get_input(void); void *packet_get_output(void); +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c ---- openssh-6.3p1/session.c.audit 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/session.c 2013-10-07 16:03:43.975861636 +0200 +diff --git a/session.c b/session.c +index ba4589b..4a297f1 100644 +--- a/session.c ++++ b/session.c @@ -137,7 +137,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; @@ -1855,7 +1872,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c extern Buffer loginmsg; /* original command from peer. */ -@@ -745,6 +745,14 @@ do_exec_pty(Session *s, const char *comm +@@ -745,6 +745,14 @@ do_exec_pty(Session *s, const char *command) /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1870,8 +1887,8 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -816,15 +824,19 @@ do_exec(Session *s, const char *command) - } +@@ -862,15 +870,19 @@ do_exec(Session *s, const char *command) + get_remote_port()); #ifdef SSH_AUDIT_EVENTS + if (s->command != NULL || s->command_handle != -1) @@ -1892,7 +1909,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1642,7 +1654,10 @@ do_child(Session *s, const char *command +@@ -1707,7 +1719,10 @@ do_child(Session *s, const char *command) int r = 0; /* remove hostkey from the child's memory */ @@ -1904,7 +1921,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1869,6 +1884,7 @@ session_unused(int id) +@@ -1931,6 +1946,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1912,7 +1929,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1951,6 +1967,19 @@ session_open(Authctxt *authctxt, int cha +@@ -2013,6 +2029,19 @@ session_open(Authctxt *authctxt, int chanid) } Session * @@ -1932,7 +1949,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c session_by_tty(char *tty) { int i; -@@ -2467,6 +2496,30 @@ session_exit_message(Session *s, int sta +@@ -2529,6 +2558,30 @@ session_exit_message(Session *s, int status) chan_write_failed(c); } @@ -1963,7 +1980,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c void session_close(Session *s) { -@@ -2475,6 +2528,10 @@ session_close(Session *s) +@@ -2537,6 +2590,10 @@ session_close(Session *s) debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1974,7 +1991,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2688,6 +2745,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2751,6 +2808,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -1990,17 +2007,18 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c void do_cleanup(Authctxt *authctxt) { -@@ -2736,5 +2802,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2799,5 +2865,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff -up openssh-6.3p1/session.h.audit openssh-6.3p1/session.h ---- openssh-6.3p1/session.h.audit 2008-05-19 07:34:50.000000000 +0200 -+++ openssh-6.3p1/session.h 2013-10-07 15:53:34.253717245 +0200 -@@ -60,6 +60,12 @@ struct Session { +diff --git a/session.h b/session.h +index 6a2f35e..e9b312e 100644 +--- a/session.h ++++ b/session.h +@@ -61,6 +61,12 @@ struct Session { char *name; char *val; } *env; @@ -2013,7 +2031,7 @@ diff -up openssh-6.3p1/session.h.audit openssh-6.3p1/session.h }; void do_authenticated(Authctxt *); -@@ -72,8 +78,10 @@ void session_close_by_pid(pid_t, int); +@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); void session_destroy_all(void (*)(Session *)); void session_pty_cleanup2(Session *); @@ -2024,9 +2042,10 @@ diff -up openssh-6.3p1/session.h.audit openssh-6.3p1/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.audit 2013-10-07 15:53:34.221717393 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-07 15:53:34.254717240 +0200 +diff --git a/sshd.c b/sshd.c +index 512c7ed..b561ec8 100644 +--- a/sshd.c ++++ b/sshd.c @@ -119,6 +119,7 @@ #endif #include "monitor_wrap.h" @@ -2035,7 +2054,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c #include "ssh-sandbox.h" #include "version.h" -@@ -260,7 +261,7 @@ Buffer loginmsg; +@@ -264,7 +265,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2044,7 +2063,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c void demote_sensitive_data(void); static void do_ssh1_kex(void); -@@ -279,6 +280,15 @@ close_listen_socks(void) +@@ -283,6 +284,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2060,7 +2079,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c static void close_startup_pipes(void) { -@@ -550,22 +560,47 @@ sshd_exchange_identification(int sock_in +@@ -562,22 +572,45 @@ sshd_exchange_identification(int sock_in, int sock_out) } } @@ -2088,9 +2107,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c + char *fp; + + if (key_is_private(sensitive_data.host_keys[i])) -+ fp = key_fingerprint(sensitive_data.host_keys[i], -+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, -+ SSH_FP_HEX); ++ fp = key_selected_fingerprint(sensitive_data.host_keys[i], SSH_FP_HEX); + else + fp = NULL; key_free(sensitive_data.host_keys[i]); @@ -2111,7 +2128,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -579,6 +614,8 @@ void +@@ -591,6 +624,8 @@ void demote_sensitive_data(void) { Key *tmp; @@ -2120,7 +2137,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c int i; if (sensitive_data.server_key) { -@@ -587,13 +624,27 @@ demote_sensitive_data(void) +@@ -599,13 +634,25 @@ demote_sensitive_data(void) sensitive_data.server_key = tmp; } @@ -2131,9 +2148,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c + char *fp; + + if (key_is_private(sensitive_data.host_keys[i])) -+ fp = key_fingerprint(sensitive_data.host_keys[i], -+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, -+ SSH_FP_HEX); ++ fp = key_selected_fingerprint(sensitive_data.host_keys[i], SSH_FP_HEX); + else + fp = NULL; tmp = key_demote(sensitive_data.host_keys[i]); @@ -2148,16 +2163,16 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c } /* Certs do not need demotion */ } -@@ -652,7 +703,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) - box = ssh_sandbox_init(); + box = ssh_sandbox_init(pmonitor); - pid = fork(); + pmonitor->m_pid = pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -708,6 +759,8 @@ privsep_preauth(Authctxt *authctxt) +@@ -729,6 +776,8 @@ privsep_preauth(Authctxt *authctxt) } } @@ -2166,7 +2181,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c static void privsep_postauth(Authctxt *authctxt) { -@@ -732,6 +785,10 @@ privsep_postauth(Authctxt *authctxt) +@@ -753,6 +802,10 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); @@ -2177,7 +2192,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1178,6 +1235,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1211,6 +1264,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2185,7 +2200,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c close_listen_socks(); unlink(options.pid_file); exit(received_sigterm == SIGTERM ? 0 : 255); -@@ -2093,6 +2151,7 @@ main(int ac, char **av) +@@ -2134,6 +2188,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2193,7 +2208,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c exit(0); } -@@ -2135,7 +2194,7 @@ main(int ac, char **av) +@@ -2179,7 +2234,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2202,7 +2217,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c } packet_set_timeout(options.client_alive_interval, -@@ -2145,6 +2204,9 @@ main(int ac, char **av) +@@ -2189,6 +2244,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2212,7 +2227,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); verbose("Transferred: sent %llu, received %llu bytes", -@@ -2302,6 +2364,10 @@ do_ssh1_kex(void) +@@ -2346,6 +2404,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); @@ -2223,7 +2238,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2368,7 +2434,7 @@ do_ssh1_kex(void) +@@ -2418,7 +2480,7 @@ do_ssh1_kex(void) session_id[i] = session_key[i] ^ session_key[i + 16]; } /* Destroy the private and public keys. No longer. */ @@ -2232,7 +2247,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2480,6 +2546,16 @@ do_ssh2_kex(void) +@@ -2584,6 +2646,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2249,7 +2264,7 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) { -@@ -2490,9 +2566,14 @@ cleanup_exit(int i) +@@ -2594,9 +2666,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } diff --git a/openssh-6.3p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch similarity index 90% rename from openssh-6.3p1-ctr-cavstest.patch rename to openssh-6.6p1-ctr-cavstest.patch index 5cd9997..1997fa6 100644 --- a/openssh-6.3p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -1,6 +1,47 @@ -diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c ---- openssh-6.2p1/ctr-cavstest.c.ctr-cavs 2013-03-25 21:35:52.512586671 +0100 -+++ openssh-6.2p1/ctr-cavstest.c 2013-03-25 21:35:52.512586671 +0100 +diff --git a/Makefile.in b/Makefile.in +index 4ab6717..581b121 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign + SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper + SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + SSH_KEYCAT=$(libexecdir)/ssh-keycat ++CTR_CAVSTEST=$(libexecdir)/ctr-cavstest + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + PRIVSEP_PATH=@PRIVSEP_PATH@ + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ + MANFMT=@MANFMT@ + INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ + +-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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) + + LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o \ +@@ -180,6 +181,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o + ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) + ++ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o ++ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) ++ + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o + $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + +@@ -288,6 +292,7 @@ install-files: + $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ + fi + $(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 --git a/ctr-cavstest.c b/ctr-cavstest.c +new file mode 100644 +index 0000000..bbcbe8a +--- /dev/null ++++ b/ctr-cavstest.c @@ -0,0 +1,208 @@ +/* + * @@ -103,7 +144,7 @@ diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c +int main (int argc, char *argv[]) +{ + -+ Cipher *c; ++ const Cipher *c; + CipherContext cc; + char *algo = "aes128-ctr"; + char *hexkey = NULL; @@ -194,7 +235,7 @@ diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c + return 2; + } + -+ cipher_crypt(&cc, outdata, data, datalen, 0, 0); ++ cipher_crypt(&cc, 0, outdata, data, datalen, 0, 0); + + free(data); + @@ -210,41 +251,3 @@ diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c + return 0; +} + -diff -up openssh-6.2p1/Makefile.in.ctr-cavs openssh-6.2p1/Makefile.in ---- openssh-6.2p1/Makefile.in.ctr-cavs 2013-03-25 21:35:52.451586280 +0100 -+++ openssh-6.2p1/Makefile.in 2013-03-25 21:37:14.956114584 +0100 -@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign - SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_KEYCAT=$(libexecdir)/ssh-keycat -+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ - INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ - --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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) - - LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ -@@ -174,6 +175,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l - ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keycat.o - $(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS) - -+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o -+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - -@@ -281,6 +285,7 @@ install-files: - $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ - fi - $(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 --git a/openssh-6.2p1-entropy.patch b/openssh-6.6p1-entropy.patch similarity index 70% rename from openssh-6.2p1-entropy.patch rename to openssh-6.6p1-entropy.patch index 4553422..67bd30f 100644 --- a/openssh-6.2p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -1,7 +1,8 @@ -diff -up openssh-6.2p1/entropy.c.entropy openssh-6.2p1/entropy.c ---- openssh-6.2p1/entropy.c.entropy 2013-03-25 19:31:42.737611051 +0100 -+++ openssh-6.2p1/entropy.c 2013-03-25 19:31:42.797611433 +0100 -@@ -237,6 +237,9 @@ seed_rng(void) +diff --git a/entropy.c b/entropy.c +index 2d483b3..b361a04 100644 +--- a/entropy.c ++++ b/entropy.c +@@ -234,6 +234,9 @@ seed_rng(void) memset(buf, '\0', sizeof(buf)); #endif /* OPENSSL_PRNG_ONLY */ @@ -11,21 +12,24 @@ diff -up openssh-6.2p1/entropy.c.entropy openssh-6.2p1/entropy.c if (RAND_status() != 1) fatal("PRNG is not seeded"); } -diff -up openssh-6.2p1/openbsd-compat/Makefile.in.entropy openssh-6.2p1/openbsd-compat/Makefile.in ---- openssh-6.2p1/openbsd-compat/Makefile.in.entropy 2013-03-25 19:31:42.798611440 +0100 -+++ openssh-6.2p1/openbsd-compat/Makefile.in 2013-03-25 19:33:02.042116876 +0100 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport +diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in +index b912dbe..9206337 100644 +--- a/openbsd-compat/Makefile.in ++++ b/openbsd-compat/Makefile.in +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o --PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o +-PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o ++PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.2p1/openbsd-compat/port-linux-prng.c ---- openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy 2013-03-25 19:31:42.798611440 +0100 -+++ openssh-6.2p1/openbsd-compat/port-linux-prng.c 2013-03-25 19:31:42.798611440 +0100 +diff --git a/openbsd-compat/port-linux-prng.c b/openbsd-compat/port-linux-prng.c +new file mode 100644 +index 0000000..92a617c +--- /dev/null ++++ b/openbsd-compat/port-linux-prng.c @@ -0,0 +1,59 @@ +/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ + @@ -86,9 +90,10 @@ diff -up openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.2p1/op + fatal ("EOF reading %s", random); + } +} -diff -up openssh-6.2p1/ssh-add.0.entropy openssh-6.2p1/ssh-add.0 ---- openssh-6.2p1/ssh-add.0.entropy 2013-03-22 00:38:29.000000000 +0100 -+++ openssh-6.2p1/ssh-add.0 2013-03-25 19:31:42.799611446 +0100 +diff --git a/ssh-add.0 b/ssh-add.0 +index ba43fee..0b2629a 100644 +--- a/ssh-add.0 ++++ b/ssh-add.0 @@ -82,6 +82,16 @@ ENVIRONMENT Identifies the path of a UNIX-domain socket used to communicate with the agent. @@ -106,10 +111,11 @@ diff -up openssh-6.2p1/ssh-add.0.entropy openssh-6.2p1/ssh-add.0 FILES ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of -diff -up openssh-6.2p1/ssh-add.1.entropy openssh-6.2p1/ssh-add.1 ---- openssh-6.2p1/ssh-add.1.entropy 2012-12-07 03:06:13.000000000 +0100 -+++ openssh-6.2p1/ssh-add.1 2013-03-25 19:31:42.799611446 +0100 -@@ -160,6 +160,20 @@ to make this work.) +diff --git a/ssh-add.1 b/ssh-add.1 +index 4812448..16305bf 100644 +--- a/ssh-add.1 ++++ b/ssh-add.1 +@@ -161,6 +161,20 @@ to make this work.) Identifies the path of a .Ux Ns -domain socket used to communicate with the agent. @@ -130,10 +136,11 @@ diff -up openssh-6.2p1/ssh-add.1.entropy openssh-6.2p1/ssh-add.1 .El .Sh FILES .Bl -tag -width Ds -diff -up openssh-6.2p1/ssh-agent.1.entropy openssh-6.2p1/ssh-agent.1 ---- openssh-6.2p1/ssh-agent.1.entropy 2010-12-01 01:50:35.000000000 +0100 -+++ openssh-6.2p1/ssh-agent.1 2013-03-25 19:31:42.800611452 +0100 -@@ -198,6 +198,24 @@ sockets used to contain the connection t +diff --git a/ssh-agent.1 b/ssh-agent.1 +index 281ecbd..1a9a635 100644 +--- a/ssh-agent.1 ++++ b/ssh-agent.1 +@@ -201,6 +201,24 @@ sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El @@ -158,38 +165,11 @@ diff -up openssh-6.2p1/ssh-agent.1.entropy openssh-6.2p1/ssh-agent.1 .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , -diff -up openssh-6.2p1/sshd.8.entropy openssh-6.2p1/sshd.8 ---- openssh-6.2p1/sshd.8.entropy 2013-03-25 19:31:42.752611146 +0100 -+++ openssh-6.2p1/sshd.8 2013-03-25 19:31:42.800611452 +0100 -@@ -945,6 +945,24 @@ concurrently for different ports, this c - started last). - The content of this file is not sensitive; it can be world-readable. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh IPV6 - IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO -diff -up openssh-6.2p1/ssh-keygen.1.entropy openssh-6.2p1/ssh-keygen.1 ---- openssh-6.2p1/ssh-keygen.1.entropy 2013-01-20 12:35:06.000000000 +0100 -+++ openssh-6.2p1/ssh-keygen.1 2013-03-25 19:31:42.801611459 +0100 -@@ -806,6 +806,24 @@ Contains Diffie-Hellman groups used for +diff --git a/ssh-keygen.1 b/ssh-keygen.1 +index 12e00d4..1b51a4a 100644 +--- a/ssh-keygen.1 ++++ b/ssh-keygen.1 +@@ -832,6 +832,24 @@ Contains Diffie-Hellman groups used for DH-GEX. The file format is described in .Xr moduli 5 . .El @@ -214,10 +194,11 @@ diff -up openssh-6.2p1/ssh-keygen.1.entropy openssh-6.2p1/ssh-keygen.1 .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , -diff -up openssh-6.2p1/ssh-keysign.8.entropy openssh-6.2p1/ssh-keysign.8 ---- openssh-6.2p1/ssh-keysign.8.entropy 2010-08-31 14:41:14.000000000 +0200 -+++ openssh-6.2p1/ssh-keysign.8 2013-03-25 19:31:42.801611459 +0100 -@@ -78,6 +78,24 @@ must be set-uid root if host-based authe +diff --git a/ssh-keysign.8 b/ssh-keysign.8 +index 69d0829..02d79f8 100644 +--- a/ssh-keysign.8 ++++ b/ssh-keysign.8 +@@ -80,6 +80,24 @@ must be set-uid root if host-based authentication is used. If these files exist they are assumed to contain public certificate information corresponding with the private keys above. .El @@ -242,10 +223,11 @@ diff -up openssh-6.2p1/ssh-keysign.8.entropy openssh-6.2p1/ssh-keysign.8 .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-keygen 1 , -diff -up openssh-6.2p1/ssh.1.entropy openssh-6.2p1/ssh.1 ---- openssh-6.2p1/ssh.1.entropy 2013-03-25 19:31:42.752611146 +0100 -+++ openssh-6.2p1/ssh.1 2013-03-25 19:31:42.799611446 +0100 -@@ -1277,6 +1277,23 @@ For more information, see the +diff --git a/ssh.1 b/ssh.1 +index 929904b..f65e42f 100644 +--- a/ssh.1 ++++ b/ssh.1 +@@ -1309,6 +1309,23 @@ For more information, see the .Cm PermitUserEnvironment option in .Xr sshd_config 5 . @@ -269,3 +251,32 @@ diff -up openssh-6.2p1/ssh.1.entropy openssh-6.2p1/ssh.1 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.rhosts +diff --git a/sshd.8 b/sshd.8 +index c2c237f..058d37a 100644 +--- a/sshd.8 ++++ b/sshd.8 +@@ -951,6 +951,24 @@ concurrently for different ports, this contains the process ID of the one + started last). + The content of this file is not sensitive; it can be world-readable. + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 14 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh IPV6 + IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO diff --git a/openssh-6.3p1-fingerprint.patch b/openssh-6.6p1-fingerprint.patch similarity index 78% rename from openssh-6.3p1-fingerprint.patch rename to openssh-6.6p1-fingerprint.patch index b9cfbdb..c5332fb 100644 --- a/openssh-6.3p1-fingerprint.patch +++ b/openssh-6.6p1-fingerprint.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.3p1/auth-rsa.c.fingerprint openssh-6.3p1/auth-rsa.c -diff -up openssh-6.3p1/auth.c.fingerprint openssh-6.3p1/auth.c ---- openssh-6.3p1/auth.c.fingerprint 2013-10-07 14:02:36.998968153 +0200 -+++ openssh-6.3p1/auth.c 2013-10-07 15:42:05.243812405 +0200 +diff --git a/auth.c b/auth.c +index 9a36f1d..420a85b 100644 +--- a/auth.c ++++ b/auth.c @@ -685,9 +685,10 @@ auth_key_is_revoked(Key *key) case 1: revoked: @@ -15,10 +15,11 @@ diff -up openssh-6.3p1/auth.c.fingerprint openssh-6.3p1/auth.c free(key_fp); return 1; } -diff -up openssh-6.3p1/auth2-hostbased.c.fingerprint openssh-6.3p1/auth2-hostbased.c ---- openssh-6.3p1/auth2-hostbased.c.fingerprint 2013-10-07 14:02:36.998968153 +0200 -+++ openssh-6.3p1/auth2-hostbased.c 2013-10-07 15:43:49.747355927 +0200 -@@ -200,16 +200,18 @@ hostbased_key_allowed(struct passwd *pw, +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index 488008f..eca0069 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -206,16 +206,18 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, if (host_status == HOST_OK) { if (key_is_cert(key)) { @@ -44,10 +45,11 @@ diff -up openssh-6.3p1/auth2-hostbased.c.fingerprint openssh-6.3p1/auth2-hostbas } free(fp); } -diff -up openssh-6.3p1/auth2-pubkey.c.fingerprint openssh-6.3p1/auth2-pubkey.c ---- openssh-6.3p1/auth2-pubkey.c.fingerprint 2013-07-18 08:10:10.000000000 +0200 -+++ openssh-6.3p1/auth2-pubkey.c 2013-10-07 15:50:44.617495624 +0200 -@@ -359,10 +359,10 @@ check_authkeys_file(FILE *f, char *file, +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 0fd27bb..749b11a 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -365,10 +365,10 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (!key_is_cert_authority) continue; @@ -62,7 +64,7 @@ diff -up openssh-6.3p1/auth2-pubkey.c.fingerprint openssh-6.3p1/auth2-pubkey.c /* * If the user has specified a list of principals as * a key option, then prefer that list to matching -@@ -400,9 +400,9 @@ check_authkeys_file(FILE *f, char *file, +@@ -406,9 +406,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) if (key_is_cert_authority) continue; found_key = 1; @@ -75,7 +77,7 @@ diff -up openssh-6.3p1/auth2-pubkey.c.fingerprint openssh-6.3p1/auth2-pubkey.c free(fp); break; } -@@ -425,13 +425,13 @@ user_cert_trusted_ca(struct passwd *pw, +@@ -431,13 +431,13 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) return 0; @@ -93,10 +95,11 @@ diff -up openssh-6.3p1/auth2-pubkey.c.fingerprint openssh-6.3p1/auth2-pubkey.c options.trusted_user_ca_keys); goto out; } -diff -up openssh-6.3p1/key.c.fingerprint openssh-6.3p1/key.c ---- openssh-6.3p1/key.c.fingerprint 2013-10-07 14:02:36.971968285 +0200 -+++ openssh-6.3p1/key.c 2013-10-07 14:02:36.999968148 +0200 -@@ -598,6 +598,34 @@ key_fingerprint(const Key *k, enum fp_ty +diff --git a/key.c b/key.c +index 168e1b7..eb98ea8 100644 +--- a/key.c ++++ b/key.c +@@ -628,6 +628,34 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) return retval; } @@ -131,10 +134,11 @@ diff -up openssh-6.3p1/key.c.fingerprint openssh-6.3p1/key.c /* * Reads a multiple-precision integer in decimal from the buffer, and advances * the pointer. The integer must already be initialized. This function is -diff -up openssh-6.3p1/key.h.fingerprint openssh-6.3p1/key.h ---- openssh-6.3p1/key.h.fingerprint 2013-10-07 14:02:36.999968148 +0200 -+++ openssh-6.3p1/key.h 2013-10-07 15:44:17.574233450 +0200 -@@ -97,6 +97,9 @@ int key_equal_public(const Key *, cons +diff --git a/key.h b/key.h +index d8ad13d..0e3eea5 100644 +--- a/key.h ++++ b/key.h +@@ -104,6 +104,9 @@ int key_equal_public(const Key *, const Key *); int key_equal(const Key *, const Key *); char *key_fingerprint(const Key *, enum fp_type, enum fp_rep); u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); @@ -144,10 +148,11 @@ diff -up openssh-6.3p1/key.h.fingerprint openssh-6.3p1/key.h const char *key_type(const Key *); const char *key_cert_type(const Key *); int key_write(const Key *, FILE *); -diff -up openssh-6.3p1/ssh-add.c.fingerprint openssh-6.3p1/ssh-add.c ---- openssh-6.3p1/ssh-add.c.fingerprint 2013-10-07 14:02:37.000968143 +0200 -+++ openssh-6.3p1/ssh-add.c 2013-10-07 14:44:57.466515766 +0200 -@@ -326,10 +326,10 @@ list_identities(AuthenticationConnection +diff --git a/ssh-add.c b/ssh-add.c +index 3421452..691949f 100644 +--- a/ssh-add.c ++++ b/ssh-add.c +@@ -330,10 +330,10 @@ list_identities(AuthenticationConnection *ac, int do_fp) key = ssh_get_next_identity(ac, &comment, version)) { had_identities = 1; if (do_fp) { @@ -162,9 +167,10 @@ diff -up openssh-6.3p1/ssh-add.c.fingerprint openssh-6.3p1/ssh-add.c free(fp); } else { if (!key_write(key, stdout)) -diff -up openssh-6.3p1/ssh-agent.c.fingerprint openssh-6.3p1/ssh-agent.c ---- openssh-6.3p1/ssh-agent.c.fingerprint 2013-10-07 14:02:37.000968143 +0200 -+++ openssh-6.3p1/ssh-agent.c 2013-10-07 15:41:11.627044336 +0200 +diff --git a/ssh-agent.c b/ssh-agent.c +index ba24612..117fdde 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c @@ -198,9 +198,9 @@ confirm_key(Identity *id) char *p; int ret = -1; @@ -178,10 +184,11 @@ diff -up openssh-6.3p1/ssh-agent.c.fingerprint openssh-6.3p1/ssh-agent.c ret = 0; free(p); -diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c ---- openssh-6.3p1/ssh-keygen.c.fingerprint 2013-07-20 05:22:32.000000000 +0200 -+++ openssh-6.3p1/ssh-keygen.c 2013-10-07 14:25:52.864145038 +0200 -@@ -767,13 +767,14 @@ do_fingerprint(struct passwd *pw) +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 2a316bc..482dc1c 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -783,13 +783,14 @@ do_fingerprint(struct passwd *pw) { FILE *f; Key *public; @@ -198,7 +205,7 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; if (!have_identity) -@@ -785,8 +786,8 @@ do_fingerprint(struct passwd *pw) +@@ -801,8 +802,8 @@ do_fingerprint(struct passwd *pw) public = key_load_public(identity_file, &comment); if (public != NULL) { fp = key_fingerprint(public, fptype, rep); @@ -209,7 +216,7 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); -@@ -851,8 +852,8 @@ do_fingerprint(struct passwd *pw) +@@ -867,8 +868,8 @@ do_fingerprint(struct passwd *pw) } comment = *cp ? cp : comment; fp = key_fingerprint(public, fptype, rep); @@ -220,7 +227,7 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c comment ? comment : "no comment", key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); -@@ -970,13 +971,15 @@ printhost(FILE *f, const char *name, Key +@@ -986,13 +987,15 @@ printhost(FILE *f, const char *name, Key *public, int ca, int hash) if (print_fingerprint) { enum fp_rep rep; enum fp_type fptype; @@ -240,7 +247,7 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); -@@ -1855,16 +1858,17 @@ do_show_cert(struct passwd *pw) +@@ -1878,16 +1881,17 @@ do_show_cert(struct passwd *pw) fatal("%s is not a certificate", identity_file); v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; @@ -264,7 +271,7 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c printf(" Key ID: \"%s\"\n", key->cert->key_id); if (!v00) { printf(" Serial: %llu\n", -@@ -2655,13 +2659,12 @@ passphrase_again: +@@ -2686,13 +2690,12 @@ passphrase_again: fclose(f); if (!quiet) { @@ -281,10 +288,11 @@ diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c printf("The key's randomart image is:\n"); printf("%s\n", ra); free(ra); -diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c ---- openssh-6.3p1/sshconnect.c.fingerprint 2013-06-01 23:31:19.000000000 +0200 -+++ openssh-6.3p1/sshconnect.c 2013-10-07 14:43:54.859822036 +0200 -@@ -830,10 +830,10 @@ check_host_key(char *hostname, struct so +diff --git a/sshconnect.c b/sshconnect.c +index 573d7a8..394cca8 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -914,10 +914,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, "key for IP address '%.128s' to the list " "of known hosts.", type, ip); } else if (options.visual_host_key) { @@ -299,7 +307,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c free(ra); free(fp); } -@@ -871,9 +871,8 @@ check_host_key(char *hostname, struct so +@@ -955,9 +955,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, else snprintf(msg1, sizeof(msg1), "."); /* The default */ @@ -311,7 +319,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) -@@ -888,10 +887,11 @@ check_host_key(char *hostname, struct so +@@ -972,10 +971,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" @@ -325,7 +333,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c options.visual_host_key ? "\n" : "", options.visual_host_key ? ra : "", msg2); -@@ -1136,8 +1136,9 @@ verify_host_key(char *host, struct socka +@@ -1220,8 +1220,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) int flags = 0; char *fp; @@ -337,7 +345,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c free(fp); /* XXX certs are not yet supported for DNS */ -@@ -1238,14 +1239,15 @@ show_other_keys(struct hostkeys *hostkey +@@ -1327,14 +1328,15 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) continue; if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; @@ -357,7 +365,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c if (options.visual_host_key) logit("%s", ra); free(ra); -@@ -1260,7 +1262,7 @@ warn_changed_key(Key *host_key) +@@ -1349,7 +1351,7 @@ warn_changed_key(Key *host_key) { char *fp; @@ -366,7 +374,7 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); -@@ -1268,8 +1270,8 @@ warn_changed_key(Key *host_key) +@@ -1357,8 +1359,8 @@ warn_changed_key(Key *host_key) error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); error("It is also possible that a host key has just been changed."); @@ -377,10 +385,11 @@ diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c error("Please contact your system administrator."); free(fp); -diff -up openssh-6.3p1/sshconnect2.c.fingerprint openssh-6.3p1/sshconnect2.c ---- openssh-6.3p1/sshconnect2.c.fingerprint 2013-10-07 14:02:37.001968139 +0200 -+++ openssh-6.3p1/sshconnect2.c 2013-10-07 15:20:09.403234714 +0200 -@@ -590,8 +590,9 @@ input_userauth_pk_ok(int type, u_int32_t +diff --git a/sshconnect2.c b/sshconnect2.c +index 7f4ff41..adbbfc7 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -577,8 +577,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) key->type, pktype); goto done; } @@ -392,7 +401,7 @@ diff -up openssh-6.3p1/sshconnect2.c.fingerprint openssh-6.3p1/sshconnect2.c free(fp); /* -@@ -1202,8 +1203,9 @@ sign_and_send_pubkey(Authctxt *authctxt, +@@ -986,8 +987,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) int have_sig = 1; char *fp; diff --git a/openssh-6.6p1-fips.patch b/openssh-6.6p1-fips.patch new file mode 100644 index 0000000..2869d2f --- /dev/null +++ b/openssh-6.6p1-fips.patch @@ -0,0 +1,808 @@ +diff --git a/Makefile.in b/Makefile.in +index 3bb7f00..294bef5 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -154,25 +154,25 @@ libssh.a: $(LIBSSH_OBJS) + $(RANLIB) $@ + + ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) +- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) ++ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) + + sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) +- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) ++ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + + ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o +- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o +- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o +- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o +- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +@@ -187,7 +187,7 @@ ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o +- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) ++ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +diff --git a/auth-rsa.c b/auth-rsa.c +index f225b0b..8bafcd6 100644 +--- a/auth-rsa.c ++++ b/auth-rsa.c +@@ -244,7 +244,7 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, + "actual %d vs. announced %d.", + file, linenum, BN_num_bits(key->rsa->n), bits); + +- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ++ fp = key_selected_fingerprint(key, SSH_FP_HEX); + debug("matching key found: file %s, line %lu %s %s", + file, linenum, key_type(key), fp); + free(fp); +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 6d1c872..3808ec8 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -214,8 +214,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) + } + + if (key_is_cert(key)) { +- fp = key_fingerprint(key->cert->signature_key, +- SSH_FP_MD5, SSH_FP_HEX); ++ fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); + auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", + key_type(key), key->cert->key_id, + (unsigned long long)key->cert->serial, +@@ -223,7 +222,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) + extra == NULL ? "" : ", ", extra == NULL ? "" : extra); + free(fp); + } else { +- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ++ fp = key_selected_fingerprint(key, SSH_FP_HEX); + auth_info(authctxt, "%s %s%s%s", key_type(key), fp, + extra == NULL ? "" : ", ", extra == NULL ? "" : extra); + free(fp); +diff --git a/authfile.c b/authfile.c +index ec4f4ff..2b3d650 100644 +--- a/authfile.c ++++ b/authfile.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + /* compatibility with old or broken OpenSSL versions */ + #include "openbsd-compat/openssl-compat.h" +@@ -1068,7 +1069,7 @@ Key * + key_parse_private(Buffer *buffer, const char *filename, + const char *passphrase, char **commentp) + { +- Key *pub, *prv; ++ Key *pub, *prv = NULL; + + /* it's a SSH v1 key if the public key part is readable */ + pub = key_parse_public_rsa1(buffer, commentp); +@@ -1080,9 +1081,10 @@ key_parse_private(Buffer *buffer, const char *filename, + *commentp = xstrdup(filename); + } else { + key_free(pub); +- /* key_parse_public_rsa1() has already loaded the comment */ +- prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, +- NULL); ++ if (! FIPS_mode()) ++ /* key_parse_public_rsa1() has already loaded the comment */ ++ prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, ++ NULL); + } + return prv; + } +diff --git a/cipher-ctr.c b/cipher-ctr.c +index 73e9c7c..40ee395 100644 +--- a/cipher-ctr.c ++++ b/cipher-ctr.c +@@ -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 --git a/cipher.c b/cipher.c +index 226e56d..b19443c 100644 +--- a/cipher.c ++++ b/cipher.c +@@ -39,6 +39,8 @@ + + #include + ++#include ++ + #include + #include + #include +@@ -90,6 +92,25 @@ static const struct Cipher ciphers[] = { + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } + }; + ++static const struct Cipher fips_ciphers[] = { ++ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, ++ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, ++ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, ++ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, ++ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, ++ { "rijndael-cbc@lysator.liu.se", ++ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, ++ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, ++ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, ++ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, ++#ifdef OPENSSL_HAVE_EVPGCM ++ { "aes128-gcm@openssh.com", ++ SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, ++ { "aes256-gcm@openssh.com", ++ SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, ++#endif ++ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } ++}; + /*--*/ + + /* Returns a list of supported ciphers separated by the specified char. */ +@@ -100,7 +121,7 @@ cipher_alg_list(char sep, int auth_only) + size_t nlen, rlen = 0; + const Cipher *c; + +- for (c = ciphers; c->name != NULL; c++) { ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { + if (c->number != SSH_CIPHER_SSH2) + continue; + if (auth_only && c->auth_len == 0) +@@ -180,7 +201,7 @@ const Cipher * + cipher_by_name(const char *name) + { + const Cipher *c; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; + return NULL; +@@ -190,7 +211,7 @@ const Cipher * + cipher_by_number(int id) + { + const Cipher *c; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (c->number == id) + return c; + return NULL; +@@ -232,7 +253,7 @@ cipher_number(const char *name) + const Cipher *c; + if (name == NULL) + return -1; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (strcasecmp(c->name, name) == 0) + return c->number; + return -1; +diff --git a/dh.h b/dh.h +index 48f7b68..9ff39f4 100644 +--- a/dh.h ++++ b/dh.h +@@ -45,6 +45,7 @@ int dh_estimate(int); + + /* Min and max values from RFC4419. */ + #define DH_GRP_MIN 1024 ++#define DH_GRP_MIN_FIPS 2048 + #define DH_GRP_MAX 8192 + + /* +diff --git a/entropy.c b/entropy.c +index b361a04..5616643 100644 +--- a/entropy.c ++++ b/entropy.c +@@ -222,6 +222,9 @@ seed_rng(void) + fatal("OpenSSL version mismatch. Built against %lx, you " + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + ++ /* clean the PRNG status when exiting the program */ ++ atexit(RAND_cleanup); ++ + #ifndef OPENSSL_PRNG_ONLY + if (RAND_status() == 1) { + debug3("RNG is ready, skipping seeding"); +diff --git a/kex.c b/kex.c +index bc3e53e..ede7b67 100644 +--- a/kex.c ++++ b/kex.c +@@ -34,6 +34,7 @@ + #include + + #include ++#include + + #include "xmalloc.h" + #include "ssh2.h" +@@ -103,6 +104,25 @@ static const struct kexalg kexalgs[] = { + { NULL, -1, -1, -1}, + }; + ++static const struct kexalg kexalgs_fips[] = { ++ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++#ifdef HAVE_EVP_SHA256 ++ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, ++#endif ++#ifdef OPENSSL_HAS_ECC ++ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, ++ SSH_DIGEST_SHA384 }, ++# ifdef OPENSSL_HAS_NISTP521 ++ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, ++ SSH_DIGEST_SHA512 }, ++# endif ++#endif ++ { NULL, -1, -1, NULL}, ++}; ++ + char * + kex_alg_list(char sep) + { +@@ -126,7 +146,7 @@ kex_alg_by_name(const char *name) + { + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { + if (strcmp(k->name, name) == 0) + return k; + #ifdef GSSAPI +@@ -151,7 +171,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/kexecdhc.c b/kexecdhc.c +index 2f7629c..20c9946 100644 +--- a/kexecdhc.c ++++ b/kexecdhc.c +@@ -154,6 +154,7 @@ kexecdh_client(Kex *kex) + + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); ++ memset(hash, 0, hashlen); + kex_finish(kex); + } + #else /* OPENSSL_HAS_ECC */ +diff --git a/kexecdhs.c b/kexecdhs.c +index 2700b72..0820894 100644 +--- a/kexecdhs.c ++++ b/kexecdhs.c +@@ -150,6 +150,7 @@ kexecdh_server(Kex *kex) + + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); ++ memset(hash, 0, hashlen); + kex_finish(kex); + } + #else /* OPENSSL_HAS_ECC */ +diff --git a/kexgexc.c b/kexgexc.c +index 355b7ba..427e11f 100644 +--- a/kexgexc.c ++++ b/kexgexc.c +@@ -26,6 +26,8 @@ + + #include "includes.h" + ++#include ++ + #include + + #include +@@ -64,13 +66,13 @@ kexgex_client(Kex *kex) + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); +- min = DH_GRP_MIN; ++ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + max = DH_GRP_MAX; + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); + } else { + /* New GEX request */ +- min = DH_GRP_MIN; ++ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); +diff --git a/kexgexs.c b/kexgexs.c +index 770ad28..9d4fc6d 100644 +--- a/kexgexs.c ++++ b/kexgexs.c +@@ -76,16 +76,16 @@ kexgex_server(Kex *kex) + omin = min = packet_get_int(); + onbits = nbits = packet_get_int(); + omax = max = packet_get_int(); +- min = MAX(DH_GRP_MIN, min); ++ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); +- nbits = MAX(DH_GRP_MIN, nbits); ++ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); + break; + case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); + onbits = nbits = packet_get_int(); + /* unused for old GEX */ +- omin = min = DH_GRP_MIN; ++ omin = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + omax = max = DH_GRP_MAX; + break; + default: +diff --git a/key.c b/key.c +index 62f3edb..c13b644 100644 +--- a/key.c ++++ b/key.c +@@ -42,6 +42,7 @@ + #include "crypto_api.h" + + #include ++#include + #include + + #include +@@ -636,9 +637,13 @@ key_fingerprint_selection(void) + char *env; + + if (!rv_defined) { +- env = getenv("SSH_FINGERPRINT_TYPE"); +- rv = (env && !strcmp (env, "sha")) ? +- SSH_FP_SHA1 : SSH_FP_MD5; ++ if (FIPS_mode()) ++ rv = SSH_FP_SHA1; ++ else { ++ env = getenv("SSH_FINGERPRINT_TYPE"); ++ rv = (env && !strcmp (env, "sha")) ? ++ SSH_FP_SHA1 : SSH_FP_MD5; ++ } + rv_defined = 1; + } + return rv; +diff --git a/mac.c b/mac.c +index 9388af4..cd7b034 100644 +--- a/mac.c ++++ b/mac.c +@@ -27,6 +27,8 @@ + + #include + ++#include ++ + #include + #include + #include +@@ -60,7 +62,7 @@ struct macalg { + int etm; /* Encrypt-then-MAC */ + }; + +-static const struct macalg macs[] = { ++static const struct macalg all_macs[] = { + /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ + { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, + { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, +@@ -91,6 +93,24 @@ static const struct macalg macs[] = { + { NULL, 0, 0, 0, 0, 0, 0 } + }; + ++static const struct macalg fips_macs[] = { ++ /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ ++ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, ++#ifdef HAVE_EVP_SHA256 ++ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, ++ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, ++#endif ++ ++ /* Encrypt-then-MAC variants */ ++ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, ++#ifdef HAVE_EVP_SHA256 ++ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, ++ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, ++#endif ++ ++ { NULL, 0, 0, 0, 0, 0, 0 } ++}; ++ + /* Returns a list of supported MACs separated by the specified char. */ + char * + mac_alg_list(char sep) +@@ -99,7 +119,7 @@ mac_alg_list(char sep) + size_t nlen, rlen = 0; + const struct macalg *m; + +- for (m = macs; m->name != NULL; m++) { ++ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(m->name); +@@ -133,7 +153,7 @@ mac_setup(Mac *mac, char *name) + { + const struct macalg *m; + +- for (m = macs; m->name != NULL; m++) { ++ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { + if (strcmp(name, m->name) != 0) + continue; + if (mac != NULL) { +diff --git a/myproposal.h b/myproposal.h +index 3a0f5ae..4f35a44 100644 +--- a/myproposal.h ++++ b/myproposal.h +@@ -88,6 +88,12 @@ + "diffie-hellman-group14-sha1," \ + "diffie-hellman-group1-sha1" + ++#define KEX_DEFAULT_KEX_FIPS \ ++ KEX_ECDH_METHODS \ ++ KEX_SHA256_METHODS \ ++ "diffie-hellman-group-exchange-sha1," \ ++ "diffie-hellman-group14-sha1" ++ + #define KEX_DEFAULT_PK_ALG \ + HOSTKEY_ECDSA_CERT_METHODS \ + "ssh-ed25519-cert-v01@openssh.com," \ +@@ -133,6 +139,22 @@ + #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" + #define KEX_DEFAULT_LANG "" + ++#define KEX_FIPS_ENCRYPT \ ++ "aes128-ctr,aes192-ctr,aes256-ctr," \ ++ "aes128-cbc,3des-cbc," \ ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" ++#ifdef HAVE_EVP_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" ++#else ++#define KEX_FIPS_MAC \ ++ "hmac-sha1" ++#endif + + static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 482dc1c..fd2eb94 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -195,6 +195,14 @@ type_bits_valid(int type, u_int32_t *bitsp) + fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); + exit(1); + } ++ if (FIPS_mode()) { ++ if (type == KEY_DSA) ++ fatal("DSA keys are not allowed in FIPS mode"); ++ if (type == KEY_RSA && bits != 2048 && bits != 3072) ++ fatal("RSA keys must be either 2048 bits or 3072 bits in FIPS mode"); ++ if (type == KEY_ED25519) ++ fatal("ED25519 keys are not allowed in FIPS mode"); ++ } + if (type == KEY_DSA && *bitsp != 1024) + fatal("DSA keys must be 1024 bits"); + else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) +@@ -746,7 +754,7 @@ do_download(struct passwd *pw) + enum fp_type fptype; + char *fp, *ra; + +- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; ++ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + + pkcs11_init(0); +@@ -756,8 +764,7 @@ do_download(struct passwd *pw) + for (i = 0; i < nkeys; i++) { + if (print_fingerprint) { + fp = key_fingerprint(keys[i], fptype, rep); +- ra = key_fingerprint(keys[i], SSH_FP_MD5, +- SSH_FP_RANDOMART); ++ ra = key_selected_fingerprint(keys[i], SSH_FP_RANDOMART); + printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), + fp, key_type(keys[i])); + if (log_level >= SYSLOG_LEVEL_VERBOSE) +diff --git a/ssh.c b/ssh.c +index 1e6cb90..ea9193f 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -73,6 +73,8 @@ + + #include + #include ++#include ++#include + #include "openbsd-compat/openssl-compat.h" + #include "openbsd-compat/sys-queue.h" + +@@ -427,6 +429,13 @@ main(int ac, char **av) + sanitise_stdfd(); + + __progname = ssh_get_progname(av[0]); ++ SSLeay_add_all_algorithms(); ++ if (access("/etc/system-fips", F_OK) == 0) ++ if (! FIPSCHECK_verify(NULL, NULL)) ++ if (FIPS_mode()) ++ fatal("FIPS integrity verification test failed."); ++ else ++ logit("FIPS integrity verification test failed."); + + #ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ +@@ -504,6 +513,9 @@ main(int ac, char **av) + "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { + switch (opt) { + case '1': ++ if (FIPS_mode()) { ++ fatal("Protocol 1 not allowed in the FIPS mode."); ++ } + options.protocol = SSH_PROTO_1; + break; + case '2': +@@ -828,7 +840,6 @@ main(int ac, char **av) + + host_arg = xstrdup(host); + +- OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + + /* Initialize the command to execute on remote host. */ +@@ -973,6 +984,10 @@ main(int ac, char **av) + + seed_rng(); + ++ if (FIPS_mode()) { ++ logit("FIPS mode initialized"); ++ } ++ + if (options.user == NULL) + options.user = xstrdup(pw->pw_name); + +@@ -1020,6 +1035,12 @@ main(int ac, char **av) + + timeout_ms = options.connection_timeout * 1000; + ++ if (FIPS_mode()) { ++ options.protocol &= SSH_PROTO_2; ++ if (options.protocol == 0) ++ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); ++ } ++ + /* Open a connection to the remote host. */ + if (ssh_connect(host, addrs, &hostaddr, options.port, + options.address_family, options.connection_attempts, +diff --git a/sshconnect2.c b/sshconnect2.c +index b00658b..6a1562c 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -44,6 +44,8 @@ + #include + #endif + ++#include ++ + #include "openbsd-compat/sys-queue.h" + + #include "xmalloc.h" +@@ -168,20 +170,25 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + + #ifdef GSSAPI + 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_trust_dns) +- gss_host = (char *)get_canonical_hostname(1); +- else +- gss_host = host; +- +- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); +- if (gss) { +- debug("Offering GSSAPI proposal: %s", gss); +- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], +- "%s,%s", gss, 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_trust_dns) ++ gss_host = (char *)get_canonical_hostname(1); ++ else ++ gss_host = host; ++ ++ gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); ++ if (gss) { ++ debug("Offering GSSAPI proposal: %s", gss); ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ } + } + } + #endif +@@ -193,6 +200,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; ++ + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); +@@ -208,7 +219,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_MAC_ALGS_CTOS] = ++ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; + } ++ + if (options.hostkeyalgorithms != NULL) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + compat_pkalg_proposal(options.hostkeyalgorithms); +@@ -220,9 +235,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; ++ else if (FIPS_mode()) ++ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; ++ + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( + myproposal[PROPOSAL_KEX_ALGS]); +- + #ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the + * 'null' hostkey, as a last resort */ +diff --git a/sshd.c b/sshd.c +index b561ec8..e977de3 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -75,6 +75,8 @@ + #include + #include + #include ++#include ++#include + #include "openbsd-compat/openssl-compat.h" + + #ifdef HAVE_SECUREWARE +@@ -1468,6 +1470,18 @@ main(int ac, char **av) + #endif + __progname = ssh_get_progname(av[0]); + ++ SSLeay_add_all_algorithms(); ++ if (access("/etc/system-fips", F_OK) == 0) ++ if (! FIPSCHECK_verify(NULL, NULL)) { ++ openlog(__progname, LOG_PID, LOG_AUTHPRIV); ++ if (FIPS_mode()) { ++ syslog(LOG_CRIT, "FIPS integrity verification test failed."); ++ cleanup_exit(255); ++ } ++ else ++ syslog(LOG_INFO, "FIPS integrity verification test failed."); ++ closelog(); ++ } + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ + saved_argc = ac; + rexec_argc = ac; +@@ -1619,8 +1633,6 @@ main(int ac, char **av) + else + closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); + +- OpenSSL_add_all_algorithms(); +- + /* If requested, redirect the logs to the specified logfile. */ + if (logfile != NULL) { + log_redirect_stderr_to(logfile); +@@ -1798,6 +1810,10 @@ main(int ac, char **av) + debug("private host key: #%d type %d %s", i, keytype, + key_type(key ? key : pubkey)); + } ++ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { ++ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); ++ options.protocol &= ~SSH_PROTO_1; ++ } + if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { + logit("Disabling protocol version 1. Could not load host key"); + options.protocol &= ~SSH_PROTO_1; +@@ -1961,6 +1977,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()) { ++ logit("FIPS mode initialized"); ++ } ++ + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ + if (chdir("/") == -1) +@@ -2530,6 +2550,9 @@ do_ssh2_kex(void) + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); +@@ -2539,6 +2562,9 @@ do_ssh2_kex(void) + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_MAC_ALGS_CTOS] = ++ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; + } + if (options.compression == COMP_NONE) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = +@@ -2549,6 +2575,8 @@ do_ssh2_kex(void) + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; ++ else if (FIPS_mode()) ++ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; + + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( + myproposal[PROPOSAL_KEX_ALGS]); +@@ -2575,10 +2603,14 @@ do_ssh2_kex(void) + 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 --git a/openssh-6.3p1-force_krb.patch b/openssh-6.6p1-force_krb.patch similarity index 84% rename from openssh-6.3p1-force_krb.patch rename to openssh-6.6p1-force_krb.patch index 695c0eb..a242394 100644 --- a/openssh-6.3p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -1,6 +1,7 @@ -diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.force_krb 2013-10-11 18:58:51.553948159 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:40:49.972337025 +0200 +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 42de994..60de320 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ #include @@ -38,7 +39,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client +@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_principal princ; int retval; const char *errmsg; @@ -46,7 +47,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c if (ssh_gssapi_krb5_init() == 0) return 0; -@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client +@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_free_error_message(krb_context, errmsg); return 0; } @@ -70,7 +71,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c } else retval = 0; -@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client +@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) return retval; } @@ -206,19 +207,20 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -diff -up openssh-6.3p1/session.c.force_krb openssh-6.3p1/session.c ---- openssh-6.3p1/session.c.force_krb 2013-10-11 18:58:51.487948468 +0200 -+++ openssh-6.3p1/session.c 2013-10-11 18:58:51.563948112 +0200 -@@ -823,6 +823,29 @@ do_exec(Session *s, const char *command) - debug("Forced command (key option) '%.900s'", command); +diff --git a/session.c b/session.c +index b5dc144..ba4589b 100644 +--- a/session.c ++++ b/session.c +@@ -806,6 +806,29 @@ do_exec(Session *s, const char *command) + command = forced_command; + forced = "(key-option)"; } - +#ifdef GSSAPI +#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ + else if (k5users_allowed_cmds) { + const char *match = command; + int allowed = 0, i = 0; -+ ++ + if (!match) + match = s->pw->pw_shell; + while (k5users_allowed_cmds[i]) { @@ -236,12 +238,13 @@ diff -up openssh-6.3p1/session.c.force_krb openssh-6.3p1/session.c +#endif +#endif + - #ifdef SSH_AUDIT_EVENTS - if (s->command != NULL || s->command_handle != -1) - fatal("do_exec: command already set"); -diff -up openssh-6.3p1/ssh-gss.h.force_krb openssh-6.3p1/ssh-gss.h ---- openssh-6.3p1/ssh-gss.h.force_krb 2013-10-11 18:58:51.558948136 +0200 -+++ openssh-6.3p1/ssh-gss.h 2013-10-11 18:58:51.563948112 +0200 + if (forced != NULL) { + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? +diff --git a/ssh-gss.h b/ssh-gss.h +index 0374c88..509109a 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h @@ -49,6 +49,10 @@ # endif /* !HAVE_DECL_GSS_C_NT_... */ @@ -253,10 +256,11 @@ diff -up openssh-6.3p1/ssh-gss.h.force_krb openssh-6.3p1/ssh-gss.h #endif /* KRB5 */ /* draft-ietf-secsh-gsskeyex-06 */ -diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8 ---- openssh-6.3p1/sshd.8.force_krb 2013-10-11 18:58:51.537948234 +0200 -+++ openssh-6.3p1/sshd.8 2013-10-11 18:58:51.563948112 +0200 -@@ -326,6 +326,7 @@ Finally, the server and the client enter +diff --git a/sshd.8 b/sshd.8 +index 058d37a..5c4f15b 100644 +--- a/sshd.8 ++++ b/sshd.8 +@@ -327,6 +327,7 @@ Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using host-based authentication, public key authentication, @@ -264,7 +268,7 @@ diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8 challenge-response authentication, or password authentication. .Pp -@@ -797,6 +798,12 @@ This file is used in exactly the same wa +@@ -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 diff --git a/openssh-6.4p1-gsissh.patch b/openssh-6.6p1-gsissh.patch similarity index 87% rename from openssh-6.4p1-gsissh.patch rename to openssh-6.6p1-gsissh.patch index 0e23d7f..f949f5f 100644 --- a/openssh-6.4p1-gsissh.patch +++ b/openssh-6.6p1-gsissh.patch @@ -1,7 +1,24 @@ -diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c ---- openssh-6.4p1.orig/auth2.c 2013-11-26 14:25:47.969371747 +0100 -+++ openssh-6.4p1/auth2.c 2013-11-26 14:26:35.169803216 +0100 -@@ -234,7 +234,27 @@ +diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c +--- openssh-6.6p1.orig/auth2.c 2014-07-14 19:49:55.195268838 +0200 ++++ openssh-6.6p1/auth2.c 2014-07-15 20:41:18.569116584 +0200 +@@ -49,6 +49,7 @@ + #include "dispatch.h" + #include "pathnames.h" + #include "buffer.h" ++#include "canohost.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -73,6 +74,8 @@ + extern Authmethod method_gssapi; + #endif + ++static int log_flag = 0; ++ + Authmethod *authmethods[] = { + &method_none, + &method_pubkey, +@@ -228,7 +231,33 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -27,15 +44,22 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c + + debug("userauth-request for user %s service %s method %s", + user[0] ? user : "", service, method); ++ if (!log_flag) { ++ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", ++ get_remote_ipaddr(), get_remote_port(), ++ user[0] ? user : ""); ++ log_flag = 1; ++ } debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -245,23 +265,48 @@ +@@ -239,23 +268,48 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; - if (authctxt->attempt++ == 0) { - /* setup auth context */ +- authctxt->pw = PRIVSEP(getpwnamallow(user)); + /* If first time or username changed or empty username, + setup/reset authentication context. */ + if ((authctxt->attempt++ == 0) || @@ -46,6 +70,8 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c + authctxt->user = NULL; + } + authctxt->valid = 0; + authctxt->user = xstrdup(user); +- if (authctxt->pw && strcmp(service, "ssh-connection")==0) { + if (strcmp(service, "ssh-connection") != 0) { + packet_disconnect("Unsupported service %s", service); + } @@ -54,14 +80,12 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c + GSSAPI context later, then wait until then to + verify it. Just put in placeholders for now. */ + if ((strcmp(user, "") == 0) && -+ (strcmp(method, "gssapi-with-mic") == 0)) { ++ ((strcmp(method, "gssapi") == 0) || ++ (strcmp(method, "gssapi-with-mic") == 0))) { + authctxt->pw = fakepw(); -+ authctxt->user = xstrdup(user); + } else { +#endif - authctxt->pw = PRIVSEP(getpwnamallow(user)); - authctxt->user = xstrdup(user); -- if (authctxt->pw && strcmp(service, "ssh-connection")==0) { ++ authctxt->pw = PRIVSEP(getpwnamallow(user)); + if (authctxt->pw) { authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); @@ -82,7 +106,7 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -276,9 +321,10 @@ +@@ -270,9 +324,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -96,9 +120,9 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c ---- openssh-6.4p1.orig/auth2-gss.c 2013-11-26 14:25:47.969371747 +0100 -+++ openssh-6.4p1/auth2-gss.c 2013-11-26 14:26:35.169803216 +0100 +diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c +--- openssh-6.6p1.orig/auth2-gss.c 2014-07-14 19:49:55.132268150 +0200 ++++ openssh-6.6p1/auth2-gss.c 2014-07-15 06:05:00.934252969 +0200 @@ -47,6 +47,7 @@ extern ServerOptions options; @@ -149,7 +173,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -102,7 +117,10 @@ +@@ -101,7 +116,10 @@ u_int len; u_char *doid = NULL; @@ -161,7 +185,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c return (0); mechs = packet_get_int(); -@@ -171,7 +189,7 @@ +@@ -166,7 +184,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -170,7 +194,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c u_int len; if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) -@@ -189,6 +207,7 @@ +@@ -184,6 +202,7 @@ free(recv_tok.value); if (GSS_ERROR(maj_status)) { @@ -178,7 +202,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c if (send_tok.length != 0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); packet_put_string(send_tok.value, send_tok.length); -@@ -252,6 +271,32 @@ +@@ -247,6 +266,32 @@ gss_release_buffer(&maj_status, &send_tok); } @@ -211,7 +235,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -267,6 +312,8 @@ +@@ -262,6 +307,8 @@ if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); @@ -220,7 +244,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -274,8 +321,13 @@ +@@ -269,8 +316,13 @@ packet_check_eom(); @@ -236,7 +260,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -316,9 +368,16 @@ +@@ -311,9 +363,16 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -255,7 +279,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -335,6 +394,23 @@ +@@ -330,6 +389,23 @@ userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); } @@ -279,9 +303,9 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-6.4p1.orig/auth.c openssh-6.4p1/auth.c ---- openssh-6.4p1.orig/auth.c 2013-11-26 14:25:47.970371735 +0100 -+++ openssh-6.4p1/auth.c 2013-11-26 14:26:35.170803204 +0100 +diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c +--- openssh-6.6p1.orig/auth.c 2014-07-14 19:49:55.035267091 +0200 ++++ openssh-6.6p1/auth.c 2014-07-15 08:14:47.720558265 +0200 @@ -74,6 +74,9 @@ #include "krl.h" #include "compat.h" @@ -302,14 +326,16 @@ diff -Nur openssh-6.4p1.orig/auth.c openssh-6.4p1/auth.c get_remote_ipaddr(), get_remote_port(), compat20 ? "ssh2" : "ssh1", -@@ -324,6 +328,21 @@ +@@ -324,6 +328,23 @@ if (authenticated == 0 && !authctxt->postponed) audit_event(audit_classify_auth(method)); #endif + if (authenticated) { + char *userdn = NULL; + char *mech_name = NULL; ++#ifdef GSSAPI + ssh_gssapi_get_client_info(&userdn, &mech_name); ++#endif + debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)", + SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), + method, mech_name?mech_name:"NULL", get_remote_ipaddr(), @@ -324,7 +350,7 @@ diff -Nur openssh-6.4p1.orig/auth.c openssh-6.4p1/auth.c } /* -@@ -604,6 +623,10 @@ +@@ -604,6 +625,10 @@ #endif pw = getpwnam(user); @@ -335,7 +361,7 @@ diff -Nur openssh-6.4p1.orig/auth.c openssh-6.4p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -623,7 +646,8 @@ +@@ -623,7 +648,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -345,20 +371,9 @@ diff -Nur openssh-6.4p1.orig/auth.c openssh-6.4p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-6.4p1.orig/auth.h openssh-6.4p1/auth.h ---- openssh-6.4p1.orig/auth.h 2013-11-26 14:25:47.970371735 +0100 -+++ openssh-6.4p1/auth.h 2013-11-26 14:26:35.170803204 +0100 -@@ -160,6 +160,7 @@ - void auth_log(Authctxt *, int, int, const char *, const char *); - void userauth_finish(Authctxt *, int, const char *, const char *); - int auth_root_allowed(const char *); -+char *expand_authorized_keys(const char *filename, struct passwd *pw); - - void userauth_send_banner(const char *); - -diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c ---- openssh-6.4p1.orig/auth-pam.c 2013-11-26 14:25:47.971371723 +0100 -+++ openssh-6.4p1/auth-pam.c 2013-11-26 14:26:35.171803192 +0100 +diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c +--- openssh-6.6p1.orig/auth-pam.c 2014-07-14 19:49:55.047267222 +0200 ++++ openssh-6.6p1/auth-pam.c 2014-07-15 06:05:00.935252978 +0200 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -370,7 +385,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c typedef pid_t sp_pthread_t; #endif -@@ -277,6 +281,55 @@ +@@ -272,6 +276,55 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -426,7 +441,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -299,7 +352,7 @@ +@@ -294,7 +347,7 @@ static void import_environments(Buffer *b) { @@ -435,7 +450,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c u_int i, num_env; int err; -@@ -309,6 +362,17 @@ +@@ -304,6 +357,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -453,7 +468,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -473,6 +537,13 @@ +@@ -470,6 +534,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -467,7 +482,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -493,6 +564,11 @@ +@@ -490,6 +561,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -479,7 +494,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -910,6 +986,18 @@ +@@ -907,6 +983,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -498,7 +513,7 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1207,6 +1295,9 @@ +@@ -1204,6 +1292,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -508,9 +523,9 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-6.4p1.orig/auth-pam.h openssh-6.4p1/auth-pam.h ---- openssh-6.4p1.orig/auth-pam.h 2013-11-26 14:25:47.971371723 +0100 -+++ openssh-6.4p1/auth-pam.h 2013-11-26 14:26:35.171803192 +0100 +diff -Nur openssh-6.6p1.orig/auth-pam.h openssh-6.6p1/auth-pam.h +--- openssh-6.6p1.orig/auth-pam.h 2014-07-14 19:49:55.047267222 +0200 ++++ openssh-6.6p1/auth-pam.h 2014-07-15 06:05:00.935252978 +0200 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -518,9 +533,9 @@ diff -Nur openssh-6.4p1.orig/auth-pam.h openssh-6.4p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-6.4p1.orig/canohost.c openssh-6.4p1/canohost.c ---- openssh-6.4p1.orig/canohost.c 2013-11-26 14:25:47.972371711 +0100 -+++ openssh-6.4p1/canohost.c 2013-11-26 14:26:35.171803192 +0100 +diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c +--- openssh-6.6p1.orig/canohost.c 2014-07-14 19:49:55.072267495 +0200 ++++ openssh-6.6p1/canohost.c 2014-07-15 06:05:00.935252978 +0200 @@ -16,6 +16,7 @@ #include @@ -529,7 +544,7 @@ diff -Nur openssh-6.4p1.orig/canohost.c openssh-6.4p1/canohost.c #include #include -@@ -451,3 +452,33 @@ +@@ -446,3 +447,33 @@ { return get_port(1); } @@ -563,9 +578,9 @@ diff -Nur openssh-6.4p1.orig/canohost.c openssh-6.4p1/canohost.c + } + } +} -diff -Nur openssh-6.4p1.orig/canohost.h openssh-6.4p1/canohost.h ---- openssh-6.4p1.orig/canohost.h 2013-11-26 14:25:47.972371711 +0100 -+++ openssh-6.4p1/canohost.h 2013-11-26 14:26:35.172803180 +0100 +diff -Nur openssh-6.6p1.orig/canohost.h openssh-6.6p1/canohost.h +--- openssh-6.6p1.orig/canohost.h 2009-06-21 11:50:08.000000000 +0200 ++++ openssh-6.6p1/canohost.h 2014-07-15 06:05:00.936252986 +0200 @@ -26,4 +26,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -573,10 +588,10 @@ diff -Nur openssh-6.4p1.orig/canohost.h openssh-6.4p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-6.4p1.orig/configure.ac openssh-6.4p1/configure.ac ---- openssh-6.4p1.orig/configure.ac 2013-11-26 14:25:47.973371699 +0100 -+++ openssh-6.4p1/configure.ac 2013-11-26 14:26:35.173803168 +0100 -@@ -3902,6 +3902,14 @@ +diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac +--- openssh-6.6p1.orig/configure.ac 2014-07-14 19:49:55.134268172 +0200 ++++ openssh-6.6p1/configure.ac 2014-07-15 06:05:00.936252986 +0200 +@@ -4133,6 +4133,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -591,7 +606,7 @@ diff -Nur openssh-6.4p1.orig/configure.ac openssh-6.4p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -3941,6 +3949,50 @@ +@@ -4172,6 +4180,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -642,9 +657,9 @@ diff -Nur openssh-6.4p1.orig/configure.ac openssh-6.4p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-6.4p1.orig/gss-genr.c openssh-6.4p1/gss-genr.c ---- openssh-6.4p1.orig/gss-genr.c 2013-11-26 14:25:47.974371687 +0100 -+++ openssh-6.4p1/gss-genr.c 2013-11-26 14:26:35.173803168 +0100 +diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c +--- openssh-6.6p1.orig/gss-genr.c 2014-07-14 19:49:55.135268183 +0200 ++++ openssh-6.6p1/gss-genr.c 2014-07-15 06:05:00.937252996 +0200 @@ -38,6 +38,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -681,10 +696,15 @@ diff -Nur openssh-6.4p1.orig/gss-genr.c openssh-6.4p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c ---- openssh-6.4p1.orig/gss-serv.c 2013-11-26 14:25:47.974371687 +0100 -+++ openssh-6.4p1/gss-serv.c 2013-11-26 14:47:37.394667653 +0100 -@@ -52,10 +52,12 @@ +diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c +--- openssh-6.6p1.orig/gss-serv.c 2014-07-14 19:49:55.135268183 +0200 ++++ openssh-6.6p1/gss-serv.c 2014-07-15 22:29:11.603965267 +0200 +@@ -48,14 +48,17 @@ + #include "servconf.h" + #include "uidswap.h" + ++#include "xmalloc.h" + #include "ssh-gss.h" #include "monitor_wrap.h" extern ServerOptions options; @@ -698,7 +718,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -63,14 +65,23 @@ +@@ -63,14 +66,24 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -719,20 +739,11 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG +static int limited = 0; +#endif - ++ /* - * Acquire credentials for a server running on the current host. -@@ -159,7 +170,8 @@ - - gss_create_empty_oid_set(&min_status, oidset); - -- if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) -+ /* Ask privileged process what mechanisms it supports. */ -+ if (GSS_ERROR(PRIVSEP(gss_indicate_mechs(&min_status, &supported)))) - return; - - while (supported_mechs[i]->name != NULL) { -@@ -212,6 +224,10 @@ + * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the + * list of supported mechanisms before privsep is set up. +@@ -231,6 +244,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -743,7 +754,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c } return (status); -@@ -231,6 +247,17 @@ +@@ -250,6 +267,17 @@ tok = ename->value; @@ -761,7 +772,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -298,8 +325,11 @@ +@@ -317,8 +345,11 @@ return GSS_S_COMPLETE; } @@ -775,7 +786,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); -@@ -342,9 +372,12 @@ +@@ -361,9 +392,12 @@ if (client->mech == NULL) return GSS_S_FAILURE; @@ -790,7 +801,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -371,6 +404,10 @@ +@@ -390,6 +424,10 @@ /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -801,7 +812,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c return (ctx->major); } -@@ -378,6 +415,7 @@ +@@ -397,6 +435,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -809,7 +820,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -393,6 +431,14 @@ +@@ -412,6 +451,14 @@ gssapi_client.store.data = NULL; } } @@ -824,7 +835,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c } /* As user */ -@@ -400,6 +446,11 @@ +@@ -419,6 +466,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -836,7 +847,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -423,8 +474,9 @@ +@@ -442,8 +494,9 @@ } /* Privileged */ @@ -847,7 +858,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c { OM_uint32 lmin; -@@ -433,6 +485,12 @@ +@@ -452,6 +505,12 @@ debug("No suitable client data"); return 0; } @@ -860,7 +871,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -451,6 +509,24 @@ +@@ -471,6 +530,24 @@ return (0); } @@ -885,7 +896,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -477,6 +553,7 @@ +@@ -497,6 +574,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -893,7 +904,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -506,6 +583,18 @@ +@@ -526,6 +604,18 @@ if (ret) return; @@ -912,7 +923,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -537,4 +626,13 @@ +@@ -557,4 +647,13 @@ return ok; } @@ -926,9 +937,9 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c +} + #endif -diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/gss-serv-gsi.c ---- openssh-6.4p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.4p1/gss-serv-gsi.c 2013-11-26 14:26:35.175803144 +0100 +diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c +--- openssh-6.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.6p1/gss-serv-gsi.c 2014-07-15 06:05:00.938253005 +0200 @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1168,9 +1179,9 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-6.4p1.orig/gss-serv-krb5.c openssh-6.4p1/gss-serv-krb5.c ---- openssh-6.4p1.orig/gss-serv-krb5.c 2013-11-26 14:25:47.976371663 +0100 -+++ openssh-6.4p1/gss-serv-krb5.c 2013-11-26 14:26:35.175803144 +0100 +diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c +--- openssh-6.6p1.orig/gss-serv-krb5.c 2014-07-14 19:49:55.158268433 +0200 ++++ openssh-6.6p1/gss-serv-krb5.c 2014-07-15 06:05:00.938253005 +0200 @@ -263,6 +263,34 @@ return found_principal; } @@ -1206,7 +1217,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv-krb5.c openssh-6.4p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -361,7 +389,7 @@ +@@ -367,7 +395,7 @@ return; } @@ -1215,7 +1226,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv-krb5.c openssh-6.4p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -432,7 +460,7 @@ +@@ -438,7 +466,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1224,9 +1235,9 @@ diff -Nur openssh-6.4p1.orig/gss-serv-krb5.c openssh-6.4p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-6.4p1.orig/kexgsss.c openssh-6.4p1/kexgsss.c ---- openssh-6.4p1.orig/kexgsss.c 2013-11-26 14:25:47.976371663 +0100 -+++ openssh-6.4p1/kexgsss.c 2013-11-26 14:26:35.176803132 +0100 +diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c +--- openssh-6.6p1.orig/kexgsss.c 2014-07-14 19:49:55.137268204 +0200 ++++ openssh-6.6p1/kexgsss.c 2014-07-15 06:05:00.938253005 +0200 @@ -44,6 +44,7 @@ #include "monitor_wrap.h" #include "servconf.h" @@ -1286,9 +1297,9 @@ diff -Nur openssh-6.4p1.orig/kexgsss.c openssh-6.4p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-6.4p1.orig/LICENSE.globus_usage openssh-6.4p1/LICENSE.globus_usage ---- openssh-6.4p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.4p1/LICENSE.globus_usage 2013-11-26 14:26:35.176803132 +0100 +diff -Nur openssh-6.6p1.orig/LICENSE.globus_usage openssh-6.6p1/LICENSE.globus_usage +--- openssh-6.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.6p1/LICENSE.globus_usage 2014-07-15 06:05:00.939253015 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1308,24 +1319,24 @@ diff -Nur openssh-6.4p1.orig/LICENSE.globus_usage openssh-6.4p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-6.4p1.orig/Makefile.in openssh-6.4p1/Makefile.in ---- openssh-6.4p1.orig/Makefile.in 2013-11-26 14:25:47.977371651 +0100 -+++ openssh-6.4p1/Makefile.in 2013-11-26 14:26:35.177803120 +0100 -@@ -95,8 +95,10 @@ +diff -Nur openssh-6.6p1.orig/Makefile.in openssh-6.6p1/Makefile.in +--- openssh-6.6p1.orig/Makefile.in 2014-07-14 19:49:55.208268979 +0200 ++++ openssh-6.6p1/Makefile.in 2014-07-15 06:05:00.939253015 +0200 +@@ -99,8 +99,10 @@ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\ + kexc25519s.o auth-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ + ssh-globus-usage.o \ roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o -diff -Nur openssh-6.4p1.orig/misc.c openssh-6.4p1/misc.c ---- openssh-6.4p1.orig/misc.c 2013-11-26 14:25:47.977371651 +0100 -+++ openssh-6.4p1/misc.c 2013-11-26 14:26:35.177803120 +0100 -@@ -158,11 +158,14 @@ + sandbox-seccomp-filter.o sandbox-capsicum.o +diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c +--- openssh-6.6p1.orig/misc.c 2014-07-14 19:49:55.174268608 +0200 ++++ openssh-6.6p1/misc.c 2014-07-15 06:05:00.939253015 +0200 +@@ -159,11 +159,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1341,7 +1352,7 @@ diff -Nur openssh-6.4p1.orig/misc.c openssh-6.4p1/misc.c int wspace = 0; if (*s == NULL) -@@ -170,6 +173,21 @@ +@@ -171,6 +174,21 @@ old = *s; @@ -1363,7 +1374,7 @@ diff -Nur openssh-6.4p1.orig/misc.c openssh-6.4p1/misc.c *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); -@@ -225,6 +243,20 @@ +@@ -226,6 +244,20 @@ return copy; } @@ -1384,10 +1395,10 @@ diff -Nur openssh-6.4p1.orig/misc.c openssh-6.4p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-6.4p1.orig/misc.h openssh-6.4p1/misc.h ---- openssh-6.4p1.orig/misc.h 2013-11-26 14:25:47.977371651 +0100 -+++ openssh-6.4p1/misc.h 2013-11-26 14:26:35.177803120 +0100 -@@ -39,6 +39,7 @@ +diff -Nur openssh-6.6p1.orig/misc.h openssh-6.6p1/misc.h +--- openssh-6.6p1.orig/misc.h 2013-10-15 03:14:12.000000000 +0200 ++++ openssh-6.6p1/misc.h 2014-07-15 06:05:00.939253015 +0200 +@@ -41,6 +41,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1395,10 +1406,10 @@ diff -Nur openssh-6.4p1.orig/misc.h openssh-6.4p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c ---- openssh-6.4p1.orig/monitor.c 2013-11-26 14:25:47.978371639 +0100 -+++ openssh-6.4p1/monitor.c 2013-11-26 14:26:35.178803108 +0100 -@@ -188,6 +188,9 @@ +diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c +--- openssh-6.6p1.orig/monitor.c 2014-07-14 19:49:55.199268881 +0200 ++++ openssh-6.6p1/monitor.c 2014-07-15 06:23:28.126793084 +0200 +@@ -182,6 +182,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1408,7 +1419,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -236,7 +239,7 @@ +@@ -230,7 +233,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1417,7 +1428,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -244,7 +247,7 @@ +@@ -238,7 +241,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1426,17 +1437,18 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -274,6 +277,9 @@ +@@ -267,6 +270,10 @@ + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, - {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, ++ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, + {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, + {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname}, #endif - #ifdef JPAKE - {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, -@@ -290,6 +296,8 @@ + {0, 0, NULL} + }; +@@ -276,6 +283,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1445,7 +1457,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, -@@ -327,7 +335,7 @@ +@@ -313,7 +322,7 @@ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM @@ -1454,7 +1466,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -417,6 +425,8 @@ +@@ -403,6 +412,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1463,7 +1475,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_proto15; -@@ -535,6 +545,8 @@ +@@ -512,6 +523,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1472,7 +1484,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -805,14 +817,17 @@ +@@ -782,14 +795,17 @@ debug3("%s", __func__); @@ -1493,7 +1505,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2306,12 +2321,15 @@ +@@ -2283,12 +2299,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1510,7 +1522,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2319,12 +2337,77 @@ +@@ -2296,12 +2315,77 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1589,10 +1601,10 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-6.4p1.orig/monitor.h openssh-6.4p1/monitor.h ---- openssh-6.4p1.orig/monitor.h 2013-11-26 14:25:47.978371639 +0100 -+++ openssh-6.4p1/monitor.h 2013-11-26 14:26:35.178803108 +0100 -@@ -79,8 +79,10 @@ +diff -Nur openssh-6.6p1.orig/monitor.h openssh-6.6p1/monitor.h +--- openssh-6.6p1.orig/monitor.h 2014-07-14 19:49:55.199268881 +0200 ++++ openssh-6.6p1/monitor.h 2014-07-15 06:05:00.941253034 +0200 +@@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, @@ -1605,10 +1617,10 @@ diff -Nur openssh-6.4p1.orig/monitor.h openssh-6.4p1/monitor.h }; struct mm_master; -diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/monitor_wrap.c ---- openssh-6.4p1.orig/monitor_wrap.c 2013-11-26 14:25:47.979371627 +0100 -+++ openssh-6.4p1/monitor_wrap.c 2013-11-26 14:26:35.179803095 +0100 -@@ -1329,12 +1329,13 @@ +diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c +--- openssh-6.6p1.orig/monitor_wrap.c 2014-07-14 19:49:55.199268881 +0200 ++++ openssh-6.6p1/monitor_wrap.c 2014-07-15 06:05:00.942253044 +0200 +@@ -1327,12 +1327,13 @@ } int @@ -1623,7 +1635,7 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1347,6 +1348,83 @@ +@@ -1345,6 +1346,83 @@ return (authenticated); } @@ -1707,9 +1719,9 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-6.4p1.orig/monitor_wrap.h openssh-6.4p1/monitor_wrap.h ---- openssh-6.4p1.orig/monitor_wrap.h 2013-11-26 14:25:47.979371627 +0100 -+++ openssh-6.4p1/monitor_wrap.h 2013-11-26 14:26:35.179803095 +0100 +diff -Nur openssh-6.6p1.orig/monitor_wrap.h openssh-6.6p1/monitor_wrap.h +--- openssh-6.6p1.orig/monitor_wrap.h 2014-07-14 19:49:55.200268892 +0200 ++++ openssh-6.6p1/monitor_wrap.h 2014-07-15 06:05:00.942253044 +0200 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1725,10 +1737,10 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.h openssh-6.4p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-6.4p1.orig/readconf.c openssh-6.4p1/readconf.c ---- openssh-6.4p1.orig/readconf.c 2013-11-26 14:25:47.979371627 +0100 -+++ openssh-6.4p1/readconf.c 2013-11-26 14:26:35.179803095 +0100 -@@ -1303,13 +1303,13 @@ +diff -Nur openssh-6.6p1.orig/readconf.c openssh-6.6p1/readconf.c +--- openssh-6.6p1.orig/readconf.c 2014-07-14 19:49:55.140268237 +0200 ++++ openssh-6.6p1/readconf.c 2014-07-15 06:05:00.943253053 +0200 +@@ -1651,13 +1651,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1746,10 +1758,10 @@ diff -Nur openssh-6.4p1.orig/readconf.c openssh-6.4p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; if (options->password_authentication == -1) -diff -Nur openssh-6.4p1.orig/readconf.h openssh-6.4p1/readconf.h ---- openssh-6.4p1.orig/readconf.h 2013-11-26 14:25:47.980371615 +0100 -+++ openssh-6.4p1/readconf.h 2013-11-26 14:26:35.179803095 +0100 -@@ -88,6 +88,8 @@ +diff -Nur openssh-6.6p1.orig/readconf.h openssh-6.6p1/readconf.h +--- openssh-6.6p1.orig/readconf.h 2014-07-14 19:49:55.140268237 +0200 ++++ openssh-6.6p1/readconf.h 2014-07-15 06:05:00.944253063 +0200 +@@ -93,6 +93,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1758,9 +1770,9 @@ diff -Nur openssh-6.4p1.orig/readconf.h openssh-6.4p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c ---- openssh-6.4p1.orig/servconf.c 2013-11-26 14:25:47.980371615 +0100 -+++ openssh-6.4p1/servconf.c 2013-11-26 14:26:35.180803083 +0100 +diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c +--- openssh-6.6p1.orig/servconf.c 2014-07-14 19:49:55.158268433 +0200 ++++ openssh-6.6p1/servconf.c 2014-07-15 06:28:26.478649137 +0200 @@ -71,6 +71,7 @@ /* Portable-specific options */ @@ -1769,7 +1781,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -107,9 +108,11 @@ +@@ -108,9 +109,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1782,9 +1794,9 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; @@ -151,6 +154,8 @@ + options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; - options->zero_knowledge_password_authentication = -1; + options->disable_usage_stats = 0; + options->usage_stats_targets = NULL; options->revoked_keys_file = NULL; @@ -1799,7 +1811,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -244,13 +251,17 @@ +@@ -248,13 +255,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1819,7 +1831,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; if (options->password_authentication == -1) -@@ -333,7 +344,7 @@ +@@ -335,7 +346,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1828,7 +1840,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -354,11 +365,15 @@ +@@ -356,10 +367,14 @@ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1836,15 +1848,14 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, - sAcceptEnv, sPermitTunnel, + sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, + sDisUsageStats, sUsageStatsTarg, - sZeroKnowledgePasswordAuthentication, sHostCertificate, + sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, sVersionAddendum, -@@ -380,8 +395,10 @@ +@@ -381,8 +396,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1855,7 +1866,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -424,15 +441,25 @@ +@@ -425,15 +442,25 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1881,7 +1892,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -497,6 +524,8 @@ +@@ -494,6 +521,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1890,7 +1901,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -889,6 +918,10 @@ +@@ -901,6 +930,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1901,7 +1912,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1104,6 +1137,10 @@ +@@ -1116,6 +1149,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1912,7 +1923,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1112,6 +1149,10 @@ +@@ -1124,6 +1161,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1923,7 +1934,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1120,6 +1161,12 @@ +@@ -1132,6 +1173,12 @@ intptr = &options->gss_store_rekey; goto parse_flag; @@ -1936,7 +1947,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1581,6 +1628,18 @@ +@@ -1592,6 +1639,18 @@ *charptr = xstrdup(arg); break; @@ -1955,18 +1966,18 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -1801,6 +1860,7 @@ - { +@@ -1799,6 +1858,7 @@ + M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); + M_CP_INTOPT(gss_deleg_creds); M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/servconf.h ---- openssh-6.4p1.orig/servconf.h 2013-11-26 14:25:47.980371615 +0100 -+++ openssh-6.4p1/servconf.h 2013-11-26 14:26:35.180803083 +0100 -@@ -110,9 +110,12 @@ +diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h +--- openssh-6.6p1.orig/servconf.h 2014-07-14 19:49:55.158268433 +0200 ++++ openssh-6.6p1/servconf.h 2014-07-15 06:05:00.946253082 +0200 +@@ -111,9 +111,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -1979,7 +1990,7 @@ diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; int password_authentication; /* If true, permit password -@@ -169,6 +172,7 @@ +@@ -168,6 +171,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -1987,7 +1998,7 @@ diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/servconf.h int permit_tun; -@@ -176,6 +180,10 @@ +@@ -175,6 +179,10 @@ int use_kuserok; char *chroot_directory; @@ -1998,10 +2009,10 @@ diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_principals_file; -diff -Nur openssh-6.4p1.orig/ssh.1 openssh-6.4p1/ssh.1 ---- openssh-6.4p1.orig/ssh.1 2013-11-26 14:25:47.981371603 +0100 -+++ openssh-6.4p1/ssh.1 2013-11-26 14:26:35.181803071 +0100 -@@ -1281,6 +1281,18 @@ +diff -Nur openssh-6.6p1.orig/ssh.1 openssh-6.6p1/ssh.1 +--- openssh-6.6p1.orig/ssh.1 2014-07-14 19:49:55.111267920 +0200 ++++ openssh-6.6p1/ssh.1 2014-07-15 06:05:00.947253092 +0200 +@@ -1295,6 +1295,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2020,10 +2031,10 @@ diff -Nur openssh-6.4p1.orig/ssh.1 openssh-6.4p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-6.4p1.orig/ssh.c openssh-6.4p1/ssh.c ---- openssh-6.4p1.orig/ssh.c 2013-11-26 14:25:47.981371603 +0100 -+++ openssh-6.4p1/ssh.c 2013-11-26 14:26:35.181803071 +0100 -@@ -718,6 +718,32 @@ +diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c +--- openssh-6.6p1.orig/ssh.c 2014-07-14 19:49:55.216269067 +0200 ++++ openssh-6.6p1/ssh.c 2014-07-15 06:31:38.640768992 +0200 +@@ -395,6 +395,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2039,24 +2050,24 @@ diff -Nur openssh-6.4p1.orig/ssh.c openssh-6.4p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, host, &options, 1); ++ (void)read_config_file(buf, pw, host, &options, 1); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, host, &options, 1); ++ (void)read_config_file(buf, pw, host, &options, 1); +#endif +#if defined(KRB5) + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, host, &options, 1); ++ (void)read_config_file(buf, pw, host, &options, 1); +#endif +#endif r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -763,8 +789,12 @@ +@@ -988,8 +1014,12 @@ logit("FIPS mode initialized"); } @@ -2068,11 +2079,11 @@ diff -Nur openssh-6.4p1.orig/ssh.c openssh-6.4p1/ssh.c + options.implicit = 0; + } - /* Get default port if port has not been set. */ - if (options.port == 0) { -diff -Nur openssh-6.4p1.orig/ssh_config openssh-6.4p1/ssh_config ---- openssh-6.4p1.orig/ssh_config 2013-11-26 14:25:47.981371603 +0100 -+++ openssh-6.4p1/ssh_config 2013-11-26 14:26:35.181803071 +0100 + if (gethostname(thishost, sizeof(thishost)) == -1) + fatal("gethostname: %s", strerror(errno)); +diff -Nur openssh-6.6p1.orig/ssh_config openssh-6.6p1/ssh_config +--- openssh-6.6p1.orig/ssh_config 2014-07-14 19:49:55.142268259 +0200 ++++ openssh-6.6p1/ssh_config 2014-07-15 06:05:00.948253101 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2088,9 +2099,9 @@ diff -Nur openssh-6.4p1.orig/ssh_config openssh-6.4p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-6.4p1.orig/ssh_config.5 openssh-6.4p1/ssh_config.5 ---- openssh-6.4p1.orig/ssh_config.5 2013-11-26 14:25:47.982371591 +0100 -+++ openssh-6.4p1/ssh_config.5 2013-11-26 14:26:35.182803059 +0100 +diff -Nur openssh-6.6p1.orig/ssh_config.5 openssh-6.6p1/ssh_config.5 +--- openssh-6.6p1.orig/ssh_config.5 2014-07-14 19:49:55.143268270 +0200 ++++ openssh-6.6p1/ssh_config.5 2014-07-15 06:05:00.949253111 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2104,10 +2115,10 @@ diff -Nur openssh-6.4p1.orig/ssh_config.5 openssh-6.4p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-6.4p1.orig/sshconnect2.c openssh-6.4p1/sshconnect2.c ---- openssh-6.4p1.orig/sshconnect2.c 2013-11-26 14:25:47.982371591 +0100 -+++ openssh-6.4p1/sshconnect2.c 2013-11-26 14:26:35.182803059 +0100 -@@ -700,6 +700,11 @@ +diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c +--- openssh-6.6p1.orig/sshconnect2.c 2014-07-14 19:49:55.216269067 +0200 ++++ openssh-6.6p1/sshconnect2.c 2014-07-15 06:05:00.950253121 +0200 +@@ -696,6 +696,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2119,7 +2130,7 @@ diff -Nur openssh-6.4p1.orig/sshconnect2.c openssh-6.4p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -933,6 +938,15 @@ +@@ -929,6 +934,15 @@ free(lang); } @@ -2135,7 +2146,7 @@ diff -Nur openssh-6.4p1.orig/sshconnect2.c openssh-6.4p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -950,8 +964,16 @@ +@@ -946,8 +960,16 @@ return (0); } @@ -2152,7 +2163,7 @@ diff -Nur openssh-6.4p1.orig/sshconnect2.c openssh-6.4p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -962,7 +984,15 @@ +@@ -958,7 +980,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2168,10 +2179,10 @@ diff -Nur openssh-6.4p1.orig/sshconnect2.c openssh-6.4p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-6.4p1.orig/sshd.8 openssh-6.4p1/sshd.8 ---- openssh-6.4p1.orig/sshd.8 2013-11-26 14:25:47.983371579 +0100 -+++ openssh-6.4p1/sshd.8 2013-11-26 14:26:35.183803047 +0100 -@@ -763,6 +763,44 @@ +diff -Nur openssh-6.6p1.orig/sshd.8 openssh-6.6p1/sshd.8 +--- openssh-6.6p1.orig/sshd.8 2014-07-14 19:49:55.150268346 +0200 ++++ openssh-6.6p1/sshd.8 2014-07-15 06:05:00.951253130 +0200 +@@ -766,6 +766,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2216,9 +2227,9 @@ diff -Nur openssh-6.4p1.orig/sshd.8 openssh-6.4p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-6.4p1.orig/sshd.c openssh-6.4p1/sshd.c ---- openssh-6.4p1.orig/sshd.c 2013-11-26 14:25:47.983371579 +0100 -+++ openssh-6.4p1/sshd.c 2013-11-26 14:26:35.183803047 +0100 +diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c +--- openssh-6.6p1.orig/sshd.c 2014-07-14 19:49:55.217269078 +0200 ++++ openssh-6.6p1/sshd.c 2014-07-15 06:05:00.952253140 +0200 @@ -124,6 +124,7 @@ #include "audit.h" #include "ssh-sandbox.h" @@ -2227,7 +2238,7 @@ diff -Nur openssh-6.4p1.orig/sshd.c openssh-6.4p1/sshd.c #ifdef USE_SECURITY_SESSION_API #include -@@ -1681,6 +1682,13 @@ +@@ -1699,6 +1700,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2241,7 +2252,7 @@ diff -Nur openssh-6.4p1.orig/sshd.c openssh-6.4p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2266,7 +2274,7 @@ +@@ -2230,7 +2238,7 @@ #endif #ifdef GSSAPI @@ -2250,27 +2261,25 @@ diff -Nur openssh-6.4p1.orig/sshd.c openssh-6.4p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-6.4p1.orig/sshd_config openssh-6.4p1/sshd_config ---- openssh-6.4p1.orig/sshd_config 2013-11-26 14:25:47.983371579 +0100 -+++ openssh-6.4p1/sshd_config 2013-11-26 14:26:35.183803047 +0100 -@@ -89,12 +89,12 @@ - #KerberosUseKuserok yes +diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config +--- openssh-6.6p1.orig/sshd_config 2014-07-14 19:49:55.160268455 +0200 ++++ openssh-6.6p1/sshd_config 2014-07-15 06:37:02.657343409 +0200 +@@ -90,10 +90,11 @@ + #KerberosUseKuserok no # GSSAPI options --#GSSAPIAuthentication no -GSSAPIAuthentication yes +#GSSAPIAuthentication yes +#GSSAPIDelegateCredentials yes - #GSSAPICleanupCredentials yes GSSAPICleanupCredentials no #GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no +#GSSAPIKeyExchange yes - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -110,6 +109,10 @@ - #UsePAM no + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +@@ -108,6 +109,10 @@ + # problems. UsePAM yes +# Set to 'yes' to allow the PAM stack to change the user name during @@ -2280,18 +2289,18 @@ diff -Nur openssh-6.4p1.orig/sshd_config openssh-6.4p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -155,3 +158,7 @@ - # X11Forwarding no +@@ -154,3 +159,7 @@ # AllowTcpForwarding no + # PermitTTY no # ForceCommand cvs server + +# Usage Metrics +#UsageStatsTargets usage-stats.cilogon.org:4810 +#DisableUsageStats no -diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 ---- openssh-6.4p1.orig/sshd_config.5 2013-11-26 14:25:47.984371567 +0100 -+++ openssh-6.4p1/sshd_config.5 2013-11-26 14:26:35.184803035 +0100 -@@ -440,6 +440,15 @@ +diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 +--- openssh-6.6p1.orig/sshd_config.5 2014-07-14 19:49:55.160268455 +0200 ++++ openssh-6.6p1/sshd_config.5 2014-07-15 06:05:00.953253149 +0200 +@@ -449,6 +449,15 @@ See PATTERNS in .Xr ssh_config 5 for more information on patterns. @@ -2307,7 +2316,7 @@ diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 .It Cm ForceCommand Forces the execution of the command specified by .Cm ForceCommand , -@@ -484,6 +493,10 @@ +@@ -493,6 +502,10 @@ The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2318,7 +2327,7 @@ diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 .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. -@@ -496,6 +509,22 @@ +@@ -505,6 +518,22 @@ The default is .Dq yes . Note that this option applies to protocol version 2 only. @@ -2341,7 +2350,7 @@ diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If -@@ -1160,6 +1189,121 @@ +@@ -1196,6 +1225,121 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2463,7 +2472,7 @@ diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication. -@@ -1225,6 +1369,12 @@ +@@ -1261,6 +1405,12 @@ as a non-root user. The default is .Dq no . @@ -2476,9 +2485,9 @@ diff -Nur openssh-6.4p1.orig/sshd_config.5 openssh-6.4p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-6.4p1.orig/ssh-globus-usage.c openssh-6.4p1/ssh-globus-usage.c ---- openssh-6.4p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.4p1/ssh-globus-usage.c 2013-11-26 14:26:35.184803035 +0100 +diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c +--- openssh-6.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.6p1/ssh-globus-usage.c 2014-07-15 06:05:00.954253159 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2876,9 +2885,9 @@ diff -Nur openssh-6.4p1.orig/ssh-globus-usage.c openssh-6.4p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-6.4p1.orig/ssh-globus-usage.h openssh-6.4p1/ssh-globus-usage.h ---- openssh-6.4p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.4p1/ssh-globus-usage.h 2013-11-26 14:26:35.184803035 +0100 +diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h +--- openssh-6.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.6p1/ssh-globus-usage.h 2014-07-15 06:05:00.954253159 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2926,9 +2935,9 @@ diff -Nur openssh-6.4p1.orig/ssh-globus-usage.h openssh-6.4p1/ssh-globus-usage.h + char *username, char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-6.4p1.orig/ssh-gss.h openssh-6.4p1/ssh-gss.h ---- openssh-6.4p1.orig/ssh-gss.h 2013-11-26 14:25:47.985371555 +0100 -+++ openssh-6.4p1/ssh-gss.h 2013-11-26 14:26:35.185803023 +0100 +diff -Nur openssh-6.6p1.orig/ssh-gss.h openssh-6.6p1/ssh-gss.h +--- openssh-6.6p1.orig/ssh-gss.h 2014-07-14 19:49:55.149268335 +0200 ++++ openssh-6.6p1/ssh-gss.h 2014-07-15 06:05:00.955253168 +0200 @@ -91,6 +91,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2946,7 +2955,7 @@ diff -Nur openssh-6.4p1.orig/ssh-gss.h openssh-6.4p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -142,6 +143,9 @@ +@@ -144,6 +145,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2956,7 +2965,7 @@ diff -Nur openssh-6.4p1.orig/ssh-gss.h openssh-6.4p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -152,7 +156,7 @@ +@@ -154,7 +158,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -2965,7 +2974,7 @@ diff -Nur openssh-6.4p1.orig/ssh-gss.h openssh-6.4p1/ssh-gss.h 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); -@@ -162,6 +166,7 @@ +@@ -164,6 +168,7 @@ int ssh_gssapi_oid_table_ok(); int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); @@ -2973,11 +2982,11 @@ diff -Nur openssh-6.4p1.orig/ssh-gss.h openssh-6.4p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-6.4p1.orig/version.h openssh-6.4p1/version.h ---- openssh-6.4p1.orig/version.h 2013-11-26 14:25:47.985371555 +0100 -+++ openssh-6.4p1/version.h 2013-11-26 14:26:35.185803023 +0100 +diff -Nur openssh-6.6p1.orig/version.h openssh-6.6p1/version.h +--- openssh-6.6p1.orig/version.h 2014-07-14 19:49:55.187268750 +0200 ++++ openssh-6.6p1/version.h 2014-07-15 06:05:00.955253168 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.68 2013/11/08 01:38:11 djm Exp $ */ + /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -2991,9 +3000,9 @@ diff -Nur openssh-6.4p1.orig/version.h openssh-6.4p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20131109" ++#define NCSA_VERSION " GSI_GSSAPI_20140522" + - #define SSH_VERSION "OpenSSH_6.4" + #define SSH_VERSION "OpenSSH_6.6.1" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-6.3p1-gsskex.patch b/openssh-6.6p1-gsskex.patch similarity index 79% rename from openssh-6.3p1-gsskex.patch rename to openssh-6.6p1-gsskex.patch index 0c54d38..90e84d2 100644 --- a/openssh-6.3p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -1,144 +1,29 @@ -diff -up openssh-6.3p1/ChangeLog.gssapi.gsskex openssh-6.3p1/ChangeLog.gssapi ---- openssh-6.3p1/ChangeLog.gssapi.gsskex 2013-10-11 15:15:17.284216176 +0200 -+++ openssh-6.3p1/ChangeLog.gssapi 2013-10-11 15:15:17.284216176 +0200 -@@ -0,0 +1,113 @@ -+20110101 -+ - Finally update for OpenSSH 5.6p1 -+ - Add GSSAPIServerIdentity option from Jim Basney -+ -+20100308 -+ - [ Makefile.in, key.c, key.h ] -+ Updates for OpenSSH 5.4p1 -+ - [ servconf.c ] -+ Include GSSAPI options in the sshd -T configuration dump, and flag -+ some older configuration options as being unsupported. Thanks to Colin -+ Watson. -+ - -+ -+20100124 -+ - [ sshconnect2.c ] -+ Adapt to deal with additional element in Authmethod structure. Thanks to -+ Colin Watson -+ -+20090615 -+ - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c -+ sshd.c ] -+ Fix issues identified by Greg Hudson following a code review -+ Check return value of gss_indicate_mechs -+ Protect GSSAPI calls in monitor, so they can only be used if enabled -+ Check return values of bignum functions in key exchange -+ Use BN_clear_free to clear other side's DH value -+ Make ssh_gssapi_id_kex more robust -+ Only configure kex table pointers if GSSAPI is enabled -+ Don't leak mechanism list, or gss mechanism list -+ Cast data.length before printing -+ If serverkey isn't provided, use an empty string, rather than NULL -+ -+20090201 -+ - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h -+ ssh_config.5 sshconnet2.c ] -+ Add support for the GSSAPIClientIdentity option, which allows the user -+ to specify which GSSAPI identity to use to contact a given server -+ -+20080404 -+ - [ gss-serv.c ] -+ Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow -+ been omitted from a previous version of this patch. Reported by Borislav -+ Stoichkov -+ -+20070317 -+ - [ gss-serv-krb5.c ] -+ Remove C99ism, where new_ccname was being declared in the middle of a -+ function -+ -+20061220 -+ - [ servconf.c ] -+ Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and -+ documented, behaviour. Reported by Dan Watson. -+ -+20060910 -+ - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c -+ ssh-gss.h ] -+ add support for gss-group14-sha1 key exchange mechanisms -+ - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] -+ Add GSSAPIStrictAcceptorCheck option to allow the disabling of -+ acceptor principal checking on multi-homed machines. -+ -+ - [ sshd_config ssh_config ] -+ Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample -+ configuration files -+ - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] -+ Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() -+ Limit length of error messages displayed by client -+ -+20060909 -+ - [ gss-genr.c gss-serv.c ] -+ move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server -+ only, where they belong -+ -+ -+20060829 -+ - [ gss-serv-krb5.c ] -+ Fix CCAPI credentials cache name when creating KRB5CCNAME environment -+ variable -+ -+20060828 -+ - [ gss-genr.c ] -+ Avoid Heimdal context freeing problem -+ -+ -+20060818 -+ - [ gss-genr.c ssh-gss.h sshconnect2.c ] -+ Make sure that SPENGO is disabled -+ -+ -+20060421 -+ - [ gssgenr.c, sshconnect2.c ] -+ a few type changes (signed versus unsigned, int versus size_t) to -+ fix compiler errors/warnings -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ kexgssc.c, sshconnect2.c ] -+ fix uninitialized variable warnings -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ gssgenr.c ] -+ pass oid to gss_display_status (helpful when using GSSAPI mechglue) -+ (from jbasney AT ncsa.uiuc.edu) -+ -+ - [ gss-serv-krb5.c ] -+ #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H -+ (from jbasney AT ncsa.uiuc.edu) -+ -+ - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c -+ add client-side GssapiKeyExchange option -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ sshconnect2.c ] -+ add support for GssapiTrustDns option for gssapi-with-mic -+ (from jbasney AT ncsa.uiuc.edu) -+ -diff -up openssh-6.3p1/Makefile.in.gsskex openssh-6.3p1/Makefile.in ---- openssh-6.3p1/Makefile.in.gsskex 2013-10-11 15:15:17.281216190 +0200 -+++ openssh-6.3p1/Makefile.in 2013-10-11 15:15:17.289216153 +0200 -@@ -77,6 +77,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o +diff --git a/Makefile.in b/Makefile.in +index 581b121..2ad26ff 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -77,6 +77,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ + kexgssc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - jpake.o schnorr.o ssh-pkcs11.o krl.o auditstub.o - -@@ -93,7 +94,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ + ssh-pkcs11.o krl.o smult_curve25519_ref.o \ + kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ +@@ -96,7 +97,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - auth-krb5.o \ + kexc25519s.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\ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ -diff -up openssh-6.3p1/auth2-gss.c.gsskex openssh-6.3p1/auth2-gss.c ---- openssh-6.3p1/auth2-gss.c.gsskex 2013-10-11 15:15:17.213216506 +0200 -+++ openssh-6.3p1/auth2-gss.c 2013-10-11 15:15:17.283216181 +0200 -@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u +diff --git a/auth2-gss.c b/auth2-gss.c +index 4756dd7..ad65059 100644 +--- a/auth2-gss.c ++++ b/auth2-gss.c +@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); static void input_gssapi_errtok(int, u_int32_t, void *); @@ -179,7 +64,7 @@ diff -up openssh-6.3p1/auth2-gss.c.gsskex openssh-6.3p1/auth2-gss.c /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -240,7 +274,8 @@ input_gssapi_exchange_complete(int type, +@@ -235,7 +269,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) packet_check_eom(); @@ -189,7 +74,7 @@ diff -up openssh-6.3p1/auth2-gss.c.gsskex openssh-6.3p1/auth2-gss.c authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -282,7 +317,8 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -277,7 +312,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) gssbuf.length = buffer_len(&b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -199,7 +84,7 @@ diff -up openssh-6.3p1/auth2-gss.c.gsskex openssh-6.3p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -299,6 +335,12 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -294,6 +330,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); } @@ -212,9 +97,10 @@ diff -up openssh-6.3p1/auth2-gss.c.gsskex openssh-6.3p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-6.3p1/auth2.c.gsskex openssh-6.3p1/auth2.c ---- openssh-6.3p1/auth2.c.gsskex 2013-10-11 15:15:17.214216502 +0200 -+++ openssh-6.3p1/auth2.c 2013-10-11 15:15:17.283216181 +0200 +diff --git a/auth2.c b/auth2.c +index 5f4f26f..0f52b68 100644 +--- a/auth2.c ++++ b/auth2.c @@ -69,6 +69,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; @@ -222,18 +108,19 @@ diff -up openssh-6.3p1/auth2.c.gsskex openssh-6.3p1/auth2.c +extern Authmethod method_gsskeyex; extern Authmethod method_gssapi; #endif - #ifdef JPAKE -@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { + +@@ -76,6 +77,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI + &method_gsskeyex, &method_gssapi, #endif - #ifdef JPAKE -diff -up openssh-6.3p1/clientloop.c.gsskex openssh-6.3p1/clientloop.c ---- openssh-6.3p1/clientloop.c.gsskex 2013-10-11 15:15:17.178216669 +0200 -+++ openssh-6.3p1/clientloop.c 2013-10-11 15:15:17.284216176 +0200 + &method_passwd, +diff --git a/clientloop.c b/clientloop.c +index 59ad3a2..9c60108 100644 +--- a/clientloop.c ++++ b/clientloop.c @@ -111,6 +111,10 @@ #include "msg.h" #include "roaming.h" @@ -245,7 +132,7 @@ diff -up openssh-6.3p1/clientloop.c.gsskex openssh-6.3p1/clientloop.c /* import options */ extern Options options; -@@ -1608,6 +1612,15 @@ client_loop(int have_pty, int escape_cha +@@ -1608,6 +1612,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Do channel operations unless rekeying in progress. */ if (!rekeying) { channel_after_select(readset, writeset); @@ -261,10 +148,11 @@ diff -up openssh-6.3p1/clientloop.c.gsskex openssh-6.3p1/clientloop.c if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); xxx_kex->done = 0; -diff -up openssh-6.3p1/configure.ac.gsskex openssh-6.3p1/configure.ac ---- openssh-6.3p1/configure.ac.gsskex 2013-10-11 15:15:17.273216227 +0200 -+++ openssh-6.3p1/configure.ac 2013-10-11 15:15:17.285216171 +0200 -@@ -548,6 +548,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +diff --git a/configure.ac b/configure.ac +index 74e77db..9bde04e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -584,6 +584,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -295,9 +183,10 @@ diff -up openssh-6.3p1/configure.ac.gsskex openssh-6.3p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c ---- openssh-6.3p1/gss-genr.c.gsskex 2013-06-01 23:31:18.000000000 +0200 -+++ openssh-6.3p1/gss-genr.c 2013-10-11 15:15:17.286216167 +0200 +diff --git a/gss-genr.c b/gss-genr.c +index b39281b..a3a2289 100644 +--- a/gss-genr.c ++++ b/gss-genr.c @@ -39,12 +39,167 @@ #include "buffer.h" #include "log.h" @@ -466,7 +355,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de +@@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -475,7 +364,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) } OM_uint32 @@ -518,7 +407,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -538,7 +427,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) -@@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha +@@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, } int @@ -556,7 +445,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -263,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -263,6 +470,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); @@ -567,7 +456,7 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -272,10 +483,67 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -272,10 +483,67 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -636,10 +525,11 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-6.3p1/gss-serv-krb5.c.gsskex openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.gsskex 2013-07-20 05:35:45.000000000 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-23 21:48:20.558346236 +0200 -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 759fa10..42de994 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; @@ -648,7 +538,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.gsskex openssh-6.3p1/gss-serv-krb5.c const char *errmsg; if (client->creds == NULL) { -@@ -174,11 +174,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; } @@ -679,7 +569,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.gsskex openssh-6.3p1/gss-serv-krb5.c #ifdef USE_PAM if (options.use_pam) -@@ -187,9 +202,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_cc_close(krb_context, ccache); @@ -756,7 +646,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.gsskex openssh-6.3p1/gss-serv-krb5.c ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", -@@ -197,7 +279,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { +@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { NULL, &ssh_gssapi_krb5_userok, NULL, @@ -766,9 +656,10 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.gsskex openssh-6.3p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c ---- openssh-6.3p1/gss-serv.c.gsskex 2013-07-20 05:35:45.000000000 +0200 -+++ openssh-6.3p1/gss-serv.c 2013-10-23 21:51:52.212347754 +0200 +diff --git a/gss-serv.c b/gss-serv.c +index e61b37b..14f540e 100644 +--- a/gss-serv.c ++++ b/gss-serv.c @@ -45,15 +45,20 @@ #include "channels.h" #include "session.h" @@ -792,7 +683,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -81,25 +86,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) +@@ -100,25 +105,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) char lname[MAXHOSTNAMELEN]; gss_OID_set oidset; @@ -801,16 +692,16 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c + if (options.gss_strict_acceptor) { + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); -+ -+ if (gethostname(lname, MAXHOSTNAMELEN)) { -+ gss_release_oid_set(&status, &oidset); -+ return (-1); -+ } - if (gethostname(lname, MAXHOSTNAMELEN)) { - gss_release_oid_set(&status, &oidset); - return (-1); - } ++ if (gethostname(lname, MAXHOSTNAMELEN)) { ++ gss_release_oid_set(&status, &oidset); ++ return (-1); ++ } ++ + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { + gss_release_oid_set(&status, &oidset); + return (ctx->major); @@ -839,7 +730,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c } /* Privileged */ -@@ -114,6 +126,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss +@@ -133,6 +145,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) } /* Unprivileged */ @@ -869,7 +760,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c void ssh_gssapi_supported_oids(gss_OID_set *oidset) { -@@ -123,7 +158,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o +@@ -142,7 +177,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -880,7 +771,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -249,8 +286,48 @@ OM_uint32 +@@ -268,8 +305,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -930,7 +821,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c client->mech = NULL; -@@ -265,6 +342,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -284,6 +361,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) if (client->mech == NULL) return GSS_S_FAILURE; @@ -944,7 +835,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -282,6 +366,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -301,6 +385,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } @@ -953,7 +844,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -292,11 +378,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -311,11 +397,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) void ssh_gssapi_cleanup_creds(void) { @@ -979,7 +870,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c } } -@@ -329,7 +424,7 @@ ssh_gssapi_do_child(char ***envp, u_int +@@ -348,7 +443,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) /* Privileged */ int @@ -988,7 +879,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c { OM_uint32 lmin; -@@ -339,9 +434,11 @@ ssh_gssapi_userok(char *user) +@@ -358,9 +453,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -1002,7 +893,7 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -354,14 +451,90 @@ ssh_gssapi_userok(char *user) +@@ -374,14 +471,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1099,12 +990,13 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c } #endif -diff -up openssh-6.3p1/kex.c.gsskex openssh-6.3p1/kex.c ---- openssh-6.3p1/kex.c.gsskex 2013-10-30 15:26:39.339608716 +0100 -+++ openssh-6.3p1/kex.c 2013-10-31 10:50:41.254535382 +0100 +diff --git a/kex.c b/kex.c +index 74e2b86..bce2ab8 100644 +--- a/kex.c ++++ b/kex.c @@ -51,6 +51,10 @@ #include "roaming.h" - #include "audit.h" + #include "digest.h" +#ifdef GSSAPI +#include "ssh-gss.h" @@ -1113,19 +1005,19 @@ diff -up openssh-6.3p1/kex.c.gsskex openssh-6.3p1/kex.c #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 -@@ -81,6 +85,11 @@ static const struct kexalg kexalgs[] = { - { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, - { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, +@@ -90,6 +94,11 @@ static const struct kexalg kexalgs[] = { + #ifdef HAVE_EVP_SHA256 + { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif +#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, EVP_sha1 }, -+ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, EVP_sha1 }, -+ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, EVP_sha1 }, ++ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, +#endif - { NULL, -1, -1, NULL}, + { NULL, -1, -1, -1}, }; -@@ -110,6 +119,12 @@ kex_alg_by_name(const char *name) +@@ -119,6 +128,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -1138,22 +1030,25 @@ diff -up openssh-6.3p1/kex.c.gsskex openssh-6.3p1/kex.c } return NULL; } -diff -up openssh-6.3p1/kex.h.gsskex openssh-6.3p1/kex.h ---- openssh-6.3p1/kex.h.gsskex 2013-10-11 15:15:17.197216581 +0200 -+++ openssh-6.3p1/kex.h 2013-10-11 15:43:21.757429309 +0200 -@@ -74,6 +74,9 @@ enum kex_exchange { - KEX_DH_GEX_SHA1, +diff --git a/kex.h b/kex.h +index c85680e..313bb51 100644 +--- a/kex.h ++++ b/kex.h +@@ -76,6 +76,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, + KEX_C25519_SHA256, ++#ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, + KEX_GSS_GEX_SHA1, ++#endif KEX_MAX }; -@@ -133,6 +136,12 @@ struct Kex { +@@ -135,6 +140,12 @@ struct Kex { int flags; - const EVP_MD *evp_md; + int hash_alg; int ec_nid; +#ifdef GSSAPI + int gss_deleg_creds; @@ -1164,21 +1059,22 @@ diff -up openssh-6.3p1/kex.h.gsskex openssh-6.3p1/kex.h char *client_version_string; char *server_version_string; int (*verify_host_key)(Key *); -@@ -162,6 +171,11 @@ void kexgex_server(Kex *); - void kexecdh_client(Kex *); +@@ -166,6 +177,10 @@ void kexecdh_client(Kex *); void kexecdh_server(Kex *); - + void kexc25519_client(Kex *); + void kexc25519_server(Kex *); +#ifdef GSSAPI -+void kexgss_client(Kex *); -+void kexgss_server(Kex *); ++void kexgss_client(Kex *); ++void kexgss_server(Kex *); +#endif -+ - void newkeys_destroy(Newkeys *newkeys); void -diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c ---- openssh-6.3p1/kexgssc.c.gsskex 2013-10-11 15:15:17.287216162 +0200 -+++ openssh-6.3p1/kexgssc.c 2013-10-11 15:15:17.287216162 +0200 + kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, +diff --git a/kexgssc.c b/kexgssc.c +new file mode 100644 +index 0000000..e90b567 +--- /dev/null ++++ b/kexgssc.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1461,7 +1357,7 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( -+ kex->evp_md, ++ kex->hash_alg, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -1508,15 +1404,17 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + else + ssh_gssapi_delete_ctx(&ctxt); + -+ kex_derive_keys(kex, hash, hashlen, shared_secret); ++ kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} + +#endif /* GSSAPI */ -diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c ---- openssh-6.3p1/kexgsss.c.gsskex 2013-10-11 15:15:17.287216162 +0200 -+++ openssh-6.3p1/kexgsss.c 2013-10-11 15:15:17.287216162 +0200 +diff --git a/kexgsss.c b/kexgsss.c +new file mode 100644 +index 0000000..6d7518c +--- /dev/null ++++ b/kexgsss.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1743,7 +1641,7 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( -+ kex->evp_md, ++ kex->hash_alg, + kex->client_version_string, kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -1796,7 +1694,7 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + + DH_free(dh); + -+ kex_derive_keys(kex, hash, hashlen, shared_secret); ++ kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); + @@ -1806,32 +1704,35 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + ssh_gssapi_rekey_creds(); +} +#endif /* GSSAPI */ -diff -up openssh-6.3p1/key.c.gsskex openssh-6.3p1/key.c ---- openssh-6.3p1/key.c.gsskex 2013-10-11 15:15:17.288216158 +0200 -+++ openssh-6.3p1/key.c 2013-10-11 15:41:44.982868222 +0200 -@@ -968,6 +968,7 @@ static const struct keytype keytypes[] = - KEY_RSA_CERT_V00, 0, 1 }, - { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00", +diff --git a/key.c b/key.c +index eb98ea8..900b9e3 100644 +--- a/key.c ++++ b/key.c +@@ -1013,6 +1013,7 @@ static const struct keytype keytypes[] = { KEY_DSA_CERT_V00, 0, 1 }, + { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", + KEY_ED25519_CERT, 0, 1 }, + { "null", "null", KEY_NULL, 0, 0 }, { NULL, NULL, -1, -1, 0 } }; -diff -up openssh-6.3p1/key.h.gsskex openssh-6.3p1/key.h ---- openssh-6.3p1/key.h.gsskex 2013-10-11 15:15:17.198216576 +0200 -+++ openssh-6.3p1/key.h 2013-10-11 15:15:17.289216153 +0200 -@@ -44,6 +44,7 @@ enum types { - KEY_ECDSA_CERT, +diff --git a/key.h b/key.h +index 0e3eea5..d51ed81 100644 +--- a/key.h ++++ b/key.h +@@ -46,6 +46,7 @@ enum types { + KEY_ED25519_CERT, KEY_RSA_CERT_V00, KEY_DSA_CERT_V00, + KEY_NULL, KEY_UNSPEC }; enum fp_type { -diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c ---- openssh-6.3p1/monitor.c.gsskex 2013-10-11 15:15:17.214216502 +0200 -+++ openssh-6.3p1/monitor.c 2013-10-11 15:15:17.290216148 +0200 -@@ -187,6 +187,8 @@ int mm_answer_gss_setup_ctx(int, Buffer +diff --git a/monitor.c b/monitor.c +index 229fada..aa70945 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -178,6 +178,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1840,15 +1741,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c #endif #ifdef SSH_AUDIT_EVENTS -@@ -271,6 +273,7 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, - {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, -+ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, - #endif - #ifdef JPAKE - {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, -@@ -283,6 +286,12 @@ struct mon_table mon_dispatch_proto20[] +@@ -258,6 +260,12 @@ struct mon_table mon_dispatch_proto20[] = { }; struct mon_table mon_dispatch_postauth20[] = { @@ -1861,7 +1754,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, {MONITOR_REQ_SIGN, 0, mm_answer_sign}, {MONITOR_REQ_PTY, 0, mm_answer_pty}, -@@ -405,6 +414,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -366,6 +374,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1872,7 +1765,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c } else { mon_dispatch = mon_dispatch_proto15; -@@ -519,6 +532,10 @@ monitor_child_postauth(struct monitor *p +@@ -471,6 +483,10 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1883,10 +1776,10 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1968,6 +1985,13 @@ mm_get_kex(Buffer *m) - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; +@@ -1866,6 +1882,13 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; @@ -1897,7 +1790,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); -@@ -2192,6 +2216,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -2073,6 +2096,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) OM_uint32 major; u_int len; @@ -1907,7 +1800,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2219,6 +2246,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2100,6 +2126,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1917,7 +1810,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2236,6 +2266,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2117,6 +2146,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1925,7 +1818,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c } return (0); } -@@ -2247,6 +2278,9 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -2128,6 +2158,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) OM_uint32 ret; u_int len; @@ -1935,7 +1828,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2273,7 +2307,11 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2154,7 +2187,11 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1948,7 +1841,7 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2286,6 +2324,74 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2167,5 +2204,73 @@ mm_answer_gss_userok(int sock, Buffer *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2022,11 +1915,11 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c + #endif /* GSSAPI */ - #ifdef JPAKE -diff -up openssh-6.3p1/monitor.h.gsskex openssh-6.3p1/monitor.h ---- openssh-6.3p1/monitor.h.gsskex 2013-10-11 15:15:17.215216497 +0200 -+++ openssh-6.3p1/monitor.h 2013-10-11 15:15:17.290216148 +0200 -@@ -64,6 +64,8 @@ enum monitor_reqtype { +diff --git a/monitor.h b/monitor.h +index 20e2b4a..ff79fbb 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, #endif @@ -2035,10 +1928,11 @@ diff -up openssh-6.3p1/monitor.h.gsskex openssh-6.3p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-6.3p1/monitor_wrap.c.gsskex openssh-6.3p1/monitor_wrap.c ---- openssh-6.3p1/monitor_wrap.c.gsskex 2013-10-11 15:15:17.215216497 +0200 -+++ openssh-6.3p1/monitor_wrap.c 2013-10-11 15:15:17.290216148 +0200 -@@ -1329,7 +1329,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff --git a/monitor_wrap.c b/monitor_wrap.c +index d1b6d99..d1e1caa 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -1290,7 +1290,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -2047,7 +1941,7 @@ diff -up openssh-6.3p1/monitor_wrap.c.gsskex openssh-6.3p1/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -1346,6 +1346,51 @@ mm_ssh_gssapi_userok(char *user) +@@ -1307,5 +1307,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -2085,24 +1979,24 @@ diff -up openssh-6.3p1/monitor_wrap.c.gsskex openssh-6.3p1/monitor_wrap.c + buffer_put_cstring(&m, store->filename ? store->filename : ""); + buffer_put_cstring(&m, store->envvar ? store->envvar : ""); + buffer_put_cstring(&m, store->envval ? store->envval : ""); -+ ++ + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); + + ok = buffer_get_int(&m); + + buffer_free(&m); -+ ++ + return (ok); +} + #endif /* GSSAPI */ - #ifdef JPAKE -diff -up openssh-6.3p1/monitor_wrap.h.gsskex openssh-6.3p1/monitor_wrap.h ---- openssh-6.3p1/monitor_wrap.h.gsskex 2013-10-11 15:15:17.215216497 +0200 -+++ openssh-6.3p1/monitor_wrap.h 2013-10-11 15:15:17.290216148 +0200 -@@ -62,8 +62,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 9d5e5ba..93929e0 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2114,10 +2008,11 @@ diff -up openssh-6.3p1/monitor_wrap.h.gsskex openssh-6.3p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c ---- openssh-6.3p1/readconf.c.gsskex 2013-07-18 08:09:05.000000000 +0200 -+++ openssh-6.3p1/readconf.c 2013-10-11 15:15:17.291216143 +0200 -@@ -132,6 +132,8 @@ typedef enum { +diff --git a/readconf.c b/readconf.c +index dc884c9..7613ff2 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -141,6 +141,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2126,7 +2021,7 @@ diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -172,10 +174,19 @@ static struct { +@@ -183,10 +185,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2146,7 +2041,7 @@ diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, -@@ -516,10 +527,30 @@ parse_flag: +@@ -841,10 +852,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2177,7 +2072,7 @@ diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1168,7 +1199,12 @@ initialize_options(Options * options) +@@ -1497,7 +1528,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2190,7 +2085,7 @@ diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1268,8 +1304,14 @@ fill_default_options(Options * options) +@@ -1616,8 +1652,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2205,10 +2100,11 @@ diff -up openssh-6.3p1/readconf.c.gsskex openssh-6.3p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-6.3p1/readconf.h.gsskex openssh-6.3p1/readconf.h ---- openssh-6.3p1/readconf.h.gsskex 2013-05-16 12:30:03.000000000 +0200 -+++ openssh-6.3p1/readconf.h 2013-10-11 15:15:17.291216143 +0200 -@@ -48,7 +48,12 @@ typedef struct { +diff --git a/readconf.h b/readconf.h +index 75e3f8f..5cc97f0 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -54,7 +54,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -2221,10 +2117,75 @@ diff -up openssh-6.3p1/readconf.h.gsskex openssh-6.3p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c ---- openssh-6.3p1/servconf.c.gsskex 2013-10-11 15:15:17.273216227 +0200 -+++ openssh-6.3p1/servconf.c 2013-10-11 15:15:17.292216139 +0200 -@@ -107,7 +107,10 @@ initialize_server_options(ServerOptions +diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh +index 1d9e0ed..1277409 100644 +--- a/regress/cert-hostkey.sh ++++ b/regress/cert-hostkey.sh +@@ -17,7 +17,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ + cat $OBJ/host_ca_key.pub + ) > $OBJ/known_hosts-cert + +-PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` ++PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` + + type_has_legacy() { + case $1 in +diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh +index b093a91..4c8da00 100644 +--- a/regress/cert-userkey.sh ++++ b/regress/cert-userkey.sh +@@ -6,7 +6,7 @@ tid="certified user keys" + rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* + cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +-PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` ++PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` + + type_has_legacy() { + case $1 in +diff --git a/regress/kextype.sh b/regress/kextype.sh +index 8c2ac09..a2a87ca 100644 +--- a/regress/kextype.sh ++++ b/regress/kextype.sh +@@ -9,6 +9,9 @@ cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + + tries="1 2 3 4" + for k in `${SSH} -Q kex`; do ++ if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o $k = "gss-group14-sha1-" ]; then ++ continue ++ fi + verbose "kex $k" + for i in $tries; do + ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true +diff --git a/regress/rekey.sh b/regress/rekey.sh +index cf9401e..31fb0f7 100644 +--- a/regress/rekey.sh ++++ b/regress/rekey.sh +@@ -30,6 +30,9 @@ increase_datafile_size 300 + + opts="" + for i in `${SSH} -Q kex`; do ++ if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o $i = "gss-group14-sha1-" ]; then ++ continue ++ fi + opts="$opts KexAlgorithms=$i" + done + for i in `${SSH} -Q cipher`; do +@@ -48,6 +51,9 @@ done + if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do ++ if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o $kex = "gss-group14-sha1-" ]; then ++ continue ++ fi + verbose "client rekey $c $kex" + ssh_data_rekeying -oRekeyLimit=256k -oCiphers=$c -oKexAlgorithms=$kex + done +diff --git a/servconf.c b/servconf.c +index f763317..68fb9ef 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -108,7 +108,10 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -2235,7 +2196,7 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -241,8 +244,14 @@ fill_default_server_options(ServerOption +@@ -245,8 +248,14 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2250,18 +2211,17 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -342,7 +351,9 @@ typedef enum { +@@ -344,7 +353,8 @@ typedef enum { sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, -+ sGssKeyEx, sGssStoreRekey, -+ sAcceptEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, - sZeroKnowledgePasswordAuthentication, sHostCertificate, -@@ -409,10 +420,20 @@ static struct { + sHostCertificate, +@@ -411,10 +421,20 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -2282,7 +2242,7 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1078,10 +1099,22 @@ process_server_config_line(ServerOptions +@@ -1091,10 +1111,22 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -2305,7 +2265,7 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1994,6 +2027,9 @@ dump_config(ServerOptions *o) +@@ -2005,6 +2037,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2313,12 +2273,13 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); #endif - #ifdef JPAKE - dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, -diff -up openssh-6.3p1/servconf.h.gsskex openssh-6.3p1/servconf.h ---- openssh-6.3p1/servconf.h.gsskex 2013-10-11 15:15:17.273216227 +0200 -+++ openssh-6.3p1/servconf.h 2013-10-11 15:15:17.292216139 +0200 -@@ -111,7 +111,10 @@ typedef struct { + dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(sKbdInteractiveAuthentication, +diff --git a/servconf.h b/servconf.h +index 4572066..37cfa9b 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -112,7 +112,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2329,11 +2290,12 @@ diff -up openssh-6.3p1/servconf.h.gsskex openssh-6.3p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-6.3p1/ssh-gss.h.gsskex openssh-6.3p1/ssh-gss.h ---- openssh-6.3p1/ssh-gss.h.gsskex 2013-02-25 01:24:44.000000000 +0100 -+++ openssh-6.3p1/ssh-gss.h 2013-10-11 15:15:17.294216130 +0200 +diff --git a/ssh-gss.h b/ssh-gss.h +index a99d7f0..0374c88 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2396,7 +2358,7 @@ diff -up openssh-6.3p1/ssh-gss.h.gsskex openssh-6.3p1/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -117,16 +134,30 @@ void ssh_gssapi_build_ctx(Gssctxt **); +@@ -119,16 +136,30 @@ void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); @@ -2429,10 +2391,24 @@ diff -up openssh-6.3p1/ssh-gss.h.gsskex openssh-6.3p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -up openssh-6.3p1/ssh_config.5.gsskex openssh-6.3p1/ssh_config.5 ---- openssh-6.3p1/ssh_config.5.gsskex 2013-07-18 08:11:50.000000000 +0200 -+++ openssh-6.3p1/ssh_config.5 2013-10-11 15:15:17.292216139 +0200 -@@ -529,11 +529,43 @@ Specifies whether user authentication ba +diff --git a/ssh_config b/ssh_config +index 6d1abaf..b0d343b 100644 +--- a/ssh_config ++++ b/ssh_config +@@ -26,6 +26,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP yes + # AddressFamily any +diff --git a/ssh_config.5 b/ssh_config.5 +index b580392..e7accd6 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -682,11 +682,43 @@ Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2477,22 +2453,11 @@ diff -up openssh-6.3p1/ssh_config.5.gsskex openssh-6.3p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-6.3p1/ssh_config.gsskex openssh-6.3p1/ssh_config ---- openssh-6.3p1/ssh_config.gsskex 2013-10-11 15:15:17.265216264 +0200 -+++ openssh-6.3p1/ssh_config 2013-10-11 15:15:17.292216139 +0200 -@@ -26,6 +26,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP yes - # AddressFamily any -diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c ---- openssh-6.3p1/sshconnect2.c.gsskex 2013-10-11 15:15:17.251216330 +0200 -+++ openssh-6.3p1/sshconnect2.c 2013-10-11 15:28:22.617529416 +0200 -@@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho +diff --git a/sshconnect2.c b/sshconnect2.c +index adbbfc7..cadf234 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -158,9 +158,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { Kex *kex; @@ -2527,7 +2492,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c if (options.ciphers == (char *)-1) { logit("No valid ciphers for protocol version 2 given, using defaults."); options.ciphers = NULL; -@@ -207,6 +232,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -196,6 +221,17 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; @@ -2545,10 +2510,10 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); -@@ -218,10 +254,30 @@ ssh_kex2(char *host, struct sockaddr *ho - kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; +@@ -208,10 +244,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; kex->kex[KEX_ECDH_SHA2] = kexecdh_client; + kex->kex[KEX_C25519_SHA256] = kexc25519_client; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; @@ -2576,7 +2541,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c xxx_kex = kex; dispatch_run(DISPATCH_BLOCK, &kex->done, kex); -@@ -317,6 +373,7 @@ void input_gssapi_token(int type, u_int3 +@@ -301,6 +357,7 @@ void input_gssapi_token(int type, u_int32_t, void *); void input_gssapi_hash(int type, u_int32_t, void *); void input_gssapi_error(int, u_int32_t, void *); void input_gssapi_errtok(int, u_int32_t, void *); @@ -2584,7 +2549,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c #endif void userauth(Authctxt *, char *); -@@ -332,6 +389,11 @@ static char *authmethods_get(void); +@@ -316,6 +373,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2596,7 +2561,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -636,19 +698,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -613,19 +675,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2630,7 +2595,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -745,8 +819,8 @@ input_gssapi_response(int type, u_int32_ +@@ -722,8 +796,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -2641,7 +2606,7 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -855,6 +929,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -832,6 +906,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) free(msg); free(lang); } @@ -2690,10 +2655,11 @@ diff -up openssh-6.3p1/sshconnect2.c.gsskex openssh-6.3p1/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh-6.3p1/sshd.c.gsskex openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.gsskex 2013-10-11 15:15:17.277216209 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-11 15:15:17.294216130 +0200 -@@ -125,6 +125,10 @@ +diff --git a/sshd.c b/sshd.c +index 24ab272..e4e406e 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -122,6 +122,10 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2704,7 +2670,7 @@ diff -up openssh-6.3p1/sshd.c.gsskex openssh-6.3p1/sshd.c #ifdef LIBWRAP #include #include -@@ -1794,10 +1798,13 @@ main(int ac, char **av) +@@ -1744,10 +1748,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2718,70 +2684,9 @@ diff -up openssh-6.3p1/sshd.c.gsskex openssh-6.3p1/sshd.c if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2130,6 +2137,60 @@ main(int ac, char **av) - /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); - -+#ifdef USE_SECURITY_SESSION_API -+ /* -+ * Create a new security session for use by the new user login if -+ * the current session is the root session or we are not launched -+ * by inetd (eg: debugging mode or server mode). We do not -+ * necessarily need to create a session if we are launched from -+ * inetd because Panther xinetd will create a session for us. -+ * -+ * The only case where this logic will fail is if there is an -+ * inetd running in a non-root session which is not creating -+ * new sessions for us. Then all the users will end up in the -+ * same session (bad). -+ * -+ * When the client exits, the session will be destroyed for us -+ * automatically. -+ * -+ * We must create the session before any credentials are stored -+ * (including AFS pags, which happens a few lines below). -+ */ -+ { -+ OSStatus err = 0; -+ SecuritySessionId sid = 0; -+ SessionAttributeBits sattrs = 0; -+ -+ err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); -+ if (err) -+ error("SessionGetInfo() failed with error %.8X", -+ (unsigned) err); -+ else -+ debug("Current Session ID is %.8X / Session Attributes are %.8X", -+ (unsigned) sid, (unsigned) sattrs); -+ -+ if (inetd_flag && !(sattrs & sessionIsRoot)) -+ debug("Running in inetd mode in a non-root session... " -+ "assuming inetd created the session for us."); -+ else { -+ debug("Creating new security session..."); -+ err = SessionCreate(0, sessionHasTTY | sessionIsRemote); -+ if (err) -+ error("SessionCreate() failed with error %.8X", -+ (unsigned) err); -+ -+ err = SessionGetInfo(callerSecuritySession, &sid, -+ &sattrs); -+ if (err) -+ error("SessionGetInfo() failed with error %.8X", -+ (unsigned) err); -+ else -+ debug("New Session ID is %.8X / Session Attributes are %.8X", -+ (unsigned) sid, (unsigned) sattrs); -+ } -+ } -+#endif -+ - /* - * We don't want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is -@@ -2551,6 +2612,48 @@ do_ssh2_kex(void) - - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); +@@ -2488,6 +2495,48 @@ do_ssh2_kex(void) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( + list_hostkey_types()); +#ifdef GSSAPI + { @@ -2828,10 +2733,10 @@ diff -up openssh-6.3p1/sshd.c.gsskex openssh-6.3p1/sshd.c /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; -@@ -2558,6 +2661,13 @@ do_ssh2_kex(void) - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; +@@ -2496,6 +2545,13 @@ do_ssh2_kex(void) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; @@ -2842,10 +2747,24 @@ diff -up openssh-6.3p1/sshd.c.gsskex openssh-6.3p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-6.3p1/sshd_config.5.gsskex openssh-6.3p1/sshd_config.5 ---- openssh-6.3p1/sshd_config.5.gsskex 2013-10-11 15:15:17.274216223 +0200 -+++ openssh-6.3p1/sshd_config.5 2013-10-11 15:15:17.294216130 +0200 -@@ -484,12 +484,40 @@ Specifies whether user authentication ba +diff --git a/sshd_config b/sshd_config +index c1b7c03..adfd7b1 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -91,6 +91,8 @@ ChallengeResponseAuthentication no + # GSSAPI options + GSSAPIAuthentication yes + GSSAPICleanupCredentials no ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange 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 95b5f8c..1fb002d 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -493,12 +493,40 @@ Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2886,15 +2805,3 @@ diff -up openssh-6.3p1/sshd_config.5.gsskex openssh-6.3p1/sshd_config.5 .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed -diff -up openssh-6.3p1/sshd_config.gsskex openssh-6.3p1/sshd_config ---- openssh-6.3p1/sshd_config.gsskex 2013-10-11 15:15:17.277216209 +0200 -+++ openssh-6.3p1/sshd_config 2013-10-11 15:15:17.294216130 +0200 -@@ -92,6 +92,8 @@ ChallengeResponseAuthentication no - GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes - GSSAPICleanupCredentials no -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will diff --git a/openssh-6.3p1-keycat.patch b/openssh-6.6p1-keycat.patch similarity index 72% rename from openssh-6.3p1-keycat.patch rename to openssh-6.6p1-keycat.patch index 6105d09..d30dedb 100644 --- a/openssh-6.3p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,6 +1,8 @@ -diff -up openssh-6.3p1/HOWTO.ssh-keycat.keycat openssh-6.3p1/HOWTO.ssh-keycat ---- openssh-6.3p1/HOWTO.ssh-keycat.keycat 2013-10-10 15:16:33.445566916 +0200 -+++ openssh-6.3p1/HOWTO.ssh-keycat 2013-10-10 15:16:33.445566916 +0200 +diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat +new file mode 100644 +index 0000000..630ec62 +--- /dev/null ++++ b/HOWTO.ssh-keycat @@ -0,0 +1,12 @@ +The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys +of an user in any environment. This includes environments with @@ -14,9 +16,10 @@ diff -up openssh-6.3p1/HOWTO.ssh-keycat.keycat openssh-6.3p1/HOWTO.ssh-keycat + PubkeyAuthentication yes + + -diff -up openssh-6.3p1/Makefile.in.keycat openssh-6.3p1/Makefile.in ---- openssh-6.3p1/Makefile.in.keycat 2013-10-10 15:16:33.442566930 +0200 -+++ openssh-6.3p1/Makefile.in 2013-10-10 15:16:33.445566916 +0200 +diff --git a/Makefile.in b/Makefile.in +index 411eadb..4ab6717 100644 +--- a/Makefile.in ++++ b/Makefile.in @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -34,17 +37,17 @@ diff -up openssh-6.3p1/Makefile.in.keycat openssh-6.3p1/Makefile.in LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ canohost.o channels.o cipher.o cipher-aes.o \ -@@ -172,6 +173,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) +@@ -176,6 +177,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11 ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) -+ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keycat.o -+ $(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS) ++ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o ++ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -@@ -279,6 +283,7 @@ install-files: +@@ -283,6 +287,7 @@ install-files: $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ fi @@ -52,15 +55,16 @@ diff -up openssh-6.3p1/Makefile.in.keycat openssh-6.3p1/Makefile.in $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff -up openssh-6.3p1/auth2-pubkey.c.keycat openssh-6.3p1/auth2-pubkey.c ---- openssh-6.3p1/auth2-pubkey.c.keycat 2013-10-10 15:16:33.429566992 +0200 -+++ openssh-6.3p1/auth2-pubkey.c 2013-10-10 15:16:33.445566916 +0200 -@@ -606,6 +606,14 @@ user_key_command_allowed2(struct passwd +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index c0ae0d4..cb0f931 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -600,6 +600,14 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) _exit(1); } +#ifdef WITH_SELINUX -+ if (ssh_selinux_setup_env_variables() < 0) { ++ if (sshd_selinux_setup_env_variables() < 0) { + error ("failed to copy environment: %s", + strerror(errno)); + _exit(127); @@ -70,19 +74,41 @@ diff -up openssh-6.3p1/auth2-pubkey.c.keycat openssh-6.3p1/auth2-pubkey.c execl(options.authorized_keys_command, options.authorized_keys_command, user_pw->pw_name, NULL); -diff -up openssh-6.3p1/openbsd-compat/port-linux.c.keycat openssh-6.3p1/openbsd-compat/port-linux.c ---- openssh-6.3p1/openbsd-compat/port-linux.c.keycat 2013-10-10 15:16:33.435566964 +0200 -+++ openssh-6.3p1/openbsd-compat/port-linux.c 2013-10-10 15:32:19.946065189 +0200 -@@ -313,7 +313,7 @@ ssh_selinux_getctxbyname(char *pwname, +diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c +index d04f4ed..0077dd7 100644 +--- a/openbsd-compat/port-linux-sshd.c ++++ b/openbsd-compat/port-linux-sshd.c +@@ -53,6 +53,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 ++sshd_selinux_enabled(void) ++{ ++ static int enabled = -1; ++ ++ if (enabled == -1) { ++ enabled = (is_selinux_enabled() == 1); ++ debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ } ++ ++ return (enabled); ++} ++ + /* Send audit message */ + static int + sshd_selinux_send_audit_message(int success, security_context_t default_context, +@@ -307,7 +321,7 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int --ssh_selinux_setup_pam_variables(void) -+ssh_selinux_setup_variables(int(*set_it)(const char *, const char *)) +-sshd_selinux_setup_pam_variables(void) ++sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) { const char *reqlvl; char *role; -@@ -324,16 +324,16 @@ ssh_selinux_setup_pam_variables(void) +@@ -318,16 +332,16 @@ sshd_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); @@ -102,34 +128,82 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.keycat openssh-6.3p1/openbsd- if (role != NULL) free(role); -@@ -341,6 +341,24 @@ ssh_selinux_setup_pam_variables(void) +@@ -335,6 +349,24 @@ sshd_selinux_setup_pam_variables(void) return rv; } +static int -+ssh_selinux_setup_pam_variables(void) ++sshd_selinux_setup_pam_variables(void) +{ -+ return ssh_selinux_setup_variables(do_pam_putenv); ++ return sshd_selinux_setup_variables(do_pam_putenv); +} + +static int -+do_setenv(char *name, char *value) ++do_setenv(char *name, const char *value) +{ + return setenv(name, value, 1); +} + +int -+ssh_selinux_setup_env_variables(void) ++sshd_selinux_setup_env_variables(void) +{ -+ return ssh_selinux_setup_variables(do_setenv); ++ return sshd_selinux_setup_variables(do_setenv); +} + /* Set the execution context to the default for the specified user */ void - ssh_selinux_setup_exec_context(char *pwname) -diff -up openssh-6.3p1/ssh-keycat.c.keycat openssh-6.3p1/ssh-keycat.c ---- openssh-6.3p1/ssh-keycat.c.keycat 2013-10-10 15:16:33.446566911 +0200 -+++ openssh-6.3p1/ssh-keycat.c 2013-10-10 15:16:33.446566911 +0200 + sshd_selinux_setup_exec_context(char *pwname) +@@ -343,7 +375,7 @@ sshd_selinux_setup_exec_context(char *pwname) + int r = 0; + security_context_t default_ctx = NULL; + +- if (!ssh_selinux_enabled()) ++ if (!sshd_selinux_enabled()) + return; + + if (options.use_pam) { +@@ -414,7 +446,7 @@ sshd_selinux_copy_context(void) + { + security_context_t *ctx; + +- if (!ssh_selinux_enabled()) ++ if (!sshd_selinux_enabled()) + return; + + if (getexeccon((security_context_t *)&ctx) != 0) { +diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h +index b18893c..cb51f99 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -25,8 +25,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 0d39ab2..0dae387 100644 +--- a/platform.c ++++ b/platform.c +@@ -102,7 +102,7 @@ platform_setusercontext(struct passwd *pw) + { + #ifdef WITH_SELINUX + /* Cache selinux status for later use */ +- (void)ssh_selinux_enabled(); ++ (void)sshd_selinux_enabled(); + #endif + + #ifdef USE_SOLARIS_PROJECTS +diff --git a/ssh-keycat.c b/ssh-keycat.c +new file mode 100644 +index 0000000..f8ed7af +--- /dev/null ++++ b/ssh-keycat.c @@ -0,0 +1,238 @@ +/* + * Redistribution and use in source and binary forms, with or without diff --git a/openssh-5.8p1-keyperm.patch b/openssh-6.6p1-keyperm.patch similarity index 56% rename from openssh-5.8p1-keyperm.patch rename to openssh-6.6p1-keyperm.patch index 6167c14..fccb328 100644 --- a/openssh-5.8p1-keyperm.patch +++ b/openssh-6.6p1-keyperm.patch @@ -1,15 +1,15 @@ -diff -up openssh-5.8p1/authfile.c.keyperm openssh-5.8p1/authfile.c ---- openssh-5.8p1/authfile.c.keyperm 2010-12-01 02:03:39.000000000 +0100 -+++ openssh-5.8p1/authfile.c 2011-04-21 16:43:36.859648916 +0200 -@@ -57,6 +57,7 @@ - #include - #include - #include -+#include +diff -up openssh-6.6p1/authfile.c.keyperm openssh-6.6p1/authfile.c +--- openssh-6.6p1/authfile.c.keyperm 2014-02-04 01:20:15.000000000 +0100 ++++ openssh-6.6p1/authfile.c 2014-05-05 15:20:43.075246776 +0200 +@@ -54,6 +54,7 @@ - #include "xmalloc.h" - #include "cipher.h" -@@ -600,6 +612,13 @@ key_perm_ok(int fd, const char *filename + #include + #include ++#include + #include + #include + #include +@@ -979,6 +980,13 @@ key_perm_ok(int fd, const char *filename #ifdef HAVE_CYGWIN if (check_ntsec(filename)) #endif diff --git a/openssh-6.3p1-kuserok.patch b/openssh-6.6p1-kuserok.patch similarity index 67% rename from openssh-6.3p1-kuserok.patch rename to openssh-6.6p1-kuserok.patch index 60688db..d2d07b6 100644 --- a/openssh-6.3p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.3p1/auth-krb5.c.kuserok openssh-6.3p1/auth-krb5.c ---- openssh-6.3p1/auth-krb5.c.kuserok 2013-10-11 21:41:42.889087613 +0200 -+++ openssh-6.3p1/auth-krb5.c 2013-10-11 21:41:42.905087537 +0200 -@@ -55,6 +55,20 @@ +diff -up openssh-6.6p1/auth-krb5.c.kuserok openssh-6.6p1/auth-krb5.c +--- openssh-6.6p1/auth-krb5.c.kuserok 2013-10-24 01:53:02.000000000 +0200 ++++ openssh-6.6p1/auth-krb5.c 2014-05-07 10:42:00.883534478 +0200 +@@ -54,6 +54,20 @@ extern ServerOptions options; @@ -22,18 +22,19 @@ diff -up openssh-6.3p1/auth-krb5.c.kuserok openssh-6.3p1/auth-krb5.c static int krb5_init(void *context) { -@@ -159,7 +173,7 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -157,8 +171,7 @@ auth_krb5_password(Authctxt *authctxt, c if (problem) goto out; -- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { +- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, +- authctxt->pw->pw_name)) { ++ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name)) { problem = -1; goto out; } -diff -up openssh-6.3p1/gss-serv-krb5.c.kuserok openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.kuserok 2013-10-11 21:41:42.901087556 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:46:42.898673597 +0200 +diff -up openssh-6.6p1/gss-serv-krb5.c.kuserok openssh-6.6p1/gss-serv-krb5.c +--- openssh-6.6p1/gss-serv-krb5.c.kuserok 2014-05-07 10:35:30.792053846 +0200 ++++ openssh-6.6p1/gss-serv-krb5.c 2014-05-07 10:35:30.801053812 +0200 @@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr int); @@ -51,9 +52,9 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.kuserok openssh-6.3p1/gss-serv-krb5.c retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); -diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c ---- openssh-6.3p1/servconf.c.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.c 2013-10-11 21:48:24.664194016 +0200 +diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c +--- openssh-6.6p1/servconf.c.kuserok 2014-05-07 10:35:30.783053881 +0200 ++++ openssh-6.6p1/servconf.c 2014-05-07 10:39:13.133189061 +0200 @@ -157,6 +157,7 @@ initialize_server_options(ServerOptions options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; @@ -62,16 +63,16 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c } void -@@ -310,6 +311,8 @@ fill_default_server_options(ServerOption +@@ -312,6 +313,8 @@ fill_default_server_options(ServerOption options->version_addendum = xstrdup(""); if (options->show_patchlevel == -1) options->show_patchlevel = 0; + if (options->use_kuserok == -1) -+ options->use_kuserok = 1; ++ options->use_kuserok = 0; /* Turn privilege separation on by default */ if (use_privsep == -1) -@@ -336,7 +339,7 @@ typedef enum { +@@ -338,7 +341,7 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -80,7 +81,7 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, -@@ -409,11 +412,13 @@ static struct { +@@ -410,11 +413,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -94,7 +95,7 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1515,6 +1520,10 @@ process_server_config_line(ServerOptions +@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions *activep = value; break; @@ -105,7 +106,7 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1815,6 +1824,7 @@ copy_set_server_options(ServerOptions *d +@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -113,7 +114,7 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2055,6 +2065,7 @@ dump_config(ServerOptions *o) +@@ -2062,6 +2072,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); @@ -121,10 +122,10 @@ diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.3p1/servconf.h.kuserok openssh-6.3p1/servconf.h ---- openssh-6.3p1/servconf.h.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.h 2013-10-11 21:41:42.907087528 +0200 -@@ -174,6 +174,7 @@ typedef struct { +diff -up openssh-6.6p1/servconf.h.kuserok openssh-6.6p1/servconf.h +--- openssh-6.6p1/servconf.h.kuserok 2014-05-07 10:35:30.783053881 +0200 ++++ openssh-6.6p1/servconf.h 2014-05-07 10:35:30.802053808 +0200 +@@ -173,6 +173,7 @@ typedef struct { int num_permitted_opens; @@ -132,21 +133,21 @@ diff -up openssh-6.3p1/servconf.h.kuserok openssh-6.3p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5 ---- openssh-6.3p1/sshd_config.5.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config.5 2013-10-11 21:41:42.907087528 +0200 -@@ -675,6 +675,10 @@ Specifies whether to automatically destr +diff -up openssh-6.6p1/sshd_config.5.kuserok openssh-6.6p1/sshd_config.5 +--- openssh-6.6p1/sshd_config.5.kuserok 2014-05-07 10:35:30.786053870 +0200 ++++ openssh-6.6p1/sshd_config.5 2014-05-07 10:43:04.784285016 +0200 +@@ -697,6 +697,10 @@ Specifies whether to automatically destr file on logout. The default is .Dq yes . +.It Cm KerberosUseKuserok +Specifies whether to look at .k5login file for user's aliases. +The default is -+.Dq yes . ++.Dq no . .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. -@@ -833,6 +837,7 @@ Available keywords are +@@ -862,6 +866,7 @@ Available keywords are .Cm HostbasedUsesNameFromPacketOnly , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -154,14 +155,14 @@ diff -up openssh-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5 .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , -diff -up openssh-6.3p1/sshd_config.kuserok openssh-6.3p1/sshd_config ---- openssh-6.3p1/sshd_config.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config 2013-10-11 21:41:42.907087528 +0200 -@@ -86,6 +86,7 @@ ChallengeResponseAuthentication no +diff -up openssh-6.6p1/sshd_config.kuserok openssh-6.6p1/sshd_config +--- openssh-6.6p1/sshd_config.kuserok 2014-05-07 10:35:30.803053804 +0200 ++++ openssh-6.6p1/sshd_config 2014-05-07 10:38:30.735354431 +0200 +@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosGetAFSToken no -+#KerberosUseKuserok yes ++#KerberosUseKuserok no # GSSAPI options - #GSSAPIAuthentication no + GSSAPIAuthentication yes diff --git a/openssh-6.3p1-ldap.patch b/openssh-6.6p1-ldap.patch similarity index 95% rename from openssh-6.3p1-ldap.patch rename to openssh-6.6p1-ldap.patch index 052973c..961cdf5 100644 --- a/openssh-6.3p1-ldap.patch +++ b/openssh-6.6p1-ldap.patch @@ -1,116 +1,8 @@ -diff -up openssh-6.2p1/configure.ac.ldap openssh-6.2p1/configure.ac ---- openssh-6.2p1/configure.ac.ldap 2013-03-20 02:55:15.000000000 +0100 -+++ openssh-6.2p1/configure.ac 2013-03-25 21:27:15.888248071 +0100 -@@ -1509,6 +1509,106 @@ AC_ARG_WITH([audit], - esac ] - ) - -+# Check whether user wants LDAP support -+LDAP_MSG="no" -+INSTALL_SSH_LDAP_HELPER="" -+AC_ARG_WITH(ldap, -+ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)], -+ [ -+ if test "x$withval" != "xno" ; then -+ -+ INSTALL_SSH_LDAP_HELPER="yes" -+ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" -+ -+ if test "x$withval" != "xyes" ; then -+ CPPFLAGS="$CPPFLAGS -I${withval}/include" -+ LDFLAGS="$LDFLAGS -L${withval}/lib" -+ fi -+ -+ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) -+ LDAP_MSG="yes" -+ -+ AC_CHECK_HEADERS(lber.h) -+ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate )) -+ AC_CHECK_HEADERS(ldap_ssl.h) -+ -+ AC_ARG_WITH(ldap-lib, -+ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) -+ -+ if test -z "$with_ldap_lib"; then -+ with_ldap_lib=auto -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then -+ AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes) -+ AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then -+ AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then -+ AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes) -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes) -+ fi -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then -+ AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib"; then -+ AC_MSG_ERROR(could not locate a valid LDAP library) -+ fi -+ -+ AC_MSG_CHECKING([for working LDAP support]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [(void)ldap_init(0, 0);], -+ [AC_MSG_RESULT(yes)], -+ [ -+ AC_MSG_RESULT(no) -+ AC_MSG_ERROR([** Incomplete or missing ldap libraries **]) -+ ]) -+ AC_CHECK_FUNCS( \ -+ ldap_init \ -+ ldap_get_lderrno \ -+ ldap_set_lderrno \ -+ ldap_parse_result \ -+ ldap_memfree \ -+ ldap_controls_free \ -+ ldap_set_option \ -+ ldap_get_option \ -+ ldapssl_init \ -+ ldap_start_tls_s \ -+ ldap_pvt_tls_set_option \ -+ ldap_initialize \ -+ ) -+ AC_CHECK_FUNCS(ldap_set_rebind_proc, -+ AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [ldap_set_rebind_proc(0, 0, 0);], -+ [ac_cv_ldap_set_rebind_proc=3], -+ [ac_cv_ldap_set_rebind_proc=2]) -+ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) -+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) -+ ) -+ fi -+ ] -+) -+AC_SUBST(INSTALL_SSH_LDAP_HELPER) -+ - dnl Checks for library functions. Please keep in alphabetical order - AC_CHECK_FUNCS([ \ - arc4random \ -diff -up openssh-6.2p1/HOWTO.ldap-keys.ldap openssh-6.2p1/HOWTO.ldap-keys ---- openssh-6.2p1/HOWTO.ldap-keys.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/HOWTO.ldap-keys 2013-03-25 21:27:15.889248078 +0100 +diff --git a/HOWTO.ldap-keys b/HOWTO.ldap-keys +new file mode 100644 +index 0000000..dd5f5cc +--- /dev/null ++++ b/HOWTO.ldap-keys @@ -0,0 +1,108 @@ + +HOW TO START @@ -220,9 +112,513 @@ diff -up openssh-6.2p1/HOWTO.ldap-keys.ldap openssh-6.2p1/HOWTO.ldap-keys +5) Author + Jan F. Chadima + -diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c ---- openssh-6.2p1/ldapbody.c.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/ldapbody.c 2013-03-25 21:27:15.889248078 +0100 +diff --git a/Makefile.in b/Makefile.in +index 28a8ec4..411eadb 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh + ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass + SFTP_SERVER=$(libexecdir)/sftp-server + SSH_KEYSIGN=$(libexecdir)/ssh-keysign ++SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper ++SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + PRIVSEP_PATH=@PRIVSEP_PATH@ + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +@@ -60,8 +62,9 @@ XAUTH_PATH=@XAUTH_PATH@ + LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ + EXEEXT=@EXEEXT@ + MANFMT=@MANFMT@ ++INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ + +-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) ++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-ldap-helper$(EXEEXT) + + LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o \ +@@ -98,8 +101,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o + +-MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out +-MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 ++MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap-helper.8.out ssh-ldap.conf.5.out ++MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 ssh-ldap-helper.8 ssh-ldap.conf.5 + MANTYPE = @MANTYPE@ + + CONFIGFILES=sshd_config.out ssh_config.out moduli.out +@@ -170,6 +173,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readco + ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o ++ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ++ + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o + $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + +@@ -273,6 +279,10 @@ install-files: + $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) + $(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) ++ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ ++ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ ++ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ ++ fi + $(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 +@@ -289,6 +299,10 @@ install-files: + $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 + $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 ++ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ ++ $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ ++ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ ++ fi + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 +@@ -318,6 +332,13 @@ install-sysconf: + else \ + echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ + fi ++ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ ++ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ ++ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ ++ else \ ++ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ ++ fi ; \ ++ fi + + host-key: ssh-keygen$(EXEEXT) + @if [ -z "$(DESTDIR)" ] ; then \ +@@ -381,6 +402,8 @@ uninstall: + -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) ++ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) ++ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 +@@ -392,6 +415,7 @@ uninstall: + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 ++ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + + regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c +diff --git a/configure.ac b/configure.ac +index 7c6ce08..722a19e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1625,6 +1625,106 @@ if test "x$use_pie" != "xno"; then + fi + fi + ++# Check whether user wants LDAP support ++LDAP_MSG="no" ++INSTALL_SSH_LDAP_HELPER="" ++AC_ARG_WITH(ldap, ++ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)], ++ [ ++ if test "x$withval" != "xno" ; then ++ ++ INSTALL_SSH_LDAP_HELPER="yes" ++ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" ++ ++ if test "x$withval" != "xyes" ; then ++ CPPFLAGS="$CPPFLAGS -I${withval}/include" ++ LDFLAGS="$LDFLAGS -L${withval}/lib" ++ fi ++ ++ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) ++ LDAP_MSG="yes" ++ ++ AC_CHECK_HEADERS(lber.h) ++ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate )) ++ AC_CHECK_HEADERS(ldap_ssl.h) ++ ++ AC_ARG_WITH(ldap-lib, ++ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) ++ ++ if test -z "$with_ldap_lib"; then ++ with_ldap_lib=auto ++ fi ++ ++ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then ++ AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes) ++ fi ++ ++ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then ++ AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes) ++ fi ++ ++ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then ++ AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes) ++ if test -z "$found_ldap_lib"; then ++ AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes) ++ fi ++ if test -z "$found_ldap_lib"; then ++ AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes) ++ fi ++ if test -z "$found_ldap_lib"; then ++ AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes) ++ fi ++ fi ++ ++ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then ++ AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes) ++ fi ++ ++ if test -z "$found_ldap_lib"; then ++ AC_MSG_ERROR(could not locate a valid LDAP library) ++ fi ++ ++ AC_MSG_CHECKING([for working LDAP support]) ++ AC_TRY_COMPILE( ++ [#include ++ #include ], ++ [(void)ldap_init(0, 0);], ++ [AC_MSG_RESULT(yes)], ++ [ ++ AC_MSG_RESULT(no) ++ AC_MSG_ERROR([** Incomplete or missing ldap libraries **]) ++ ]) ++ AC_CHECK_FUNCS( \ ++ ldap_init \ ++ ldap_get_lderrno \ ++ ldap_set_lderrno \ ++ ldap_parse_result \ ++ ldap_memfree \ ++ ldap_controls_free \ ++ ldap_set_option \ ++ ldap_get_option \ ++ ldapssl_init \ ++ ldap_start_tls_s \ ++ ldap_pvt_tls_set_option \ ++ ldap_initialize \ ++ ) ++ AC_CHECK_FUNCS(ldap_set_rebind_proc, ++ AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc]) ++ AC_TRY_COMPILE( ++ [#include ++ #include ], ++ [ldap_set_rebind_proc(0, 0, 0);], ++ [ac_cv_ldap_set_rebind_proc=3], ++ [ac_cv_ldap_set_rebind_proc=2]) ++ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) ++ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) ++ ) ++ fi ++ ] ++) ++AC_SUBST(INSTALL_SSH_LDAP_HELPER) ++ + dnl Checks for library functions. Please keep in alphabetical order + AC_CHECK_FUNCS([ \ + Blowfish_initstate \ +diff --git a/ldap-helper.c b/ldap-helper.c +new file mode 100644 +index 0000000..e95a94a +--- /dev/null ++++ b/ldap-helper.c +@@ -0,0 +1,155 @@ ++/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ ++/* ++ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "ldapincludes.h" ++#include "log.h" ++#include "misc.h" ++#include "xmalloc.h" ++#include "ldapconf.h" ++#include "ldapbody.h" ++#include ++#include ++ ++static int config_debug = 0; ++int config_exclusive_config_file = 0; ++static char *config_file_name = "/etc/ssh/ldap.conf"; ++static char *config_single_user = NULL; ++static int config_verbose = SYSLOG_LEVEL_VERBOSE; ++int config_warning_config_file = 0; ++extern char *__progname; ++ ++static void ++usage(void) ++{ ++ fprintf(stderr, "usage: %s [options]\n", ++ __progname); ++ fprintf(stderr, "Options:\n"); ++ fprintf(stderr, " -d Output the log messages to stderr.\n"); ++ fprintf(stderr, " -e Check the config file for unknown commands.\n"); ++ fprintf(stderr, " -f file Use alternate config file (default is /etc/ssh/ldap.conf).\n"); ++ fprintf(stderr, " -s user Do not demonize, send the user's key to stdout.\n"); ++ fprintf(stderr, " -v Increase verbosity of the debug output (implies -d).\n"); ++ fprintf(stderr, " -w Warn on unknown commands in the config file.\n"); ++ exit(1); ++} ++ ++/* ++ * Main program for the ssh pka ldap agent. ++ */ ++ ++int ++main(int ac, char **av) ++{ ++ int opt; ++ FILE *outfile = NULL; ++ ++ __progname = ssh_get_progname(av[0]); ++ ++ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); ++ ++ /* ++ * Initialize option structure to indicate that no values have been ++ * set. ++ */ ++ initialize_options(); ++ ++ /* Parse command-line arguments. */ ++ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { ++ switch (opt) { ++ case 'd': ++ config_debug = 1; ++ break; ++ ++ case 'e': ++ config_exclusive_config_file = 1; ++ config_warning_config_file = 1; ++ break; ++ ++ case 'f': ++ config_file_name = optarg; ++ break; ++ ++ case 's': ++ config_single_user = optarg; ++ outfile = fdopen (dup (fileno (stdout)), "w"); ++ break; ++ ++ case 'v': ++ config_debug = 1; ++ if (config_verbose < SYSLOG_LEVEL_DEBUG3) ++ config_verbose++; ++ break; ++ ++ case 'w': ++ config_warning_config_file = 1; ++ break; ++ ++ case '?': ++ default: ++ usage(); ++ break; ++ } ++ } ++ ++ /* Initialize loging */ ++ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); ++ ++ if (ac != optind) ++ fatal ("illegal extra parameter %s", av[1]); ++ ++ /* Ensure that fds 0 and 2 are open or directed to /dev/null */ ++ if (config_debug == 0) ++ sanitise_stdfd(); ++ ++ /* Read config file */ ++ read_config_file(config_file_name); ++ fill_default_options(); ++ if (config_verbose == SYSLOG_LEVEL_DEBUG3) { ++ debug3 ("=== Configuration ==="); ++ dump_config(); ++ debug3 ("=== *** ==="); ++ } ++ ++ ldap_checkconfig(); ++ ldap_do_connect(); ++ ++ if (config_single_user) { ++ process_user (config_single_user, outfile); ++ } else { ++ usage(); ++ fatal ("Not yet implemented"); ++/* TODO ++ * open unix socket a run the loop on it ++ */ ++ } ++ ++ ldap_do_close(); ++ return 0; ++} ++ ++/* Ugly hack */ ++void *buffer_get_string(Buffer *b, u_int *l) { return NULL; } ++void buffer_put_string(Buffer *b, const void *f, u_int l) {} ++ +diff --git a/ldap-helper.h b/ldap-helper.h +new file mode 100644 +index 0000000..14cb29a +--- /dev/null ++++ b/ldap-helper.h +@@ -0,0 +1,32 @@ ++/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ ++/* ++ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef LDAP_HELPER_H ++#define LDAP_HELPER_H ++ ++extern int config_exclusive_config_file; ++extern int config_warning_config_file; ++ ++#endif /* LDAP_HELPER_H */ +diff --git a/ldap.conf b/ldap.conf +new file mode 100644 +index 0000000..42e38d3 +--- /dev/null ++++ b/ldap.conf +@@ -0,0 +1,88 @@ ++# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ ++# ++# This is the example configuration file for the OpenSSH ++# LDAP backend ++# ++# see ssh-ldap.conf(5) ++# ++ ++# URI with your LDAP server name. This allows to use ++# Unix Domain Sockets to connect to a local LDAP Server. ++#uri ldap://127.0.0.1/ ++#uri ldaps://127.0.0.1/ ++#uri ldapi://%2fvar%2frun%2fldapi_sock/ ++# Note: %2f encodes the '/' used as directory separator ++ ++# Another way to specify your LDAP server is to provide an ++# host name and the port of our LDAP server. Host name ++# must be resolvable without using LDAP. ++# Multiple hosts may be specified, each separated by a ++# space. How long nss_ldap takes to failover depends on ++# whether your LDAP client library supports configurable ++# network or connect timeouts (see bind_timelimit). ++#host 127.0.0.1 ++ ++# The port. ++# Optional: default is 389. ++#port 389 ++ ++# The distinguished name to bind to the server with. ++# Optional: default is to bind anonymously. ++#binddn cn=openssh_keys,dc=example,dc=org ++ ++# The credentials to bind with. ++# Optional: default is no credential. ++#bindpw TopSecret ++ ++# The distinguished name of the search base. ++#base dc=example,dc=org ++ ++# The LDAP version to use (defaults to 3 ++# if supported by client library) ++#ldap_version 3 ++ ++# The search scope. ++#scope sub ++#scope one ++#scope base ++ ++# Search timelimit ++#timelimit 30 ++ ++# Bind/connect timelimit ++#bind_timelimit 30 ++ ++# Reconnect policy: hard (default) will retry connecting to ++# the software with exponential backoff, soft will fail ++# immediately. ++#bind_policy hard ++ ++# SSL setup, may be implied by URI also. ++#ssl no ++#ssl on ++#ssl start_tls ++ ++# OpenLDAP SSL options ++# Require and verify server certificate (yes/no) ++# Default is to use libldap's default behavior, which can be configured in ++# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for ++# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". ++#tls_checkpeer hard ++ ++# CA certificates for server certificate verification ++# At least one of these are required if tls_checkpeer is "yes" ++#tls_cacertfile /etc/ssl/ca.cert ++#tls_cacertdir /etc/pki/tls/certs ++ ++# Seed the PRNG if /dev/urandom is not provided ++#tls_randfile /var/run/egd-pool ++ ++# SSL cipher suite ++# See man ciphers for syntax ++#tls_ciphers TLSv1 ++ ++# Client certificate and key ++# Use these, if your server requires client authentication. ++#tls_cert ++#tls_key ++ +diff --git a/ldapbody.c b/ldapbody.c +new file mode 100644 +index 0000000..3029108 +--- /dev/null ++++ b/ldapbody.c @@ -0,0 +1,494 @@ +/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -718,9 +1114,11 @@ diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c + return; +} + -diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h ---- openssh-6.2p1/ldapbody.h.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/ldapbody.h 2013-03-25 21:27:15.889248078 +0100 +diff --git a/ldapbody.h b/ldapbody.h +new file mode 100644 +index 0000000..665dca2 +--- /dev/null ++++ b/ldapbody.h @@ -0,0 +1,37 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -759,8 +1157,11 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + +#endif /* LDAPBODY_H */ + ---- openssh-6.4p1/ldapconf.c.ldap 2013-11-26 10:31:03.513794385 +0100 -+++ openssh-6.4p1/ldapconf.c 2013-11-26 10:38:15.474635149 +0100 +diff --git a/ldapconf.c b/ldapconf.c +new file mode 100644 +index 0000000..525060a +--- /dev/null ++++ b/ldapconf.c @@ -0,0 +1,720 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1482,9 +1883,11 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + dump_cfg_string(lAccountClass, options.logdir); +} + -diff -up openssh-6.2p2/ldapconf.h.ldap openssh-6.2p2/ldapconf.h ---- openssh-6.2p2/ldapconf.h.ldap 2013-06-07 15:10:05.602942689 +0200 -+++ openssh-6.2p2/ldapconf.h 2013-06-07 15:10:24.928857566 +0200 +diff --git a/ldapconf.h b/ldapconf.h +new file mode 100644 +index 0000000..2cb550c +--- /dev/null ++++ b/ldapconf.h @@ -0,0 +1,72 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1558,296 +1961,11 @@ diff -up openssh-6.2p2/ldapconf.h.ldap openssh-6.2p2/ldapconf.h +void dump_config(void); + +#endif /* LDAPCONF_H */ -diff -up openssh-6.2p1/ldap.conf.ldap openssh-6.2p1/ldap.conf ---- openssh-6.2p1/ldap.conf.ldap 2013-03-25 21:27:15.891248091 +0100 -+++ openssh-6.2p1/ldap.conf 2013-03-25 21:27:15.891248091 +0100 -@@ -0,0 +1,88 @@ -+# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ -+# -+# This is the example configuration file for the OpenSSH -+# LDAP backend -+# -+# see ssh-ldap.conf(5) -+# -+ -+# URI with your LDAP server name. This allows to use -+# Unix Domain Sockets to connect to a local LDAP Server. -+#uri ldap://127.0.0.1/ -+#uri ldaps://127.0.0.1/ -+#uri ldapi://%2fvar%2frun%2fldapi_sock/ -+# Note: %2f encodes the '/' used as directory separator -+ -+# Another way to specify your LDAP server is to provide an -+# host name and the port of our LDAP server. Host name -+# must be resolvable without using LDAP. -+# Multiple hosts may be specified, each separated by a -+# space. How long nss_ldap takes to failover depends on -+# whether your LDAP client library supports configurable -+# network or connect timeouts (see bind_timelimit). -+#host 127.0.0.1 -+ -+# The port. -+# Optional: default is 389. -+#port 389 -+ -+# The distinguished name to bind to the server with. -+# Optional: default is to bind anonymously. -+#binddn cn=openssh_keys,dc=example,dc=org -+ -+# The credentials to bind with. -+# Optional: default is no credential. -+#bindpw TopSecret -+ -+# The distinguished name of the search base. -+#base dc=example,dc=org -+ -+# The LDAP version to use (defaults to 3 -+# if supported by client library) -+#ldap_version 3 -+ -+# The search scope. -+#scope sub -+#scope one -+#scope base -+ -+# Search timelimit -+#timelimit 30 -+ -+# Bind/connect timelimit -+#bind_timelimit 30 -+ -+# Reconnect policy: hard (default) will retry connecting to -+# the software with exponential backoff, soft will fail -+# immediately. -+#bind_policy hard -+ -+# SSL setup, may be implied by URI also. -+#ssl no -+#ssl on -+#ssl start_tls -+ -+# OpenLDAP SSL options -+# Require and verify server certificate (yes/no) -+# Default is to use libldap's default behavior, which can be configured in -+# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for -+# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". -+#tls_checkpeer hard -+ -+# CA certificates for server certificate verification -+# At least one of these are required if tls_checkpeer is "yes" -+#tls_cacertfile /etc/ssl/ca.cert -+#tls_cacertdir /etc/pki/tls/certs -+ -+# Seed the PRNG if /dev/urandom is not provided -+#tls_randfile /var/run/egd-pool -+ -+# SSL cipher suite -+# See man ciphers for syntax -+#tls_ciphers TLSv1 -+ -+# Client certificate and key -+# Use these, if your server requires client authentication. -+#tls_cert -+#tls_key -+ -diff -up openssh-6.2p1/ldap-helper.c.ldap openssh-6.2p1/ldap-helper.c ---- openssh-6.2p1/ldap-helper.c.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldap-helper.c 2013-03-25 21:27:15.892248097 +0100 -@@ -0,0 +1,155 @@ -+/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapbody.h" -+#include -+#include -+ -+static int config_debug = 0; -+int config_exclusive_config_file = 0; -+static char *config_file_name = "/etc/ssh/ldap.conf"; -+static char *config_single_user = NULL; -+static int config_verbose = SYSLOG_LEVEL_VERBOSE; -+int config_warning_config_file = 0; -+extern char *__progname; -+ -+static void -+usage(void) -+{ -+ fprintf(stderr, "usage: %s [options]\n", -+ __progname); -+ fprintf(stderr, "Options:\n"); -+ fprintf(stderr, " -d Output the log messages to stderr.\n"); -+ fprintf(stderr, " -e Check the config file for unknown commands.\n"); -+ fprintf(stderr, " -f file Use alternate config file (default is /etc/ssh/ldap.conf).\n"); -+ fprintf(stderr, " -s user Do not demonize, send the user's key to stdout.\n"); -+ fprintf(stderr, " -v Increase verbosity of the debug output (implies -d).\n"); -+ fprintf(stderr, " -w Warn on unknown commands in the config file.\n"); -+ exit(1); -+} -+ -+/* -+ * Main program for the ssh pka ldap agent. -+ */ -+ -+int -+main(int ac, char **av) -+{ -+ int opt; -+ FILE *outfile = NULL; -+ -+ __progname = ssh_get_progname(av[0]); -+ -+ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); -+ -+ /* -+ * Initialize option structure to indicate that no values have been -+ * set. -+ */ -+ initialize_options(); -+ -+ /* Parse command-line arguments. */ -+ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { -+ switch (opt) { -+ case 'd': -+ config_debug = 1; -+ break; -+ -+ case 'e': -+ config_exclusive_config_file = 1; -+ config_warning_config_file = 1; -+ break; -+ -+ case 'f': -+ config_file_name = optarg; -+ break; -+ -+ case 's': -+ config_single_user = optarg; -+ outfile = fdopen (dup (fileno (stdout)), "w"); -+ break; -+ -+ case 'v': -+ config_debug = 1; -+ if (config_verbose < SYSLOG_LEVEL_DEBUG3) -+ config_verbose++; -+ break; -+ -+ case 'w': -+ config_warning_config_file = 1; -+ break; -+ -+ case '?': -+ default: -+ usage(); -+ break; -+ } -+ } -+ -+ /* Initialize loging */ -+ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); -+ -+ if (ac != optind) -+ fatal ("illegal extra parameter %s", av[1]); -+ -+ /* Ensure that fds 0 and 2 are open or directed to /dev/null */ -+ if (config_debug == 0) -+ sanitise_stdfd(); -+ -+ /* Read config file */ -+ read_config_file(config_file_name); -+ fill_default_options(); -+ if (config_verbose == SYSLOG_LEVEL_DEBUG3) { -+ debug3 ("=== Configuration ==="); -+ dump_config(); -+ debug3 ("=== *** ==="); -+ } -+ -+ ldap_checkconfig(); -+ ldap_do_connect(); -+ -+ if (config_single_user) { -+ process_user (config_single_user, outfile); -+ } else { -+ usage(); -+ fatal ("Not yet implemented"); -+/* TODO -+ * open unix socket a run the loop on it -+ */ -+ } -+ -+ ldap_do_close(); -+ return 0; -+} -+ -+/* Ugly hack */ -+void *buffer_get_string(Buffer *b, u_int *l) { return NULL; } -+void buffer_put_string(Buffer *b, const void *f, u_int l) {} -+ -diff -up openssh-6.2p1/ldap-helper.h.ldap openssh-6.2p1/ldap-helper.h ---- openssh-6.2p1/ldap-helper.h.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldap-helper.h 2013-03-25 21:27:15.892248097 +0100 -@@ -0,0 +1,32 @@ -+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAP_HELPER_H -+#define LDAP_HELPER_H -+ -+extern int config_exclusive_config_file; -+extern int config_warning_config_file; -+ -+#endif /* LDAP_HELPER_H */ -diff -up openssh-6.2p1/ldapincludes.h.ldap openssh-6.2p1/ldapincludes.h ---- openssh-6.2p1/ldapincludes.h.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldapincludes.h 2013-03-25 21:27:15.892248097 +0100 +diff --git a/ldapincludes.h b/ldapincludes.h +new file mode 100644 +index 0000000..8539bdc +--- /dev/null ++++ b/ldapincludes.h @@ -0,0 +1,41 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1890,9 +2008,11 @@ diff -up openssh-6.2p1/ldapincludes.h.ldap openssh-6.2p1/ldapincludes.h +#endif + +#endif /* LDAPINCLUDES_H */ -diff -up openssh-6.2p1/ldapmisc.c.ldap openssh-6.2p1/ldapmisc.c ---- openssh-6.2p1/ldapmisc.c.ldap 2013-03-25 21:27:15.893248104 +0100 -+++ openssh-6.2p1/ldapmisc.c 2013-03-25 21:27:15.893248104 +0100 +diff --git a/ldapmisc.c b/ldapmisc.c +new file mode 100644 +index 0000000..de23c0c +--- /dev/null ++++ b/ldapmisc.c @@ -0,0 +1,79 @@ + +#include "ldapincludes.h" @@ -1973,9 +2093,11 @@ diff -up openssh-6.2p1/ldapmisc.c.ldap openssh-6.2p1/ldapmisc.c +} +#endif + -diff -up openssh-6.2p1/ldapmisc.h.ldap openssh-6.2p1/ldapmisc.h ---- openssh-6.2p1/ldapmisc.h.ldap 2013-03-25 21:27:15.893248104 +0100 -+++ openssh-6.2p1/ldapmisc.h 2013-03-25 21:27:15.893248104 +0100 +diff --git a/ldapmisc.h b/ldapmisc.h +new file mode 100644 +index 0000000..4c271df +--- /dev/null ++++ b/ldapmisc.h @@ -0,0 +1,35 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -2012,106 +2134,11 @@ diff -up openssh-6.2p1/ldapmisc.h.ldap openssh-6.2p1/ldapmisc.h + +#endif /* LDAPMISC_H */ + -diff -up openssh-6.2p1/Makefile.in.ldap openssh-6.2p1/Makefile.in ---- openssh-6.2p1/Makefile.in.ldap 2013-03-25 21:27:15.850247822 +0100 -+++ openssh-6.2p1/Makefile.in 2013-03-25 21:27:57.356518817 +0100 -@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh - ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass - SFTP_SERVER=$(libexecdir)/sftp-server - SSH_KEYSIGN=$(libexecdir)/ssh-keysign -+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper -+SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -60,8 +62,9 @@ XAUTH_PATH=@XAUTH_PATH@ - LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ - EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ -+INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ - --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) -+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-ldap-helper$(EXEEXT) - - LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ -@@ -95,8 +98,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o - --MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out --MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 -+MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out -+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5 - MANTYPE = @MANTYPE@ - - CONFIGFILES=sshd_config.out ssh_config.out moduli.out -@@ -164,6 +167,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -266,6 +272,10 @@ install-files: - $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) - $(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) -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ -+ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ -+ fi - $(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 -@@ -282,6 +292,10 @@ install-files: - $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 - $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ -+ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ -+ fi - -rm -f $(DESTDIR)$(bindir)/slogin - ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 -@@ -311,6 +325,13 @@ install-sysconf: - else \ - echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ - fi -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ -+ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ -+ else \ -+ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ -+ fi ; \ -+ fi - - host-key: ssh-keygen$(EXEEXT) - @if [ -z "$(DESTDIR)" ] ; then \ -@@ -368,6 +389,8 @@ uninstall: - -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 -@@ -379,6 +402,7 @@ uninstall: - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 - - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c -diff -up openssh-6.2p1/openssh-lpk-openldap.schema.ldap openssh-6.2p1/openssh-lpk-openldap.schema ---- openssh-6.2p1/openssh-lpk-openldap.schema.ldap 2013-03-25 21:27:15.894248110 +0100 -+++ openssh-6.2p1/openssh-lpk-openldap.schema 2013-03-25 21:27:15.894248110 +0100 +diff --git a/openssh-lpk-openldap.schema b/openssh-lpk-openldap.schema +new file mode 100644 +index 0000000..c84f90f +--- /dev/null ++++ b/openssh-lpk-openldap.schema @@ -0,0 +1,21 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2134,9 +2161,11 @@ diff -up openssh-6.2p1/openssh-lpk-openldap.schema.ldap openssh-6.2p1/openssh-lp + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff -up openssh-6.2p1/openssh-lpk-sun.schema.ldap openssh-6.2p1/openssh-lpk-sun.schema ---- openssh-6.2p1/openssh-lpk-sun.schema.ldap 2013-03-25 21:27:15.894248110 +0100 -+++ openssh-6.2p1/openssh-lpk-sun.schema 2013-03-25 21:27:15.894248110 +0100 +diff --git a/openssh-lpk-sun.schema b/openssh-lpk-sun.schema +new file mode 100644 +index 0000000..3136673 +--- /dev/null ++++ b/openssh-lpk-sun.schema @@ -0,0 +1,23 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2161,9 +2190,106 @@ diff -up openssh-6.2p1/openssh-lpk-sun.schema.ldap openssh-6.2p1/openssh-lpk-sun + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff -up openssh-6.2p2/ssh-ldap.conf.5.ldap openssh-6.2p2/ssh-ldap.conf.5 ---- openssh-6.2p2/ssh-ldap.conf.5.ldap 2013-06-07 15:10:05.604942680 +0200 -+++ openssh-6.2p2/ssh-ldap.conf.5 2013-06-07 15:10:24.928857566 +0200 +diff --git a/ssh-ldap-helper.8 b/ssh-ldap-helper.8 +new file mode 100644 +index 0000000..5d2d7be +--- /dev/null ++++ b/ssh-ldap-helper.8 +@@ -0,0 +1,79 @@ ++.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $ ++.\" ++.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. ++.\" ++.\" Permission to use, copy, modify, and distribute this software for any ++.\" purpose with or without fee is hereby granted, provided that the above ++.\" copyright notice and this permission notice appear in all copies. ++.\" ++.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++.\" ++.Dd $Mdocdate: April 29 2010 $ ++.Dt SSH-LDAP-HELPER 8 ++.Os ++.Sh NAME ++.Nm ssh-ldap-helper ++.Nd sshd helper program for ldap support ++.Sh SYNOPSIS ++.Nm ssh-ldap-helper ++.Op Fl devw ++.Op Fl f Ar file ++.Op Fl s Ar user ++.Sh DESCRIPTION ++.Nm ++is used by ++.Xr sshd 1 ++to access keys provided by an LDAP. ++.Nm ++is disabled by default and can only be enabled in the ++sshd configuration file ++.Pa /etc/ssh/sshd_config ++by setting ++.Cm AuthorizedKeysCommand ++to ++.Dq /usr/libexec/ssh-ldap-wrapper . ++.Pp ++.Nm ++is not intended to be invoked by the user, but from ++.Xr sshd 8 via ++.Xr ssh-ldap-wrapper . ++.Pp ++The options are as follows: ++.Bl -tag -width Ds ++.It Fl d ++Set the debug mode; ++.Nm ++prints all logs to stderr instead of syslog. ++.It Fl e ++Implies \-w; ++.Nm ++halts if it encounters an unknown item in the ldap.conf file. ++.It Fl f ++.Nm ++uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). ++.It Fl s ++.Nm ++prints out the user's keys to stdout and exits. ++.It Fl v ++Implies \-d; ++increases verbosity. ++.It Fl w ++.Nm ++writes warnings about unknown items in the ldap.conf configuration file. ++.El ++.Sh SEE ALSO ++.Xr sshd 8 , ++.Xr sshd_config 5 , ++.Xr ssh-ldap.conf 5 , ++.Sh HISTORY ++.Nm ++first appeared in ++OpenSSH 5.5 + PKA-LDAP . ++.Sh AUTHORS ++.An Jan F. Chadima Aq jchadima@redhat.com +diff --git a/ssh-ldap-wrapper b/ssh-ldap-wrapper +new file mode 100644 +index 0000000..cb500aa +--- /dev/null ++++ b/ssh-ldap-wrapper +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" ++ +diff --git a/ssh-ldap.conf.5 b/ssh-ldap.conf.5 +new file mode 100644 +index 0000000..f7081b8 +--- /dev/null ++++ b/ssh-ldap.conf.5 @@ -0,0 +1,379 @@ +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ +.\" @@ -2544,94 +2670,3 @@ diff -up openssh-6.2p2/ssh-ldap.conf.5.ldap openssh-6.2p2/ssh-ldap.conf.5 +OpenSSH 5.5 + PKA-LDAP . +.Sh AUTHORS +.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.2p1/ssh-ldap-helper.8.ldap openssh-6.2p1/ssh-ldap-helper.8 ---- openssh-6.2p1/ssh-ldap-helper.8.ldap 2013-03-25 21:27:15.895248117 +0100 -+++ openssh-6.2p1/ssh-ldap-helper.8 2013-03-25 21:27:15.895248117 +0100 -@@ -0,0 +1,79 @@ -+.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $ -+.\" -+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. -+.\" -+.\" Permission to use, copy, modify, and distribute this software for any -+.\" purpose with or without fee is hereby granted, provided that the above -+.\" copyright notice and this permission notice appear in all copies. -+.\" -+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+.\" -+.Dd $Mdocdate: April 29 2010 $ -+.Dt SSH-LDAP-HELPER 8 -+.Os -+.Sh NAME -+.Nm ssh-ldap-helper -+.Nd sshd helper program for ldap support -+.Sh SYNOPSIS -+.Nm ssh-ldap-helper -+.Op Fl devw -+.Op Fl f Ar file -+.Op Fl s Ar user -+.Sh DESCRIPTION -+.Nm -+is used by -+.Xr sshd 1 -+to access keys provided by an LDAP. -+.Nm -+is disabled by default and can only be enabled in the -+sshd configuration file -+.Pa /etc/ssh/sshd_config -+by setting -+.Cm AuthorizedKeysCommand -+to -+.Dq /usr/libexec/ssh-ldap-wrapper . -+.Pp -+.Nm -+is not intended to be invoked by the user, but from -+.Xr sshd 8 via -+.Xr ssh-ldap-wrapper . -+.Pp -+The options are as follows: -+.Bl -tag -width Ds -+.It Fl d -+Set the debug mode; -+.Nm -+prints all logs to stderr instead of syslog. -+.It Fl e -+Implies \-w; -+.Nm -+halts if it encounters an unknown item in the ldap.conf file. -+.It Fl f -+.Nm -+uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). -+.It Fl s -+.Nm -+prints out the user's keys to stdout and exits. -+.It Fl v -+Implies \-d; -+increases verbosity. -+.It Fl w -+.Nm -+writes warnings about unknown items in the ldap.conf configuration file. -+.El -+.Sh SEE ALSO -+.Xr sshd 8 , -+.Xr sshd_config 5 , -+.Xr ssh-ldap.conf 5 , -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.2p1/ssh-ldap-wrapper.ldap openssh-6.2p1/ssh-ldap-wrapper ---- openssh-6.2p1/ssh-ldap-wrapper.ldap 2013-03-25 21:27:15.896248124 +0100 -+++ openssh-6.2p1/ssh-ldap-wrapper 2013-03-25 21:27:15.896248124 +0100 -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" -+ diff --git a/openssh-6.1p1-log-usepam-no.patch b/openssh-6.6p1-log-usepam-no.patch similarity index 54% rename from openssh-6.1p1-log-usepam-no.patch rename to openssh-6.6p1-log-usepam-no.patch index 64cec2c..bd3048c 100644 --- a/openssh-6.1p1-log-usepam-no.patch +++ b/openssh-6.6p1-log-usepam-no.patch @@ -1,7 +1,8 @@ -diff -up openssh-6.1p1/sshd.c.log-usepam-no openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.log-usepam-no 2012-09-14 20:54:58.000000000 +0200 -+++ openssh-6.1p1/sshd.c 2012-09-14 20:55:42.289477749 +0200 -@@ -1617,6 +1617,10 @@ main(int ac, char **av) +diff --git a/sshd.c b/sshd.c +index a7b8b6a..24ab272 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1620,6 +1620,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, &cfg, NULL); @@ -12,15 +13,16 @@ diff -up openssh-6.1p1/sshd.c.log-usepam-no openssh-6.1p1/sshd.c seed_rng(); /* Fill in default values for those options not explicitly set. */ -diff -up openssh-6.1p1/sshd_config.log-usepam-no openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.log-usepam-no 2012-09-14 20:54:58.514255748 +0200 -+++ openssh-6.1p1/sshd_config 2012-09-14 20:54:58.551255954 +0200 -@@ -95,6 +95,8 @@ GSSAPICleanupCredentials no +diff --git a/sshd_config b/sshd_config +index 36cb27a..c1b7c03 100644 +--- 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 UsePAM yes + #AllowAgentForwarding yes diff --git a/openssh-6.3p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch similarity index 51% rename from openssh-6.3p1-privsep-selinux.patch rename to openssh-6.6p1-privsep-selinux.patch index 529468c..6507647 100644 --- a/openssh-6.3p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -1,12 +1,13 @@ -diff -up openssh-6.3p1/openbsd-compat/port-linux.c.privsep-selinux openssh-6.3p1/openbsd-compat/port-linux.c ---- openssh-6.3p1/openbsd-compat/port-linux.c.privsep-selinux 2013-10-10 14:58:20.634762245 +0200 -+++ openssh-6.3p1/openbsd-compat/port-linux.c 2013-10-10 15:13:57.864306950 +0200 -@@ -503,6 +503,25 @@ ssh_selinux_change_context(const char *n - free(newctx); +diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c +index c18524e..d04f4ed 100644 +--- a/openbsd-compat/port-linux-sshd.c ++++ b/openbsd-compat/port-linux-sshd.c +@@ -409,6 +409,25 @@ sshd_selinux_setup_exec_context(char *pwname) + debug3("%s: done", __func__); } +void -+ssh_selinux_copy_context(void) ++sshd_selinux_copy_context(void) +{ + security_context_t *ctx; + @@ -24,34 +25,36 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.privsep-selinux openssh-6.3p1 + } +} + - #endif /* WITH_SELINUX */ - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-6.3p1/openbsd-compat/port-linux.h.privsep-selinux openssh-6.3p1/openbsd-compat/port-linux.h ---- openssh-6.3p1/openbsd-compat/port-linux.h.privsep-selinux 2011-01-25 02:16:18.000000000 +0100 -+++ openssh-6.3p1/openbsd-compat/port-linux.h 2013-10-10 14:58:20.634762245 +0200 -@@ -24,6 +24,7 @@ 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_copy_context(void); - void ssh_selinux_setfscreatecon(const char *); + #endif #endif -diff -up openssh-6.3p1/session.c.privsep-selinux openssh-6.3p1/session.c ---- openssh-6.3p1/session.c.privsep-selinux 2013-10-10 14:58:20.617762326 +0200 -+++ openssh-6.3p1/session.c 2013-10-10 15:13:16.520503590 +0200 -@@ -1522,6 +1522,9 @@ do_setusercontext(struct passwd *pw) +diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h +index 8ef6cc4..b18893c 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -25,6 +25,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 2bcf818..b5dc144 100644 +--- a/session.c ++++ b/session.c +@@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *pw) pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); +#ifdef WITH_SELINUX -+ ssh_selinux_copy_context(); ++ sshd_selinux_copy_context(); +#endif safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); -@@ -1544,6 +1547,12 @@ do_setusercontext(struct passwd *pw) +@@ -1565,6 +1568,12 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -59,12 +62,12 @@ diff -up openssh-6.3p1/session.c.privsep-selinux openssh-6.3p1/session.c +#ifdef WITH_SELINUX + if (options.chroot_directory == NULL || + strcasecmp(options.chroot_directory, "none") == 0) -+ ssh_selinux_copy_context(); ++ 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"); -@@ -1808,9 +1817,6 @@ do_child(Session *s, const char *command +@@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -74,10 +77,11 @@ diff -up openssh-6.3p1/session.c.privsep-selinux openssh-6.3p1/session.c exit(sftp_server_main(i, argv, s->pw)); } -diff -up openssh-6.3p1/sshd.c.privsep-selinux openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.privsep-selinux 2013-10-10 14:58:20.632762255 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-10 14:58:20.635762241 +0200 -@@ -668,6 +668,10 @@ privsep_preauth_child(void) +diff --git a/sshd.c b/sshd.c +index 07f9926..a97f8b7 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -632,6 +632,10 @@ privsep_preauth_child(void) /* Demote the private keys to public keys. */ demote_sensitive_data(); @@ -88,14 +92,14 @@ diff -up openssh-6.3p1/sshd.c.privsep-selinux openssh-6.3p1/sshd.c /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, -@@ -811,6 +815,13 @@ privsep_postauth(Authctxt *authctxt) +@@ -768,6 +772,13 @@ privsep_postauth(Authctxt *authctxt) do_setusercontext(authctxt->pw); skip: +#ifdef WITH_SELINUX + /* switch SELinux content for root too */ + if (authctxt->pw->pw_uid == 0) { -+ ssh_selinux_copy_context(); ++ sshd_selinux_copy_context(); + } +#endif + diff --git a/openssh-6.3p1-redhat.patch b/openssh-6.6p1-redhat.patch similarity index 72% rename from openssh-6.3p1-redhat.patch rename to openssh-6.6p1-redhat.patch index 98df47d..a87d9bf 100644 --- a/openssh-6.3p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -1,6 +1,7 @@ -diff -up openssh-6.3p1/ssh_config.redhat openssh-6.3p1/ssh_config ---- openssh-6.3p1/ssh_config.redhat 2013-10-11 14:51:18.345876648 +0200 -+++ openssh-6.3p1/ssh_config 2013-10-11 15:13:05.429829266 +0200 +diff --git a/ssh_config b/ssh_config +index 03a228f..6d1abaf 100644 +--- a/ssh_config ++++ b/ssh_config @@ -46,3 +46,14 @@ # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com @@ -16,37 +17,10 @@ diff -up openssh-6.3p1/ssh_config.redhat openssh-6.3p1/ssh_config + SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT + SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE + SendEnv XMODIFIERS -diff -up openssh-6.3p1/sshd_config.0.redhat openssh-6.3p1/sshd_config.0 ---- openssh-6.3p1/sshd_config.0.redhat 2013-09-13 08:20:43.000000000 +0200 -+++ openssh-6.3p1/sshd_config.0 2013-10-11 14:51:18.345876648 +0200 -@@ -653,9 +653,9 @@ DESCRIPTION - - SyslogFacility - Gives the facility code that is used when logging messages from -- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, -- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The -- default is AUTH. -+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, -+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. -+ The default is AUTH. - - TCPKeepAlive - Specifies whether the system should send TCP keepalive messages -diff -up openssh-6.3p1/sshd_config.5.redhat openssh-6.3p1/sshd_config.5 ---- openssh-6.3p1/sshd_config.5.redhat 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/sshd_config.5 2013-10-11 14:51:18.346876643 +0200 -@@ -1095,7 +1095,7 @@ Note that this option applies to protoco - .It Cm SyslogFacility - Gives the facility code that is used when logging messages from - .Xr sshd 8 . --The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, -+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, - LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. - The default is AUTH. - .It Cm TCPKeepAlive -diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config ---- openssh-6.3p1/sshd_config.redhat 2013-10-11 14:51:18.343876657 +0200 -+++ openssh-6.3p1/sshd_config 2013-10-11 14:51:18.346876643 +0200 +diff --git a/sshd_config b/sshd_config +index c735429..e68ddee 100644 +--- a/sshd_config ++++ b/sshd_config @@ -10,6 +10,10 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -58,7 +32,7 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -21,9 +25,9 @@ +@@ -21,10 +25,10 @@ # HostKey for protocol version 1 #HostKey /etc/ssh/ssh_host_key # HostKeys for protocol version 2 @@ -66,11 +40,13 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config +HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key +-#HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_ecdsa_key ++HostKey /etc/ssh/ssh_host_ed25519_key # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h -@@ -35,6 +39,7 @@ +@@ -36,6 +40,7 @@ # Logging # obsoletes QuietMode and FascistLogging #SyslogFacility AUTH @@ -78,7 +54,7 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config #LogLevel INFO # Authentication: -@@ -70,9 +75,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -71,9 +76,11 @@ AuthorizedKeysFile .ssh/authorized_keys # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no @@ -90,31 +66,33 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config # Kerberos options #KerberosAuthentication no -@@ -82,7 +89,9 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -82,8 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys + #KerberosGetAFSToken no # GSSAPI options - #GSSAPIAuthentication no +-#GSSAPIAuthentication no +-#GSSAPICleanupCredentials yes +GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes +GSSAPICleanupCredentials no - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -94,11 +103,13 @@ AuthorizedKeysFile .ssh/authorized_keys + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +@@ -94,12 +101,12 @@ 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 ChallengeResponseAuthentication to 'no'. - #UsePAM no +-#UsePAM no +UsePAM yes #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no - #X11Forwarding no +-#X11Forwarding no +X11Forwarding yes #X11DisplayOffset 10 #X11UseLocalhost yes - #PrintMotd yes -@@ -120,6 +131,12 @@ UsePrivilegeSeparation sandbox # Defaul + #PermitTTY yes +@@ -122,6 +129,12 @@ UsePrivilegeSeparation sandbox # Default for new installations. # no default banner path #Banner none @@ -127,3 +105,33 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server +diff --git a/sshd_config.0 b/sshd_config.0 +index 413c260..87e7ee7 100644 +--- a/sshd_config.0 ++++ b/sshd_config.0 +@@ -675,9 +675,9 @@ DESCRIPTION + + SyslogFacility + Gives the facility code that is used when logging messages from +- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, +- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The +- default is AUTH. ++ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, ++ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. ++ The default is AUTH. + + TCPKeepAlive + Specifies whether the system should send TCP keepalive messages +diff --git a/sshd_config.5 b/sshd_config.5 +index ce71efe..12465c2 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1131,7 +1131,7 @@ Note that this option applies to protocol version 2 only. + .It Cm SyslogFacility + Gives the facility code that is used when logging messages from + .Xr sshd 8 . +-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, ++The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, + LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. + The default is AUTH. + .It Cm TCPKeepAlive diff --git a/openssh-6.3p1-role-mls.patch b/openssh-6.6p1-role-mls.patch similarity index 66% rename from openssh-6.3p1-role-mls.patch rename to openssh-6.6p1-role-mls.patch index 89d54b3..4740c99 100644 --- a/openssh-6.3p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -1,7 +1,8 @@ -diff -up openssh-6.3p1/auth-pam.c.role-mls openssh-6.3p1/auth-pam.c ---- openssh-6.3p1/auth-pam.c.role-mls 2013-10-10 14:34:43.799494546 +0200 -+++ openssh-6.3p1/auth-pam.c 2013-10-10 14:34:43.835494375 +0200 -@@ -1071,7 +1071,7 @@ is_pam_session_open(void) +diff --git a/auth-pam.c b/auth-pam.c +index d789bad..cd1a775 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -1068,7 +1068,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ int @@ -10,9 +11,10 @@ diff -up openssh-6.3p1/auth-pam.c.role-mls openssh-6.3p1/auth-pam.c { int ret = 1; #ifdef HAVE_PAM_PUTENV -diff -up openssh-6.3p1/auth-pam.h.role-mls openssh-6.3p1/auth-pam.h ---- openssh-6.3p1/auth-pam.h.role-mls 2004-09-11 14:17:26.000000000 +0200 -+++ openssh-6.3p1/auth-pam.h 2013-10-10 14:34:43.835494375 +0200 +diff --git a/auth-pam.h b/auth-pam.h +index a1a2b52..b109a5a 100644 +--- a/auth-pam.h ++++ b/auth-pam.h @@ -38,7 +38,7 @@ void do_pam_session(void); void do_pam_set_tty(const char *); void do_pam_setcred(int ); @@ -22,9 +24,10 @@ diff -up openssh-6.3p1/auth-pam.h.role-mls openssh-6.3p1/auth-pam.h char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh-6.3p1/auth.h.role-mls openssh-6.3p1/auth.h ---- openssh-6.3p1/auth.h.role-mls 2013-10-10 14:34:43.834494379 +0200 -+++ openssh-6.3p1/auth.h 2013-10-10 14:38:45.060348227 +0200 +diff --git a/auth.h b/auth.h +index 124e597..4605588 100644 +--- a/auth.h ++++ b/auth.h @@ -59,6 +59,9 @@ struct Authctxt { char *service; struct passwd *pw; /* set if 'valid' */ @@ -34,10 +37,11 @@ diff -up openssh-6.3p1/auth.h.role-mls openssh-6.3p1/auth.h +#endif void *kbdintctxt; char *info; /* Extra info for next auth_log */ - void *jpake_ctx; -diff -up openssh-6.3p1/auth1.c.role-mls openssh-6.3p1/auth1.c ---- openssh-6.3p1/auth1.c.role-mls 2013-06-02 00:01:24.000000000 +0200 -+++ openssh-6.3p1/auth1.c 2013-10-10 14:34:43.835494375 +0200 + #ifdef BSD_AUTH +diff --git a/auth1.c b/auth1.c +index 0f870b3..df040bb 100644 +--- a/auth1.c ++++ b/auth1.c @@ -381,6 +381,9 @@ do_authentication(Authctxt *authctxt) { u_int ulen; @@ -73,10 +77,11 @@ diff -up openssh-6.3p1/auth1.c.role-mls openssh-6.3p1/auth1.c /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh-6.3p1/auth2-gss.c.role-mls openssh-6.3p1/auth2-gss.c ---- openssh-6.3p1/auth2-gss.c.role-mls 2013-06-01 23:31:18.000000000 +0200 -+++ openssh-6.3p1/auth2-gss.c 2013-10-10 14:34:43.836494370 +0200 -@@ -256,6 +256,7 @@ input_gssapi_mic(int type, u_int32_t ple +diff --git a/auth2-gss.c b/auth2-gss.c +index c28a705..4756dd7 100644 +--- a/auth2-gss.c ++++ b/auth2-gss.c +@@ -251,6 +251,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) Authctxt *authctxt = ctxt; Gssctxt *gssctxt; int authenticated = 0; @@ -84,7 +89,7 @@ diff -up openssh-6.3p1/auth2-gss.c.role-mls openssh-6.3p1/auth2-gss.c Buffer b; gss_buffer_desc mic, gssbuf; u_int len; -@@ -268,7 +269,13 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -263,7 +264,13 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) mic.value = packet_get_string(&len); mic.length = len; @@ -99,7 +104,7 @@ diff -up openssh-6.3p1/auth2-gss.c.role-mls openssh-6.3p1/auth2-gss.c "gssapi-with-mic"); gssbuf.value = buffer_ptr(&b); -@@ -280,6 +287,8 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -275,6 +282,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) logit("GSSAPI MIC check failed"); buffer_free(&b); @@ -108,10 +113,11 @@ diff -up openssh-6.3p1/auth2-gss.c.role-mls openssh-6.3p1/auth2-gss.c free(mic.value); authctxt->postponed = 0; -diff -up openssh-6.3p1/auth2-hostbased.c.role-mls openssh-6.3p1/auth2-hostbased.c ---- openssh-6.3p1/auth2-hostbased.c.role-mls 2013-10-10 14:34:43.818494455 +0200 -+++ openssh-6.3p1/auth2-hostbased.c 2013-10-10 14:34:43.836494370 +0200 -@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index eca0069..95d678e 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -112,7 +112,15 @@ userauth_hostbased(Authctxt *authctxt) buffer_put_string(&b, session_id2, session_id2_len); /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -128,10 +134,11 @@ diff -up openssh-6.3p1/auth2-hostbased.c.role-mls openssh-6.3p1/auth2-hostbased. buffer_put_cstring(&b, service); buffer_put_cstring(&b, "hostbased"); buffer_put_string(&b, pkalg, alen); -diff -up openssh-6.3p1/auth2-pubkey.c.role-mls openssh-6.3p1/auth2-pubkey.c ---- openssh-6.3p1/auth2-pubkey.c.role-mls 2013-10-10 14:34:43.836494370 +0200 -+++ openssh-6.3p1/auth2-pubkey.c 2013-10-10 14:57:17.452062486 +0200 -@@ -127,9 +127,11 @@ userauth_pubkey(Authctxt *authctxt) +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 749b11a..c0ae0d4 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -133,9 +133,11 @@ userauth_pubkey(Authctxt *authctxt) } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -145,10 +152,11 @@ diff -up openssh-6.3p1/auth2-pubkey.c.role-mls openssh-6.3p1/auth2-pubkey.c buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, -diff -up openssh-6.3p1/auth2.c.role-mls openssh-6.3p1/auth2.c ---- openssh-6.3p1/auth2.c.role-mls 2013-10-10 14:34:43.819494451 +0200 -+++ openssh-6.3p1/auth2.c 2013-10-10 14:34:43.835494375 +0200 -@@ -221,6 +221,9 @@ input_userauth_request(int type, u_int32 +diff --git a/auth2.c b/auth2.c +index a5490c0..5f4f26f 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) Authctxt *authctxt = ctxt; Authmethod *m = NULL; char *user, *service, *method, *style = NULL; @@ -158,7 +166,7 @@ diff -up openssh-6.3p1/auth2.c.role-mls openssh-6.3p1/auth2.c int authenticated = 0; if (authctxt == NULL) -@@ -232,6 +235,11 @@ input_userauth_request(int type, u_int32 +@@ -226,6 +229,11 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); @@ -170,7 +178,7 @@ diff -up openssh-6.3p1/auth2.c.role-mls openssh-6.3p1/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -254,8 +262,15 @@ input_userauth_request(int type, u_int32 +@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -187,10 +195,11 @@ diff -up openssh-6.3p1/auth2.c.role-mls openssh-6.3p1/auth2.c userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); -diff -up openssh-6.3p1/misc.c.role-mls openssh-6.3p1/misc.c ---- openssh-6.3p1/misc.c.role-mls 2013-08-08 04:50:06.000000000 +0200 -+++ openssh-6.3p1/misc.c 2013-10-10 14:34:43.836494370 +0200 -@@ -429,6 +429,7 @@ char * +diff --git a/misc.c b/misc.c +index e4c8c32..f31cd91 100644 +--- a/misc.c ++++ b/misc.c +@@ -430,6 +430,7 @@ char * colon(char *cp) { int flag = 0; @@ -198,7 +207,7 @@ diff -up openssh-6.3p1/misc.c.role-mls openssh-6.3p1/misc.c if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -444,6 +445,13 @@ colon(char *cp) +@@ -445,6 +446,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -212,10 +221,11 @@ diff -up openssh-6.3p1/misc.c.role-mls openssh-6.3p1/misc.c } return NULL; } -diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c ---- openssh-6.3p1/monitor.c.role-mls 2013-10-10 14:34:43.821494441 +0200 -+++ openssh-6.3p1/monitor.c 2013-10-10 14:54:57.933725463 +0200 -@@ -149,6 +149,9 @@ int mm_answer_sign(int, Buffer *); +diff --git a/monitor.c b/monitor.c +index 531c4f9..229fada 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -145,6 +145,9 @@ int mm_answer_sign(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); @@ -225,7 +235,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c int mm_answer_authpassword(int, Buffer *); int mm_answer_bsdauthquery(int, Buffer *); int mm_answer_bsdauthrespond(int, Buffer *); -@@ -233,6 +236,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -219,6 +222,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 +245,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -853,6 +859,9 @@ mm_answer_pwnamallow(int sock, Buffer *m +@@ -805,6 +811,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) else { /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -245,7 +255,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); } #ifdef USE_PAM -@@ -894,6 +903,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -846,6 +855,25 @@ mm_answer_authserv(int sock, Buffer *m) return (0); } @@ -271,7 +281,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c int mm_answer_authpassword(int sock, Buffer *m) { -@@ -1269,7 +1297,7 @@ static int +@@ -1220,7 +1248,7 @@ static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; @@ -280,7 +290,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c u_int len; int fail = 0; -@@ -1295,6 +1323,8 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1246,6 +1274,8 @@ monitor_valid_userblob(u_char *data, u_int datalen) if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -289,7 +299,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1330,7 +1360,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1281,7 +1311,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, char *chost) { Buffer b; @@ -298,7 +308,7 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c u_int len; int fail = 0; -@@ -1347,6 +1377,8 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1298,6 +1328,8 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -307,23 +317,26 @@ diff -up openssh-6.3p1/monitor.c.role-mls openssh-6.3p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh-6.3p1/monitor.h.role-mls openssh-6.3p1/monitor.h ---- openssh-6.3p1/monitor.h.role-mls 2013-10-10 14:34:43.821494441 +0200 -+++ openssh-6.3p1/monitor.h 2013-10-10 14:34:43.837494365 +0200 -@@ -61,6 +61,9 @@ enum monitor_reqtype { - MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57, - MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59, - MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61, +diff --git a/monitor.h b/monitor.h +index 5bc41b5..20e2b4a 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -57,6 +57,10 @@ enum monitor_reqtype { + MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, + MONITOR_REQ_TERM = 50, + +#ifdef WITH_SELINUX + MONITOR_REQ_AUTHROLE = 80, +#endif - ++ MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-6.3p1/monitor_wrap.c.role-mls openssh-6.3p1/monitor_wrap.c ---- openssh-6.3p1/monitor_wrap.c.role-mls 2013-10-10 14:34:43.822494436 +0200 -+++ openssh-6.3p1/monitor_wrap.c 2013-10-10 14:34:43.838494360 +0200 -@@ -338,6 +338,25 @@ mm_inform_authserv(char *service, char * + MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 1a47e41..d1b6d99 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char *style) buffer_free(&m); } @@ -349,9 +362,10 @@ diff -up openssh-6.3p1/monitor_wrap.c.role-mls openssh-6.3p1/monitor_wrap.c /* Do the password authentication */ int mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh-6.3p1/monitor_wrap.h.role-mls openssh-6.3p1/monitor_wrap.h ---- openssh-6.3p1/monitor_wrap.h.role-mls 2013-10-10 14:34:43.822494436 +0200 -+++ openssh-6.3p1/monitor_wrap.h 2013-10-10 14:34:43.838494360 +0200 +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 18c2501..9d5e5ba 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h @@ -42,6 +42,9 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); @@ -362,36 +376,67 @@ diff -up openssh-6.3p1/monitor_wrap.h.role-mls openssh-6.3p1/monitor_wrap.h struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct Authctxt *, char *); -diff -up openssh-6.3p1/openbsd-compat/Makefile.in.role-mls openssh-6.3p1/openbsd-compat/Makefile.in ---- openssh-6.3p1/openbsd-compat/Makefile.in.role-mls 2013-05-10 08:28:56.000000000 +0200 -+++ openssh-6.3p1/openbsd-compat/Makefile.in 2013-10-10 14:34:43.838494360 +0200 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport +diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in +index 6ecfb93..b912dbe 100644 +--- a/openbsd-compat/Makefile.in ++++ b/openbsd-compat/Makefile.in +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o ++PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbsd-compat/port-linux.c ---- openssh-6.3p1/openbsd-compat/port-linux.c.role-mls 2013-06-02 00:07:32.000000000 +0200 -+++ openssh-6.3p1/openbsd-compat/port-linux.c 2013-10-10 14:40:41.841793347 +0200 -@@ -31,68 +31,271 @@ - - #include "log.h" - #include "xmalloc.h" +diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c +new file mode 100644 +index 0000000..c18524e +--- /dev/null ++++ b/openbsd-compat/port-linux-sshd.c +@@ -0,0 +1,414 @@ ++/* ++ * Copyright (c) 2005 Daniel Walsh ++ * Copyright (c) 2014 Petr Lautrbach ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* ++ * Linux-specific portability code - just SELinux support for sshd at present ++ */ ++ ++#include "includes.h" ++ ++#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) ++#include ++#include ++#include ++#include ++ ++#include "log.h" ++#include "xmalloc.h" +#include "servconf.h" - #include "port-linux.h" ++#include "port-linux.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" - - #ifdef WITH_SELINUX - #include - #include ++ ++#ifdef WITH_SELINUX ++#include ++#include +#include - #include ++#include +#include +#include + @@ -399,14 +444,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs +#include +#include +#endif - - #ifndef SSH_SELINUX_UNCONFINED_TYPE - # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" - #endif - --/* Wrapper around is_selinux_enabled() to log its return value once only */ --int --ssh_selinux_enabled(void) ++ +extern ServerOptions options; +extern Authctxt *the_authctxt; +extern int inetd_flag; @@ -414,10 +452,9 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + +/* Send audit message */ +static int -+send_audit_message(int success, security_context_t default_context, ++sshd_selinux_send_audit_message(int success, security_context_t default_context, + security_context_t selected_context) - { -- static int enabled = -1; ++{ + int rc=0; +#ifdef HAVE_LINUX_AUDIT + char *msg = NULL; @@ -509,7 +546,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + freecon(*sc); + *sc = strdup(context_str(con)); + context_free(con); -+ if (!*sc) ++ if (!*sc) + return -1; + } +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL @@ -532,10 +569,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + context_free(con); + goto out; + } - -- if (enabled == -1) { -- enabled = (is_selinux_enabled() == 1); -- debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ + debug("get_user_context: obtained context '%s' requested context '%s'", + obtained_raw, requested_raw); + if (strcmp(obtained_raw, requested_raw)) { @@ -550,7 +584,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + freecon(requested_raw); + freecon(obtained_raw); + context_free(con); - } ++ } +#endif + return 0; + out: @@ -558,8 +592,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + *sc = NULL; + return -1; +} - -- return (enabled); ++ +static void +ssh_selinux_get_role_level(char **role, const char **level) +{ @@ -575,46 +608,37 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + } + } + } - } - - /* Return the default security context for the given username */ - static security_context_t --ssh_selinux_getctxbyname(char *pwname) -+ssh_selinux_getctxbyname(char *pwname, ++} ++ ++/* 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) - { -- security_context_t sc = NULL; -- char *sename = NULL, *lvl = NULL; -- int r; ++{ + char *sename, *lvl; + char *role; + const char *reqlvl; + int r = 0; + context_t con = NULL; -+ ++ + ssh_selinux_get_role_level(&role, &reqlvl); - - #ifdef HAVE_GETSEUSERBYNAME -- if (getseuserbyname(pwname, &sename, &lvl) != 0) -- return NULL; ++ ++#ifdef HAVE_GETSEUSERBYNAME + if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { + sename = NULL; + lvl = NULL; + } - #else - sename = pwname; -- lvl = NULL; ++#else ++ sename = pwname; + lvl = ""; - #endif - ++#endif ++ + if (r == 0) { - #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -- r = get_default_context_with_level(sename, lvl, NULL, &sc); ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL + r = get_default_context_with_level(sename, lvl, NULL, default_sc); - #else -- r = get_default_context(sename, NULL, &sc); ++#else + r = get_default_context(sename, NULL, default_sc); - #endif ++#endif + } + + if (r == 0) { @@ -634,26 +658,12 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + reqlvl = ""; + + debug("%s: current connection level '%s'", __func__, reqlvl); - -- if (r != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: ssh_selinux_getctxbyname: " -- "security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to get default SELinux security " -- "context for %s", __func__, pwname); -- sc = NULL; -- break; -- default: -- fatal("%s: Failed to get default SELinux security " -- "context for %s (in enforcing mode)", -- __func__, pwname); - } -+ ++ ++ } ++ + if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { + r = get_user_context(sename, role, reqlvl, user_sc); -+ ++ + if (r == 0 && reqlvl != NULL && reqlvl[0]) { + security_context_t default_level_sc = *default_sc; + if (role != NULL && role[0]) { @@ -677,14 +687,13 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + if (r != 0) { + error("%s: Failed to get default SELinux security " + "context for %s", __func__, pwname); - } - - #ifdef HAVE_GETSEUSERBYNAME -@@ -100,7 +303,42 @@ ssh_selinux_getctxbyname(char *pwname) - free(lvl); - #endif - -- return sc; ++ } ++ ++#ifdef HAVE_GETSEUSERBYNAME ++ free(sename); ++ free(lvl); ++#endif ++ + if (role != NULL) + free(role); + if (con) @@ -695,7 +704,7 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + +/* Setup environment variables for pam_selinux */ +static int -+ssh_selinux_setup_pam_variables(void) ++sshd_selinux_setup_pam_variables(void) +{ + const char *reqlvl; + char *role; @@ -721,22 +730,22 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + free(role); + + return rv; - } - - /* Set the execution context to the default for the specified user */ -@@ -108,28 +346,71 @@ void - ssh_selinux_setup_exec_context(char *pwname) - { - security_context_t user_ctx = NULL; ++} ++ ++/* Set the execution context to the default for the specified user */ ++void ++sshd_selinux_setup_exec_context(char *pwname) ++{ ++ security_context_t user_ctx = NULL; + int r = 0; + security_context_t default_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; - ++ ++ if (!ssh_selinux_enabled()) ++ return; ++ + if (options.use_pam) { + /* do not compute context, just setup environment for pam_selinux */ -+ if (ssh_selinux_setup_pam_variables()) { ++ if (sshd_selinux_setup_pam_variables()) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); @@ -752,17 +761,15 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + return; + } + - debug3("%s: setting execution context", __func__); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -+ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); ++ 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("%s: Failed to set SELinux execution context %s for %s", + __func__, user_ctx, pwname); -+ } ++ } +#ifdef HAVE_SETKEYCREATECON + else if (setkeycreatecon(user_ctx) < 0) { + error("%s: Failed to set SELinux keyring creation context %s for %s", @@ -776,155 +783,113 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.role-mls openssh-6.3p1/openbs + if (r < 0 || user_ctx != default_ctx) { + /* audit just the case when user changed a role or there was + a failure */ -+ send_audit_message(r >= 0, default_ctx, user_ctx); ++ sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx); + } + if (r < 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); ++ switch (security_getenforce()) { ++ case -1: ++ fatal("%s: security_getenforce() failed", __func__); ++ case 0: + error("%s: SELinux failure. Continuing in permissive mode.", + __func__); - break; - default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); ++ break; ++ default: + fatal("%s: SELinux failure. Aborting connection.", + __func__); - } - } -- if (user_ctx != NULL) ++ } ++ } + if (user_ctx != NULL && user_ctx != default_ctx) - freecon(user_ctx); ++ freecon(user_ctx); + if (default_ctx != NULL) + freecon(default_ctx); - - debug3("%s: done", __func__); - } -@@ -147,7 +428,10 @@ 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? */ - -@@ -219,21 +503,6 @@ ssh_selinux_change_context(const char *n - free(newctx); ++ ++ debug3("%s: done", __func__); ++} ++ ++#endif ++#endif ++ +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 4637a7a..22ea8ef 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -103,37 +103,6 @@ ssh_selinux_getctxbyname(char *pwname) + return sc; } +-/* Set the execution context to the default for the specified user */ -void --ssh_selinux_setfscreatecon(const char *path) +-ssh_selinux_setup_exec_context(char *pwname) -{ -- security_context_t context; +- security_context_t user_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; -- if (path == NULL) { -- setfscreatecon(NULL); -- 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 (matchpathcon(path, 0700, &context) == 0) -- setfscreatecon(context); +- if (user_ctx != NULL) +- freecon(user_ctx); +- +- debug3("%s: done", __func__); -} - - #endif /* WITH_SELINUX */ + /* Set the TTY context for the specified user */ + void + ssh_selinux_setup_pty(char *pwname, const char *tty) +diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h +index e3d1004..8ef6cc4 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -22,9 +22,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-6.3p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.3p1/openbsd-compat/port-linux_part_2.c ---- openssh-6.3p1/openbsd-compat/port-linux_part_2.c.role-mls 2013-10-10 14:34:43.839494355 +0200 -+++ openssh-6.3p1/openbsd-compat/port-linux_part_2.c 2013-10-10 14:34:43.839494355 +0200 -@@ -0,0 +1,75 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2005 Daniel Walsh -+ * Copyright (c) 2006 Damien Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - just SELinux support at present -+ */ -+ -+#include "includes.h" -+ -+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) -+#include -+#include -+#include -+#include -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+#ifdef WITH_SELINUX -+#include -+#include -+#include -+ -+/* Wrapper around is_selinux_enabled() to log its return value once only */ -+int -+ssh_selinux_enabled(void) -+{ -+ static int enabled = -1; -+ -+ if (enabled == -1) { -+ enabled = (is_selinux_enabled() == 1); -+ debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ } -+ -+ return (enabled); -+} -+ -+void -+ssh_selinux_setfscreatecon(const char *path) -+{ -+ security_context_t context; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ if (path == NULL) { -+ setfscreatecon(NULL); -+ return; -+ } -+ if (matchpathcon(path, 0700, &context) == 0) -+ setfscreatecon(context); -+} -+ -+#endif /* WITH_SELINUX */ -+ -+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff -up openssh-6.3p1/sshd.c.role-mls openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.role-mls 2013-10-10 14:34:43.824494427 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-10 14:34:43.839494355 +0200 -@@ -2179,6 +2179,9 @@ main(int ac, char **av) +diff --git a/platform.c b/platform.c +index 30fc609..0d39ab2 100644 +--- a/platform.c ++++ b/platform.c +@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(struct passwd *pw) + } + #endif /* HAVE_SETPCRED */ + #ifdef WITH_SELINUX +- ssh_selinux_setup_exec_context(pw->pw_name); ++ sshd_selinux_setup_exec_context(pw->pw_name); + #endif + } + +diff --git a/sshd.c b/sshd.c +index 7523de9..07f9926 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2138,6 +2138,9 @@ main(int ac, char **av) restore_uid(); } #endif +#ifdef WITH_SELINUX -+ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); ++ sshd_selinux_setup_exec_context(authctxt->pw->pw_name); +#endif #ifdef USE_PAM if (options.use_pam) { diff --git a/sources b/sources index a583b69..a3faed2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a62b88b884df0b09b8a8c5789ac9e51b openssh-6.4p1.tar.gz +3e9800e6bca1fbac0eea4d41baa7f239 openssh-6.6p1.tar.gz From 0670469f970bfdc7b3b84d2c563a8763d0dc783e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 16 Aug 2014 19:11:21 +0000 Subject: [PATCH 005/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index cd35f65..52bb233 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -34,7 +34,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -501,6 +501,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Sat Aug 16 2014 Fedora Release Engineering - 6.6.1p1-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + * Wed Jul 16 2014 Mattias Ellert - 6.6.1p1-1 - Based on openssh-6.6.1p1-2.fc21 From 913439ce706adfb8b47df683bbf36c9ff739667d Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 22 Oct 2014 19:07:34 +0200 Subject: [PATCH 006/146] Based on openssh-6.6.1p1-5.fc21 --- gsi-openssh.spec | 27 +- openssh-6.6.1p1-NI_MAXHOST.patch | 76 ++ openssh-6.6.1p1-partial-success.patch | 16 + openssh-6.6.1p1-utf8-banner.patch | 994 ++++++++++++++++++++++++++ openssh-6.6p1-audit.patch | 26 +- openssh-6.6p1-fips.patch | 25 +- openssh-6.6p1-set_remote_ipaddr.patch | 87 +++ 7 files changed, 1228 insertions(+), 23 deletions(-) create mode 100644 openssh-6.6.1p1-NI_MAXHOST.patch create mode 100644 openssh-6.6.1p1-partial-success.patch create mode 100644 openssh-6.6.1p1-utf8-banner.patch create mode 100644 openssh-6.6p1-set_remote_ipaddr.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 52bb233..161c235 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,12 +29,12 @@ %global ldap 1 %global openssh_ver 6.6.1p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -136,6 +136,18 @@ Patch908: openssh-6.6p1-CVE-2014-2653.patch # OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 key exchange incorrectly # Disable the curve25519 KEX when speaking to OpenSSH 6.5 or 6.6 Patch909: openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch +# standardise on NI_MAXHOST for gethostname() string lengths (#1051490) +Patch910: openssh-6.6.1p1-NI_MAXHOST.patch +# set a client's address right after a connection is set +# http://bugzilla.mindrot.org/show_bug.cgi?id=2257 +Patch911: openssh-6.6p1-set_remote_ipaddr.patch +# apply RFC3454 stringprep to banners when possible +# https://bugzilla.mindrot.org/show_bug.cgi?id=2058 +# slightly changed patch from comment 10 +Patch912: openssh-6.6.1p1-utf8-banner.patch +# don't consider a partial success as a failure +# https://bugzilla.mindrot.org/show_bug.cgi?id=2270 +Patch913: openssh-6.6.1p1-partial-success.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch @@ -285,6 +297,10 @@ This version of OpenSSH has been modified to support GSI authentication. %patch907 -p1 -b .CLOCK_BOOTTIME %patch908 -p1 -b .CVE-2014-2653 %patch909 -p1 -b .6.6.1 +%patch910 -p1 -b .NI_MAXHOST +%patch911 -p1 -b .set_remote_ipaddr +%patch912 -p1 -b .utf8-banner +%patch913 -p1 -b .partial-success %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -457,7 +473,9 @@ getent passwd sshd >/dev/null || \ %files %defattr(-,root,root) -%doc CREDITS ChangeLog INSTALL LICENCE LICENSE.globus_usage OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO +%{!?_licensedir:%global license %%doc} +%license LICENCE LICENSE.globus_usage +%doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli %attr(0755,root,root) %{_bindir}/gsissh-keygen @@ -501,6 +519,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Wed Oct 22 2014 Mattias Ellert - 6.6.1p1-2 +- Based on openssh-6.6.1p1-5.fc21 + * Sat Aug 16 2014 Fedora Release Engineering - 6.6.1p1-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild diff --git a/openssh-6.6.1p1-NI_MAXHOST.patch b/openssh-6.6.1p1-NI_MAXHOST.patch new file mode 100644 index 0000000..7eeee50 --- /dev/null +++ b/openssh-6.6.1p1-NI_MAXHOST.patch @@ -0,0 +1,76 @@ +diff --git a/ChangeLog b/ChangeLog +index 928999d..3887495 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++20140703 ++ - OpenBSD CVS Sync ++ - djm@cvs.openbsd.org 2014/07/03 03:34:09 ++ [gss-serv.c session.c ssh-keygen.c] ++ standardise on NI_MAXHOST for gethostname() string lengths; about ++ 1/2 the cases were using it already. Fixes bz#2239 en passant ++ + 20140420 + - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] + OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 +diff --git a/gss-serv.c b/gss-serv.c +index 14f540e..29916d3 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */ ++/* $OpenBSD: gss-serv.c,v 1.27 2014/07/03 03:34:09 djm Exp $ */ + + /* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. +@@ -102,14 +102,14 @@ static OM_uint32 + ssh_gssapi_acquire_cred(Gssctxt *ctx) + { + OM_uint32 status; +- char lname[MAXHOSTNAMELEN]; ++ char lname[NI_MAXHOST]; + gss_OID_set oidset; + + if (options.gss_strict_acceptor) { + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + +- if (gethostname(lname, MAXHOSTNAMELEN)) { ++ if (gethostname(lname, sizeof(lname))) { + gss_release_oid_set(&status, &oidset); + return (-1); + } +diff --git a/session.c b/session.c +index ba4589b..e4add93 100644 +--- a/session.c ++++ b/session.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + #ifdef HAVE_PATHS_H + #include + #endif +@@ -2669,7 +2670,7 @@ session_setup_x11fwd(Session *s) + { + struct stat st; + char display[512], auth_display[512]; +- char hostname[MAXHOSTNAMELEN]; ++ char hostname[NI_MAXHOST]; + u_int i; + + if (no_x11_forwarding_flag) { +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 482dc1c..66198e6 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -165,7 +165,7 @@ int rounds = 0; + /* argv0 */ + extern char *__progname; + +-char hostname[MAXHOSTNAMELEN]; ++char hostname[NI_MAXHOST]; + + /* moduli.c */ + int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); diff --git a/openssh-6.6.1p1-partial-success.patch b/openssh-6.6.1p1-partial-success.patch new file mode 100644 index 0000000..b5c61cf --- /dev/null +++ b/openssh-6.6.1p1-partial-success.patch @@ -0,0 +1,16 @@ +diff --git a/auth2.c b/auth2.c +index d9b440a..ec0bf12 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -355,8 +355,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, + authctxt->success = 1; + } else { + +- /* Allow initial try of "none" auth without failure penalty */ +- if (!authctxt->server_caused_failure && ++ /* Allow initial try of "none" auth without failure penalty ++ * Partial succes is not failure */ ++ if (!authctxt->server_caused_failure && !partial && + (authctxt->attempt > 1 || strcmp(method, "none") != 0)) + authctxt->failures++; + if (authctxt->failures >= options.max_authtries) { diff --git a/openssh-6.6.1p1-utf8-banner.patch b/openssh-6.6.1p1-utf8-banner.patch new file mode 100644 index 0000000..1ab8ade --- /dev/null +++ b/openssh-6.6.1p1-utf8-banner.patch @@ -0,0 +1,994 @@ +diff --git a/Makefile.in b/Makefile.in +index 2ad26ff..0f0d39f 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -81,7 +81,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ + ssh-pkcs11.o krl.o smult_curve25519_ref.o \ + kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ +- ssh-ed25519.o digest-openssl.o hmac.o \ ++ ssh-ed25519.o digest-openssl.o hmac.o utf8_stringprep.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ +diff --git a/misc.h b/misc.h +index d4df619..d98b83d 100644 +--- a/misc.h ++++ b/misc.h +@@ -106,4 +106,7 @@ char *read_passphrase(const char *, int); + int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); + int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); + ++/* utf8_stringprep.c */ ++int utf8_stringprep(const char *, char *, size_t); ++ + #endif /* _MISC_H */ +diff --git a/sshconnect2.c b/sshconnect2.c +index b00658b..08064f4 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -33,6 +33,8 @@ + + #include + #include ++#include ++#include + #include + #include + #include +@@ -519,21 +521,51 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) + "type %d", type); + } + ++/* Check whether we can display UTF-8 safely */ ++static int ++utf8_ok(void) ++{ ++ static int ret = -1; ++ char *cp; ++ ++ if (ret == -1) { ++ setlocale(LC_CTYPE, ""); ++ cp = nl_langinfo(CODESET); ++ ret = strcmp(cp, "UTF-8") == 0; ++ } ++ return ret; ++} ++ + /* ARGSUSED */ + void + input_userauth_banner(int type, u_int32_t seq, void *ctxt) + { + char *msg, *raw, *lang; +- u_int len; ++ u_int done, len; + + debug3("input_userauth_banner"); ++ + raw = packet_get_string(&len); + lang = packet_get_string(NULL); + if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { + if (len > 65536) + len = 65536; + msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ +- strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); ++ done = 0; ++ if (utf8_ok()) { ++ if (utf8_stringprep(raw, msg, len * 4 + 1) == 0) ++ done = 1; ++ else ++ debug2("%s: UTF8 stringprep failed", __func__); ++ } ++ /* ++ * Fallback to strnvis if UTF8 display not supported or ++ * conversion failed. ++ */ ++ if (!done) { ++ strnvis(msg, raw, len * 4 + 1, ++ VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); ++ } + fprintf(stderr, "%s", msg); + free(msg); + } +diff --git a/stringprep-tables.c b/stringprep-tables.c +new file mode 100644 +index 0000000..49f4d9d +--- /dev/null ++++ b/stringprep-tables.c +@@ -0,0 +1,661 @@ ++/* Public domain. */ ++ ++/* $OpenBSD$ */ ++ ++/* ++ * Tables for RFC3454 stringprep algorithm, updated with a table of allocated ++ * characters generated from Unicode.6.2's UnicodeData.txt ++ * ++ * Intended to be included directly from utf8_stringprep.c ++ */ ++ ++/* Unassigned characters in Unicode 6.2 */ ++static const struct u32_range unassigned[] = { ++ { 0x0378, 0x0379 }, ++ { 0x037F, 0x0383 }, ++ { 0x038B, 0x038B }, ++ { 0x038D, 0x038D }, ++ { 0x03A2, 0x03A2 }, ++ { 0x0528, 0x0530 }, ++ { 0x0557, 0x0558 }, ++ { 0x0560, 0x0560 }, ++ { 0x0588, 0x0588 }, ++ { 0x058B, 0x058E }, ++ { 0x0590, 0x0590 }, ++ { 0x05C8, 0x05CF }, ++ { 0x05EB, 0x05EF }, ++ { 0x05F5, 0x05FF }, ++ { 0x0605, 0x0605 }, ++ { 0x061C, 0x061D }, ++ { 0x070E, 0x070E }, ++ { 0x074B, 0x074C }, ++ { 0x07B2, 0x07BF }, ++ { 0x07FB, 0x07FF }, ++ { 0x082E, 0x082F }, ++ { 0x083F, 0x083F }, ++ { 0x085C, 0x085D }, ++ { 0x085F, 0x089F }, ++ { 0x08A1, 0x08A1 }, ++ { 0x08AD, 0x08E3 }, ++ { 0x08FF, 0x08FF }, ++ { 0x0978, 0x0978 }, ++ { 0x0980, 0x0980 }, ++ { 0x0984, 0x0984 }, ++ { 0x098D, 0x098E }, ++ { 0x0991, 0x0992 }, ++ { 0x09A9, 0x09A9 }, ++ { 0x09B1, 0x09B1 }, ++ { 0x09B3, 0x09B5 }, ++ { 0x09BA, 0x09BB }, ++ { 0x09C5, 0x09C6 }, ++ { 0x09C9, 0x09CA }, ++ { 0x09CF, 0x09D6 }, ++ { 0x09D8, 0x09DB }, ++ { 0x09DE, 0x09DE }, ++ { 0x09E4, 0x09E5 }, ++ { 0x09FC, 0x0A00 }, ++ { 0x0A04, 0x0A04 }, ++ { 0x0A0B, 0x0A0E }, ++ { 0x0A11, 0x0A12 }, ++ { 0x0A29, 0x0A29 }, ++ { 0x0A31, 0x0A31 }, ++ { 0x0A34, 0x0A34 }, ++ { 0x0A37, 0x0A37 }, ++ { 0x0A3A, 0x0A3B }, ++ { 0x0A3D, 0x0A3D }, ++ { 0x0A43, 0x0A46 }, ++ { 0x0A49, 0x0A4A }, ++ { 0x0A4E, 0x0A50 }, ++ { 0x0A52, 0x0A58 }, ++ { 0x0A5D, 0x0A5D }, ++ { 0x0A5F, 0x0A65 }, ++ { 0x0A76, 0x0A80 }, ++ { 0x0A84, 0x0A84 }, ++ { 0x0A8E, 0x0A8E }, ++ { 0x0A92, 0x0A92 }, ++ { 0x0AA9, 0x0AA9 }, ++ { 0x0AB1, 0x0AB1 }, ++ { 0x0AB4, 0x0AB4 }, ++ { 0x0ABA, 0x0ABB }, ++ { 0x0AC6, 0x0AC6 }, ++ { 0x0ACA, 0x0ACA }, ++ { 0x0ACE, 0x0ACF }, ++ { 0x0AD1, 0x0ADF }, ++ { 0x0AE4, 0x0AE5 }, ++ { 0x0AF2, 0x0B00 }, ++ { 0x0B04, 0x0B04 }, ++ { 0x0B0D, 0x0B0E }, ++ { 0x0B11, 0x0B12 }, ++ { 0x0B29, 0x0B29 }, ++ { 0x0B31, 0x0B31 }, ++ { 0x0B34, 0x0B34 }, ++ { 0x0B3A, 0x0B3B }, ++ { 0x0B45, 0x0B46 }, ++ { 0x0B49, 0x0B4A }, ++ { 0x0B4E, 0x0B55 }, ++ { 0x0B58, 0x0B5B }, ++ { 0x0B5E, 0x0B5E }, ++ { 0x0B64, 0x0B65 }, ++ { 0x0B78, 0x0B81 }, ++ { 0x0B84, 0x0B84 }, ++ { 0x0B8B, 0x0B8D }, ++ { 0x0B91, 0x0B91 }, ++ { 0x0B96, 0x0B98 }, ++ { 0x0B9B, 0x0B9B }, ++ { 0x0B9D, 0x0B9D }, ++ { 0x0BA0, 0x0BA2 }, ++ { 0x0BA5, 0x0BA7 }, ++ { 0x0BAB, 0x0BAD }, ++ { 0x0BBA, 0x0BBD }, ++ { 0x0BC3, 0x0BC5 }, ++ { 0x0BC9, 0x0BC9 }, ++ { 0x0BCE, 0x0BCF }, ++ { 0x0BD1, 0x0BD6 }, ++ { 0x0BD8, 0x0BE5 }, ++ { 0x0BFB, 0x0C00 }, ++ { 0x0C04, 0x0C04 }, ++ { 0x0C0D, 0x0C0D }, ++ { 0x0C11, 0x0C11 }, ++ { 0x0C29, 0x0C29 }, ++ { 0x0C34, 0x0C34 }, ++ { 0x0C3A, 0x0C3C }, ++ { 0x0C45, 0x0C45 }, ++ { 0x0C49, 0x0C49 }, ++ { 0x0C4E, 0x0C54 }, ++ { 0x0C57, 0x0C57 }, ++ { 0x0C5A, 0x0C5F }, ++ { 0x0C64, 0x0C65 }, ++ { 0x0C70, 0x0C77 }, ++ { 0x0C80, 0x0C81 }, ++ { 0x0C84, 0x0C84 }, ++ { 0x0C8D, 0x0C8D }, ++ { 0x0C91, 0x0C91 }, ++ { 0x0CA9, 0x0CA9 }, ++ { 0x0CB4, 0x0CB4 }, ++ { 0x0CBA, 0x0CBB }, ++ { 0x0CC5, 0x0CC5 }, ++ { 0x0CC9, 0x0CC9 }, ++ { 0x0CCE, 0x0CD4 }, ++ { 0x0CD7, 0x0CDD }, ++ { 0x0CDF, 0x0CDF }, ++ { 0x0CE4, 0x0CE5 }, ++ { 0x0CF0, 0x0CF0 }, ++ { 0x0CF3, 0x0D01 }, ++ { 0x0D04, 0x0D04 }, ++ { 0x0D0D, 0x0D0D }, ++ { 0x0D11, 0x0D11 }, ++ { 0x0D3B, 0x0D3C }, ++ { 0x0D45, 0x0D45 }, ++ { 0x0D49, 0x0D49 }, ++ { 0x0D4F, 0x0D56 }, ++ { 0x0D58, 0x0D5F }, ++ { 0x0D64, 0x0D65 }, ++ { 0x0D76, 0x0D78 }, ++ { 0x0D80, 0x0D81 }, ++ { 0x0D84, 0x0D84 }, ++ { 0x0D97, 0x0D99 }, ++ { 0x0DB2, 0x0DB2 }, ++ { 0x0DBC, 0x0DBC }, ++ { 0x0DBE, 0x0DBF }, ++ { 0x0DC7, 0x0DC9 }, ++ { 0x0DCB, 0x0DCE }, ++ { 0x0DD5, 0x0DD5 }, ++ { 0x0DD7, 0x0DD7 }, ++ { 0x0DE0, 0x0DF1 }, ++ { 0x0DF5, 0x0E00 }, ++ { 0x0E3B, 0x0E3E }, ++ { 0x0E5C, 0x0E80 }, ++ { 0x0E83, 0x0E83 }, ++ { 0x0E85, 0x0E86 }, ++ { 0x0E89, 0x0E89 }, ++ { 0x0E8B, 0x0E8C }, ++ { 0x0E8E, 0x0E93 }, ++ { 0x0E98, 0x0E98 }, ++ { 0x0EA0, 0x0EA0 }, ++ { 0x0EA4, 0x0EA4 }, ++ { 0x0EA6, 0x0EA6 }, ++ { 0x0EA8, 0x0EA9 }, ++ { 0x0EAC, 0x0EAC }, ++ { 0x0EBA, 0x0EBA }, ++ { 0x0EBE, 0x0EBF }, ++ { 0x0EC5, 0x0EC5 }, ++ { 0x0EC7, 0x0EC7 }, ++ { 0x0ECE, 0x0ECF }, ++ { 0x0EDA, 0x0EDB }, ++ { 0x0EE0, 0x0EFF }, ++ { 0x0F48, 0x0F48 }, ++ { 0x0F6D, 0x0F70 }, ++ { 0x0F98, 0x0F98 }, ++ { 0x0FBD, 0x0FBD }, ++ { 0x0FCD, 0x0FCD }, ++ { 0x0FDB, 0x0FFF }, ++ { 0x10C6, 0x10C6 }, ++ { 0x10C8, 0x10CC }, ++ { 0x10CE, 0x10CF }, ++ { 0x1249, 0x1249 }, ++ { 0x124E, 0x124F }, ++ { 0x1257, 0x1257 }, ++ { 0x1259, 0x1259 }, ++ { 0x125E, 0x125F }, ++ { 0x1289, 0x1289 }, ++ { 0x128E, 0x128F }, ++ { 0x12B1, 0x12B1 }, ++ { 0x12B6, 0x12B7 }, ++ { 0x12BF, 0x12BF }, ++ { 0x12C1, 0x12C1 }, ++ { 0x12C6, 0x12C7 }, ++ { 0x12D7, 0x12D7 }, ++ { 0x1311, 0x1311 }, ++ { 0x1316, 0x1317 }, ++ { 0x135B, 0x135C }, ++ { 0x137D, 0x137F }, ++ { 0x139A, 0x139F }, ++ { 0x13F5, 0x13FF }, ++ { 0x169D, 0x169F }, ++ { 0x16F1, 0x16FF }, ++ { 0x170D, 0x170D }, ++ { 0x1715, 0x171F }, ++ { 0x1737, 0x173F }, ++ { 0x1754, 0x175F }, ++ { 0x176D, 0x176D }, ++ { 0x1771, 0x1771 }, ++ { 0x1774, 0x177F }, ++ { 0x17DE, 0x17DF }, ++ { 0x17EA, 0x17EF }, ++ { 0x17FA, 0x17FF }, ++ { 0x180F, 0x180F }, ++ { 0x181A, 0x181F }, ++ { 0x1878, 0x187F }, ++ { 0x18AB, 0x18AF }, ++ { 0x18F6, 0x18FF }, ++ { 0x191D, 0x191F }, ++ { 0x192C, 0x192F }, ++ { 0x193C, 0x193F }, ++ { 0x1941, 0x1943 }, ++ { 0x196E, 0x196F }, ++ { 0x1975, 0x197F }, ++ { 0x19AC, 0x19AF }, ++ { 0x19CA, 0x19CF }, ++ { 0x19DB, 0x19DD }, ++ { 0x1A1C, 0x1A1D }, ++ { 0x1A5F, 0x1A5F }, ++ { 0x1A7D, 0x1A7E }, ++ { 0x1A8A, 0x1A8F }, ++ { 0x1A9A, 0x1A9F }, ++ { 0x1AAE, 0x1AFF }, ++ { 0x1B4C, 0x1B4F }, ++ { 0x1B7D, 0x1B7F }, ++ { 0x1BF4, 0x1BFB }, ++ { 0x1C38, 0x1C3A }, ++ { 0x1C4A, 0x1C4C }, ++ { 0x1C80, 0x1CBF }, ++ { 0x1CC8, 0x1CCF }, ++ { 0x1CF7, 0x1CFF }, ++ { 0x1DE7, 0x1DFB }, ++ { 0x1F16, 0x1F17 }, ++ { 0x1F1E, 0x1F1F }, ++ { 0x1F46, 0x1F47 }, ++ { 0x1F4E, 0x1F4F }, ++ { 0x1F58, 0x1F58 }, ++ { 0x1F5A, 0x1F5A }, ++ { 0x1F5C, 0x1F5C }, ++ { 0x1F5E, 0x1F5E }, ++ { 0x1F7E, 0x1F7F }, ++ { 0x1FB5, 0x1FB5 }, ++ { 0x1FC5, 0x1FC5 }, ++ { 0x1FD4, 0x1FD5 }, ++ { 0x1FDC, 0x1FDC }, ++ { 0x1FF0, 0x1FF1 }, ++ { 0x1FF5, 0x1FF5 }, ++ { 0x1FFF, 0x1FFF }, ++ { 0x2065, 0x2069 }, ++ { 0x2072, 0x2073 }, ++ { 0x208F, 0x208F }, ++ { 0x209D, 0x209F }, ++ { 0x20BB, 0x20CF }, ++ { 0x20F1, 0x20FF }, ++ { 0x218A, 0x218F }, ++ { 0x23F4, 0x23FF }, ++ { 0x2427, 0x243F }, ++ { 0x244B, 0x245F }, ++ { 0x2700, 0x2700 }, ++ { 0x2B4D, 0x2B4F }, ++ { 0x2B5A, 0x2BFF }, ++ { 0x2C2F, 0x2C2F }, ++ { 0x2C5F, 0x2C5F }, ++ { 0x2CF4, 0x2CF8 }, ++ { 0x2D26, 0x2D26 }, ++ { 0x2D28, 0x2D2C }, ++ { 0x2D2E, 0x2D2F }, ++ { 0x2D68, 0x2D6E }, ++ { 0x2D71, 0x2D7E }, ++ { 0x2D97, 0x2D9F }, ++ { 0x2DA7, 0x2DA7 }, ++ { 0x2DAF, 0x2DAF }, ++ { 0x2DB7, 0x2DB7 }, ++ { 0x2DBF, 0x2DBF }, ++ { 0x2DC7, 0x2DC7 }, ++ { 0x2DCF, 0x2DCF }, ++ { 0x2DD7, 0x2DD7 }, ++ { 0x2DDF, 0x2DDF }, ++ { 0x2E3C, 0x2E7F }, ++ { 0x2E9A, 0x2E9A }, ++ { 0x2EF4, 0x2EFF }, ++ { 0x2FD6, 0x2FEF }, ++ { 0x2FFC, 0x2FFF }, ++ { 0x3040, 0x3040 }, ++ { 0x3097, 0x3098 }, ++ { 0x3100, 0x3104 }, ++ { 0x312E, 0x3130 }, ++ { 0x318F, 0x318F }, ++ { 0x31BB, 0x31BF }, ++ { 0x31E4, 0x31EF }, ++ { 0x321F, 0x321F }, ++ { 0x32FF, 0x32FF }, ++ { 0x4DB6, 0x4DBF }, ++ { 0x9FA6, 0x9FCB }, ++ { 0x9FCD, 0x9FFF }, ++ { 0xA48D, 0xA48F }, ++ { 0xA4C7, 0xA4CF }, ++ { 0xA62C, 0xA63F }, ++ { 0xA698, 0xA69E }, ++ { 0xA6F8, 0xA6FF }, ++ { 0xA78F, 0xA78F }, ++ { 0xA794, 0xA79F }, ++ { 0xA7AB, 0xA7F7 }, ++ { 0xA82C, 0xA82F }, ++ { 0xA83A, 0xA83F }, ++ { 0xA878, 0xA87F }, ++ { 0xA8C5, 0xA8CD }, ++ { 0xA8DA, 0xA8DF }, ++ { 0xA8FC, 0xA8FF }, ++ { 0xA954, 0xA95E }, ++ { 0xA97D, 0xA97F }, ++ { 0xA9CE, 0xA9CE }, ++ { 0xA9DA, 0xA9DD }, ++ { 0xA9E0, 0xA9FF }, ++ { 0xAA37, 0xAA3F }, ++ { 0xAA4E, 0xAA4F }, ++ { 0xAA5A, 0xAA5B }, ++ { 0xAA7C, 0xAA7F }, ++ { 0xAAC3, 0xAADA }, ++ { 0xAAF7, 0xAB00 }, ++ { 0xAB07, 0xAB08 }, ++ { 0xAB0F, 0xAB10 }, ++ { 0xAB17, 0xAB1F }, ++ { 0xAB27, 0xAB27 }, ++ { 0xAB2F, 0xABBF }, ++ { 0xABEE, 0xABEF }, ++ { 0xABFA, 0xABFF }, ++ { 0xD7A4, 0xD7AF }, ++ { 0xD7C7, 0xD7CA }, ++ { 0xD7FC, 0xD7FF }, ++ { 0xFA6E, 0xFA6F }, ++ { 0xFADA, 0xFAFF }, ++ { 0xFB07, 0xFB12 }, ++ { 0xFB18, 0xFB1C }, ++ { 0xFB37, 0xFB37 }, ++ { 0xFB3D, 0xFB3D }, ++ { 0xFB3F, 0xFB3F }, ++ { 0xFB42, 0xFB42 }, ++ { 0xFB45, 0xFB45 }, ++ { 0xFBC2, 0xFBD2 }, ++ { 0xFD40, 0xFD4F }, ++ { 0xFD90, 0xFD91 }, ++ { 0xFDC8, 0xFDCF }, ++ { 0xFDFE, 0xFDFF }, ++ { 0xFE1A, 0xFE1F }, ++ { 0xFE27, 0xFE2F }, ++ { 0xFE53, 0xFE53 }, ++ { 0xFE67, 0xFE67 }, ++ { 0xFE6C, 0xFE6F }, ++ { 0xFE75, 0xFE75 }, ++ { 0xFEFD, 0xFEFE }, ++ { 0xFF00, 0xFF00 }, ++ { 0xFFBF, 0xFFC1 }, ++ { 0xFFC8, 0xFFC9 }, ++ { 0xFFD0, 0xFFD1 }, ++ { 0xFFD8, 0xFFD9 }, ++ { 0xFFDD, 0xFFDF }, ++ { 0xFFE7, 0xFFE7 }, ++ { 0xFFEF, 0xFFF8 }, ++ { 0x1000C, 0x1000C }, ++ { 0x10027, 0x10027 }, ++ { 0x1003B, 0x1003B }, ++ { 0x1003E, 0x1003E }, ++ { 0x1004E, 0x1004F }, ++ { 0x1005E, 0x1007F }, ++ { 0x100FB, 0x100FF }, ++ { 0x10103, 0x10106 }, ++ { 0x10134, 0x10136 }, ++ { 0x1018B, 0x1018F }, ++ { 0x1019C, 0x101CF }, ++ { 0x101FE, 0x1027F }, ++ { 0x1029D, 0x1029F }, ++ { 0x102D1, 0x102FF }, ++ { 0x1031F, 0x1031F }, ++ { 0x10324, 0x1032F }, ++ { 0x1034B, 0x1037F }, ++ { 0x1039E, 0x1039E }, ++ { 0x103C4, 0x103C7 }, ++ { 0x103D6, 0x103FF }, ++ { 0x1049E, 0x1049F }, ++ { 0x104AA, 0x107FF }, ++ { 0x10806, 0x10807 }, ++ { 0x10809, 0x10809 }, ++ { 0x10836, 0x10836 }, ++ { 0x10839, 0x1083B }, ++ { 0x1083D, 0x1083E }, ++ { 0x10856, 0x10856 }, ++ { 0x10860, 0x108FF }, ++ { 0x1091C, 0x1091E }, ++ { 0x1093A, 0x1093E }, ++ { 0x10940, 0x1097F }, ++ { 0x109B8, 0x109BD }, ++ { 0x109C0, 0x109FF }, ++ { 0x10A04, 0x10A04 }, ++ { 0x10A07, 0x10A0B }, ++ { 0x10A14, 0x10A14 }, ++ { 0x10A18, 0x10A18 }, ++ { 0x10A34, 0x10A37 }, ++ { 0x10A3B, 0x10A3E }, ++ { 0x10A48, 0x10A4F }, ++ { 0x10A59, 0x10A5F }, ++ { 0x10A80, 0x10AFF }, ++ { 0x10B36, 0x10B38 }, ++ { 0x10B56, 0x10B57 }, ++ { 0x10B73, 0x10B77 }, ++ { 0x10B80, 0x10BFF }, ++ { 0x10C49, 0x10E5F }, ++ { 0x10E7F, 0x10FFF }, ++ { 0x1104E, 0x11051 }, ++ { 0x11070, 0x1107F }, ++ { 0x110C2, 0x110CF }, ++ { 0x110E9, 0x110EF }, ++ { 0x110FA, 0x110FF }, ++ { 0x11135, 0x11135 }, ++ { 0x11144, 0x1117F }, ++ { 0x111C9, 0x111CF }, ++ { 0x111DA, 0x1167F }, ++ { 0x116B8, 0x116BF }, ++ { 0x116CA, 0x11FFF }, ++ { 0x1236F, 0x123FF }, ++ { 0x12463, 0x1246F }, ++ { 0x12474, 0x12FFF }, ++ { 0x1342F, 0x167FF }, ++ { 0x16A39, 0x16EFF }, ++ { 0x16F45, 0x16F4F }, ++ { 0x16F7F, 0x16F8E }, ++ { 0x16FA0, 0x1AFFF }, ++ { 0x1B002, 0x1CFFF }, ++ { 0x1D0F6, 0x1D0FF }, ++ { 0x1D127, 0x1D128 }, ++ { 0x1D1DE, 0x1D1FF }, ++ { 0x1D246, 0x1D2FF }, ++ { 0x1D357, 0x1D35F }, ++ { 0x1D372, 0x1D3FF }, ++ { 0x1D455, 0x1D455 }, ++ { 0x1D49D, 0x1D49D }, ++ { 0x1D4A0, 0x1D4A1 }, ++ { 0x1D4A3, 0x1D4A4 }, ++ { 0x1D4A7, 0x1D4A8 }, ++ { 0x1D4AD, 0x1D4AD }, ++ { 0x1D4BA, 0x1D4BA }, ++ { 0x1D4BC, 0x1D4BC }, ++ { 0x1D4C4, 0x1D4C4 }, ++ { 0x1D506, 0x1D506 }, ++ { 0x1D50B, 0x1D50C }, ++ { 0x1D515, 0x1D515 }, ++ { 0x1D51D, 0x1D51D }, ++ { 0x1D53A, 0x1D53A }, ++ { 0x1D53F, 0x1D53F }, ++ { 0x1D545, 0x1D545 }, ++ { 0x1D547, 0x1D549 }, ++ { 0x1D551, 0x1D551 }, ++ { 0x1D6A6, 0x1D6A7 }, ++ { 0x1D7CC, 0x1D7CD }, ++ { 0x1D800, 0x1EDFF }, ++ { 0x1EE04, 0x1EE04 }, ++ { 0x1EE20, 0x1EE20 }, ++ { 0x1EE23, 0x1EE23 }, ++ { 0x1EE25, 0x1EE26 }, ++ { 0x1EE28, 0x1EE28 }, ++ { 0x1EE33, 0x1EE33 }, ++ { 0x1EE38, 0x1EE38 }, ++ { 0x1EE3A, 0x1EE3A }, ++ { 0x1EE3C, 0x1EE41 }, ++ { 0x1EE43, 0x1EE46 }, ++ { 0x1EE48, 0x1EE48 }, ++ { 0x1EE4A, 0x1EE4A }, ++ { 0x1EE4C, 0x1EE4C }, ++ { 0x1EE50, 0x1EE50 }, ++ { 0x1EE53, 0x1EE53 }, ++ { 0x1EE55, 0x1EE56 }, ++ { 0x1EE58, 0x1EE58 }, ++ { 0x1EE5A, 0x1EE5A }, ++ { 0x1EE5C, 0x1EE5C }, ++ { 0x1EE5E, 0x1EE5E }, ++ { 0x1EE60, 0x1EE60 }, ++ { 0x1EE63, 0x1EE63 }, ++ { 0x1EE65, 0x1EE66 }, ++ { 0x1EE6B, 0x1EE6B }, ++ { 0x1EE73, 0x1EE73 }, ++ { 0x1EE78, 0x1EE78 }, ++ { 0x1EE7D, 0x1EE7D }, ++ { 0x1EE7F, 0x1EE7F }, ++ { 0x1EE8A, 0x1EE8A }, ++ { 0x1EE9C, 0x1EEA0 }, ++ { 0x1EEA4, 0x1EEA4 }, ++ { 0x1EEAA, 0x1EEAA }, ++ { 0x1EEBC, 0x1EEEF }, ++ { 0x1EEF2, 0x1EFFF }, ++ { 0x1F02C, 0x1F02F }, ++ { 0x1F094, 0x1F09F }, ++ { 0x1F0AF, 0x1F0B0 }, ++ { 0x1F0BF, 0x1F0C0 }, ++ { 0x1F0D0, 0x1F0D0 }, ++ { 0x1F0E0, 0x1F0FF }, ++ { 0x1F10B, 0x1F10F }, ++ { 0x1F12F, 0x1F12F }, ++ { 0x1F16C, 0x1F16F }, ++ { 0x1F19B, 0x1F1E5 }, ++ { 0x1F203, 0x1F20F }, ++ { 0x1F23B, 0x1F23F }, ++ { 0x1F249, 0x1F24F }, ++ { 0x1F252, 0x1F2FF }, ++ { 0x1F321, 0x1F32F }, ++ { 0x1F336, 0x1F336 }, ++ { 0x1F37D, 0x1F37F }, ++ { 0x1F394, 0x1F39F }, ++ { 0x1F3C5, 0x1F3C5 }, ++ { 0x1F3CB, 0x1F3DF }, ++ { 0x1F3F1, 0x1F3FF }, ++ { 0x1F43F, 0x1F43F }, ++ { 0x1F441, 0x1F441 }, ++ { 0x1F4F8, 0x1F4F8 }, ++ { 0x1F4FD, 0x1F4FF }, ++ { 0x1F53E, 0x1F53F }, ++ { 0x1F544, 0x1F54F }, ++ { 0x1F568, 0x1F5FA }, ++ { 0x1F641, 0x1F644 }, ++ { 0x1F650, 0x1F67F }, ++ { 0x1F6C6, 0x1F6FF }, ++ { 0x1F774, 0x1FFFD }, ++ { 0x2A6D7, 0x2A6FF }, ++ { 0x2A701, 0x2B733 }, ++ { 0x2B735, 0x2B73F }, ++ { 0x2B741, 0x2B81C }, ++ { 0x2B81E, 0x2F7FF }, ++ { 0x2FA1E, 0x2FFFD }, ++ { 0x30000, 0x3FFFD }, ++ { 0x40000, 0x4FFFD }, ++ { 0x50000, 0x5FFFD }, ++ { 0x60000, 0x6FFFD }, ++ { 0x70000, 0x7FFFD }, ++ { 0x80000, 0x8FFFD }, ++ { 0x90000, 0x9FFFD }, ++ { 0xA0000, 0xAFFFD }, ++ { 0xB0000, 0xBFFFD }, ++ { 0xC0000, 0xCFFFD }, ++ { 0xD0000, 0xDFFFD }, ++ { 0xE0000, 0xE0000 }, ++ { 0xE0002, 0xE001F }, ++ { 0xE0080, 0xE00FF }, ++ { 0xE01F0, 0xEFFFD }, ++}; ++ ++/* RFC3454 Table B.1 */ ++static const struct u32_range map_to_nothing[] = { ++ { 0x00AD, 0x00AD }, ++ { 0x034F, 0x034F }, ++ { 0x1806, 0x1806 }, ++ { 0x180B, 0x180D }, ++ { 0x200B, 0x200D }, ++ { 0x2060, 0x2060 }, ++ { 0xFE00, 0xFE0F }, ++ { 0xFEFF, 0xFEFF }, ++}; ++ ++/* Local: allow tab, CR and LF */ ++static const struct u32_range whitelist[] = { ++ { 0x09, 0x09 }, ++ { 0x0a, 0x0a }, ++ { 0x0d, 0x0d }, ++}; ++ ++/* RFC3454 Tables in appendix C */ ++static const struct u32_range prohibited[] = { ++ /* C.2.1 ASCII control characters */ ++ { 0x0000, 0x001F }, ++ { 0x007F, 0x007F }, ++ /* C.2.2 Non-ASCII control characters */ ++ { 0x0080, 0x009F }, ++ { 0x06DD, 0x06DD }, ++ { 0x070F, 0x070F }, ++ { 0x180E, 0x180E }, ++ { 0x200C, 0x200C }, ++ { 0x200D, 0x200D }, ++ { 0x2028, 0x2028 }, ++ { 0x2029, 0x2029 }, ++ { 0x2060, 0x2060 }, ++ { 0x2061, 0x2061 }, ++ { 0x2062, 0x2062 }, ++ { 0x2063, 0x2063 }, ++ { 0x206A, 0x206F }, ++ { 0xFEFF, 0xFEFF }, ++ { 0xFFF9, 0xFFFC }, ++ { 0x1D173, 0x1D17A }, ++ /* C.3 Private use */ ++ { 0xE000, 0xF8FF }, ++ { 0xF0000, 0xFFFFD }, ++ { 0x100000, 0x10FFFD }, ++ /* C.4 Non-character code points */ ++ { 0xFDD0, 0xFDEF }, ++ { 0xFFFE, 0xFFFF }, ++ { 0x1FFFE, 0x1FFFF }, ++ { 0x2FFFE, 0x2FFFF }, ++ { 0x3FFFE, 0x3FFFF }, ++ { 0x4FFFE, 0x4FFFF }, ++ { 0x5FFFE, 0x5FFFF }, ++ { 0x6FFFE, 0x6FFFF }, ++ { 0x7FFFE, 0x7FFFF }, ++ { 0x8FFFE, 0x8FFFF }, ++ { 0x9FFFE, 0x9FFFF }, ++ { 0xAFFFE, 0xAFFFF }, ++ { 0xBFFFE, 0xBFFFF }, ++ { 0xCFFFE, 0xCFFFF }, ++ { 0xDFFFE, 0xDFFFF }, ++ { 0xEFFFE, 0xEFFFF }, ++ { 0xFFFFE, 0xFFFFF }, ++ { 0x10FFFE, 0x10FFFF }, ++ /* C.5 Surrogate codes */ ++ { 0xD800, 0xDFFF }, ++ /* C.6 Inappropriate for plain text */ ++ { 0xFFF9, 0xFFF9 }, ++ { 0xFFFA, 0xFFFA }, ++ { 0xFFFB, 0xFFFB }, ++ { 0xFFFC, 0xFFFC }, ++ { 0xFFFD, 0xFFFD }, ++ /* C.7 Inappropriate for canonical representation */ ++ { 0x2FF0, 0x2FFB }, ++ /* C.8 Change display properties or are deprecated */ ++ { 0x0340, 0x0340 }, ++ { 0x0341, 0x0341 }, ++ { 0x200E, 0x200E }, ++ { 0x200F, 0x200F }, ++ { 0x202A, 0x202A }, ++ { 0x202B, 0x202B }, ++ { 0x202C, 0x202C }, ++ { 0x202D, 0x202D }, ++ { 0x202E, 0x202E }, ++ { 0x206A, 0x206A }, ++ { 0x206B, 0x206B }, ++ { 0x206C, 0x206C }, ++ { 0x206D, 0x206D }, ++ { 0x206E, 0x206E }, ++ { 0x206F, 0x206F }, ++ /* C.9 Tagging characters */ ++ { 0xE0001, 0xE0001 }, ++ { 0xE0020, 0xE007F }, ++}; ++ +diff --git a/utf8_stringprep.c b/utf8_stringprep.c +new file mode 100644 +index 0000000..bcafae7 +--- /dev/null ++++ b/utf8_stringprep.c +@@ -0,0 +1,229 @@ ++/* ++ * Copyright (c) 2013 Damien Miller ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* ++ * This is a simple RFC3454 stringprep profile to sanitise UTF-8 strings ++ * from untrusted sources. ++ * ++ * It is intended to be used prior to display of untrusted strings only. ++ * It should not be used for logging because of bi-di ambiguity. It ++ * should also not be used in any case where lack of normalisation may ++ * cause problems. ++ * ++ * This profile uses the prohibition and mapping tables from RFC3454 ++ * (listed below) but the unassigned character table has been updated to ++ * Unicode 6.2. It uses a local whitelist of whitespace characters (\n, ++ * \a and \t). Unicode normalisation and bi-di testing are not used. ++ * ++ * XXX: implement bi-di handling (needed for logs) ++ * XXX: implement KC normalisation (needed for passing to libs/syscalls) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "misc.h" ++ ++struct u32_range { ++ u_int32_t lo, hi; /* Inclusive */ ++}; ++ ++#include "stringprep-tables.c" ++ ++/* Returns 1 if code 'c' appears in the table or 0 otherwise */ ++static int ++code_in_table(u_int32_t c, const struct u32_range *table, size_t tlen) ++{ ++ const struct u32_range *e, *end = (void *)(tlen + (char *)table); ++ ++ for (e = table; e < end; e++) { ++ if (c >= e->lo && c <= e->hi) ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * Decode the next valid UCS character from a UTF-8 string, skipping past bad ++ * codes. Returns the decoded character or 0 for end-of-string and updates ++ * nextc to point to the start of the next character (if any). ++ * had_error is set if an invalid code was encountered. ++ */ ++static u_int32_t ++decode_utf8(const char *in, const char **nextc, int *had_error) ++{ ++ int state = 0; ++ size_t i; ++ u_int32_t c, e; ++ ++ e = c = 0; ++ for (i = 0; in[i] != '\0'; i++) { ++ e = (u_char)in[i]; ++ /* Invalid code point state */ ++ if (state == -1) { ++ /* ++ * Continue eating continuation characters until ++ * a new start character comes along. ++ */ ++ if ((e & 0xc0) == 0x80) ++ continue; ++ state = 0; ++ } ++ ++ /* New code point state */ ++ if (state == 0) { ++ if ((e & 0x80) == 0) { /* 7 bit code */ ++ c = e & 0x7f; ++ goto have_code; ++ } else if ((e & 0xe0) == 0xc0) { /* 11 bit code point */ ++ state = 1; ++ c = (e & 0x1f) << 6; ++ } else if ((e & 0xf0) == 0xe0) { /* 16 bit code point */ ++ state = 2; ++ c = (e & 0xf) << 12; ++ } else if ((e & 0xf8) == 0xf0) { /* 21 bit code point */ ++ state = 3; ++ c = (e & 0x7) << 18; ++ } else { ++ /* A five or six byte header, or 0xff */ ++ goto bad_encoding; ++ } ++ /* ++ * Check that the header byte has some non-zero data ++ * after masking off the length marker. If not it is ++ * an invalid encoding. ++ */ ++ if (c == 0) { ++ bad_encoding: ++ c = 0; ++ state = -1; ++ if (had_error != NULL) ++ *had_error = 1; ++ } ++ continue; ++ } ++ ++ /* Sanity check: should never happen */ ++ if (state < 1 || state > 5) { ++ *nextc = NULL; ++ if (had_error != NULL) ++ *had_error = 1; ++ return 0; ++ } ++ /* Multibyte code point state */ ++ state--; ++ c |= (e & 0x3f) << (state * 6); ++ if (state > 0) ++ continue; ++ ++ /* RFC3629 bans codepoints > U+10FFFF */ ++ if (c > 0x10FFFF) { ++ if (had_error != NULL) ++ *had_error = 1; ++ continue; ++ } ++ have_code: ++ *nextc = in + i + 1; ++ return c; ++ } ++ if (state != 0 && had_error != NULL) ++ *had_error = 1; ++ *nextc = in + i; ++ return 0; ++} ++ ++/* ++ * Attempt to encode a UCS character as a UTF-8 sequence. Returns the number ++ * of characters used or -1 on error (insufficient space or bad code). ++ */ ++static int ++encode_utf8(u_int32_t c, char *s, size_t slen) ++{ ++ size_t i, need; ++ u_char h; ++ ++ if (c < 0x80) { ++ if (slen >= 1) { ++ s[0] = (char)c; ++ } ++ return 1; ++ } else if (c < 0x800) { ++ need = 2; ++ h = 0xc0; ++ } else if (c < 0x10000) { ++ need = 3; ++ h = 0xe0; ++ } else if (c < 0x200000) { ++ need = 4; ++ h = 0xf0; ++ } else { ++ /* Invalid code point > U+10FFFF */ ++ return -1; ++ } ++ if (need > slen) ++ return -1; ++ for (i = 0; i < need; i++) { ++ s[i] = (i == 0 ? h : 0x80); ++ s[i] |= (c >> (need - i - 1) * 6) & 0x3f; ++ } ++ return need; ++} ++ ++ ++/* ++ * Normalise a UTF-8 string using the RFC3454 stringprep algorithm. ++ * Returns 0 on success or -1 on failure (prohibited code or insufficient ++ * length in the output string. ++ * Requires an output buffer at most the same length as the input. ++ */ ++int ++utf8_stringprep(const char *in, char *out, size_t olen) ++{ ++ int r; ++ size_t o; ++ u_int32_t c; ++ ++ if (olen < 1) ++ return -1; ++ ++ for (o = 0; (c = decode_utf8(in, &in, NULL)) != 0;) { ++ /* Mapping */ ++ if (code_in_table(c, map_to_nothing, sizeof(map_to_nothing))) ++ continue; ++ ++ /* Prohibitied output */ ++ if (code_in_table(c, prohibited, sizeof(prohibited)) && ++ !code_in_table(c, whitelist, sizeof(whitelist))) ++ return -1; ++ ++ /* Map unassigned code points to U+FFFD */ ++ if (code_in_table(c, unassigned, sizeof(unassigned))) ++ c = 0xFFFD; ++ ++ /* Encode the character */ ++ r = encode_utf8(c, out + o, olen - o - 1); ++ if (r < 0) ++ return -1; ++ o += r; ++ } ++ out[o] = '\0'; ++ return 0; ++} ++ diff --git a/openssh-6.6p1-audit.patch b/openssh-6.6p1-audit.patch index f205436..b83b46a 100644 --- a/openssh-6.6p1-audit.patch +++ b/openssh-6.6p1-audit.patch @@ -1,11 +1,11 @@ diff --git a/Makefile.in b/Makefile.in -index 2ad26ff..3bb7f00 100644 +index 0f0d39f..9d8c2eb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,7 +82,8 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ ssh-pkcs11.o krl.o smult_curve25519_ref.o \ kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o hmac.o \ + ssh-ed25519.o digest-openssl.o hmac.o utf8_stringprep.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + auditstub.o @@ -1860,10 +1860,10 @@ index f8edf85..c36c812 100644 +void packet_destroy_all(int, int); #endif /* PACKET_H */ diff --git a/session.c b/session.c -index ba4589b..4a297f1 100644 +index e4add93..626a642 100644 --- a/session.c +++ b/session.c -@@ -137,7 +137,7 @@ extern int log_stderr; +@@ -138,7 +138,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1872,7 +1872,7 @@ index ba4589b..4a297f1 100644 extern Buffer loginmsg; /* original command from peer. */ -@@ -745,6 +745,14 @@ do_exec_pty(Session *s, const char *command) +@@ -746,6 +746,14 @@ do_exec_pty(Session *s, const char *command) /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1887,7 +1887,7 @@ index ba4589b..4a297f1 100644 /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -862,15 +870,19 @@ do_exec(Session *s, const char *command) +@@ -863,15 +871,19 @@ do_exec(Session *s, const char *command) get_remote_port()); #ifdef SSH_AUDIT_EVENTS @@ -1909,7 +1909,7 @@ index ba4589b..4a297f1 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1707,7 +1719,10 @@ do_child(Session *s, const char *command) +@@ -1708,7 +1720,10 @@ do_child(Session *s, const char *command) int r = 0; /* remove hostkey from the child's memory */ @@ -1921,7 +1921,7 @@ index ba4589b..4a297f1 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1931,6 +1946,7 @@ session_unused(int id) +@@ -1932,6 +1947,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1929,7 +1929,7 @@ index ba4589b..4a297f1 100644 sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2013,6 +2029,19 @@ session_open(Authctxt *authctxt, int chanid) +@@ -2014,6 +2030,19 @@ session_open(Authctxt *authctxt, int chanid) } Session * @@ -1949,7 +1949,7 @@ index ba4589b..4a297f1 100644 session_by_tty(char *tty) { int i; -@@ -2529,6 +2558,30 @@ session_exit_message(Session *s, int status) +@@ -2530,6 +2559,30 @@ session_exit_message(Session *s, int status) chan_write_failed(c); } @@ -1980,7 +1980,7 @@ index ba4589b..4a297f1 100644 void session_close(Session *s) { -@@ -2537,6 +2590,10 @@ session_close(Session *s) +@@ -2538,6 +2591,10 @@ session_close(Session *s) debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1991,7 +1991,7 @@ index ba4589b..4a297f1 100644 free(s->term); free(s->display); free(s->x11_chanids); -@@ -2751,6 +2808,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2752,6 +2809,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -2007,7 +2007,7 @@ index ba4589b..4a297f1 100644 void do_cleanup(Authctxt *authctxt) { -@@ -2799,5 +2865,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2800,5 +2866,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) diff --git a/openssh-6.6p1-fips.patch b/openssh-6.6p1-fips.patch index 2869d2f..9227b37 100644 --- a/openssh-6.6p1-fips.patch +++ b/openssh-6.6p1-fips.patch @@ -366,7 +366,7 @@ index 770ad28..9d4fc6d 100644 break; default: diff --git a/key.c b/key.c -index 62f3edb..c13b644 100644 +index 62f3edb..a2050f6 100644 --- a/key.c +++ b/key.c @@ -42,6 +42,7 @@ @@ -394,6 +394,19 @@ index 62f3edb..c13b644 100644 rv_defined = 1; } return rv; +@@ -1168,8 +1173,11 @@ rsa_generate_private_key(u_int bits) + fatal("%s: BN_new failed", __func__); + if (!BN_set_word(f4, RSA_F4)) + fatal("%s: BN_new failed", __func__); +- if (!RSA_generate_key_ex(private, bits, f4, NULL)) ++ if (!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__); + fatal("%s: key generation failed.", __func__); ++ } + BN_free(f4); + return private; + } diff --git a/mac.c b/mac.c index 9388af4..cd7b034 100644 --- a/mac.c @@ -500,25 +513,23 @@ index 3a0f5ae..4f35a44 100644 static char *myproposal[PROPOSAL_MAX] = { KEX_DEFAULT_KEX, diff --git a/ssh-keygen.c b/ssh-keygen.c -index 482dc1c..fd2eb94 100644 +index 66198e6..ccf22c8 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -195,6 +195,14 @@ type_bits_valid(int type, u_int32_t *bitsp) +@@ -195,6 +195,12 @@ type_bits_valid(int type, u_int32_t *bitsp) fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); exit(1); } + if (FIPS_mode()) { + if (type == KEY_DSA) + fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_RSA && bits != 2048 && bits != 3072) -+ fatal("RSA keys must be either 2048 bits or 3072 bits in FIPS mode"); + if (type == KEY_ED25519) + fatal("ED25519 keys are not allowed in FIPS mode"); + } if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) -@@ -746,7 +754,7 @@ do_download(struct passwd *pw) +@@ -746,7 +752,7 @@ do_download(struct passwd *pw) enum fp_type fptype; char *fp, *ra; @@ -527,7 +538,7 @@ index 482dc1c..fd2eb94 100644 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; pkcs11_init(0); -@@ -756,8 +764,7 @@ do_download(struct passwd *pw) +@@ -756,8 +762,7 @@ do_download(struct passwd *pw) for (i = 0; i < nkeys; i++) { if (print_fingerprint) { fp = key_fingerprint(keys[i], fptype, rep); diff --git a/openssh-6.6p1-set_remote_ipaddr.patch b/openssh-6.6p1-set_remote_ipaddr.patch new file mode 100644 index 0000000..166e569 --- /dev/null +++ b/openssh-6.6p1-set_remote_ipaddr.patch @@ -0,0 +1,87 @@ +diff --git a/canohost.c b/canohost.c +index 97ce58c..1f9320a 100644 +--- a/canohost.c ++++ b/canohost.c +@@ -338,6 +338,21 @@ clear_cached_addr(void) + cached_port = -1; + } + ++void set_remote_ipaddr(void) { ++ if (canonical_host_ip != NULL) ++ free(canonical_host_ip); ++ ++ if (packet_connection_is_on_socket()) { ++ canonical_host_ip = ++ get_peer_ipaddr(packet_get_connection_in()); ++ if (canonical_host_ip == NULL) ++ cleanup_exit(255); ++ } else { ++ /* If not on socket, return UNKNOWN. */ ++ canonical_host_ip = xstrdup("UNKNOWN"); ++ } ++} ++ + /* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. +@@ -347,17 +362,9 @@ const char * + get_remote_ipaddr(void) + { + /* Check whether we have cached the ipaddr. */ +- if (canonical_host_ip == NULL) { +- if (packet_connection_is_on_socket()) { +- canonical_host_ip = +- get_peer_ipaddr(packet_get_connection_in()); +- if (canonical_host_ip == NULL) +- cleanup_exit(255); +- } else { +- /* If not on socket, return UNKNOWN. */ +- canonical_host_ip = xstrdup("UNKNOWN"); +- } +- } ++ if (canonical_host_ip == NULL) ++ set_remote_ipaddr(); ++ + return canonical_host_ip; + } + +diff --git a/canohost.h b/canohost.h +index 4c8636f..4079953 100644 +--- a/canohost.h ++++ b/canohost.h +@@ -13,6 +13,7 @@ + */ + + const char *get_canonical_hostname(int); ++void set_remote_ipaddr(void); + const char *get_remote_ipaddr(void); + const char *get_remote_name_or_ip(u_int, int); + +diff --git a/sshconnect.c b/sshconnect.c +index e636f33..451a58b 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -62,6 +62,7 @@ + #include "monitor_fdpass.h" + #include "ssh2.h" + #include "version.h" ++#include "canohost.h" + + char *client_version_string = NULL; + char *server_version_string = NULL; +@@ -170,6 +171,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, + + /* Set the connection file descriptors. */ + packet_set_connection(sock, sock); ++ set_remote_ipaddr(); + + return 0; + } +@@ -492,6 +494,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, + + /* Set the connection. */ + packet_set_connection(sock, sock); ++ set_remote_ipaddr(); + + return 0; + } From b5761e5d23044cbf3738e3dbe7cc6bc0f8835e8c Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 24 Nov 2014 13:32:03 +0100 Subject: [PATCH 007/146] Based on openssh-6.6.1p1-8.fc21 --- gsi-openssh.spec | 29 +- gsisshd-keygen | 4 +- ...h-6.3p1-krb5-use-default_ccache_name.patch | 2 +- ...ty.patch => openssh-6.6.1p1-coverity.patch | 360 ++++++++++-------- ...h-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch | 28 ++ openssh-6.6.1p1-selinux-contexts.patch | 118 ++++++ openssh-6.6.1p1-servconf-parser.patch | 31 ++ openssh-6.6p1-audit.patch | 76 ++-- openssh-6.6p1-gsissh.patch | 7 +- openssh-6.6p1-gsskex.patch | 26 +- openssh-6.6p1-kuserok.patch | 210 ++++++++-- 11 files changed, 650 insertions(+), 241 deletions(-) rename openssh-6.3p1-coverity.patch => openssh-6.6.1p1-coverity.patch (65%) create mode 100644 openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch create mode 100644 openssh-6.6.1p1-selinux-contexts.patch create mode 100644 openssh-6.6.1p1-servconf-parser.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 161c235..3a5bae1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ %global ldap 1 %global openssh_ver 6.6.1p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -50,7 +50,7 @@ Source13: gsisshd-keygen Source99: README.sshd-and-gsisshd #? -Patch100: openssh-6.3p1-coverity.patch +Patch100: openssh-6.6.1p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1872 Patch101: openssh-6.6p1-fingerprint.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 @@ -148,6 +148,14 @@ Patch912: openssh-6.6.1p1-utf8-banner.patch # don't consider a partial success as a failure # https://bugzilla.mindrot.org/show_bug.cgi?id=2270 Patch913: openssh-6.6.1p1-partial-success.patch +# fix parsing of empty options in sshd_conf +# https://bugzilla.mindrot.org/show_bug.cgi?id=2281 +Patch914: openssh-6.6.1p1-servconf-parser.patch +# Ignore SIGXFSZ in postauth monitor +# https://bugzilla.mindrot.org/show_bug.cgi?id=2263 +Patch915: openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch +# privsep_preauth: use SELinux context from selinux-policy (#1008580) +Patch916: openssh-6.6.1p1-selinux-contexts.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch @@ -176,8 +184,8 @@ BuildRequires: krb5-devel %if %{gsi} BuildRequires: globus-gss-assist-devel >= 8 -BuildRequires: globus-gssapi-gsi >= 10 -BuildRequires: globus-common >= 14 +BuildRequires: globus-gssapi-gsi-devel >= 10 +BuildRequires: globus-common-devel >= 14 BuildRequires: globus-usage-devel >= 3 %endif @@ -186,8 +194,8 @@ BuildRequires: libedit-devel ncurses-devel %endif %if %{WITH_SELINUX} -Requires: libselinux >= 1.27.7 -BuildRequires: libselinux-devel >= 1.27.7 +Requires: libselinux >= 2.3-5 +BuildRequires: libselinux-devel >= 2.3-5 Requires: audit-libs >= 1.0.8 BuildRequires: audit-libs >= 1.0.8 %endif @@ -249,7 +257,6 @@ This version of OpenSSH has been modified to support GSI authentication. %prep %setup -q -n openssh-6.6p1 -# rework %patch100 -p1 -b .coverity %patch101 -p1 -b .fingerprint # investigate %patch102 -p1 -b .getaddrinfo %patch103 -p1 -b .packet @@ -301,10 +308,15 @@ This version of OpenSSH has been modified to support GSI authentication. %patch911 -p1 -b .set_remote_ipaddr %patch912 -p1 -b .utf8-banner %patch913 -p1 -b .partial-success +%patch914 -p1 -b .servconf +%patch915 -p1 -b .SIGXFSZ +%patch916 -p1 -b .contexts %patch200 -p1 -b .audit %patch700 -p1 -b .fips +%patch100 -p1 -b .coverity + %patch98 -p1 -b .gsi sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h @@ -519,6 +531,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Mon Nov 24 2014 Mattias Ellert - 6.6.1p1-3 +- Based on openssh-6.6.1p1-8.fc21 + * Wed Oct 22 2014 Mattias Ellert - 6.6.1p1-2 - Based on openssh-6.6.1p1-5.fc21 diff --git a/gsisshd-keygen b/gsisshd-keygen index 80134db..b313c87 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -71,7 +71,7 @@ do_rsa_keygen() { } do_dsa_keygen() { - if [ ! -s $DSA_KEY ]; then + if [ ! -s $DSA_KEY -a `fips_enabled` -eq 0 ]; then echo -n $"Generating SSH2 DSA host key: " rm -f $DSA_KEY if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then @@ -113,7 +113,7 @@ do_ecdsa_keygen() { } do_ed25519_keygen() { - if [ ! -s $ED25519_KEY ]; then + if [ ! -s $ED25519_KEY -a `fips_enabled` -eq 0 ]; then echo -n $"Generating SSH2 ED25519 host key: " rm -f $ED25519_KEY if test ! -f $ED25519_KEY && $KEYGEN -q -t ed25519 -f $ED25519_KEY -C '' -N '' >&/dev/null; then diff --git a/openssh-6.3p1-krb5-use-default_ccache_name.patch b/openssh-6.3p1-krb5-use-default_ccache_name.patch index b9c8000..dd201a4 100644 --- a/openssh-6.3p1-krb5-use-default_ccache_name.patch +++ b/openssh-6.3p1-krb5-use-default_ccache_name.patch @@ -30,7 +30,7 @@ diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c + if (authctxt->krb5_ticket_file[0] == ':') + authctxt->krb5_ticket_file++; + -+ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type); ++ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type) + 2; authctxt->krb5_ccname = xmalloc(len); - snprintf(authctxt->krb5_ccname, len, "FILE:%s", + diff --git a/openssh-6.3p1-coverity.patch b/openssh-6.6.1p1-coverity.patch similarity index 65% rename from openssh-6.3p1-coverity.patch rename to openssh-6.6.1p1-coverity.patch index 69bcb81..9f71f9c 100644 --- a/openssh-6.3p1-coverity.patch +++ b/openssh-6.6.1p1-coverity.patch @@ -1,7 +1,8 @@ -diff -up openssh-6.3p1/auth-pam.c.coverity openssh-6.3p1/auth-pam.c ---- openssh-6.3p1/auth-pam.c.coverity 2013-06-02 00:07:32.000000000 +0200 -+++ openssh-6.3p1/auth-pam.c 2013-10-07 13:20:36.288298063 +0200 -@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * +diff --git a/auth-pam.c b/auth-pam.c +index cd1a775..690711e 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void **value) if (sshpam_thread_status != -1) return (sshpam_thread_status); signal(SIGCHLD, sshpam_oldsig); @@ -15,10 +16,11 @@ diff -up openssh-6.3p1/auth-pam.c.coverity openssh-6.3p1/auth-pam.c return (status); } #endif -diff -up openssh-6.3p1/channels.c.coverity openssh-6.3p1/channels.c ---- openssh-6.3p1/channels.c.coverity 2013-09-13 08:19:31.000000000 +0200 -+++ openssh-6.3p1/channels.c 2013-10-07 13:20:36.289298058 +0200 -@@ -233,11 +233,11 @@ channel_register_fds(Channel *c, int rfd +diff --git a/channels.c b/channels.c +index af3fdc2..39c9f89 100644 +--- a/channels.c ++++ b/channels.c +@@ -233,11 +233,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, channel_max_fd = MAX(channel_max_fd, wfd); channel_max_fd = MAX(channel_max_fd, efd); @@ -33,7 +35,7 @@ diff -up openssh-6.3p1/channels.c.coverity openssh-6.3p1/channels.c fcntl(efd, F_SETFD, FD_CLOEXEC); c->rfd = rfd; -@@ -255,11 +255,11 @@ channel_register_fds(Channel *c, int rfd +@@ -255,11 +255,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, /* enable nonblocking mode */ if (nonblock) { @@ -48,10 +50,11 @@ diff -up openssh-6.3p1/channels.c.coverity openssh-6.3p1/channels.c set_nonblock(efd); } } -diff -up openssh-6.3p1/clientloop.c.coverity openssh-6.3p1/clientloop.c ---- openssh-6.3p1/clientloop.c.coverity 2013-06-10 05:07:12.000000000 +0200 -+++ openssh-6.3p1/clientloop.c 2013-10-07 13:20:36.289298058 +0200 -@@ -2068,14 +2068,15 @@ client_input_global_request(int type, u_ +diff --git a/clientloop.c b/clientloop.c +index 9c60108..d372b53 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -2081,14 +2081,15 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) char *rtype; int want_reply; int success = 0; @@ -69,10 +72,11 @@ diff -up openssh-6.3p1/clientloop.c.coverity openssh-6.3p1/clientloop.c packet_send(); packet_write_wait(); } -diff -up openssh-6.3p1/key.c.coverity openssh-6.3p1/key.c ---- openssh-6.3p1/key.c.coverity 2013-06-01 23:41:51.000000000 +0200 -+++ openssh-6.3p1/key.c 2013-10-07 13:20:36.290298054 +0200 -@@ -807,8 +807,10 @@ key_read(Key *ret, char **cpp) +diff --git a/key.c b/key.c +index a2050f6..6487d81 100644 +--- a/key.c ++++ b/key.c +@@ -880,8 +880,10 @@ key_read(Key *ret, char **cpp) success = 1; /*XXXX*/ key_free(k); @@ -83,10 +87,11 @@ diff -up openssh-6.3p1/key.c.coverity openssh-6.3p1/key.c /* advance cp: skip whitespace and data */ while (*cp == ' ' || *cp == '\t') cp++; -diff -up openssh-6.3p1/monitor.c.coverity openssh-6.3p1/monitor.c ---- openssh-6.3p1/monitor.c.coverity 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/monitor.c 2013-10-07 13:54:36.761314042 +0200 -@@ -449,7 +449,7 @@ monitor_child_preauth(Authctxt *_authctx +diff --git a/monitor.c b/monitor.c +index 3ff62b0..70b9b4c 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -472,7 +472,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) mm_get_keystate(pmonitor); /* Drain any buffered messages from the child */ @@ -95,7 +100,7 @@ diff -up openssh-6.3p1/monitor.c.coverity openssh-6.3p1/monitor.c ; close(pmonitor->m_sendfd); -@@ -1202,6 +1202,10 @@ mm_answer_keyallowed(int sock, Buffer *m +@@ -1254,6 +1254,10 @@ mm_answer_keyallowed(int sock, Buffer *m) break; } } @@ -106,7 +111,7 @@ diff -up openssh-6.3p1/monitor.c.coverity openssh-6.3p1/monitor.c if (key != NULL) key_free(key); -@@ -1223,9 +1227,6 @@ mm_answer_keyallowed(int sock, Buffer *m +@@ -1275,9 +1279,6 @@ mm_answer_keyallowed(int sock, Buffer *m) free(chost); } @@ -116,10 +121,11 @@ diff -up openssh-6.3p1/monitor.c.coverity openssh-6.3p1/monitor.c buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); -diff -up openssh-6.3p1/monitor_wrap.c.coverity openssh-6.3p1/monitor_wrap.c ---- openssh-6.3p1/monitor_wrap.c.coverity 2013-06-02 00:07:32.000000000 +0200 -+++ openssh-6.3p1/monitor_wrap.c 2013-10-07 13:20:36.291298049 +0200 -@@ -710,10 +710,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 6df236a..93f6535 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -743,10 +743,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || (tmp2 = dup(pmonitor->m_recvfd)) == -1) { error("%s: cannot allocate fds for pty", __func__); @@ -133,10 +139,11 @@ diff -up openssh-6.3p1/monitor_wrap.c.coverity openssh-6.3p1/monitor_wrap.c return 0; } close(tmp1); -diff -up openssh-6.3p1/openbsd-compat/bindresvport.c.coverity openssh-6.3p1/openbsd-compat/bindresvport.c ---- openssh-6.3p1/openbsd-compat/bindresvport.c.coverity 2010-12-03 00:50:26.000000000 +0100 -+++ openssh-6.3p1/openbsd-compat/bindresvport.c 2013-10-07 13:20:36.291298049 +0200 -@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr +diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c +index c89f214..80115c2 100644 +--- a/openbsd-compat/bindresvport.c ++++ b/openbsd-compat/bindresvport.c +@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) struct sockaddr_in6 *in6; u_int16_t *portp; u_int16_t port; @@ -145,10 +152,11 @@ diff -up openssh-6.3p1/openbsd-compat/bindresvport.c.coverity openssh-6.3p1/open int i; if (sa == NULL) { -diff -up openssh-6.3p1/packet.c.coverity openssh-6.3p1/packet.c ---- openssh-6.3p1/packet.c.coverity 2013-07-18 08:12:45.000000000 +0200 -+++ openssh-6.3p1/packet.c 2013-10-07 13:20:36.291298049 +0200 -@@ -1199,6 +1199,7 @@ packet_read_poll1(void) +diff --git a/packet.c b/packet.c +index f5b122b..1305e87 100644 +--- a/packet.c ++++ b/packet.c +@@ -1234,6 +1234,7 @@ packet_read_poll1(void) case DEATTACK_DETECTED: packet_disconnect("crc32 compensation attack: " "network attack detected"); @@ -156,19 +164,20 @@ diff -up openssh-6.3p1/packet.c.coverity openssh-6.3p1/packet.c case DEATTACK_DOS_DETECTED: packet_disconnect("deattack denial of " "service detected"); -diff -up openssh-6.3p1/progressmeter.c.coverity openssh-6.3p1/progressmeter.c ---- openssh-6.3p1/progressmeter.c.coverity 2013-06-02 15:46:24.000000000 +0200 -+++ openssh-6.3p1/progressmeter.c 2013-10-07 13:42:32.377850691 +0200 +diff --git a/progressmeter.c b/progressmeter.c +index bbbc706..ae6d1aa 100644 +--- a/progressmeter.c ++++ b/progressmeter.c @@ -65,7 +65,7 @@ static void update_progress_meter(int); static time_t start; /* start progress */ static time_t last_update; /* last progress update */ -static char *file; /* name of the file being transferred */ +static const char *file; /* name of the file being transferred */ + static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ - static volatile off_t *counter; /* progress counter */ -@@ -247,7 +247,7 @@ update_progress_meter(int ignore) +@@ -248,7 +248,7 @@ update_progress_meter(int ignore) } void @@ -177,9 +186,10 @@ diff -up openssh-6.3p1/progressmeter.c.coverity openssh-6.3p1/progressmeter.c { start = last_update = monotime(); file = f; -diff -up openssh-6.3p1/progressmeter.h.coverity openssh-6.3p1/progressmeter.h ---- openssh-6.3p1/progressmeter.h.coverity 2006-03-26 05:30:02.000000000 +0200 -+++ openssh-6.3p1/progressmeter.h 2013-10-07 13:20:36.292298044 +0200 +diff --git a/progressmeter.h b/progressmeter.h +index 10bab99..e9ca8f0 100644 +--- a/progressmeter.h ++++ b/progressmeter.h @@ -23,5 +23,5 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -187,9 +197,10 @@ diff -up openssh-6.3p1/progressmeter.h.coverity openssh-6.3p1/progressmeter.h -void start_progress_meter(char *, off_t, off_t *); +void start_progress_meter(const char *, off_t, off_t *); void stop_progress_meter(void); -diff -up openssh-6.3p1/scp.c.coverity openssh-6.3p1/scp.c ---- openssh-6.3p1/scp.c.coverity 2013-07-18 08:11:25.000000000 +0200 -+++ openssh-6.3p1/scp.c 2013-10-07 13:20:36.292298044 +0200 +diff --git a/scp.c b/scp.c +index 1178a07..d9bc016 100644 +--- a/scp.c ++++ b/scp.c @@ -155,7 +155,7 @@ killchild(int signo) { if (do_cmd_pid > 1) { @@ -199,10 +210,11 @@ diff -up openssh-6.3p1/scp.c.coverity openssh-6.3p1/scp.c } if (signo) -diff -up openssh-6.3p1/servconf.c.coverity openssh-6.3p1/servconf.c ---- openssh-6.3p1/servconf.c.coverity 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/servconf.c 2013-10-07 13:20:36.293298039 +0200 -@@ -1323,7 +1323,7 @@ process_server_config_line(ServerOptions +diff --git a/servconf.c b/servconf.c +index 3839928..d482e79 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1382,7 +1382,7 @@ process_server_config_line(ServerOptions *options, char *line, fatal("%s line %d: Missing subsystem name.", filename, linenum); if (!*activep) { @@ -211,7 +223,7 @@ diff -up openssh-6.3p1/servconf.c.coverity openssh-6.3p1/servconf.c break; } for (i = 0; i < options->num_subsystems; i++) -@@ -1414,8 +1414,9 @@ process_server_config_line(ServerOptions +@@ -1473,8 +1473,9 @@ process_server_config_line(ServerOptions *options, char *line, if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ @@ -223,9 +235,10 @@ diff -up openssh-6.3p1/servconf.c.coverity openssh-6.3p1/servconf.c } break; -diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c ---- openssh-6.3p1/serverloop.c.coverity 2013-07-18 08:12:45.000000000 +0200 -+++ openssh-6.3p1/serverloop.c 2013-10-07 13:43:36.620537138 +0200 +diff --git a/serverloop.c b/serverloop.c +index 2f8e3a0..e03bc6c 100644 +--- a/serverloop.c ++++ b/serverloop.c @@ -147,13 +147,13 @@ notify_setup(void) static void notify_parent(void) @@ -253,7 +266,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c debug2("notify_done: reading"); } -@@ -336,7 +336,7 @@ wait_until_can_do_something(fd_set **rea +@@ -337,7 +337,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, * If we have buffered data, try to write some of that data * to the program. */ @@ -262,7 +275,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c FD_SET(fdin, *writesetp); } notify_prepare(*readsetp); -@@ -476,7 +476,7 @@ process_output(fd_set *writeset) +@@ -477,7 +477,7 @@ process_output(fd_set *writeset) int len; /* Write buffered data to program stdin. */ @@ -271,7 +284,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c data = buffer_ptr(&stdin_buffer); dlen = buffer_len(&stdin_buffer); len = write(fdin, data, dlen); -@@ -589,7 +589,7 @@ server_loop(pid_t pid, int fdin_arg, int +@@ -590,7 +590,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) set_nonblock(fdin); set_nonblock(fdout); /* we don't have stderr for interactive terminal sessions, see below */ @@ -280,7 +293,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c set_nonblock(fderr); if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) -@@ -613,7 +613,7 @@ server_loop(pid_t pid, int fdin_arg, int +@@ -614,7 +614,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); @@ -289,7 +302,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c max_fd = MAX(max_fd, fderr); #endif -@@ -643,7 +643,7 @@ server_loop(pid_t pid, int fdin_arg, int +@@ -644,7 +644,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) * If we have received eof, and there is no more pending * input data, cause a real eof by closing fdin. */ @@ -298,7 +311,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c if (fdin != fdout) close(fdin); else -@@ -739,15 +739,15 @@ server_loop(pid_t pid, int fdin_arg, int +@@ -740,15 +740,15 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) buffer_free(&stderr_buffer); /* Close the file descriptors. */ @@ -317,7 +330,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c close(fdin); fdin = -1; -@@ -946,7 +946,7 @@ server_input_window_size(int type, u_int +@@ -947,7 +947,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt) debug("Window change received."); packet_check_eom(); @@ -326,7 +339,7 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c pty_change_window_size(fdin, row, col, xpixel, ypixel); } -@@ -1006,7 +1006,7 @@ server_request_tun(void) +@@ -1007,7 +1007,7 @@ server_request_tun(void) } tun = packet_get_int(); @@ -335,10 +348,11 @@ diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c if (tun != SSH_TUNID_ANY && forced_tun_device != tun) goto done; tun = forced_tun_device; -diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c ---- openssh-6.3p1/sftp-client.c.coverity 2013-07-26 00:40:00.000000000 +0200 -+++ openssh-6.3p1/sftp-client.c 2013-10-07 13:48:45.885027420 +0200 -@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer * +diff --git a/sftp-client.c b/sftp-client.c +index 2f5907c..3a2affd 100644 +--- a/sftp-client.c ++++ b/sftp-client.c +@@ -151,7 +151,7 @@ get_msg(struct sftp_conn *conn, Buffer *m) } static void @@ -347,7 +361,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c u_int len) { Buffer msg; -@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co +@@ -167,7 +167,7 @@ send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, static void send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, @@ -356,7 +370,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { Buffer msg; -@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con +@@ -429,7 +429,7 @@ sftp_proto_version(struct sftp_conn *conn) } int @@ -365,16 +379,16 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int id, status; Buffer msg; -@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h +@@ -454,7 +454,7 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len) static int --do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, -+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag, +-do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, ++do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, SFTP_DIRENT ***dir) { Buffer msg; -@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha +@@ -577,7 +577,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, } int @@ -383,7 +397,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { return(do_lsreaddir(conn, path, 0, dir)); } -@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) +@@ -597,7 +597,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) } int @@ -392,16 +406,16 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int status, id; -@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path +@@ -612,7 +612,7 @@ do_rm(struct sftp_conn *conn, char *path) } int --do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) -+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag) +-do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) ++do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) { u_int status, id; -@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p +@@ -628,7 +628,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) } int @@ -410,7 +424,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int status, id; -@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p +@@ -644,7 +644,7 @@ do_rmdir(struct sftp_conn *conn, char *path) } Attrib * @@ -419,7 +433,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int id; -@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa +@@ -658,7 +658,7 @@ do_stat(struct sftp_conn *conn, char *path, int quiet) } Attrib * @@ -428,7 +442,16 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int id; -@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h +@@ -679,7 +679,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) + + #ifdef notyet + Attrib * +-do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) ++do_fstat(struct sftp_conn *conn, const char *handle, u_int handle_len, int quiet) + { + u_int id; + +@@ -692,7 +692,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) #endif int @@ -437,7 +460,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { u_int status, id; -@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char +@@ -709,7 +709,7 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a) } int @@ -446,7 +469,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c Attrib *a) { u_int status, id; -@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char +@@ -726,7 +726,7 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, } char * @@ -455,16 +478,16 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { Buffer msg; u_int type, expected_id, count, id; -@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char +@@ -775,7 +775,7 @@ do_realpath(struct sftp_conn *conn, char *path) } int --do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath) +-do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, ++do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, + int force_legacy) { Buffer msg; - u_int status, id; -@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char * +@@ -811,7 +811,7 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, } int @@ -473,7 +496,7 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { Buffer msg; u_int status, id; -@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char +@@ -844,7 +844,7 @@ do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) } int @@ -482,61 +505,88 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { Buffer msg; u_int status, id; -@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn +@@ -876,7 +876,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) + } + + int +-do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) ++do_fsync(struct sftp_conn *conn, const char *handle, u_int handle_len) + { + Buffer msg; + u_int status, id; +@@ -907,7 +907,7 @@ do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) + + #ifdef notyet + char * +-do_readlink(struct sftp_conn *conn, char *path) ++do_readlink(struct sftp_conn *conn, const char *path) + { + Buffer msg; + u_int type, expected_id, count, id; +@@ -1010,7 +1010,7 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, + + static void + send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, +- u_int len, char *handle, u_int handle_len) ++ u_int len, const char *handle, u_int handle_len) + { + Buffer msg; + +@@ -1026,7 +1026,7 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, } int -do_download(struct sftp_conn *conn, char *remote_path, char *local_path, +do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, - Attrib *a, int pflag, int resume) + Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) { Attrib junk; -@@ -1255,7 +1255,7 @@ do_download(struct sftp_conn *conn, char +@@ -1308,7 +1308,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, } static int --download_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag, int depth, int resume) +-download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, ++download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, + Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, + int fsync_flag) { - int i, ret = 0; -@@ -1345,7 +1345,7 @@ download_dir_internal(struct sftp_conn * +@@ -1400,7 +1400,7 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, } int -download_dir(struct sftp_conn *conn, char *src, char *dst, +download_dir(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag, int resume) + Attrib *dirattrib, int preserve_flag, int print_flag, + int resume_flag, int fsync_flag) { - char *src_canon; -@@ -1363,7 +1363,7 @@ download_dir(struct sftp_conn *conn, cha +@@ -1419,7 +1419,7 @@ download_dir(struct sftp_conn *conn, char *src, char *dst, } int -do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, +do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, - int pflag) + int preserve_flag, int fsync_flag) { int local_fd; -@@ -1548,7 +1548,7 @@ do_upload(struct sftp_conn *conn, char * +@@ -1607,7 +1607,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, } static int --upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - int pflag, int printflag, int depth) +-upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, ++upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, + int preserve_flag, int print_flag, int fsync_flag) { int ret = 0, status; -@@ -1639,7 +1639,7 @@ upload_dir_internal(struct sftp_conn *co +@@ -1700,7 +1700,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, } int --upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, -+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag, - int pflag) +-upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, ++upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, + int print_flag, int fsync_flag) { char *dst_canon; -@@ -1656,7 +1656,7 @@ upload_dir(struct sftp_conn *conn, char +@@ -1719,7 +1719,7 @@ upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, } char * @@ -545,10 +595,11 @@ diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c { char *ret; size_t len = strlen(p1) + strlen(p2) + 2; -diff -up openssh-6.3p1/sftp-client.h.coverity openssh-6.3p1/sftp-client.h ---- openssh-6.3p1/sftp-client.h.coverity 2013-07-25 03:56:52.000000000 +0200 -+++ openssh-6.3p1/sftp-client.h 2013-10-07 13:45:10.108080813 +0200 -@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in +diff --git a/sftp-client.h b/sftp-client.h +index ba92ad0..c085423 100644 +--- a/sftp-client.h ++++ b/sftp-client.h +@@ -56,79 +56,79 @@ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); u_int sftp_proto_version(struct sftp_conn *); /* Close file referred to by 'handle' */ @@ -598,57 +649,60 @@ diff -up openssh-6.3p1/sftp-client.h.coverity openssh-6.3p1/sftp-client.h int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); /* Rename 'oldpath' to 'newpath' */ --int do_rename(struct sftp_conn *, char *, char *); -+int do_rename(struct sftp_conn *, const char *, const char *); +-int do_rename(struct sftp_conn *, char *, char *m, int force_legacy); ++int do_rename(struct sftp_conn *, const char *, const char *m, int force_legacy); /* Link 'oldpath' to 'newpath' */ -int do_hardlink(struct sftp_conn *, char *, char *); +int do_hardlink(struct sftp_conn *, const char *, const char *); --/* Rename 'oldpath' to 'newpath' */ + /* Rename 'oldpath' to 'newpath' */ -int do_symlink(struct sftp_conn *, char *, char *); -+/* Symlink 'oldpath' to 'newpath' */ +int do_symlink(struct sftp_conn *, const char *, const char *); - /* XXX: add callbacks to do_download/do_upload so we can do progress meter */ + /* Call fsync() on open file 'handle' */ +-int do_fsync(struct sftp_conn *conn, char *, u_int); ++int do_fsync(struct sftp_conn *conn, const char *, u_int); -@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char + /* * Download 'remote_path' to 'local_path'. Preserve permissions and times * if 'pflag' is set */ --int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int); -+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int); +-int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int, int); ++int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int); /* * Recursively download 'remote_directory' to 'local_directory'. Preserve * times if 'pflag' is set */ --int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int, int); -+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int); +-int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, ++int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, + int, int, int); /* * Upload 'local_path' to 'remote_path'. Preserve permissions and times * if 'pflag' is set */ --int do_upload(struct sftp_conn *, char *, char *, int); -+int do_upload(struct sftp_conn *, const char *, const char *, int); +-int do_upload(struct sftp_conn *, char *, char *, int, int); ++int do_upload(struct sftp_conn *, const char *, const char *, int, int); /* * Recursively upload 'local_directory' to 'remote_directory'. Preserve * times if 'pflag' is set */ --int upload_dir(struct sftp_conn *, char *, char *, int, int); -+int upload_dir(struct sftp_conn *, const char *, const char *, int, int); +-int upload_dir(struct sftp_conn *, char *, char *, int, int, int); ++int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int); /* Concatenate paths, taking care of slashes. Caller must free result. */ -char *path_append(char *, char *); +char *path_append(const char *, const char *); #endif -diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c ---- openssh-6.3p1/sftp.c.coverity 2013-07-25 03:56:52.000000000 +0200 -+++ openssh-6.3p1/sftp.c 2013-10-07 13:49:47.322727449 +0200 -@@ -213,7 +213,7 @@ killchild(int signo) +diff --git a/sftp.c b/sftp.c +index ad1f8c8..3987117 100644 +--- a/sftp.c ++++ b/sftp.c +@@ -218,7 +218,7 @@ killchild(int signo) { if (sshpid > 1) { kill(sshpid, SIGTERM); @@ -657,7 +711,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c } _exit(1); -@@ -324,7 +324,7 @@ local_do_ls(const char *args) +@@ -329,7 +329,7 @@ local_do_ls(const char *args) /* Strip one path (usually the pwd) from the start of another */ static char * @@ -666,7 +720,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { size_t len; -@@ -342,7 +342,7 @@ path_strip(char *path, char *strip) +@@ -347,7 +347,7 @@ path_strip(char *path, char *strip) } static char * @@ -675,7 +729,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { char *abs_str; -@@ -493,7 +493,7 @@ parse_df_flags(const char *cmd, char **a +@@ -545,7 +545,7 @@ parse_no_flags(const char *cmd, char **argv, int argc) } static int @@ -684,7 +738,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { struct stat sb; -@@ -505,7 +505,7 @@ is_dir(char *path) +@@ -557,7 +557,7 @@ is_dir(char *path) } static int @@ -693,7 +747,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { Attrib *a; -@@ -519,7 +519,7 @@ remote_is_dir(struct sftp_conn *conn, ch +@@ -571,7 +571,7 @@ remote_is_dir(struct sftp_conn *conn, char *path) /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ static int @@ -702,25 +756,25 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { size_t l = strlen(pathname); -@@ -527,7 +527,7 @@ pathname_is_dir(char *pathname) +@@ -579,7 +579,7 @@ pathname_is_dir(char *pathname) } static int -process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, +process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag, int resume) + int pflag, int rflag, int resume, int fflag) { char *abs_src = NULL; -@@ -605,7 +605,7 @@ out: +@@ -659,7 +659,7 @@ out: } static int -process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, +process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag) + int pflag, int rflag, int fflag) { char *tmp_dst = NULL; -@@ -709,7 +709,7 @@ sdirent_comp(const void *aa, const void +@@ -765,7 +765,7 @@ sdirent_comp(const void *aa, const void *bb) /* sftp ls.1 replacement for directories */ static int @@ -729,7 +783,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { int n; u_int c = 1, colspace = 0, columns = 1; -@@ -794,7 +794,7 @@ do_ls_dir(struct sftp_conn *conn, char * +@@ -850,7 +850,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) /* sftp ls.1 replacement which handles path globs */ static int @@ -738,7 +792,7 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c int lflag) { char *fname, *lname; -@@ -875,7 +875,7 @@ do_globbed_ls(struct sftp_conn *conn, ch +@@ -931,7 +931,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, } static int @@ -747,10 +801,11 @@ diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c { struct sftp_statvfs st; char s_used[FMT_SCALED_STRSIZE]; -diff -up openssh-6.3p1/ssh-agent.c.coverity openssh-6.3p1/ssh-agent.c ---- openssh-6.3p1/ssh-agent.c.coverity 2013-07-20 05:22:49.000000000 +0200 -+++ openssh-6.3p1/ssh-agent.c 2013-10-07 13:20:36.296298024 +0200 -@@ -1143,8 +1143,8 @@ main(int ac, char **av) +diff --git a/ssh-agent.c b/ssh-agent.c +index 117fdde..2b50132 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1037,8 +1037,8 @@ main(int ac, char **av) sanitise_stdfd(); /* drop */ @@ -761,10 +816,11 @@ diff -up openssh-6.3p1/ssh-agent.c.coverity openssh-6.3p1/ssh-agent.c #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* Disable ptrace on Linux without sgid bit */ -diff -up openssh-6.3p1/sshd.c.coverity openssh-6.3p1/sshd.c ---- openssh-6.3p1/sshd.c.coverity 2013-07-20 05:21:53.000000000 +0200 -+++ openssh-6.3p1/sshd.c 2013-10-07 13:20:36.296298024 +0200 -@@ -699,8 +699,10 @@ privsep_preauth(Authctxt *authctxt) +diff --git a/sshd.c b/sshd.c +index 773bb02..1eaa9f7 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -771,8 +771,10 @@ privsep_preauth(Authctxt *authctxt) if (getuid() == 0 || geteuid() == 0) privsep_preauth_child(); setproctitle("%s", "[net]"); @@ -776,7 +832,7 @@ diff -up openssh-6.3p1/sshd.c.coverity openssh-6.3p1/sshd.c return 0; } -@@ -1345,6 +1347,9 @@ server_accept_loop(int *sock_in, int *so +@@ -1439,6 +1441,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) if (num_listen_socks < 0) break; } diff --git a/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch b/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch new file mode 100644 index 0000000..87434ce --- /dev/null +++ b/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch @@ -0,0 +1,28 @@ +diff --git a/ChangeLog b/ChangeLog +index 3887495..a4dc72f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++20140823 ++ - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on ++ lastlog writing on platforms with high UIDs; bz#2263 ++ - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth ++ monitor, not preauth; bz#2263 ++ + 20140703 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2014/07/03 03:34:09 +diff --git a/monitor.c b/monitor.c +index bdabe21..5a65114 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -501,6 +501,9 @@ monitor_child_postauth(struct monitor *pmonitor) + signal(SIGHUP, &monitor_child_handler); + signal(SIGTERM, &monitor_child_handler); + signal(SIGINT, &monitor_child_handler); ++#ifdef SIGXFSZ ++ signal(SIGXFSZ, SIG_IGN); ++#endif + + if (compat20) { + mon_dispatch = mon_dispatch_postauth20; diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch new file mode 100644 index 0000000..a831a15 --- /dev/null +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -0,0 +1,118 @@ +diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c +index 0077dd7..e3f2ced 100644 +--- a/openbsd-compat/port-linux-sshd.c ++++ b/openbsd-compat/port-linux-sshd.c +@@ -31,6 +31,7 @@ + #include "xmalloc.h" + #include "servconf.h" + #include "port-linux.h" ++#include "misc.h" + #include "key.h" + #include "hostfile.h" + #include "auth.h" +@@ -444,7 +445,7 @@ sshd_selinux_setup_exec_context(char *pwname) + void + sshd_selinux_copy_context(void) + { +- security_context_t *ctx; ++ char *ctx; + + if (!sshd_selinux_enabled()) + return; +@@ -460,6 +461,58 @@ sshd_selinux_copy_context(void) + } + } + ++void ++sshd_selinux_change_privsep_preauth_context(void) ++{ ++ int len; ++ char line[1024], *preauth_context = NULL, *cp, *arg; ++ const char *contexts_path; ++ FILE *contexts_file; ++ ++ contexts_path = selinux_openssh_contexts_path(); ++ if (contexts_path != NULL) { ++ if ((contexts_file = fopen(contexts_path, "r")) != NULL) { ++ struct stat sb; ++ ++ if (fstat(fileno(contexts_file), &sb) == 0 && ((sb.st_uid == 0) && ((sb.st_mode & 022) == 0))) { ++ while (fgets(line, sizeof(line), contexts_file)) { ++ /* Strip trailing whitespace */ ++ for (len = strlen(line) - 1; len > 0; len--) { ++ if (strchr(" \t\r\n", line[len]) == NULL) ++ break; ++ line[len] = '\0'; ++ } ++ ++ if (line[0] == '\0') ++ continue; ++ ++ cp = line; ++ arg = strdelim(&cp); ++ if (*arg == '\0') ++ arg = strdelim(&cp); ++ ++ if (strcmp(arg, "privsep_preauth") == 0) { ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') { ++ debug("%s: privsep_preauth is empty", __func__); ++ fclose(contexts_file); ++ return; ++ } ++ preauth_context = xstrdup(arg); ++ } ++ } ++ } ++ fclose(contexts_file); ++ } ++ } ++ ++ if (preauth_context == NULL) ++ preauth_context = xstrdup("sshd_net_t"); ++ ++ ssh_selinux_change_context(preauth_context); ++ free(preauth_context); ++} ++ + #endif + #endif + +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 22ea8ef..1fc963d 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) + strlcpy(newctx + len, newname, newlen - len); + if ((cx = index(cx + 1, ':'))) + strlcat(newctx, cx, newlen); +- debug3("%s: setting context from '%s' to '%s'", __func__, ++ debug("%s: setting context from '%s' to '%s'", __func__, + oldctx, newctx); + if (setcon(newctx) < 0) + 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 cb51f99..8b7cda2 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -29,6 +29,7 @@ int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); + void sshd_selinux_setup_exec_context(char *); + int sshd_selinux_setup_env_variables(void); ++void sshd_selinux_change_privsep_preauth_context(void); + #endif + + #ifdef LINUX_OOM_ADJUST +diff --git a/sshd.c b/sshd.c +index 512c7ed..3eee75a 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -637,7 +637,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 + + /* Change our root directory */ diff --git a/openssh-6.6.1p1-servconf-parser.patch b/openssh-6.6.1p1-servconf-parser.patch new file mode 100644 index 0000000..b93f6f3 --- /dev/null +++ b/openssh-6.6.1p1-servconf-parser.patch @@ -0,0 +1,31 @@ +diff --git a/servconf.c b/servconf.c +index b7f3294..bc1e909 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1550,7 +1550,7 @@ process_server_config_line(ServerOptions *options, char *line, + break; + + case sForceCommand: +- if (cp == NULL) ++ if (cp == NULL || *cp == '\0') + fatal("%.200s line %d: Missing argument.", filename, + linenum); + len = strspn(cp, WHITESPACE); +@@ -1595,7 +1595,7 @@ process_server_config_line(ServerOptions *options, char *line, + break; + + case sVersionAddendum: +- if (cp == NULL) ++ if (cp == NULL || *cp == '\0') + fatal("%.200s line %d: Missing argument.", filename, + linenum); + len = strspn(cp, WHITESPACE); +@@ -1630,6 +1630,8 @@ process_server_config_line(ServerOptions *options, char *line, + break; + + case sAuthenticationMethods: ++ if (cp == NULL || *cp == '\0') ++ fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep && options->num_auth_methods == 0) { + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_auth_methods >= diff --git a/openssh-6.6p1-audit.patch b/openssh-6.6p1-audit.patch index b83b46a..7e0c0f4 100644 --- a/openssh-6.6p1-audit.patch +++ b/openssh-6.6p1-audit.patch @@ -486,7 +486,7 @@ index b3ee2f4..946f7fa 100644 +} #endif /* USE_LINUX_AUDIT */ diff --git a/audit.c b/audit.c -index ced57fa..b806f03 100644 +index ced57fa..ab9fb82 100644 --- a/audit.c +++ b/audit.c @@ -28,6 +28,7 @@ @@ -507,7 +507,23 @@ index ced57fa..b806f03 100644 /* * Care must be taken when using this since it WILL NOT be initialized when -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -71,13 +75,10 @@ audit_classify_auth(const char *method) + const char * + audit_username(void) + { +- static const char unknownuser[] = "(unknown user)"; +- static const char invaliduser[] = "(invalid user)"; ++ static const char unknownuser[] = "(unknown)"; + +- if (the_authctxt == NULL || the_authctxt->user == NULL) ++ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) + return (unknownuser); +- if (!the_authctxt->valid) +- return (invaliduser); + return (the_authctxt->user); + } + +@@ -111,6 +112,40 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -548,7 +564,7 @@ index ced57fa..b806f03 100644 # ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) +@@ -140,6 +175,17 @@ audit_event(ssh_audit_event_t event) } /* @@ -566,7 +582,7 @@ index ced57fa..b806f03 100644 * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) +@@ -174,13 +220,91 @@ audit_session_close(struct logininfo *li) /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -795,6 +811,20 @@ index 5dad6c3..f225b0b 100644 } /* +diff --git a/auth.c b/auth.c +index 420a85b..d613f8c 100644 +--- a/auth.c ++++ b/auth.c +@@ -628,9 +628,6 @@ getpwnamallow(const char *user) + record_failed_login(user, + get_canonical_hostname(options.use_dns), "ssh"); + #endif +-#ifdef SSH_AUDIT_EVENTS +- audit_event(SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(pw)) diff --git a/auth.h b/auth.h index 4605588..f9d191c 100644 --- a/auth.h @@ -880,7 +910,7 @@ index cb0f931..6d1c872 100644 match_principals_option(const char *principal_list, struct KeyCert *cert) { diff --git a/auth2.c b/auth2.c -index 0f52b68..472a5b2 100644 +index 426dcd6..436cd60 100644 --- a/auth2.c +++ b/auth2.c @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) @@ -1143,7 +1173,7 @@ index fbe18c4..7dc7f43 100644 void mac_clear(Mac *); +void mac_destroy(Mac *); diff --git a/monitor.c b/monitor.c -index aa70945..bdabe21 100644 +index 8b18086..5a65114 100644 --- a/monitor.c +++ b/monitor.c @@ -97,6 +97,7 @@ @@ -1221,7 +1251,7 @@ index aa70945..bdabe21 100644 #endif {0, 0, NULL} }; -@@ -1390,9 +1416,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1393,9 +1419,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1233,7 +1263,7 @@ index aa70945..bdabe21 100644 blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1400,6 +1428,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1403,6 +1431,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1242,7 +1272,7 @@ index aa70945..bdabe21 100644 key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1420,7 +1450,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1423,7 +1453,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1261,7 +1291,7 @@ index aa70945..bdabe21 100644 debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1473,6 +1513,12 @@ mm_session_close(Session *s) +@@ -1476,6 +1516,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1274,7 +1304,7 @@ index aa70945..bdabe21 100644 session_unused(s->self); } -@@ -1753,6 +1799,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1756,6 +1802,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1283,7 +1313,7 @@ index aa70945..bdabe21 100644 while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1795,11 +1843,43 @@ mm_answer_audit_command(int socket, Buffer *m) +@@ -1798,11 +1846,43 @@ mm_answer_audit_command(int socket, Buffer *m) { u_int len; char *cmd; @@ -1328,7 +1358,7 @@ index aa70945..bdabe21 100644 free(cmd); return (0); } -@@ -1943,11 +2023,13 @@ mm_get_keystate(struct monitor *pmonitor) +@@ -1946,11 +2026,13 @@ mm_get_keystate(struct monitor *pmonitor) blob = buffer_get_string(&m, &bloblen); current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); @@ -1342,7 +1372,7 @@ index aa70945..bdabe21 100644 free(blob); /* Now get sequence numbers for the packets */ -@@ -1993,6 +2075,21 @@ mm_get_keystate(struct monitor *pmonitor) +@@ -1996,6 +2078,21 @@ mm_get_keystate(struct monitor *pmonitor) } buffer_free(&m); @@ -1364,7 +1394,7 @@ index aa70945..bdabe21 100644 } -@@ -2274,3 +2371,85 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) { +@@ -2277,3 +2374,85 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) { #endif /* GSSAPI */ @@ -1860,7 +1890,7 @@ index f8edf85..c36c812 100644 +void packet_destroy_all(int, int); #endif /* PACKET_H */ diff --git a/session.c b/session.c -index e4add93..626a642 100644 +index df43592..b186ca1 100644 --- a/session.c +++ b/session.c @@ -138,7 +138,7 @@ extern int log_stderr; @@ -1921,7 +1951,7 @@ index e4add93..626a642 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1932,6 +1947,7 @@ session_unused(int id) +@@ -1933,6 +1948,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1929,7 +1959,7 @@ index e4add93..626a642 100644 sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2014,6 +2030,19 @@ session_open(Authctxt *authctxt, int chanid) +@@ -2015,6 +2031,19 @@ session_open(Authctxt *authctxt, int chanid) } Session * @@ -1949,7 +1979,7 @@ index e4add93..626a642 100644 session_by_tty(char *tty) { int i; -@@ -2530,6 +2559,30 @@ session_exit_message(Session *s, int status) +@@ -2531,6 +2560,30 @@ session_exit_message(Session *s, int status) chan_write_failed(c); } @@ -1980,7 +2010,7 @@ index e4add93..626a642 100644 void session_close(Session *s) { -@@ -2538,6 +2591,10 @@ session_close(Session *s) +@@ -2539,6 +2592,10 @@ session_close(Session *s) debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1991,7 +2021,7 @@ index e4add93..626a642 100644 free(s->term); free(s->display); free(s->x11_chanids); -@@ -2752,6 +2809,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2753,6 +2810,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -2007,7 +2037,7 @@ index e4add93..626a642 100644 void do_cleanup(Authctxt *authctxt) { -@@ -2800,5 +2866,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2801,5 +2867,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -2043,7 +2073,7 @@ index 6a2f35e..e9b312e 100644 void session_close(Session *); void do_setusercontext(struct passwd *); diff --git a/sshd.c b/sshd.c -index 512c7ed..b561ec8 100644 +index 8a0740a..2813aa2 100644 --- a/sshd.c +++ b/sshd.c @@ -119,6 +119,7 @@ diff --git a/openssh-6.6p1-gsissh.patch b/openssh-6.6p1-gsissh.patch index f949f5f..9402ed5 100644 --- a/openssh-6.6p1-gsissh.patch +++ b/openssh-6.6p1-gsissh.patch @@ -1437,11 +1437,10 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -267,6 +270,10 @@ - {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, +@@ -268,6 +271,9 @@ {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, -+ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, + {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, + {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname}, @@ -2265,7 +2264,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config --- openssh-6.6p1.orig/sshd_config 2014-07-14 19:49:55.160268455 +0200 +++ openssh-6.6p1/sshd_config 2014-07-15 06:37:02.657343409 +0200 @@ -90,10 +90,11 @@ - #KerberosUseKuserok no + #KerberosUseKuserok yes # GSSAPI options -GSSAPIAuthentication yes diff --git a/openssh-6.6p1-gsskex.patch b/openssh-6.6p1-gsskex.patch index 90e84d2..826acd4 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -1741,7 +1741,13 @@ index 229fada..aa70945 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -258,6 +260,12 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -253,11 +255,18 @@ struct mon_table mon_dispatch_proto20[] = { + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, + {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, ++ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + #endif + {0, 0, NULL} }; struct mon_table mon_dispatch_postauth20[] = { @@ -1754,7 +1760,7 @@ index 229fada..aa70945 100644 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, {MONITOR_REQ_SIGN, 0, mm_answer_sign}, {MONITOR_REQ_PTY, 0, mm_answer_pty}, -@@ -366,6 +374,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) +@@ -366,6 +375,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1765,7 +1771,7 @@ index 229fada..aa70945 100644 } else { mon_dispatch = mon_dispatch_proto15; -@@ -471,6 +483,10 @@ monitor_child_postauth(struct monitor *pmonitor) +@@ -471,6 +484,10 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1776,7 +1782,7 @@ index 229fada..aa70945 100644 } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1866,6 +1882,13 @@ mm_get_kex(Buffer *m) +@@ -1866,6 +1883,13 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1790,7 +1796,7 @@ index 229fada..aa70945 100644 kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); -@@ -2073,6 +2096,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) +@@ -2073,6 +2097,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) OM_uint32 major; u_int len; @@ -1800,7 +1806,7 @@ index 229fada..aa70945 100644 goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2100,6 +2126,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) +@@ -2100,6 +2127,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1810,7 +1816,7 @@ index 229fada..aa70945 100644 in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2117,6 +2146,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) +@@ -2117,6 +2147,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1818,7 +1824,7 @@ index 229fada..aa70945 100644 } return (0); } -@@ -2128,6 +2158,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) +@@ -2128,6 +2159,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) OM_uint32 ret; u_int len; @@ -1828,7 +1834,7 @@ index 229fada..aa70945 100644 gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2154,7 +2187,11 @@ mm_answer_gss_userok(int sock, Buffer *m) +@@ -2154,7 +2188,11 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1841,7 +1847,7 @@ index 229fada..aa70945 100644 buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2167,5 +2204,73 @@ mm_answer_gss_userok(int sock, Buffer *m) +@@ -2167,5 +2205,73 @@ mm_answer_gss_userok(int sock, Buffer *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index d2d07b6..f7c5a1c 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,14 +1,16 @@ -diff -up openssh-6.6p1/auth-krb5.c.kuserok openssh-6.6p1/auth-krb5.c ---- openssh-6.6p1/auth-krb5.c.kuserok 2013-10-24 01:53:02.000000000 +0200 -+++ openssh-6.6p1/auth-krb5.c 2014-05-07 10:42:00.883534478 +0200 -@@ -54,6 +54,20 @@ +diff --git a/auth-krb5.c b/auth-krb5.c +index 6c62bdf..11c8562 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -54,6 +54,21 @@ extern ServerOptions options; +int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) ++ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client, ++ int k5login_exists) +{ -+ if (options.use_kuserok) ++ if (options.use_kuserok || !k5login_exists) + return krb5_kuserok(krb5_ctx, krb5_user, client); + else { + char kuser[65]; @@ -22,40 +24,161 @@ diff -up openssh-6.6p1/auth-krb5.c.kuserok openssh-6.6p1/auth-krb5.c static int krb5_init(void *context) { -@@ -157,8 +171,7 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -157,8 +172,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->pw->pw_name)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name)) { ++ /* Use !options.use_kuserok here to make ssh_krb5_kuserok() not ++ * depend on the existance of .k5login */ ++ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) { problem = -1; goto out; } -diff -up openssh-6.6p1/gss-serv-krb5.c.kuserok openssh-6.6p1/gss-serv-krb5.c ---- openssh-6.6p1/gss-serv-krb5.c.kuserok 2014-05-07 10:35:30.792053846 +0200 -+++ openssh-6.6p1/gss-serv-krb5.c 2014-05-07 10:35:30.801053812 +0200 -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 60de320..0a4930e 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, int); static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); ++extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int); /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -116,7 +117,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client +@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) + * Returns true if the user is OK to log in, otherwise returns 0 + */ + ++/* The purpose of the function is to find out if a Kerberos principal is ++ * allowed to log in as the given local user. This is a general problem with ++ * Kerberized services because by design the Kerberos principals are ++ * completely independent from the local user names. This is one of the ++ * reasons why Kerberos is working well on different operating systems like ++ * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos ++ * principal and a local user name must be established because otherwise every ++ * access would be granted for every principal with a valid ticket. ++ * ++ * Since it is a general issue libkrb5 provides some functions for ++ * applications to find out about the relationship between the Kerberos ++ * principal and a local user name. They are krb5_kuserok() and ++ * krb5_aname_to_localname(). ++ * ++ * krb5_kuserok() can be used to "Determine if a principal is authorized to ++ * log in as a local user" (from the MIT Kerberos documentation of this ++ * function). Which is exactly what we are looking for and should be the ++ * preferred choice. It accepts the Kerberos principal and a local user name ++ * and let libkrb5 or its plugins determine if they relate to each other or ++ * not. ++ * ++ * krb5_aname_to_localname() can use used to "Convert a principal name to a ++ * local name" (from the MIT Kerberos documentation of this function). It ++ * accepts a Kerberos principle and returns a local name and it is up to the ++ * application to do any additional checks. There are two issues using ++ * krb5_aname_to_localname(). First, since POSIX user names are case ++ * sensitive, the calling application in general has no other choice than ++ * doing a case-sensitive string comparison between the name returned by ++ * krb5_aname_to_localname() and the name used at the login prompt. When the ++ * users are provided by a case in-sensitive server, e.g. Active Directory, ++ * this might lead to login failures because the user typing the name at the ++ * login prompt might not be aware of the right case. Another issue might be ++ * caused if there are multiple alias names available for a single user. E.g. ++ * the canonical name of a user is user@group.department.example.com but there ++ * exists a shorter login name, e.g. user@example.com, to safe typing at the ++ * login prompt. Here krb5_aname_to_localname() can only return the canonical ++ * name, but if the short alias is used at the login prompt authentication ++ * will fail as well. All this can be avoided by using krb5_kuserok() and ++ * configuring krb5.conf or using a suitable plugin to meet the needs of the ++ * given environment. ++ * ++ * The Fedora and RHEL version of openssh contain two patches which modify the ++ * access control behavior: ++ * - openssh-6.6p1-kuserok.patch ++ * - openssh-6.6p1-force_krb.patch ++ * ++ * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for ++ * sshd_config which controls if krb5_kuserok() is used to check if the ++ * principle is authorized or if krb5_aname_to_localname() should be used. ++ * The reason to add this patch was that krb5_kuserok() by default checks if ++ * a .k5login file exits in the users home-directory. With this the user can ++ * give access to his account for any given principal which might be ++ * in violation with company policies and it would be useful if this can be ++ * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does ++ * no only check .k5login but other sources as well and checking .k5login can ++ * be disabled for all applications in krb5.conf as well. With this new ++ * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7 ++ * and Fedora 21) openssh can only use krb5_aname_to_localname() with the ++ * restrictions mentioned above. ++ * ++ * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when ++ * using GSSAPI authentication only commands configured in the .k5user can be ++ * executed. Here the wrong assumption that krb5_kuserok() only checks ++ * .k5login is made as well. In contrast ksu checks .k5login directly and ++ * does not use krb5_kuserok() which might be more useful for the given ++ * purpose. Additionally this patch is not synced with ++ * openssh-6.6p1-kuserok.patch. ++ * ++ * The current patch tries to restore the usage of krb5_kuserok() so that e.g. ++ * localauth plugins can be used. It does so by adding a forth parameter to ++ * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it ++ * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set ++ * to 'no' because the intent of the option is to not check .k5login and if it ++ * does not exists krb5_kuserok() returns a result without checking .k5login. ++ * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to ++ * krb5_aname_to_localname(). This is in my point of view an acceptable ++ * limitation and does not break the current behaviour. ++ * ++ * Additionally with this patch ssh_krb5_kuserok() is called in ++ * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is ++ * neither .k5login nor .k5users exists to allow plugin evaluation via ++ * krb5_kuserok() as well. ++ * ++ * I tried to keep the patch as minimal as possible, nevertheless I see some ++ * areas for improvement which, if they make sense, have to be evaluated ++ * carefully because they might change existing behaviour and cause breaks ++ * during upgrade: ++ * - I wonder if disabling .k5login usage make sense in sshd or if it should ++ * be better disabled globally in krb5.conf ++ * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really ++ * only disable checking .k5login and maybe .k5users ++ * - the ksu behaviour should be configurable and maybe check the .k5login and ++ * .k5users files directly like ksu itself does ++ * - to make krb5_aname_to_localname() more useful an option for sshd to use ++ * the canonical name (the one returned by getpwnam()) instead of the name ++ * given at the login prompt might be useful */ ++ + static int + ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + { +@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) /* NOTE: .k5login and .k5users must opened as root, not the user, * because if they are on a krb5-protected filesystem, user credentials * to access these files aren't available yet. */ - if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { -+ if (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); -diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c ---- openssh-6.6p1/servconf.c.kuserok 2014-05-07 10:35:30.783053881 +0200 -+++ openssh-6.6p1/servconf.c 2014-05-07 10:39:13.133189061 +0200 -@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions +@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, + snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); + /* If both .k5login and .k5users DNE, self-login is ok. */ + if (!k5login_exists && (access(file, F_OK) == -1)) { +- return (krb5_aname_to_localname(krb_context, principal, +- sizeof(kuser), kuser) == 0) && +- (strcmp(kuser, luser) == 0); ++ return ssh_krb5_kuserok(krb_context, principal, luser, ++ k5login_exists); + } + if ((fp = fopen(file, "r")) == NULL) { + int saved_errno = errno; +diff --git a/servconf.c b/servconf.c +index 68fb9ef..904c869 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; @@ -63,12 +186,12 @@ diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c } void -@@ -312,6 +313,8 @@ fill_default_server_options(ServerOption +@@ -312,6 +313,8 @@ fill_default_server_options(ServerOptions *options) options->version_addendum = xstrdup(""); if (options->show_patchlevel == -1) options->show_patchlevel = 0; + if (options->use_kuserok == -1) -+ options->use_kuserok = 0; ++ options->use_kuserok = 1; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -95,7 +218,7 @@ diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions +@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions *options, char *line, *activep = value; break; @@ -106,7 +229,7 @@ diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *d +@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -122,9 +245,10 @@ diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.6p1/servconf.h.kuserok openssh-6.6p1/servconf.h ---- openssh-6.6p1/servconf.h.kuserok 2014-05-07 10:35:30.783053881 +0200 -+++ openssh-6.6p1/servconf.h 2014-05-07 10:35:30.802053808 +0200 +diff --git a/servconf.h b/servconf.h +index 37cfa9b..5117dfa 100644 +--- a/servconf.h ++++ b/servconf.h @@ -173,6 +173,7 @@ typedef struct { int num_permitted_opens; @@ -133,17 +257,30 @@ diff -up openssh-6.6p1/servconf.h.kuserok openssh-6.6p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-6.6p1/sshd_config.5.kuserok openssh-6.6p1/sshd_config.5 ---- openssh-6.6p1/sshd_config.5.kuserok 2014-05-07 10:35:30.786053870 +0200 -+++ openssh-6.6p1/sshd_config.5 2014-05-07 10:43:04.784285016 +0200 -@@ -697,6 +697,10 @@ Specifies whether to automatically destr +diff --git a/sshd_config b/sshd_config +index adfd7b1..e772ed5 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + GSSAPIAuthentication yes +diff --git a/sshd_config.5 b/sshd_config.5 +index 1fb002d..e0e5fff 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -697,6 +697,10 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Dq yes . +.It Cm KerberosUseKuserok +Specifies whether to look at .k5login file for user's aliases. +The default is -+.Dq no . ++.Dq yes . .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. @@ -155,14 +292,3 @@ diff -up openssh-6.6p1/sshd_config.5.kuserok openssh-6.6p1/sshd_config.5 .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , -diff -up openssh-6.6p1/sshd_config.kuserok openssh-6.6p1/sshd_config ---- openssh-6.6p1/sshd_config.kuserok 2014-05-07 10:35:30.803053804 +0200 -+++ openssh-6.6p1/sshd_config 2014-05-07 10:38:30.735354431 +0200 -@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok no - - # GSSAPI options - GSSAPIAuthentication yes From 300c081db250616e0dd2727e361d5df578f77ac4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 15 Jan 2015 21:56:09 +0100 Subject: [PATCH 008/146] Based on openssh-6.6.1p1-11.1.fc21 --- gsi-openssh.spec | 31 +- gsisshd.service | 2 + gsisshd.socket | 1 + gsisshd@.service | 1 + openssh-5.8p1-localdomain.patch | 14 - openssh-6.6.1p1-audit-pfs.patch | 212 +++++++++++++ openssh-6.6.1p1-cisco-dh-keys.patch | 70 +++++ openssh-6.6.1p1-ip-port-config-parser.patch | 24 ++ openssh-6.6.1p1-localdomain.patch | 12 + openssh-6.6.1p1-log-in-chroot.patch | 295 ++++++++++++++++++ ...h-6.6.1p1-scp-non-existing-directory.patch | 14 + openssh-6.6p1-GSSAPIEnablek5users.patch | 137 ++++++++ openssh-6.6p1-audit.patch | 2 +- openssh-6.6p1-fips.patch | 23 +- openssh-6.6p1-gsissh.patch | 245 +++++++-------- openssh-6.6p1-ldap.patch | 4 +- openssh-6.6p1-redhat.patch | 11 +- 17 files changed, 936 insertions(+), 162 deletions(-) delete mode 100644 openssh-5.8p1-localdomain.patch create mode 100644 openssh-6.6.1p1-audit-pfs.patch create mode 100644 openssh-6.6.1p1-cisco-dh-keys.patch create mode 100644 openssh-6.6.1p1-ip-port-config-parser.patch create mode 100644 openssh-6.6.1p1-localdomain.patch create mode 100644 openssh-6.6.1p1-log-in-chroot.patch create mode 100644 openssh-6.6.1p1-scp-non-existing-directory.patch create mode 100644 openssh-6.6p1-GSSAPIEnablek5users.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 3a5bae1..a3bf8b6 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ %global ldap 1 %global openssh_ver 6.6.1p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -61,6 +61,9 @@ Patch103: openssh-5.8p1-packet.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 Patch200: openssh-6.6p1-audit.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 +# record pfs= field in CRYPTO_SESSION audit event +Patch201: openssh-6.6.1p1-audit-pfs.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-6.6p1-role-mls.patch @@ -100,7 +103,7 @@ Patch703: openssh-4.3p2-askpass-grab-info.patch #? Patch705: openssh-5.1p1-scp-manpage.patch #? -Patch706: openssh-5.8p1-localdomain.patch +Patch706: openssh-6.6.1p1-localdomain.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) Patch707: openssh-6.6p1-redhat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :) @@ -119,6 +122,9 @@ Patch713: openssh-6.6p1-ctr-cavstest.patch Patch800: openssh-6.6p1-gsskex.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 Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 Patch901: openssh-6.6p1-kuserok.patch @@ -156,6 +162,14 @@ Patch914: openssh-6.6.1p1-servconf-parser.patch Patch915: openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch # privsep_preauth: use SELinux context from selinux-policy (#1008580) Patch916: openssh-6.6.1p1-selinux-contexts.patch +# use different values for DH for Cisco servers (#1026430) +Patch917: openssh-6.6.1p1-cisco-dh-keys.patch +# log via monitor in chroots without /dev/log +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 +# Config parser shouldn't accept ip/port syntax (#1130733) +Patch920: openssh-6.6.1p1-ip-port-config-parser.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch @@ -311,8 +325,14 @@ This version of OpenSSH has been modified to support GSI authentication. %patch914 -p1 -b .servconf %patch915 -p1 -b .SIGXFSZ %patch916 -p1 -b .contexts +%patch917 -p1 -b .cisco-dh +%patch918 -p1 -b .log-in-chroot +%patch919 -p1 -b .scp +%patch920 -p1 -b .config +%patch802 -p1 -b .GSSAPIEnablek5users %patch200 -p1 -b .audit +%patch201 -p1 -b .audit-fps %patch700 -p1 -b .fips %patch100 -p1 -b .coverity @@ -364,7 +384,7 @@ fi --with-default-path=/usr/local/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/gsisshd \ - --enable-vendor-patchlevel="FC-%{version}-%{release}" \ + --enable-vendor-patchlevel="FC-%{openssh_ver}-%{openssh_rel}" \ --disable-strip \ --without-zlib-version-check \ --with-ssl-engine \ @@ -473,7 +493,7 @@ getent passwd sshd >/dev/null || \ %systemd_preun gsisshd.service gsisshd.socket %postun server -%systemd_postun_with_restart gsisshd.service gsisshd.socket +%systemd_postun_with_restart gsisshd.service %triggerun server -- gsi-openssh-server < 5.8p2-1 /usr/bin/systemd-sysv-convert --save gsisshd >/dev/null 2>&1 || : @@ -531,6 +551,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog +* Thu Jan 15 2015 Mattias Ellert - 6.6.1p1-4 +- Based on openssh-6.6.1p1-11.1.fc21 + * Mon Nov 24 2014 Mattias Ellert - 6.6.1p1-3 - Based on openssh-6.6.1p1-8.fc21 diff --git a/gsisshd.service b/gsisshd.service index 634f7a9..8f18090 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -1,6 +1,8 @@ [Unit] Description=gsissh server daemon +Documentation=man:gsisshd(8) man:gsisshd_config(5) After=network.target gsisshd-keygen.service +Wants=gsisshd-keygen.service [Service] EnvironmentFile=/etc/sysconfig/gsisshd diff --git a/gsisshd.socket b/gsisshd.socket index eb295f5..28e40d1 100644 --- a/gsisshd.socket +++ b/gsisshd.socket @@ -1,5 +1,6 @@ [Unit] Description=gsissh Server Socket +Documentation=man:gsisshd(8) man:gsisshd_config(5) Conflicts=gsisshd.service [Socket] diff --git a/gsisshd@.service b/gsisshd@.service index a4b88ba..2f59be2 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -1,5 +1,6 @@ [Unit] Description=gsissh per-connection server daemon +Documentation=man:gsisshd(8) man:gsisshd_config(5) Wants=gsisshd-keygen.service After=gsisshd-keygen.service diff --git a/openssh-5.8p1-localdomain.patch b/openssh-5.8p1-localdomain.patch deleted file mode 100644 index 2f21658..0000000 --- a/openssh-5.8p1-localdomain.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up openssh-5.8p1/sshd_config.localdomain openssh-5.8p1/sshd_config ---- openssh-5.8p1/sshd_config.localdomain 2011-04-22 11:37:49.273648812 +0200 -+++ openssh-5.8p1/sshd_config 2011-04-22 11:39:31.758648401 +0200 -@@ -130,6 +130,10 @@ X11Forwarding yes - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - -+# Uncomment this if you want to use .local domain -+#Host *.local -+# CheckHostIP no -+ - # Example of overriding settings on a per-user basis - #Match User anoncvs - # X11Forwarding no diff --git a/openssh-6.6.1p1-audit-pfs.patch b/openssh-6.6.1p1-audit-pfs.patch new file mode 100644 index 0000000..a2b6d75 --- /dev/null +++ b/openssh-6.6.1p1-audit-pfs.patch @@ -0,0 +1,212 @@ +diff --git a/audit-bsm.c b/audit-bsm.c +index 5160869..c7a1b47 100644 +--- a/audit-bsm.c ++++ b/audit-bsm.c +@@ -481,7 +481,7 @@ audit_unsupported_body(int what) + } + + void +-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid) ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) + { + /* not implemented */ + } +diff --git a/audit-linux.c b/audit-linux.c +index 6954fc1..6686f6a 100644 +--- a/audit-linux.c ++++ b/audit-linux.c +@@ -297,7 +297,7 @@ audit_unsupported_body(int what) + const static char *direction[] = { "from-server", "from-client", "both" }; + + void +-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, + uid_t uid) + { + #ifdef AUDIT_CRYPTO_SESSION +@@ -306,8 +306,8 @@ audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, + Cipher *cipher = cipher_by_name(enc); + char *s; + +- snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", +- direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, ++ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, + (intmax_t)pid, (intmax_t)uid, + get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); + free(s); +diff --git a/audit.c b/audit.c +index 13c6849..5b49434 100644 +--- a/audit.c ++++ b/audit.c +@@ -135,9 +135,9 @@ audit_unsupported(int what) + } + + void +-audit_kex(int ctos, char *enc, char *mac, char *comp) ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) + { +- PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); ++ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); + } + + void +@@ -270,11 +270,11 @@ audit_unsupported_body(int what) + * This will be called on succesfull protocol negotiation. + */ + void +-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, + uid_t uid) + { +- debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u", +- (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, + (unsigned)uid); + } + +diff --git a/audit.h b/audit.h +index a2dc3ff..903df66 100644 +--- a/audit.h ++++ b/audit.h +@@ -61,9 +61,9 @@ ssh_audit_event_t audit_classify_auth(const char *); + int audit_keyusage(int, const char *, unsigned, char *, int); + void audit_key(int, int *, const Key *); + void audit_unsupported(int); +-void audit_kex(int, char *, char *, char *); ++void audit_kex(int, char *, char *, char *, char *); + void audit_unsupported_body(int); +-void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); + void audit_session_key_free(int ctos); + void audit_session_key_free_body(int ctos, pid_t, uid_t); + void audit_destroy_sensitive_data(const char *, pid_t, uid_t); +diff --git a/auditstub.c b/auditstub.c +index 45817e0..116f460 100644 +--- a/auditstub.c ++++ b/auditstub.c +@@ -35,7 +35,7 @@ audit_unsupported(int n) + } + + void +-audit_kex(int ctos, char *enc, char *mac, char *comp) ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) + { + } + +diff --git a/kex.c b/kex.c +index ede7b67..eb5f333 100644 +--- a/kex.c ++++ b/kex.c +@@ -553,13 +553,12 @@ kex_choose_conf(Kex *kex) + newkeys->enc.name, + authlen == 0 ? newkeys->mac.name : "", + newkeys->comp.name); +-#ifdef SSH_AUDIT_EVENTS +- audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); +-#endif + } ++ + choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); ++ + need = dh_need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + newkeys = kex->newkeys[mode]; +@@ -571,11 +570,16 @@ kex_choose_conf(Kex *kex) + dh_need = MAX(dh_need, newkeys->enc.block_size); + dh_need = MAX(dh_need, newkeys->enc.iv_len); + dh_need = MAX(dh_need, newkeys->mac.key_len); ++ debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); ++#ifdef SSH_AUDIT_EVENTS ++ audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); ++#endif + } + /* XXX need runden? */ + kex->we_need = need; + kex->dh_need = dh_need; + ++ + /* ignore the next message if the proposals do not match */ + if (first_kex_follows && !proposals_match(my, peer) && + !(datafellows & SSH_BUG_FIRSTKEX)) { +diff --git a/monitor.c b/monitor.c +index 70b9b4c..81bc9c1 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -2396,7 +2396,7 @@ int + mm_answer_audit_kex_body(int sock, Buffer *m) + { + int ctos, len; +- char *cipher, *mac, *compress; ++ char *cipher, *mac, *compress, *pfs; + pid_t pid; + uid_t uid; + +@@ -2404,14 +2404,16 @@ mm_answer_audit_kex_body(int sock, Buffer *m) + cipher = buffer_get_string(m, &len); + mac = buffer_get_string(m, &len); + compress = buffer_get_string(m, &len); ++ pfs = buffer_get_string(m, &len); + pid = buffer_get_int64(m); + uid = buffer_get_int64(m); + +- audit_kex_body(ctos, cipher, mac, compress, pid, uid); ++ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); + + free(cipher); + free(mac); + free(compress); ++ free(pfs); + buffer_clear(m); + + mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 93f6535..69b29d8 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -1408,7 +1408,7 @@ mm_audit_unsupported_body(int what) + } + + void +-mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, ++mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, + uid_t uid) + { + Buffer m; +@@ -1418,6 +1418,7 @@ mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, + buffer_put_cstring(&m, cipher); + buffer_put_cstring(&m, (mac ? mac : "")); + buffer_put_cstring(&m, compress); ++ buffer_put_cstring(&m, fps); + buffer_put_int64(&m, pid); + buffer_put_int64(&m, uid); + +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 4cf0c78..e43109f 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -83,7 +83,7 @@ void mm_audit_event(ssh_audit_event_t); + int mm_audit_run_command(const char *); + void mm_audit_end_command(int, const char *); + void mm_audit_unsupported_body(int); +-void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); + void mm_audit_session_key_free_body(int, pid_t, uid_t); + void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); + #endif +diff --git a/sshd.c b/sshd.c +index ee94825..41a94a7 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2430,7 +2430,7 @@ do_ssh1_kex(void) + packet_disconnect("IP Spoofing check bytes do not match."); + + #ifdef SSH_AUDIT_EVENTS +- audit_kex(2, cipher_name(cipher_type), "crc", "none"); ++ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); + #endif + + debug("Encryption type: %.200s", cipher_name(cipher_type)); diff --git a/openssh-6.6.1p1-cisco-dh-keys.patch b/openssh-6.6.1p1-cisco-dh-keys.patch new file mode 100644 index 0000000..0763b10 --- /dev/null +++ b/openssh-6.6.1p1-cisco-dh-keys.patch @@ -0,0 +1,70 @@ +diff --git a/compat.c b/compat.c +index 2709dc5..7412a54 100644 +--- a/compat.c ++++ b/compat.c +@@ -167,6 +167,7 @@ compat_datafellows(const char *version) + SSH_BUG_SCANNER }, + { "Probe-*", + SSH_BUG_PROBE }, ++ { "Cisco-*", SSH_BUG_MAX4096DH }, + { NULL, 0 } + }; + +diff --git a/compat.h b/compat.h +index a6c3f3d..d8def7d 100644 +--- a/compat.h ++++ b/compat.h +@@ -60,6 +60,7 @@ + #define SSH_NEW_OPENSSH 0x04000000 + #define SSH_BUG_DYNAMIC_RPORT 0x08000000 + #define SSH_BUG_CURVE25519PAD 0x10000000 ++#define SSH_BUG_MAX4096DH 0x20000000 + + void enable_compat13(void); + void enable_compat20(void); +diff --git a/kexgexc.c b/kexgexc.c +index 355b7ba..0a91bdd 100644 +--- a/kexgexc.c ++++ b/kexgexc.c +@@ -58,20 +58,37 @@ kexgex_client(Kex *kex) + int min, max, nbits; + DH *dh; + ++ min = DH_GRP_MIN; ++ max = DH_GRP_MAX; ++ ++ /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. ++ * We need to also ensure that min < nbits < max */ ++ ++ if (datafellows & SSH_BUG_MAX4096DH) { ++ /* The largest min for these servers is 4096 */ ++ min = MIN(min, 4096); ++ } ++ + nbits = dh_estimate(kex->dh_need * 8); ++ nbits = MIN(nbits, max); ++ nbits = MAX(nbits, min); ++ ++ if (datafellows & SSH_BUG_MAX4096DH) { ++ /* Cannot have a nbits > 4096 for these servers */ ++ nbits = MIN(nbits, 4096); ++ /* nbits has to be powers of two */ ++ if (nbits == 3072) ++ nbits = 4096; ++ } + + if (datafellows & SSH_OLD_DHGEX) { + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); +- min = DH_GRP_MIN; +- max = DH_GRP_MAX; + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); + } else { + /* New GEX request */ +- min = DH_GRP_MIN; +- max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); + packet_put_int(nbits); diff --git a/openssh-6.6.1p1-ip-port-config-parser.patch b/openssh-6.6.1p1-ip-port-config-parser.patch new file mode 100644 index 0000000..d2746bf --- /dev/null +++ b/openssh-6.6.1p1-ip-port-config-parser.patch @@ -0,0 +1,24 @@ +diff --git a/misc.c b/misc.c +index 2f11de4..36402d1 100644 +--- a/misc.c ++++ b/misc.c +@@ -396,7 +396,7 @@ hpdelim(char **cp) + return NULL; + else + s++; +- } else if ((s = strpbrk(s, ":/")) == NULL) ++ } else if ((s = strpbrk(s, ":")) == NULL) + s = *cp + strlen(*cp); /* skip to end (see first case below) */ + + switch (*s) { +@@ -405,7 +405,6 @@ hpdelim(char **cp) + break; + + case ':': +- case '/': + *s = '\0'; /* terminate */ + *cp = s + 1; + break; +-- +2.1.0 + diff --git a/openssh-6.6.1p1-localdomain.patch b/openssh-6.6.1p1-localdomain.patch new file mode 100644 index 0000000..4995171 --- /dev/null +++ b/openssh-6.6.1p1-localdomain.patch @@ -0,0 +1,12 @@ +diff --git a/ssh_config b/ssh_config +index 03a228f..49a4f6c 100644 +--- a/ssh_config ++++ b/ssh_config +@@ -46,3 +46,7 @@ + # VisualHostKey no + # ProxyCommand ssh -q -W %h:%p gateway.example.com + # RekeyLimit 1G 1h ++# ++# Uncomment this if you want to use .local domain ++# Host *.local ++# CheckHostIP no diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch new file mode 100644 index 0000000..bccf39b --- /dev/null +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -0,0 +1,295 @@ +diff --git a/log.c b/log.c +index 32e1d2e..d4caeb5 100644 +--- a/log.c ++++ b/log.c +@@ -241,6 +241,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 +@@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) + 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 ae7df25..30c3310 100644 +--- a/log.h ++++ b/log.h +@@ -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); + void log_change_level(LogLevel); + int log_is_on_stderr(void); + void log_redirect_stderr_to(const char *); +diff --git a/monitor.c b/monitor.c +index 7461fae..da2f766 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -364,6 +364,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) + close(pmonitor->m_log_sendfd); + pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "preauth"; ++ + authctxt = _authctxt; + memset(authctxt, 0, sizeof(*authctxt)); + +@@ -472,6 +474,8 @@ monitor_child_postauth(struct monitor *pmonitor) + close(pmonitor->m_recvfd); + pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "postauth"; ++ + monitor_set_child_handler(pmonitor->m_pid); + signal(SIGHUP, &monitor_child_handler); + signal(SIGTERM, &monitor_child_handler); +@@ -552,7 +556,7 @@ monitor_read_log(struct monitor *pmonitor) + 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); + + buffer_free(&logmsg); + free(msg); +@@ -2083,13 +2087,28 @@ monitor_init(void) + mm_init_compression(mon->m_zlib); + } + ++ 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 --git a/monitor.h b/monitor.h +index ff79fbb..00c2028 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -83,10 +83,11 @@ struct monitor { + struct mm_master *m_zlib; + 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 *); + void monitor_sync(struct monitor *); + + struct Authctxt; +diff --git a/session.c b/session.c +index e4add93..bc4a8dd 100644 +--- a/session.c ++++ b/session.c +@@ -160,6 +160,8 @@ login_cap_t *lc; + + static int is_child = 0; + ++static int have_dev_log = 1; ++ + /* Name and directory of socket for authentication agent forwarding. */ + static char *auth_sock_name = NULL; + static char *auth_sock_dir = NULL; +@@ -523,8 +525,8 @@ do_exec_no_pty(Session *s, const char *command) + is_child = 1; + + /* Child. Reinitialize the log since the pid has changed. */ +- log_init(__progname, options.log_level, +- options.log_facility, log_stderr); ++ log_init_handler(__progname, options.log_level, ++ options.log_facility, log_stderr, have_dev_log); + + /* + * Create a new session and process group since the 4.4BSD +@@ -692,8 +694,8 @@ do_exec_pty(Session *s, const char *command) + close(ptymaster); + + /* Child. Reinitialize the log because the pid has changed. */ +- log_init(__progname, options.log_level, +- options.log_facility, log_stderr); ++ log_init_handler(__progname, options.log_level, ++ options.log_facility, log_stderr, have_dev_log); + /* Close the master side of the pseudo tty. */ + close(ptyfd); + +@@ -797,6 +799,7 @@ do_exec(Session *s, const char *command) + int ret; + const char *forced = NULL; + char session_type[1024], *tty = NULL; ++ struct stat dev_log_stat; + + if (options.adm_forced_command) { + original_command = command; +@@ -854,6 +857,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", + session_type, + tty == NULL ? "" : " on ", +@@ -1681,14 +1688,6 @@ child_close_fds(void) + * descriptors left by system functions. They will be closed later. + */ + endpwent(); +- +- /* +- * 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); + } + + /* +@@ -1834,8 +1833,6 @@ do_child(Session *s, const char *command) + exit(1); + } + +- closefrom(STDERR_FILENO + 1); +- + if (!options.use_login) + do_rc_files(s, shell); + +@@ -1859,9 +1856,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); + + if (options.use_login) { +diff --git a/sftp-server-main.c b/sftp-server-main.c +index 7e644ab..e162b7a 100644 +--- a/sftp-server-main.c ++++ b/sftp-server-main.c +@@ -47,5 +47,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 b8eb59c..a0e644c 100644 +--- a/sftp-server.c ++++ b/sftp-server.c +@@ -1437,7 +1437,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, in, out, max, ch, skipargs = 0, log_stderr = 0; +@@ -1450,7 +1450,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); + +@@ -1521,7 +1521,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); + + if ((cp = getenv("SSH_CONNECTION")) != NULL) { + client_addr = xstrdup(cp); +diff --git a/sftp.h b/sftp.h +index 2bde8bb..ddf1a39 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.c b/sshd.c +index 3eee75a..9c00bcb 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -745,7 +745,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) +@@ -763,6 +763,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(); diff --git a/openssh-6.6.1p1-scp-non-existing-directory.patch b/openssh-6.6.1p1-scp-non-existing-directory.patch new file mode 100644 index 0000000..5412bc5 --- /dev/null +++ b/openssh-6.6.1p1-scp-non-existing-directory.patch @@ -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)) < 0) { +-- diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch new file mode 100644 index 0000000..a60d608 --- /dev/null +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -0,0 +1,137 @@ +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 0a4930e..a7c0c5f 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, + FILE *fp; + char file[MAXPATHLEN]; + char line[BUFSIZ]; +- char kuser[65]; /* match krb5_kuserok() */ + struct stat st; + struct passwd *pw = the_authctxt->pw; + int found_principal = 0; +@@ -269,7 +268,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, + + snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); + /* If both .k5login and .k5users DNE, self-login is ok. */ +- if (!k5login_exists && (access(file, F_OK) == -1)) { ++ if ( !options.enable_k5users || (!k5login_exists && (access(file, F_OK) == -1))) { + return ssh_krb5_kuserok(krb_context, principal, luser, + k5login_exists); + } +diff --git a/servconf.c b/servconf.c +index d482e79..ad5869b 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -158,6 +158,7 @@ initialize_server_options(ServerOptions *options) + options->ip_qos_bulk = -1; + options->version_addendum = NULL; + options->use_kuserok = -1; ++ options->enable_k5users = -1; + } + + void +@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) + options->show_patchlevel = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; ++ if (options->enable_k5users == -1) ++ options->enable_k5users = 0; + + /* Turn privilege separation on by default */ + if (use_privsep == -1) +@@ -356,7 +359,7 @@ typedef enum { + sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, + sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, + sClientAliveCountMax, sAuthorizedKeysFile, +- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, ++ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, + sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, sAllowAgentForwarding, +@@ -430,6 +433,7 @@ static struct { + { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, ++ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, + #else + { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, +@@ -437,6 +441,7 @@ static struct { + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, + #endif + { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, +@@ -1536,6 +1541,10 @@ process_server_config_line(ServerOptions *options, char *line, + intptr = &options->use_kuserok; + goto parse_flag; + ++ case sGssEnablek5users: ++ intptr = &options->enable_k5users; ++ goto parse_flag; ++ + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') +@@ -1824,6 +1833,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + M_CP_INTOPT(ip_qos_interactive); + M_CP_INTOPT(ip_qos_bulk); + M_CP_INTOPT(use_kuserok); ++ M_CP_INTOPT(enable_k5users); + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); + +@@ -2076,6 +2086,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); ++ dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff --git a/servconf.h b/servconf.h +index 5117dfa..d63cb71 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -173,7 +173,8 @@ typedef struct { + + int num_permitted_opens; + +- int use_kuserok; ++ int use_kuserok; ++ int enable_k5users; + char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; +diff --git a/sshd_config b/sshd_config +index 43671f6..6ab00ed 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -94,6 +94,7 @@ GSSAPIAuthentication yes + GSSAPICleanupCredentials no + #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 e0e5fff..aa9525d 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -505,6 +505,12 @@ on logout. + The default is + .Dq yes . + Note that this option applies to protocol version 2 only. ++.It Cm GSSAPIEnablek5users ++Specifies whether to look at .k5users file for GSSAPI authentication ++access control. Further details are described in ++.Xr ksu 1 . ++The default is ++.Dq no . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. If diff --git a/openssh-6.6p1-audit.patch b/openssh-6.6p1-audit.patch index 7e0c0f4..2ee2012 100644 --- a/openssh-6.6p1-audit.patch +++ b/openssh-6.6p1-audit.patch @@ -111,7 +111,7 @@ index b3ee2f4..946f7fa 100644 +#include "packet.h" +#include "cipher.h" -+#define AUDIT_LOG_SIZE 128 ++#define AUDIT_LOG_SIZE 256 + +extern ServerOptions options; +extern Authctxt *the_authctxt; diff --git a/openssh-6.6p1-fips.patch b/openssh-6.6p1-fips.patch index 9227b37..f97e2ba 100644 --- a/openssh-6.6p1-fips.patch +++ b/openssh-6.6p1-fips.patch @@ -325,22 +325,15 @@ index 355b7ba..427e11f 100644 #include #include -@@ -64,13 +66,13 @@ kexgex_client(Kex *kex) - /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); -- min = DH_GRP_MIN; -+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - max = DH_GRP_MAX; +@@ -58,7 +60,7 @@ kexgex_client(Kex *kex) + int min, max, nbits; + DH *dh; - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); - } else { - /* New GEX request */ -- min = DH_GRP_MIN; -+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); +- min = DH_GRP_MIN; ++ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + max = DH_GRP_MAX; + + /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. diff --git a/kexgexs.c b/kexgexs.c index 770ad28..9d4fc6d 100644 --- a/kexgexs.c diff --git a/openssh-6.6p1-gsissh.patch b/openssh-6.6p1-gsissh.patch index 9402ed5..5bf7cc9 100644 --- a/openssh-6.6p1-gsissh.patch +++ b/openssh-6.6p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c ---- openssh-6.6p1.orig/auth2.c 2014-07-14 19:49:55.195268838 +0200 -+++ openssh-6.6p1/auth2.c 2014-07-15 20:41:18.569116584 +0200 +--- openssh-6.6p1.orig/auth2.c 2015-01-15 20:08:13.117214971 +0100 ++++ openssh-6.6p1/auth2.c 2015-01-15 20:08:56.673616238 +0100 @@ -49,6 +49,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -121,8 +121,8 @@ diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c ---- openssh-6.6p1.orig/auth2-gss.c 2014-07-14 19:49:55.132268150 +0200 -+++ openssh-6.6p1/auth2-gss.c 2014-07-15 06:05:00.934252969 +0200 +--- openssh-6.6p1.orig/auth2-gss.c 2015-01-15 20:08:13.020214078 +0100 ++++ openssh-6.6p1/auth2-gss.c 2015-01-15 20:08:56.674616247 +0100 @@ -47,6 +47,7 @@ extern ServerOptions options; @@ -304,8 +304,8 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c ---- openssh-6.6p1.orig/auth.c 2014-07-14 19:49:55.035267091 +0200 -+++ openssh-6.6p1/auth.c 2014-07-15 08:14:47.720558265 +0200 +--- openssh-6.6p1.orig/auth.c 2015-01-15 20:08:13.116214962 +0100 ++++ openssh-6.6p1/auth.c 2015-01-15 20:08:56.675616256 +0100 @@ -74,6 +74,9 @@ #include "krl.h" #include "compat.h" @@ -372,8 +372,8 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c ---- openssh-6.6p1.orig/auth-pam.c 2014-07-14 19:49:55.047267222 +0200 -+++ openssh-6.6p1/auth-pam.c 2014-07-15 06:05:00.935252978 +0200 +--- openssh-6.6p1.orig/auth-pam.c 2015-01-15 20:08:13.146215238 +0100 ++++ openssh-6.6p1/auth-pam.c 2015-01-15 20:08:56.676616265 +0100 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -385,7 +385,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c typedef pid_t sp_pthread_t; #endif -@@ -272,6 +276,55 @@ +@@ -277,6 +281,55 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -441,7 +441,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -294,7 +347,7 @@ +@@ -299,7 +352,7 @@ static void import_environments(Buffer *b) { @@ -450,7 +450,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c u_int i, num_env; int err; -@@ -304,6 +357,17 @@ +@@ -309,6 +362,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -468,7 +468,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -470,6 +534,13 @@ +@@ -475,6 +539,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -482,7 +482,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -490,6 +561,11 @@ +@@ -495,6 +566,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -494,7 +494,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -907,6 +983,18 @@ +@@ -912,6 +988,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -513,7 +513,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1204,6 +1292,9 @@ +@@ -1209,6 +1297,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -524,8 +524,8 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", diff -Nur openssh-6.6p1.orig/auth-pam.h openssh-6.6p1/auth-pam.h ---- openssh-6.6p1.orig/auth-pam.h 2014-07-14 19:49:55.047267222 +0200 -+++ openssh-6.6p1/auth-pam.h 2014-07-15 06:05:00.935252978 +0200 +--- openssh-6.6p1.orig/auth-pam.h 2015-01-15 20:08:12.937213313 +0100 ++++ openssh-6.6p1/auth-pam.h 2015-01-15 20:08:56.677616275 +0100 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -534,8 +534,8 @@ diff -Nur openssh-6.6p1.orig/auth-pam.h openssh-6.6p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c ---- openssh-6.6p1.orig/canohost.c 2014-07-14 19:49:55.072267495 +0200 -+++ openssh-6.6p1/canohost.c 2014-07-15 06:05:00.935252978 +0200 +--- openssh-6.6p1.orig/canohost.c 2015-01-15 20:08:13.072214556 +0100 ++++ openssh-6.6p1/canohost.c 2015-01-15 20:08:56.678616284 +0100 @@ -16,6 +16,7 @@ #include @@ -544,7 +544,7 @@ diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c #include #include -@@ -446,3 +447,33 @@ +@@ -453,3 +454,33 @@ { return get_port(1); } @@ -579,9 +579,9 @@ diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c + } +} diff -Nur openssh-6.6p1.orig/canohost.h openssh-6.6p1/canohost.h ---- openssh-6.6p1.orig/canohost.h 2009-06-21 11:50:08.000000000 +0200 -+++ openssh-6.6p1/canohost.h 2014-07-15 06:05:00.936252986 +0200 -@@ -26,4 +26,6 @@ +--- openssh-6.6p1.orig/canohost.h 2015-01-15 20:08:13.073214566 +0100 ++++ openssh-6.6p1/canohost.h 2015-01-15 20:08:56.679616293 +0100 +@@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -589,8 +589,8 @@ diff -Nur openssh-6.6p1.orig/canohost.h openssh-6.6p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac ---- openssh-6.6p1.orig/configure.ac 2014-07-14 19:49:55.134268172 +0200 -+++ openssh-6.6p1/configure.ac 2014-07-15 06:05:00.936252986 +0200 +--- openssh-6.6p1.orig/configure.ac 2015-01-15 20:08:13.022214096 +0100 ++++ openssh-6.6p1/configure.ac 2015-01-15 20:08:56.681616311 +0100 @@ -4133,6 +4133,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -658,8 +658,8 @@ diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac PRIVSEP_PATH=/var/empty diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c ---- openssh-6.6p1.orig/gss-genr.c 2014-07-14 19:49:55.135268183 +0200 -+++ openssh-6.6p1/gss-genr.c 2014-07-15 06:05:00.937252996 +0200 +--- openssh-6.6p1.orig/gss-genr.c 2015-01-15 20:08:13.023214105 +0100 ++++ openssh-6.6p1/gss-genr.c 2015-01-15 20:08:56.681616311 +0100 @@ -38,6 +38,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -697,8 +697,8 @@ diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c return (ctx->major); } diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c ---- openssh-6.6p1.orig/gss-serv.c 2014-07-14 19:49:55.135268183 +0200 -+++ openssh-6.6p1/gss-serv.c 2014-07-15 22:29:11.603965267 +0200 +--- openssh-6.6p1.orig/gss-serv.c 2015-01-15 20:08:13.068214520 +0100 ++++ openssh-6.6p1/gss-serv.c 2015-01-15 20:08:56.682616321 +0100 @@ -48,14 +48,17 @@ #include "servconf.h" #include "uidswap.h" @@ -939,7 +939,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c #endif diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c --- openssh-6.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/gss-serv-gsi.c 2014-07-15 06:05:00.938253005 +0200 ++++ openssh-6.6p1/gss-serv-gsi.c 2015-01-15 20:08:56.682616321 +0100 @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1180,9 +1180,9 @@ diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c ---- openssh-6.6p1.orig/gss-serv-krb5.c 2014-07-14 19:49:55.158268433 +0200 -+++ openssh-6.6p1/gss-serv-krb5.c 2014-07-15 06:05:00.938253005 +0200 -@@ -263,6 +263,34 @@ +--- openssh-6.6p1.orig/gss-serv-krb5.c 2015-01-15 20:08:13.108214888 +0100 ++++ openssh-6.6p1/gss-serv-krb5.c 2015-01-15 20:08:56.683616330 +0100 +@@ -359,6 +359,34 @@ return found_principal; } @@ -1217,7 +1217,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -367,7 +395,7 @@ +@@ -463,7 +491,7 @@ return; } @@ -1226,7 +1226,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -438,7 +466,7 @@ +@@ -534,7 +562,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1236,8 +1236,8 @@ diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c ---- openssh-6.6p1.orig/kexgsss.c 2014-07-14 19:49:55.137268204 +0200 -+++ openssh-6.6p1/kexgsss.c 2014-07-15 06:05:00.938253005 +0200 +--- openssh-6.6p1.orig/kexgsss.c 2015-01-15 20:08:13.025214124 +0100 ++++ openssh-6.6p1/kexgsss.c 2015-01-15 20:08:56.683616330 +0100 @@ -44,6 +44,7 @@ #include "monitor_wrap.h" #include "servconf.h" @@ -1299,7 +1299,7 @@ diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c #endif /* GSSAPI */ diff -Nur openssh-6.6p1.orig/LICENSE.globus_usage openssh-6.6p1/LICENSE.globus_usage --- openssh-6.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/LICENSE.globus_usage 2014-07-15 06:05:00.939253015 +0200 ++++ openssh-6.6p1/LICENSE.globus_usage 2015-01-15 20:08:56.684616339 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1320,8 +1320,8 @@ diff -Nur openssh-6.6p1.orig/LICENSE.globus_usage openssh-6.6p1/LICENSE.globus_u + * limitations under the License. + */ diff -Nur openssh-6.6p1.orig/Makefile.in openssh-6.6p1/Makefile.in ---- openssh-6.6p1.orig/Makefile.in 2014-07-14 19:49:55.208268979 +0200 -+++ openssh-6.6p1/Makefile.in 2014-07-15 06:05:00.939253015 +0200 +--- openssh-6.6p1.orig/Makefile.in 2015-01-15 20:08:13.135215137 +0100 ++++ openssh-6.6p1/Makefile.in 2015-01-15 20:08:56.684616339 +0100 @@ -99,8 +99,10 @@ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ kexc25519s.o auth-krb5.o \ @@ -1334,8 +1334,8 @@ diff -Nur openssh-6.6p1.orig/Makefile.in openssh-6.6p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c ---- openssh-6.6p1.orig/misc.c 2014-07-14 19:49:55.174268608 +0200 -+++ openssh-6.6p1/misc.c 2014-07-15 06:05:00.939253015 +0200 +--- openssh-6.6p1.orig/misc.c 2015-01-15 20:08:13.106214870 +0100 ++++ openssh-6.6p1/misc.c 2015-01-15 20:08:56.685616348 +0100 @@ -159,11 +159,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1396,8 +1396,8 @@ diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-6.6p1.orig/misc.h openssh-6.6p1/misc.h ---- openssh-6.6p1.orig/misc.h 2013-10-15 03:14:12.000000000 +0200 -+++ openssh-6.6p1/misc.h 2014-07-15 06:05:00.939253015 +0200 +--- openssh-6.6p1.orig/misc.h 2015-01-15 20:08:13.076214593 +0100 ++++ openssh-6.6p1/misc.h 2015-01-15 20:08:56.685616348 +0100 @@ -41,6 +41,7 @@ void sock_set_v6only(int); @@ -1407,8 +1407,8 @@ diff -Nur openssh-6.6p1.orig/misc.h openssh-6.6p1/misc.h typedef struct arglist arglist; diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c ---- openssh-6.6p1.orig/monitor.c 2014-07-14 19:49:55.199268881 +0200 -+++ openssh-6.6p1/monitor.c 2014-07-15 06:23:28.126793084 +0200 +--- openssh-6.6p1.orig/monitor.c 2015-01-15 20:08:13.150215275 +0100 ++++ openssh-6.6p1/monitor.c 2015-01-15 20:08:56.686616358 +0100 @@ -182,6 +182,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1447,7 +1447,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -276,6 +283,8 @@ +@@ -277,6 +283,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1456,7 +1456,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, -@@ -313,7 +322,7 @@ +@@ -314,7 +322,7 @@ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM @@ -1465,7 +1465,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -403,6 +412,8 @@ +@@ -406,6 +414,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1474,7 +1474,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_proto15; -@@ -512,6 +523,8 @@ +@@ -520,6 +530,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1483,7 +1483,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -782,14 +795,17 @@ +@@ -790,14 +802,17 @@ debug3("%s", __func__); @@ -1504,7 +1504,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2283,12 +2299,15 @@ +@@ -2307,12 +2322,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1521,7 +1521,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2296,12 +2315,77 @@ +@@ -2320,12 +2338,77 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1601,8 +1601,8 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c mm_answer_gss_sign(int socket, Buffer *m) { diff -Nur openssh-6.6p1.orig/monitor.h openssh-6.6p1/monitor.h ---- openssh-6.6p1.orig/monitor.h 2014-07-14 19:49:55.199268881 +0200 -+++ openssh-6.6p1/monitor.h 2014-07-15 06:05:00.941253034 +0200 +--- openssh-6.6p1.orig/monitor.h 2015-01-15 20:08:13.121215008 +0100 ++++ openssh-6.6p1/monitor.h 2015-01-15 20:08:56.686616358 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1617,8 +1617,8 @@ diff -Nur openssh-6.6p1.orig/monitor.h openssh-6.6p1/monitor.h struct mm_master; diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c ---- openssh-6.6p1.orig/monitor_wrap.c 2014-07-14 19:49:55.199268881 +0200 -+++ openssh-6.6p1/monitor_wrap.c 2014-07-15 06:05:00.942253044 +0200 +--- openssh-6.6p1.orig/monitor_wrap.c 2015-01-15 20:08:13.151215284 +0100 ++++ openssh-6.6p1/monitor_wrap.c 2015-01-15 20:08:56.687616367 +0100 @@ -1327,12 +1327,13 @@ } @@ -1719,8 +1719,8 @@ diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-6.6p1.orig/monitor_wrap.h openssh-6.6p1/monitor_wrap.h ---- openssh-6.6p1.orig/monitor_wrap.h 2014-07-14 19:49:55.200268892 +0200 -+++ openssh-6.6p1/monitor_wrap.h 2014-07-15 06:05:00.942253044 +0200 +--- openssh-6.6p1.orig/monitor_wrap.h 2015-01-15 20:08:13.131215100 +0100 ++++ openssh-6.6p1/monitor_wrap.h 2015-01-15 20:08:56.687616367 +0100 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1737,8 +1737,8 @@ diff -Nur openssh-6.6p1.orig/monitor_wrap.h openssh-6.6p1/monitor_wrap.h #endif diff -Nur openssh-6.6p1.orig/readconf.c openssh-6.6p1/readconf.c ---- openssh-6.6p1.orig/readconf.c 2014-07-14 19:49:55.140268237 +0200 -+++ openssh-6.6p1/readconf.c 2014-07-15 06:05:00.943253053 +0200 +--- openssh-6.6p1.orig/readconf.c 2015-01-15 20:08:13.028214151 +0100 ++++ openssh-6.6p1/readconf.c 2015-01-15 20:08:56.688616376 +0100 @@ -1651,13 +1651,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1758,8 +1758,8 @@ diff -Nur openssh-6.6p1.orig/readconf.c openssh-6.6p1/readconf.c options->gss_renewal_rekey = 0; if (options->password_authentication == -1) diff -Nur openssh-6.6p1.orig/readconf.h openssh-6.6p1/readconf.h ---- openssh-6.6p1.orig/readconf.h 2014-07-14 19:49:55.140268237 +0200 -+++ openssh-6.6p1/readconf.h 2014-07-15 06:05:00.944253063 +0200 +--- openssh-6.6p1.orig/readconf.h 2015-01-15 20:08:13.028214151 +0100 ++++ openssh-6.6p1/readconf.h 2015-01-15 20:08:56.688616376 +0100 @@ -93,6 +93,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1770,8 +1770,8 @@ diff -Nur openssh-6.6p1.orig/readconf.h openssh-6.6p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c ---- openssh-6.6p1.orig/servconf.c 2014-07-14 19:49:55.158268433 +0200 -+++ openssh-6.6p1/servconf.c 2014-07-15 06:28:26.478649137 +0200 +--- openssh-6.6p1.orig/servconf.c 2015-01-15 20:08:13.152215293 +0100 ++++ openssh-6.6p1/servconf.c 2015-01-15 20:16:24.463735405 +0100 @@ -71,6 +71,7 @@ /* Portable-specific options */ @@ -1801,7 +1801,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -166,6 +171,8 @@ +@@ -167,6 +172,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1810,7 +1810,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -248,13 +255,17 @@ +@@ -249,13 +256,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1830,7 +1830,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; if (options->password_authentication == -1) -@@ -335,7 +346,7 @@ +@@ -338,7 +349,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1839,14 +1839,14 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -356,10 +367,14 @@ +@@ -359,10 +370,14 @@ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, + sGsiAllowLimitedProxy, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, @@ -1854,7 +1854,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, sVersionAddendum, -@@ -381,8 +396,10 @@ +@@ -384,8 +399,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1865,7 +1865,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -425,15 +442,25 @@ +@@ -428,16 +445,26 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1881,6 +1881,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, + { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, @@ -1891,7 +1892,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -494,6 +521,8 @@ +@@ -499,6 +526,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1900,7 +1901,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -901,6 +930,10 @@ +@@ -906,6 +935,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1911,7 +1912,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1116,6 +1149,10 @@ +@@ -1121,6 +1154,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1922,7 +1923,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1124,6 +1161,10 @@ +@@ -1129,6 +1166,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1933,7 +1934,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1132,6 +1173,12 @@ +@@ -1137,6 +1178,12 @@ intptr = &options->gss_store_rekey; goto parse_flag; @@ -1946,7 +1947,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1592,6 +1639,18 @@ +@@ -1602,6 +1649,18 @@ *charptr = xstrdup(arg); break; @@ -1965,7 +1966,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -1799,6 +1858,7 @@ +@@ -1811,6 +1870,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1974,8 +1975,8 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h ---- openssh-6.6p1.orig/servconf.h 2014-07-14 19:49:55.158268433 +0200 -+++ openssh-6.6p1/servconf.h 2014-07-15 06:05:00.946253082 +0200 +--- openssh-6.6p1.orig/servconf.h 2015-01-15 20:08:13.109214897 +0100 ++++ openssh-6.6p1/servconf.h 2015-01-15 20:08:56.690616394 +0100 @@ -111,9 +111,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if @@ -1997,9 +1998,9 @@ diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h int permit_tun; -@@ -175,6 +179,10 @@ - - int use_kuserok; +@@ -176,6 +180,10 @@ + int use_kuserok; + int enable_k5users; char *chroot_directory; + + int disable_usage_stats; @@ -2009,8 +2010,8 @@ diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h char *trusted_user_ca_keys; char *authorized_principals_file; diff -Nur openssh-6.6p1.orig/ssh.1 openssh-6.6p1/ssh.1 ---- openssh-6.6p1.orig/ssh.1 2014-07-14 19:49:55.111267920 +0200 -+++ openssh-6.6p1/ssh.1 2014-07-15 06:05:00.947253092 +0200 +--- openssh-6.6p1.orig/ssh.1 2015-01-15 20:08:12.997213865 +0100 ++++ openssh-6.6p1/ssh.1 2015-01-15 20:08:56.690616394 +0100 @@ -1295,6 +1295,18 @@ on to new connections). .It Ev USER @@ -2031,8 +2032,8 @@ diff -Nur openssh-6.6p1.orig/ssh.1 openssh-6.6p1/ssh.1 .Pp Additionally, diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c ---- openssh-6.6p1.orig/ssh.c 2014-07-14 19:49:55.216269067 +0200 -+++ openssh-6.6p1/ssh.c 2014-07-15 06:31:38.640768992 +0200 +--- openssh-6.6p1.orig/ssh.c 2015-01-15 20:08:13.141215192 +0100 ++++ openssh-6.6p1/ssh.c 2015-01-15 20:08:56.691616404 +0100 @@ -395,6 +395,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2081,8 +2082,8 @@ diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); diff -Nur openssh-6.6p1.orig/ssh_config openssh-6.6p1/ssh_config ---- openssh-6.6p1.orig/ssh_config 2014-07-14 19:49:55.142268259 +0200 -+++ openssh-6.6p1/ssh_config 2014-07-15 06:05:00.948253101 +0200 +--- openssh-6.6p1.orig/ssh_config 2015-01-15 20:08:13.031214179 +0100 ++++ openssh-6.6p1/ssh_config 2015-01-15 20:08:56.691616404 +0100 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2099,8 +2100,8 @@ diff -Nur openssh-6.6p1.orig/ssh_config openssh-6.6p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-6.6p1.orig/ssh_config.5 openssh-6.6p1/ssh_config.5 ---- openssh-6.6p1.orig/ssh_config.5 2014-07-14 19:49:55.143268270 +0200 -+++ openssh-6.6p1/ssh_config.5 2014-07-15 06:05:00.949253111 +0200 +--- openssh-6.6p1.orig/ssh_config.5 2015-01-15 20:08:13.031214179 +0100 ++++ openssh-6.6p1/ssh_config.5 2015-01-15 20:08:56.692616413 +0100 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2115,9 +2116,9 @@ diff -Nur openssh-6.6p1.orig/ssh_config.5 openssh-6.6p1/ssh_config.5 .Pq Pa /etc/ssh/ssh_config .El diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c ---- openssh-6.6p1.orig/sshconnect2.c 2014-07-14 19:49:55.216269067 +0200 -+++ openssh-6.6p1/sshconnect2.c 2014-07-15 06:05:00.950253121 +0200 -@@ -696,6 +696,11 @@ +--- openssh-6.6p1.orig/sshconnect2.c 2015-01-15 20:08:13.142215201 +0100 ++++ openssh-6.6p1/sshconnect2.c 2015-01-15 20:08:56.692616413 +0100 +@@ -728,6 +728,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2129,7 +2130,7 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -929,6 +934,15 @@ +@@ -961,6 +966,15 @@ free(lang); } @@ -2145,7 +2146,7 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -946,8 +960,16 @@ +@@ -978,8 +992,16 @@ return (0); } @@ -2162,7 +2163,7 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -958,7 +980,15 @@ +@@ -990,7 +1012,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2179,8 +2180,8 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-6.6p1.orig/sshd.8 openssh-6.6p1/sshd.8 ---- openssh-6.6p1.orig/sshd.8 2014-07-14 19:49:55.150268346 +0200 -+++ openssh-6.6p1/sshd.8 2014-07-15 06:05:00.951253130 +0200 +--- openssh-6.6p1.orig/sshd.8 2015-01-15 20:08:13.036214225 +0100 ++++ openssh-6.6p1/sshd.8 2015-01-15 20:08:56.693616422 +0100 @@ -766,6 +766,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2227,8 +2228,8 @@ diff -Nur openssh-6.6p1.orig/sshd.8 openssh-6.6p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c ---- openssh-6.6p1.orig/sshd.c 2014-07-14 19:49:55.217269078 +0200 -+++ openssh-6.6p1/sshd.c 2014-07-15 06:05:00.952253140 +0200 +--- openssh-6.6p1.orig/sshd.c 2015-01-15 20:08:13.154215312 +0100 ++++ openssh-6.6p1/sshd.c 2015-01-15 20:08:56.693616422 +0100 @@ -124,6 +124,7 @@ #include "audit.h" #include "ssh-sandbox.h" @@ -2237,7 +2238,7 @@ diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c #ifdef USE_SECURITY_SESSION_API #include -@@ -1699,6 +1700,13 @@ +@@ -1709,6 +1710,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2251,7 +2252,7 @@ diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2230,7 +2238,7 @@ +@@ -2240,7 +2248,7 @@ #endif #ifdef GSSAPI @@ -2261,8 +2262,8 @@ diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config ---- openssh-6.6p1.orig/sshd_config 2014-07-14 19:49:55.160268455 +0200 -+++ openssh-6.6p1/sshd_config 2014-07-15 06:37:02.657343409 +0200 +--- openssh-6.6p1.orig/sshd_config 2015-01-15 20:08:13.110214907 +0100 ++++ openssh-6.6p1/sshd_config 2015-01-15 20:12:27.743560736 +0100 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2274,10 +2275,10 @@ diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config #GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no +#GSSAPIKeyExchange yes + #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -108,6 +109,10 @@ +@@ -109,6 +110,10 @@ # problems. UsePAM yes @@ -2288,7 +2289,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -154,3 +159,7 @@ +@@ -151,3 +156,7 @@ # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server @@ -2297,8 +2298,8 @@ diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config +#UsageStatsTargets usage-stats.cilogon.org:4810 +#DisableUsageStats no diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 ---- openssh-6.6p1.orig/sshd_config.5 2014-07-14 19:49:55.160268455 +0200 -+++ openssh-6.6p1/sshd_config.5 2014-07-15 06:05:00.953253149 +0200 +--- openssh-6.6p1.orig/sshd_config.5 2015-01-15 20:08:13.110214907 +0100 ++++ openssh-6.6p1/sshd_config.5 2015-01-15 20:10:59.416747018 +0100 @@ -449,6 +449,15 @@ See PATTERNS in .Xr ssh_config 5 @@ -2326,10 +2327,10 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .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. -@@ -505,6 +518,22 @@ +@@ -511,6 +524,22 @@ + .Xr ksu 1 . The default is - .Dq yes . - Note that this option applies to protocol version 2 only. + .Dq no . +.It Cm GSSAPICredentialsPath +If specified, the delegated GSSAPI credential is stored in the +given path, overwriting any existing credentials. @@ -2349,7 +2350,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If -@@ -1196,6 +1225,121 @@ +@@ -1202,6 +1231,121 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2471,7 +2472,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication. -@@ -1261,6 +1405,12 @@ +@@ -1267,6 +1411,12 @@ as a non-root user. The default is .Dq no . @@ -2486,7 +2487,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .Xr sshd 8 diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c --- openssh-6.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/ssh-globus-usage.c 2014-07-15 06:05:00.954253159 +0200 ++++ openssh-6.6p1/ssh-globus-usage.c 2015-01-15 20:08:56.696616450 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2886,7 +2887,7 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c +} diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h --- openssh-6.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/ssh-globus-usage.h 2014-07-15 06:05:00.954253159 +0200 ++++ openssh-6.6p1/ssh-globus-usage.h 2015-01-15 20:08:56.696616450 +0100 @@ -0,0 +1,46 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2935,8 +2936,8 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h + +#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-6.6p1.orig/ssh-gss.h openssh-6.6p1/ssh-gss.h ---- openssh-6.6p1.orig/ssh-gss.h 2014-07-14 19:49:55.149268335 +0200 -+++ openssh-6.6p1/ssh-gss.h 2014-07-15 06:05:00.955253168 +0200 +--- openssh-6.6p1.orig/ssh-gss.h 2015-01-15 20:08:13.036214225 +0100 ++++ openssh-6.6p1/ssh-gss.h 2015-01-15 20:08:56.696616450 +0100 @@ -91,6 +91,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2982,8 +2983,8 @@ diff -Nur openssh-6.6p1.orig/ssh-gss.h openssh-6.6p1/ssh-gss.h #endif /* _SSH_GSS_H */ diff -Nur openssh-6.6p1.orig/version.h openssh-6.6p1/version.h ---- openssh-6.6p1.orig/version.h 2014-07-14 19:49:55.187268750 +0200 -+++ openssh-6.6p1/version.h 2014-07-15 06:05:00.955253168 +0200 +--- openssh-6.6p1.orig/version.h 2015-01-15 20:08:13.065214492 +0100 ++++ openssh-6.6p1/version.h 2015-01-15 20:08:56.696616450 +0100 @@ -1,6 +1,21 @@ /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ diff --git a/openssh-6.6p1-ldap.patch b/openssh-6.6p1-ldap.patch index 961cdf5..ae3e7cd 100644 --- a/openssh-6.6p1-ldap.patch +++ b/openssh-6.6p1-ldap.patch @@ -1162,7 +1162,7 @@ new file mode 100644 index 0000000..525060a --- /dev/null +++ b/ldapconf.c -@@ -0,0 +1,720 @@ +@@ -0,0 +1,722 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -1479,6 +1479,7 @@ index 0000000..525060a + else + fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum); + if (*intptr == -1) ++ *intptr = value; + break; + + case lSSLPath: @@ -1543,6 +1544,7 @@ index 0000000..525060a + else + fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum); + if (*intptr == -1) ++ *intptr = value; + break; + + case lTLS_CaCertFile: diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index a87d9bf..12f4a9f 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -1,11 +1,12 @@ diff --git a/ssh_config b/ssh_config -index 03a228f..6d1abaf 100644 +index 49a4f6c..3f83c40 100644 --- a/ssh_config +++ b/ssh_config -@@ -46,3 +46,14 @@ - # VisualHostKey no - # ProxyCommand ssh -q -W %h:%p gateway.example.com - # RekeyLimit 1G 1h +@@ -50,3 +50,15 @@ + # Uncomment this if you want to use .local domain + # Host *.local + # CheckHostIP no ++ +Host * + GSSAPIAuthentication yes +# If this option is set to yes then remote X11 clients will have full access From 17725e15da78edd0e0553401be2b712bf5c7911b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 13 Apr 2015 20:01:21 +0200 Subject: [PATCH 009/146] Based on openssh-6.6.1p1-12.fc21 --- gsi-openssh.spec | 17 +++++++++++++---- gsisshd.tmpfiles | 1 + openssh-5.1p1-scp-manpage.patch | 18 ------------------ ...6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch | 16 ++++++++++++++++ openssh-6.7p1-ssh-copy-id-truncated-keys.patch | 13 +++++++++++++ 5 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 gsisshd.tmpfiles delete mode 100644 openssh-5.1p1-scp-manpage.patch create mode 100644 openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch create mode 100644 openssh-6.7p1-ssh-copy-id-truncated-keys.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a3bf8b6..7e30efa 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ %global ldap 1 %global openssh_ver 6.6.1p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -47,6 +47,7 @@ Source10: gsisshd.socket Source11: gsisshd.service Source12: gsisshd-keygen.service Source13: gsisshd-keygen +Source14: gsisshd.tmpfiles Source99: README.sshd-and-gsisshd #? @@ -101,8 +102,6 @@ Patch703: openssh-4.3p2-askpass-grab-info.patch # https://bugzilla.redhat.com/show_bug.cgi?id=205842 # drop? Patch704: openssh-5.9p1-edns.patch #? -Patch705: openssh-5.1p1-scp-manpage.patch -#? Patch706: openssh-6.6.1p1-localdomain.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) Patch707: openssh-6.6p1-redhat.patch @@ -170,6 +169,10 @@ Patch918: openssh-6.6.1p1-log-in-chroot.patch Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch # Config parser shouldn't accept ip/port syntax (#1130733) Patch920: openssh-6.6.1p1-ip-port-config-parser.patch +# fix ssh-copy-id on non-sh shells (#1045191) +Patch921: openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch +# Solve issue with ssh-copy-id and keys without trailing newline (#1093168) +Patch922: openssh-6.7p1-ssh-copy-id-truncated-keys.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch @@ -298,7 +301,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch703 -p1 -b .grab-info # investigate - https://bugzilla.redhat.com/show_bug.cgi?id=205842 # probably not needed anymore %patch704 -p1 -b .edns -# drop it %patch705 -p1 -b .manpage %patch706 -p1 -b .localdomain %patch707 -p1 -b .redhat %patch708 -p1 -b .entropy @@ -330,6 +332,8 @@ This version of OpenSSH has been modified to support GSI authentication. %patch919 -p1 -b .scp %patch920 -p1 -b .config %patch802 -p1 -b .GSSAPIEnablek5users +%patch921 -p1 -b .ssh-copy-id +%patch922 -p1 -b .newline %patch200 -p1 -b .audit %patch201 -p1 -b .audit-fps @@ -449,6 +453,7 @@ install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd@.service install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.socket install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.service install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd-keygen.service +install -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/gsissh.conf rm $RPM_BUILD_ROOT%{_bindir}/ssh-add rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent @@ -549,8 +554,12 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd@.service %attr(0644,root,root) %{_unitdir}/gsisshd.socket %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service +%attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Apr 13 2015 Mattias Ellert - 6.6.1p1-5 +- Based on openssh-6.6.1p1-12.fc21 + * Thu Jan 15 2015 Mattias Ellert - 6.6.1p1-4 - Based on openssh-6.6.1p1-11.1.fc21 diff --git a/gsisshd.tmpfiles b/gsisshd.tmpfiles new file mode 100644 index 0000000..e13d962 --- /dev/null +++ b/gsisshd.tmpfiles @@ -0,0 +1 @@ +d /var/empty/gsisshd 711 root root - diff --git a/openssh-5.1p1-scp-manpage.patch b/openssh-5.1p1-scp-manpage.patch deleted file mode 100644 index e314a05..0000000 --- a/openssh-5.1p1-scp-manpage.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up openssh-5.1p1/scp.1.manpage openssh-5.1p1/scp.1 ---- openssh-5.1p1/scp.1.manpage 2008-07-12 09:12:49.000000000 +0200 -+++ openssh-5.1p1/scp.1 2008-07-23 19:18:15.000000000 +0200 -@@ -66,6 +66,14 @@ treating file names containing - as host specifiers. - Copies between two remote hosts are also permitted. - .Pp -+When copying a source file to a target file which already exists, -+.Nm -+will replace the contents of the target file (keeping the inode). -+.Pp -+If the target file does not yet exist, an empty file with the target -+file name is created, then filled with the source file contents. -+No attempt is made at "near-atomic" transfer using temporary files. -+.Pp - The options are as follows: - .Bl -tag -width Ds - .It Fl 1 diff --git a/openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch b/openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch new file mode 100644 index 0000000..f6997a2 --- /dev/null +++ b/openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch @@ -0,0 +1,16 @@ +diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id +index 8e1091c..4bba5d6 100644 +--- a/contrib/ssh-copy-id ++++ b/contrib/ssh-copy-id +@@ -274,9 +274,9 @@ case "$REMOTE_VERSION" in + populate_new_ids 0 + fi + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " +- umask 077 ; ++ exec sh -c 'umask 077 ; + mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; +- if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ ++ if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ + || exit 1 + ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) + ;; diff --git a/openssh-6.7p1-ssh-copy-id-truncated-keys.patch b/openssh-6.7p1-ssh-copy-id-truncated-keys.patch new file mode 100644 index 0000000..f4c91a4 --- /dev/null +++ b/openssh-6.7p1-ssh-copy-id-truncated-keys.patch @@ -0,0 +1,13 @@ +diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id +index 4bba5d6..ed1208e 100644 +--- a/contrib/ssh-copy-id ++++ b/contrib/ssh-copy-id +@@ -207,7 +207,7 @@ populate_new_ids() { + printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 + NEW_IDS=$( + eval $GET_ID | { +- while read ID ; do ++ while read ID || [[ -n $ID ]]; do + printf '%s\n' "$ID" > $L_TMP_ID_FILE + + # the next line assumes $PRIV_ID_FILE only set if using a single id file - this From 04aef646ab7de9bcb4738db00e9d26febd5f0875 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 14 Apr 2015 11:49:37 +0200 Subject: [PATCH 010/146] Based on openssh-6.8p1-4.fc22 --- gsi-openssh.spec | 98 +- gsisshd.pam | 1 + openssh-5.6p1-exit-deadlock.patch | 14 - openssh-5.8p1-packet.patch | 12 +- openssh-5.9p1-edns.patch | 72 -- ...210618256bbf5f4f71b2887ff186fd451736.patch | 177 ---- openssh-6.1p1-askpass-ld.patch | 18 - openssh-6.2p1-vendor.patch | 138 ++- openssh-6.4p1-CLOCK_BOOTTIME.patch | 29 - openssh-6.6.1p1-NI_MAXHOST.patch | 76 -- openssh-6.6.1p1-audit-pfs.patch | 212 ---- openssh-6.6.1p1-cisco-dh-keys.patch | 64 +- openssh-6.6.1p1-coverity.patch | 844 --------------- ...h-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch | 28 - openssh-6.6.1p1-log-in-chroot.patch | 109 +- openssh-6.6.1p1-partial-success.patch | 16 - openssh-6.6.1p1-selinux-contexts.patch | 14 +- openssh-6.6.1p1-utf8-banner.patch | 61 +- openssh-6.6p1-CVE-2014-2653.patch | 80 -- openssh-6.6p1-GSSAPIEnablek5users.patch | 75 +- openssh-6.6p1-ctr-cavstest.patch | 25 +- openssh-6.6p1-entropy.patch | 36 +- openssh-6.6p1-fingerprint.patch | 415 -------- openssh-6.6p1-force_krb.patch | 27 +- openssh-6.6p1-gsskex.patch | 714 ++++++------- openssh-6.6p1-keycat.patch | 83 +- openssh-6.6p1-keyperm.patch | 13 +- openssh-6.6p1-kuserok.patch | 92 +- openssh-6.6p1-role-mls.patch | 208 ++-- openssh-6.6p1-set_remote_ipaddr.patch | 35 +- ...1-audit.patch => openssh-6.7p1-audit.patch | 972 +++++++++--------- openssh-6.7p1-coverity.patch | 471 +++++++++ ...sh-6.7p1-debian-restore-tcp-wrappers.patch | 140 +++ ...6p1-fips.patch => openssh-6.7p1-fips.patch | 501 ++++----- openssh-6.7p1-kdf-cavs.patch | 614 +++++++++++ ...6p1-ldap.patch => openssh-6.7p1-ldap.patch | 240 +++-- openssh-6.7p1-seccomp-aarch64.patch | 66 ++ openssh-6.7p1-sftp-force-permission.patch | 81 ++ openssh-6.7p1-sshdT-output.patch | 56 + openssh-6.8p1-880575.patch | 11 + ...gsissh.patch => openssh-6.8p1-gsissh.patch | 632 ++++++------ sources | 2 +- 42 files changed, 3395 insertions(+), 4177 deletions(-) delete mode 100644 openssh-5.6p1-exit-deadlock.patch delete mode 100644 openssh-5.9p1-edns.patch delete mode 100644 openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch delete mode 100644 openssh-6.1p1-askpass-ld.patch delete mode 100644 openssh-6.4p1-CLOCK_BOOTTIME.patch delete mode 100644 openssh-6.6.1p1-NI_MAXHOST.patch delete mode 100644 openssh-6.6.1p1-audit-pfs.patch delete mode 100644 openssh-6.6.1p1-coverity.patch delete mode 100644 openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch delete mode 100644 openssh-6.6.1p1-partial-success.patch delete mode 100644 openssh-6.6p1-CVE-2014-2653.patch delete mode 100644 openssh-6.6p1-fingerprint.patch rename openssh-6.6p1-audit.patch => openssh-6.7p1-audit.patch (68%) create mode 100644 openssh-6.7p1-coverity.patch create mode 100644 openssh-6.7p1-debian-restore-tcp-wrappers.patch rename openssh-6.6p1-fips.patch => openssh-6.7p1-fips.patch (61%) create mode 100644 openssh-6.7p1-kdf-cavs.patch rename openssh-6.6p1-ldap.patch => openssh-6.7p1-ldap.patch (92%) create mode 100644 openssh-6.7p1-seccomp-aarch64.patch create mode 100644 openssh-6.7p1-sftp-force-permission.patch create mode 100644 openssh-6.7p1-sshdT-output.patch create mode 100644 openssh-6.8p1-880575.patch rename openssh-6.6p1-gsissh.patch => openssh-6.8p1-gsissh.patch (85%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 7e30efa..3a386ed 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -8,6 +8,8 @@ %global WITH_SELINUX 0 %endif +%global _hardened_build 1 + # OpenSSH privilege separation requires a user & group ID %global sshd_uid 74 %global sshd_gid 74 @@ -28,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 6.6.1p1 -%global openssh_rel 5 +%global openssh_ver 6.8p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -38,8 +40,7 @@ Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html -# Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz -Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-6.6p1.tar.gz +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz Source2: gsisshd.pam Source7: gsisshd.sysconfig Source9: gsisshd@.service @@ -51,9 +52,7 @@ Source14: gsisshd.tmpfiles Source99: README.sshd-and-gsisshd #? -Patch100: openssh-6.6.1p1-coverity.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1872 -Patch101: openssh-6.6p1-fingerprint.patch +Patch100: openssh-6.7p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 #https://bugzilla.redhat.com/show_bug.cgi?id=735889 Patch102: openssh-5.8p1-getaddrinfo.patch @@ -61,10 +60,9 @@ Patch102: openssh-5.8p1-getaddrinfo.patch Patch103: openssh-5.8p1-packet.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 -Patch200: openssh-6.6p1-audit.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event -Patch201: openssh-6.6.1p1-audit-pfs.patch +Patch200: openssh-6.7p1-audit.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-6.6p1-role-mls.patch @@ -72,7 +70,7 @@ Patch400: openssh-6.6p1-role-mls.patch Patch404: openssh-6.6p1-privsep-selinux.patch #?-- unwanted child :( -Patch501: openssh-6.6p1-ldap.patch +Patch501: openssh-6.7p1-ldap.patch #? Patch502: openssh-6.6p1-keycat.patch @@ -86,21 +84,15 @@ Patch604: openssh-6.6p1-keyperm.patch Patch606: openssh-5.9p1-ipv6man.patch #? Patch607: openssh-5.8p2-sigpipe.patch -#? -Patch608: openssh-6.1p1-askpass-ld.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1789 Patch609: openssh-5.5p1-x11.patch #? -Patch700: openssh-6.6p1-fips.patch -#? -# drop? Patch701: openssh-5.6p1-exit-deadlock.patch +Patch700: openssh-6.7p1-fips.patch #? Patch702: openssh-5.1p1-askpass-progress.patch #? Patch703: openssh-4.3p2-askpass-grab-info.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=205842 -# drop? Patch704: openssh-5.9p1-edns.patch #? Patch706: openssh-6.6.1p1-localdomain.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) @@ -115,6 +107,8 @@ Patch711: openssh-6.6p1-log-usepam-no.patch 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 #http://www.sxw.org.uk/computing/patches/openssh.html #changed cache storage type - #848228 @@ -133,16 +127,6 @@ Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch Patch905: openssh-6.4p1-legacy-ssh-copy-id.patch # Use tty allocation for a remote scp (#985650) Patch906: openssh-6.4p1-fromto-remote.patch -# Try CLOCK_BOOTTIME with fallback (#1091992) -Patch907: openssh-6.4p1-CLOCK_BOOTTIME.patch -# Prevents a server from skipping SSHFP lookup and forcing a new-hostkey -# dialog by offering only certificate keys. (#1081338) -Patch908: openssh-6.6p1-CVE-2014-2653.patch -# OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 key exchange incorrectly -# Disable the curve25519 KEX when speaking to OpenSSH 6.5 or 6.6 -Patch909: openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch -# standardise on NI_MAXHOST for gethostname() string lengths (#1051490) -Patch910: openssh-6.6.1p1-NI_MAXHOST.patch # set a client's address right after a connection is set # http://bugzilla.mindrot.org/show_bug.cgi?id=2257 Patch911: openssh-6.6p1-set_remote_ipaddr.patch @@ -150,15 +134,9 @@ Patch911: openssh-6.6p1-set_remote_ipaddr.patch # https://bugzilla.mindrot.org/show_bug.cgi?id=2058 # slightly changed patch from comment 10 Patch912: openssh-6.6.1p1-utf8-banner.patch -# don't consider a partial success as a failure -# https://bugzilla.mindrot.org/show_bug.cgi?id=2270 -Patch913: openssh-6.6.1p1-partial-success.patch # fix parsing of empty options in sshd_conf # https://bugzilla.mindrot.org/show_bug.cgi?id=2281 Patch914: openssh-6.6.1p1-servconf-parser.patch -# Ignore SIGXFSZ in postauth monitor -# https://bugzilla.mindrot.org/show_bug.cgi?id=2263 -Patch915: openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch # privsep_preauth: use SELinux context from selinux-policy (#1008580) Patch916: openssh-6.6.1p1-selinux-contexts.patch # use different values for DH for Cisco servers (#1026430) @@ -169,14 +147,25 @@ Patch918: openssh-6.6.1p1-log-in-chroot.patch Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch # Config parser shouldn't accept ip/port syntax (#1130733) Patch920: openssh-6.6.1p1-ip-port-config-parser.patch +# restore tcp wrappers support, based on Debian patch +# https://lists.mindrot.org/pipermail/openssh-unix-dev/2014-April/032497.html +Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.patch +# apply upstream patch and make sshd -T more consistent (#1187521) +Patch922: openssh-6.7p1-sshdT-output.patch # fix ssh-copy-id on non-sh shells (#1045191) -Patch921: openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch +Patch923: openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch +# AArch64 has seccomp support since 3.19 kernel (#1195065) +Patch924: openssh-6.7p1-seccomp-aarch64.patch # Solve issue with ssh-copy-id and keys without trailing newline (#1093168) -Patch922: openssh-6.7p1-ssh-copy-id-truncated-keys.patch +Patch925: openssh-6.7p1-ssh-copy-id-truncated-keys.patch +# Add sftp option to force mode of created files (#1191055) +Patch926: openssh-6.7p1-sftp-force-permission.patch +# Upstream bug #1878 reintroduced in openssh6.7p1 +Patch927: openssh-6.8p1-880575.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.6p1.patch -Patch98: openssh-6.6p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.8p1.patch +Patch98: openssh-6.8p1-gsissh.patch License: BSD Group: Applications/Internet @@ -272,9 +261,8 @@ securely connect to your SSH server. This version of OpenSSH has been modified to support GSI authentication. %prep -%setup -q -n openssh-6.6p1 +%setup -q -n openssh-%{version} -%patch101 -p1 -b .fingerprint # investigate %patch102 -p1 -b .getaddrinfo %patch103 -p1 -b .packet @@ -293,14 +281,10 @@ This version of OpenSSH has been modified to support GSI authentication. %patch604 -p1 -b .keyperm %patch606 -p1 -b .ipv6man %patch607 -p1 -b .sigpipe -%patch608 -p1 -b .askpass-ld %patch609 -p1 -b .x11 -# drop? %patch701 -p1 -b .exit-deadlock %patch702 -p1 -b .progress %patch703 -p1 -b .grab-info -# investigate - https://bugzilla.redhat.com/show_bug.cgi?id=205842 -# probably not needed anymore %patch704 -p1 -b .edns %patch706 -p1 -b .localdomain %patch707 -p1 -b .redhat %patch708 -p1 -b .entropy @@ -308,6 +292,7 @@ This version of OpenSSH has been modified to support GSI authentication. %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 @@ -317,26 +302,24 @@ This version of OpenSSH has been modified to support GSI authentication. %patch902 -p1 -b .ccache_name %patch905 -p1 -b .legacy-ssh-copy-id %patch906 -p1 -b .fromto-remote -%patch907 -p1 -b .CLOCK_BOOTTIME -%patch908 -p1 -b .CVE-2014-2653 -%patch909 -p1 -b .6.6.1 -%patch910 -p1 -b .NI_MAXHOST %patch911 -p1 -b .set_remote_ipaddr %patch912 -p1 -b .utf8-banner -%patch913 -p1 -b .partial-success %patch914 -p1 -b .servconf -%patch915 -p1 -b .SIGXFSZ %patch916 -p1 -b .contexts %patch917 -p1 -b .cisco-dh %patch918 -p1 -b .log-in-chroot %patch919 -p1 -b .scp %patch920 -p1 -b .config %patch802 -p1 -b .GSSAPIEnablek5users -%patch921 -p1 -b .ssh-copy-id -%patch922 -p1 -b .newline +%patch921 -p1 -b .tcp_wrappers +%patch922 -p1 -b .sshdt +%patch923 -p1 -b .ssh-copy-id +%patch924 -p1 -b .seccomp +%patch925 -p1 -b .newline +%patch926 -p1 -b .sftp-force-mode +%patch927 -p1 -b .bz880575 %patch200 -p1 -b .audit -%patch201 -p1 -b .audit-fps %patch700 -p1 -b .fips %patch100 -p1 -b .coverity @@ -393,14 +376,14 @@ fi --without-zlib-version-check \ --with-ssl-engine \ --with-ipaddr-display \ + --with-pie=no \ %if %{ldap} --with-ldap \ %endif --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ -%if 0 - #seccomp_filter cannot be build right now +%ifarch %{ix86} x86_64 %{arm} aarch64 --with-sandbox=seccomp_filter \ %else --with-sandbox=rlimit \ @@ -458,6 +441,9 @@ 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-ldap-helper rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-ldap-wrapper rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-keycat @@ -519,7 +505,6 @@ getent passwd sshd >/dev/null || \ %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(0755,root,root) %{_libexecdir}/gsissh/ctr-cavstest %attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8* %files clients @@ -557,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Apr 13 2015 Mattias Ellert - 6.8p1-1 +- Based on openssh-6.8p1-4.fc22 + * Mon Apr 13 2015 Mattias Ellert - 6.6.1p1-5 - Based on openssh-6.6.1p1-12.fc21 diff --git a/gsisshd.pam b/gsisshd.pam index 766aa93..eae0ba6 100644 --- a/gsisshd.pam +++ b/gsisshd.pam @@ -12,6 +12,7 @@ session required pam_selinux.so close session required pam_loginuid.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open env_params +session required pam_namespace.so session optional pam_keyinit.so force revoke session include password-auth session include postlogin diff --git a/openssh-5.6p1-exit-deadlock.patch b/openssh-5.6p1-exit-deadlock.patch deleted file mode 100644 index 278dfa1..0000000 --- a/openssh-5.6p1-exit-deadlock.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up openssh-5.6p1/channels.c.exit-deadlock openssh-5.6p1/channels.c ---- openssh-5.6p1/channels.c.exit-deadlock 2010-08-05 15:09:48.000000000 +0200 -+++ openssh-5.6p1/channels.c 2010-08-23 12:41:43.000000000 +0200 -@@ -1647,6 +1647,10 @@ channel_handle_wfd(Channel *c, fd_set *r - u_int dlen, olen = 0; - int len; - -+ if(c->wfd != -1 && buffer_len(&c->output) > 0 && c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { -+ debug("channel %d: forcing write", c->self); -+ FD_SET(c->wfd, writeset); -+ } - /* Send buffered output data to the socket. */ - if (c->wfd != -1 && - FD_ISSET(c->wfd, writeset) && diff --git a/openssh-5.8p1-packet.patch b/openssh-5.8p1-packet.patch index 4951af6..baccb53 100644 --- a/openssh-5.8p1-packet.patch +++ b/openssh-5.8p1-packet.patch @@ -1,12 +1,12 @@ -diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c ---- openssh-5.8p1/packet.c.packet 2011-04-05 13:29:06.998648899 +0200 -+++ openssh-5.8p1/packet.c 2011-04-05 13:30:32.967648596 +0200 -@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void) +diff -up openssh-6.8p1/packet.c.packet openssh-6.8p1/packet.c +--- openssh-6.8p1/packet.c.packet 2015-03-18 10:56:32.286930601 +0100 ++++ openssh-6.8p1/packet.c 2015-03-18 10:58:38.535629739 +0100 +@@ -371,6 +371,8 @@ ssh_packet_connection_is_on_socket(struc struct sockaddr_storage from, to; socklen_t fromlen, tolen; -+ if (!active_state) ++ if (!state) + return 0; /* filedescriptors in and out are the same, so it's a socket */ - if (active_state->connection_in == active_state->connection_out) + if (state->connection_in == state->connection_out) return 1; diff --git a/openssh-5.9p1-edns.patch b/openssh-5.9p1-edns.patch deleted file mode 100644 index 34f3851..0000000 --- a/openssh-5.9p1-edns.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff -up openssh-5.9p1/dns.c.edns openssh-5.9p1/dns.c ---- openssh-5.9p1/dns.c.edns 2010-08-31 14:41:14.000000000 +0200 -+++ openssh-5.9p1/dns.c 2011-09-09 08:05:27.782440497 +0200 -@@ -177,6 +177,7 @@ verify_host_key_dns(const char *hostname - { - u_int counter; - int result; -+ unsigned int rrset_flags = 0; - struct rrsetinfo *fingerprints = NULL; - - u_int8_t hostkey_algorithm; -@@ -200,8 +201,19 @@ verify_host_key_dns(const char *hostname - return -1; - } - -+ /* -+ * Original getrrsetbyname function, found on OpenBSD for example, -+ * doesn't accept any flag and prerequisite for obtaining AD bit in -+ * DNS response is set by "options edns0" in resolv.conf. -+ * -+ * Our version is more clever and use RRSET_FORCE_EDNS0 flag. -+ */ -+#ifndef HAVE_GETRRSETBYNAME -+ rrset_flags |= RRSET_FORCE_EDNS0; -+#endif - result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, -- DNS_RDATATYPE_SSHFP, 0, &fingerprints); -+ DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints); -+ - if (result) { - verbose("DNS lookup error: %s", dns_result_totext(result)); - return -1; -diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.c ---- openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns 2009-07-13 03:38:23.000000000 +0200 -+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.c 2011-09-09 15:03:39.930500801 +0200 -@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns - goto fail; - } - -- /* don't allow flags yet, unimplemented */ -- if (flags) { -+ /* Allow RRSET_FORCE_EDNS0 flag only. */ -+ if ((flags & ~RRSET_FORCE_EDNS0) != 0) { - result = ERRSET_INVAL; - goto fail; - } -@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns - #endif /* DEBUG */ - - #ifdef RES_USE_DNSSEC -- /* turn on DNSSEC if EDNS0 is configured */ -- if (_resp->options & RES_USE_EDNS0) -- _resp->options |= RES_USE_DNSSEC; -+ /* turn on DNSSEC if required */ -+ if (flags & RRSET_FORCE_EDNS0) -+ _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC); - #endif /* RES_USE_DNSEC */ - - /* make query */ -diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.h ---- openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns 2007-10-26 08:26:50.000000000 +0200 -+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.h 2011-09-09 08:05:27.965438689 +0200 -@@ -72,6 +72,9 @@ - #ifndef RRSET_VALIDATED - # define RRSET_VALIDATED 1 - #endif -+#ifndef RRSET_FORCE_EDNS0 -+# define RRSET_FORCE_EDNS0 0x0001 -+#endif - - /* - * Return codes for getrrsetbyname() diff --git a/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch b/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch deleted file mode 100644 index 44da114..0000000 --- a/openssh-5618210618256bbf5f4f71b2887ff186fd451736.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 5618210618256bbf5f4f71b2887ff186fd451736 Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Sun, 20 Apr 2014 13:44:47 +1000 -Subject: [PATCH] - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c - version.h] OpenSSH 6.5 and 6.6 sometimes encode a value used in the - curve25519 key exchange incorrectly, causing connection failures about - 0.2% of the time when this method is used against a peer that implements - the method properly. - - Fix the problem and disable the curve25519 KEX when speaking to - OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 - to enable the compatability code. ---- - ChangeLog | 11 +++++++++++ - bufaux.c | 5 ++++- - compat.c | 17 ++++++++++++++++- - compat.h | 2 ++ - sshconnect2.c | 2 ++ - sshd.c | 3 +++ - version.h | 2 +- - 7 files changed, 39 insertions(+), 3 deletions(-) - -diff --git a/ChangeLog b/ChangeLog -index 1603a07..928999d 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,13 +1,23 @@ - 20140420 -- - djm@cvs.openbsd.org 2014/04/01 03:34:10 -- [sshconnect.c] -- When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any -- certificate keys to plain keys and attempt SSHFP resolution. -- -- Prevents a server from skipping SSHFP lookup and forcing a new-hostkey -- dialog by offering only certificate keys. -- -- Reported by mcv21 AT cam.ac.uk -+ - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] -+ OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 -+ key exchange incorrectly, causing connection failures about 0.2% of -+ the time when this method is used against a peer that implements -+ the method properly. -+ -+ Fix the problem and disable the curve25519 KEX when speaking to -+ OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 -+ to enable the compatability code. -+ -+ - djm@cvs.openbsd.org 2014/04/01 03:34:10 -+ [sshconnect.c] -+ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any -+ certificate keys to plain keys and attempt SSHFP resolution. -+ -+ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey -+ dialog by offering only certificate keys. -+ -+ Reported by mcv21 AT cam.ac.uk - - 20140313 - - (djm) Release OpenSSH 6.6 -diff --git a/bufaux.c b/bufaux.c -index e24b5fc..f6a6f2a 100644 ---- a/bufaux.c -+++ b/bufaux.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */ -+/* $OpenBSD: bufaux.c,v 1.57 2014/04/16 23:22:45 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -372,6 +372,9 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) - - if (l > 8 * 1024) - fatal("%s: length %u too long", __func__, l); -+ /* Skip leading zero bytes */ -+ for (; l > 0 && *s == 0; l--, s++) -+ ; - p = buf = xmalloc(l + 1); - /* - * If most significant bit is set then prepend a zero byte to -diff --git a/compat.c b/compat.c -index 9d9fabe..2709dc5 100644 ---- a/compat.c -+++ b/compat.c -@@ -95,6 +95,9 @@ compat_datafellows(const char *version) - { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, - { "OpenSSH_4*", 0 }, - { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, -+ { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH}, -+ { "OpenSSH_6.5*," -+ "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD}, - { "OpenSSH*", SSH_NEW_OPENSSH }, - { "*MindTerm*", 0 }, - { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| -@@ -251,7 +254,6 @@ compat_cipher_proposal(char *cipher_prop) - return cipher_prop; - } - -- - char * - compat_pkalg_proposal(char *pkalg_prop) - { -@@ -265,3 +267,16 @@ compat_pkalg_proposal(char *pkalg_prop) - return pkalg_prop; - } - -+char * -+compat_kex_proposal(char *kex_prop) -+{ -+ if (!(datafellows & SSH_BUG_CURVE25519PAD)) -+ return kex_prop; -+ debug2("%s: original KEX proposal: %s", __func__, kex_prop); -+ kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org"); -+ debug2("%s: compat KEX proposal: %s", __func__, kex_prop); -+ if (*kex_prop == '\0') -+ fatal("No supported key exchange algorithms found"); -+ return kex_prop; -+} -+ -diff --git a/compat.h b/compat.h -index b174fa1..a6c3f3d 100644 ---- a/compat.h -+++ b/compat.h -@@ -59,6 +59,7 @@ - #define SSH_BUG_RFWD_ADDR 0x02000000 - #define SSH_NEW_OPENSSH 0x04000000 - #define SSH_BUG_DYNAMIC_RPORT 0x08000000 -+#define SSH_BUG_CURVE25519PAD 0x10000000 - - void enable_compat13(void); - void enable_compat20(void); -@@ -66,6 +67,7 @@ void compat_datafellows(const char *); - int proto_spec(const char *); - char *compat_cipher_proposal(char *); - char *compat_pkalg_proposal(char *); -+char *compat_kex_proposal(char *); - - extern int compat13; - extern int compat20; -diff --git a/sshconnect2.c b/sshconnect2.c -index bb9292f..b00658b 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -220,6 +220,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - } - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; -+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( -+ myproposal[PROPOSAL_KEX_ALGS]); - - #ifdef GSSAPI - /* If we've got GSSAPI algorithms, then we also support the -diff --git a/sshd.c b/sshd.c -index e4e406e..512c7ed 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2488,6 +2488,9 @@ do_ssh2_kex(void) - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; - -+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( -+ myproposal[PROPOSAL_KEX_ALGS]); -+ - if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits((u_int32_t)options.rekey_limit, - (time_t)options.rekey_interval); -diff --git a/version.h b/version.h -index a1579ac..a33e77c 100644 ---- a/version.h -+++ b/version.h -@@ -1,6 +1,6 @@ - /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ - --#define SSH_VERSION "OpenSSH_6.6" -+#define SSH_VERSION "OpenSSH_6.6.1" - - #define SSH_PORTABLE "p1" - #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-6.1p1-askpass-ld.patch b/openssh-6.1p1-askpass-ld.patch deleted file mode 100644 index f7a7fac..0000000 --- a/openssh-6.1p1-askpass-ld.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile ---- openssh-6.1p1/contrib/Makefile.askpass-ld 2012-05-19 07:24:37.000000000 +0200 -+++ openssh-6.1p1/contrib/Makefile 2012-09-14 20:35:47.565704718 +0200 -@@ -4,12 +4,12 @@ all: - @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" - - gnome-ssh-askpass1: gnome-ssh-askpass1.c -- $(CC) `gnome-config --cflags gnome gnomeui` \ -+ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \ - gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ - `gnome-config --libs gnome gnomeui` - - gnome-ssh-askpass2: gnome-ssh-askpass2.c -- $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \ -+ $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \ - gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ - `$(PKG_CONFIG) --libs gtk+-2.0 x11` - diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index ddccd2c..67769f0 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.2p1/configure.ac.vendor openssh-6.2p1/configure.ac ---- openssh-6.2p1/configure.ac.vendor 2013-03-25 19:34:01.277495179 +0100 -+++ openssh-6.2p1/configure.ac 2013-03-25 19:34:01.377495818 +0100 -@@ -4420,6 +4420,12 @@ AC_ARG_WITH([lastlog], +diff -up openssh-6.8p1/configure.ac.vendor openssh-6.8p1/configure.ac +--- openssh-6.8p1/configure.ac.vendor 2015-03-18 11:17:56.670880303 +0100 ++++ openssh-6.8p1/configure.ac 2015-03-18 11:17:56.695880243 +0100 +@@ -4743,6 +4743,12 @@ AC_ARG_WITH([lastlog], fi ] ) @@ -14,7 +14,7 @@ diff -up openssh-6.2p1/configure.ac.vendor openssh-6.2p1/configure.ac dnl lastlog, [uw]tmpx? detection dnl NOTE: set the paths in the platform section to avoid the -@@ -4681,6 +4687,7 @@ echo " Translate v4 in v6 hack +@@ -5005,6 +5011,7 @@ echo " Translate v4 in v6 hack echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -22,10 +22,10 @@ diff -up openssh-6.2p1/configure.ac.vendor openssh-6.2p1/configure.ac echo "" -diff -up openssh-6.2p1/servconf.c.vendor openssh-6.2p1/servconf.c ---- openssh-6.2p1/servconf.c.vendor 2013-03-25 19:34:01.197494668 +0100 -+++ openssh-6.2p1/servconf.c 2013-03-25 19:34:01.379495831 +0100 -@@ -128,6 +128,7 @@ initialize_server_options(ServerOptions +diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.vendor 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 11:19:16.279691126 +0100 +@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; @@ -33,26 +33,25 @@ diff -up openssh-6.2p1/servconf.c.vendor openssh-6.2p1/servconf.c options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; -@@ -287,6 +288,9 @@ fill_default_server_options(ServerOption +@@ -327,6 +328,8 @@ fill_default_server_options(ServerOption options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); + if (options->show_patchlevel == -1) + options->show_patchlevel = 0; -+ - /* Turn privilege separation on by default */ - if (use_privsep == -1) - use_privsep = PRIVSEP_NOSANDBOX; -@@ -324,7 +328,7 @@ typedef enum { + if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) + options->fwd_opts.streamlocal_bind_mask = 0177; + if (options->fwd_opts.streamlocal_bind_unlink == -1) +@@ -388,7 +391,7 @@ typedef enum { sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, sMaxSessions, + sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, + sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, - sBanner, sUseDNS, sHostbasedAuthentication, + sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -@@ -439,6 +443,7 @@ static struct { +@@ -504,6 +507,7 @@ static struct { { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, @@ -60,7 +59,7 @@ diff -up openssh-6.2p1/servconf.c.vendor openssh-6.2p1/servconf.c { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1163,6 +1168,10 @@ process_server_config_line(ServerOptions +@@ -1320,6 +1324,10 @@ process_server_config_line(ServerOptions multistate_ptr = multistate_privsep; goto parse_multistate; @@ -71,18 +70,18 @@ diff -up openssh-6.2p1/servconf.c.vendor openssh-6.2p1/servconf.c case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -1950,6 +1959,7 @@ dump_config(ServerOptions *o) +@@ -2145,6 +2153,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); - dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); + dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); + dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -diff -up openssh-6.2p1/servconf.h.vendor openssh-6.2p1/servconf.h ---- openssh-6.2p1/servconf.h.vendor 2013-01-09 05:56:45.000000000 +0100 -+++ openssh-6.2p1/servconf.h 2013-03-25 19:34:01.379495831 +0100 -@@ -147,6 +147,7 @@ typedef struct { + dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); +diff -up openssh-6.8p1/servconf.h.vendor openssh-6.8p1/servconf.h +--- openssh-6.8p1/servconf.h.vendor 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/servconf.h 2015-03-18 11:17:56.696880241 +0100 +@@ -151,6 +151,7 @@ typedef struct { int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ @@ -90,21 +89,43 @@ diff -up openssh-6.2p1/servconf.h.vendor openssh-6.2p1/servconf.h int use_dns; int client_alive_interval; /* * poke the client this often to -diff -up openssh-6.2p1/sshd_config.vendor openssh-6.2p1/sshd_config ---- openssh-6.2p1/sshd_config.vendor 2013-03-25 19:34:01.380495837 +0100 -+++ openssh-6.2p1/sshd_config 2013-03-25 19:44:43.471296362 +0100 -@@ -118,6 +118,7 @@ UsePrivilegeSeparation sandbox # Defaul +diff -up openssh-6.8p1/sshd.c.vendor openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.vendor 2015-03-18 11:17:56.669880305 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 11:17:56.697880239 +0100 +@@ -431,7 +431,7 @@ sshd_exchange_identification(int sock_in + } + + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", +- major, minor, SSH_VERSION, ++ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + *options.version_addendum == '\0' ? "" : " ", + options.version_addendum, newline); + +@@ -1737,7 +1737,8 @@ main(int ac, char **av) + exit(1); + } + +- debug("sshd version %s, %s", SSH_VERSION, ++ debug("sshd version %s, %s", ++ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + #ifdef WITH_OPENSSL + SSLeay_version(SSLEAY_VERSION) + #else +diff -up openssh-6.8p1/sshd_config.vendor openssh-6.8p1/sshd_config +--- openssh-6.8p1/sshd_config.vendor 2015-03-18 11:17:56.697880239 +0100 ++++ openssh-6.8p1/sshd_config 2015-03-18 11:20:15.552550274 +0100 +@@ -119,6 +119,7 @@ UsePrivilegeSeparation sandbox # Defaul #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 +#ShowPatchLevel no - #UseDNS yes + #UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 -diff -up openssh-6.2p1/sshd_config.0.vendor openssh-6.2p1/sshd_config.0 ---- openssh-6.2p1/sshd_config.0.vendor 2013-03-25 19:34:01.361495716 +0100 -+++ openssh-6.2p1/sshd_config.0 2013-03-25 19:34:01.381495844 +0100 -@@ -595,6 +595,11 @@ DESCRIPTION +diff -up openssh-6.8p1/sshd_config.0.vendor openssh-6.8p1/sshd_config.0 +--- openssh-6.8p1/sshd_config.0.vendor 2015-03-18 11:17:56.691880253 +0100 ++++ openssh-6.8p1/sshd_config.0 2015-03-18 11:17:56.697880239 +0100 +@@ -740,6 +740,11 @@ DESCRIPTION Defines the number of bits in the ephemeral protocol version 1 server key. The minimum value is 512, and the default is 1024. @@ -113,13 +134,13 @@ diff -up openssh-6.2p1/sshd_config.0.vendor openssh-6.2p1/sshd_config.0 + the binary in the server identification string. The patch level + is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^]. + - StrictModes - Specifies whether sshd(8) should check file modes and ownership - of the user's files and home directory before accepting login. -diff -up openssh-6.2p1/sshd_config.5.vendor openssh-6.2p1/sshd_config.5 ---- openssh-6.2p1/sshd_config.5.vendor 2013-03-25 19:34:01.362495722 +0100 -+++ openssh-6.2p1/sshd_config.5 2013-03-25 19:34:01.382495850 +0100 -@@ -1019,6 +1019,14 @@ This option applies to protocol version + StreamLocalBindMask + Sets the octal file creation mode mask (umask) used when creating + a Unix-domain socket file for local or remote port forwarding. +diff -up openssh-6.8p1/sshd_config.5.vendor openssh-6.8p1/sshd_config.5 +--- openssh-6.8p1/sshd_config.5.vendor 2015-03-18 11:17:56.691880253 +0100 ++++ openssh-6.8p1/sshd_config.5 2015-03-18 11:17:56.697880239 +0100 +@@ -1276,6 +1276,13 @@ This option applies to protocol version .It Cm ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. The minimum value is 512, and the default is 1024. @@ -130,29 +151,6 @@ diff -up openssh-6.2p1/sshd_config.5.vendor openssh-6.2p1/sshd_config.5 +The patch level is set at compile-time. +The default is +.Dq no . -+This option applies to protocol version 1 only. - .It Cm StrictModes - Specifies whether - .Xr sshd 8 -diff -up openssh-6.2p1/sshd.c.vendor openssh-6.2p1/sshd.c ---- openssh-6.2p1/sshd.c.vendor 2013-03-25 19:34:01.332495531 +0100 -+++ openssh-6.2p1/sshd.c 2013-03-25 19:44:11.864112092 +0100 -@@ -442,7 +442,7 @@ sshd_exchange_identification(int sock_in - } - - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", -- major, minor, SSH_VERSION, -+ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - *options.version_addendum == '\0' ? "" : " ", - options.version_addendum, newline); - -@@ -1675,7 +1675,8 @@ main(int ac, char **av) - exit(1); - } - -- debug("sshd version %s, %s", SSH_VERSION, -+ debug("sshd version %s, %s", -+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - SSLeay_version(SSLEAY_VERSION)); - - /* Store privilege separation user for later use if required. */ + .It Cm StreamLocalBindMask + Sets the octal file creation mode mask + .Pq umask diff --git a/openssh-6.4p1-CLOCK_BOOTTIME.patch b/openssh-6.4p1-CLOCK_BOOTTIME.patch deleted file mode 100644 index 1073a77..0000000 --- a/openssh-6.4p1-CLOCK_BOOTTIME.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/misc.c -+++ b/misc.c -@@ -865,17 +865,24 @@ ms_to_timeval(struct timeval *tv, int ms - time_t - monotime(void) - { --#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) -+#if defined(HAVE_CLOCK_GETTIME) && \ -+ (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) - struct timespec ts; - static int gettime_failed = 0; - - if (!gettime_failed) { -+#if defined(CLOCK_BOOTTIME) -+ if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) -+ return (ts.tv_sec); -+#endif -+#if defined(CLOCK_MONOTONIC) - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) - return (ts.tv_sec); -+#endif - debug3("clock_gettime: %s", strerror(errno)); - gettime_failed = 1; - } --#endif -+#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ - - return time(NULL); - } diff --git a/openssh-6.6.1p1-NI_MAXHOST.patch b/openssh-6.6.1p1-NI_MAXHOST.patch deleted file mode 100644 index 7eeee50..0000000 --- a/openssh-6.6.1p1-NI_MAXHOST.patch +++ /dev/null @@ -1,76 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index 928999d..3887495 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,10 @@ -+20140703 -+ - OpenBSD CVS Sync -+ - djm@cvs.openbsd.org 2014/07/03 03:34:09 -+ [gss-serv.c session.c ssh-keygen.c] -+ standardise on NI_MAXHOST for gethostname() string lengths; about -+ 1/2 the cases were using it already. Fixes bz#2239 en passant -+ - 20140420 - - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] - OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 -diff --git a/gss-serv.c b/gss-serv.c -index 14f540e..29916d3 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */ -+/* $OpenBSD: gss-serv.c,v 1.27 2014/07/03 03:34:09 djm Exp $ */ - - /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. -@@ -102,14 +102,14 @@ static OM_uint32 - ssh_gssapi_acquire_cred(Gssctxt *ctx) - { - OM_uint32 status; -- char lname[MAXHOSTNAMELEN]; -+ char lname[NI_MAXHOST]; - gss_OID_set oidset; - - if (options.gss_strict_acceptor) { - gss_create_empty_oid_set(&status, &oidset); - gss_add_oid_set_member(&status, ctx->oid, &oidset); - -- if (gethostname(lname, MAXHOSTNAMELEN)) { -+ if (gethostname(lname, sizeof(lname))) { - gss_release_oid_set(&status, &oidset); - return (-1); - } -diff --git a/session.c b/session.c -index ba4589b..e4add93 100644 ---- a/session.c -+++ b/session.c -@@ -49,6 +49,7 @@ - #include - #include - #include -+#include - #ifdef HAVE_PATHS_H - #include - #endif -@@ -2669,7 +2670,7 @@ session_setup_x11fwd(Session *s) - { - struct stat st; - char display[512], auth_display[512]; -- char hostname[MAXHOSTNAMELEN]; -+ char hostname[NI_MAXHOST]; - u_int i; - - if (no_x11_forwarding_flag) { -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 482dc1c..66198e6 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -165,7 +165,7 @@ int rounds = 0; - /* argv0 */ - extern char *__progname; - --char hostname[MAXHOSTNAMELEN]; -+char hostname[NI_MAXHOST]; - - /* moduli.c */ - int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); diff --git a/openssh-6.6.1p1-audit-pfs.patch b/openssh-6.6.1p1-audit-pfs.patch deleted file mode 100644 index a2b6d75..0000000 --- a/openssh-6.6.1p1-audit-pfs.patch +++ /dev/null @@ -1,212 +0,0 @@ -diff --git a/audit-bsm.c b/audit-bsm.c -index 5160869..c7a1b47 100644 ---- a/audit-bsm.c -+++ b/audit-bsm.c -@@ -481,7 +481,7 @@ audit_unsupported_body(int what) - } - - void --audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid) -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) - { - /* not implemented */ - } -diff --git a/audit-linux.c b/audit-linux.c -index 6954fc1..6686f6a 100644 ---- a/audit-linux.c -+++ b/audit-linux.c -@@ -297,7 +297,7 @@ audit_unsupported_body(int what) - const static char *direction[] = { "from-server", "from-client", "both" }; - - void --audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, - uid_t uid) - { - #ifdef AUDIT_CRYPTO_SESSION -@@ -306,8 +306,8 @@ audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, - Cipher *cipher = cipher_by_name(enc); - char *s; - -- snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -- direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, - (intmax_t)pid, (intmax_t)uid, - get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); - free(s); -diff --git a/audit.c b/audit.c -index 13c6849..5b49434 100644 ---- a/audit.c -+++ b/audit.c -@@ -135,9 +135,9 @@ audit_unsupported(int what) - } - - void --audit_kex(int ctos, char *enc, char *mac, char *comp) -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) - { -- PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); - } - - void -@@ -270,11 +270,11 @@ audit_unsupported_body(int what) - * This will be called on succesfull protocol negotiation. - */ - void --audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, - uid_t uid) - { -- debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u", -- (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, -+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, - (unsigned)uid); - } - -diff --git a/audit.h b/audit.h -index a2dc3ff..903df66 100644 ---- a/audit.h -+++ b/audit.h -@@ -61,9 +61,9 @@ ssh_audit_event_t audit_classify_auth(const char *); - int audit_keyusage(int, const char *, unsigned, char *, int); - void audit_key(int, int *, const Key *); - void audit_unsupported(int); --void audit_kex(int, char *, char *, char *); -+void audit_kex(int, char *, char *, char *, char *); - void audit_unsupported_body(int); --void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); - void audit_session_key_free(int ctos); - void audit_session_key_free_body(int ctos, pid_t, uid_t); - void audit_destroy_sensitive_data(const char *, pid_t, uid_t); -diff --git a/auditstub.c b/auditstub.c -index 45817e0..116f460 100644 ---- a/auditstub.c -+++ b/auditstub.c -@@ -35,7 +35,7 @@ audit_unsupported(int n) - } - - void --audit_kex(int ctos, char *enc, char *mac, char *comp) -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) - { - } - -diff --git a/kex.c b/kex.c -index ede7b67..eb5f333 100644 ---- a/kex.c -+++ b/kex.c -@@ -553,13 +553,12 @@ kex_choose_conf(Kex *kex) - newkeys->enc.name, - authlen == 0 ? newkeys->mac.name : "", - newkeys->comp.name); --#ifdef SSH_AUDIT_EVENTS -- audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); --#endif - } -+ - choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); - choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); -+ - need = dh_need = 0; - for (mode = 0; mode < MODE_MAX; mode++) { - newkeys = kex->newkeys[mode]; -@@ -571,11 +570,16 @@ kex_choose_conf(Kex *kex) - dh_need = MAX(dh_need, newkeys->enc.block_size); - dh_need = MAX(dh_need, newkeys->enc.iv_len); - dh_need = MAX(dh_need, newkeys->mac.key_len); -+ debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); -+#ifdef SSH_AUDIT_EVENTS -+ audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); -+#endif - } - /* XXX need runden? */ - kex->we_need = need; - kex->dh_need = dh_need; - -+ - /* ignore the next message if the proposals do not match */ - if (first_kex_follows && !proposals_match(my, peer) && - !(datafellows & SSH_BUG_FIRSTKEX)) { -diff --git a/monitor.c b/monitor.c -index 70b9b4c..81bc9c1 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -2396,7 +2396,7 @@ int - mm_answer_audit_kex_body(int sock, Buffer *m) - { - int ctos, len; -- char *cipher, *mac, *compress; -+ char *cipher, *mac, *compress, *pfs; - pid_t pid; - uid_t uid; - -@@ -2404,14 +2404,16 @@ mm_answer_audit_kex_body(int sock, Buffer *m) - cipher = buffer_get_string(m, &len); - mac = buffer_get_string(m, &len); - compress = buffer_get_string(m, &len); -+ pfs = buffer_get_string(m, &len); - pid = buffer_get_int64(m); - uid = buffer_get_int64(m); - -- audit_kex_body(ctos, cipher, mac, compress, pid, uid); -+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); - - free(cipher); - free(mac); - free(compress); -+ free(pfs); - buffer_clear(m); - - mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 93f6535..69b29d8 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -1408,7 +1408,7 @@ mm_audit_unsupported_body(int what) - } - - void --mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, - uid_t uid) - { - Buffer m; -@@ -1418,6 +1418,7 @@ mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, - buffer_put_cstring(&m, cipher); - buffer_put_cstring(&m, (mac ? mac : "")); - buffer_put_cstring(&m, compress); -+ buffer_put_cstring(&m, fps); - buffer_put_int64(&m, pid); - buffer_put_int64(&m, uid); - -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 4cf0c78..e43109f 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -83,7 +83,7 @@ void mm_audit_event(ssh_audit_event_t); - int mm_audit_run_command(const char *); - void mm_audit_end_command(int, const char *); - void mm_audit_unsupported_body(int); --void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); -+void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); - void mm_audit_session_key_free_body(int, pid_t, uid_t); - void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); - #endif -diff --git a/sshd.c b/sshd.c -index ee94825..41a94a7 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2430,7 +2430,7 @@ do_ssh1_kex(void) - packet_disconnect("IP Spoofing check bytes do not match."); - - #ifdef SSH_AUDIT_EVENTS -- audit_kex(2, cipher_name(cipher_type), "crc", "none"); -+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); - #endif - - debug("Encryption type: %.200s", cipher_name(cipher_type)); diff --git a/openssh-6.6.1p1-cisco-dh-keys.patch b/openssh-6.6.1p1-cisco-dh-keys.patch index 0763b10..6890c05 100644 --- a/openssh-6.6.1p1-cisco-dh-keys.patch +++ b/openssh-6.6.1p1-cisco-dh-keys.patch @@ -1,7 +1,6 @@ -diff --git a/compat.c b/compat.c -index 2709dc5..7412a54 100644 ---- a/compat.c -+++ b/compat.c +diff -up openssh-6.8p1/compat.c.cisco-dh openssh-6.8p1/compat.c +--- openssh-6.8p1/compat.c.cisco-dh 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/compat.c 2015-03-19 12:57:58.862606969 +0100 @@ -167,6 +167,7 @@ compat_datafellows(const char *version) SSH_BUG_SCANNER }, { "Probe-*", @@ -10,10 +9,9 @@ index 2709dc5..7412a54 100644 { NULL, 0 } }; -diff --git a/compat.h b/compat.h -index a6c3f3d..d8def7d 100644 ---- a/compat.h -+++ b/compat.h +diff -up openssh-6.8p1/compat.h.cisco-dh openssh-6.8p1/compat.h +--- openssh-6.8p1/compat.h.cisco-dh 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/compat.h 2015-03-19 12:57:58.862606969 +0100 @@ -60,6 +60,7 @@ #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 @@ -22,49 +20,35 @@ index a6c3f3d..d8def7d 100644 void enable_compat13(void); void enable_compat20(void); -diff --git a/kexgexc.c b/kexgexc.c -index 355b7ba..0a91bdd 100644 ---- a/kexgexc.c -+++ b/kexgexc.c -@@ -58,20 +58,37 @@ kexgex_client(Kex *kex) - int min, max, nbits; - DH *dh; +diff -up openssh-6.8p1/kexgexc.c.cisco-dh openssh-6.8p1/kexgexc.c +--- openssh-6.8p1/kexgexc.c.cisco-dh 2015-03-19 12:57:58.862606969 +0100 ++++ openssh-6.8p1/kexgexc.c 2015-03-19 13:11:52.320519969 +0100 +@@ -64,8 +64,27 @@ kexgex_client(struct ssh *ssh) -+ min = DH_GRP_MIN; -+ max = DH_GRP_MAX; + kex->min = DH_GRP_MIN; + kex->max = DH_GRP_MAX; + + /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. + * We need to also ensure that min < nbits < max */ + + if (datafellows & SSH_BUG_MAX4096DH) { + /* The largest min for these servers is 4096 */ -+ min = MIN(min, 4096); ++ kex->min = MIN(kex->min, 4096); + } + - nbits = dh_estimate(kex->dh_need * 8); -+ nbits = MIN(nbits, max); -+ nbits = MAX(nbits, min); + kex->nbits = nbits; +- if (ssh->compat & SSH_OLD_DHGEX) { ++ kex->nbits = MIN(nbits, kex->max); ++ kex->nbits = MAX(nbits, kex->min); + -+ if (datafellows & SSH_BUG_MAX4096DH) { ++ if (ssh->compat & SSH_BUG_MAX4096DH) { + /* Cannot have a nbits > 4096 for these servers */ -+ nbits = MIN(nbits, 4096); ++ kex->nbits = MIN(kex->nbits, 4096); + /* nbits has to be powers of two */ -+ if (nbits == 3072) -+ nbits = 4096; ++ if (kex->nbits == 3072) ++ kex->nbits = 4096; + } - - if (datafellows & SSH_OLD_DHGEX) { ++ if (ssh->compat & SSH_OLD_DHGEX) { /* Old GEX request */ /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); -- min = DH_GRP_MIN; -- max = DH_GRP_MAX; - - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); - } else { - /* New GEX request */ -- min = DH_GRP_MIN; -- max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); - packet_put_int(nbits); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)) + != 0 || diff --git a/openssh-6.6.1p1-coverity.patch b/openssh-6.6.1p1-coverity.patch deleted file mode 100644 index 9f71f9c..0000000 --- a/openssh-6.6.1p1-coverity.patch +++ /dev/null @@ -1,844 +0,0 @@ -diff --git a/auth-pam.c b/auth-pam.c -index cd1a775..690711e 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void **value) - if (sshpam_thread_status != -1) - return (sshpam_thread_status); - signal(SIGCHLD, sshpam_oldsig); -- waitpid(thread, &status, 0); -+ while (waitpid(thread, &status, 0) < 0) { -+ if (errno == EINTR) -+ continue; -+ fatal("%s: waitpid: %s", __func__, -+ strerror(errno)); -+ } - return (status); - } - #endif -diff --git a/channels.c b/channels.c -index af3fdc2..39c9f89 100644 ---- a/channels.c -+++ b/channels.c -@@ -233,11 +233,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, - channel_max_fd = MAX(channel_max_fd, wfd); - channel_max_fd = MAX(channel_max_fd, efd); - -- if (rfd != -1) -+ if (rfd >= 0) - fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -+ if (wfd >= 0 && wfd != rfd) - fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -+ if (efd >= 0 && efd != rfd && efd != wfd) - fcntl(efd, F_SETFD, FD_CLOEXEC); - - c->rfd = rfd; -@@ -255,11 +255,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, - - /* 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 --git a/clientloop.c b/clientloop.c -index 9c60108..d372b53 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -2081,14 +2081,15 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) - char *rtype; - int want_reply; - int success = 0; -+/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */ - - rtype = packet_get_string(NULL); - want_reply = packet_get_char(); - debug("client_input_global_request: rtype %s want_reply %d", - rtype, want_reply); - if (want_reply) { -- packet_start(success ? -- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); -+ packet_start(/*success ? -+ SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE); - packet_send(); - packet_write_wait(); - } -diff --git a/key.c b/key.c -index a2050f6..6487d81 100644 ---- a/key.c -+++ b/key.c -@@ -880,8 +880,10 @@ key_read(Key *ret, char **cpp) - success = 1; - /*XXXX*/ - key_free(k); -+/*XXXX - if (success != 1) - break; -+XXXX*/ - /* advance cp: skip whitespace and data */ - while (*cp == ' ' || *cp == '\t') - cp++; -diff --git a/monitor.c b/monitor.c -index 3ff62b0..70b9b4c 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -472,7 +472,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) - mm_get_keystate(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) - ; - - close(pmonitor->m_sendfd); -@@ -1254,6 +1254,10 @@ mm_answer_keyallowed(int sock, Buffer *m) - break; - } - } -+ -+ debug3("%s: key %p is %s", -+ __func__, key, allowed ? "allowed" : "not allowed"); -+ - if (key != NULL) - key_free(key); - -@@ -1275,9 +1279,6 @@ mm_answer_keyallowed(int sock, Buffer *m) - free(chost); - } - -- debug3("%s: key %p is %s", -- __func__, key, allowed ? "allowed" : "not allowed"); -- - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 6df236a..93f6535 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -743,10 +743,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) - 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 --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c -index c89f214..80115c2 100644 ---- a/openbsd-compat/bindresvport.c -+++ b/openbsd-compat/bindresvport.c -@@ -58,7 +58,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/packet.c b/packet.c -index f5b122b..1305e87 100644 ---- a/packet.c -+++ b/packet.c -@@ -1234,6 +1234,7 @@ packet_read_poll1(void) - case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); -+ break; - case DEATTACK_DOS_DETECTED: - packet_disconnect("deattack denial of " - "service detected"); -diff --git a/progressmeter.c b/progressmeter.c -index bbbc706..ae6d1aa 100644 ---- a/progressmeter.c -+++ b/progressmeter.c -@@ -65,7 +65,7 @@ static void update_progress_meter(int); - - static time_t start; /* start progress */ - static time_t last_update; /* last progress update */ --static char *file; /* name of the file being transferred */ -+static const char *file; /* name of the file being transferred */ - static off_t start_pos; /* initial position of transfer */ - static off_t end_pos; /* ending position of transfer */ - static off_t cur_pos; /* transfer position as of last refresh */ -@@ -248,7 +248,7 @@ update_progress_meter(int ignore) - } - - void --start_progress_meter(char *f, off_t filesize, off_t *ctr) -+start_progress_meter(const char *f, off_t filesize, off_t *ctr) - { - start = last_update = monotime(); - file = f; -diff --git a/progressmeter.h b/progressmeter.h -index 10bab99..e9ca8f0 100644 ---- a/progressmeter.h -+++ b/progressmeter.h -@@ -23,5 +23,5 @@ - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - --void start_progress_meter(char *, off_t, off_t *); -+void start_progress_meter(const char *, off_t, off_t *); - void stop_progress_meter(void); -diff --git a/scp.c b/scp.c -index 1178a07..d9bc016 100644 ---- a/scp.c -+++ b/scp.c -@@ -155,7 +155,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 --git a/servconf.c b/servconf.c -index 3839928..d482e79 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -1382,7 +1382,7 @@ process_server_config_line(ServerOptions *options, char *line, - 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++) -@@ -1473,8 +1473,9 @@ process_server_config_line(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 2f8e3a0..e03bc6c 100644 ---- a/serverloop.c -+++ b/serverloop.c -@@ -147,13 +147,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 -@@ -161,8 +161,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("notify_done: reading"); - } - -@@ -337,7 +337,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - * If we have buffered data, try to write some of that data - * to the program. - */ -- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) -+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, *writesetp); - } - notify_prepare(*readsetp); -@@ -477,7 +477,7 @@ process_output(fd_set *writeset) - int len; - - /* Write buffered data to program stdin. */ -- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { -+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { - data = buffer_ptr(&stdin_buffer); - dlen = buffer_len(&stdin_buffer); - len = write(fdin, data, dlen); -@@ -590,7 +590,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) - set_nonblock(fdin); - set_nonblock(fdout); - /* we don't have stderr for interactive terminal sessions, see below */ -- if (fderr != -1) -+ if (fderr >= 0) - set_nonblock(fderr); - - if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) -@@ -614,7 +614,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); -- if (fderr != -1) -+ if (fderr >= 0) - max_fd = MAX(max_fd, fderr); - #endif - -@@ -644,7 +644,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) - * If we have received eof, and there is no more pending - * input data, cause a real eof by closing fdin. - */ -- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { -+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { - if (fdin != fdout) - close(fdin); - else -@@ -740,15 +740,15 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) - buffer_free(&stderr_buffer); - - /* Close the file descriptors. */ -- if (fdout != -1) -+ if (fdout >= 0) - close(fdout); - fdout = -1; - fdout_eof = 1; -- if (fderr != -1) -+ if (fderr >= 0) - close(fderr); - fderr = -1; - fderr_eof = 1; -- if (fdin != -1) -+ if (fdin >= 0) - close(fdin); - fdin = -1; - -@@ -947,7 +947,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt) - - debug("Window change received."); - packet_check_eom(); -- if (fdin != -1) -+ if (fdin >= 0) - pty_change_window_size(fdin, row, col, xpixel, ypixel); - } - -@@ -1007,7 +1007,7 @@ server_request_tun(void) - } - - tun = packet_get_int(); -- if (forced_tun_device != -1) { -+ if (forced_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && forced_tun_device != tun) - goto done; - tun = forced_tun_device; -diff --git a/sftp-client.c b/sftp-client.c -index 2f5907c..3a2affd 100644 ---- a/sftp-client.c -+++ b/sftp-client.c -@@ -151,7 +151,7 @@ get_msg(struct sftp_conn *conn, Buffer *m) - } - - static void --send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, -+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, - u_int len) - { - Buffer msg; -@@ -167,7 +167,7 @@ send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, - - static void - send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, -- char *s, u_int len, Attrib *a) -+ const char *s, u_int len, Attrib *a) - { - Buffer msg; - -@@ -429,7 +429,7 @@ sftp_proto_version(struct sftp_conn *conn) - } - - int --do_close(struct sftp_conn *conn, char *handle, u_int handle_len) -+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len) - { - u_int id, status; - Buffer msg; -@@ -454,7 +454,7 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len) - - - static int --do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, -+do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, - SFTP_DIRENT ***dir) - { - Buffer msg; -@@ -577,7 +577,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, - } - - int --do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) -+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) - { - return(do_lsreaddir(conn, path, 0, dir)); - } -@@ -597,7 +597,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) - } - - int --do_rm(struct sftp_conn *conn, char *path) -+do_rm(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -612,7 +612,7 @@ do_rm(struct sftp_conn *conn, char *path) - } - - int --do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) -+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) - { - u_int status, id; - -@@ -628,7 +628,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) - } - - int --do_rmdir(struct sftp_conn *conn, char *path) -+do_rmdir(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -644,7 +644,7 @@ do_rmdir(struct sftp_conn *conn, char *path) - } - - Attrib * --do_stat(struct sftp_conn *conn, char *path, int quiet) -+do_stat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -658,7 +658,7 @@ do_stat(struct sftp_conn *conn, char *path, int quiet) - } - - Attrib * --do_lstat(struct sftp_conn *conn, char *path, int quiet) -+do_lstat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -679,7 +679,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) - - #ifdef notyet - Attrib * --do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) -+do_fstat(struct sftp_conn *conn, const char *handle, u_int handle_len, int quiet) - { - u_int id; - -@@ -692,7 +692,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) - #endif - - int --do_setstat(struct sftp_conn *conn, char *path, Attrib *a) -+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) - { - u_int status, id; - -@@ -709,7 +709,7 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a) - } - - int --do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, -+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len, - Attrib *a) - { - u_int status, id; -@@ -726,7 +726,7 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, - } - - char * --do_realpath(struct sftp_conn *conn, char *path) -+do_realpath(struct sftp_conn *conn, const char *path) - { - Buffer msg; - u_int type, expected_id, count, id; -@@ -775,7 +775,7 @@ do_realpath(struct sftp_conn *conn, char *path) - } - - int --do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, -+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, - int force_legacy) - { - Buffer msg; -@@ -811,7 +811,7 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, - } - - int --do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -844,7 +844,7 @@ do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) - } - - int --do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -876,7 +876,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) - } - - int --do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) -+do_fsync(struct sftp_conn *conn, const char *handle, u_int handle_len) - { - Buffer msg; - u_int status, id; -@@ -907,7 +907,7 @@ do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) - - #ifdef notyet - char * --do_readlink(struct sftp_conn *conn, char *path) -+do_readlink(struct sftp_conn *conn, const char *path) - { - Buffer msg; - u_int type, expected_id, count, id; -@@ -1010,7 +1010,7 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, - - static void - send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, -- u_int len, char *handle, u_int handle_len) -+ u_int len, const char *handle, u_int handle_len) - { - Buffer msg; - -@@ -1026,7 +1026,7 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, - } - - int --do_download(struct sftp_conn *conn, char *remote_path, char *local_path, -+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, - Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) - { - Attrib junk; -@@ -1308,7 +1308,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, - } - - static int --download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, -+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, - Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, - int fsync_flag) - { -@@ -1400,7 +1400,7 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, - } - - int --download_dir(struct sftp_conn *conn, char *src, char *dst, -+download_dir(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int preserve_flag, int print_flag, - int resume_flag, int fsync_flag) - { -@@ -1419,7 +1419,7 @@ download_dir(struct sftp_conn *conn, char *src, char *dst, - } - - int --do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, -+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, - int preserve_flag, int fsync_flag) - { - int local_fd; -@@ -1607,7 +1607,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, - } - - static int --upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, -+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, - int preserve_flag, int print_flag, int fsync_flag) - { - int ret = 0, status; -@@ -1700,7 +1700,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, - } - - int --upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, -+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, - int print_flag, int fsync_flag) - { - char *dst_canon; -@@ -1719,7 +1719,7 @@ upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, - } - - char * --path_append(char *p1, char *p2) -+path_append(const char *p1, const char *p2) - { - char *ret; - size_t len = strlen(p1) + strlen(p2) + 2; -diff --git a/sftp-client.h b/sftp-client.h -index ba92ad0..c085423 100644 ---- a/sftp-client.h -+++ b/sftp-client.h -@@ -56,79 +56,79 @@ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); - u_int sftp_proto_version(struct sftp_conn *); - - /* Close file referred to by 'handle' */ --int do_close(struct sftp_conn *, char *, u_int); -+int do_close(struct sftp_conn *, const char *, u_int); - - /* Read contents of 'path' to NULL-terminated array 'dir' */ --int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); -+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); - - /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ - void free_sftp_dirents(SFTP_DIRENT **); - - /* Delete file 'path' */ --int do_rm(struct sftp_conn *, char *); -+int do_rm(struct sftp_conn *, const char *); - - /* Create directory 'path' */ --int do_mkdir(struct sftp_conn *, char *, Attrib *, int); -+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); - - /* Remove directory 'path' */ --int do_rmdir(struct sftp_conn *, char *); -+int do_rmdir(struct sftp_conn *, const char *); - - /* Get file attributes of 'path' (follows symlinks) */ --Attrib *do_stat(struct sftp_conn *, char *, int); -+Attrib *do_stat(struct sftp_conn *, const char *, int); - - /* Get file attributes of 'path' (does not follow symlinks) */ --Attrib *do_lstat(struct sftp_conn *, char *, int); -+Attrib *do_lstat(struct sftp_conn *, const char *, int); - - /* Set file attributes of 'path' */ --int do_setstat(struct sftp_conn *, char *, Attrib *); -+int do_setstat(struct sftp_conn *, const char *, Attrib *); - - /* Set file attributes of open file 'handle' */ --int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); -+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *); - - /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, char *); -+char *do_realpath(struct sftp_conn *, const char *); - - /* Get statistics for filesystem hosting file at "path" */ - int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); - - /* Rename 'oldpath' to 'newpath' */ --int do_rename(struct sftp_conn *, char *, char *m, int force_legacy); -+int do_rename(struct sftp_conn *, const char *, const char *m, int force_legacy); - - /* Link 'oldpath' to 'newpath' */ --int do_hardlink(struct sftp_conn *, char *, char *); -+int do_hardlink(struct sftp_conn *, const char *, const char *); - - /* Rename 'oldpath' to 'newpath' */ --int do_symlink(struct sftp_conn *, char *, char *); -+int do_symlink(struct sftp_conn *, const char *, const char *); - - /* Call fsync() on open file 'handle' */ --int do_fsync(struct sftp_conn *conn, char *, u_int); -+int do_fsync(struct sftp_conn *conn, const char *, u_int); - - /* - * Download 'remote_path' to 'local_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int, int); -+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int); - - /* - * Recursively download 'remote_directory' to 'local_directory'. Preserve - * times if 'pflag' is set - */ --int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, -+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, - int, int, int); - - /* - * Upload 'local_path' to 'remote_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_upload(struct sftp_conn *, char *, char *, int, int); -+int do_upload(struct sftp_conn *, const char *, const char *, int, int); - - /* - * Recursively upload 'local_directory' to 'remote_directory'. Preserve - * times if 'pflag' is set - */ --int upload_dir(struct sftp_conn *, char *, char *, int, int, int); -+int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int); - - /* Concatenate paths, taking care of slashes. Caller must free result. */ --char *path_append(char *, char *); -+char *path_append(const char *, const char *); - - #endif -diff --git a/sftp.c b/sftp.c -index ad1f8c8..3987117 100644 ---- a/sftp.c -+++ b/sftp.c -@@ -218,7 +218,7 @@ killchild(int signo) - { - if (sshpid > 1) { - kill(sshpid, SIGTERM); -- waitpid(sshpid, NULL, 0); -+ (void) waitpid(sshpid, NULL, 0); - } - - _exit(1); -@@ -329,7 +329,7 @@ local_do_ls(const char *args) - - /* Strip one path (usually the pwd) from the start of another */ - static char * --path_strip(char *path, char *strip) -+path_strip(const char *path, const char *strip) - { - size_t len; - -@@ -347,7 +347,7 @@ path_strip(char *path, char *strip) - } - - static char * --make_absolute(char *p, char *pwd) -+make_absolute(char *p, const char *pwd) - { - char *abs_str; - -@@ -545,7 +545,7 @@ parse_no_flags(const char *cmd, char **argv, int argc) - } - - static int --is_dir(char *path) -+is_dir(const char *path) - { - struct stat sb; - -@@ -557,7 +557,7 @@ is_dir(char *path) - } - - static int --remote_is_dir(struct sftp_conn *conn, char *path) -+remote_is_dir(struct sftp_conn *conn, const char *path) - { - Attrib *a; - -@@ -571,7 +571,7 @@ remote_is_dir(struct sftp_conn *conn, char *path) - - /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ - static int --pathname_is_dir(char *pathname) -+pathname_is_dir(const char *pathname) - { - size_t l = strlen(pathname); - -@@ -579,7 +579,7 @@ pathname_is_dir(char *pathname) - } - - static int --process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag, int resume, int fflag) - { - char *abs_src = NULL; -@@ -659,7 +659,7 @@ out: - } - - static int --process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag, int fflag) - { - char *tmp_dst = NULL; -@@ -765,7 +765,7 @@ sdirent_comp(const void *aa, const void *bb) - - /* sftp ls.1 replacement for directories */ - static int --do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) -+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) - { - int n; - u_int c = 1, colspace = 0, columns = 1; -@@ -850,7 +850,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) - - /* sftp ls.1 replacement which handles path globs */ - static int --do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, -+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, - int lflag) - { - char *fname, *lname; -@@ -931,7 +931,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, - } - - static int --do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) -+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) - { - struct sftp_statvfs st; - char s_used[FMT_SCALED_STRSIZE]; -diff --git a/ssh-agent.c b/ssh-agent.c -index 117fdde..2b50132 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1037,8 +1037,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) - /* Disable ptrace on Linux without sgid bit */ -diff --git a/sshd.c b/sshd.c -index 773bb02..1eaa9f7 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -771,8 +771,10 @@ privsep_preauth(Authctxt *authctxt) - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - setproctitle("%s", "[net]"); -- if (box != NULL) -+ if (box != NULL) { - ssh_sandbox_child(box); -+ free(box); -+ } - - return 0; - } -@@ -1439,6 +1441,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) - if (num_listen_socks < 0) - break; - } -+ -+ if (fdset != NULL) -+ free(fdset); - } - - diff --git a/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch b/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch deleted file mode 100644 index 87434ce..0000000 --- a/openssh-6.6.1p1-ignore-SIGXFSZ-in-postauth.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index 3887495..a4dc72f 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,9 @@ -+20140823 -+ - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on -+ lastlog writing on platforms with high UIDs; bz#2263 -+ - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth -+ monitor, not preauth; bz#2263 -+ - 20140703 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/07/03 03:34:09 -diff --git a/monitor.c b/monitor.c -index bdabe21..5a65114 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -501,6 +501,9 @@ monitor_child_postauth(struct monitor *pmonitor) - signal(SIGHUP, &monitor_child_handler); - signal(SIGTERM, &monitor_child_handler); - signal(SIGINT, &monitor_child_handler); -+#ifdef SIGXFSZ -+ signal(SIGXFSZ, SIG_IGN); -+#endif - - if (compat20) { - mon_dispatch = mon_dispatch_postauth20; diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index bccf39b..7590812 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,6 @@ -diff --git a/log.c b/log.c -index 32e1d2e..d4caeb5 100644 ---- a/log.c -+++ b/log.c +diff -up openssh-6.8p1/log.c.log-in-chroot openssh-6.8p1/log.c +--- openssh-6.8p1/log.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/log.c 2015-03-18 12:59:29.694022313 +0100 @@ -241,6 +241,11 @@ debug3(const char *fmt,...) void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) @@ -14,7 +13,7 @@ index 32e1d2e..d4caeb5 100644 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif -@@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) +@@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, Sysl exit(1); } @@ -27,10 +26,9 @@ index 32e1d2e..d4caeb5 100644 log_on_stderr = on_stderr; if (on_stderr) -diff --git a/log.h b/log.h -index ae7df25..30c3310 100644 ---- a/log.h -+++ b/log.h +diff -up openssh-6.8p1/log.h.log-in-chroot openssh-6.8p1/log.h +--- openssh-6.8p1/log.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/log.h 2015-03-18 12:59:29.694022313 +0100 @@ -49,6 +49,7 @@ typedef enum { typedef void (log_handler_fn)(LogLevel, const char *, void *); @@ -39,11 +37,10 @@ index ae7df25..30c3310 100644 void log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); -diff --git a/monitor.c b/monitor.c -index 7461fae..da2f766 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -364,6 +364,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) +diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.log-in-chroot 2015-03-18 12:59:29.669022374 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-18 13:01:52.894671198 +0100 +@@ -357,6 +357,8 @@ monitor_child_preauth(Authctxt *_authctx close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; @@ -52,7 +49,7 @@ index 7461fae..da2f766 100644 authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); -@@ -472,6 +474,8 @@ monitor_child_postauth(struct monitor *pmonitor) +@@ -465,6 +467,8 @@ monitor_child_postauth(struct monitor *p close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; @@ -61,7 +58,7 @@ index 7461fae..da2f766 100644 monitor_set_child_handler(pmonitor->m_pid); signal(SIGHUP, &monitor_child_handler); signal(SIGTERM, &monitor_child_handler); -@@ -552,7 +556,7 @@ monitor_read_log(struct monitor *pmonitor) +@@ -566,7 +570,7 @@ monitor_read_log(struct monitor *pmonito if (log_level_name(level) == NULL) fatal("%s: invalid log level %u (corrupted message?)", __func__, level); @@ -70,8 +67,8 @@ index 7461fae..da2f766 100644 buffer_free(&logmsg); free(msg); -@@ -2083,13 +2087,28 @@ monitor_init(void) - mm_init_compression(mon->m_zlib); +@@ -1998,13 +2002,28 @@ monitor_init(void) + (ssh_packet_comp_free_func *)mm_zfree); } + mon->m_state = ""; @@ -101,13 +98,12 @@ index 7461fae..da2f766 100644 } #ifdef GSSAPI -diff --git a/monitor.h b/monitor.h -index ff79fbb..00c2028 100644 ---- a/monitor.h -+++ b/monitor.h +diff -up openssh-6.8p1/monitor.h.log-in-chroot openssh-6.8p1/monitor.h +--- openssh-6.8p1/monitor.h.log-in-chroot 2015-03-18 12:59:29.695022310 +0100 ++++ openssh-6.8p1/monitor.h 2015-03-18 13:02:56.926514197 +0100 @@ -83,10 +83,11 @@ struct monitor { struct mm_master *m_zlib; - struct Kex **m_pkex; + struct kex **m_pkex; pid_t m_pid; + char *m_state; }; @@ -118,11 +114,10 @@ index ff79fbb..00c2028 100644 void monitor_sync(struct monitor *); struct Authctxt; -diff --git a/session.c b/session.c -index e4add93..bc4a8dd 100644 ---- a/session.c -+++ b/session.c -@@ -160,6 +160,8 @@ login_cap_t *lc; +diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c +--- openssh-6.8p1/session.c.log-in-chroot 2015-03-18 12:59:29.675022359 +0100 ++++ openssh-6.8p1/session.c 2015-03-18 12:59:29.696022308 +0100 +@@ -161,6 +161,8 @@ login_cap_t *lc; static int is_child = 0; @@ -131,7 +126,7 @@ index e4add93..bc4a8dd 100644 /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; static char *auth_sock_dir = NULL; -@@ -523,8 +525,8 @@ do_exec_no_pty(Session *s, const char *command) +@@ -506,8 +508,8 @@ do_exec_no_pty(Session *s, const char *c is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ @@ -142,7 +137,7 @@ index e4add93..bc4a8dd 100644 /* * Create a new session and process group since the 4.4BSD -@@ -692,8 +694,8 @@ do_exec_pty(Session *s, const char *command) +@@ -675,8 +677,8 @@ do_exec_pty(Session *s, const char *comm close(ptymaster); /* Child. Reinitialize the log because the pid has changed. */ @@ -153,7 +148,7 @@ index e4add93..bc4a8dd 100644 /* Close the master side of the pseudo tty. */ close(ptyfd); -@@ -797,6 +799,7 @@ do_exec(Session *s, const char *command) +@@ -780,6 +782,7 @@ do_exec(Session *s, const char *command) int ret; const char *forced = NULL; char session_type[1024], *tty = NULL; @@ -161,7 +156,7 @@ index e4add93..bc4a8dd 100644 if (options.adm_forced_command) { original_command = command; -@@ -854,6 +857,10 @@ do_exec(Session *s, const char *command) +@@ -837,6 +840,10 @@ do_exec(Session *s, const char *command) tty += 5; } @@ -172,7 +167,7 @@ index e4add93..bc4a8dd 100644 verbose("Starting session: %s%s%s for %s from %.200s port %d", session_type, tty == NULL ? "" : " on ", -@@ -1681,14 +1688,6 @@ child_close_fds(void) +@@ -1678,14 +1685,6 @@ child_close_fds(void) * descriptors left by system functions. They will be closed later. */ endpwent(); @@ -187,7 +182,7 @@ index e4add93..bc4a8dd 100644 } /* -@@ -1834,8 +1833,6 @@ do_child(Session *s, const char *command) +@@ -1831,8 +1830,6 @@ do_child(Session *s, const char *command exit(1); } @@ -196,7 +191,7 @@ index e4add93..bc4a8dd 100644 if (!options.use_login) do_rc_files(s, shell); -@@ -1859,9 +1856,17 @@ do_child(Session *s, const char *command) +@@ -1856,9 +1853,17 @@ do_child(Session *s, const char *command argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -215,10 +210,9 @@ index e4add93..bc4a8dd 100644 fflush(NULL); if (options.use_login) { -diff --git a/sftp-server-main.c b/sftp-server-main.c -index 7e644ab..e162b7a 100644 ---- a/sftp-server-main.c -+++ b/sftp-server-main.c +diff -up openssh-6.8p1/sftp-server-main.c.log-in-chroot openssh-6.8p1/sftp-server-main.c +--- openssh-6.8p1/sftp-server-main.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp-server-main.c 2015-03-18 12:59:29.696022308 +0100 @@ -47,5 +47,5 @@ main(int argc, char **argv) return 1; } @@ -226,11 +220,10 @@ index 7e644ab..e162b7a 100644 - 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 b8eb59c..a0e644c 100644 ---- a/sftp-server.c -+++ b/sftp-server.c -@@ -1437,7 +1437,7 @@ sftp_server_usage(void) +diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c +--- openssh-6.8p1/sftp-server.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp-server.c 2015-03-18 13:03:52.510377911 +0100 +@@ -1502,7 +1502,7 @@ sftp_server_usage(void) } int @@ -238,8 +231,8 @@ index b8eb59c..a0e644c 100644 +sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) { fd_set *rset, *wset; - int i, in, out, max, ch, skipargs = 0, log_stderr = 0; -@@ -1450,7 +1450,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) + int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; +@@ -1515,7 +1515,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -248,19 +241,18 @@ index b8eb59c..a0e644c 100644 pw = pwcopy(user_pw); -@@ -1521,7 +1521,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) +@@ -1586,7 +1586,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); - if ((cp = getenv("SSH_CONNECTION")) != NULL) { - client_addr = xstrdup(cp); -diff --git a/sftp.h b/sftp.h -index 2bde8bb..ddf1a39 100644 ---- a/sftp.h -+++ b/sftp.h + #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* +diff -up openssh-6.8p1/sftp.h.log-in-chroot openssh-6.8p1/sftp.h +--- openssh-6.8p1/sftp.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp.h 2015-03-18 12:59:29.696022308 +0100 @@ -97,5 +97,5 @@ struct passwd; @@ -268,11 +260,10 @@ index 2bde8bb..ddf1a39 100644 -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.c b/sshd.c -index 3eee75a..9c00bcb 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -745,7 +745,7 @@ privsep_postauth(Authctxt *authctxt) +diff -up openssh-6.8p1/sshd.c.log-in-chroot openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.log-in-chroot 2015-03-18 12:59:29.691022320 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 12:59:29.697022305 +0100 +@@ -744,7 +744,7 @@ privsep_postauth(Authctxt *authctxt) } /* New socket pair */ @@ -281,7 +272,7 @@ index 3eee75a..9c00bcb 100644 pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -763,6 +763,11 @@ privsep_postauth(Authctxt *authctxt) +@@ -762,6 +762,11 @@ privsep_postauth(Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; diff --git a/openssh-6.6.1p1-partial-success.patch b/openssh-6.6.1p1-partial-success.patch deleted file mode 100644 index b5c61cf..0000000 --- a/openssh-6.6.1p1-partial-success.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/auth2.c b/auth2.c -index d9b440a..ec0bf12 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -355,8 +355,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, - authctxt->success = 1; - } else { - -- /* Allow initial try of "none" auth without failure penalty */ -- if (!authctxt->server_caused_failure && -+ /* Allow initial try of "none" auth without failure penalty -+ * Partial succes is not failure */ -+ if (!authctxt->server_caused_failure && !partial && - (authctxt->attempt > 1 || strcmp(method, "none") != 0)) - authctxt->failures++; - if (authctxt->failures >= options.max_authtries) { diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index a831a15..425ffda 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -1,16 +1,16 @@ diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index 0077dd7..e3f2ced 100644 +index 8f32464..18a2ca4 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -31,6 +31,7 @@ - #include "xmalloc.h" +@@ -32,6 +32,7 @@ + #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ #include "servconf.h" #include "port-linux.h" +#include "misc.h" #include "key.h" #include "hostfile.h" #include "auth.h" -@@ -444,7 +445,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) { @@ -19,7 +19,7 @@ index 0077dd7..e3f2ced 100644 if (!sshd_selinux_enabled()) return; -@@ -460,6 +461,58 @@ sshd_selinux_copy_context(void) +@@ -461,6 +462,58 @@ sshd_selinux_copy_context(void) } } @@ -104,10 +104,10 @@ index cb51f99..8b7cda2 100644 #ifdef LINUX_OOM_ADJUST diff --git a/sshd.c b/sshd.c -index 512c7ed..3eee75a 100644 +index 2871fe9..39b9c08 100644 --- a/sshd.c +++ b/sshd.c -@@ -637,7 +637,7 @@ privsep_preauth_child(void) +@@ -629,7 +629,7 @@ privsep_preauth_child(void) demote_sensitive_data(); #ifdef WITH_SELINUX diff --git a/openssh-6.6.1p1-utf8-banner.patch b/openssh-6.6.1p1-utf8-banner.patch index 1ab8ade..1513b6f 100644 --- a/openssh-6.6.1p1-utf8-banner.patch +++ b/openssh-6.6.1p1-utf8-banner.patch @@ -1,21 +1,19 @@ -diff --git a/Makefile.in b/Makefile.in -index 2ad26ff..0f0d39f 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -81,7 +81,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ +diff -up openssh-6.8p1/Makefile.in.utf8-banner openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.utf8-banner 2015-03-18 12:41:28.174713188 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-18 12:45:52.723048114 +0100 +@@ -94,7 +94,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o krl.o smult_curve25519_ref.o \ - kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ -- ssh-ed25519.o digest-openssl.o hmac.o \ -+ ssh-ed25519.o digest-openssl.o hmac.o utf8_stringprep.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o - - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ -diff --git a/misc.h b/misc.h -index d4df619..d98b83d 100644 ---- a/misc.h -+++ b/misc.h -@@ -106,4 +106,7 @@ char *read_passphrase(const char *, int); + ssh-pkcs11.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ +- ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ ++ ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o utf8_stringprep.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ +diff -up openssh-6.8p1/misc.h.utf8-banner openssh-6.8p1/misc.h +--- openssh-6.8p1/misc.h.utf8-banner 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/misc.h 2015-03-18 12:41:28.175713185 +0100 +@@ -135,4 +135,7 @@ char *read_passphrase(const char *, int) int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); @@ -23,10 +21,9 @@ index d4df619..d98b83d 100644 +int utf8_stringprep(const char *, char *, size_t); + #endif /* _MISC_H */ -diff --git a/sshconnect2.c b/sshconnect2.c -index b00658b..08064f4 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c +diff -up openssh-6.8p1/sshconnect2.c.utf8-banner openssh-6.8p1/sshconnect2.c +--- openssh-6.8p1/sshconnect2.c.utf8-banner 2015-03-18 12:41:28.161713220 +0100 ++++ openssh-6.8p1/sshconnect2.c 2015-03-18 12:44:05.483317714 +0100 @@ -33,6 +33,8 @@ #include @@ -36,8 +33,8 @@ index b00658b..08064f4 100644 #include #include #include -@@ -519,21 +521,51 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) - "type %d", type); +@@ -532,21 +534,51 @@ input_userauth_error(int type, u_int32_t + return 0; } +/* Check whether we can display UTF-8 safely */ @@ -56,7 +53,7 @@ index b00658b..08064f4 100644 +} + /* ARGSUSED */ - void + int input_userauth_banner(int type, u_int32_t seq, void *ctxt) { char *msg, *raw, *lang; @@ -90,11 +87,9 @@ index b00658b..08064f4 100644 fprintf(stderr, "%s", msg); free(msg); } -diff --git a/stringprep-tables.c b/stringprep-tables.c -new file mode 100644 -index 0000000..49f4d9d ---- /dev/null -+++ b/stringprep-tables.c +diff -up openssh-6.8p1/stringprep-tables.c.utf8-banner openssh-6.8p1/stringprep-tables.c +--- openssh-6.8p1/stringprep-tables.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 ++++ openssh-6.8p1/stringprep-tables.c 2015-03-18 12:41:28.175713185 +0100 @@ -0,0 +1,661 @@ +/* Public domain. */ + @@ -757,11 +752,9 @@ index 0000000..49f4d9d + { 0xE0020, 0xE007F }, +}; + -diff --git a/utf8_stringprep.c b/utf8_stringprep.c -new file mode 100644 -index 0000000..bcafae7 ---- /dev/null -+++ b/utf8_stringprep.c +diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringprep.c +--- openssh-6.8p1/utf8_stringprep.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 ++++ openssh-6.8p1/utf8_stringprep.c 2015-03-18 12:41:28.175713185 +0100 @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2013 Damien Miller diff --git a/openssh-6.6p1-CVE-2014-2653.patch b/openssh-6.6p1-CVE-2014-2653.patch deleted file mode 100644 index c3bd0a1..0000000 --- a/openssh-6.6p1-CVE-2014-2653.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index 38de846..1603a07 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,14 @@ -+20140420 -+ - djm@cvs.openbsd.org 2014/04/01 03:34:10 -+ [sshconnect.c] -+ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any -+ certificate keys to plain keys and attempt SSHFP resolution. -+ -+ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey -+ dialog by offering only certificate keys. -+ -+ Reported by mcv21 AT cam.ac.uk -+ - 20140313 - - (djm) Release OpenSSH 6.6 - -diff --git a/sshconnect.c b/sshconnect.c -index 394cca8..e636f33 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -1219,30 +1219,40 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) - { - int flags = 0; - char *fp; -+ Key *plain = NULL; - - fp = key_selected_fingerprint(host_key, SSH_FP_HEX); - debug("Server host key: %s %s%s", key_type(host_key), - key_fingerprint_prefix(), fp); - free(fp); - -- /* XXX certs are not yet supported for DNS */ -- if (!key_is_cert(host_key) && options.verify_host_key_dns && -- verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { -- if (flags & DNS_VERIFY_FOUND) { -- -- if (options.verify_host_key_dns == 1 && -- flags & DNS_VERIFY_MATCH && -- flags & DNS_VERIFY_SECURE) -- return 0; -- -- if (flags & DNS_VERIFY_MATCH) { -- matching_host_key_dns = 1; -- } else { -- warn_changed_key(host_key); -- error("Update the SSHFP RR in DNS with the new " -- "host key to get rid of this message."); -+ if (options.verify_host_key_dns) { -+ /* -+ * XXX certs are not yet supported for DNS, so downgrade -+ * them and try the plain key. -+ */ -+ plain = key_from_private(host_key); -+ if (key_is_cert(plain)) -+ key_drop_cert(plain); -+ if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { -+ if (flags & DNS_VERIFY_FOUND) { -+ if (options.verify_host_key_dns == 1 && -+ flags & DNS_VERIFY_MATCH && -+ flags & DNS_VERIFY_SECURE) { -+ key_free(plain); -+ return 0; -+ } -+ if (flags & DNS_VERIFY_MATCH) { -+ matching_host_key_dns = 1; -+ } else { -+ warn_changed_key(plain); -+ error("Update the SSHFP RR in DNS " -+ "with the new host key to get rid " -+ "of this message."); -+ } - } - } -+ key_free(plain); - } - - return check_host_key(host, hostaddr, options.port, host_key, RDRW, diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index a60d608..cf01dd5 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,16 +1,15 @@ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 0a4930e..a7c0c5f 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +diff -up openssh-6.8p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-6.8p1/gss-serv-krb5.c +--- openssh-6.8p1/gss-serv-krb5.c.GSSAPIEnablek5users 2015-03-18 13:04:21.505306818 +0100 ++++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 13:04:21.527306764 +0100 +@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri FILE *fp; char file[MAXPATHLEN]; - char line[BUFSIZ]; + char line[BUFSIZ] = ""; - char kuser[65]; /* match krb5_kuserok() */ struct stat st; struct passwd *pw = the_authctxt->pw; int found_principal = 0; -@@ -269,7 +268,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +@@ -269,7 +268,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. */ @@ -19,37 +18,36 @@ index 0a4930e..a7c0c5f 100644 return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff --git a/servconf.c b/servconf.c -index d482e79..ad5869b 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -158,6 +158,7 @@ initialize_server_options(ServerOptions *options) - options->ip_qos_bulk = -1; +diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.GSSAPIEnablek5users 2015-03-18 13:04:21.516306791 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 13:05:26.846146608 +0100 +@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions options->version_addendum = NULL; + options->fingerprint_hash = -1; options->use_kuserok = -1; + options->enable_k5users = -1; } - void -@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) - options->show_patchlevel = 0; + /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +@@ -348,6 +349,8 @@ fill_default_server_options(ServerOption + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; if (options->use_kuserok == -1) options->use_kuserok = 1; + if (options->enable_k5users == -1) + options->enable_k5users = 0; - /* Turn privilege separation on by default */ if (use_privsep == -1) -@@ -356,7 +359,7 @@ typedef enum { + use_privsep = PRIVSEP_NOSANDBOX; +@@ -406,7 +409,7 @@ typedef enum { sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -430,6 +433,7 @@ static struct { +@@ -484,6 +487,7 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, @@ -57,7 +55,7 @@ index d482e79..ad5869b 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -437,6 +441,7 @@ static struct { +@@ -491,6 +495,7 @@ static struct { { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, @@ -65,7 +63,7 @@ index d482e79..ad5869b 100644 #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1536,6 +1541,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1623,6 +1628,10 @@ process_server_config_line(ServerOptions intptr = &options->use_kuserok; goto parse_flag; @@ -76,7 +74,7 @@ index d482e79..ad5869b 100644 case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1824,6 +1833,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -1947,6 +1956,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -84,19 +82,18 @@ index d482e79..ad5869b 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2076,6 +2086,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); +@@ -2207,6 +2217,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff --git a/servconf.h b/servconf.h -index 5117dfa..d63cb71 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -173,7 +173,8 @@ typedef struct { +diff -up openssh-6.8p1/servconf.h.GSSAPIEnablek5users openssh-6.8p1/servconf.h +--- openssh-6.8p1/servconf.h.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 ++++ openssh-6.8p1/servconf.h 2015-03-18 13:04:21.528306762 +0100 +@@ -177,7 +177,8 @@ typedef struct { int num_permitted_opens; @@ -106,10 +103,9 @@ index 5117dfa..d63cb71 100644 char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff --git a/sshd_config b/sshd_config -index 43671f6..6ab00ed 100644 ---- a/sshd_config -+++ b/sshd_config +diff -up openssh-6.8p1/sshd_config.GSSAPIEnablek5users openssh-6.8p1/sshd_config +--- openssh-6.8p1/sshd_config.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 ++++ openssh-6.8p1/sshd_config 2015-03-18 13:04:21.528306762 +0100 @@ -94,6 +94,7 @@ GSSAPIAuthentication yes GSSAPICleanupCredentials no #GSSAPIStrictAcceptorCheck yes @@ -118,11 +114,10 @@ index 43671f6..6ab00ed 100644 # 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 e0e5fff..aa9525d 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -505,6 +505,12 @@ on logout. +diff -up openssh-6.8p1/sshd_config.5.GSSAPIEnablek5users openssh-6.8p1/sshd_config.5 +--- openssh-6.8p1/sshd_config.5.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 ++++ openssh-6.8p1/sshd_config.5 2015-03-18 13:04:21.528306762 +0100 +@@ -576,6 +576,12 @@ on logout. The default is .Dq yes . Note that this option applies to protocol version 2 only. diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 1997fa6..6f4f1e8 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -1,7 +1,6 @@ -diff --git a/Makefile.in b/Makefile.in -index 4ab6717..581b121 100644 ---- a/Makefile.in -+++ b/Makefile.in +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 SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper @@ -10,16 +9,16 @@ index 4ab6717..581b121 100644 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ +@@ -66,7 +67,7 @@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) - LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ -@@ -180,6 +181,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o + LIBOPENSSH_OBJS=\ + ssh_api.o \ +@@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) @@ -29,7 +28,7 @@ index 4ab6717..581b121 100644 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -@@ -288,6 +292,7 @@ install-files: +@@ -326,6 +330,7 @@ install-files: $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ fi $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) @@ -37,11 +36,9 @@ index 4ab6717..581b121 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/ctr-cavstest.c b/ctr-cavstest.c -new file mode 100644 -index 0000000..bbcbe8a ---- /dev/null -+++ b/ctr-cavstest.c +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,208 @@ +/* + * diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index 67bd30f..6076165 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -1,8 +1,8 @@ diff --git a/entropy.c b/entropy.c -index 2d483b3..b361a04 100644 +index 1e9d52a..d24e724 100644 --- a/entropy.c +++ b/entropy.c -@@ -234,6 +234,9 @@ seed_rng(void) +@@ -227,6 +227,9 @@ seed_rng(void) memset(buf, '\0', sizeof(buf)); #endif /* OPENSSL_PRNG_ONLY */ @@ -13,12 +13,12 @@ index 2d483b3..b361a04 100644 fatal("PRNG is not seeded"); } diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in -index b912dbe..9206337 100644 +index 843225d..041bbab 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o @@ -27,7 +27,7 @@ index b912dbe..9206337 100644 $(CC) $(CFLAGS) $(CPPFLAGS) -c $< diff --git a/openbsd-compat/port-linux-prng.c b/openbsd-compat/port-linux-prng.c new file mode 100644 -index 0000000..92a617c +index 0000000..da84bf2 --- /dev/null +++ b/openbsd-compat/port-linux-prng.c @@ -0,0 +1,59 @@ @@ -63,6 +63,7 @@ index 0000000..92a617c + +#include "log.h" +#include "xmalloc.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" +#include "port-linux.h" +#include "key.h" @@ -72,10 +73,9 @@ index 0000000..92a617c +void +linux_seed(void) +{ -+ int len; + char *env = getenv("SSH_USE_STRONG_RNG"); + char *random = "/dev/random"; -+ size_t ienv, randlen = 14; ++ size_t len, ienv, randlen = 14; + + if (!env || !strcmp(env, "0")) + random = "/dev/urandom"; @@ -91,7 +91,7 @@ index 0000000..92a617c + } +} diff --git a/ssh-add.0 b/ssh-add.0 -index ba43fee..0b2629a 100644 +index f16165a..17d22cf 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -82,6 +82,16 @@ ENVIRONMENT @@ -112,10 +112,10 @@ index ba43fee..0b2629a 100644 ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of diff --git a/ssh-add.1 b/ssh-add.1 -index 4812448..16305bf 100644 +index 04d1840..db883a4 100644 --- a/ssh-add.1 +++ b/ssh-add.1 -@@ -161,6 +161,20 @@ to make this work.) +@@ -170,6 +170,20 @@ to make this work.) Identifies the path of a .Ux Ns -domain socket used to communicate with the agent. @@ -137,10 +137,10 @@ index 4812448..16305bf 100644 .Sh FILES .Bl -tag -width Ds diff --git a/ssh-agent.1 b/ssh-agent.1 -index 281ecbd..1a9a635 100644 +index d7e791b..7332f0d 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 -@@ -201,6 +201,24 @@ sockets used to contain the connection to the authentication agent. +@@ -189,6 +189,24 @@ sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El @@ -166,10 +166,10 @@ index 281ecbd..1a9a635 100644 .Xr ssh 1 , .Xr ssh-add 1 , diff --git a/ssh-keygen.1 b/ssh-keygen.1 -index 12e00d4..1b51a4a 100644 +index 276dacc..a09d9b1 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 -@@ -832,6 +832,24 @@ Contains Diffie-Hellman groups used for DH-GEX. +@@ -841,6 +841,24 @@ Contains Diffie-Hellman groups used for DH-GEX. The file format is described in .Xr moduli 5 . .El @@ -224,10 +224,10 @@ index 69d0829..02d79f8 100644 .Xr ssh 1 , .Xr ssh-keygen 1 , diff --git a/ssh.1 b/ssh.1 -index 929904b..f65e42f 100644 +index 4a476c2..410a04a 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -1309,6 +1309,23 @@ For more information, see the +@@ -1299,6 +1299,23 @@ For more information, see the .Cm PermitUserEnvironment option in .Xr sshd_config 5 . @@ -252,10 +252,10 @@ index 929904b..f65e42f 100644 .Bl -tag -width Ds -compact .It Pa ~/.rhosts diff --git a/sshd.8 b/sshd.8 -index c2c237f..058d37a 100644 +index cb866b5..adcaaf9 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -951,6 +951,24 @@ concurrently for different ports, this contains the process ID of the one +@@ -945,6 +945,24 @@ concurrently for different ports, this contains the process ID of the one started last). The content of this file is not sensitive; it can be world-readable. .El diff --git a/openssh-6.6p1-fingerprint.patch b/openssh-6.6p1-fingerprint.patch deleted file mode 100644 index c5332fb..0000000 --- a/openssh-6.6p1-fingerprint.patch +++ /dev/null @@ -1,415 +0,0 @@ -diff --git a/auth.c b/auth.c -index 9a36f1d..420a85b 100644 ---- a/auth.c -+++ b/auth.c -@@ -685,9 +685,10 @@ auth_key_is_revoked(Key *key) - case 1: - revoked: - /* Key revoked */ -- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); - error("WARNING: authentication attempt with a revoked " -- "%s key %s ", key_type(key), key_fp); -+ "%s key %s%s ", key_type(key), -+ key_fingerprint_prefix(), key_fp); - free(key_fp); - return 1; - } -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 488008f..eca0069 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -206,16 +206,18 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, - - if (host_status == HOST_OK) { - if (key_is_cert(key)) { -- fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(key->cert->signature_key, -+ SSH_FP_HEX); - verbose("Accepted certificate ID \"%s\" signed by " -- "%s CA %s from %s@%s", key->cert->key_id, -- key_type(key->cert->signature_key), fp, -+ "%s CA %s%s from %s@%s", key->cert->key_id, -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), fp, - cuser, lookup); - } else { -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- verbose("Accepted %s public key %s from %s@%s", -- key_type(key), fp, cuser, lookup); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ verbose("Accepted %s public key %s%s from %s@%s", -+ key_type(key), key_fingerprint_prefix(), -+ fp, cuser, lookup); - } - free(fp); - } -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 0fd27bb..749b11a 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -365,10 +365,10 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) - continue; - if (!key_is_cert_authority) - continue; -- fp = key_fingerprint(found, SSH_FP_MD5, -- SSH_FP_HEX); -- debug("matching CA found: file %s, line %lu, %s %s", -- file, linenum, key_type(found), fp); -+ fp = key_selected_fingerprint(found, SSH_FP_HEX); -+ debug("matching CA found: file %s, line %lu, %s %s%s", -+ file, linenum, key_type(found), -+ key_fingerprint_prefix(), fp); - /* - * If the user has specified a list of principals as - * a key option, then prefer that list to matching -@@ -406,9 +406,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) - if (key_is_cert_authority) - continue; - found_key = 1; -- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); -- debug("matching key found: file %s, line %lu %s %s", -- file, linenum, key_type(found), fp); -+ fp = key_selected_fingerprint(found, SSH_FP_HEX); -+ verbose("Found matching %s key: %s%s", -+ key_type(found), key_fingerprint_prefix(), fp); - free(fp); - break; - } -@@ -431,13 +431,13 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) - if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) - return 0; - -- ca_fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); - - if (key_in_file(key->cert->signature_key, - options.trusted_user_ca_keys, 1) != 1) { -- debug2("%s: CA %s %s is not listed in %s", __func__, -- key_type(key->cert->signature_key), ca_fp, -+ debug2("%s: CA %s%s %s is not listed in %s", __func__, -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), ca_fp, - options.trusted_user_ca_keys); - goto out; - } -diff --git a/key.c b/key.c -index 168e1b7..eb98ea8 100644 ---- a/key.c -+++ b/key.c -@@ -628,6 +628,34 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) - return retval; - } - -+enum fp_type -+key_fingerprint_selection(void) -+{ -+ static enum fp_type rv; -+ static char rv_defined = 0; -+ char *env; -+ -+ if (!rv_defined) { -+ env = getenv("SSH_FINGERPRINT_TYPE"); -+ rv = (env && !strcmp (env, "sha")) ? -+ SSH_FP_SHA1 : SSH_FP_MD5; -+ rv_defined = 1; -+ } -+ return rv; -+} -+ -+char * -+key_selected_fingerprint(Key *k, enum fp_rep dgst_rep) -+{ -+ return key_fingerprint(k, key_fingerprint_selection(), dgst_rep); -+} -+ -+char * -+key_fingerprint_prefix(void) -+{ -+ return key_fingerprint_selection() == SSH_FP_SHA1 ? "sha1:" : ""; -+} -+ - /* - * Reads a multiple-precision integer in decimal from the buffer, and advances - * the pointer. The integer must already be initialized. This function is -diff --git a/key.h b/key.h -index d8ad13d..0e3eea5 100644 ---- a/key.h -+++ b/key.h -@@ -104,6 +104,9 @@ int key_equal_public(const Key *, const Key *); - int key_equal(const Key *, const Key *); - char *key_fingerprint(const Key *, enum fp_type, enum fp_rep); - u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); -+enum fp_type key_fingerprint_selection(void); -+char *key_selected_fingerprint(Key *, enum fp_rep); -+char *key_fingerprint_prefix(void); - const char *key_type(const Key *); - const char *key_cert_type(const Key *); - int key_write(const Key *, FILE *); -diff --git a/ssh-add.c b/ssh-add.c -index 3421452..691949f 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -330,10 +330,10 @@ list_identities(AuthenticationConnection *ac, int do_fp) - key = ssh_get_next_identity(ac, &comment, version)) { - had_identities = 1; - if (do_fp) { -- fp = key_fingerprint(key, SSH_FP_MD5, -- SSH_FP_HEX); -- printf("%d %s %s (%s)\n", -- key_size(key), fp, comment, key_type(key)); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ printf("%d %s%s %s (%s)\n", -+ key_size(key), key_fingerprint_prefix(), -+ fp, comment, key_type(key)); - free(fp); - } else { - if (!key_write(key, stdout)) -diff --git a/ssh-agent.c b/ssh-agent.c -index ba24612..117fdde 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -198,9 +198,9 @@ confirm_key(Identity *id) - char *p; - int ret = -1; - -- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); -- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", -- id->comment, p)) -+ p = key_selected_fingerprint(id->key, SSH_FP_HEX); -+ if (ask_permission("Allow use of key %s?\nKey fingerprint %s%s.", -+ id->comment, key_fingerprint_prefix(), p)) - ret = 0; - free(p); - -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 2a316bc..482dc1c 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -783,13 +783,14 @@ do_fingerprint(struct passwd *pw) - { - FILE *f; - Key *public; -- char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; -+ char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra, *pfx; - int i, skip = 0, num = 0, invalid = 1; - enum fp_rep rep; - enum fp_type fptype; - struct stat st; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); -+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - if (!have_identity) -@@ -801,8 +802,8 @@ do_fingerprint(struct passwd *pw) - public = key_load_public(identity_file, &comment); - if (public != NULL) { - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, comment, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, comment, - key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -867,8 +868,8 @@ do_fingerprint(struct passwd *pw) - } - comment = *cp ? cp : comment; - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, - comment ? comment : "no comment", key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -986,13 +987,15 @@ printhost(FILE *f, const char *name, Key *public, int ca, int hash) - if (print_fingerprint) { - enum fp_rep rep; - enum fp_type fptype; -- char *fp, *ra; -+ char *fp, *ra, *pfx; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); -+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; -+ - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, name, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, name, - key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -1878,16 +1881,17 @@ do_show_cert(struct passwd *pw) - fatal("%s is not a certificate", identity_file); - v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - -- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- ca_fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); - - printf("%s:\n", identity_file); - printf(" Type: %s %s certificate\n", key_ssh_name(key), - key_cert_type(key)); -- printf(" Public key: %s %s\n", key_type(key), key_fp); -- printf(" Signing CA: %s %s\n", -- key_type(key->cert->signature_key), ca_fp); -+ printf(" Public key: %s %s%s\n", key_type(key), -+ key_fingerprint_prefix(), key_fp); -+ printf(" Signing CA: %s %s%s\n", -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), ca_fp); - printf(" Key ID: \"%s\"\n", key->cert->key_id); - if (!v00) { - printf(" Serial: %llu\n", -@@ -2686,13 +2690,12 @@ passphrase_again: - fclose(f); - - if (!quiet) { -- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); -- char *ra = key_fingerprint(public, SSH_FP_MD5, -- SSH_FP_RANDOMART); -+ char *fp = key_selected_fingerprint(public, SSH_FP_HEX); -+ char *ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); - printf("Your public key has been saved in %s.\n", - identity_file); - printf("The key fingerprint is:\n"); -- printf("%s %s\n", fp, comment); -+ printf("%s%s %s\n", key_fingerprint_prefix(), fp, comment); - printf("The key's randomart image is:\n"); - printf("%s\n", ra); - free(ra); -diff --git a/sshconnect.c b/sshconnect.c -index 573d7a8..394cca8 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -914,10 +914,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, - "key for IP address '%.128s' to the list " - "of known hosts.", type, ip); - } else if (options.visual_host_key) { -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(host_key, SSH_FP_MD5, -- SSH_FP_RANDOMART); -- logit("Host key fingerprint is %s\n%s\n", fp, ra); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); -+ logit("Host key fingerprint is %s%s\n%s\n", -+ key_fingerprint_prefix(), fp, ra); - free(ra); - free(fp); - } -@@ -955,9 +955,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, - else - snprintf(msg1, sizeof(msg1), "."); - /* The default */ -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(host_key, SSH_FP_MD5, -- SSH_FP_RANDOMART); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); - msg2[0] = '\0'; - if (options.verify_host_key_dns) { - if (matching_host_key_dns) -@@ -972,10 +971,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, - snprintf(msg, sizeof(msg), - "The authenticity of host '%.200s (%s)' can't be " - "established%s\n" -- "%s key fingerprint is %s.%s%s\n%s" -+ "%s key fingerprint is %s%s.%s%s\n%s" - "Are you sure you want to continue connecting " - "(yes/no)? ", -- host, ip, msg1, type, fp, -+ host, ip, msg1, type, -+ key_fingerprint_prefix(), fp, - options.visual_host_key ? "\n" : "", - options.visual_host_key ? ra : "", - msg2); -@@ -1220,8 +1220,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) - int flags = 0; - char *fp; - -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- debug("Server host key: %s %s", key_type(host_key), fp); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ debug("Server host key: %s %s%s", key_type(host_key), -+ key_fingerprint_prefix(), fp); - free(fp); - - /* XXX certs are not yet supported for DNS */ -@@ -1327,14 +1328,15 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) - continue; - if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) - continue; -- fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); -+ fp = key_selected_fingerprint(found->key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(found->key, SSH_FP_RANDOMART); - logit("WARNING: %s key found for host %s\n" - "in %s:%lu\n" -- "%s key fingerprint %s.", -+ "%s key fingerprint %s%s.", - key_type(found->key), - found->host, found->file, found->line, -- key_type(found->key), fp); -+ key_type(found->key), -+ key_fingerprint_prefix(), fp); - if (options.visual_host_key) - logit("%s", ra); - free(ra); -@@ -1349,7 +1351,7 @@ warn_changed_key(Key *host_key) - { - char *fp; - -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); - - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); -@@ -1357,8 +1359,8 @@ warn_changed_key(Key *host_key) - error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that a host key has just been changed."); -- error("The fingerprint for the %s key sent by the remote host is\n%s.", -- key_type(host_key), fp); -+ error("The fingerprint for the %s key sent by the remote host is\n%s%s.", -+ key_type(host_key),key_fingerprint_prefix(), fp); - error("Please contact your system administrator."); - - free(fp); -diff --git a/sshconnect2.c b/sshconnect2.c -index 7f4ff41..adbbfc7 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -577,8 +577,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) - key->type, pktype); - goto done; - } -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- debug2("input_userauth_pk_ok: fp %s", fp); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ debug2("input_userauth_pk_ok: fp %s%s", -+ key_fingerprint_prefix(), fp); - free(fp); - - /* -@@ -986,8 +987,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) - int have_sig = 1; - char *fp; - -- fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); -- debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); -+ fp = key_selected_fingerprint(id->key, SSH_FP_HEX); -+ debug3("sign_and_send_pubkey: %s %s%s", key_type(id->key), -+ key_fingerprint_prefix(), fp); - free(fp); - - if (key_to_blob(id->key, &blob, &bloblen) == 0) { diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch index a242394..6703c15 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -1,5 +1,5 @@ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 42de994..60de320 100644 +index 413b845..54dd383 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ @@ -12,12 +12,7 @@ index 42de994..60de320 100644 #include "xmalloc.h" #include "key.h" -@@ -40,10 +42,12 @@ - #include "auth.h" - #include "log.h" - #include "servconf.h" -+#include "misc.h" - +@@ -45,6 +47,7 @@ #include "buffer.h" #include "ssh-gss.h" @@ -25,7 +20,7 @@ index 42de994..60de320 100644 extern ServerOptions options; #ifdef HEIMDAL -@@ -55,6 +59,13 @@ extern ServerOptions options; +@@ -56,6 +59,13 @@ extern ServerOptions options; # include #endif @@ -39,7 +34,7 @@ index 42de994..60de320 100644 static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -87,6 +98,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; @@ -47,7 +42,7 @@ index 42de994..60de320 100644 if (ssh_gssapi_krb5_init() == 0) return 0; -@@ -98,10 +110,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; } @@ -71,7 +66,7 @@ index 42de994..60de320 100644 } else retval = 0; -@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -110,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) return retval; } @@ -102,7 +97,7 @@ index 42de994..60de320 100644 +{ + FILE *fp; + char file[MAXPATHLEN]; -+ char line[BUFSIZ]; ++ char line[BUFSIZ] = ""; + char kuser[65]; /* match krb5_kuserok() */ + struct stat st; + struct passwd *pw = the_authctxt->pw; @@ -208,10 +203,10 @@ index 42de994..60de320 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 b5dc144..ba4589b 100644 +index 28659ec..9c94d8e 100644 --- a/session.c +++ b/session.c -@@ -806,6 +806,29 @@ do_exec(Session *s, const char *command) +@@ -789,6 +789,29 @@ do_exec(Session *s, const char *command) command = forced_command; forced = "(key-option)"; } @@ -257,10 +252,10 @@ index 0374c88..509109a 100644 /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/sshd.8 b/sshd.8 -index 058d37a..5c4f15b 100644 +index adcaaf9..824163b 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -327,6 +327,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, diff --git a/openssh-6.6p1-gsskex.patch b/openssh-6.6p1-gsskex.patch index 826acd4..42b6a10 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -1,31 +1,37 @@ -diff --git a/Makefile.in b/Makefile.in -index 581b121..2ad26ff 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -77,6 +77,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ +diff -up openssh-6.8p1/Makefile.in.gsskex openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.gsskex 2015-03-18 11:24:48.875900767 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-18 12:34:36.468748216 +0100 +@@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ + atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ - kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ + kexgssc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o krl.o smult_curve25519_ref.o \ - kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ -@@ -96,7 +97,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + ssh-pkcs11.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ +@@ -111,7 +112,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw + auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - kexc25519s.o auth-krb5.o \ + monitor_mm.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 \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ -diff --git a/auth2-gss.c b/auth2-gss.c -index 4756dd7..ad65059 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_errtok(int, u_int32_t, void *); +diff -up openssh-6.8p1/auth2-gss.c.gsskex openssh-6.8p1/auth2-gss.c +--- openssh-6.8p1/auth2-gss.c.gsskex 2015-03-18 11:24:48.832900869 +0100 ++++ openssh-6.8p1/auth2-gss.c 2015-03-18 12:32:50.584011552 +0100 +@@ -31,6 +31,7 @@ + #include + + #include ++#include + + #include "xmalloc.h" + #include "key.h" +@@ -53,6 +54,40 @@ static int input_gssapi_mic(int type, u_ + static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); + static int input_gssapi_errtok(int, u_int32_t, void *); +/* + * The 'gssapi_keyex' userauth mechanism. @@ -64,7 +70,7 @@ index 4756dd7..ad65059 100644 /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -235,7 +269,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) +@@ -238,7 +273,8 @@ input_gssapi_exchange_complete(int type, packet_check_eom(); @@ -74,7 +80,7 @@ index 4756dd7..ad65059 100644 authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -277,7 +312,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) +@@ -281,7 +317,8 @@ input_gssapi_mic(int type, u_int32_t ple gssbuf.length = buffer_len(&b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -84,8 +90,8 @@ index 4756dd7..ad65059 100644 else logit("GSSAPI MIC check failed"); -@@ -294,6 +330,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) - userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); +@@ -299,6 +336,12 @@ input_gssapi_mic(int type, u_int32_t ple + return 0; } +Authmethod method_gsskeyex = { @@ -97,11 +103,10 @@ index 4756dd7..ad65059 100644 Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff --git a/auth2.c b/auth2.c -index 5f4f26f..0f52b68 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -69,6 +69,7 @@ extern Authmethod method_passwd; +diff -up openssh-6.8p1/auth2.c.gsskex openssh-6.8p1/auth2.c +--- openssh-6.8p1/auth2.c.gsskex 2015-03-18 11:24:48.832900869 +0100 ++++ openssh-6.8p1/auth2.c 2015-03-18 11:24:48.875900767 +0100 +@@ -70,6 +70,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -109,7 +114,7 @@ index 5f4f26f..0f52b68 100644 extern Authmethod method_gssapi; #endif -@@ -76,6 +77,7 @@ Authmethod *authmethods[] = { +@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -117,13 +122,12 @@ index 5f4f26f..0f52b68 100644 &method_gssapi, #endif &method_passwd, -diff --git a/clientloop.c b/clientloop.c -index 59ad3a2..9c60108 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -111,6 +111,10 @@ - #include "msg.h" - #include "roaming.h" +diff -up openssh-6.8p1/clientloop.c.gsskex openssh-6.8p1/clientloop.c +--- openssh-6.8p1/clientloop.c.gsskex 2015-03-18 11:24:48.875900767 +0100 ++++ openssh-6.8p1/clientloop.c 2015-03-18 12:30:42.647329654 +0100 +@@ -114,6 +114,10 @@ + #include "ssherr.h" + #include "hostfile.h" +#ifdef GSSAPI +#include "ssh-gss.h" @@ -132,7 +136,7 @@ index 59ad3a2..9c60108 100644 /* import options */ extern Options options; -@@ -1608,6 +1612,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) +@@ -1596,6 +1600,15 @@ client_loop(int have_pty, int escape_cha /* Do channel operations unless rekeying in progress. */ if (!rekeying) { channel_after_select(readset, writeset); @@ -147,12 +151,11 @@ index 59ad3a2..9c60108 100644 + if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); - xxx_kex->done = 0; -diff --git a/configure.ac b/configure.ac -index 74e77db..9bde04e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -584,6 +584,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + active_state->kex->done = 0; +diff -up openssh-6.8p1/configure.ac.gsskex openssh-6.8p1/configure.ac +--- openssh-6.8p1/configure.ac.gsskex 2015-03-18 11:24:48.866900788 +0100 ++++ openssh-6.8p1/configure.ac 2015-03-18 11:24:48.876900765 +0100 +@@ -620,6 +620,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -183,11 +186,10 @@ index 74e77db..9bde04e 100644 m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff --git a/gss-genr.c b/gss-genr.c -index b39281b..a3a2289 100644 ---- a/gss-genr.c -+++ b/gss-genr.c -@@ -39,12 +39,167 @@ +diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c +--- openssh-6.8p1/gss-genr.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/gss-genr.c 2015-03-18 11:24:48.876900765 +0100 +@@ -40,12 +40,167 @@ #include "buffer.h" #include "log.h" #include "ssh2.h" @@ -355,7 +357,7 @@ index b39281b..a3a2289 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -364,7 +366,7 @@ index b39281b..a3a2289 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +@@ -228,8 +383,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -407,7 +409,7 @@ index b39281b..a3a2289 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -427,7 +429,7 @@ index b39281b..a3a2289 100644 void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) -@@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, +@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha } int @@ -445,7 +447,7 @@ index b39281b..a3a2289 100644 /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -263,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -264,6 +471,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -456,7 +458,7 @@ index b39281b..a3a2289 100644 if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -272,10 +483,67 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -476,7 +478,6 @@ index b39281b..a3a2289 100644 + static OM_uint32 last_call = 0; + OM_uint32 lifetime, now, major, minor; + int equal; -+ gss_cred_usage_t usage = GSS_C_INITIATE; + + now = time(NULL); + @@ -525,11 +526,10 @@ index b39281b..a3a2289 100644 +} + #endif /* GSSAPI */ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 759fa10..42de994 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +diff -up openssh-6.8p1/gss-serv-krb5.c.gsskex openssh-6.8p1/gss-serv-krb5.c +--- openssh-6.8p1/gss-serv-krb5.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 11:24:48.876900765 +0100 +@@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; @@ -538,7 +538,7 @@ index 759fa10..42de994 100644 const char *errmsg; if (client->creds == NULL) { -@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -181,11 +181,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl return; } @@ -569,7 +569,7 @@ index 759fa10..42de994 100644 #ifdef USE_PAM if (options.use_pam) -@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -194,9 +209,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_cc_close(krb_context, ccache); @@ -646,7 +646,7 @@ index 759fa10..42de994 100644 ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", -@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { +@@ -204,7 +286,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { NULL, &ssh_gssapi_krb5_userok, NULL, @@ -656,11 +656,10 @@ index 759fa10..42de994 100644 }; #endif /* KRB5 */ -diff --git a/gss-serv.c b/gss-serv.c -index e61b37b..14f540e 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -45,15 +45,20 @@ +diff -up openssh-6.8p1/gss-serv.c.gsskex openssh-6.8p1/gss-serv.c +--- openssh-6.8p1/gss-serv.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/gss-serv.c 2015-03-18 11:24:48.877900762 +0100 +@@ -44,15 +44,20 @@ #include "channels.h" #include "session.h" #include "misc.h" @@ -683,54 +682,55 @@ index e61b37b..14f540e 100644 #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -100,25 +105,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) - char lname[MAXHOSTNAMELEN]; +@@ -99,25 +104,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) + char lname[NI_MAXHOST]; gss_OID_set oidset; - gss_create_empty_oid_set(&status, &oidset); - gss_add_oid_set_member(&status, ctx->oid, &oidset); -+ if (options.gss_strict_acceptor) { -+ gss_create_empty_oid_set(&status, &oidset); -+ gss_add_oid_set_member(&status, ctx->oid, &oidset); - -- if (gethostname(lname, MAXHOSTNAMELEN)) { +- +- if (gethostname(lname, sizeof(lname))) { - gss_release_oid_set(&status, &oidset); - return (-1); - } -+ if (gethostname(lname, MAXHOSTNAMELEN)) { ++ if (options.gss_strict_acceptor) { ++ gss_create_empty_oid_set(&status, &oidset); ++ gss_add_oid_set_member(&status, ctx->oid, &oidset); ++ ++ if (gethostname(lname, sizeof(lname))) { + gss_release_oid_set(&status, &oidset); + return (-1); + } -+ ++ + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { + gss_release_oid_set(&status, &oidset); + return (ctx->major); + } -+ ++ + if ((ctx->major = gss_acquire_cred(&ctx->minor, -+ ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, -+ NULL, NULL))) ++ ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) + ssh_gssapi_error(ctx); - if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); +- } + } else { + ctx->name = GSS_C_NO_NAME; + ctx->creds = GSS_C_NO_CREDENTIAL; - } -- ++ return GSS_S_COMPLETE; ++ } + - if ((ctx->major = gss_acquire_cred(&ctx->minor, - ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) - ssh_gssapi_error(ctx); - - gss_release_oid_set(&status, &oidset); - return (ctx->major); -+ return GSS_S_COMPLETE; } /* Privileged */ -@@ -133,6 +145,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +@@ -132,6 +144,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss } /* Unprivileged */ @@ -760,7 +760,7 @@ index e61b37b..14f540e 100644 void ssh_gssapi_supported_oids(gss_OID_set *oidset) { -@@ -142,7 +177,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) +@@ -141,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -771,7 +771,7 @@ index e61b37b..14f540e 100644 while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -268,8 +305,48 @@ OM_uint32 +@@ -267,8 +304,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -793,11 +793,11 @@ index e61b37b..14f540e 100644 + ssh_gssapi_error(ctx); + return (ctx->major); + } -+ -+ ctx->major = gss_compare_name(&ctx->minor, client->name, -+ new_name, &equal); - gss_buffer_desc ename; ++ ctx->major = gss_compare_name(&ctx->minor, client->name, ++ new_name, &equal); ++ + if (GSS_ERROR(ctx->major)) { + ssh_gssapi_error(ctx); + return (ctx->major); @@ -821,7 +821,7 @@ index e61b37b..14f540e 100644 client->mech = NULL; -@@ -284,6 +361,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -283,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -835,7 +835,7 @@ index e61b37b..14f540e 100644 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -301,6 +385,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -300,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -844,7 +844,7 @@ index e61b37b..14f540e 100644 /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -311,11 +397,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -310,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -870,7 +870,7 @@ index e61b37b..14f540e 100644 } } -@@ -348,7 +443,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) +@@ -347,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -879,7 +879,7 @@ index e61b37b..14f540e 100644 { OM_uint32 lmin; -@@ -358,9 +453,11 @@ ssh_gssapi_userok(char *user) +@@ -357,9 +452,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -893,7 +893,7 @@ index e61b37b..14f540e 100644 /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -374,14 +471,90 @@ ssh_gssapi_userok(char *user) +@@ -373,14 +470,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -990,12 +990,11 @@ index e61b37b..14f540e 100644 } #endif -diff --git a/kex.c b/kex.c -index 74e2b86..bce2ab8 100644 ---- a/kex.c -+++ b/kex.c -@@ -51,6 +51,10 @@ - #include "roaming.h" +diff -up openssh-6.8p1/kex.c.gsskex openssh-6.8p1/kex.c +--- openssh-6.8p1/kex.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/kex.c 2015-03-18 12:29:33.452501699 +0100 +@@ -55,6 +55,10 @@ + #include "sshbuf.h" #include "digest.h" +#ifdef GSSAPI @@ -1005,10 +1004,10 @@ index 74e2b86..bce2ab8 100644 #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 -@@ -90,6 +94,11 @@ static const struct kexalg kexalgs[] = { - #ifdef HAVE_EVP_SHA256 +@@ -95,6 +99,11 @@ static const struct kexalg kexalgs[] = { + #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - #endif + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ +#ifdef GSSAPI + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, @@ -1017,7 +1016,7 @@ index 74e2b86..bce2ab8 100644 { NULL, -1, -1, -1}, }; -@@ -119,6 +128,12 @@ kex_alg_by_name(const char *name) +@@ -128,6 +137,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -1030,11 +1029,10 @@ index 74e2b86..bce2ab8 100644 } return NULL; } -diff --git a/kex.h b/kex.h -index c85680e..313bb51 100644 ---- a/kex.h -+++ b/kex.h -@@ -76,6 +76,11 @@ enum kex_exchange { +diff -up openssh-6.8p1/kex.h.gsskex openssh-6.8p1/kex.h +--- openssh-6.8p1/kex.h.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/kex.h 2015-03-18 12:28:17.600690296 +0100 +@@ -93,6 +93,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, @@ -1046,8 +1044,8 @@ index c85680e..313bb51 100644 KEX_MAX }; -@@ -135,6 +140,12 @@ struct Kex { - int flags; +@@ -139,6 +144,12 @@ struct kex { + u_int flags; int hash_alg; int ec_nid; +#ifdef GSSAPI @@ -1058,24 +1056,22 @@ index c85680e..313bb51 100644 +#endif char *client_version_string; char *server_version_string; - int (*verify_host_key)(Key *); -@@ -166,6 +177,10 @@ void kexecdh_client(Kex *); - void kexecdh_server(Kex *); - void kexc25519_client(Kex *); - void kexc25519_server(Kex *); + int (*verify_host_key)(struct sshkey *, struct ssh *); +@@ -183,6 +194,10 @@ int kexecdh_client(struct ssh *); + int kexecdh_server(struct ssh *); + int kexc25519_client(struct ssh *); + int kexc25519_server(struct ssh *); +#ifdef GSSAPI -+void kexgss_client(Kex *); -+void kexgss_server(Kex *); ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); +#endif - void - kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, -diff --git a/kexgssc.c b/kexgssc.c -new file mode 100644 -index 0000000..e90b567 ---- /dev/null -+++ b/kexgssc.c -@@ -0,0 +1,334 @@ + int kex_dh_hash(const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, +diff -up openssh-6.8p1/kexgssc.c.gsskex openssh-6.8p1/kexgssc.c +--- openssh-6.8p1/kexgssc.c.gsskex 2015-03-18 11:24:48.877900762 +0100 ++++ openssh-6.8p1/kexgssc.c 2015-03-18 11:24:48.877900762 +0100 +@@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1120,22 +1116,23 @@ index 0000000..e90b567 +#include "log.h" +#include "packet.h" +#include "dh.h" ++#include "digest.h" + +#include "ssh-gss.h" + -+void -+kexgss_client(Kex *kex) { ++int ++kexgss_client(struct ssh *ssh) { + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; + Gssctxt *ctxt; + OM_uint32 maj_status, min_status, ret_flags; -+ u_int klen, kout, slen = 0, hashlen, strlen; ++ u_int klen, kout, slen = 0, strlen; + DH *dh; + BIGNUM *dh_server_pub = NULL; + BIGNUM *shared_secret = NULL; + BIGNUM *p = NULL; + BIGNUM *g = NULL; -+ u_char *kbuf, *hash; ++ u_char *kbuf; + u_char *serverhostkey = NULL; + u_char *empty = ""; + char *msg; @@ -1143,21 +1140,23 @@ index 0000000..e90b567 + int type = 0; + int first = 1; + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; + + /* Initialise our GSSAPI world */ + ssh_gssapi_build_ctx(&ctxt); -+ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) ++ if (ssh_gssapi_id_kex(ctxt, ssh->kex->name, ssh->kex->kex_type) + == GSS_C_NO_OID) + fatal("Couldn't identify host exchange"); + -+ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ if (ssh_gssapi_import_name(ctxt, ssh->kex->gss_host)) + fatal("Couldn't import hostname"); + -+ if (kex->gss_client && -+ ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ if (ssh->kex->gss_client && ++ ssh_gssapi_client_identity(ctxt, ssh->kex->gss_client)) + fatal("Couldn't acquire client credentials"); + -+ switch (kex->kex_type) { ++ switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + dh = dh_new_group1(); + break; @@ -1166,7 +1165,7 @@ index 0000000..e90b567 + break; + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange\n"); -+ nbits = dh_estimate(kex->we_need * 8); ++ nbits = dh_estimate(ssh->kex->we_need * 8); + packet_start(SSH2_MSG_KEXGSS_GROUPREQ); + packet_put_int(min); + packet_put_int(nbits); @@ -1191,11 +1190,11 @@ index 0000000..e90b567 + dh = dh_new_group(g, p); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); + } + + /* Step 1 - e is dh->pub_key */ -+ dh_gen_key(dh, kex->we_need * 8); ++ dh_gen_key(dh, ssh->kex->we_need * 8); + + /* This is f, we initialise it now to make life easier */ + dh_server_pub = BN_new(); @@ -1208,7 +1207,7 @@ index 0000000..e90b567 + debug("Calling gss_init_sec_context"); + + maj_status = ssh_gssapi_init_ctx(ctxt, -+ kex->gss_deleg_creds, token_ptr, &send_tok, ++ ssh->kex->gss_deleg_creds, token_ptr, &send_tok, + &ret_flags); + + if (GSS_ERROR(maj_status)) { @@ -1341,38 +1340,39 @@ index 0000000..e90b567 + memset(kbuf, 0, klen); + free(kbuf); + -+ switch (kex->kex_type) { ++ hashlen = sizeof(hash); ++ switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: -+ kex_dh_hash( kex->client_version_string, -+ kex->server_version_string, -+ buffer_ptr(&kex->my), buffer_len(&kex->my), -+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), ++ kex_dh_hash( ssh->kex->client_version_string, ++ ssh->kex->server_version_string, ++ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), ++ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + dh->pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ -+ &hash, &hashlen ++ hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( -+ kex->hash_alg, -+ kex->client_version_string, -+ kex->server_version_string, -+ buffer_ptr(&kex->my), buffer_len(&kex->my), -+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), ++ ssh->kex->hash_alg, ++ ssh->kex->client_version_string, ++ ssh->kex->server_version_string, ++ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), ++ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + min, nbits, max, + dh->p, dh->g, + dh->pub_key, + dh_server_pub, + shared_secret, -+ &hash, &hashlen ++ hash, &hashlen + ); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); + } + + gssbuf.value = hash; @@ -1390,13 +1390,13 @@ index 0000000..e90b567 + BN_clear_free(dh_server_pub); + + /* save session id */ -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); ++ if (ssh->kex->session_id == NULL) { ++ ssh->kex->session_id_len = hashlen; ++ ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); ++ memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); + } + -+ if (kex->gss_deleg_creds) ++ if (ssh->kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + + if (gss_kex_context == NULL) @@ -1404,18 +1404,16 @@ index 0000000..e90b567 + else + ssh_gssapi_delete_ctx(&ctxt); + -+ kex_derive_keys_bn(kex, hash, hashlen, shared_secret); ++ kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); -+ kex_finish(kex); ++ return kex_send_newkeys(ssh); +} + +#endif /* GSSAPI */ -diff --git a/kexgsss.c b/kexgsss.c -new file mode 100644 -index 0000000..6d7518c ---- /dev/null -+++ b/kexgsss.c -@@ -0,0 +1,288 @@ +diff -up openssh-6.8p1/kexgsss.c.gsskex openssh-6.8p1/kexgsss.c +--- openssh-6.8p1/kexgsss.c.gsskex 2015-03-18 11:24:48.878900760 +0100 ++++ openssh-6.8p1/kexgsss.c 2015-03-18 11:24:48.878900760 +0100 +@@ -0,0 +1,295 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1460,12 +1458,15 @@ index 0000000..6d7518c +#include "dh.h" +#include "ssh-gss.h" +#include "monitor_wrap.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" ++#include "ssh-gss.h" ++#include "digest.h" + +extern ServerOptions options; + -+void -+kexgss_server(Kex *kex) ++int ++kexgss_server(struct ssh *ssh) +{ + OM_uint32 maj_status, min_status; + @@ -1480,8 +1481,8 @@ index 0000000..6d7518c + gss_buffer_desc gssbuf, recv_tok, msg_tok; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; -+ u_int slen, klen, kout, hashlen; -+ u_char *kbuf, *hash; ++ u_int slen, klen, kout; ++ u_char *kbuf; + DH *dh; + int min = -1, max = -1, nbits = -1; + BIGNUM *shared_secret = NULL; @@ -1489,6 +1490,8 @@ index 0000000..6d7518c + int type = 0; + gss_OID oid; + char *mechs; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; + + /* Initialise GSSAPI */ + @@ -1500,8 +1503,8 @@ index 0000000..6d7518c + if ((mechs = ssh_gssapi_server_mechanisms())) + free(mechs); + -+ debug2("%s: Identifying %s", __func__, kex->name); -+ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); ++ debug2("%s: Identifying %s", __func__, ssh->kex->name); ++ oid = ssh_gssapi_id_kex(NULL, ssh->kex->name, ssh->kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + @@ -1510,7 +1513,7 @@ index 0000000..6d7518c + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); + -+ switch (kex->kex_type) { ++ switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + dh = dh_new_group1(); + break; @@ -1541,10 +1544,10 @@ index 0000000..6d7518c + packet_write_wait(); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); + } + -+ dh_gen_key(dh, kex->we_need * 8); ++ dh_gen_key(dh, ssh->kex->we_need * 8); + + do { + debug("Wait SSH2_MSG_GSSAPI_INIT"); @@ -1627,43 +1630,44 @@ index 0000000..6d7518c + memset(kbuf, 0, klen); + free(kbuf); + -+ switch (kex->kex_type) { ++ hashlen = sizeof(hash); ++ switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: + kex_dh_hash( -+ kex->client_version_string, kex->server_version_string, -+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), -+ buffer_ptr(&kex->my), buffer_len(&kex->my), ++ ssh->kex->client_version_string, ssh->kex->server_version_string, ++ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), ++ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, /* Change this if we start sending host keys */ + dh_client_pub, dh->pub_key, shared_secret, -+ &hash, &hashlen ++ hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( -+ kex->hash_alg, -+ kex->client_version_string, kex->server_version_string, -+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), -+ buffer_ptr(&kex->my), buffer_len(&kex->my), ++ ssh->kex->hash_alg, ++ ssh->kex->client_version_string, ssh->kex->server_version_string, ++ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), ++ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, + min, nbits, max, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, + shared_secret, -+ &hash, &hashlen ++ hash, &hashlen + ); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); + } + + BN_clear_free(dh_client_pub); + -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); ++ if (ssh->kex->session_id == NULL) { ++ ssh->kex->session_id_len = hashlen; ++ ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); ++ memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); + } + + gssbuf.value = hash; @@ -1694,45 +1698,21 @@ index 0000000..6d7518c + + DH_free(dh); + -+ kex_derive_keys_bn(kex, hash, hashlen, shared_secret); ++ kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); -+ kex_finish(kex); ++ kex_send_newkeys(ssh); + + /* If this was a rekey, then save out any delegated credentials we + * just exchanged. */ + if (options.gss_store_rekey) + ssh_gssapi_rekey_creds(); ++ return 0; +} +#endif /* GSSAPI */ -diff --git a/key.c b/key.c -index eb98ea8..900b9e3 100644 ---- a/key.c -+++ b/key.c -@@ -1013,6 +1013,7 @@ static const struct keytype keytypes[] = { - KEY_DSA_CERT_V00, 0, 1 }, - { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", - KEY_ED25519_CERT, 0, 1 }, -+ { "null", "null", KEY_NULL, 0, 0 }, - { NULL, NULL, -1, -1, 0 } - }; - -diff --git a/key.h b/key.h -index 0e3eea5..d51ed81 100644 ---- a/key.h -+++ b/key.h -@@ -46,6 +46,7 @@ enum types { - KEY_ED25519_CERT, - KEY_RSA_CERT_V00, - KEY_DSA_CERT_V00, -+ KEY_NULL, - KEY_UNSPEC - }; - enum fp_type { -diff --git a/monitor.c b/monitor.c -index 229fada..aa70945 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -178,6 +178,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); +diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.gsskex 2015-03-18 11:24:48.834900865 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-18 12:24:38.971233895 +0100 +@@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1741,7 +1721,7 @@ index 229fada..aa70945 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -253,11 +255,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -240,11 +242,18 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, @@ -1757,10 +1737,10 @@ index 229fada..aa70945 100644 + {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, + {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, +#endif + #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, - {MONITOR_REQ_SIGN, 0, mm_answer_sign}, - {MONITOR_REQ_PTY, 0, mm_answer_pty}, -@@ -366,6 +375,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) + #endif +@@ -359,6 +368,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1771,7 +1751,7 @@ index 229fada..aa70945 100644 } else { mon_dispatch = mon_dispatch_proto15; -@@ -471,6 +484,10 @@ monitor_child_postauth(struct monitor *pmonitor) +@@ -467,6 +480,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1782,10 +1762,10 @@ index 229fada..aa70945 100644 } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1866,6 +1883,13 @@ mm_get_kex(Buffer *m) - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kexecdh_server; - kex->kex[KEX_C25519_SHA256] = kexc25519_server; +@@ -1892,6 +1909,13 @@ monitor_apply_keystate(struct monitor *p + # endif + #endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; @@ -1793,10 +1773,10 @@ index 229fada..aa70945 100644 + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; + } +#endif - kex->server = 1; - kex->hostkey_type = buffer_get_int(m); - kex->kex_type = buffer_get_int(m); -@@ -2073,6 +2097,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; +@@ -1991,6 +2015,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -1806,7 +1786,7 @@ index 229fada..aa70945 100644 goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2100,6 +2127,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) +@@ -2018,6 +2045,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1816,7 +1796,7 @@ index 229fada..aa70945 100644 in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2117,6 +2147,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) +@@ -2035,6 +2065,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1824,7 +1804,7 @@ index 229fada..aa70945 100644 } return (0); } -@@ -2128,6 +2159,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) +@@ -2046,6 +2077,9 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -1834,7 +1814,7 @@ index 229fada..aa70945 100644 gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2154,7 +2188,11 @@ mm_answer_gss_userok(int sock, Buffer *m) +@@ -2072,7 +2106,11 @@ mm_answer_gss_userok(int sock, Buffer *m { int authenticated; @@ -1847,7 +1827,7 @@ index 229fada..aa70945 100644 buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2167,5 +2205,73 @@ mm_answer_gss_userok(int sock, Buffer *m) +@@ -2085,5 +2123,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1921,10 +1901,9 @@ index 229fada..aa70945 100644 + #endif /* GSSAPI */ -diff --git a/monitor.h b/monitor.h -index 20e2b4a..ff79fbb 100644 ---- a/monitor.h -+++ b/monitor.h +diff -up openssh-6.8p1/monitor.h.gsskex openssh-6.8p1/monitor.h +--- openssh-6.8p1/monitor.h.gsskex 2015-03-18 11:24:48.834900865 +0100 ++++ openssh-6.8p1/monitor.h 2015-03-18 11:24:48.878900760 +0100 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1934,11 +1913,10 @@ index 20e2b4a..ff79fbb 100644 MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff --git a/monitor_wrap.c b/monitor_wrap.c -index d1b6d99..d1e1caa 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -1290,7 +1290,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +diff -up openssh-6.8p1/monitor_wrap.c.gsskex openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1/monitor_wrap.c.gsskex 2015-03-18 11:24:48.834900865 +0100 ++++ openssh-6.8p1/monitor_wrap.c 2015-03-18 11:24:48.878900760 +0100 +@@ -1087,7 +1087,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1947,7 +1925,7 @@ index d1b6d99..d1e1caa 100644 { Buffer m; int authenticated = 0; -@@ -1307,5 +1307,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -1104,5 +1104,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1998,11 +1976,10 @@ index d1b6d99..d1e1caa 100644 + #endif /* GSSAPI */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 9d5e5ba..93929e0 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); +diff -up openssh-6.8p1/monitor_wrap.h.gsskex openssh-6.8p1/monitor_wrap.h +--- openssh-6.8p1/monitor_wrap.h.gsskex 2015-03-18 11:24:48.834900865 +0100 ++++ openssh-6.8p1/monitor_wrap.h 2015-03-18 11:24:48.878900760 +0100 +@@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2014,11 +1991,10 @@ index 9d5e5ba..93929e0 100644 #endif #ifdef USE_PAM -diff --git a/readconf.c b/readconf.c -index dc884c9..7613ff2 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -141,6 +141,8 @@ typedef enum { +diff -up openssh-6.8p1/readconf.c.gsskex openssh-6.8p1/readconf.c +--- openssh-6.8p1/readconf.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/readconf.c 2015-03-18 11:24:48.879900758 +0100 +@@ -147,6 +147,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2027,7 +2003,7 @@ index dc884c9..7613ff2 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -183,10 +185,19 @@ static struct { +@@ -191,10 +193,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2047,7 +2023,7 @@ index dc884c9..7613ff2 100644 #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, -@@ -841,10 +852,30 @@ parse_time: +@@ -892,10 +903,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2078,7 +2054,7 @@ index dc884c9..7613ff2 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1497,7 +1528,12 @@ initialize_options(Options * options) +@@ -1601,7 +1632,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2091,7 +2067,7 @@ index dc884c9..7613ff2 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1616,8 +1652,14 @@ fill_default_options(Options * options) +@@ -1728,8 +1764,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2106,11 +2082,10 @@ index dc884c9..7613ff2 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff --git a/readconf.h b/readconf.h -index 75e3f8f..5cc97f0 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -54,7 +54,12 @@ typedef struct { +diff -up openssh-6.8p1/readconf.h.gsskex openssh-6.8p1/readconf.h +--- openssh-6.8p1/readconf.h.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/readconf.h 2015-03-18 11:24:48.879900758 +0100 +@@ -45,7 +45,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -2123,23 +2098,21 @@ index 75e3f8f..5cc97f0 100644 int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh -index 1d9e0ed..1277409 100644 ---- a/regress/cert-hostkey.sh -+++ b/regress/cert-hostkey.sh -@@ -17,7 +17,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ - cat $OBJ/host_ca_key.pub - ) > $OBJ/known_hosts-cert +diff -up openssh-6.8p1/regress/cert-hostkey.sh.gsskex openssh-6.8p1/regress/cert-hostkey.sh +--- openssh-6.8p1/regress/cert-hostkey.sh.gsskex 2015-03-18 11:24:48.879900758 +0100 ++++ openssh-6.8p1/regress/cert-hostkey.sh 2015-03-18 12:15:49.556546478 +0100 +@@ -25,7 +25,7 @@ touch $OBJ/host_revoked_plain + touch $OBJ/host_revoked_cert + cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` type_has_legacy() { case $1 in -diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh -index b093a91..4c8da00 100644 ---- a/regress/cert-userkey.sh -+++ b/regress/cert-userkey.sh +diff -up openssh-6.8p1/regress/cert-userkey.sh.gsskex openssh-6.8p1/regress/cert-userkey.sh +--- openssh-6.8p1/regress/cert-userkey.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/regress/cert-userkey.sh 2015-03-18 11:24:48.879900758 +0100 @@ -6,7 +6,7 @@ tid="certified user keys" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak @@ -2149,11 +2122,10 @@ index b093a91..4c8da00 100644 type_has_legacy() { case $1 in -diff --git a/regress/kextype.sh b/regress/kextype.sh -index 8c2ac09..a2a87ca 100644 ---- a/regress/kextype.sh -+++ b/regress/kextype.sh -@@ -9,6 +9,9 @@ cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak +diff -up openssh-6.8p1/regress/kextype.sh.gsskex openssh-6.8p1/regress/kextype.sh +--- openssh-6.8p1/regress/kextype.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/regress/kextype.sh 2015-03-18 11:24:48.879900758 +0100 +@@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" for k in `${SSH} -Q kex`; do @@ -2163,11 +2135,10 @@ index 8c2ac09..a2a87ca 100644 verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff --git a/regress/rekey.sh b/regress/rekey.sh -index cf9401e..31fb0f7 100644 ---- a/regress/rekey.sh -+++ b/regress/rekey.sh -@@ -30,6 +30,9 @@ increase_datafile_size 300 +diff -up openssh-6.8p1/regress/rekey.sh.gsskex openssh-6.8p1/regress/rekey.sh +--- openssh-6.8p1/regress/rekey.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/regress/rekey.sh 2015-03-18 11:24:48.879900758 +0100 +@@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" for i in `${SSH} -Q kex`; do @@ -2177,7 +2148,7 @@ index cf9401e..31fb0f7 100644 opts="$opts KexAlgorithms=$i" done for i in `${SSH} -Q cipher`; do -@@ -48,6 +51,9 @@ done +@@ -56,6 +59,9 @@ done if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then for c in `${SSH} -Q cipher-auth`; do for kex in `${SSH} -Q kex`; do @@ -2185,13 +2156,12 @@ index cf9401e..31fb0f7 100644 + continue + fi verbose "client rekey $c $kex" - ssh_data_rekeying -oRekeyLimit=256k -oCiphers=$c -oKexAlgorithms=$kex + ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff --git a/servconf.c b/servconf.c -index f763317..68fb9ef 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -108,7 +108,10 @@ initialize_server_options(ServerOptions *options) +diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.gsskex 2015-03-18 11:24:48.866900788 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 12:14:37.967721387 +0100 +@@ -114,7 +114,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -2202,7 +2172,7 @@ index f763317..68fb9ef 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -245,8 +248,14 @@ fill_default_server_options(ServerOptions *options) +@@ -270,8 +273,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2217,17 +2187,17 @@ index f763317..68fb9ef 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -344,7 +353,8 @@ typedef enum { +@@ -394,7 +403,8 @@ typedef enum { sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -411,10 +421,20 @@ static struct { +@@ -465,10 +475,20 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -2248,7 +2218,7 @@ index f763317..68fb9ef 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1091,10 +1111,22 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1170,10 +1190,22 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2271,7 +2241,7 @@ index f763317..68fb9ef 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2005,6 +2037,9 @@ dump_config(ServerOptions *o) +@@ -2134,6 +2166,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2281,11 +2251,10 @@ index f763317..68fb9ef 100644 #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --git a/servconf.h b/servconf.h -index 4572066..37cfa9b 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -112,7 +112,10 @@ typedef struct { +diff -up openssh-6.8p1/servconf.h.gsskex openssh-6.8p1/servconf.h +--- openssh-6.8p1/servconf.h.gsskex 2015-03-18 11:24:48.866900788 +0100 ++++ openssh-6.8p1/servconf.h 2015-03-18 11:24:48.880900755 +0100 +@@ -115,7 +115,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2296,10 +2265,9 @@ index 4572066..37cfa9b 100644 int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff --git a/ssh-gss.h b/ssh-gss.h -index a99d7f0..0374c88 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h +diff -up openssh-6.8p1/ssh-gss.h.gsskex openssh-6.8p1/ssh-gss.h +--- openssh-6.8p1/ssh-gss.h.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/ssh-gss.h 2015-03-18 11:24:48.880900755 +0100 @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* @@ -2364,7 +2332,7 @@ index a99d7f0..0374c88 100644 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -119,16 +136,30 @@ void ssh_gssapi_build_ctx(Gssctxt **); +@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); @@ -2394,13 +2362,14 @@ index a99d7f0..0374c88 100644 +int ssh_gssapi_oid_table_ok(); + +int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); ++ ++void ssh_gssapi_rekey_creds(void); #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff --git a/ssh_config b/ssh_config -index 6d1abaf..b0d343b 100644 ---- a/ssh_config -+++ b/ssh_config +diff -up openssh-6.8p1/ssh_config.gsskex openssh-6.8p1/ssh_config +--- openssh-6.8p1/ssh_config.gsskex 2015-03-18 11:24:48.861900800 +0100 ++++ openssh-6.8p1/ssh_config 2015-03-18 11:24:48.880900755 +0100 @@ -26,6 +26,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -2410,11 +2379,10 @@ index 6d1abaf..b0d343b 100644 # BatchMode no # CheckHostIP yes # AddressFamily any -diff --git a/ssh_config.5 b/ssh_config.5 -index b580392..e7accd6 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -682,11 +682,43 @@ Specifies whether user authentication based on GSSAPI is allowed. +diff -up openssh-6.8p1/ssh_config.5.gsskex openssh-6.8p1/ssh_config.5 +--- openssh-6.8p1/ssh_config.5.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/ssh_config.5 2015-03-18 11:24:48.881900753 +0100 +@@ -743,11 +743,43 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2459,13 +2427,12 @@ index b580392..e7accd6 100644 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff --git a/sshconnect2.c b/sshconnect2.c -index adbbfc7..cadf234 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -158,9 +158,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - { - Kex *kex; +diff -up openssh-6.8p1/sshconnect2.c.gsskex openssh-6.8p1/sshconnect2.c +--- openssh-6.8p1/sshconnect2.c.gsskex 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshconnect2.c 2015-03-18 11:32:36.879784546 +0100 +@@ -160,9 +160,34 @@ ssh_kex2(char *host, struct sockaddr *ho + struct kex *kex; + int r; +#ifdef GSSAPI + char *orig = NULL, *gss = NULL; @@ -2498,9 +2465,9 @@ index adbbfc7..cadf234 100644 if (options.ciphers == (char *)-1) { logit("No valid ciphers for protocol version 2 given, using defaults."); options.ciphers = NULL; -@@ -196,6 +221,17 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; +@@ -200,6 +225,17 @@ ssh_kex2(char *host, struct sockaddr *ho + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( + myproposal[PROPOSAL_KEX_ALGS]); +#ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the @@ -2516,10 +2483,10 @@ index adbbfc7..cadf234 100644 if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); -@@ -208,10 +244,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; +@@ -217,11 +253,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; - kex->kex[KEX_C25519_SHA256] = kexc25519_client; + # endif + #endif +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; @@ -2527,6 +2494,7 @@ index adbbfc7..cadf234 100644 + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; + } +#endif + kex->kex[KEX_C25519_SHA256] = kexc25519_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; @@ -2544,18 +2512,18 @@ index adbbfc7..cadf234 100644 + } +#endif + - xxx_kex = kex; + dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); -@@ -301,6 +357,7 @@ void input_gssapi_token(int type, u_int32_t, void *); - void input_gssapi_hash(int type, u_int32_t, void *); - void input_gssapi_error(int, u_int32_t, void *); - void input_gssapi_errtok(int, u_int32_t, void *); + if (options.use_roaming && !kex->roaming) { +@@ -313,6 +369,7 @@ int input_gssapi_token(int type, u_int32 + int input_gssapi_hash(int type, u_int32_t, void *); + int input_gssapi_error(int, u_int32_t, void *); + int input_gssapi_errtok(int, u_int32_t, void *); +int userauth_gsskeyex(Authctxt *authctxt); #endif void userauth(Authctxt *, char *); -@@ -316,6 +373,11 @@ static char *authmethods_get(void); +@@ -328,6 +385,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2567,7 +2535,7 @@ index adbbfc7..cadf234 100644 {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -613,19 +675,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -634,19 +696,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2601,7 +2569,7 @@ index adbbfc7..cadf234 100644 ok = 1; /* Mechanism works */ } else { mech++; -@@ -722,8 +796,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) +@@ -743,8 +817,8 @@ input_gssapi_response(int type, u_int32_ { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -2612,9 +2580,9 @@ index adbbfc7..cadf234 100644 if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -832,6 +906,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) - free(msg); +@@ -857,6 +931,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); + return 0; } + +int @@ -2661,22 +2629,10 @@ index adbbfc7..cadf234 100644 #endif /* GSSAPI */ int -diff --git a/sshd.c b/sshd.c -index 24ab272..e4e406e 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -122,6 +122,10 @@ - #include "ssh-sandbox.h" - #include "version.h" - -+#ifdef USE_SECURITY_SESSION_API -+#include -+#endif -+ - #ifdef LIBWRAP - #include - #include -@@ -1744,10 +1748,13 @@ main(int ac, char **av) +diff -up openssh-6.8p1/sshd.c.gsskex openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.gsskex 2015-03-18 11:24:48.869900781 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 11:35:53.260315986 +0100 +@@ -1831,10 +1831,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2690,7 +2646,7 @@ index 24ab272..e4e406e 100644 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2488,6 +2495,48 @@ do_ssh2_kex(void) +@@ -2580,6 +2583,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2737,11 +2693,11 @@ index 24ab272..e4e406e 100644 +#endif + /* start key exchange */ - kex = kex_setup(myproposal); - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; -@@ -2496,6 +2545,13 @@ do_ssh2_kex(void) - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + if ((r = kex_setup(active_state, myproposal)) != 0) + fatal("kex_setup: %s", ssh_err(r)); +@@ -2594,6 +2639,13 @@ do_ssh2_kex(void) + # endif + #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { @@ -2753,10 +2709,9 @@ index 24ab272..e4e406e 100644 kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff --git a/sshd_config b/sshd_config -index c1b7c03..adfd7b1 100644 ---- a/sshd_config -+++ b/sshd_config +diff -up openssh-6.8p1/sshd_config.gsskex openssh-6.8p1/sshd_config +--- openssh-6.8p1/sshd_config.gsskex 2015-03-18 11:24:48.869900781 +0100 ++++ openssh-6.8p1/sshd_config 2015-03-18 11:24:48.882900750 +0100 @@ -91,6 +91,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes @@ -2766,11 +2721,10 @@ index c1b7c03..adfd7b1 100644 # 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 95b5f8c..1fb002d 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -493,12 +493,40 @@ Specifies whether user authentication based on GSSAPI is allowed. +diff -up openssh-6.8p1/sshd_config.5.gsskex openssh-6.8p1/sshd_config.5 +--- openssh-6.8p1/sshd_config.5.gsskex 2015-03-18 11:24:48.882900750 +0100 ++++ openssh-6.8p1/sshd_config.5 2015-03-18 12:12:57.914965842 +0100 +@@ -564,12 +564,40 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2808,6 +2762,6 @@ index 95b5f8c..1fb002d 100644 +successful connection rekeying. This option can be used to accepted renewed +or updated credentials from a compatible client. The default is +.Dq no . - .It Cm HostbasedAuthentication - Specifies whether rhosts or /etc/hosts.equiv authentication together - with successful public key client host authentication is allowed + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a comma-separated pattern list. diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index d30dedb..be79371 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,8 +1,6 @@ -diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat -new file mode 100644 -index 0000000..630ec62 ---- /dev/null -+++ b/HOWTO.ssh-keycat +diff -up openssh-6.8p1/HOWTO.ssh-keycat.keycat openssh-6.8p1/HOWTO.ssh-keycat +--- openssh-6.8p1/HOWTO.ssh-keycat.keycat 2015-03-18 11:13:43.063482958 +0100 ++++ openssh-6.8p1/HOWTO.ssh-keycat 2015-03-18 11:13:43.063482958 +0100 @@ -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 @@ -16,10 +14,9 @@ index 0000000..630ec62 + PubkeyAuthentication yes + + -diff --git a/Makefile.in b/Makefile.in -index 411eadb..4ab6717 100644 ---- a/Makefile.in -+++ b/Makefile.in +diff -up openssh-6.8p1/Makefile.in.keycat openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.keycat 2015-03-18 11:13:43.061482963 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-18 11:14:22.480389291 +0100 @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -28,18 +25,18 @@ index 411eadb..4ab6717 100644 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -64,7 +65,7 @@ EXEEXT=@EXEEXT@ +@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) - LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ -@@ -176,6 +177,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11 - ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + LIBOPENSSH_OBJS=\ + ssh_api.o \ +@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) + ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) @@ -47,7 +44,7 @@ index 411eadb..4ab6717 100644 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -@@ -283,6 +287,7 @@ install-files: +@@ -321,6 +325,7 @@ install-files: $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ fi @@ -55,11 +52,10 @@ index 411eadb..4ab6717 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/auth2-pubkey.c b/auth2-pubkey.c -index c0ae0d4..cb0f931 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -600,6 +600,14 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) +diff -up openssh-6.8p1/auth2-pubkey.c.keycat openssh-6.8p1/auth2-pubkey.c +--- openssh-6.8p1/auth2-pubkey.c.keycat 2015-03-18 11:13:43.053482982 +0100 ++++ openssh-6.8p1/auth2-pubkey.c 2015-03-18 11:13:43.063482958 +0100 +@@ -623,6 +623,14 @@ user_key_command_allowed2(struct passwd _exit(1); } @@ -74,11 +70,10 @@ index c0ae0d4..cb0f931 100644 execl(options.authorized_keys_command, options.authorized_keys_command, user_pw->pw_name, NULL); -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index d04f4ed..0077dd7 100644 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c -@@ -53,6 +53,20 @@ extern Authctxt *the_authctxt; +diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.keycat openssh-6.8p1/openbsd-compat/port-linux-sshd.c +--- openssh-6.8p1/openbsd-compat/port-linux-sshd.c.keycat 2015-03-18 11:13:43.057482972 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux-sshd.c 2015-03-18 11:13:43.063482958 +0100 +@@ -54,6 +54,20 @@ extern Authctxt *the_authctxt; extern int inetd_flag; extern int rexeced_flag; @@ -99,7 +94,7 @@ index d04f4ed..0077dd7 100644 /* Send audit message */ static int sshd_selinux_send_audit_message(int success, security_context_t default_context, -@@ -307,7 +321,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -108,7 +103,7 @@ index d04f4ed..0077dd7 100644 { const char *reqlvl; char *role; -@@ -318,16 +332,16 @@ sshd_selinux_setup_pam_variables(void) +@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); @@ -128,7 +123,7 @@ index d04f4ed..0077dd7 100644 if (role != NULL) free(role); -@@ -335,6 +349,24 @@ sshd_selinux_setup_pam_variables(void) +@@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void) return rv; } @@ -153,7 +148,7 @@ index d04f4ed..0077dd7 100644 /* Set the execution context to the default for the specified user */ void sshd_selinux_setup_exec_context(char *pwname) -@@ -343,7 +375,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; @@ -162,7 +157,7 @@ index d04f4ed..0077dd7 100644 return; if (options.use_pam) { -@@ -414,7 +446,7 @@ sshd_selinux_copy_context(void) +@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void) { security_context_t *ctx; @@ -171,11 +166,10 @@ index d04f4ed..0077dd7 100644 return; if (getexeccon((security_context_t *)&ctx) != 0) { -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index b18893c..cb51f99 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const char *); +diff -up openssh-6.8p1/openbsd-compat/port-linux.h.keycat openssh-6.8p1/openbsd-compat/port-linux.h +--- openssh-6.8p1/openbsd-compat/port-linux.h.keycat 2015-03-18 11:13:43.057482972 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 11:13:43.063482958 +0100 +@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const void ssh_selinux_change_context(const char *); void ssh_selinux_setfscreatecon(const char *); @@ -186,11 +180,10 @@ index b18893c..cb51f99 100644 #endif #ifdef LINUX_OOM_ADJUST -diff --git a/platform.c b/platform.c -index 0d39ab2..0dae387 100644 ---- a/platform.c -+++ b/platform.c -@@ -102,7 +102,7 @@ platform_setusercontext(struct passwd *pw) +diff -up openssh-6.8p1/platform.c.keycat openssh-6.8p1/platform.c +--- openssh-6.8p1/platform.c.keycat 2015-03-18 11:13:43.055482977 +0100 ++++ openssh-6.8p1/platform.c 2015-03-18 11:13:43.063482958 +0100 +@@ -103,7 +103,7 @@ platform_setusercontext(struct passwd *p { #ifdef WITH_SELINUX /* Cache selinux status for later use */ @@ -199,11 +192,9 @@ index 0d39ab2..0dae387 100644 #endif #ifdef USE_SOLARIS_PROJECTS -diff --git a/ssh-keycat.c b/ssh-keycat.c -new file mode 100644 -index 0000000..f8ed7af ---- /dev/null -+++ b/ssh-keycat.c +diff -up openssh-6.8p1/ssh-keycat.c.keycat openssh-6.8p1/ssh-keycat.c +--- openssh-6.8p1/ssh-keycat.c.keycat 2015-03-18 11:13:43.064482956 +0100 ++++ openssh-6.8p1/ssh-keycat.c 2015-03-18 11:13:43.064482956 +0100 @@ -0,0 +1,238 @@ +/* + * Redistribution and use in source and binary forms, with or without diff --git a/openssh-6.6p1-keyperm.patch b/openssh-6.6p1-keyperm.patch index fccb328..fbe33b0 100644 --- a/openssh-6.6p1-keyperm.patch +++ b/openssh-6.6p1-keyperm.patch @@ -1,15 +1,16 @@ -diff -up openssh-6.6p1/authfile.c.keyperm openssh-6.6p1/authfile.c ---- openssh-6.6p1/authfile.c.keyperm 2014-02-04 01:20:15.000000000 +0100 -+++ openssh-6.6p1/authfile.c 2014-05-05 15:20:43.075246776 +0200 -@@ -54,6 +54,7 @@ +diff --git a/authfile.c b/authfile.c +index e93d867..4fc5b3d 100644 +--- a/authfile.c ++++ b/authfile.c +@@ -32,6 +32,7 @@ #include #include +#include - #include #include + #include #include -@@ -979,6 +980,13 @@ key_perm_ok(int fd, const char *filename +@@ -207,6 +208,13 @@ sshkey_perm_ok(int fd, const char *filename) #ifdef HAVE_CYGWIN if (check_ntsec(filename)) #endif diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index f7c5a1c..9e93051 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,8 +1,7 @@ -diff --git a/auth-krb5.c b/auth-krb5.c -index 6c62bdf..11c8562 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c -@@ -54,6 +54,21 @@ +diff -up openssh-6.8p1/auth-krb5.c.kuserok openssh-6.8p1/auth-krb5.c +--- openssh-6.8p1/auth-krb5.c.kuserok 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth-krb5.c 2015-03-18 12:37:14.349351304 +0100 +@@ -55,6 +55,21 @@ extern ServerOptions options; @@ -24,7 +23,7 @@ index 6c62bdf..11c8562 100644 static int krb5_init(void *context) { -@@ -157,8 +172,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, c if (problem) goto out; @@ -36,11 +35,10 @@ index 6c62bdf..11c8562 100644 problem = -1; goto out; } -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 60de320..0a4930e 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, +diff -up openssh-6.8p1/gss-serv-krb5.c.kuserok openssh-6.8p1/gss-serv-krb5.c +--- openssh-6.8p1/gss-serv-krb5.c.kuserok 2015-03-18 12:37:14.346351312 +0100 ++++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 12:37:14.349351304 +0100 +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr int); static krb5_context krb_context = NULL; @@ -152,7 +150,7 @@ index 60de320..0a4930e 100644 static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) { -@@ -116,7 +214,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. */ @@ -162,7 +160,7 @@ index 60de320..0a4930e 100644 retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); -@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +@@ -171,9 +270,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)) { @@ -174,29 +172,28 @@ index 60de320..0a4930e 100644 } if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; -diff --git a/servconf.c b/servconf.c -index 68fb9ef..904c869 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) - options->ip_qos_interactive = -1; +diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.kuserok 2015-03-18 12:37:14.342351322 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 12:38:36.133145700 +0100 +@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions options->ip_qos_bulk = -1; options->version_addendum = NULL; + options->fingerprint_hash = -1; + options->use_kuserok = -1; } - void -@@ -312,6 +313,8 @@ fill_default_server_options(ServerOptions *options) - options->version_addendum = xstrdup(""); - if (options->show_patchlevel == -1) - options->show_patchlevel = 0; + /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption + options->fwd_opts.streamlocal_bind_unlink = 0; + if (options->fingerprint_hash == -1) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->use_kuserok == -1) + options->use_kuserok = 1; - /* Turn privilege separation on by default */ if (use_privsep == -1) -@@ -338,7 +341,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, + use_privsep = PRIVSEP_NOSANDBOX; +@@ -388,7 +391,7 @@ typedef enum { + sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, @@ -204,7 +201,7 @@ index 68fb9ef..904c869 100644 sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, -@@ -410,11 +413,13 @@ static struct { +@@ -464,11 +467,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -218,7 +215,7 @@ index 68fb9ef..904c869 100644 #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1614,6 +1619,10 @@ process_server_config_line(ServerOptions *activep = value; break; @@ -229,7 +226,7 @@ index 68fb9ef..904c869 100644 case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -1935,6 +1944,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -237,19 +234,18 @@ index 68fb9ef..904c869 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2062,6 +2072,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); +@@ -2194,6 +2204,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff --git a/servconf.h b/servconf.h -index 37cfa9b..5117dfa 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -173,6 +173,7 @@ typedef struct { +diff -up openssh-6.8p1/servconf.h.kuserok openssh-6.8p1/servconf.h +--- openssh-6.8p1/servconf.h.kuserok 2015-03-18 12:37:14.342351322 +0100 ++++ openssh-6.8p1/servconf.h 2015-03-18 12:37:14.350351302 +0100 +@@ -177,6 +177,7 @@ typedef struct { int num_permitted_opens; @@ -257,10 +253,9 @@ index 37cfa9b..5117dfa 100644 char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff --git a/sshd_config b/sshd_config -index adfd7b1..e772ed5 100644 ---- a/sshd_config -+++ b/sshd_config +diff -up openssh-6.8p1/sshd_config.kuserok openssh-6.8p1/sshd_config +--- openssh-6.8p1/sshd_config.kuserok 2015-03-18 12:37:14.344351317 +0100 ++++ openssh-6.8p1/sshd_config 2015-03-18 12:37:14.350351302 +0100 @@ -87,6 +87,7 @@ ChallengeResponseAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes @@ -269,11 +264,10 @@ index adfd7b1..e772ed5 100644 # GSSAPI options GSSAPIAuthentication yes -diff --git a/sshd_config.5 b/sshd_config.5 -index 1fb002d..e0e5fff 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -697,6 +697,10 @@ Specifies whether to automatically destroy the user's ticket cache +diff -up openssh-6.8p1/sshd_config.5.kuserok openssh-6.8p1/sshd_config.5 +--- openssh-6.8p1/sshd_config.5.kuserok 2015-03-18 12:37:14.343351319 +0100 ++++ openssh-6.8p1/sshd_config.5 2015-03-18 12:39:23.373026939 +0100 +@@ -779,6 +779,10 @@ Specifies whether to automatically destr file on logout. The default is .Dq yes . @@ -284,8 +278,8 @@ index 1fb002d..e0e5fff 100644 .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. -@@ -862,6 +866,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , +@@ -1017,6 +1021,7 @@ Available keywords are + .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , +.Cm KerberosUseKuserok , diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index 4740c99..da164d3 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -1,7 +1,6 @@ -diff --git a/auth-pam.c b/auth-pam.c -index d789bad..cd1a775 100644 ---- a/auth-pam.c -+++ b/auth-pam.c +diff -up openssh-6.8p1/auth-pam.c.role-mls openssh-6.8p1/auth-pam.c +--- openssh-6.8p1/auth-pam.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth-pam.c 2015-03-18 11:04:21.045817122 +0100 @@ -1068,7 +1068,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ @@ -11,10 +10,9 @@ index d789bad..cd1a775 100644 { int ret = 1; #ifdef HAVE_PAM_PUTENV -diff --git a/auth-pam.h b/auth-pam.h -index a1a2b52..b109a5a 100644 ---- a/auth-pam.h -+++ b/auth-pam.h +diff -up openssh-6.8p1/auth-pam.h.role-mls openssh-6.8p1/auth-pam.h +--- openssh-6.8p1/auth-pam.h.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth-pam.h 2015-03-18 11:04:21.045817122 +0100 @@ -38,7 +38,7 @@ void do_pam_session(void); void do_pam_set_tty(const char *); void do_pam_setcred(int ); @@ -24,11 +22,10 @@ index a1a2b52..b109a5a 100644 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 124e597..4605588 100644 ---- a/auth.h -+++ b/auth.h -@@ -59,6 +59,9 @@ struct Authctxt { +diff -up openssh-6.8p1/auth.h.role-mls openssh-6.8p1/auth.h +--- openssh-6.8p1/auth.h.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth.h 2015-03-18 11:04:21.045817122 +0100 +@@ -62,6 +62,9 @@ struct Authctxt { char *service; struct passwd *pw; /* set if 'valid' */ char *style; @@ -38,11 +35,10 @@ index 124e597..4605588 100644 void *kbdintctxt; char *info; /* Extra info for next auth_log */ #ifdef BSD_AUTH -diff --git a/auth1.c b/auth1.c -index 0f870b3..df040bb 100644 ---- a/auth1.c -+++ b/auth1.c -@@ -381,6 +381,9 @@ do_authentication(Authctxt *authctxt) +diff -up openssh-6.8p1/auth1.c.role-mls openssh-6.8p1/auth1.c +--- openssh-6.8p1/auth1.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth1.c 2015-03-18 11:04:21.046817119 +0100 +@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) { u_int ulen; char *user, *style = NULL; @@ -52,7 +48,7 @@ index 0f870b3..df040bb 100644 /* Get the name of the user that we wish to log in as. */ packet_read_expect(SSH_CMSG_USER); -@@ -389,11 +392,24 @@ do_authentication(Authctxt *authctxt) +@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) user = packet_get_cstring(&ulen); packet_check_eom(); @@ -77,11 +73,10 @@ index 0f870b3..df040bb 100644 /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff --git a/auth2-gss.c b/auth2-gss.c -index c28a705..4756dd7 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -251,6 +251,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) +diff -up openssh-6.8p1/auth2-gss.c.role-mls openssh-6.8p1/auth2-gss.c +--- openssh-6.8p1/auth2-gss.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth2-gss.c 2015-03-18 11:04:21.046817119 +0100 +@@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple Authctxt *authctxt = ctxt; Gssctxt *gssctxt; int authenticated = 0; @@ -89,7 +84,7 @@ index c28a705..4756dd7 100644 Buffer b; gss_buffer_desc mic, gssbuf; u_int len; -@@ -263,7 +264,13 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) +@@ -267,7 +268,13 @@ input_gssapi_mic(int type, u_int32_t ple mic.value = packet_get_string(&len); mic.length = len; @@ -104,7 +99,7 @@ index c28a705..4756dd7 100644 "gssapi-with-mic"); gssbuf.value = buffer_ptr(&b); -@@ -275,6 +282,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) +@@ -279,6 +286,8 @@ input_gssapi_mic(int type, u_int32_t ple logit("GSSAPI MIC check failed"); buffer_free(&b); @@ -113,11 +108,10 @@ index c28a705..4756dd7 100644 free(mic.value); authctxt->postponed = 0; -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index eca0069..95d678e 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -112,7 +112,15 @@ userauth_hostbased(Authctxt *authctxt) +diff -up openssh-6.8p1/auth2-hostbased.c.role-mls openssh-6.8p1/auth2-hostbased.c +--- openssh-6.8p1/auth2-hostbased.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth2-hostbased.c 2015-03-18 11:04:21.046817119 +0100 +@@ -122,7 +122,15 @@ userauth_hostbased(Authctxt *authctxt) buffer_put_string(&b, session_id2, session_id2_len); /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -134,11 +128,10 @@ index eca0069..95d678e 100644 buffer_put_cstring(&b, service); buffer_put_cstring(&b, "hostbased"); buffer_put_string(&b, pkalg, alen); -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 749b11a..c0ae0d4 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -133,9 +133,11 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-6.8p1/auth2-pubkey.c.role-mls openssh-6.8p1/auth2-pubkey.c +--- openssh-6.8p1/auth2-pubkey.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth2-pubkey.c 2015-03-18 11:04:21.046817119 +0100 +@@ -145,9 +145,11 @@ userauth_pubkey(Authctxt *authctxt) } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -152,11 +145,10 @@ index 749b11a..c0ae0d4 100644 buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, -diff --git a/auth2.c b/auth2.c -index a5490c0..5f4f26f 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) +diff -up openssh-6.8p1/auth2.c.role-mls openssh-6.8p1/auth2.c +--- openssh-6.8p1/auth2.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth2.c 2015-03-18 11:04:21.046817119 +0100 +@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ctxt; Authmethod *m = NULL; char *user, *service, *method, *style = NULL; @@ -166,7 +158,7 @@ index a5490c0..5f4f26f 100644 int authenticated = 0; if (authctxt == NULL) -@@ -226,6 +229,11 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) +@@ -226,6 +229,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); @@ -178,7 +170,7 @@ index a5490c0..5f4f26f 100644 if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) +@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -195,11 +187,10 @@ index a5490c0..5f4f26f 100644 userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); -diff --git a/misc.c b/misc.c -index e4c8c32..f31cd91 100644 ---- a/misc.c -+++ b/misc.c -@@ -430,6 +430,7 @@ char * +diff -up openssh-6.8p1/misc.c.role-mls openssh-6.8p1/misc.c +--- openssh-6.8p1/misc.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/misc.c 2015-03-18 11:04:21.046817119 +0100 +@@ -431,6 +431,7 @@ char * colon(char *cp) { int flag = 0; @@ -207,7 +198,7 @@ index e4c8c32..f31cd91 100644 if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -445,6 +446,13 @@ colon(char *cp) +@@ -446,6 +447,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -221,11 +212,10 @@ index e4c8c32..f31cd91 100644 } return NULL; } -diff --git a/monitor.c b/monitor.c -index 531c4f9..229fada 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -145,6 +145,9 @@ int mm_answer_sign(int, Buffer *); +diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-18 11:04:21.047817117 +0100 +@@ -127,6 +127,9 @@ int mm_answer_sign(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); @@ -235,7 +225,7 @@ index 531c4f9..229fada 100644 int mm_answer_authpassword(int, Buffer *); int mm_answer_bsdauthquery(int, Buffer *); int mm_answer_bsdauthrespond(int, Buffer *); -@@ -219,6 +222,9 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -206,6 +209,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}, @@ -245,7 +235,7 @@ index 531c4f9..229fada 100644 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -805,6 +811,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) +@@ -862,6 +868,9 @@ mm_answer_pwnamallow(int sock, Buffer *m else { /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -255,7 +245,7 @@ index 531c4f9..229fada 100644 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); } #ifdef USE_PAM -@@ -846,6 +855,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -903,6 +912,25 @@ mm_answer_authserv(int sock, Buffer *m) return (0); } @@ -281,7 +271,7 @@ index 531c4f9..229fada 100644 int mm_answer_authpassword(int sock, Buffer *m) { -@@ -1220,7 +1248,7 @@ static int +@@ -1291,7 +1319,7 @@ static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; @@ -290,7 +280,7 @@ index 531c4f9..229fada 100644 u_int len; int fail = 0; -@@ -1246,6 +1274,8 @@ monitor_valid_userblob(u_char *data, u_int datalen) +@@ -1317,6 +1345,8 @@ monitor_valid_userblob(u_char *data, u_i if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -299,7 +289,7 @@ index 531c4f9..229fada 100644 xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1281,7 +1311,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, +@@ -1352,7 +1382,7 @@ monitor_valid_hostbasedblob(u_char *data char *chost) { Buffer b; @@ -308,7 +298,7 @@ index 531c4f9..229fada 100644 u_int len; int fail = 0; -@@ -1298,6 +1328,8 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, +@@ -1369,6 +1399,8 @@ monitor_valid_hostbasedblob(u_char *data if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -317,10 +307,9 @@ index 531c4f9..229fada 100644 xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff --git a/monitor.h b/monitor.h -index 5bc41b5..20e2b4a 100644 ---- a/monitor.h -+++ b/monitor.h +diff -up openssh-6.8p1/monitor.h.role-mls openssh-6.8p1/monitor.h +--- openssh-6.8p1/monitor.h.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/monitor.h 2015-03-18 11:04:21.047817117 +0100 @@ -57,6 +57,10 @@ enum monitor_reqtype { MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, @@ -332,11 +321,10 @@ index 5bc41b5..20e2b4a 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 1a47e41..d1b6d99 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char *style) +diff -up openssh-6.8p1/monitor_wrap.c.role-mls openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1/monitor_wrap.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/monitor_wrap.c 2015-03-18 11:04:21.047817117 +0100 +@@ -347,6 +347,25 @@ mm_inform_authserv(char *service, char * buffer_free(&m); } @@ -362,13 +350,12 @@ index 1a47e41..d1b6d99 100644 /* Do the password authentication */ int mm_auth_password(Authctxt *authctxt, char *password) -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 18c2501..9d5e5ba 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h +diff -up openssh-6.8p1/monitor_wrap.h.role-mls openssh-6.8p1/monitor_wrap.h +--- openssh-6.8p1/monitor_wrap.h.role-mls 2015-03-18 11:04:21.047817117 +0100 ++++ openssh-6.8p1/monitor_wrap.h 2015-03-18 11:10:32.343936171 +0100 @@ -42,6 +42,9 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); + int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -376,25 +363,22 @@ index 18c2501..9d5e5ba 100644 struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct Authctxt *, char *); -diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in -index 6ecfb93..b912dbe 100644 ---- a/openbsd-compat/Makefile.in -+++ b/openbsd-compat/Makefile.in -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di +diff -up openssh-6.8p1/openbsd-compat/Makefile.in.role-mls openssh-6.8p1/openbsd-compat/Makefile.in +--- openssh-6.8p1/openbsd-compat/Makefile.in.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/openbsd-compat/Makefile.in 2015-03-18 11:04:21.047817117 +0100 +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -new file mode 100644 -index 0000000..c18524e ---- /dev/null -+++ b/openbsd-compat/port-linux-sshd.c -@@ -0,0 +1,414 @@ +diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/openbsd-compat/port-linux-sshd.c +--- openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls 2015-03-18 11:04:21.048817114 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux-sshd.c 2015-03-18 11:04:21.048817114 +0100 +@@ -0,0 +1,415 @@ +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2014 Petr Lautrbach @@ -426,6 +410,7 @@ index 0000000..c18524e + +#include "log.h" +#include "xmalloc.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" +#include "port-linux.h" +#include "key.h" @@ -809,10 +794,9 @@ index 0000000..c18524e +#endif +#endif + -diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 4637a7a..22ea8ef 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c +diff -up openssh-6.8p1/openbsd-compat/port-linux.c.role-mls openssh-6.8p1/openbsd-compat/port-linux.c +--- openssh-6.8p1/openbsd-compat/port-linux.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux.c 2015-03-18 11:04:21.048817114 +0100 @@ -103,37 +103,6 @@ ssh_selinux_getctxbyname(char *pwname) return sc; } @@ -851,10 +835,9 @@ index 4637a7a..22ea8ef 100644 /* Set the TTY context for the specified user */ void ssh_selinux_setup_pty(char *pwname, const char *tty) -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index e3d1004..8ef6cc4 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h +diff -up openssh-6.8p1/openbsd-compat/port-linux.h.role-mls openssh-6.8p1/openbsd-compat/port-linux.h +--- openssh-6.8p1/openbsd-compat/port-linux.h.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 11:04:21.048817114 +0100 @@ -22,9 +22,10 @@ #ifdef WITH_SELINUX int ssh_selinux_enabled(void); @@ -867,11 +850,10 @@ index e3d1004..8ef6cc4 100644 #endif #ifdef LINUX_OOM_ADJUST -diff --git a/platform.c b/platform.c -index 30fc609..0d39ab2 100644 ---- a/platform.c -+++ b/platform.c -@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(struct passwd *pw) +diff -up openssh-6.8p1/platform.c.role-mls openssh-6.8p1/platform.c +--- openssh-6.8p1/platform.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/platform.c 2015-03-18 11:04:21.048817114 +0100 +@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -880,11 +862,10 @@ index 30fc609..0d39ab2 100644 #endif } -diff --git a/sshd.c b/sshd.c -index 7523de9..07f9926 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2138,6 +2138,9 @@ main(int ac, char **av) +diff -up openssh-6.8p1/sshd.c.role-mls openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.role-mls 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 11:04:21.048817114 +0100 +@@ -2220,6 +2220,9 @@ main(int ac, char **av) restore_uid(); } #endif @@ -894,3 +875,20 @@ index 7523de9..07f9926 100644 #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(1); +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 22ea8ef..2660085 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -116,7 +116,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("%s: getexeccon: %s", __func__, strerror(errno)); ++ goto out; ++ } ++ + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + diff --git a/openssh-6.6p1-set_remote_ipaddr.patch b/openssh-6.6p1-set_remote_ipaddr.patch index 166e569..ec4e416 100644 --- a/openssh-6.6p1-set_remote_ipaddr.patch +++ b/openssh-6.6p1-set_remote_ipaddr.patch @@ -1,8 +1,7 @@ -diff --git a/canohost.c b/canohost.c -index 97ce58c..1f9320a 100644 ---- a/canohost.c -+++ b/canohost.c -@@ -338,6 +338,21 @@ clear_cached_addr(void) +diff -up openssh-6.8p1/canohost.c.set_remote_ipaddr openssh-6.8p1/canohost.c +--- openssh-6.8p1/canohost.c.set_remote_ipaddr 2015-03-18 12:40:03.702925550 +0100 ++++ openssh-6.8p1/canohost.c 2015-03-18 12:40:03.749925432 +0100 +@@ -349,6 +349,21 @@ clear_cached_addr(void) cached_port = -1; } @@ -24,7 +23,7 @@ index 97ce58c..1f9320a 100644 /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -347,17 +362,9 @@ const char * +@@ -358,17 +373,9 @@ const char * get_remote_ipaddr(void) { /* Check whether we have cached the ipaddr. */ @@ -45,10 +44,9 @@ index 97ce58c..1f9320a 100644 return canonical_host_ip; } -diff --git a/canohost.h b/canohost.h -index 4c8636f..4079953 100644 ---- a/canohost.h -+++ b/canohost.h +diff -up openssh-6.8p1/canohost.h.set_remote_ipaddr openssh-6.8p1/canohost.h +--- openssh-6.8p1/canohost.h.set_remote_ipaddr 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/canohost.h 2015-03-18 12:40:03.749925432 +0100 @@ -13,6 +13,7 @@ */ @@ -57,19 +55,18 @@ index 4c8636f..4079953 100644 const char *get_remote_ipaddr(void); const char *get_remote_name_or_ip(u_int, int); -diff --git a/sshconnect.c b/sshconnect.c -index e636f33..451a58b 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -62,6 +62,7 @@ - #include "monitor_fdpass.h" - #include "ssh2.h" +diff -up openssh-6.8p1/sshconnect.c.set_remote_ipaddr openssh-6.8p1/sshconnect.c +--- openssh-6.8p1/sshconnect.c.set_remote_ipaddr 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshconnect.c 2015-03-18 12:40:58.096788804 +0100 +@@ -65,6 +65,7 @@ #include "version.h" + #include "authfile.h" + #include "ssherr.h" +#include "canohost.h" char *client_version_string = NULL; char *server_version_string = NULL; -@@ -170,6 +171,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, +@@ -174,6 +175,7 @@ ssh_proxy_fdpass_connect(const char *hos /* Set the connection file descriptors. */ packet_set_connection(sock, sock); @@ -77,7 +74,7 @@ index e636f33..451a58b 100644 return 0; } -@@ -492,6 +494,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, +@@ -496,6 +498,7 @@ ssh_connect_direct(const char *host, str /* Set the connection. */ packet_set_connection(sock, sock); diff --git a/openssh-6.6p1-audit.patch b/openssh-6.7p1-audit.patch similarity index 68% rename from openssh-6.6p1-audit.patch rename to openssh-6.7p1-audit.patch index 2ee2012..213ca67 100644 --- a/openssh-6.6p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -1,22 +1,19 @@ -diff --git a/Makefile.in b/Makefile.in -index 0f0d39f..9d8c2eb 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -82,7 +82,8 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - ssh-pkcs11.o krl.o smult_curve25519_ref.o \ - kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o hmac.o utf8_stringprep.o \ -- sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o -+ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ -+ auditstub.o +diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.audit 2015-03-20 13:41:15.065883826 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 +@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ +- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o ++ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ -diff --git a/audit-bsm.c b/audit-bsm.c -index 6135591..5160869 100644 ---- a/audit-bsm.c -+++ b/audit-bsm.c -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, int port) +diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c +--- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 +@@ -375,10 +375,23 @@ audit_connection_from(const char *host, #endif } @@ -66,7 +63,7 @@ index 6135591..5160869 100644 +} + +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid) ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) +{ + /* not implemented */ +} @@ -95,17 +92,17 @@ index 6135591..5160869 100644 + /* not implemented */ +} #endif /* BSM */ -diff --git a/audit-linux.c b/audit-linux.c -index b3ee2f4..946f7fa 100644 ---- a/audit-linux.c -+++ b/audit-linux.c -@@ -35,13 +35,24 @@ +diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c +--- openssh-6.8p1/audit-linux.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 +0100 +@@ -35,13 +35,25 @@ #include "log.h" #include "audit.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" #include "canohost.h" +#include "packet.h" @@ -127,7 +124,7 @@ index b3ee2f4..946f7fa 100644 { int audit_fd, rc, saved_errno; -@@ -49,11 +60,11 @@ linux_audit_record_event(int uid, const char *username, +@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char *username, if (audit_fd < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) @@ -142,7 +139,7 @@ index b3ee2f4..946f7fa 100644 NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -65,35 +76,150 @@ linux_audit_record_event(int uid, const char *username, +@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char *username, if ((rc == -EPERM) && (geteuid() != 0)) rc = 0; errno = saved_errno; @@ -224,8 +221,12 @@ index b3ee2f4..946f7fa 100644 + buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; ++ /* is the fingerprint_prefix() still needed? + snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d", -+ type, bits, key_fingerprint_prefix(), fp, get_remote_port()); ++ type, bits, sshkey_fingerprint_prefix(), fp, get_remote_port()); ++ */ ++ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", ++ type, bits, fp, get_remote_port()); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, + buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); +out: @@ -301,7 +302,7 @@ index b3ee2f4..946f7fa 100644 } void -@@ -101,21 +227,43 @@ audit_event(ssh_audit_event_t event) +@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) { switch(event) { case SSH_AUTH_SUCCESS: @@ -349,7 +350,7 @@ index b3ee2f4..946f7fa 100644 break; default: -@@ -123,4 +271,135 @@ audit_event(ssh_audit_event_t event) +@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) } } @@ -379,17 +380,17 @@ index b3ee2f4..946f7fa 100644 +const static char *direction[] = { "from-server", "from-client", "both" }; + +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, + uid_t uid) +{ +#ifdef AUDIT_CRYPTO_SESSION + char buf[AUDIT_LOG_SIZE]; + int audit_fd, audit_ok; -+ Cipher *cipher = cipher_by_name(enc); ++ const Cipher *cipher = cipher_by_name(enc); + char *s; + -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, ++ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, + (intmax_t)pid, (intmax_t)uid, + get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); + free(s); @@ -455,7 +456,7 @@ index b3ee2f4..946f7fa 100644 + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, + buf, NULL, -+ listening_for_clients() ? NULL : get_remote_ipaddr(), ++ listening_for_clients() ? get_remote_ipaddr() : NULL, + NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ @@ -485,10 +486,9 @@ index b3ee2f4..946f7fa 100644 + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff --git a/audit.c b/audit.c -index ced57fa..ab9fb82 100644 ---- a/audit.c -+++ b/audit.c +diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c +--- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 @@ -28,6 +28,7 @@ #include @@ -497,17 +497,27 @@ index ced57fa..ab9fb82 100644 #ifdef SSH_AUDIT_EVENTS -@@ -36,6 +37,9 @@ +@@ -36,6 +37,11 @@ #include "key.h" #include "hostfile.h" #include "auth.h" +#include "ssh-gss.h" +#include "monitor_wrap.h" +#include "xmalloc.h" ++#include "misc.h" ++#include "servconf.h" /* * Care must be taken when using this since it WILL NOT be initialized when -@@ -71,13 +75,10 @@ audit_classify_auth(const char *method) +@@ -43,6 +49,7 @@ + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ + extern Authctxt *the_authctxt; ++extern ServerOptions options; + + /* Maybe add the audit class to struct Authmethod? */ + ssh_audit_event_t +@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) const char * audit_username(void) { @@ -523,7 +533,7 @@ index ced57fa..ab9fb82 100644 return (the_authctxt->user); } -@@ -111,6 +112,40 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -533,7 +543,7 @@ index ced57fa..ab9fb82 100644 + char *fp; + const char *crypto_name; + -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); + if (key->type == KEY_RSA1) + crypto_name = "ssh-rsa1"; + else @@ -550,9 +560,9 @@ index ced57fa..ab9fb82 100644 +} + +void -+audit_kex(int ctos, char *enc, char *mac, char *comp) ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) +{ -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); ++ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); +} + +void @@ -564,7 +574,7 @@ index ced57fa..ab9fb82 100644 # ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. -@@ -140,6 +175,17 @@ audit_event(ssh_audit_event_t event) +@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) } /* @@ -582,7 +592,7 @@ index ced57fa..ab9fb82 100644 * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -174,13 +220,91 @@ audit_session_close(struct logininfo *li) +@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -622,7 +632,7 @@ index ced57fa..ab9fb82 100644 +{ + debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", + host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, -+ key_fingerprint_prefix(), fp, rv); ++ sshkey_fingerprint_prefix(), fp, rv); +} + +/* @@ -638,11 +648,11 @@ index ced57fa..ab9fb82 100644 + * This will be called on succesfull protocol negotiation. + */ +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, + uid_t uid) +{ -+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, + (unsigned)uid); +} + @@ -676,10 +686,9 @@ index ced57fa..ab9fb82 100644 } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff --git a/audit.h b/audit.h -index 92ede5b..a2dc3ff 100644 ---- a/audit.h -+++ b/audit.h +diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h +--- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 @@ -28,6 +28,7 @@ # define _SSH_AUDIT_H @@ -706,20 +715,18 @@ index 92ede5b..a2dc3ff 100644 +int audit_keyusage(int, const char *, unsigned, char *, int); +void audit_key(int, int *, const Key *); +void audit_unsupported(int); -+void audit_kex(int, char *, char *, char *); ++void audit_kex(int, char *, char *, char *, char *); +void audit_unsupported_body(int); -+void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); +void audit_session_key_free(int ctos); +void audit_session_key_free_body(int ctos, pid_t, uid_t); +void audit_destroy_sensitive_data(const char *, pid_t, uid_t); +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff --git a/auditstub.c b/auditstub.c -new file mode 100644 -index 0000000..45817e0 ---- /dev/null -+++ b/auditstub.c +diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c +--- openssh-6.8p1/auditstub.c.audit 2015-03-20 13:41:15.093883780 +0100 ++++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -758,7 +765,7 @@ index 0000000..45817e0 +} + +void -+audit_kex(int ctos, char *enc, char *mac, char *comp) ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) +{ +} + @@ -771,11 +778,10 @@ index 0000000..45817e0 +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff --git a/auth-rsa.c b/auth-rsa.c -index 5dad6c3..f225b0b 100644 ---- a/auth-rsa.c -+++ b/auth-rsa.c -@@ -93,7 +93,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) +diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c +--- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 +@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) { u_char buf[32], mdbuf[16]; struct ssh_digest_ctx *md; @@ -787,7 +793,7 @@ index 5dad6c3..f225b0b 100644 /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -@@ -117,12 +120,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) +@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) ssh_digest_free(md); /* Verify that the response is the original challenge. */ @@ -797,7 +803,7 @@ index 5dad6c3..f225b0b 100644 + rv = timingsafe_bcmp(response, mdbuf, 16) == 0; + +#ifdef SSH_AUDIT_EVENTS -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); + if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) { + debug("unsuccessful audit"); + rv = 0; @@ -811,11 +817,10 @@ index 5dad6c3..f225b0b 100644 } /* -diff --git a/auth.c b/auth.c -index 420a85b..d613f8c 100644 ---- a/auth.c -+++ b/auth.c -@@ -628,9 +628,6 @@ getpwnamallow(const char *user) +diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c +--- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 +@@ -644,9 +644,6 @@ getpwnamallow(const char *user) record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); #endif @@ -825,11 +830,10 @@ index 420a85b..d613f8c 100644 return (NULL); } if (!allowed_user(pw)) -diff --git a/auth.h b/auth.h -index 4605588..f9d191c 100644 ---- a/auth.h -+++ b/auth.h -@@ -186,6 +186,7 @@ void abandon_challenge_response(Authctxt *); +diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h +--- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100 ++++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 +@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -837,19 +841,18 @@ index 4605588..f9d191c 100644 FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -203,6 +204,7 @@ Key *get_hostkey_private_by_type(int); - int get_hostkey_index(Key *); +@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc int ssh1_session_key(BIGNUM *); - void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int); + int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, + const u_char *, size_t, u_int); +int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 95d678e..48aede4 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -137,7 +137,7 @@ userauth_hostbased(Authctxt *authctxt) +diff -up openssh-6.8p1/auth2-hostbased.c.audit openssh-6.8p1/auth2-hostbased.c +--- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 13:41:15.002883927 +0100 ++++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 13:41:15.093883780 +0100 +@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && @@ -858,7 +861,7 @@ index 95d678e..48aede4 100644 buffer_len(&b))) == 1) authenticated = 1; -@@ -154,6 +154,18 @@ done: +@@ -164,6 +164,18 @@ done: return authenticated; } @@ -877,20 +880,19 @@ index 95d678e..48aede4 100644 /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index cb0f931..6d1c872 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -160,7 +160,7 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-6.8p1/auth2-pubkey.c.audit openssh-6.8p1/auth2-pubkey.c +--- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 13:41:15.013883910 +0100 ++++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 +0100 +@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) + buffer_len(&b))) == 1) { authenticated = 1; - buffer_free(&b); -@@ -231,6 +231,18 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) + /* Record the successful key to prevent reuse */ +@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } @@ -907,13 +909,12 @@ index cb0f931..6d1c872 100644 +} + static int - match_principals_option(const char *principal_list, struct KeyCert *cert) + match_principals_option(const char *principal_list, struct sshkey_cert *cert) { -diff --git a/auth2.c b/auth2.c -index 426dcd6..436cd60 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) +diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c +--- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 +0100 ++++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 +@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); @@ -923,15 +924,14 @@ index 426dcd6..436cd60 100644 } #ifdef USE_PAM if (options.use_pam) -diff --git a/cipher.c b/cipher.c -index 53d9b4f..226e56d 100644 ---- a/cipher.c -+++ b/cipher.c -@@ -57,20 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_bf(void); - extern const EVP_CIPHER *evp_ssh1_3des(void); - extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); +diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c +--- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 +@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v + extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + #endif --struct Cipher { +-struct sshcipher { - char *name; - int number; /* for ssh1 only */ - u_int block_size; @@ -942,22 +942,27 @@ index 53d9b4f..226e56d 100644 - u_int flags; -#define CFLAG_CBC (1<<0) -#define CFLAG_CHACHAPOLY (1<<1) +-#define CFLAG_AESCTR (1<<2) +-#define CFLAG_NONE (1<<3) +-#ifdef WITH_OPENSSL - const EVP_CIPHER *(*evptype)(void); +-#else +- void *ignored; +-#endif -}; - - static const struct Cipher ciphers[] = { - { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, + static const struct sshcipher ciphers[] = { + #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff --git a/cipher.h b/cipher.h -index 133d2e7..d41758e 100644 ---- a/cipher.h -+++ b/cipher.h -@@ -63,7 +63,20 @@ - typedef struct Cipher Cipher; - typedef struct CipherContext CipherContext; +diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h +--- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 +@@ -62,7 +62,26 @@ + #define CIPHER_ENCRYPT 1 + #define CIPHER_DECRYPT 0 --struct Cipher; -+struct Cipher { +-struct sshcipher; ++struct sshcipher { + char *name; + int number; /* for ssh1 only */ + u_int block_size; @@ -968,85 +973,89 @@ index 133d2e7..d41758e 100644 + u_int flags; +#define CFLAG_CBC (1<<0) +#define CFLAG_CHACHAPOLY (1<<1) ++#define CFLAG_AESCTR (1<<2) ++#define CFLAG_NONE (1<<3) ++#ifdef WITH_OPENSSL + const EVP_CIPHER *(*evptype)(void); ++#else ++ void *ignored; ++#endif +}; + - struct CipherContext { + struct sshcipher_ctx { int plaintext; int encrypt; -diff --git a/kex.c b/kex.c -index bce2ab8..bc3e53e 100644 ---- a/kex.c -+++ b/kex.c -@@ -50,6 +50,7 @@ - #include "monitor.h" - #include "roaming.h" +diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c +--- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 ++++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 +@@ -54,6 +55,7 @@ + #include "ssherr.h" + #include "sshbuf.h" #include "digest.h" +#include "audit.h" #ifdef GSSAPI #include "ssh-gss.h" -@@ -366,9 +367,13 @@ static void - choose_enc(Enc *enc, char *client, char *server) +@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); + - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS + audit_unsupported(0); +#endif - fatal("no matching cipher found: client %s server %s", - client, server); + return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) - fatal("matching cipher is not supported: %s", name); + return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -384,9 +389,13 @@ static void - choose_mac(Mac *mac, char *client, char *server) +@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); + - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS + audit_unsupported(1); +#endif - fatal("no matching mac found: client %s server %s", - client, server); + return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) - fatal("unsupported mac %s", name); + return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -401,8 +410,12 @@ static void - choose_comp(Comp *comp, char *client, char *server) +@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); + - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS + audit_unsupported(2); +#endif - fatal("no matching comp found: client %s server %s", client, server); + return SSH_ERR_NO_COMPRESS_ALG_MATCH; + } if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -517,6 +530,9 @@ kex_choose_conf(Kex *kex) - newkeys->enc.name, - authlen == 0 ? newkeys->mac.name : "", - newkeys->comp.name); +@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) + dh_need = MAX(dh_need, newkeys->enc.block_size); + dh_need = MAX(dh_need, newkeys->enc.iv_len); + dh_need = MAX(dh_need, newkeys->mac.key_len); ++ debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); +#ifdef SSH_AUDIT_EVENTS -+ audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); ++ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); +#endif } - choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); - choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], -@@ -702,3 +718,34 @@ dump_digest(char *msg, u_char *digest, int len) - fprintf(stderr, "\n"); + /* XXX need runden? */ + kex->we_need = need; +@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i + sshbuf_dump_data(digest, len, stderr); } #endif + +static void -+enc_destroy(Enc *enc) ++enc_destroy(struct sshenc *enc) +{ + if (enc == NULL) + return; @@ -1065,7 +1074,7 @@ index bce2ab8..bc3e53e 100644 +} + +void -+newkeys_destroy(Newkeys *newkeys) ++newkeys_destroy(struct newkeys *newkeys) +{ + if (newkeys == NULL) + return; @@ -1075,79 +1084,38 @@ index bce2ab8..bc3e53e 100644 + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} + -diff --git a/kex.h b/kex.h -index 313bb51..c643250 100644 ---- a/kex.h -+++ b/kex.h -@@ -182,6 +182,8 @@ void kexgss_client(Kex *); - void kexgss_server(Kex *); +diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h +--- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 ++++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 +@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); + int kexgss_server(struct ssh *); #endif -+void newkeys_destroy(Newkeys *newkeys); ++void newkeys_destroy(struct newkeys *newkeys); + - void - kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, - BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); -diff --git a/key.c b/key.c -index 900b9e3..62f3edb 100644 ---- a/key.c -+++ b/key.c -@@ -1925,6 +1925,33 @@ key_demote(const Key *k) - } - - int -+key_is_private(const Key *k) -+{ -+ switch (k->type) { -+ case KEY_RSA_CERT_V00: -+ case KEY_RSA_CERT: -+ case KEY_RSA1: -+ case KEY_RSA: -+ return k->rsa->d != NULL; -+ case KEY_DSA_CERT_V00: -+ case KEY_DSA_CERT: -+ case KEY_DSA: -+ return k->dsa->priv_key != NULL; -+#ifdef OPENSSL_HAS_ECC -+ case KEY_ECDSA_CERT: -+ case KEY_ECDSA: -+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; -+#endif -+ case KEY_ED25519_CERT: -+ case KEY_ED25519: -+ return (k->ed25519_pk != NULL); -+ default: -+ fatal("key_is_private: bad key type %d", k->type); -+ return 1; -+ } -+} -+ -+int - key_is_cert(const Key *k) - { - if (k == NULL) -diff --git a/key.h b/key.h -index d51ed81..8f61605 100644 ---- a/key.h -+++ b/key.h -@@ -118,6 +118,7 @@ Key *key_generate(int, u_int); - Key *key_from_private(const Key *); - int key_type_from_name(char *); - int key_is_cert(const Key *); -+int key_is_private(const Key *k); - int key_type_is_cert(int); - int key_type_plain(int); - int key_to_certified(Key *, int); -diff --git a/mac.c b/mac.c -index 0977572..9388af4 100644 ---- a/mac.c -+++ b/mac.c -@@ -222,6 +222,20 @@ mac_clear(Mac *mac) + int kex_dh_hash(const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, + const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); +diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h +--- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 +@@ -50,6 +50,7 @@ typedef struct sshkey Key; + #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid + #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid + #define key_is_cert sshkey_is_cert ++#define key_is_private sshkey_is_private + #define key_type_plain sshkey_type_plain + #define key_cert_is_legacy sshkey_cert_is_legacy + #define key_curve_name_to_nid sshkey_curve_name_to_nid +diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c +--- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 +@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } +void -+mac_destroy(Mac *mac) ++mac_destroy(struct sshmac *mac) +{ + if (mac == NULL) + return; @@ -1163,37 +1131,37 @@ index 0977572..9388af4 100644 /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff --git a/mac.h b/mac.h -index fbe18c4..7dc7f43 100644 ---- a/mac.h -+++ b/mac.h -@@ -29,3 +29,4 @@ int mac_setup(Mac *, char *); - int mac_init(Mac *); - u_char *mac_compute(Mac *, u_int32_t, u_char *, int); - void mac_clear(Mac *); -+void mac_destroy(Mac *); -diff --git a/monitor.c b/monitor.c -index 8b18086..5a65114 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -97,6 +97,7 @@ +diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h +--- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 +@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); + int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, + u_char *, size_t); + void mac_clear(struct sshmac *); ++void mac_destroy(struct sshmac *); + + #endif /* SSHMAC_H */ +diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 +@@ -102,6 +102,7 @@ #include "ssh2.h" #include "roaming.h" #include "authfd.h" +#include "audit.h" + #include "match.h" + #include "ssherr.h" - #ifdef GSSAPI - static Gssctxt *gsscontext = NULL; -@@ -113,6 +114,8 @@ extern Buffer auth_debug; +@@ -117,6 +118,8 @@ extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; +extern void destroy_sensitive_data(int); + /* State exported from the child */ + static struct sshbuf *child_state; - struct { -@@ -185,6 +188,11 @@ int mm_answer_gss_updatecreds(int, Buffer *); +@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); @@ -1205,7 +1173,7 @@ index 8b18086..5a65114 100644 #endif static int monitor_read_log(struct monitor *); -@@ -239,6 +247,10 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1216,7 +1184,7 @@ index 8b18086..5a65114 100644 #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -274,6 +286,11 @@ struct mon_table mon_dispatch_postauth20[] = { +@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1228,7 +1196,7 @@ index 8b18086..5a65114 100644 #endif {0, 0, NULL} }; -@@ -305,6 +322,10 @@ struct mon_table mon_dispatch_proto15[] = { +@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1237,9 +1205,9 @@ index 8b18086..5a65114 100644 + {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, #endif + #endif /* WITH_SSH1 */ {0, 0, NULL} - }; -@@ -316,6 +337,11 @@ struct mon_table mon_dispatch_postauth15[] = { +@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, @@ -1249,9 +1217,9 @@ index 8b18086..5a65114 100644 + {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, #endif + #endif /* WITH_SSH1 */ {0, 0, NULL} - }; -@@ -1393,9 +1419,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1263,7 +1231,7 @@ index 8b18086..5a65114 100644 blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1403,6 +1431,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1272,7 +1240,7 @@ index 8b18086..5a65114 100644 key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1423,7 +1453,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1291,7 +1259,7 @@ index 8b18086..5a65114 100644 debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1476,6 +1516,12 @@ mm_session_close(Session *s) +@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1304,7 +1272,7 @@ index 8b18086..5a65114 100644 session_unused(s->self); } -@@ -1756,6 +1802,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1313,7 +1281,7 @@ index 8b18086..5a65114 100644 while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1798,11 +1846,43 @@ mm_answer_audit_command(int socket, Buffer *m) +@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1358,24 +1326,18 @@ index 8b18086..5a65114 100644 free(cmd); return (0); } -@@ -1946,11 +2026,13 @@ mm_get_keystate(struct monitor *pmonitor) +@@ -1936,6 +2017,7 @@ + void + mm_get_keystate(struct monitor *pmonitor) + { ++ Buffer m; + debug3("%s: Waiting for new keys", __func__); - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); -+ memset(blob, 0, bloblen); - free(blob); - - debug3("%s: Waiting for second key", __func__); - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); -+ memset(blob, 0, bloblen); - free(blob); - - /* Now get sequence numbers for the packets */ -@@ -1996,6 +2078,21 @@ mm_get_keystate(struct monitor *pmonitor) - } - - buffer_free(&m); + if ((child_state = sshbuf_new()) == NULL) +@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor + mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, + child_state); + debug3("%s: GOT new keys", __func__); + +#ifdef SSH_AUDIT_EVENTS + if (compat20) { @@ -1394,7 +1356,7 @@ index 8b18086..5a65114 100644 } -@@ -2277,3 +2374,85 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) { +@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1418,7 +1380,7 @@ index 8b18086..5a65114 100644 +mm_answer_audit_kex_body(int sock, Buffer *m) +{ + int ctos, len; -+ char *cipher, *mac, *compress; ++ char *cipher, *mac, *compress, *pfs; + pid_t pid; + uid_t uid; + @@ -1426,14 +1388,16 @@ index 8b18086..5a65114 100644 + cipher = buffer_get_string(m, &len); + mac = buffer_get_string(m, &len); + compress = buffer_get_string(m, &len); ++ pfs = buffer_get_string(m, &len); + pid = buffer_get_int64(m); + uid = buffer_get_int64(m); + -+ audit_kex_body(ctos, cipher, mac, compress, pid, uid); ++ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); + + free(cipher); + free(mac); + free(compress); ++ free(pfs); + buffer_clear(m); + + mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); @@ -1480,10 +1444,9 @@ index 8b18086..5a65114 100644 + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor.h b/monitor.h -index ff79fbb..6dfb234 100644 ---- a/monitor.h -+++ b/monitor.h +diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h +--- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 +0100 ++++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1499,11 +1462,10 @@ index ff79fbb..6dfb234 100644 }; -diff --git a/monitor_wrap.c b/monitor_wrap.c -index d1e1caa..6df236a 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -450,7 +450,7 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) +diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 13:41:15.047883855 +0100 ++++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 +0100 +@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha */ int @@ -1512,7 +1474,7 @@ index d1e1caa..6df236a 100644 { Buffer m; u_char *blob; -@@ -464,6 +464,7 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) +@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i return (0); buffer_init(&m); @@ -1520,7 +1482,7 @@ index d1e1caa..6df236a 100644 buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -481,6 +482,19 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) +@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i return (verified); } @@ -1536,26 +1498,10 @@ index d1e1caa..6df236a 100644 + return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen); +} + -+ - /* Export key state after authentication */ - Newkeys * - mm_newkeys_from_blob(u_char *blob, int blen) -@@ -659,12 +673,14 @@ mm_send_keystate(struct monitor *monitor) - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); -+ memset(blob, 0, bloblen); - free(blob); - - if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); -+ memset(blob, 0, bloblen); - free(blob); - - packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); -@@ -1208,10 +1224,11 @@ mm_audit_event(ssh_audit_event_t event) + void + mm_send_keystate(struct monitor *monitor) + { +@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1568,7 +1514,7 @@ index d1e1caa..6df236a 100644 debug3("%s entering command %s", __func__, command); -@@ -1219,6 +1236,26 @@ mm_audit_run_command(const char *command) +@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1595,7 +1541,7 @@ index d1e1caa..6df236a 100644 buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1354,3 +1391,71 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) +@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1616,7 +1562,7 @@ index d1e1caa..6df236a 100644 +} + +void -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, ++mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, + uid_t uid) +{ + Buffer m; @@ -1626,6 +1572,7 @@ index d1e1caa..6df236a 100644 + buffer_put_cstring(&m, cipher); + buffer_put_cstring(&m, (mac ? mac : "")); + buffer_put_cstring(&m, compress); ++ buffer_put_cstring(&m, fps); + buffer_put_int64(&m, pid); + buffer_put_int64(&m, uid); + @@ -1667,11 +1614,10 @@ index d1e1caa..6df236a 100644 + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 93929e0..4cf0c78 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char *, char *, Key *); +diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h +--- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 13:41:15.048883853 +0100 ++++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 +0100 +@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char int mm_user_key_allowed(struct passwd *, Key *); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); @@ -1689,26 +1635,25 @@ index 93929e0..4cf0c78 100644 +int mm_audit_run_command(const char *); +void mm_audit_end_command(int, const char *); +void mm_audit_unsupported_body(int); -+void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); +void mm_audit_session_key_free_body(int, pid_t, uid_t); +void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); #endif struct Session; -diff --git a/packet.c b/packet.c -index 660a9fc..f5b122b 100644 ---- a/packet.c -+++ b/packet.c -@@ -61,6 +61,7 @@ - #include +diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c +--- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 +0100 ++++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 +@@ -67,6 +67,7 @@ + #include "key.h" /* typedefs XXX */ #include "xmalloc.h" +#include "audit.h" - #include "buffer.h" - #include "packet.h" #include "crc32.h" -@@ -476,6 +477,13 @@ packet_get_connection_out(void) - return active_state->connection_out; + #include "deattack.h" + #include "compat.h" +@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh + return ssh->state->connection_out; } +static int @@ -1718,50 +1663,66 @@ index 660a9fc..f5b122b 100644 + (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL); +} + - /* Closes the connection and clears and frees internal data structures. */ - - void -@@ -484,13 +492,6 @@ packet_close(void) - if (!active_state->initialized) + /* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. +@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) + if (!state->initialized) return; - active_state->initialized = 0; -- if (active_state->connection_in == active_state->connection_out) { -- shutdown(active_state->connection_out, SHUT_RDWR); -- close(active_state->connection_out); + state->initialized = 0; +- if (state->connection_in == state->connection_out) { +- shutdown(state->connection_out, SHUT_RDWR); +- close(state->connection_out); - } else { -- close(active_state->connection_in); -- close(active_state->connection_out); +- close(state->connection_in); +- close(state->connection_out); - } - buffer_free(&active_state->input); - buffer_free(&active_state->output); - buffer_free(&active_state->outgoing_packet); -@@ -499,8 +500,18 @@ packet_close(void) - buffer_free(&active_state->compression_buffer); - buffer_compress_uninit(); + sshbuf_free(state->input); + sshbuf_free(state->output); + sshbuf_free(state->outgoing_packet); +@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) + inflateEnd(stream); + } } -- cipher_cleanup(&active_state->send_context); -- cipher_cleanup(&active_state->receive_context); -+ if (packet_state_has_keys(active_state)) { -+ cipher_cleanup(&active_state->send_context); -+ cipher_cleanup(&active_state->receive_context); +- if ((r = cipher_cleanup(&state->send_context)) != 0) +- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); +- if ((r = cipher_cleanup(&state->receive_context)) != 0) +- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ if (packet_state_has_keys(state)) { ++ if ((r = cipher_cleanup(&state->send_context)) != 0) ++ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ if ((r = cipher_cleanup(&state->receive_context)) != 0) ++ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); + audit_session_key_free(2); + } -+ if (active_state->connection_in == active_state->connection_out) { -+ shutdown(active_state->connection_out, SHUT_RDWR); -+ close(active_state->connection_out); + if (ssh->remote_ipaddr) { + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + } ++ if (state->connection_in == state->connection_out) { ++ shutdown(state->connection_out, SHUT_RDWR); ++ close(state->connection_out); + } else { -+ close(active_state->connection_in); -+ close(active_state->connection_out); ++ close(state->connection_in); ++ close(state->connection_out); + } + free(ssh->state); + ssh->state = NULL; } - - /* Sets remote side protocol flags. */ -@@ -736,6 +747,25 @@ packet_send1(void) - */ +@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + } + if (state->newkeys[mode] != NULL) { + debug("set_newkeys: rekeying"); ++ audit_session_key_free(mode); + if ((r = cipher_cleanup(cc)) != 0) + return r; + enc = &state->newkeys[mode]->enc; +@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) + return (void *)ssh->state->output; } +static void -+newkeys_destroy_and_free(Newkeys *newkeys) ++newkeys_destroy_and_free(struct newkeys *newkeys) +{ + if (newkeys == NULL) + return; @@ -1779,21 +1740,6 @@ index 660a9fc..f5b122b 100644 + free(newkeys); +} + - void - set_newkeys(int mode) - { -@@ -761,6 +791,7 @@ set_newkeys(int mode) - } - if (active_state->newkeys[mode] != NULL) { - debug("set_newkeys: rekeying"); -+ audit_session_key_free(mode); - cipher_cleanup(cc); - enc = &active_state->newkeys[mode]->enc; - mac = &active_state->newkeys[mode]->mac; -@@ -2011,6 +2042,47 @@ packet_get_newkeys(int mode) - return (void *)active_state->newkeys[mode]; - } - +static void +packet_destroy_state(struct session_state *state) +{ @@ -1803,11 +1749,18 @@ index 660a9fc..f5b122b 100644 + cipher_cleanup(&state->receive_context); + cipher_cleanup(&state->send_context); + -+ buffer_free(&state->input); -+ buffer_free(&state->output); -+ buffer_free(&state->outgoing_packet); -+ buffer_free(&state->incoming_packet); -+ buffer_free(&state->compression_buffer); ++ buffer_free(state->input); ++ state->input = NULL; ++ buffer_free(state->output); ++ state->output = NULL; ++ buffer_free(state->outgoing_packet); ++ state->outgoing_packet = NULL; ++ buffer_free(state->incoming_packet); ++ state->incoming_packet = NULL; ++ if( state->compression_buffer ) { ++ buffer_free(state->compression_buffer); ++ state->compression_buffer = NULL; ++ } + newkeys_destroy_and_free(state->newkeys[MODE_IN]); + state->newkeys[MODE_IN] = NULL; + newkeys_destroy_and_free(state->newkeys[MODE_OUT]); @@ -1821,10 +1774,12 @@ index 660a9fc..f5b122b 100644 +packet_destroy_all(int audit_it, int privsep) +{ + if (audit_it) -+ audit_it = packet_state_has_keys (active_state) || -+ packet_state_has_keys (backup_state); -+ packet_destroy_state(active_state); -+ packet_destroy_state(backup_state); ++ audit_it = (active_state != NULL && packet_state_has_keys(active_state->state)) ++ || (backup_state != NULL && packet_state_has_keys(backup_state->state)); ++ if (active_state != NULL) ++ packet_destroy_state(active_state->state); ++ if (backup_state != NULL) ++ packet_destroy_state(backup_state->state); + if (audit_it) { +#ifdef SSH_AUDIT_EVENTS + if (privsep) @@ -1835,65 +1790,73 @@ index 660a9fc..f5b122b 100644 + } +} + + /* XXX TODO update roaming to new API (does not work anyway) */ /* * Save the state for the real connection, and use a separate state when - * resuming a suspended connection. -@@ -2018,18 +2090,12 @@ packet_get_newkeys(int mode) - void - packet_backup_state(void) +@@ -2272,18 +2373,12 @@ void + ssh_packet_backup_state(struct ssh *ssh, + struct ssh *backup_state) { -- struct session_state *tmp; +- struct ssh *tmp; - - close(active_state->connection_in); - active_state->connection_in = -1; - close(active_state->connection_out); - active_state->connection_out = -1; + close(ssh->state->connection_in); + ssh->state->connection_in = -1; + close(ssh->state->connection_out); + ssh->state->connection_out = -1; - if (backup_state) - tmp = backup_state; - else -- tmp = alloc_session_state(); - backup_state = active_state; -- active_state = tmp; -+ active_state = alloc_session_state(); +- tmp = ssh_alloc_session_state(); + backup_state = ssh; +- ssh = tmp; ++ ssh = ssh_alloc_session_state(); } - /* -@@ -2046,9 +2112,7 @@ packet_restore_state(void) - backup_state = active_state; - active_state = tmp; - active_state->connection_in = backup_state->connection_in; -- backup_state->connection_in = -1; - active_state->connection_out = backup_state->connection_out; -- backup_state->connection_out = -1; - len = buffer_len(&backup_state->input); + /* XXX FIXME FIXME FIXME */ +@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh + backup_state = ssh; + ssh = tmp; + ssh->state->connection_in = backup_state->state->connection_in; +- backup_state->state->connection_in = -1; + ssh->state->connection_out = backup_state->state->connection_out; +- backup_state->state->connection_out = -1; + len = sshbuf_len(backup_state->state->input); if (len > 0) { - buf = buffer_ptr(&backup_state->input); -@@ -2056,4 +2120,10 @@ packet_restore_state(void) - buffer_clear(&backup_state->input); + if ((r = sshbuf_putb(ssh->state->input, +@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh + sshbuf_reset(backup_state->state->input); add_recv_bytes(len); } -+ backup_state->connection_in = -1; -+ backup_state->connection_out = -1; -+ packet_destroy_state(backup_state); ++ backup_state->state->connection_in = -1; ++ backup_state->state->connection_out = -1; ++ packet_destroy_state(backup_state->state); + free(backup_state); + backup_state = NULL; } -+ -diff --git a/packet.h b/packet.h -index f8edf85..c36c812 100644 ---- a/packet.h -+++ b/packet.h -@@ -124,4 +124,5 @@ void packet_restore_state(void); - void *packet_get_input(void); - void *packet_get_output(void); + + /* Reset after_authentication and reset compression in post-auth privsep */ +diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h +--- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 +@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); + const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); + + /* OLD API */ +-extern struct ssh *active_state; ++extern struct ssh *active_state, *backup_state; + #include "opacket.h" + + #if !defined(WITH_OPENSSL) +@@ -203,4 +203,5 @@ extern struct ssh *active_state; + # undef EC_POINT + #endif +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff --git a/session.c b/session.c -index df43592..b186ca1 100644 ---- a/session.c -+++ b/session.c -@@ -138,7 +138,7 @@ extern int log_stderr; +diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c +--- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 +0100 ++++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 +@@ -139,7 +139,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1902,7 +1865,7 @@ index df43592..b186ca1 100644 extern Buffer loginmsg; /* original command from peer. */ -@@ -746,6 +746,14 @@ do_exec_pty(Session *s, const char *command) +@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1917,7 +1880,7 @@ index df43592..b186ca1 100644 /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -863,15 +871,19 @@ do_exec(Session *s, const char *command) +@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) get_remote_port()); #ifdef SSH_AUDIT_EVENTS @@ -1934,12 +1897,12 @@ index df43592..b186ca1 100644 - PRIVSEP(audit_run_command(shell)); + s->command = xstrdup(shell); } -+ if (s->command != NULL) ++ if (s->command != NULL && s->ptyfd == -1) + s->command_handle = PRIVSEP(audit_run_command(s->command)); #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1708,7 +1720,10 @@ do_child(Session *s, const char *command) +@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command int r = 0; /* remove hostkey from the child's memory */ @@ -1951,7 +1914,7 @@ index df43592..b186ca1 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1933,6 +1948,7 @@ session_unused(int id) +@@ -1934,6 +1949,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1959,7 +1922,7 @@ index df43592..b186ca1 100644 sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2015,6 +2031,19 @@ session_open(Authctxt *authctxt, int chanid) +@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1979,7 +1942,7 @@ index df43592..b186ca1 100644 session_by_tty(char *tty) { int i; -@@ -2531,6 +2560,30 @@ session_exit_message(Session *s, int status) +@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta chan_write_failed(c); } @@ -1988,7 +1951,8 @@ index df43592..b186ca1 100644 +session_end_command2(Session *s) +{ + if (s->command != NULL) { -+ audit_end_command(s->command_handle, s->command); ++ if (s->command_handle != -1) ++ audit_end_command(s->command_handle, s->command); + free(s->command); + s->command = NULL; + s->command_handle = -1; @@ -1999,7 +1963,8 @@ index df43592..b186ca1 100644 +session_end_command(Session *s) +{ + if (s->command != NULL) { -+ PRIVSEP(audit_end_command(s->command_handle, s->command)); ++ if (s->command_handle != -1) ++ PRIVSEP(audit_end_command(s->command_handle, s->command)); + free(s->command); + s->command = NULL; + s->command_handle = -1; @@ -2010,7 +1975,7 @@ index df43592..b186ca1 100644 void session_close(Session *s) { -@@ -2539,6 +2592,10 @@ session_close(Session *s) +@@ -2540,6 +2593,10 @@ session_close(Session *s) debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -2021,7 +1986,7 @@ index df43592..b186ca1 100644 free(s->term); free(s->display); free(s->x11_chanids); -@@ -2753,6 +2810,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -2037,17 +2002,16 @@ index df43592..b186ca1 100644 void do_cleanup(Authctxt *authctxt) { -@@ -2801,5 +2867,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff --git a/session.h b/session.h -index 6a2f35e..e9b312e 100644 ---- a/session.h -+++ b/session.h +diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h +--- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2072,19 +2036,18 @@ index 6a2f35e..e9b312e 100644 Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff --git a/sshd.c b/sshd.c -index 8a0740a..2813aa2 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -119,6 +119,7 @@ +diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 +@@ -121,6 +124,7 @@ #endif #include "monitor_wrap.h" #include "roaming.h" +#include "audit.h" #include "ssh-sandbox.h" #include "version.h" - -@@ -264,7 +265,7 @@ Buffer loginmsg; + #include "ssherr.h" +@@ -260,7 +264,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2092,8 +2055,8 @@ index 8a0740a..2813aa2 100644 +void destroy_sensitive_data(int); void demote_sensitive_data(void); - static void do_ssh1_kex(void); -@@ -283,6 +284,15 @@ close_listen_socks(void) + #ifdef WITH_SSH1 +@@ -281,6 +285,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2109,7 +2072,7 @@ index 8a0740a..2813aa2 100644 static void close_startup_pipes(void) { -@@ -562,22 +572,45 @@ sshd_exchange_identification(int sock_in, int sock_out) +@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in } } @@ -2137,7 +2100,7 @@ index 8a0740a..2813aa2 100644 + char *fp; + + if (key_is_private(sensitive_data.host_keys[i])) -+ fp = key_selected_fingerprint(sensitive_data.host_keys[i], SSH_FP_HEX); ++ fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; key_free(sensitive_data.host_keys[i]); @@ -2158,7 +2121,7 @@ index 8a0740a..2813aa2 100644 key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -591,6 +624,8 @@ void +@@ -589,6 +625,8 @@ void demote_sensitive_data(void) { Key *tmp; @@ -2167,7 +2130,7 @@ index 8a0740a..2813aa2 100644 int i; if (sensitive_data.server_key) { -@@ -599,13 +634,25 @@ demote_sensitive_data(void) +@@ -597,13 +635,25 @@ demote_sensitive_data(void) sensitive_data.server_key = tmp; } @@ -2178,7 +2141,7 @@ index 8a0740a..2813aa2 100644 + char *fp; + + if (key_is_private(sensitive_data.host_keys[i])) -+ fp = key_selected_fingerprint(sensitive_data.host_keys[i], SSH_FP_HEX); ++ fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; tmp = key_demote(sensitive_data.host_keys[i]); @@ -2193,7 +2156,7 @@ index 8a0740a..2813aa2 100644 } /* Certs do not need demotion */ } -@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2202,35 +2165,28 @@ index 8a0740a..2813aa2 100644 if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -729,6 +776,8 @@ privsep_preauth(Authctxt *authctxt) - } - } - -+extern Newkeys *current_keys[]; -+ - static void - privsep_postauth(Authctxt *authctxt) - { -@@ -753,6 +802,10 @@ privsep_postauth(Authctxt *authctxt) +@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); -+ newkeys_destroy(current_keys[MODE_OUT]); -+ newkeys_destroy(current_keys[MODE_IN]); -+ audit_session_key_free_body(2, getpid(), getuid()); -+ packet_destroy_all(0, 0); ++ if (*pmonitor->m_pkex != NULL ){ ++ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); ++ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]); ++ audit_session_key_free_body(2, getpid(), getuid()); ++ packet_destroy_all(0, 0); ++ } monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1211,6 +1264,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) +@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); + destroy_sensitive_data(0); close_listen_socks(); - unlink(options.pid_file); - exit(received_sigterm == SIGTERM ? 0 : 255); -@@ -2134,6 +2188,7 @@ main(int ac, char **av) + if (options.pid_file != NULL) + unlink(options.pid_file); +@@ -2242,6 +2321,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2238,7 +2194,7 @@ index 8a0740a..2813aa2 100644 exit(0); } -@@ -2179,7 +2234,7 @@ main(int ac, char **av) +@@ -2287,7 +2367,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2247,37 +2203,37 @@ index 8a0740a..2813aa2 100644 } packet_set_timeout(options.client_alive_interval, -@@ -2189,6 +2244,9 @@ main(int ac, char **av) +@@ -2301,6 +2381,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ + packet_destroy_all(1, 1); + destroy_sensitive_data(1); + - packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); - packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", -@@ -2346,6 +2404,10 @@ do_ssh1_kex(void) + (unsigned long long)obytes, (unsigned long long)ibytes); +@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); +#ifdef SSH_AUDIT_EVENTS -+ audit_kex(2, cipher_name(cipher_type), "crc", "none"); ++ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); +#endif + debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2418,7 +2480,7 @@ do_ssh1_kex(void) - session_id[i] = session_key[i] ^ session_key[i + 16]; +@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) } + /* Destroy the private and public keys. No longer. */ - destroy_sensitive_data(); -+ destroy_sensitive_data(0); ++ destroy_sensitive_data(1); if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2584,6 +2646,16 @@ do_ssh2_kex(void) +@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2293,8 +2249,8 @@ index 8a0740a..2813aa2 100644 + if (the_authctxt) { do_cleanup(the_authctxt); - if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) { -@@ -2594,9 +2666,14 @@ cleanup_exit(int i) + if (use_privsep && privsep_is_preauth && +@@ -2714,9 +2823,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2310,3 +2266,67 @@ index 8a0740a..2813aa2 100644 audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); +diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c +--- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 +@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) + } + + int ++sshkey_is_private(const struct sshkey *k) ++{ ++ switch (k->type) { ++ case KEY_RSA_CERT_V00: ++ case KEY_RSA_CERT: ++ case KEY_RSA1: ++ case KEY_RSA: ++ return k->rsa->d != NULL; ++ case KEY_DSA_CERT_V00: ++ case KEY_DSA_CERT: ++ case KEY_DSA: ++ return k->dsa->priv_key != NULL; ++#ifdef OPENSSL_HAS_ECC ++ case KEY_ECDSA_CERT: ++ case KEY_ECDSA: ++ return EC_KEY_get0_private_key(k->ecdsa) != NULL; ++#endif ++ case KEY_ED25519_CERT: ++ case KEY_ED25519: ++ return (k->ed25519_pk != NULL); ++ default: ++ /* fatal("key_is_private: bad key type %d", k->type); */ ++ return 0; ++ } ++} ++ ++int + sshkey_is_cert(const struct sshkey *k) + { + if (k == NULL) +diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h +--- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 +@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey + int sshkey_generate(int type, u_int bits, struct sshkey **keyp); + int sshkey_from_private(const struct sshkey *, struct sshkey **); + int sshkey_type_from_name(const char *); ++int sshkey_is_private(const struct sshkey *); + int sshkey_is_cert(const struct sshkey *); + int sshkey_type_is_cert(int); + int sshkey_type_plain(int); +diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit openssh-6.8p1/sandbox-seccomp-filter.c +--- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 13:41:15.088883788 +0100 ++++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 13:41:15.097883774 +0100 +@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ + #ifdef __NR_time /* not defined on EABI ARM */ + SC_ALLOW(time), + #endif ++#ifdef SSH_AUDIT_EVENTS ++ SC_ALLOW(getuid), ++#ifdef __NR_getuid32 /* not defined on x86_64 */ ++ SC_ALLOW(getuid32), ++#endif ++#endif + SC_ALLOW(read), + SC_ALLOW(write), + SC_ALLOW(close), diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch new file mode 100644 index 0000000..fe3b349 --- /dev/null +++ b/openssh-6.7p1-coverity.patch @@ -0,0 +1,471 @@ +diff -up openssh-6.8p1/auth-pam.c.coverity openssh-6.8p1/auth-pam.c +--- openssh-6.8p1/auth-pam.c.coverity 2015-03-18 17:21:51.792265051 +0100 ++++ openssh-6.8p1/auth-pam.c 2015-03-18 17:21:51.895264835 +0100 +@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * + if (sshpam_thread_status != -1) + return (sshpam_thread_status); + signal(SIGCHLD, sshpam_oldsig); +- waitpid(thread, &status, 0); ++ while (waitpid(thread, &status, 0) < 0) { ++ if (errno == EINTR) ++ continue; ++ fatal("%s: waitpid: %s", __func__, ++ strerror(errno)); ++ } + return (status); + } + #endif +diff -up openssh-6.8p1/channels.c.coverity openssh-6.8p1/channels.c +--- openssh-6.8p1/channels.c.coverity 2015-03-18 17:21:51.815265002 +0100 ++++ openssh-6.8p1/channels.c 2015-03-18 17:21:51.896264833 +0100 +@@ -243,11 +243,11 @@ channel_register_fds(Channel *c, int rfd + channel_max_fd = MAX(channel_max_fd, wfd); + channel_max_fd = MAX(channel_max_fd, efd); + +- if (rfd != -1) ++ if (rfd >= 0) + fcntl(rfd, F_SETFD, FD_CLOEXEC); +- if (wfd != -1 && wfd != rfd) ++ if (wfd >= 0 && wfd != rfd) + fcntl(wfd, F_SETFD, FD_CLOEXEC); +- if (efd != -1 && efd != rfd && efd != wfd) ++ if (efd >= 0 && efd != rfd && efd != wfd) + fcntl(efd, F_SETFD, FD_CLOEXEC); + + c->rfd = rfd; +@@ -265,11 +265,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); + } + } +@@ -3972,13 +3972,13 @@ connect_local_xsocket_path(const char *p + int sock; + struct sockaddr_un addr; + ++ if (len <= 0) ++ return -1; + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; +- if (len <= 0) +- return -1; + if (len > sizeof addr.sun_path) + len = sizeof addr.sun_path; + memcpy(addr.sun_path, pathname, len); +diff -up openssh-6.8p1/entropy.c.coverity openssh-6.8p1/entropy.c +--- openssh-6.8p1/entropy.c.coverity 2015-03-18 17:21:51.891264843 +0100 ++++ openssh-6.8p1/entropy.c 2015-03-18 17:21:51.897264831 +0100 +@@ -46,6 +46,7 @@ + #include + + #include "openbsd-compat/openssl-compat.h" ++#include "openbsd-compat/port-linux.h" + + #include "ssh.h" + #include "misc.h" +diff -up openssh-6.8p1/monitor.c.coverity openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.coverity 2015-03-18 17:21:51.887264852 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-18 17:21:51.897264831 +0100 +@@ -444,7 +444,7 @@ monitor_child_preauth(Authctxt *_authctx + mm_get_keystate(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) + ; + + close(pmonitor->m_sendfd); +@@ -1303,6 +1303,10 @@ mm_answer_keyallowed(int sock, Buffer *m + break; + } + } ++ ++ debug3("%s: key %p is %s", ++ __func__, key, allowed ? "allowed" : "not allowed"); ++ + if (key != NULL) + key_free(key); + +@@ -1324,9 +1328,6 @@ mm_answer_keyallowed(int sock, Buffer *m + free(chost); + } + +- debug3("%s: key %p is %s", +- __func__, key, allowed ? "allowed" : "not allowed"); +- + buffer_clear(m); + buffer_put_int(m, allowed); + buffer_put_int(m, forced_command != NULL); +diff -up openssh-6.8p1/monitor_wrap.c.coverity openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1/monitor_wrap.c.coverity 2015-03-18 17:21:51.888264849 +0100 ++++ openssh-6.8p1/monitor_wrap.c 2015-03-18 17:21:51.897264831 +0100 +@@ -533,10 +533,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-6.8p1/openbsd-compat/bindresvport.c.coverity openssh-6.8p1/openbsd-compat/bindresvport.c +--- openssh-6.8p1/openbsd-compat/bindresvport.c.coverity 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/openbsd-compat/bindresvport.c 2015-03-18 17:21:51.897264831 +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-6.8p1/openbsd-compat/port-linux.h.coverity openssh-6.8p1/openbsd-compat/port-linux.h +--- openssh-6.8p1/openbsd-compat/port-linux.h.coverity 2015-03-18 17:21:51.861264906 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 17:21:51.897264831 +0100 +@@ -37,4 +37,6 @@ void oom_adjust_restore(void); + void oom_adjust_setup(void); + #endif + ++void linux_seed(void); ++ + #endif /* ! _PORT_LINUX_H */ +diff -up openssh-6.8p1/scp.c.coverity openssh-6.8p1/scp.c +--- openssh-6.8p1/scp.c.coverity 2015-03-18 17:21:51.868264891 +0100 ++++ openssh-6.8p1/scp.c 2015-03-18 17:21:58.281251460 +0100 +@@ -156,7 +156,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-6.8p1/servconf.c.coverity openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.coverity 2015-03-18 17:21:51.893264839 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 17:21:58.281251460 +0100 +@@ -1475,7 +1475,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++) +@@ -1566,8 +1566,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-6.8p1/serverloop.c.coverity openssh-6.8p1/serverloop.c +--- openssh-6.8p1/serverloop.c.coverity 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/serverloop.c 2015-03-18 17:28:45.616436080 +0100 +@@ -147,13 +147,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 +@@ -161,8 +161,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("notify_done: reading"); + } + +@@ -337,7 +337,7 @@ wait_until_can_do_something(fd_set **rea + * If we have buffered data, try to write some of that data + * to the program. + */ +- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) ++ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) + FD_SET(fdin, *writesetp); + } + notify_prepare(*readsetp); +@@ -477,7 +477,7 @@ process_output(fd_set *writeset) + int len; + + /* Write buffered data to program stdin. */ +- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { ++ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { + data = buffer_ptr(&stdin_buffer); + dlen = buffer_len(&stdin_buffer); + len = write(fdin, data, dlen); +@@ -590,7 +590,7 @@ server_loop(pid_t pid, int fdin_arg, int + set_nonblock(fdin); + set_nonblock(fdout); + /* we don't have stderr for interactive terminal sessions, see below */ +- if (fderr != -1) ++ if (fderr >= 0) + set_nonblock(fderr); + + if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) +@@ -614,7 +614,7 @@ server_loop(pid_t pid, int fdin_arg, int + max_fd = MAX(connection_in, connection_out); + max_fd = MAX(max_fd, fdin); + max_fd = MAX(max_fd, fdout); +- if (fderr != -1) ++ if (fderr >= 0) + max_fd = MAX(max_fd, fderr); + #endif + +@@ -644,7 +644,7 @@ server_loop(pid_t pid, int fdin_arg, int + * If we have received eof, and there is no more pending + * input data, cause a real eof by closing fdin. + */ +- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { ++ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { + if (fdin != fdout) + close(fdin); + else +@@ -740,15 +740,15 @@ server_loop(pid_t pid, int fdin_arg, int + buffer_free(&stderr_buffer); + + /* Close the file descriptors. */ +- if (fdout != -1) ++ if (fdout >= 0) + close(fdout); + fdout = -1; + fdout_eof = 1; +- if (fderr != -1) ++ if (fderr >= 0) + close(fderr); + fderr = -1; + fderr_eof = 1; +- if (fdin != -1) ++ if (fdin >= 0) + close(fdin); + fdin = -1; + +@@ -950,7 +950,7 @@ server_input_window_size(int type, u_int + + debug("Window change received."); + packet_check_eom(); +- if (fdin != -1) ++ if (fdin >= 0) + pty_change_window_size(fdin, row, col, xpixel, ypixel); + return 0; + } +@@ -1043,7 +1043,7 @@ server_request_tun(void) + } + + tun = packet_get_int(); +- if (forced_tun_device != -1) { ++ if (forced_tun_device >= 0) { + if (tun != SSH_TUNID_ANY && forced_tun_device != tun) + goto done; + tun = forced_tun_device; +diff -up openssh-6.8p1/sftp.c.coverity openssh-6.8p1/sftp.c +--- openssh-6.8p1/sftp.c.coverity 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp.c 2015-03-18 17:21:58.283251456 +0100 +@@ -223,7 +223,7 @@ killchild(int signo) + { + if (sshpid > 1) { + kill(sshpid, SIGTERM); +- waitpid(sshpid, NULL, 0); ++ (void) waitpid(sshpid, NULL, 0); + } + + _exit(1); +@@ -335,7 +335,7 @@ local_do_ls(const char *args) + + /* Strip one path (usually the pwd) from the start of another */ + static char * +-path_strip(char *path, char *strip) ++path_strip(const char *path, const char *strip) + { + size_t len; + +@@ -353,7 +353,7 @@ path_strip(char *path, char *strip) + } + + static char * +-make_absolute(char *p, char *pwd) ++make_absolute(char *p, const char *pwd) + { + char *abs_str; + +@@ -551,7 +551,7 @@ parse_no_flags(const char *cmd, char **a + } + + static int +-is_dir(char *path) ++is_dir(const char *path) + { + struct stat sb; + +@@ -563,7 +563,7 @@ is_dir(char *path) + } + + static int +-remote_is_dir(struct sftp_conn *conn, char *path) ++remote_is_dir(struct sftp_conn *conn, const char *path) + { + Attrib *a; + +@@ -577,7 +577,7 @@ remote_is_dir(struct sftp_conn *conn, ch + + /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ + static int +-pathname_is_dir(char *pathname) ++pathname_is_dir(const char *pathname) + { + size_t l = strlen(pathname); + +@@ -585,7 +585,7 @@ pathname_is_dir(char *pathname) + } + + static int +-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, ++process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, + int pflag, int rflag, int resume, int fflag) + { + char *abs_src = NULL; +@@ -669,7 +669,7 @@ out: + } + + static int +-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, ++process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, + int pflag, int rflag, int resume, int fflag) + { + char *tmp_dst = NULL; +@@ -779,7 +779,7 @@ sdirent_comp(const void *aa, const void + + /* sftp ls.1 replacement for directories */ + static int +-do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) ++do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) + { + int n; + u_int c = 1, colspace = 0, columns = 1; +@@ -864,7 +864,7 @@ do_ls_dir(struct sftp_conn *conn, char * + + /* sftp ls.1 replacement which handles path globs */ + static int +-do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, ++do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, + int lflag) + { + char *fname, *lname; +@@ -949,7 +949,7 @@ do_globbed_ls(struct sftp_conn *conn, ch + } + + static int +-do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) ++do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) + { + struct sftp_statvfs st; + char s_used[FMT_SCALED_STRSIZE]; +diff -up openssh-6.8p1/ssh-agent.c.coverity openssh-6.8p1/ssh-agent.c +--- openssh-6.8p1/ssh-agent.c.coverity 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/ssh-agent.c 2015-03-18 17:21:58.284251454 +0100 +@@ -1166,8 +1166,8 @@ main(int ac, char **av) + sanitise_stdfd(); + + /* drop */ +- setegid(getgid()); +- setgid(getgid()); ++ (void) setegid(getgid()); ++ (void) setgid(getgid()); + + #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* Disable ptrace on Linux without sgid bit */ +diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.coverity 2015-03-18 17:21:51.893264839 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 17:21:58.284251454 +0100 +@@ -778,8 +778,10 @@ privsep_preauth(Authctxt *authctxt) + if (getuid() == 0 || geteuid() == 0) + privsep_preauth_child(); + setproctitle("%s", "[net]"); +- if (box != NULL) ++ if (box != NULL) { + ssh_sandbox_child(box); ++ free(box); ++ } + + return 0; + } +@@ -1518,6 +1520,9 @@ server_accept_loop(int *sock_in, int *so + if (num_listen_socks < 0) + break; + } ++ ++ if (fdset != NULL) ++ free(fdset); + } + + +diff -up openssh-6.8p1/sshkey.c.coverity openssh-6.8p1/sshkey.c +--- openssh-6.8p1/sshkey.c.coverity 2015-03-18 17:21:58.285251452 +0100 ++++ openssh-6.8p1/sshkey.c 2015-03-18 17:45:32.232705363 +0100 +@@ -58,6 +58,7 @@ + #include "digest.h" + #define SSHKEY_INTERNAL + #include "sshkey.h" ++#include "log.h" + #include "match.h" + + /* openssh private key file format */ +diff --git a/sshd.c b/sshd.c +index 6ff8f6f..2f2fcf8 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1548,6 +1548,7 @@ main(int ac, char **av) + int keytype; + Authctxt *authctxt; + struct connection_info *connection_info = get_connection_info(0, 0); ++ char *addr = NULL; + + #ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +@@ -2261,7 +2262,8 @@ main(int ac, char **av) + /* Log the connection. */ + verbose("Connection from %s port %d on %s port %d", + remote_ip, remote_port, +- get_local_ipaddr(sock_in), get_local_port()); ++ (addr = get_local_ipaddr(sock_in)), get_local_port()); ++ free(addr); + + /* + * We don't want to listen forever unless the other side diff --git a/openssh-6.7p1-debian-restore-tcp-wrappers.patch b/openssh-6.7p1-debian-restore-tcp-wrappers.patch new file mode 100644 index 0000000..63d62a0 --- /dev/null +++ b/openssh-6.7p1-debian-restore-tcp-wrappers.patch @@ -0,0 +1,140 @@ +diff -up openssh-6.8p1/configure.ac.tcp_wrappers openssh-6.8p1/configure.ac +--- openssh-6.8p1/configure.ac.tcp_wrappers 2015-03-18 13:05:57.365071779 +0100 ++++ openssh-6.8p1/configure.ac 2015-03-18 13:05:57.408071673 +0100 +@@ -1440,6 +1440,62 @@ AC_ARG_WITH([skey], + ] + ) + ++# Check whether user wants TCP wrappers support ++TCPW_MSG="no" ++AC_ARG_WITH([tcp-wrappers], ++ [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], ++ [ ++ if test "x$withval" != "xno" ; then ++ saved_LIBS="$LIBS" ++ saved_LDFLAGS="$LDFLAGS" ++ saved_CPPFLAGS="$CPPFLAGS" ++ if test -n "${withval}" && \ ++ test "x${withval}" != "xyes"; then ++ if test -d "${withval}/lib"; then ++ if test -n "${need_dash_r}"; then ++ LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" ++ else ++ LDFLAGS="-L${withval}/lib ${LDFLAGS}" ++ fi ++ else ++ if test -n "${need_dash_r}"; then ++ LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" ++ else ++ LDFLAGS="-L${withval} ${LDFLAGS}" ++ fi ++ fi ++ if test -d "${withval}/include"; then ++ CPPFLAGS="-I${withval}/include ${CPPFLAGS}" ++ else ++ CPPFLAGS="-I${withval} ${CPPFLAGS}" ++ fi ++ fi ++ LIBS="-lwrap $LIBS" ++ AC_MSG_CHECKING([for libwrap]) ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ++#include ++#include ++#include ++#include ++int deny_severity = 0, allow_severity = 0; ++ ]], [[ ++ hosts_access(0); ++ ]])], [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE([LIBWRAP], [1], ++ [Define if you want ++ TCP Wrappers support]) ++ SSHDLIBS="$SSHDLIBS -lwrap" ++ TCPW_MSG="yes" ++ ], [ ++ AC_MSG_ERROR([*** libwrap missing]) ++ ++ ]) ++ LIBS="$saved_LIBS" ++ fi ++ ] ++) ++ + # Check whether user wants to use ldns + LDNS_MSG="no" + AC_ARG_WITH(ldns, +@@ -5026,6 +5082,7 @@ echo " KerberosV support + echo " SELinux support: $SELINUX_MSG" + echo " Smartcard support: $SCARD_MSG" + echo " S/KEY support: $SKEY_MSG" ++echo " TCP Wrappers support: $TCPW_MSG" + echo " MD5 password support: $MD5_MSG" + echo " libedit support: $LIBEDIT_MSG" + echo " Solaris process contract support: $SPC_MSG" +diff -up openssh-6.8p1/sshd.8.tcp_wrappers openssh-6.8p1/sshd.8 +--- openssh-6.8p1/sshd.8.tcp_wrappers 2015-03-18 13:05:57.377071749 +0100 ++++ openssh-6.8p1/sshd.8 2015-03-18 13:05:57.408071673 +0100 +@@ -858,6 +858,12 @@ the user's home directory becomes access + This file should be writable only by the user, and need not be + readable by anyone else. + .Pp ++.It Pa /etc/hosts.allow ++.It Pa /etc/hosts.deny ++Access controls that should be enforced by tcp-wrappers are defined here. ++Further details are described in ++.Xr hosts_access 5 . ++.Pp + .It Pa /etc/hosts.equiv + This file is for host-based authentication (see + .Xr ssh 1 ) . +@@ -981,6 +987,7 @@ IPv6 address can be used everywhere wher + .Xr ssh-keygen 1 , + .Xr ssh-keyscan 1 , + .Xr chroot 2 , ++.Xr hosts_access 5 , + .Xr login.conf 5 , + .Xr moduli 5 , + .Xr sshd_config 5 , +diff -up openssh-6.8p1/sshd.c.tcp_wrappers openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.tcp_wrappers 2015-03-18 13:05:57.402071688 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-18 13:06:48.199947136 +0100 +@@ -125,6 +125,13 @@ + #include "version.h" + #include "ssherr.h" + ++#ifdef LIBWRAP ++#include ++#include ++int allow_severity; ++int deny_severity; ++#endif /* LIBWRAP */ ++ + #ifndef O_NOCTTY + #define O_NOCTTY 0 + #endif +@@ -2150,6 +2157,24 @@ main(int ac, char **av) + #ifdef SSH_AUDIT_EVENTS + audit_connection_from(remote_ip, remote_port); + #endif ++#ifdef LIBWRAP ++ allow_severity = options.log_facility|LOG_INFO; ++ deny_severity = options.log_facility|LOG_WARNING; ++ /* Check whether logins are denied from this host. */ ++ if (packet_connection_is_on_socket()) { ++ struct request_info req; ++ ++ request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); ++ fromhost(&req); ++ ++ if (!hosts_access(&req)) { ++ debug("Connection refused by tcp wrapper"); ++ refuse(&req); ++ /* NOTREACHED */ ++ fatal("libwrap refuse returns"); ++ } ++ } ++#endif /* LIBWRAP */ + + /* Log the connection. */ + verbose("Connection from %s port %d on %s port %d", diff --git a/openssh-6.6p1-fips.patch b/openssh-6.7p1-fips.patch similarity index 61% rename from openssh-6.6p1-fips.patch rename to openssh-6.7p1-fips.patch index f97e2ba..0aafdcc 100644 --- a/openssh-6.6p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -1,8 +1,7 @@ -diff --git a/Makefile.in b/Makefile.in -index 3bb7f00..294bef5 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -154,25 +154,25 @@ libssh.a: $(LIBSSH_OBJS) +diff -up openssh-6.8p1/Makefile.in.fips openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.fips 2015-03-19 13:14:22.221212174 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-19 13:14:22.230212157 +0100 +@@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) @@ -34,8 +33,8 @@ index 3bb7f00..294bef5 100644 ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -187,7 +187,7 @@ ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o - $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) +@@ -204,7 +204,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a + $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -43,81 +42,9 @@ index 3bb7f00..294bef5 100644 sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff --git a/auth-rsa.c b/auth-rsa.c -index f225b0b..8bafcd6 100644 ---- a/auth-rsa.c -+++ b/auth-rsa.c -@@ -244,7 +244,7 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, - "actual %d vs. announced %d.", - file, linenum, BN_num_bits(key->rsa->n), bits); - -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); - debug("matching key found: file %s, line %lu %s %s", - file, linenum, key_type(key), fp); - free(fp); -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 6d1c872..3808ec8 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -214,8 +214,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) - } - - if (key_is_cert(key)) { -- fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); - auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", - key_type(key), key->cert->key_id, - (unsigned long long)key->cert->serial, -@@ -223,7 +222,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) - extra == NULL ? "" : ", ", extra == NULL ? "" : extra); - free(fp); - } else { -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); - auth_info(authctxt, "%s %s%s%s", key_type(key), fp, - extra == NULL ? "" : ", ", extra == NULL ? "" : extra); - free(fp); -diff --git a/authfile.c b/authfile.c -index ec4f4ff..2b3d650 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - /* compatibility with old or broken OpenSSL versions */ - #include "openbsd-compat/openssl-compat.h" -@@ -1068,7 +1069,7 @@ Key * - key_parse_private(Buffer *buffer, const char *filename, - const char *passphrase, char **commentp) - { -- Key *pub, *prv; -+ Key *pub, *prv = NULL; - - /* it's a SSH v1 key if the public key part is readable */ - pub = key_parse_public_rsa1(buffer, commentp); -@@ -1080,9 +1081,10 @@ key_parse_private(Buffer *buffer, const char *filename, - *commentp = xstrdup(filename); - } else { - key_free(pub); -- /* key_parse_public_rsa1() has already loaded the comment */ -- prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, -- NULL); -+ if (! FIPS_mode()) -+ /* key_parse_public_rsa1() has already loaded the comment */ -+ prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, -+ NULL); - } - return prv; - } -diff --git a/cipher-ctr.c b/cipher-ctr.c -index 73e9c7c..40ee395 100644 ---- a/cipher-ctr.c -+++ b/cipher-ctr.c +diff -up openssh-6.8p1/cipher-ctr.c.fips openssh-6.8p1/cipher-ctr.c +--- openssh-6.8p1/cipher-ctr.c.fips 2015-03-19 13:14:22.155212302 +0100 ++++ openssh-6.8p1/cipher-ctr.c 2015-03-19 13:14:22.230212157 +0100 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -128,10 +55,9 @@ index 73e9c7c..40ee395 100644 #endif return (&aes_ctr); } -diff --git a/cipher.c b/cipher.c -index 226e56d..b19443c 100644 ---- a/cipher.c -+++ b/cipher.c +diff -up openssh-6.8p1/cipher.c.fips openssh-6.8p1/cipher.c +--- openssh-6.8p1/cipher.c.fips 2015-03-19 13:14:22.224212169 +0100 ++++ openssh-6.8p1/cipher.c 2015-03-19 13:14:22.230212157 +0100 @@ -39,6 +39,8 @@ #include @@ -141,11 +67,11 @@ index 226e56d..b19443c 100644 #include #include #include -@@ -90,6 +92,25 @@ static const struct Cipher ciphers[] = { +@@ -99,6 +101,26 @@ static const struct sshcipher ciphers[] { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; -+static const struct Cipher fips_ciphers[] = { ++static const struct sshcipher fips_ciphers[] = { + { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, + { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, + { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, @@ -164,38 +90,39 @@ index 226e56d..b19443c 100644 +#endif + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } +}; ++ /*--*/ - /* Returns a list of supported ciphers separated by the specified char. */ -@@ -100,7 +121,7 @@ cipher_alg_list(char sep, int auth_only) + /* Returns a comma-separated list of supported ciphers. */ +@@ -109,7 +131,7 @@ cipher_alg_list(char sep, int auth_only) size_t nlen, rlen = 0; - const Cipher *c; + const struct sshcipher *c; - for (c = ciphers; c->name != NULL; c++) { + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { if (c->number != SSH_CIPHER_SSH2) continue; if (auth_only && c->auth_len == 0) -@@ -180,7 +201,7 @@ const Cipher * +@@ -193,7 +215,7 @@ const struct sshcipher * cipher_by_name(const char *name) { - const Cipher *c; + const struct sshcipher *c; - for (c = ciphers; c->name != NULL; c++) + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) if (strcmp(c->name, name) == 0) return c; return NULL; -@@ -190,7 +211,7 @@ const Cipher * +@@ -203,7 +225,7 @@ const struct sshcipher * cipher_by_number(int id) { - const Cipher *c; + const struct sshcipher *c; - for (c = ciphers; c->name != NULL; c++) + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) if (c->number == id) return c; return NULL; -@@ -232,7 +253,7 @@ cipher_number(const char *name) - const Cipher *c; +@@ -244,7 +266,7 @@ cipher_number(const char *name) + const struct sshcipher *c; if (name == NULL) return -1; - for (c = ciphers; c->name != NULL; c++) @@ -203,11 +130,10 @@ index 226e56d..b19443c 100644 if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff --git a/dh.h b/dh.h -index 48f7b68..9ff39f4 100644 ---- a/dh.h -+++ b/dh.h -@@ -45,6 +45,7 @@ int dh_estimate(int); +diff -up openssh-6.8p1/dh.h.fips openssh-6.8p1/dh.h +--- openssh-6.8p1/dh.h.fips 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/dh.h 2015-03-19 13:14:22.230212157 +0100 +@@ -45,6 +45,7 @@ u_int dh_estimate(int); /* Min and max values from RFC4419. */ #define DH_GRP_MIN 1024 @@ -215,11 +141,10 @@ index 48f7b68..9ff39f4 100644 #define DH_GRP_MAX 8192 /* -diff --git a/entropy.c b/entropy.c -index b361a04..5616643 100644 ---- a/entropy.c -+++ b/entropy.c -@@ -222,6 +222,9 @@ seed_rng(void) +diff -up openssh-6.8p1/entropy.c.fips openssh-6.8p1/entropy.c +--- openssh-6.8p1/entropy.c.fips 2015-03-19 13:14:22.147212317 +0100 ++++ openssh-6.8p1/entropy.c 2015-03-19 13:14:22.230212157 +0100 +@@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -229,19 +154,18 @@ index b361a04..5616643 100644 #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff --git a/kex.c b/kex.c -index bc3e53e..ede7b67 100644 ---- a/kex.c -+++ b/kex.c -@@ -34,6 +34,7 @@ - #include +diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c +--- openssh-6.8p1/kex.c.fips 2015-03-19 13:14:22.165212282 +0100 ++++ openssh-6.8p1/kex.c 2015-03-19 13:14:22.230212157 +0100 +@@ -35,6 +35,7 @@ + #ifdef WITH_OPENSSL #include +#include + #endif - #include "xmalloc.h" #include "ssh2.h" -@@ -103,6 +104,25 @@ static const struct kexalg kexalgs[] = { +@@ -107,6 +108,25 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; @@ -261,13 +185,13 @@ index bc3e53e..ede7b67 100644 + SSH_DIGEST_SHA512 }, +# endif +#endif -+ { NULL, -1, -1, NULL}, ++ { NULL, -1, -1, -1}, +}; + char * kex_alg_list(char sep) { -@@ -126,7 +146,7 @@ kex_alg_by_name(const char *name) +@@ -134,7 +154,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -276,7 +200,7 @@ index bc3e53e..ede7b67 100644 if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -151,7 +171,10 @@ kex_names_valid(const char *names) +@@ -160,7 +180,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -288,60 +212,34 @@ index bc3e53e..ede7b67 100644 free(s); return 0; } -diff --git a/kexecdhc.c b/kexecdhc.c -index 2f7629c..20c9946 100644 ---- a/kexecdhc.c -+++ b/kexecdhc.c -@@ -154,6 +154,7 @@ kexecdh_client(Kex *kex) +diff -up openssh-6.8p1/kexgexc.c.fips openssh-6.8p1/kexgexc.c +--- openssh-6.8p1/kexgexc.c.fips 2015-03-19 13:14:22.196212223 +0100 ++++ openssh-6.8p1/kexgexc.c 2015-03-19 13:15:11.462117016 +0100 +@@ -28,6 +28,8 @@ - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); -+ memset(hash, 0, hashlen); - kex_finish(kex); - } - #else /* OPENSSL_HAS_ECC */ -diff --git a/kexecdhs.c b/kexecdhs.c -index 2700b72..0820894 100644 ---- a/kexecdhs.c -+++ b/kexecdhs.c -@@ -150,6 +150,7 @@ kexecdh_server(Kex *kex) - - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); -+ memset(hash, 0, hashlen); - kex_finish(kex); - } - #else /* OPENSSL_HAS_ECC */ -diff --git a/kexgexc.c b/kexgexc.c -index 355b7ba..427e11f 100644 ---- a/kexgexc.c -+++ b/kexgexc.c -@@ -26,6 +26,8 @@ - - #include "includes.h" + #ifdef WITH_OPENSSL +#include + #include #include -@@ -58,7 +60,7 @@ kexgex_client(Kex *kex) - int min, max, nbits; - DH *dh; +@@ -62,7 +64,7 @@ kexgex_client(struct ssh *ssh) -- min = DH_GRP_MIN; -+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - max = DH_GRP_MAX; + nbits = dh_estimate(kex->dh_need * 8); + +- kex->min = DH_GRP_MIN; ++ kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + kex->max = DH_GRP_MAX; /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. -diff --git a/kexgexs.c b/kexgexs.c -index 770ad28..9d4fc6d 100644 ---- a/kexgexs.c -+++ b/kexgexs.c -@@ -76,16 +76,16 @@ kexgex_server(Kex *kex) - omin = min = packet_get_int(); - onbits = nbits = packet_get_int(); - omax = max = packet_get_int(); +diff -up openssh-6.8p1/kexgexs.c.fips openssh-6.8p1/kexgexs.c +--- openssh-6.8p1/kexgexs.c.fips 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/kexgexs.c 2015-03-19 13:14:22.231212155 +0100 +@@ -87,9 +87,9 @@ input_kex_dh_gex_request(int type, u_int + kex->nbits = nbits; + kex->min = min; + kex->max = max; - min = MAX(DH_GRP_MIN, min); + min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); max = MIN(DH_GRP_MAX, max); @@ -350,70 +248,28 @@ index 770ad28..9d4fc6d 100644 nbits = MIN(DH_GRP_MAX, nbits); break; case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - onbits = nbits = packet_get_int(); +@@ -99,7 +99,7 @@ input_kex_dh_gex_request(int type, u_int + goto out; + kex->nbits = nbits; /* unused for old GEX */ -- omin = min = DH_GRP_MIN; -+ omin = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - omax = max = DH_GRP_MAX; +- kex->min = min = DH_GRP_MIN; ++ kex->min = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + kex->max = max = DH_GRP_MAX; break; default: -diff --git a/key.c b/key.c -index 62f3edb..a2050f6 100644 ---- a/key.c -+++ b/key.c -@@ -42,6 +42,7 @@ - #include "crypto_api.h" - - #include -+#include - #include - - #include -@@ -636,9 +637,13 @@ key_fingerprint_selection(void) - char *env; - - if (!rv_defined) { -- env = getenv("SSH_FINGERPRINT_TYPE"); -- rv = (env && !strcmp (env, "sha")) ? -- SSH_FP_SHA1 : SSH_FP_MD5; -+ if (FIPS_mode()) -+ rv = SSH_FP_SHA1; -+ else { -+ env = getenv("SSH_FINGERPRINT_TYPE"); -+ rv = (env && !strcmp (env, "sha")) ? -+ SSH_FP_SHA1 : SSH_FP_MD5; -+ } - rv_defined = 1; - } - return rv; -@@ -1168,8 +1173,11 @@ rsa_generate_private_key(u_int bits) - fatal("%s: BN_new failed", __func__); - if (!BN_set_word(f4, RSA_F4)) - fatal("%s: BN_new failed", __func__); -- if (!RSA_generate_key_ex(private, bits, f4, NULL)) -+ if (!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__); - fatal("%s: key generation failed.", __func__); -+ } - BN_free(f4); - return private; - } -diff --git a/mac.c b/mac.c -index 9388af4..cd7b034 100644 ---- a/mac.c -+++ b/mac.c +diff -up openssh-6.8p1/mac.c.fips openssh-6.8p1/mac.c +--- openssh-6.8p1/mac.c.fips 2015-03-19 13:14:22.224212169 +0100 ++++ openssh-6.8p1/mac.c 2015-03-19 13:14:22.231212155 +0100 @@ -27,6 +27,8 @@ #include +#include + - #include #include - #include -@@ -60,7 +62,7 @@ struct macalg { + #include + +@@ -54,7 +56,7 @@ struct macalg { int etm; /* Encrypt-then-MAC */ }; @@ -422,7 +278,7 @@ index 9388af4..cd7b034 100644 /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, -@@ -91,6 +93,24 @@ static const struct macalg macs[] = { +@@ -85,6 +87,24 @@ static const struct macalg macs[] = { { NULL, 0, 0, 0, 0, 0, 0 } }; @@ -447,7 +303,7 @@ index 9388af4..cd7b034 100644 /* Returns a list of supported MACs separated by the specified char. */ char * mac_alg_list(char sep) -@@ -99,7 +119,7 @@ mac_alg_list(char sep) +@@ -93,7 +113,7 @@ mac_alg_list(char sep) size_t nlen, rlen = 0; const struct macalg *m; @@ -456,7 +312,7 @@ index 9388af4..cd7b034 100644 if (ret != NULL) ret[rlen++] = sep; nlen = strlen(m->name); -@@ -133,7 +153,7 @@ mac_setup(Mac *mac, char *name) +@@ -132,7 +152,7 @@ mac_setup(struct sshmac *mac, char *name { const struct macalg *m; @@ -464,28 +320,19 @@ index 9388af4..cd7b034 100644 + for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { if (strcmp(name, m->name) != 0) continue; - if (mac != NULL) { -diff --git a/myproposal.h b/myproposal.h -index 3a0f5ae..4f35a44 100644 ---- a/myproposal.h -+++ b/myproposal.h -@@ -88,6 +88,12 @@ - "diffie-hellman-group14-sha1," \ - "diffie-hellman-group1-sha1" + if (mac != NULL) +diff -up openssh-6.8p1/myproposal.h.fips openssh-6.8p1/myproposal.h +--- openssh-6.8p1/myproposal.h.fips 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/myproposal.h 2015-03-19 13:14:22.231212155 +0100 +@@ -140,6 +140,28 @@ + "hmac-sha1-96," \ + "hmac-md5-96" +#define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ + KEX_SHA256_METHODS \ + "diffie-hellman-group-exchange-sha1," \ + "diffie-hellman-group14-sha1" -+ - #define KEX_DEFAULT_PK_ALG \ - HOSTKEY_ECDSA_CERT_METHODS \ - "ssh-ed25519-cert-v01@openssh.com," \ -@@ -133,6 +139,22 @@ - #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" - #define KEX_DEFAULT_LANG "" - +#define KEX_FIPS_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-cbc,3des-cbc," \ @@ -502,74 +349,39 @@ index 3a0f5ae..4f35a44 100644 +#define KEX_FIPS_MAC \ + "hmac-sha1" +#endif ++ + #else - static char *myproposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 66198e6..ccf22c8 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -195,6 +195,12 @@ type_bits_valid(int type, u_int32_t *bitsp) - fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); - exit(1); - } -+ 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"); -+ } - if (type == KEY_DSA && *bitsp != 1024) - fatal("DSA keys must be 1024 bits"); - else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) -@@ -746,7 +752,7 @@ do_download(struct passwd *pw) - enum fp_type fptype; - char *fp, *ra; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - pkcs11_init(0); -@@ -756,8 +762,7 @@ do_download(struct passwd *pw) - for (i = 0; i < nkeys; i++) { - if (print_fingerprint) { - fp = key_fingerprint(keys[i], fptype, rep); -- ra = key_fingerprint(keys[i], SSH_FP_MD5, -- SSH_FP_RANDOMART); -+ ra = key_selected_fingerprint(keys[i], SSH_FP_RANDOMART); - printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), - fp, key_type(keys[i])); - if (log_level >= SYSLOG_LEVEL_VERBOSE) -diff --git a/ssh.c b/ssh.c -index 1e6cb90..ea9193f 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -73,6 +73,8 @@ - + #define KEX_SERVER_KEX \ +diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c +--- openssh-6.8p1/ssh.c.fips 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/ssh.c 2015-03-19 13:14:22.232212153 +0100 +@@ -75,6 +75,8 @@ #include #include + #endif +#include +#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -427,6 +429,13 @@ main(int ac, char **av) +@@ -523,6 +525,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); + SSLeay_add_all_algorithms(); + if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) ++ if (! FIPSCHECK_verify(NULL, NULL)){ + if (FIPS_mode()) + fatal("FIPS integrity verification test failed."); + else + logit("FIPS integrity verification test failed."); ++ } #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -504,6 +513,9 @@ main(int ac, char **av) - "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { +@@ -600,6 +610,9 @@ main(int ac, char **av) + "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': + if (FIPS_mode()) { @@ -578,15 +390,15 @@ index 1e6cb90..ea9193f 100644 options.protocol = SSH_PROTO_1; break; case '2': -@@ -828,7 +840,6 @@ main(int ac, char **av) - +@@ -941,7 +954,6 @@ main(int ac, char **av) host_arg = xstrdup(host); + #ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); + #endif - /* Initialize the command to execute on remote host. */ -@@ -973,6 +984,10 @@ main(int ac, char **av) +@@ -1115,6 +1127,10 @@ main(int ac, char **av) seed_rng(); @@ -597,7 +409,7 @@ index 1e6cb90..ea9193f 100644 if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1020,6 +1035,12 @@ main(int ac, char **av) +@@ -1192,6 +1208,12 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; @@ -610,11 +422,10 @@ index 1e6cb90..ea9193f 100644 /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff --git a/sshconnect2.c b/sshconnect2.c -index b00658b..6a1562c 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -44,6 +44,8 @@ +diff -up openssh-6.8p1/sshconnect2.c.fips openssh-6.8p1/sshconnect2.c +--- openssh-6.8p1/sshconnect2.c.fips 2015-03-19 13:14:22.188212238 +0100 ++++ openssh-6.8p1/sshconnect2.c 2015-03-19 13:14:22.232212153 +0100 +@@ -46,6 +46,8 @@ #include #endif @@ -623,7 +434,7 @@ index b00658b..6a1562c 100644 #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -168,20 +170,25 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) +@@ -172,20 +174,25 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -663,7 +474,7 @@ index b00658b..6a1562c 100644 } } #endif -@@ -193,6 +200,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) +@@ -197,6 +204,10 @@ ssh_kex2(char *host, struct sockaddr *ho if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; @@ -674,7 +485,7 @@ index b00658b..6a1562c 100644 } myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -208,7 +219,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) +@@ -212,7 +223,11 @@ ssh_kex2(char *host, struct sockaddr *ho if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; @@ -686,7 +497,7 @@ index b00658b..6a1562c 100644 if (options.hostkeyalgorithms != NULL) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(options.hostkeyalgorithms); -@@ -220,9 +235,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) +@@ -224,9 +239,11 @@ ssh_kex2(char *host, struct sockaddr *ho } if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; @@ -699,20 +510,27 @@ index b00658b..6a1562c 100644 #ifdef GSSAPI /* If we've got GSSAPI algorithms, then we also support the * 'null' hostkey, as a last resort */ -diff --git a/sshd.c b/sshd.c -index b561ec8..e977de3 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -75,6 +75,8 @@ +diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.fips 2015-03-19 13:14:22.226212165 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-19 13:14:22.232212153 +0100 +@@ -66,6 +66,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -77,6 +78,8 @@ #include #include #include +#include +#include #include "openbsd-compat/openssl-compat.h" + #endif - #ifdef HAVE_SECUREWARE -@@ -1468,6 +1470,18 @@ main(int ac, char **av) +@@ -1543,6 +1546,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -731,18 +549,18 @@ index b561ec8..e977de3 100644 /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1619,8 +1633,6 @@ main(int ac, char **av) +@@ -1694,7 +1709,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); -- OpenSSL_add_all_algorithms(); -- - /* If requested, redirect the logs to the specified logfile. */ - if (logfile != NULL) { - log_redirect_stderr_to(logfile); -@@ -1798,6 +1810,10 @@ main(int ac, char **av) - debug("private host key: #%d type %d %s", i, keytype, - key_type(key ? key : pubkey)); +-#ifdef WITH_OPENSSL ++#if 0 /* FIPS */ + OpenSSL_add_all_algorithms(); + #endif + +@@ -1890,6 +1905,10 @@ main(int ac, char **av) + sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); + free(fp); } + if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { + logit("Disabling protocol version 1. Not allowed in the FIPS mode."); @@ -751,7 +569,7 @@ index b561ec8..e977de3 100644 if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; -@@ -1961,6 +1977,10 @@ main(int ac, char **av) +@@ -2058,6 +2077,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); @@ -762,7 +580,7 @@ index b561ec8..e977de3 100644 /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2530,6 +2550,9 @@ do_ssh2_kex(void) +@@ -2642,6 +2665,9 @@ do_ssh2_kex(void) if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; @@ -772,7 +590,7 @@ index b561ec8..e977de3 100644 } myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2539,6 +2562,9 @@ do_ssh2_kex(void) +@@ -2651,6 +2677,9 @@ do_ssh2_kex(void) if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; @@ -782,7 +600,7 @@ index b561ec8..e977de3 100644 } if (options.compression == COMP_NONE) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = -@@ -2549,6 +2575,8 @@ do_ssh2_kex(void) +@@ -2661,6 +2690,8 @@ do_ssh2_kex(void) } if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; @@ -791,7 +609,7 @@ index b561ec8..e977de3 100644 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( myproposal[PROPOSAL_KEX_ALGS]); -@@ -2575,10 +2603,14 @@ do_ssh2_kex(void) +@@ -2687,10 +2718,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -810,3 +628,50 @@ index b561ec8..e977de3 100644 if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); +diff -up openssh-6.8p1/sshkey.c.fips openssh-6.8p1/sshkey.c +--- openssh-6.8p1/sshkey.c.fips 2015-03-19 13:14:22.227212163 +0100 ++++ openssh-6.8p1/sshkey.c 2015-03-19 13:14:22.233212151 +0100 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #endif + + #include "crypto_api.h" +@@ -1562,6 +1563,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-6.8p1/servconf.c.fips openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.fips 2015-03-19 13:14:22.210212196 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-19 13:14:22.233212151 +0100 +@@ -2226,8 +2226,10 @@ dump_config(ServerOptions *o) + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); + dump_cfg_string(sXAuthLocation, o->xauth_location); +- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); +- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); ++ dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : FIPS_mode() ++ ? KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT); ++ dump_cfg_string(sMacs, o->macs ? o->macs : FIPS_mode() ++ ? KEX_FIPS_MAC : KEX_SERVER_MAC); + dump_cfg_string(sBanner, o->banner); + dump_cfg_string(sForceCommand, o->adm_forced_command); + dump_cfg_string(sChrootDirectory, o->chroot_directory); +@@ -2240,8 +2242,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); + dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); + dump_cfg_string(sHostKeyAgent, o->host_key_agent); +- dump_cfg_string(sKexAlgorithms, +- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); ++ dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : ++ FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); + dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? + o->hostbased_key_types : KEX_DEFAULT_PK_ALG); + dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch new file mode 100644 index 0000000..d219791 --- /dev/null +++ b/openssh-6.7p1-kdf-cavs.patch @@ -0,0 +1,614 @@ +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_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + SSH_KEYCAT=$(libexecdir)/ssh-keycat + CTR_CAVSTEST=$(libexecdir)/ctr-cavstest ++SSH_CAVS=$(libexecdir)/ssh-cavs + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + PRIVSEP_PATH=@PRIVSEP_PATH@ + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +@@ -67,7 +68,7 @@ EXEEXT=@EXEEXT@ + MANFMT=@MANFMT@ + INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ + +-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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT) + + LIBOPENSSH_OBJS=\ + ssh_api.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 -lfipscheck $(LIBS) + ++ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o roaming_dummy.o ++ $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o + $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + +@@ -331,6 +335,8 @@ install-files: + fi + $(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,383 @@ ++/* ++ * Copyright (C) 2015, Stephan Mueller ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "xmalloc.h" ++#include "buffer.h" ++#include "key.h" ++#include "cipher.h" ++#include "kex.h" ++#include "packet.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; ++ 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; ++ } ++ ++ 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 = 2; ++ break; ++ case 32: ++ kex.hash_alg = 3; ++ break; ++ case 48: ++ kex.hash_alg = 4; ++ break; ++ case 64: ++ kex.hash_alg = 5; ++ 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_bn(ssh, test->H, test->Hlen, Kbn); ++ ++ 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); ++ ++ free(ctoskeys); ++ free(stockeys); ++ ++out: ++ if (Kbn) ++ BN_free(Kbn); ++ if (kex.newkeys[0]) ++ free(kex.newkeys[0]); ++ if (kex.newkeys[1]) ++ free(kex.newkeys[1]); ++ 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 ++# ++# 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() { ++ ++ 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; diff --git a/openssh-6.6p1-ldap.patch b/openssh-6.7p1-ldap.patch similarity index 92% rename from openssh-6.6p1-ldap.patch rename to openssh-6.7p1-ldap.patch index ae3e7cd..296e7ea 100644 --- a/openssh-6.6p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -1,9 +1,7 @@ -diff --git a/HOWTO.ldap-keys b/HOWTO.ldap-keys -new file mode 100644 -index 0000000..dd5f5cc ---- /dev/null -+++ b/HOWTO.ldap-keys -@@ -0,0 +1,108 @@ +diff -up openssh-6.8p1/HOWTO.ldap-keys.ldap openssh-6.8p1/HOWTO.ldap-keys +--- openssh-6.8p1/HOWTO.ldap-keys.ldap 2015-03-18 11:11:29.029801467 +0100 ++++ openssh-6.8p1/HOWTO.ldap-keys 2015-03-18 11:11:29.029801467 +0100 +@@ -0,0 +1,119 @@ + +HOW TO START + @@ -66,6 +64,17 @@ index 0000000..dd5f5cc + * ssh-ldap-helper -d -d -d -d -s +3) use tcpdump ... other ldap client etc. + ++HOW TO CONFIGURE SSH FOR OTHER LDAP CONFIGURATION / SERVER /SCHEMA ++ ++You can adjust search format string in /etc/ldap.conf using ++ 1) SSH_Filter option to limit results for only specified users ++ (this appends search condition after original query) ++ 2) Search_Format option to define your own search string using expansion ++ characters %u for username, %c for objectclass and %f for above mentioned filter. ++ ++Example: ++Search_Format (&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%u)%f) ++ +ADVANTAGES + +1) Blocking an user account can be done directly from LDAP (if sshd is using PubkeyAuthentication + AuthorizedKeysCommand with ldap only). @@ -112,10 +121,9 @@ index 0000000..dd5f5cc +5) Author + Jan F. Chadima + -diff --git a/Makefile.in b/Makefile.in -index 28a8ec4..411eadb 100644 ---- a/Makefile.in -+++ b/Makefile.in +diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.ldap 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-18 11:13:10.147561177 +0100 @@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server @@ -125,7 +133,7 @@ index 28a8ec4..411eadb 100644 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -60,8 +62,9 @@ XAUTH_PATH=@XAUTH_PATH@ +@@ -61,8 +63,9 @@ XAUTH_PATH=@XAUTH_PATH@ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ @@ -134,9 +142,9 @@ index 28a8ec4..411eadb 100644 -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) +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-ldap-helper$(EXEEXT) - LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ -@@ -98,8 +101,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + LIBOPENSSH_OBJS=\ + ssh_api.o \ +@@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o @@ -147,17 +155,17 @@ index 28a8ec4..411eadb 100644 MANTYPE = @MANTYPE@ CONFIGFILES=sshd_config.out ssh_config.out moduli.out -@@ -170,6 +173,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readco +@@ -184,6 +187,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ++ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o ++ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -@@ -273,6 +279,10 @@ install-files: +@@ -311,6 +317,10 @@ install-files: $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(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) @@ -168,7 +176,7 @@ index 28a8ec4..411eadb 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 -@@ -289,6 +299,10 @@ install-files: +@@ -327,6 +337,10 @@ install-files: $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 @@ -179,7 +187,7 @@ index 28a8ec4..411eadb 100644 -rm -f $(DESTDIR)$(bindir)/slogin ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 -@@ -318,6 +332,13 @@ install-sysconf: +@@ -356,6 +370,13 @@ install-sysconf: else \ echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ fi @@ -193,7 +201,7 @@ index 28a8ec4..411eadb 100644 host-key: ssh-keygen$(EXEEXT) @if [ -z "$(DESTDIR)" ] ; then \ -@@ -381,6 +402,8 @@ uninstall: +@@ -419,6 +440,8 @@ uninstall: -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) @@ -202,19 +210,18 @@ index 28a8ec4..411eadb 100644 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 -@@ -392,6 +415,7 @@ uninstall: +@@ -430,6 +453,7 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c -diff --git a/configure.ac b/configure.ac -index 7c6ce08..722a19e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1625,6 +1625,106 @@ if test "x$use_pie" != "xno"; then + regress-prep: +diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac +--- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 +@@ -1605,6 +1605,106 @@ if test "x$use_pie" != "xno"; then fi fi @@ -321,11 +328,9 @@ index 7c6ce08..722a19e 100644 dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ Blowfish_initstate \ -diff --git a/ldap-helper.c b/ldap-helper.c -new file mode 100644 -index 0000000..e95a94a ---- /dev/null -+++ b/ldap-helper.c +diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c +--- openssh-6.8p1/ldap-helper.c.ldap 2015-03-18 11:11:29.030801464 +0100 ++++ openssh-6.8p1/ldap-helper.c 2015-03-18 11:11:29.030801464 +0100 @@ -0,0 +1,155 @@ +/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -482,11 +487,9 @@ index 0000000..e95a94a +void *buffer_get_string(Buffer *b, u_int *l) { return NULL; } +void buffer_put_string(Buffer *b, const void *f, u_int l) {} + -diff --git a/ldap-helper.h b/ldap-helper.h -new file mode 100644 -index 0000000..14cb29a ---- /dev/null -+++ b/ldap-helper.h +diff -up openssh-6.8p1/ldap-helper.h.ldap openssh-6.8p1/ldap-helper.h +--- openssh-6.8p1/ldap-helper.h.ldap 2015-03-18 11:11:29.031801462 +0100 ++++ openssh-6.8p1/ldap-helper.h 2015-03-18 11:11:29.031801462 +0100 @@ -0,0 +1,32 @@ +/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -520,12 +523,10 @@ index 0000000..14cb29a +extern int config_warning_config_file; + +#endif /* LDAP_HELPER_H */ -diff --git a/ldap.conf b/ldap.conf -new file mode 100644 -index 0000000..42e38d3 ---- /dev/null -+++ b/ldap.conf -@@ -0,0 +1,88 @@ +diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf +--- openssh-6.8p1/ldap.conf.ldap 2015-03-18 11:11:29.031801462 +0100 ++++ openssh-6.8p1/ldap.conf 2015-03-18 11:11:29.031801462 +0100 +@@ -0,0 +1,95 @@ +# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ +# +# This is the example configuration file for the OpenSSH @@ -614,12 +615,17 @@ index 0000000..42e38d3 +#tls_cert +#tls_key + -diff --git a/ldapbody.c b/ldapbody.c -new file mode 100644 -index 0000000..3029108 ---- /dev/null -+++ b/ldapbody.c -@@ -0,0 +1,494 @@ ++# OpenLDAP search_format ++# format used to search for users in LDAP directory using substitution ++# for %u for user name and %f for SSH_Filter option (optional, empty by default) ++#search_format (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) ++ ++#AccountClass posixAccount ++ +diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c +--- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100 ++++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100 +@@ -0,0 +1,493 @@ +/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -653,8 +659,9 @@ index 0000000..3029108 +#include "ldapbody.h" +#include +#include ++#include "misc.h" + -+#define LDAPSEARCH_FORMAT "(&(objectclass=%s)(objectclass=ldapPublicKey)(uid=%s)%s)" ++#define LDAPSEARCH_FORMAT "(&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f)" +#define PUBKEYATTR "sshPublicKey" +#define LDAP_LOGFILE "%s/ldap.%d" + @@ -1041,8 +1048,8 @@ index 0000000..3029108 +process_user (const char *user, FILE *output) +{ + LDAPMessage *res, *e; -+ char *buffer; -+ int bufflen, rc, i; ++ char *buffer, *format; ++ int rc, i; + struct timeval timeout; + + debug ("LDAP process user"); @@ -1055,12 +1062,10 @@ index 0000000..3029108 + } + + /* build filter for LDAP request */ -+ bufflen = strlen (LDAPSEARCH_FORMAT) + strlen(options.account_class) + strlen (user); -+ if (options.ssh_filter != NULL) -+ bufflen += strlen (options.ssh_filter); -+ buffer = xmalloc (bufflen); -+ snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, options.account_class, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL); -+ buffer[bufflen - 1] = 0; ++ format = LDAPSEARCH_FORMAT; ++ if (options.search_format != NULL) ++ format = options.search_format; ++ buffer = percent_expand(format, "c", options.account_class, "u", user, "f", options.ssh_filter, (char *)NULL); + + debug3 ("LDAP search scope = %d %s", options.scope, buffer); + @@ -1114,11 +1119,9 @@ index 0000000..3029108 + return; +} + -diff --git a/ldapbody.h b/ldapbody.h -new file mode 100644 -index 0000000..665dca2 ---- /dev/null -+++ b/ldapbody.h +diff -up openssh-6.8p1/ldapbody.h.ldap openssh-6.8p1/ldapbody.h +--- openssh-6.8p1/ldapbody.h.ldap 2015-03-18 11:11:29.031801462 +0100 ++++ openssh-6.8p1/ldapbody.h 2015-03-18 11:11:29.031801462 +0100 @@ -0,0 +1,37 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1157,12 +1160,10 @@ index 0000000..665dca2 + +#endif /* LDAPBODY_H */ + -diff --git a/ldapconf.c b/ldapconf.c -new file mode 100644 -index 0000000..525060a ---- /dev/null -+++ b/ldapconf.c -@@ -0,0 +1,722 @@ +diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c +--- openssh-6.8p1/ldapconf.c.ldap 2015-03-18 11:11:29.032801460 +0100 ++++ openssh-6.8p1/ldapconf.c 2015-03-18 11:11:29.032801460 +0100 +@@ -0,0 +1,728 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -1206,7 +1207,7 @@ index 0000000..525060a + lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals, + lRestart, lTLS_CheckPeer, lTLS_CaCertFile, + lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, -+ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, ++ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, lSearch_Format, + lAccountClass, lDeprecated, lUnsupported +} OpCodes; + @@ -1259,6 +1260,7 @@ index 0000000..525060a + { "LogDir", lLogDir }, + { "Debug", lDebug }, + { "SSH_Filter", lSSH_Filter }, ++ { "search_format", lSearch_Format }, + { "AccountClass", lAccountClass }, + { NULL, lBadOption } +}; @@ -1583,6 +1585,10 @@ index 0000000..525060a + xstringptr = &options.ssh_filter; + goto parse_xstring; + ++ case lSearch_Format: ++ charptr = &options.search_format; ++ goto parse_string; ++ + case lAccountClass: + charptr = &options.account_class; + goto parse_string; @@ -1620,7 +1626,7 @@ index 0000000..525060a +{ + FILE *f; + char line[1024]; -+ int active, linenum; ++ int linenum; + int bad_options = 0; + struct stat sb; + @@ -1639,7 +1645,6 @@ index 0000000..525060a + * Mark that we are now processing the options. This flag is turned + * on/off by Host specifications. + */ -+ active = 1; + linenum = 0; + while (fgets(line, sizeof(line), f)) { + /* Update line number counter. */ @@ -1690,6 +1695,7 @@ index 0000000..525060a + options.logdir = NULL; + options.debug = -1; + options.ssh_filter = NULL; ++ options.search_format = NULL; + options.account_class = NULL; +} + @@ -1882,15 +1888,14 @@ index 0000000..525060a + dump_cfg_string(lLogDir, options.logdir); + dump_cfg_int(lDebug, options.debug); + dump_cfg_string(lSSH_Filter, options.ssh_filter); -+ dump_cfg_string(lAccountClass, options.logdir); ++ dump_cfg_string(lSearch_Format, options.search_format); ++ dump_cfg_string(lAccountClass, options.account_class); +} + -diff --git a/ldapconf.h b/ldapconf.h -new file mode 100644 -index 0000000..2cb550c ---- /dev/null -+++ b/ldapconf.h -@@ -0,0 +1,72 @@ +diff -up openssh-6.8p1/ldapconf.h.ldap openssh-6.8p1/ldapconf.h +--- openssh-6.8p1/ldapconf.h.ldap 2015-03-18 11:11:29.032801460 +0100 ++++ openssh-6.8p1/ldapconf.h 2015-03-18 11:11:29.032801460 +0100 +@@ -0,0 +1,73 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -1952,6 +1957,7 @@ index 0000000..2cb550c + char *logdir; + int debug; + char *ssh_filter; ++ char *search_format; + char *account_class; +} Options; + @@ -1963,11 +1969,9 @@ index 0000000..2cb550c +void dump_config(void); + +#endif /* LDAPCONF_H */ -diff --git a/ldapincludes.h b/ldapincludes.h -new file mode 100644 -index 0000000..8539bdc ---- /dev/null -+++ b/ldapincludes.h +diff -up openssh-6.8p1/ldapincludes.h.ldap openssh-6.8p1/ldapincludes.h +--- openssh-6.8p1/ldapincludes.h.ldap 2015-03-18 11:11:29.032801460 +0100 ++++ openssh-6.8p1/ldapincludes.h 2015-03-18 11:11:29.032801460 +0100 @@ -0,0 +1,41 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -2010,11 +2014,9 @@ index 0000000..8539bdc +#endif + +#endif /* LDAPINCLUDES_H */ -diff --git a/ldapmisc.c b/ldapmisc.c -new file mode 100644 -index 0000000..de23c0c ---- /dev/null -+++ b/ldapmisc.c +diff -up openssh-6.8p1/ldapmisc.c.ldap openssh-6.8p1/ldapmisc.c +--- openssh-6.8p1/ldapmisc.c.ldap 2015-03-18 11:11:29.032801460 +0100 ++++ openssh-6.8p1/ldapmisc.c 2015-03-18 11:11:29.032801460 +0100 @@ -0,0 +1,79 @@ + +#include "ldapincludes.h" @@ -2095,11 +2097,9 @@ index 0000000..de23c0c +} +#endif + -diff --git a/ldapmisc.h b/ldapmisc.h -new file mode 100644 -index 0000000..4c271df ---- /dev/null -+++ b/ldapmisc.h +diff -up openssh-6.8p1/ldapmisc.h.ldap openssh-6.8p1/ldapmisc.h +--- openssh-6.8p1/ldapmisc.h.ldap 2015-03-18 11:11:29.032801460 +0100 ++++ openssh-6.8p1/ldapmisc.h 2015-03-18 11:11:29.032801460 +0100 @@ -0,0 +1,35 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -2136,11 +2136,9 @@ index 0000000..4c271df + +#endif /* LDAPMISC_H */ + -diff --git a/openssh-lpk-openldap.schema b/openssh-lpk-openldap.schema -new file mode 100644 -index 0000000..c84f90f ---- /dev/null -+++ b/openssh-lpk-openldap.schema +diff -up openssh-6.8p1/openssh-lpk-openldap.schema.ldap openssh-6.8p1/openssh-lpk-openldap.schema +--- openssh-6.8p1/openssh-lpk-openldap.schema.ldap 2015-03-18 11:11:29.033801457 +0100 ++++ openssh-6.8p1/openssh-lpk-openldap.schema 2015-03-18 11:11:29.033801457 +0100 @@ -0,0 +1,21 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2163,11 +2161,9 @@ index 0000000..c84f90f + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff --git a/openssh-lpk-sun.schema b/openssh-lpk-sun.schema -new file mode 100644 -index 0000000..3136673 ---- /dev/null -+++ b/openssh-lpk-sun.schema +diff -up openssh-6.8p1/openssh-lpk-sun.schema.ldap openssh-6.8p1/openssh-lpk-sun.schema +--- openssh-6.8p1/openssh-lpk-sun.schema.ldap 2015-03-18 11:11:29.033801457 +0100 ++++ openssh-6.8p1/openssh-lpk-sun.schema 2015-03-18 11:11:29.033801457 +0100 @@ -0,0 +1,23 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2192,11 +2188,9 @@ index 0000000..3136673 + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff --git a/ssh-ldap-helper.8 b/ssh-ldap-helper.8 -new file mode 100644 -index 0000000..5d2d7be ---- /dev/null -+++ b/ssh-ldap-helper.8 +diff -up openssh-6.8p1/ssh-ldap-helper.8.ldap openssh-6.8p1/ssh-ldap-helper.8 +--- openssh-6.8p1/ssh-ldap-helper.8.ldap 2015-03-18 11:11:29.033801457 +0100 ++++ openssh-6.8p1/ssh-ldap-helper.8 2015-03-18 11:11:29.033801457 +0100 @@ -0,0 +1,79 @@ +.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $ +.\" @@ -2277,22 +2271,18 @@ index 0000000..5d2d7be +OpenSSH 5.5 + PKA-LDAP . +.Sh AUTHORS +.An Jan F. Chadima Aq jchadima@redhat.com -diff --git a/ssh-ldap-wrapper b/ssh-ldap-wrapper -new file mode 100644 -index 0000000..cb500aa ---- /dev/null -+++ b/ssh-ldap-wrapper +diff -up openssh-6.8p1/ssh-ldap-wrapper.ldap openssh-6.8p1/ssh-ldap-wrapper +--- openssh-6.8p1/ssh-ldap-wrapper.ldap 2015-03-18 11:11:29.033801457 +0100 ++++ openssh-6.8p1/ssh-ldap-wrapper 2015-03-18 11:11:29.033801457 +0100 @@ -0,0 +1,4 @@ +#!/bin/sh + +exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" + -diff --git a/ssh-ldap.conf.5 b/ssh-ldap.conf.5 -new file mode 100644 -index 0000000..f7081b8 ---- /dev/null -+++ b/ssh-ldap.conf.5 -@@ -0,0 +1,379 @@ +diff -up openssh-6.8p1/ssh-ldap.conf.5.ldap openssh-6.8p1/ssh-ldap.conf.5 +--- openssh-6.8p1/ssh-ldap.conf.5.ldap 2015-03-18 11:11:29.033801457 +0100 ++++ openssh-6.8p1/ssh-ldap.conf.5 2015-03-18 11:11:29.033801457 +0100 +@@ -0,0 +1,385 @@ +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ +.\" +.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. @@ -2651,11 +2641,17 @@ index 0000000..f7081b8 +Specifies the debug level used for logging by the LDAP client library. +There is no default. +.It Cm SSH_Filter -+Specifies the user filter applied on the LDAP serch. ++Specifies the user filter applied on the LDAP search. +The default is no filter. +.It Cm AccountClass +Specifies the LDAP class used to find user accounts. +The default is posixAccount. ++.It Cm search_format ++Specifies the user format of search string in LDAP substituting %u for user name ++and %f for additional ssh filter ++.Cm SSH_Filter ++(optional). ++The default value is (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) +.El +.Sh FILES +.Bl -tag -width Ds diff --git a/openssh-6.7p1-seccomp-aarch64.patch b/openssh-6.7p1-seccomp-aarch64.patch new file mode 100644 index 0000000..4285bd9 --- /dev/null +++ b/openssh-6.7p1-seccomp-aarch64.patch @@ -0,0 +1,66 @@ +diff --git a/configure.ac b/configure.ac +index 4065d0e..d59ad44 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + i*86-*) + seccomp_audit_arch=AUDIT_ARCH_I386 + ;; +- arm*-*) ++ aarch64*-*) ++ seccomp_audit_arch=AUDIT_ARCH_AARCH64 ++ ;; ++ arm*-*) + seccomp_audit_arch=AUDIT_ARCH_ARM +- ;; ++ ;; + esac + if test "x$seccomp_audit_arch" != "x" ; then + AC_MSG_RESULT(["$seccomp_audit_arch"]) +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 095b04a..52f6810 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = { + /* Load the syscall number for checking. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, nr)), +- SC_DENY(open, EACCES), +- SC_DENY(stat, EACCES), ++ SC_DENY(openat, EACCES), ++#ifdef __NR_open ++ SC_DENY(open, EACCES), /* not on AArch64 */ ++#endif ++#ifdef __NR_fstat ++ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ ++#endif ++#if defined(__NR_stat64) && defined(__NR_fstat64) ++ SC_DENY(stat64, EACCES), /* ix86, arm */ ++ SC_DENY(fstat64, EACCES), ++#endif ++#ifdef __NR_newfstatat ++ SC_DENY(newfstatat, EACCES), /* Aarch64 */ ++#endif + SC_ALLOW(getpid), + SC_ALLOW(gettimeofday), + SC_ALLOW(clock_gettime), +@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = { + SC_ALLOW(shutdown), + #endif + SC_ALLOW(brk), ++#ifdef __NR_poll /* not on AArch64 */ + SC_ALLOW(poll), ++#endif + #ifdef __NR__newselect + SC_ALLOW(_newselect), + #else ++#ifdef __NR_select /* not on AArch64 */ + SC_ALLOW(select), + #endif ++#ifdef __NR_pselect6 /* AArch64 */ ++ SC_ALLOW(pselect6), ++#endif ++#endif + SC_ALLOW(madvise), + #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ + SC_ALLOW(mmap2), diff --git a/openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch new file mode 100644 index 0000000..1a88e50 --- /dev/null +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -0,0 +1,81 @@ +diff -up openssh-6.8p1/sftp-server.8.sftp-force-mode openssh-6.8p1/sftp-server.8 +--- openssh-6.8p1/sftp-server.8.sftp-force-mode 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp-server.8 2015-03-18 13:18:05.898306477 +0100 +@@ -38,6 +38,7 @@ + .Op Fl P Ar blacklisted_requests + .Op Fl p Ar whitelisted_requests + .Op Fl u Ar umask ++.Op Fl m Ar force_file_perms + .Ek + .Nm + .Fl Q Ar protocol_feature +@@ -138,6 +139,10 @@ Sets an explicit + .Xr umask 2 + to be applied to newly-created files and directories, instead of the + user's default mask. ++.It Fl m Ar force_file_perms ++Sets explicit file permissions to be applied to newly-created files instead ++of the default or client requested mode. Numeric values include: ++777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set. + .El + .Pp + On some systems, +diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c +--- openssh-6.8p1/sftp-server.c.sftp-force-mode 2015-03-18 13:18:05.883306513 +0100 ++++ openssh-6.8p1/sftp-server.c 2015-03-18 13:18:36.697232193 +0100 +@@ -70,6 +70,10 @@ struct sshbuf *oqueue; + /* Version of client */ + static u_int version; + ++/* Force file permissions */ ++int permforce = 0; ++long permforcemode; ++ + /* SSH2_FXP_INIT received */ + static int init_done; + +@@ -693,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; ++ if (permforce == 1) { /* Force perm if -m is set */ ++ mode = permforcemode; ++ (void)umask(0); /* so umask does not interfere */ ++ } + logit("open \"%s\" flags %s mode 0%o", + name, string_from_portable(pflags), mode); + if (readonly && +@@ -1495,7 +1503,7 @@ sftp_server_usage(void) + fprintf(stderr, + "usage: %s [-ehR] [-d start_directory] [-f log_facility] " + "[-l log_level]\n\t[-P blacklisted_requests] " +- "[-p whitelisted_requests] [-u umask]\n" ++ "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n" + " %s -Q protocol_feature\n", + __progname, __progname); + exit(1); +@@ -1520,7 +1528,7 @@ sftp_server_main(int argc, char **argv, + pw = pwcopy(user_pw); + + while (!skipargs && (ch = getopt(argc, argv, +- "d:f:l:P:p:Q:u:cehR")) != -1) { ++ "d:f:l:P:p:Q:u:m:cehR")) != -1) { + switch (ch) { + case 'Q': + if (strcasecmp(optarg, "requests") != 0) { +@@ -1580,6 +1588,15 @@ sftp_server_main(int argc, char **argv, + fatal("Invalid umask \"%s\"", optarg); + (void)umask((mode_t)mask); + break; ++ case 'm': ++ /* Force permissions on file received via sftp */ ++ permforce = 1; ++ permforcemode = strtol(optarg, &cp, 8); ++ if (permforcemode < 0 || permforcemode > 0777 || ++ *cp != '\0' || (permforcemode == 0 && ++ errno != 0)) ++ fatal("Invalid file mode \"%s\"", optarg); ++ break; + case 'h': + default: + sftp_server_usage(); diff --git a/openssh-6.7p1-sshdT-output.patch b/openssh-6.7p1-sshdT-output.patch new file mode 100644 index 0000000..aa09346 --- /dev/null +++ b/openssh-6.7p1-sshdT-output.patch @@ -0,0 +1,56 @@ +diff -up openssh-6.8p1/servconf.c.sshdt openssh-6.8p1/servconf.c +--- openssh-6.8p1/servconf.c.sshdt 2015-03-18 13:07:24.457858235 +0100 ++++ openssh-6.8p1/servconf.c 2015-03-18 13:09:27.253557396 +0100 +@@ -2118,6 +2118,8 @@ dump_cfg_strarray_oneline(ServerOpCodes + { + u_int i; + ++ if (count <= 0) ++ return; + printf("%s", lookup_opcode_name(code)); + for (i = 0; i < count; i++) + printf(" %s", vals[i]); +@@ -2156,7 +2158,7 @@ dump_config(ServerOptions *o) + + /* integer arguments */ + #ifdef USE_PAM +- dump_cfg_int(sUsePAM, o->use_pam); ++ dump_cfg_fmtint(sUsePAM, o->use_pam); + #endif + dump_cfg_int(sServerKeyBits, o->server_key_bits); + dump_cfg_int(sLoginGraceTime, o->login_grace_time); +@@ -2166,6 +2168,7 @@ dump_config(ServerOptions *o) + dump_cfg_int(sMaxSessions, o->max_sessions); + dump_cfg_int(sClientAliveInterval, o->client_alive_interval); + dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); ++ dump_cfg_int(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); + + /* formatted integer arguments */ + dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); +@@ -2213,6 +2216,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); ++ dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); + dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); +@@ -2231,7 +2235,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sRevokedKeys, o->revoked_keys_file); + dump_cfg_string(sAuthorizedPrincipalsFile, + o->authorized_principals_file); +- dump_cfg_string(sVersionAddendum, o->version_addendum); ++ dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' ++ ? "none" : o->version_addendum); + dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); + dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); + dump_cfg_string(sHostKeyAgent, o->host_key_agent); +@@ -2251,7 +2256,7 @@ dump_config(ServerOptions *o) + o->authorized_keys_files); + dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, + o->host_key_files); +- dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, ++ dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, + o->host_cert_files); + dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); + dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); diff --git a/openssh-6.8p1-880575.patch b/openssh-6.8p1-880575.patch new file mode 100644 index 0000000..9936282 --- /dev/null +++ b/openssh-6.8p1-880575.patch @@ -0,0 +1,11 @@ +--- openssh-6.8p1/authfile.c.orig 2015-03-26 09:59:06.646924879 +0100 ++++ openssh-6.8p1/authfile.c 2015-03-26 09:59:19.310905998 +0100 +@@ -194,7 +194,7 @@ + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("Permissions 0%3.3o for '%s' are too open.", + (u_int)st.st_mode & 0777, filename); +- error("It is recommended that your private key files are NOT accessible by others."); ++ error("It is required that your private key files are NOT accessible by others."); + error("This private key will be ignored."); + return SSH_ERR_KEY_BAD_PERMISSIONS; + } diff --git a/openssh-6.6p1-gsissh.patch b/openssh-6.8p1-gsissh.patch similarity index 85% rename from openssh-6.6p1-gsissh.patch rename to openssh-6.8p1-gsissh.patch index 5bf7cc9..2ffe24a 100644 --- a/openssh-6.6p1-gsissh.patch +++ b/openssh-6.8p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c ---- openssh-6.6p1.orig/auth2.c 2015-01-15 20:08:13.117214971 +0100 -+++ openssh-6.6p1/auth2.c 2015-01-15 20:08:56.673616238 +0100 -@@ -49,6 +49,7 @@ +diff -Nur openssh-6.8p1.orig/auth2.c openssh-6.8p1/auth2.c +--- openssh-6.8p1.orig/auth2.c 2015-04-13 20:23:30.749419514 +0200 ++++ openssh-6.8p1/auth2.c 2015-04-13 20:24:30.206740480 +0200 +@@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" #include "buffer.h" @@ -9,7 +9,7 @@ diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -73,6 +74,8 @@ +@@ -74,6 +75,8 @@ extern Authmethod method_gssapi; #endif @@ -120,18 +120,18 @@ diff -Nur openssh-6.6p1.orig/auth2.c openssh-6.6p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c ---- openssh-6.6p1.orig/auth2-gss.c 2015-01-15 20:08:13.020214078 +0100 -+++ openssh-6.6p1/auth2-gss.c 2015-01-15 20:08:56.674616247 +0100 -@@ -47,6 +47,7 @@ +diff -Nur openssh-6.8p1.orig/auth2-gss.c openssh-6.8p1/auth2-gss.c +--- openssh-6.8p1.orig/auth2-gss.c 2015-04-13 20:23:30.664420485 +0200 ++++ openssh-6.8p1/auth2-gss.c 2015-04-13 20:31:12.831142116 +0200 +@@ -49,6 +49,7 @@ extern ServerOptions options; +static void ssh_gssapi_userauth_error(Gssctxt *ctxt); - static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); -@@ -59,8 +60,8 @@ + static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); + static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); + static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +@@ -61,8 +62,8 @@ userauth_gsskeyex(Authctxt *authctxt) { int authenticated = 0; @@ -142,7 +142,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c u_int len; mic.value = packet_get_string(&len); -@@ -74,13 +75,27 @@ +@@ -76,13 +77,27 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -173,7 +173,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -101,7 +116,10 @@ +@@ -103,7 +118,10 @@ u_int len; u_char *doid = NULL; @@ -185,7 +185,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c return (0); mechs = packet_get_int(); -@@ -166,7 +184,7 @@ +@@ -168,7 +186,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -194,7 +194,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c u_int len; if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) -@@ -184,6 +202,7 @@ +@@ -186,6 +204,7 @@ free(recv_tok.value); if (GSS_ERROR(maj_status)) { @@ -202,8 +202,8 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c if (send_tok.length != 0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); packet_put_string(send_tok.value, send_tok.length); -@@ -247,6 +266,32 @@ - gss_release_buffer(&maj_status, &send_tok); +@@ -251,6 +270,32 @@ + return 0; } +static void @@ -235,7 +235,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -262,6 +307,8 @@ +@@ -266,6 +311,8 @@ if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); @@ -244,7 +244,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -269,8 +316,13 @@ +@@ -273,8 +320,13 @@ packet_check_eom(); @@ -260,7 +260,7 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -311,9 +363,16 @@ +@@ -316,9 +368,16 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -279,8 +279,8 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -330,6 +389,23 @@ - userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); +@@ -336,6 +395,23 @@ + return 0; } +static void ssh_gssapi_userauth_error(Gssctxt *ctxt) { @@ -303,11 +303,11 @@ diff -Nur openssh-6.6p1.orig/auth2-gss.c openssh-6.6p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c ---- openssh-6.6p1.orig/auth.c 2015-01-15 20:08:13.116214962 +0100 -+++ openssh-6.6p1/auth.c 2015-01-15 20:08:56.675616256 +0100 -@@ -74,6 +74,9 @@ - #include "krl.h" +diff -Nur openssh-6.8p1.orig/auth.c openssh-6.8p1/auth.c +--- openssh-6.8p1.orig/auth.c 2015-04-13 20:23:30.748419526 +0200 ++++ openssh-6.8p1/auth.c 2015-04-13 20:24:30.208740457 +0200 +@@ -75,6 +75,9 @@ + #include "ssherr.h" #include "compat.h" +#include "version.h" @@ -316,7 +316,7 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -298,7 +301,8 @@ +@@ -299,7 +302,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -326,7 +326,7 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c get_remote_ipaddr(), get_remote_port(), compat20 ? "ssh2" : "ssh1", -@@ -324,6 +328,23 @@ +@@ -325,6 +329,23 @@ if (authenticated == 0 && !authctxt->postponed) audit_event(audit_classify_auth(method)); #endif @@ -349,8 +349,8 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c + } } - /* -@@ -604,6 +625,10 @@ + +@@ -620,6 +641,10 @@ #endif pw = getpwnam(user); @@ -361,7 +361,7 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -623,7 +648,8 @@ +@@ -639,7 +664,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -371,9 +371,9 @@ diff -Nur openssh-6.6p1.orig/auth.c openssh-6.6p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c ---- openssh-6.6p1.orig/auth-pam.c 2015-01-15 20:08:13.146215238 +0100 -+++ openssh-6.6p1/auth-pam.c 2015-01-15 20:08:56.676616265 +0100 +diff -Nur openssh-6.8p1.orig/auth-pam.c openssh-6.8p1/auth-pam.c +--- openssh-6.8p1.orig/auth-pam.c 2015-04-13 20:23:30.769419286 +0200 ++++ openssh-6.8p1/auth-pam.c 2015-04-14 08:07:16.092353124 +0200 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -385,7 +385,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c typedef pid_t sp_pthread_t; #endif -@@ -277,6 +281,55 @@ +@@ -277,6 +281,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -414,7 +414,8 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c + const char *user; + + debug("sshpam_check_userchanged"); -+ sshpam_err = pam_get_item(sshpam_handle, PAM_USER, &user); ++ sshpam_err = pam_get_item(sshpam_handle, PAM_USER, ++ (sshpam_const void **)&user); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: could not get PAM_USER: %s", + pam_strerror(sshpam_handle, sshpam_err)); @@ -441,7 +442,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -299,7 +352,7 @@ +@@ -299,7 +353,7 @@ static void import_environments(Buffer *b) { @@ -450,7 +451,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c u_int i, num_env; int err; -@@ -309,6 +362,17 @@ +@@ -309,6 +363,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -468,21 +469,21 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -475,6 +539,13 @@ +@@ -475,6 +540,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; + if (options.permit_pam_user_change) { -+ debug("sshpam_thread: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ debug("sshpam_thread: user is '%.100s'", ++ sshpam_authctxt->pw->pw_name); + sshpam_check_userchanged(); -+ debug("sshpam_thread: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ debug("sshpam_thread: user is '%.100s'", ++ sshpam_authctxt->pw->pw_name); + } if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -495,6 +566,11 @@ +@@ -495,6 +567,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -494,7 +495,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -912,6 +988,18 @@ +@@ -912,6 +989,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -513,7 +514,7 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1209,6 +1297,9 @@ +@@ -1209,6 +1298,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -523,9 +524,9 @@ diff -Nur openssh-6.6p1.orig/auth-pam.c openssh-6.6p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-6.6p1.orig/auth-pam.h openssh-6.6p1/auth-pam.h ---- openssh-6.6p1.orig/auth-pam.h 2015-01-15 20:08:12.937213313 +0100 -+++ openssh-6.6p1/auth-pam.h 2015-01-15 20:08:56.677616275 +0100 +diff -Nur openssh-6.8p1.orig/auth-pam.h openssh-6.8p1/auth-pam.h +--- openssh-6.8p1.orig/auth-pam.h 2015-04-13 20:23:30.590421330 +0200 ++++ openssh-6.8p1/auth-pam.h 2015-04-13 20:24:30.209740445 +0200 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -533,18 +534,18 @@ diff -Nur openssh-6.6p1.orig/auth-pam.h openssh-6.6p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c ---- openssh-6.6p1.orig/canohost.c 2015-01-15 20:08:13.072214556 +0100 -+++ openssh-6.6p1/canohost.c 2015-01-15 20:08:56.678616284 +0100 -@@ -16,6 +16,7 @@ - +diff -Nur openssh-6.8p1.orig/canohost.c openssh-6.8p1/canohost.c +--- openssh-6.8p1.orig/canohost.c 2015-04-13 20:23:30.694420142 +0200 ++++ openssh-6.8p1/canohost.c 2015-04-13 20:30:24.391695342 +0200 +@@ -17,6 +17,7 @@ #include #include + #include +#include /* for MAXHOSTNAMELEN */ #include #include -@@ -453,3 +454,33 @@ +@@ -468,3 +469,33 @@ { return get_port(1); } @@ -578,9 +579,9 @@ diff -Nur openssh-6.6p1.orig/canohost.c openssh-6.6p1/canohost.c + } + } +} -diff -Nur openssh-6.6p1.orig/canohost.h openssh-6.6p1/canohost.h ---- openssh-6.6p1.orig/canohost.h 2015-01-15 20:08:13.073214566 +0100 -+++ openssh-6.6p1/canohost.h 2015-01-15 20:08:56.679616293 +0100 +diff -Nur openssh-6.8p1.orig/canohost.h openssh-6.8p1/canohost.h +--- openssh-6.8p1.orig/canohost.h 2015-04-13 20:23:30.695420131 +0200 ++++ openssh-6.8p1/canohost.h 2015-04-13 20:24:30.210740434 +0200 @@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -588,10 +589,10 @@ diff -Nur openssh-6.6p1.orig/canohost.h openssh-6.6p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac ---- openssh-6.6p1.orig/configure.ac 2015-01-15 20:08:13.022214096 +0100 -+++ openssh-6.6p1/configure.ac 2015-01-15 20:08:56.681616311 +0100 -@@ -4133,6 +4133,14 @@ +diff -Nur openssh-6.8p1.orig/configure.ac openssh-6.8p1/configure.ac +--- openssh-6.8p1.orig/configure.ac 2015-04-13 20:23:30.736419663 +0200 ++++ openssh-6.8p1/configure.ac 2015-04-13 20:24:30.211740422 +0200 +@@ -4244,6 +4244,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -606,7 +607,7 @@ diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4172,6 +4180,50 @@ +@@ -4283,6 +4291,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -657,10 +658,10 @@ diff -Nur openssh-6.6p1.orig/configure.ac openssh-6.6p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c ---- openssh-6.6p1.orig/gss-genr.c 2015-01-15 20:08:13.023214105 +0100 -+++ openssh-6.6p1/gss-genr.c 2015-01-15 20:08:56.681616311 +0100 -@@ -38,6 +38,7 @@ +diff -Nur openssh-6.8p1.orig/gss-genr.c openssh-6.8p1/gss-genr.c +--- openssh-6.8p1.orig/gss-genr.c 2015-04-13 20:23:30.666420462 +0200 ++++ openssh-6.8p1/gss-genr.c 2015-04-13 20:24:30.212740411 +0200 +@@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" #include "log.h" @@ -668,7 +669,7 @@ diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -367,9 +368,18 @@ +@@ -368,9 +369,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -688,7 +689,7 @@ diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -377,6 +387,7 @@ +@@ -378,6 +388,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -696,10 +697,10 @@ diff -Nur openssh-6.6p1.orig/gss-genr.c openssh-6.6p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c ---- openssh-6.6p1.orig/gss-serv.c 2015-01-15 20:08:13.068214520 +0100 -+++ openssh-6.6p1/gss-serv.c 2015-01-15 20:08:56.682616321 +0100 -@@ -48,14 +48,17 @@ +diff -Nur openssh-6.8p1.orig/gss-serv.c openssh-6.8p1/gss-serv.c +--- openssh-6.8p1.orig/gss-serv.c 2015-04-13 20:23:30.667420451 +0200 ++++ openssh-6.8p1/gss-serv.c 2015-04-13 20:24:30.214740388 +0200 +@@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -718,7 +719,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -63,14 +66,24 @@ +@@ -62,14 +65,24 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -743,7 +744,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -231,6 +244,10 @@ +@@ -230,6 +243,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -754,7 +755,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c } return (status); -@@ -250,6 +267,17 @@ +@@ -249,6 +266,17 @@ tok = ename->value; @@ -772,7 +773,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -317,8 +345,11 @@ +@@ -316,8 +344,11 @@ return GSS_S_COMPLETE; } @@ -786,7 +787,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); -@@ -361,9 +392,12 @@ +@@ -360,9 +391,12 @@ if (client->mech == NULL) return GSS_S_FAILURE; @@ -801,7 +802,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -390,6 +424,10 @@ +@@ -389,6 +423,10 @@ /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -812,7 +813,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c return (ctx->major); } -@@ -397,6 +435,7 @@ +@@ -396,6 +434,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -820,7 +821,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -412,6 +451,14 @@ +@@ -411,6 +450,14 @@ gssapi_client.store.data = NULL; } } @@ -835,7 +836,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c } /* As user */ -@@ -419,6 +466,11 @@ +@@ -418,6 +465,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -847,7 +848,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -442,8 +494,9 @@ +@@ -441,8 +493,9 @@ } /* Privileged */ @@ -858,7 +859,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c { OM_uint32 lmin; -@@ -452,6 +505,12 @@ +@@ -451,6 +504,12 @@ debug("No suitable client data"); return 0; } @@ -871,7 +872,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -471,6 +530,24 @@ +@@ -470,6 +529,24 @@ return (0); } @@ -896,7 +897,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -497,6 +574,7 @@ +@@ -496,6 +573,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -904,7 +905,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -526,6 +604,18 @@ +@@ -525,6 +603,18 @@ if (ret) return; @@ -923,7 +924,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -557,4 +647,13 @@ +@@ -556,4 +646,13 @@ return ok; } @@ -937,10 +938,10 @@ diff -Nur openssh-6.6p1.orig/gss-serv.c openssh-6.6p1/gss-serv.c +} + #endif -diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c ---- openssh-6.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/gss-serv-gsi.c 2015-01-15 20:08:56.682616321 +0100 -@@ -0,0 +1,238 @@ +diff -Nur openssh-6.8p1.orig/gss-serv-gsi.c openssh-6.8p1/gss-serv-gsi.c +--- openssh-6.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.8p1/gss-serv-gsi.c 2015-04-13 23:54:37.138628621 +0200 +@@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * @@ -980,6 +981,7 @@ diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c +#include "hostfile.h" +#include "auth.h" +#include "log.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" + +#include "buffer.h" @@ -1179,9 +1181,9 @@ diff -Nur openssh-6.6p1.orig/gss-serv-gsi.c openssh-6.6p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c ---- openssh-6.6p1.orig/gss-serv-krb5.c 2015-01-15 20:08:13.108214888 +0100 -+++ openssh-6.6p1/gss-serv-krb5.c 2015-01-15 20:08:56.683616330 +0100 +diff -Nur openssh-6.8p1.orig/gss-serv-krb5.c openssh-6.8p1/gss-serv-krb5.c +--- openssh-6.8p1.orig/gss-serv-krb5.c 2015-04-13 20:23:30.722419823 +0200 ++++ openssh-6.8p1/gss-serv-krb5.c 2015-04-13 20:24:30.215740377 +0200 @@ -359,6 +359,34 @@ return found_principal; } @@ -1235,18 +1237,18 @@ diff -Nur openssh-6.6p1.orig/gss-serv-krb5.c openssh-6.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c ---- openssh-6.6p1.orig/kexgsss.c 2015-01-15 20:08:13.025214124 +0100 -+++ openssh-6.6p1/kexgsss.c 2015-01-15 20:08:56.683616330 +0100 -@@ -44,6 +44,7 @@ - #include "monitor_wrap.h" - #include "servconf.h" +diff -Nur openssh-6.8p1.orig/kexgsss.c openssh-6.8p1/kexgsss.c +--- openssh-6.8p1.orig/kexgsss.c 2015-04-13 20:23:30.668420439 +0200 ++++ openssh-6.8p1/kexgsss.c 2015-04-13 20:24:30.216740365 +0200 +@@ -47,6 +47,7 @@ + #include "ssh-gss.h" + #include "digest.h" +static void kex_gss_send_error(Gssctxt *ctxt); extern ServerOptions options; - void -@@ -89,8 +90,10 @@ + int +@@ -94,8 +95,10 @@ debug2("%s: Acquiring credentials", __func__); @@ -1256,9 +1258,9 @@ diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c fatal("Unable to acquire credentials for the server"); + } - switch (kex->kex_type) { + switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -176,12 +179,13 @@ +@@ -181,12 +184,13 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1273,9 +1275,9 @@ diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -285,4 +289,23 @@ - if (options.gss_store_rekey) +@@ -292,4 +296,23 @@ ssh_gssapi_rekey_creds(); + return 0; } + +static void @@ -1297,9 +1299,9 @@ diff -Nur openssh-6.6p1.orig/kexgsss.c openssh-6.6p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-6.6p1.orig/LICENSE.globus_usage openssh-6.6p1/LICENSE.globus_usage ---- openssh-6.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/LICENSE.globus_usage 2015-01-15 20:08:56.684616339 +0100 +diff -Nur openssh-6.8p1.orig/LICENSE.globus_usage openssh-6.8p1/LICENSE.globus_usage +--- openssh-6.8p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.8p1/LICENSE.globus_usage 2015-04-13 20:24:30.216740365 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1319,12 +1321,12 @@ diff -Nur openssh-6.6p1.orig/LICENSE.globus_usage openssh-6.6p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-6.6p1.orig/Makefile.in openssh-6.6p1/Makefile.in ---- openssh-6.6p1.orig/Makefile.in 2015-01-15 20:08:13.135215137 +0100 -+++ openssh-6.6p1/Makefile.in 2015-01-15 20:08:56.684616339 +0100 -@@ -99,8 +99,10 @@ - monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - kexc25519s.o auth-krb5.o \ +diff -Nur openssh-6.8p1.orig/Makefile.in openssh-6.8p1/Makefile.in +--- openssh-6.8p1.orig/Makefile.in 2015-04-13 20:23:30.759419400 +0200 ++++ openssh-6.8p1/Makefile.in 2015-04-13 20:24:30.217740354 +0200 +@@ -113,8 +113,10 @@ + auth2-none.o auth2-passwd.o auth2-pubkey.o \ + monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ @@ -1333,10 +1335,10 @@ diff -Nur openssh-6.6p1.orig/Makefile.in openssh-6.6p1/Makefile.in roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o -diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c ---- openssh-6.6p1.orig/misc.c 2015-01-15 20:08:13.106214870 +0100 -+++ openssh-6.6p1/misc.c 2015-01-15 20:08:56.685616348 +0100 -@@ -159,11 +159,14 @@ +diff -Nur openssh-6.8p1.orig/misc.c openssh-6.8p1/misc.c +--- openssh-6.8p1.orig/misc.c 2015-04-13 20:23:30.719419857 +0200 ++++ openssh-6.8p1/misc.c 2015-04-13 20:24:30.218740342 +0200 +@@ -160,11 +160,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1352,7 +1354,7 @@ diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c int wspace = 0; if (*s == NULL) -@@ -171,6 +174,21 @@ +@@ -172,6 +175,21 @@ old = *s; @@ -1374,7 +1376,7 @@ diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); -@@ -226,6 +244,20 @@ +@@ -227,6 +245,20 @@ return copy; } @@ -1395,10 +1397,10 @@ diff -Nur openssh-6.6p1.orig/misc.c openssh-6.6p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-6.6p1.orig/misc.h openssh-6.6p1/misc.h ---- openssh-6.6p1.orig/misc.h 2015-01-15 20:08:13.076214593 +0100 -+++ openssh-6.6p1/misc.h 2015-01-15 20:08:56.685616348 +0100 -@@ -41,6 +41,7 @@ +diff -Nur openssh-6.8p1.orig/misc.h openssh-6.8p1/misc.h +--- openssh-6.8p1.orig/misc.h 2015-04-13 20:23:30.698420097 +0200 ++++ openssh-6.8p1/misc.h 2015-04-13 20:24:30.218740342 +0200 +@@ -61,6 +61,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1406,10 +1408,10 @@ diff -Nur openssh-6.6p1.orig/misc.h openssh-6.6p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c ---- openssh-6.6p1.orig/monitor.c 2015-01-15 20:08:13.150215275 +0100 -+++ openssh-6.6p1/monitor.c 2015-01-15 20:08:56.686616358 +0100 -@@ -182,6 +182,9 @@ +diff -Nur openssh-6.8p1.orig/monitor.c openssh-6.8p1/monitor.c +--- openssh-6.8p1.orig/monitor.c 2015-04-13 20:23:30.771419263 +0200 ++++ openssh-6.8p1/monitor.c 2015-04-13 20:24:30.220740320 +0200 +@@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1419,16 +1421,16 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -230,7 +233,7 @@ - struct mon_table mon_dispatch_proto20[] = { +@@ -217,7 +220,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, + #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, - {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_PWNAM, MON_AUTH, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -238,7 +241,7 @@ +@@ -225,7 +228,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1437,7 +1439,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -268,6 +271,9 @@ +@@ -255,6 +258,9 @@ {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, @@ -1447,7 +1449,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -277,6 +283,8 @@ +@@ -264,6 +270,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1455,8 +1457,8 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c + {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs}, {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif - {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, -@@ -314,7 +322,7 @@ + #ifdef WITH_OPENSSL +@@ -304,7 +312,7 @@ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM @@ -1465,7 +1467,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -406,6 +414,8 @@ +@@ -399,6 +407,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1474,7 +1476,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_proto15; -@@ -520,6 +530,8 @@ +@@ -513,6 +523,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1483,7 +1485,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -790,14 +802,17 @@ +@@ -844,14 +856,17 @@ debug3("%s", __func__); @@ -1504,7 +1506,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2307,12 +2322,15 @@ +@@ -2221,12 +2236,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1521,7 +1523,7 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2320,12 +2338,77 @@ +@@ -2234,12 +2252,77 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1600,9 +1602,9 @@ diff -Nur openssh-6.6p1.orig/monitor.c openssh-6.6p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-6.6p1.orig/monitor.h openssh-6.6p1/monitor.h ---- openssh-6.6p1.orig/monitor.h 2015-01-15 20:08:13.121215008 +0100 -+++ openssh-6.6p1/monitor.h 2015-01-15 20:08:56.686616358 +0100 +diff -Nur openssh-6.8p1.orig/monitor.h openssh-6.8p1/monitor.h +--- openssh-6.8p1.orig/monitor.h 2015-04-13 20:23:30.752419480 +0200 ++++ openssh-6.8p1/monitor.h 2015-04-13 20:24:30.221740308 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1616,10 +1618,10 @@ diff -Nur openssh-6.6p1.orig/monitor.h openssh-6.6p1/monitor.h }; struct mm_master; -diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c ---- openssh-6.6p1.orig/monitor_wrap.c 2015-01-15 20:08:13.151215284 +0100 -+++ openssh-6.6p1/monitor_wrap.c 2015-01-15 20:08:56.687616367 +0100 -@@ -1327,12 +1327,13 @@ +diff -Nur openssh-6.8p1.orig/monitor_wrap.c openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1.orig/monitor_wrap.c 2015-04-13 20:23:30.771419263 +0200 ++++ openssh-6.8p1/monitor_wrap.c 2015-04-13 20:24:30.222740297 +0200 +@@ -1121,12 +1121,13 @@ } int @@ -1634,7 +1636,7 @@ diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1345,6 +1346,83 @@ +@@ -1139,6 +1140,83 @@ return (authenticated); } @@ -1718,9 +1720,9 @@ diff -Nur openssh-6.6p1.orig/monitor_wrap.c openssh-6.6p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-6.6p1.orig/monitor_wrap.h openssh-6.6p1/monitor_wrap.h ---- openssh-6.6p1.orig/monitor_wrap.h 2015-01-15 20:08:13.131215100 +0100 -+++ openssh-6.6p1/monitor_wrap.h 2015-01-15 20:08:56.687616367 +0100 +diff -Nur openssh-6.8p1.orig/monitor_wrap.h openssh-6.8p1/monitor_wrap.h +--- openssh-6.8p1.orig/monitor_wrap.h 2015-04-13 20:23:30.752419480 +0200 ++++ openssh-6.8p1/monitor_wrap.h 2015-04-13 20:24:30.223740285 +0200 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1736,10 +1738,10 @@ diff -Nur openssh-6.6p1.orig/monitor_wrap.h openssh-6.6p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-6.6p1.orig/readconf.c openssh-6.6p1/readconf.c ---- openssh-6.6p1.orig/readconf.c 2015-01-15 20:08:13.028214151 +0100 -+++ openssh-6.6p1/readconf.c 2015-01-15 20:08:56.688616376 +0100 -@@ -1651,13 +1651,13 @@ +diff -Nur openssh-6.8p1.orig/readconf.c openssh-6.8p1/readconf.c +--- openssh-6.8p1.orig/readconf.c 2015-04-13 20:23:30.670420417 +0200 ++++ openssh-6.8p1/readconf.c 2015-04-13 20:24:30.224740274 +0200 +@@ -1763,13 +1763,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1757,10 +1759,10 @@ diff -Nur openssh-6.6p1.orig/readconf.c openssh-6.6p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; if (options->password_authentication == -1) -diff -Nur openssh-6.6p1.orig/readconf.h openssh-6.6p1/readconf.h ---- openssh-6.6p1.orig/readconf.h 2015-01-15 20:08:13.028214151 +0100 -+++ openssh-6.6p1/readconf.h 2015-01-15 20:08:56.688616376 +0100 -@@ -93,6 +93,8 @@ +diff -Nur openssh-6.8p1.orig/readconf.h openssh-6.8p1/readconf.h +--- openssh-6.8p1.orig/readconf.h 2015-04-13 20:23:30.670420417 +0200 ++++ openssh-6.8p1/readconf.h 2015-04-13 20:24:30.225740263 +0200 +@@ -84,6 +84,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1769,10 +1771,10 @@ diff -Nur openssh-6.6p1.orig/readconf.h openssh-6.6p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c ---- openssh-6.6p1.orig/servconf.c 2015-01-15 20:08:13.152215293 +0100 -+++ openssh-6.6p1/servconf.c 2015-01-15 20:16:24.463735405 +0100 -@@ -71,6 +71,7 @@ +diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c +--- openssh-6.8p1.orig/servconf.c 2015-04-13 20:23:30.772419252 +0200 ++++ openssh-6.8p1/servconf.c 2015-04-14 10:46:40.415664385 +0200 +@@ -74,6 +74,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1780,7 +1782,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -108,9 +109,11 @@ +@@ -114,9 +115,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1792,7 +1794,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c options->gss_store_rekey = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; -@@ -151,6 +154,8 @@ +@@ -160,6 +163,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1801,7 +1803,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -167,6 +172,8 @@ +@@ -186,6 +191,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1810,7 +1812,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -249,13 +256,17 @@ +@@ -274,13 +281,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1830,19 +1832,19 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; if (options->password_authentication == -1) -@@ -338,7 +349,7 @@ +@@ -388,7 +399,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sUsePAM, + sUsePAM, sPermitPAMUserChange, /* Standard Options */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, - sPermitRootLogin, sLogFacility, sLogLevel, -@@ -359,10 +370,14 @@ + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, + sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, +@@ -409,10 +420,14 @@ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, + sGsiAllowLimitedProxy, @@ -1854,7 +1856,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, sVersionAddendum, -@@ -384,8 +399,10 @@ +@@ -436,8 +451,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1865,7 +1867,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -428,16 +445,26 @@ +@@ -482,16 +499,26 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1892,7 +1894,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -499,6 +526,8 @@ +@@ -554,6 +581,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1901,7 +1903,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -906,6 +935,10 @@ +@@ -967,6 +996,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1912,7 +1914,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1121,6 +1154,10 @@ +@@ -1200,6 +1233,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1923,7 +1925,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1129,6 +1166,10 @@ +@@ -1208,6 +1245,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1934,7 +1936,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1137,6 +1178,12 @@ +@@ -1216,6 +1257,12 @@ intptr = &options->gss_store_rekey; goto parse_flag; @@ -1947,13 +1949,30 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1602,6 +1649,18 @@ +@@ -1690,6 +1737,35 @@ *charptr = xstrdup(arg); break; + case sDisUsageStats: -+ intptr = &options->disable_usage_stats; -+ goto parse_flag; ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing value.", ++ filename, linenum); ++ if (!strcasecmp(arg, "true") || ++ !strcasecmp(arg, "enabled") || ++ !strcasecmp(arg, "yes") || ++ !strcasecmp(arg, "on") || ++ !strcasecmp(arg, "1")) ++ options->disable_usage_stats = 1; ++ else if (!strcasecmp(arg, "false") || ++ !strcasecmp(arg, "disabled") || ++ !strcasecmp(arg, "no") || ++ !strcasecmp(arg, "off") || ++ !strcasecmp(arg, "0")) ++ options->disable_usage_stats = 0; ++ else ++ fatal("Incorrect value for disable_usage_stats"); ++ break; + + case sUsageStatsTarg: + arg = strdelim(&cp); @@ -1966,7 +1985,7 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -1811,6 +1870,7 @@ +@@ -1933,6 +2009,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1974,10 +1993,10 @@ diff -Nur openssh-6.6p1.orig/servconf.c openssh-6.6p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h ---- openssh-6.6p1.orig/servconf.h 2015-01-15 20:08:13.109214897 +0100 -+++ openssh-6.6p1/servconf.h 2015-01-15 20:08:56.690616394 +0100 -@@ -111,9 +111,12 @@ +diff -Nur openssh-6.8p1.orig/servconf.h openssh-6.8p1/servconf.h +--- openssh-6.8p1.orig/servconf.h 2015-04-13 20:23:30.723419811 +0200 ++++ openssh-6.8p1/servconf.h 2015-04-13 20:24:30.228740228 +0200 +@@ -114,9 +114,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -1990,7 +2009,7 @@ diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; int password_authentication; /* If true, permit password -@@ -168,6 +171,7 @@ +@@ -172,6 +175,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -1998,7 +2017,7 @@ diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h int permit_tun; -@@ -176,6 +180,10 @@ +@@ -180,6 +184,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2009,10 +2028,10 @@ diff -Nur openssh-6.6p1.orig/servconf.h openssh-6.6p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_principals_file; -diff -Nur openssh-6.6p1.orig/ssh.1 openssh-6.6p1/ssh.1 ---- openssh-6.6p1.orig/ssh.1 2015-01-15 20:08:12.997213865 +0100 -+++ openssh-6.6p1/ssh.1 2015-01-15 20:08:56.690616394 +0100 -@@ -1295,6 +1295,18 @@ +diff -Nur openssh-6.8p1.orig/ssh.1 openssh-6.8p1/ssh.1 +--- openssh-6.8p1.orig/ssh.1 2015-04-13 20:23:30.642420736 +0200 ++++ openssh-6.8p1/ssh.1 2015-04-13 20:24:30.229740217 +0200 +@@ -1298,6 +1298,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2031,10 +2050,10 @@ diff -Nur openssh-6.6p1.orig/ssh.1 openssh-6.6p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c ---- openssh-6.6p1.orig/ssh.c 2015-01-15 20:08:13.141215192 +0100 -+++ openssh-6.6p1/ssh.c 2015-01-15 20:08:56.691616404 +0100 -@@ -395,6 +395,32 @@ +diff -Nur openssh-6.8p1.orig/ssh.c openssh-6.8p1/ssh.c +--- openssh-6.8p1.orig/ssh.c 2015-04-13 20:23:30.763419355 +0200 ++++ openssh-6.8p1/ssh.c 2015-04-13 22:10:01.137426177 +0200 +@@ -466,6 +466,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2050,24 +2069,24 @@ diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, &options, 1); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, &options, 1); +#endif +#if defined(KRB5) + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, &options, 1); +#endif +#endif r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -988,8 +1014,12 @@ +@@ -1131,8 +1157,12 @@ logit("FIPS mode initialized"); } @@ -2081,9 +2100,9 @@ diff -Nur openssh-6.6p1.orig/ssh.c openssh-6.6p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-6.6p1.orig/ssh_config openssh-6.6p1/ssh_config ---- openssh-6.6p1.orig/ssh_config 2015-01-15 20:08:13.031214179 +0100 -+++ openssh-6.6p1/ssh_config 2015-01-15 20:08:56.691616404 +0100 +diff -Nur openssh-6.8p1.orig/ssh_config openssh-6.8p1/ssh_config +--- openssh-6.8p1.orig/ssh_config 2015-04-13 20:23:30.672420394 +0200 ++++ openssh-6.8p1/ssh_config 2015-04-13 20:24:30.230740205 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2099,9 +2118,9 @@ diff -Nur openssh-6.6p1.orig/ssh_config openssh-6.6p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-6.6p1.orig/ssh_config.5 openssh-6.6p1/ssh_config.5 ---- openssh-6.6p1.orig/ssh_config.5 2015-01-15 20:08:13.031214179 +0100 -+++ openssh-6.6p1/ssh_config.5 2015-01-15 20:08:56.692616413 +0100 +diff -Nur openssh-6.8p1.orig/ssh_config.5 openssh-6.8p1/ssh_config.5 +--- openssh-6.8p1.orig/ssh_config.5 2015-04-13 20:23:30.672420394 +0200 ++++ openssh-6.8p1/ssh_config.5 2015-04-13 20:24:30.231740194 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2115,10 +2134,10 @@ diff -Nur openssh-6.6p1.orig/ssh_config.5 openssh-6.6p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c ---- openssh-6.6p1.orig/sshconnect2.c 2015-01-15 20:08:13.142215201 +0100 -+++ openssh-6.6p1/sshconnect2.c 2015-01-15 20:08:56.692616413 +0100 -@@ -728,6 +728,11 @@ +diff -Nur openssh-6.8p1.orig/sshconnect2.c openssh-6.8p1/sshconnect2.c +--- openssh-6.8p1.orig/sshconnect2.c 2015-04-13 20:23:30.763419355 +0200 ++++ openssh-6.8p1/sshconnect2.c 2015-04-13 20:24:30.231740194 +0200 +@@ -747,6 +747,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2130,8 +2149,8 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -961,6 +966,15 @@ - free(lang); +@@ -984,6 +989,15 @@ + return 0; } +#ifdef GSI @@ -2146,7 +2165,7 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -978,8 +992,16 @@ +@@ -1001,8 +1015,16 @@ return (0); } @@ -2163,7 +2182,7 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -990,7 +1012,15 @@ +@@ -1013,7 +1035,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2179,9 +2198,9 @@ diff -Nur openssh-6.6p1.orig/sshconnect2.c openssh-6.6p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-6.6p1.orig/sshd.8 openssh-6.6p1/sshd.8 ---- openssh-6.6p1.orig/sshd.8 2015-01-15 20:08:13.036214225 +0100 -+++ openssh-6.6p1/sshd.8 2015-01-15 20:08:56.693616422 +0100 +diff -Nur openssh-6.8p1.orig/sshd.8 openssh-6.8p1/sshd.8 +--- openssh-6.8p1.orig/sshd.8 2015-04-13 20:23:30.727419766 +0200 ++++ openssh-6.8p1/sshd.8 2015-04-13 20:24:30.232740183 +0200 @@ -766,6 +766,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2227,18 +2246,18 @@ diff -Nur openssh-6.6p1.orig/sshd.8 openssh-6.6p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c ---- openssh-6.6p1.orig/sshd.c 2015-01-15 20:08:13.154215312 +0100 -+++ openssh-6.6p1/sshd.c 2015-01-15 20:08:56.693616422 +0100 -@@ -124,6 +124,7 @@ - #include "audit.h" +diff -Nur openssh-6.8p1.orig/sshd.c openssh-6.8p1/sshd.c +--- openssh-6.8p1.orig/sshd.c 2015-04-13 20:23:30.776419206 +0200 ++++ openssh-6.8p1/sshd.c 2015-04-13 20:32:10.658481671 +0200 +@@ -128,6 +128,7 @@ #include "ssh-sandbox.h" #include "version.h" + #include "ssherr.h" +#include "ssh-globus-usage.h" - #ifdef USE_SECURITY_SESSION_API - #include -@@ -1709,6 +1710,13 @@ + #ifdef LIBWRAP + #include +@@ -1788,6 +1789,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2252,7 +2271,7 @@ diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2240,7 +2248,7 @@ +@@ -2348,7 +2356,7 @@ #endif #ifdef GSSAPI @@ -2261,9 +2280,9 @@ diff -Nur openssh-6.6p1.orig/sshd.c openssh-6.6p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config ---- openssh-6.6p1.orig/sshd_config 2015-01-15 20:08:13.110214907 +0100 -+++ openssh-6.6p1/sshd_config 2015-01-15 20:12:27.743560736 +0100 +diff -Nur openssh-6.8p1.orig/sshd_config openssh-6.8p1/sshd_config +--- openssh-6.8p1.orig/sshd_config 2015-04-13 20:23:30.723419811 +0200 ++++ openssh-6.8p1/sshd_config 2015-04-14 08:42:12.640139901 +0200 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2289,34 +2308,33 @@ diff -Nur openssh-6.6p1.orig/sshd_config openssh-6.6p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -151,3 +156,7 @@ +@@ -151,3 +156,6 @@ # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server + +# Usage Metrics -+#UsageStatsTargets usage-stats.cilogon.org:4810 -+#DisableUsageStats no -diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 ---- openssh-6.6p1.orig/sshd_config.5 2015-01-15 20:08:13.110214907 +0100 -+++ openssh-6.6p1/sshd_config.5 2015-01-15 20:10:59.416747018 +0100 -@@ -449,6 +449,15 @@ ++#UsageStatsTargets usage-stats.example.edu:4810 +diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 +--- openssh-6.8p1.orig/sshd_config.5 2015-04-13 20:23:30.723419811 +0200 ++++ openssh-6.8p1/sshd_config.5 2015-04-14 07:58:57.173124634 +0200 +@@ -512,6 +512,15 @@ See PATTERNS in .Xr ssh_config 5 for more information on patterns. +.It Cm DisableUsageStats -+This keyword can be followed by "yes" to disable reporting of usage metrics. -+Or it can be set to "no" to enable reporting of usage metrics, which is the -+default. Setting the ++This keyword can be followed by one of the keywords "true", "enabled", "yes", ++"on" or "1" to disable reporting of usage metrics. Or it can be set to "false", ++"disabled", "no", "off", "0" to enable reporting of usage metrics. Setting the +.Cm GLOBUS_USAGE_OPTOUT +environment variable to "1" will also disable the reporting of usage metrics. +Disabling reporting of usage metrics will cause the +.Cm UsageStatsTargets +setting to be ignored. - .It Cm ForceCommand - Forces the execution of the command specified by - .Cm ForceCommand , -@@ -493,6 +502,10 @@ + .It Cm FingerprintHash + Specifies the hash algorithm used when logging key fingerprints. + Valid options are: +@@ -564,6 +573,10 @@ The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2327,7 +2345,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .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. -@@ -511,6 +524,22 @@ +@@ -582,6 +595,22 @@ .Xr ksu 1 . The default is .Dq no . @@ -2350,7 +2368,7 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If -@@ -1202,6 +1231,121 @@ +@@ -1410,6 +1439,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2447,32 +2465,14 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 +denotes all tags. +.El +.Pp -+By default, Usage Metrics reporting is sent to -+.Dq usage-stats.cilogon.org:4810 . -+This can be made explicit by specifying -+.Dq default -+(all by itself) for the -+target specification as in: -+.Pp -+.Bl -item -offset indent -compact -+.It ++Usage Metrics reporting is disabled unless +.Cm UsageStatsTargets -+.Sm off -+default -+.Sm on -+.El -+.Pp -+If -+.Cm UsageStatsTargets -+is not specified, a comma-separated list of targets -+(without any tags specified) if specified in the environment variable -+.Cm GLOBUS_USAGE_TARGETS -+will be used. ++is specified. +.Pp .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication. -@@ -1267,6 +1411,12 @@ +@@ -1475,6 +1601,12 @@ as a non-root user. The default is .Dq no . @@ -2485,9 +2485,9 @@ diff -Nur openssh-6.6p1.orig/sshd_config.5 openssh-6.6p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c ---- openssh-6.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/ssh-globus-usage.c 2015-01-15 20:08:56.696616450 +0100 +diff -Nur openssh-6.8p1.orig/ssh-globus-usage.c openssh-6.8p1/ssh-globus-usage.c +--- openssh-6.8p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.8p1/ssh-globus-usage.c 2015-04-14 07:26:22.280670505 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2564,7 +2564,7 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + globus_list_t * list = NULL; + ssh_usage_ent_t * usage_ent = NULL; + -+ if (disable_usage_stats) ++ if (disable_usage_stats || !usage_stats_targets) + return GLOBUS_SUCCESS; + + result = globus_module_activate(GLOBUS_USAGE_MODULE); @@ -2574,12 +2574,7 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + return result; + } + -+ if (!usage_stats_targets || -+ !strcasecmp(usage_stats_targets, "default")) -+ target_str = strdup(CILOGON_COLLECTOR); -+ else -+ target_str = strdup(usage_stats_targets); -+ ++ target_str = strdup(usage_stats_targets); + if (target_str == NULL) + { + error("ERROR: strdup failure for target_str"); @@ -2765,9 +2760,10 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c +} + +static void -+log_usage_stats(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *clientip, -+ char *username, char *userdn) ++log_usage_stats(const char *ssh_release, const char *ssl_release, ++ const char *method, const char *mechanism, ++ const char *clientip, ++ const char *username, const char *userdn) +{ + globus_result_t result; + globus_list_t * list; @@ -2802,7 +2798,7 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + { + case SSH_GLOBUS_USAGE_SSH_VER: + key = "SSH_VER"; -+ value = ssh_release; ++ value = (char *) ssh_release; + break; + + case SSH_GLOBUS_USAGE_SSL_VER: @@ -2812,12 +2808,12 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + + case SSH_GLOBUS_USAGE_METHOD: + key = "METHOD"; -+ value = method; ++ value = (char *) method; + break; + + case SSH_GLOBUS_USAGE_MECHANISM: + key = "MECH"; -+ value = mechanism?:""; ++ value = (char *) mechanism?:""; + break; + + case SSH_GLOBUS_USAGE_CLIENTIP: @@ -2827,12 +2823,12 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + + case SSH_GLOBUS_USAGE_USERNAME: + key = "USER"; -+ value = username?:""; ++ value = (char *) username?:""; + break; + + case SSH_GLOBUS_USAGE_USERDN: + key = "USERDN"; -+ value = userdn?:""; ++ value = (char *) userdn?:""; + break; + + default: @@ -2874,9 +2870,13 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c +#endif /* HAVE_GLOBUS_USAGE */ + +void -+ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *client_ip, -+ char *username, char *userdn) ++ssh_globus_send_usage_metrics(const char *ssh_release, ++ const char *ssl_release, ++ const char *method, ++ const char *mechanism, ++ const char *client_ip, ++ const char *username, ++ const char *userdn) +{ +#ifdef HAVE_GLOBUS_USAGE + @@ -2885,10 +2885,10 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.c openssh-6.6p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h ---- openssh-6.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.6p1/ssh-globus-usage.h 2015-01-15 20:08:56.696616450 +0100 -@@ -0,0 +1,46 @@ +diff -Nur openssh-6.8p1.orig/ssh-globus-usage.h openssh-6.8p1/ssh-globus-usage.h +--- openssh-6.8p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.8p1/ssh-globus-usage.h 2015-04-14 07:28:43.646038850 +0200 +@@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University + * of Illinois. See the LICENSE file for detailed license information. @@ -2919,8 +2919,6 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h + +#include "globus_usage.h" + -+#define CILOGON_COLLECTOR "usage-stats.cilogon.org:4810" -+ +globus_result_t +ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets); + @@ -2930,14 +2928,18 @@ diff -Nur openssh-6.6p1.orig/ssh-globus-usage.h openssh-6.6p1/ssh-globus-usage.h +#endif /* HAVE_GLOBUS_USAGE */ + +void -+ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *client_ip, -+ char *username, char *userdn); ++ssh_globus_send_usage_metrics(const char *ssh_release, ++ const char *ssl_release, ++ const char *method, ++ const char *mechanism, ++ const char *client_ip, ++ const char *username, ++ const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-6.6p1.orig/ssh-gss.h openssh-6.6p1/ssh-gss.h ---- openssh-6.6p1.orig/ssh-gss.h 2015-01-15 20:08:13.036214225 +0100 -+++ openssh-6.6p1/ssh-gss.h 2015-01-15 20:08:56.696616450 +0100 +diff -Nur openssh-6.8p1.orig/ssh-gss.h openssh-6.8p1/ssh-gss.h +--- openssh-6.8p1.orig/ssh-gss.h 2015-04-13 20:23:30.677420337 +0200 ++++ openssh-6.8p1/ssh-gss.h 2015-04-13 20:33:05.203858665 +0200 @@ -91,6 +91,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2974,19 +2976,19 @@ diff -Nur openssh-6.6p1.orig/ssh-gss.h openssh-6.6p1/ssh-gss.h 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); -@@ -164,6 +168,7 @@ - int ssh_gssapi_oid_table_ok(); - +@@ -166,6 +170,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); + + void ssh_gssapi_rekey_creds(void); +void ssh_gssapi_get_client_info(char **userdn, char **mech); #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-6.6p1.orig/version.h openssh-6.6p1/version.h ---- openssh-6.6p1.orig/version.h 2015-01-15 20:08:13.065214492 +0100 -+++ openssh-6.6p1/version.h 2015-01-15 20:08:56.696616450 +0100 +diff -Nur openssh-6.8p1.orig/version.h openssh-6.8p1/version.h +--- openssh-6.8p1.orig/version.h 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/version.h 2015-04-14 07:47:24.569105583 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ + /* $OpenBSD: version.h,v 1.72 2015/03/04 18:53:53 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3000,9 +3002,9 @@ diff -Nur openssh-6.6p1.orig/version.h openssh-6.6p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20140522" ++#define NCSA_VERSION " GSI_GSSAPI_20150323" + - #define SSH_VERSION "OpenSSH_6.6.1" + #define SSH_VERSION "OpenSSH_6.8" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/sources b/sources index a3faed2..d5b3f7b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -3e9800e6bca1fbac0eea4d41baa7f239 openssh-6.6p1.tar.gz +08f72de6751acfbd0892b5f003922701 openssh-6.8p1.tar.gz From b88dcfd5236fadf52948bfdb4e8be2e35e34b037 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 21 Apr 2015 11:00:54 +0200 Subject: [PATCH 011/146] Based on openssh-6.8p1-5.fc22 --- gsi-openssh.spec | 5 ++++- openssh-6.6p1-set_remote_ipaddr.patch | 2 +- openssh-6.7p1-audit.patch | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 3a386ed..912ed7c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 6.8p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Apr 21 2015 Mattias Ellert - 6.8p1-2 +- Based on openssh-6.8p1-5.fc22 + * Mon Apr 13 2015 Mattias Ellert - 6.8p1-1 - Based on openssh-6.8p1-4.fc22 diff --git a/openssh-6.6p1-set_remote_ipaddr.patch b/openssh-6.6p1-set_remote_ipaddr.patch index ec4e416..14ff48c 100644 --- a/openssh-6.6p1-set_remote_ipaddr.patch +++ b/openssh-6.6p1-set_remote_ipaddr.patch @@ -9,7 +9,7 @@ diff -up openssh-6.8p1/canohost.c.set_remote_ipaddr openssh-6.8p1/canohost.c + if (canonical_host_ip != NULL) + free(canonical_host_ip); + -+ if (packet_connection_is_on_socket()) { ++ if (active_state != NULL && packet_connection_is_on_socket()) { + canonical_host_ip = + get_peer_ipaddr(packet_get_connection_in()); + if (canonical_host_ip == NULL) diff --git a/openssh-6.7p1-audit.patch b/openssh-6.7p1-audit.patch index 213ca67..614604e 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -456,7 +456,7 @@ diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, + buf, NULL, -+ listening_for_clients() ? get_remote_ipaddr() : NULL, ++ listening_for_clients() ? NULL : get_remote_ipaddr(), + NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ From bb89cad94faed880d6074cf8a8981a40fc171873 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 17 Jun 2015 09:52:51 +0000 Subject: [PATCH 012/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 912ed7c..808d187 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Jun 17 2015 Fedora Release Engineering - 6.8p1-2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + * Tue Apr 21 2015 Mattias Ellert - 6.8p1-2 - Based on openssh-6.8p1-5.fc22 From 00e17c136bab1c269c47c0af03980eb149a75dc9 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 5 Jul 2015 07:18:45 +0200 Subject: [PATCH 013/146] Based on openssh-6.8p1-10.fc22 --- gsi-openssh.spec | 29 +- openssh-5.8p1-glob.patch | 14 + openssh-6.2p1-vendor.patch | 48 +- openssh-6.6.1p1-servconf-parser.patch | 29 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 69 +- openssh-6.6p1-ctr-cavstest.patch | 2 +- openssh-6.6p1-force_krb.patch | 4 +- openssh-6.6p1-gsskex.patch | 1276 ++++++++--------- openssh-6.6p1-keycat.patch | 90 +- openssh-6.7p1-audit.patch | 992 ++++++------- openssh-6.7p1-coverity.patch | 22 - ...sh-6.7p1-debian-restore-tcp-wrappers.patch | 30 +- openssh-6.7p1-fips.patch | 323 ++--- openssh-6.7p1-ldap.patch | 55 +- openssh-6.7p1-seccomp-aarch64.patch | 68 +- openssh-6.7p1-sshdT-output.patch | 56 - openssh-6.8p1-880575.patch | 11 - ....8p1-fix-ssh-copy-id-on-non-sh-shell.patch | 7 +- openssh-6.8p1-memory-problems.patch | 25 + openssh-6.8p1-sshdT-output.patch | 27 + ...gsissh.patch => openssh-6.9p1-gsissh.patch | 332 +++-- openssh-6.9p1-permit-root-login.patch | 27 + sources | 2 +- 23 files changed, 1724 insertions(+), 1814 deletions(-) delete mode 100644 openssh-6.7p1-sshdT-output.patch delete mode 100644 openssh-6.8p1-880575.patch rename openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch => openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch (59%) create mode 100644 openssh-6.8p1-memory-problems.patch create mode 100644 openssh-6.8p1-sshdT-output.patch rename openssh-6.8p1-gsissh.patch => openssh-6.9p1-gsissh.patch (90%) create mode 100644 openssh-6.9p1-permit-root-login.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 808d187..e3f2e5e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,13 +30,13 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 6.8p1 -%global openssh_rel 2 +%global openssh_ver 6.9p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -151,21 +151,24 @@ Patch920: openssh-6.6.1p1-ip-port-config-parser.patch # https://lists.mindrot.org/pipermail/openssh-unix-dev/2014-April/032497.html Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.patch # apply upstream patch and make sshd -T more consistent (#1187521) -Patch922: openssh-6.7p1-sshdT-output.patch +Patch922: openssh-6.8p1-sshdT-output.patch # fix ssh-copy-id on non-sh shells (#1045191) -Patch923: openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch +Patch923: openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch # AArch64 has seccomp support since 3.19 kernel (#1195065) Patch924: openssh-6.7p1-seccomp-aarch64.patch # Solve issue with ssh-copy-id and keys without trailing newline (#1093168) Patch925: openssh-6.7p1-ssh-copy-id-truncated-keys.patch # Add sftp option to force mode of created files (#1191055) Patch926: openssh-6.7p1-sftp-force-permission.patch -# Upstream bug #1878 reintroduced in openssh6.7p1 -Patch927: openssh-6.8p1-880575.patch +# Memory problems +# https://bugzilla.mindrot.org/show_bug.cgi?id=2401 +Patch928: openssh-6.8p1-memory-problems.patch +# Restore compatible default (#89216) +Patch929: openssh-6.9p1-permit-root-login.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.8p1.patch -Patch98: openssh-6.8p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.9p1.patch +Patch98: openssh-6.9p1-gsissh.patch License: BSD Group: Applications/Internet @@ -306,7 +309,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch912 -p1 -b .utf8-banner %patch914 -p1 -b .servconf %patch916 -p1 -b .contexts -%patch917 -p1 -b .cisco-dh +#%patch917 -p1 -b .cisco-dh # investigate %patch918 -p1 -b .log-in-chroot %patch919 -p1 -b .scp %patch920 -p1 -b .config @@ -317,7 +320,8 @@ This version of OpenSSH has been modified to support GSI authentication. %patch924 -p1 -b .seccomp %patch925 -p1 -b .newline %patch926 -p1 -b .sftp-force-mode -%patch927 -p1 -b .bz880575 +%patch928 -p1 -b .memory +%patch929 -p1 -b .root-login %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -542,6 +546,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sun Jul 05 2015 Mattias Ellert - 6.9p1-1 +- Based on openssh-6.8p1-10.fc22 + * Wed Jun 17 2015 Fedora Release Engineering - 6.8p1-2.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild diff --git a/openssh-5.8p1-glob.patch b/openssh-5.8p1-glob.patch index cb45cd1..fe8a3d4 100644 --- a/openssh-5.8p1-glob.patch +++ b/openssh-5.8p1-glob.patch @@ -8,3 +8,17 @@ diff -up openssh-5.8p1/sftp-glob.c.glob openssh-5.8p1/sftp-glob.c - return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); + return(glob(pattern, flags | GLOB_LIMIT | GLOB_ALTDIRFUNC, errfunc, pglob)); } +diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c +index 742b4b9..acae399 100644 +--- a/openbsd-compat/glob.c ++++ b/openbsd-compat/glob.c +@@ -130,7 +130,7 @@ typedef char Char; + #define ismeta(c) (((c)&M_QUOTE) != 0) + + #define GLOB_LIMIT_MALLOC 65536 +-#define GLOB_LIMIT_STAT 128 ++#define GLOB_LIMIT_STAT 1024 + #define GLOB_LIMIT_READDIR 16384 + + /* Limit of recursion during matching attempts. */ + diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index 67769f0..cb95e5f 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.8p1/configure.ac.vendor openssh-6.8p1/configure.ac ---- openssh-6.8p1/configure.ac.vendor 2015-03-18 11:17:56.670880303 +0100 -+++ openssh-6.8p1/configure.ac 2015-03-18 11:17:56.695880243 +0100 -@@ -4743,6 +4743,12 @@ AC_ARG_WITH([lastlog], +diff -up openssh/configure.ac.vendor openssh/configure.ac +--- openssh/configure.ac.vendor 2015-06-24 11:05:39.805679794 +0200 ++++ openssh/configure.ac 2015-06-24 11:05:39.835679719 +0200 +@@ -4751,6 +4751,12 @@ AC_ARG_WITH([lastlog], fi ] ) @@ -14,7 +14,7 @@ diff -up openssh-6.8p1/configure.ac.vendor openssh-6.8p1/configure.ac dnl lastlog, [uw]tmpx? detection dnl NOTE: set the paths in the platform section to avoid the -@@ -5005,6 +5011,7 @@ echo " Translate v4 in v6 hack +@@ -5013,6 +5019,7 @@ echo " Translate v4 in v6 hack echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -22,10 +22,10 @@ diff -up openssh-6.8p1/configure.ac.vendor openssh-6.8p1/configure.ac echo "" -diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.vendor 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 11:19:16.279691126 +0100 -@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions +diff -up openssh/servconf.c.vendor openssh/servconf.c +--- openssh/servconf.c.vendor 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/servconf.c 2015-06-24 11:07:07.689460890 +0200 +@@ -147,6 +147,7 @@ initialize_server_options(ServerOptions options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; @@ -33,7 +33,7 @@ diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; -@@ -327,6 +328,8 @@ fill_default_server_options(ServerOption +@@ -335,6 +336,8 @@ fill_default_server_options(ServerOption options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); @@ -42,7 +42,7 @@ diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) -@@ -388,7 +391,7 @@ typedef enum { +@@ -397,7 +400,7 @@ typedef enum { sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, @@ -50,8 +50,8 @@ diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c + sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -@@ -504,6 +507,7 @@ static struct { + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, +@@ -517,6 +520,7 @@ static struct { { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, @@ -59,7 +59,7 @@ diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1320,6 +1324,10 @@ process_server_config_line(ServerOptions +@@ -1372,6 +1376,10 @@ process_server_config_line(ServerOptions multistate_ptr = multistate_privsep; goto parse_multistate; @@ -70,18 +70,18 @@ diff -up openssh-6.8p1/servconf.c.vendor openssh-6.8p1/servconf.c case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -2145,6 +2153,7 @@ dump_config(ServerOptions *o) +@@ -2249,6 +2257,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); + dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); -diff -up openssh-6.8p1/servconf.h.vendor openssh-6.8p1/servconf.h ---- openssh-6.8p1/servconf.h.vendor 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/servconf.h 2015-03-18 11:17:56.696880241 +0100 -@@ -151,6 +151,7 @@ typedef struct { + dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); +diff -up openssh/servconf.h.vendor openssh/servconf.h +--- openssh/servconf.h.vendor 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/servconf.h 2015-06-24 11:05:39.837679714 +0200 +@@ -154,6 +154,7 @@ typedef struct { int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ @@ -137,10 +137,10 @@ diff -up openssh-6.8p1/sshd_config.0.vendor openssh-6.8p1/sshd_config.0 StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. -diff -up openssh-6.8p1/sshd_config.5.vendor openssh-6.8p1/sshd_config.5 ---- openssh-6.8p1/sshd_config.5.vendor 2015-03-18 11:17:56.691880253 +0100 -+++ openssh-6.8p1/sshd_config.5 2015-03-18 11:17:56.697880239 +0100 -@@ -1276,6 +1276,13 @@ This option applies to protocol version +diff -up openssh/sshd_config.5.vendor openssh/sshd_config.5 +--- openssh/sshd_config.5.vendor 2015-06-24 11:05:39.831679729 +0200 ++++ openssh/sshd_config.5 2015-06-24 11:05:39.837679714 +0200 +@@ -1344,6 +1344,13 @@ This option applies to protocol version .It Cm ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. The minimum value is 512, and the default is 1024. diff --git a/openssh-6.6.1p1-servconf-parser.patch b/openssh-6.6.1p1-servconf-parser.patch index b93f6f3..1439e80 100644 --- a/openssh-6.6.1p1-servconf-parser.patch +++ b/openssh-6.6.1p1-servconf-parser.patch @@ -1,31 +1,12 @@ -diff --git a/servconf.c b/servconf.c -index b7f3294..bc1e909 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -1550,7 +1550,7 @@ process_server_config_line(ServerOptions *options, char *line, - break; - - case sForceCommand: -- if (cp == NULL) -+ if (cp == NULL || *cp == '\0') - fatal("%.200s line %d: Missing argument.", filename, - linenum); - len = strspn(cp, WHITESPACE); -@@ -1595,7 +1595,7 @@ process_server_config_line(ServerOptions *options, char *line, - break; - - case sVersionAddendum: -- if (cp == NULL) -+ if (cp == NULL || *cp == '\0') - fatal("%.200s line %d: Missing argument.", filename, - linenum); - len = strspn(cp, WHITESPACE); -@@ -1630,6 +1630,8 @@ process_server_config_line(ServerOptions *options, char *line, +diff -up openssh/servconf.c.servconf openssh/servconf.c +--- openssh/servconf.c.servconf 2015-06-24 11:26:26.186527736 +0200 ++++ openssh/servconf.c 2015-06-24 11:26:39.847493075 +0200 +@@ -1815,6 +1815,8 @@ process_server_config_line(ServerOptions break; case sAuthenticationMethods: + if (cp == NULL || *cp == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep && options->num_auth_methods == 0) { + if (options->num_auth_methods == 0) { while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_auth_methods >= diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index cf01dd5..fc8f59d 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,6 +1,6 @@ -diff -up openssh-6.8p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-6.8p1/gss-serv-krb5.c ---- openssh-6.8p1/gss-serv-krb5.c.GSSAPIEnablek5users 2015-03-18 13:04:21.505306818 +0100 -+++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 13:04:21.527306764 +0100 +diff -up openssh/gss-serv-krb5.c.GSSAPIEnablek5users openssh/gss-serv-krb5.c +--- openssh/gss-serv-krb5.c.GSSAPIEnablek5users 2015-06-24 11:40:03.716448353 +0200 ++++ openssh/gss-serv-krb5.c 2015-06-24 11:40:03.739448295 +0200 @@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri FILE *fp; char file[MAXPATHLEN]; @@ -18,10 +18,10 @@ diff -up openssh-6.8p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-6.8p1/gss-ser return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.GSSAPIEnablek5users 2015-03-18 13:04:21.516306791 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 13:05:26.846146608 +0100 -@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions +diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c +--- openssh/servconf.c.GSSAPIEnablek5users 2015-06-24 11:40:03.728448323 +0200 ++++ openssh/servconf.c 2015-06-24 11:40:03.740448292 +0200 +@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions options->version_addendum = NULL; options->fingerprint_hash = -1; options->use_kuserok = -1; @@ -29,7 +29,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -348,6 +349,8 @@ fill_default_server_options(ServerOption +@@ -353,6 +354,8 @@ fill_default_server_options(ServerOption options->fingerprint_hash = SSH_FP_HASH_DEFAULT; if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -38,7 +38,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c /* Turn privilege separation on by default */ if (use_privsep == -1) use_privsep = PRIVSEP_NOSANDBOX; -@@ -406,7 +409,7 @@ typedef enum { +@@ -412,7 +415,7 @@ typedef enum { sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -47,7 +47,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -484,6 +487,7 @@ static struct { +@@ -490,12 +493,14 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, @@ -55,7 +55,6 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -491,6 +495,7 @@ static struct { { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, @@ -63,7 +62,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1623,6 +1628,10 @@ process_server_config_line(ServerOptions +@@ -1663,6 +1668,10 @@ process_server_config_line(ServerOptions intptr = &options->use_kuserok; goto parse_flag; @@ -74,7 +73,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1947,6 +1956,7 @@ copy_set_server_options(ServerOptions *d +@@ -2018,6 +2027,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -82,7 +81,7 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2207,6 +2217,7 @@ dump_config(ServerOptions *o) +@@ -2300,6 +2310,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -90,10 +89,10 @@ diff -up openssh-6.8p1/servconf.c.GSSAPIEnablek5users openssh-6.8p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.8p1/servconf.h.GSSAPIEnablek5users openssh-6.8p1/servconf.h ---- openssh-6.8p1/servconf.h.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 -+++ openssh-6.8p1/servconf.h 2015-03-18 13:04:21.528306762 +0100 -@@ -177,7 +177,8 @@ typedef struct { +diff -up openssh/servconf.h.GSSAPIEnablek5users openssh/servconf.h +--- openssh/servconf.h.GSSAPIEnablek5users 2015-06-24 11:40:03.717448351 +0200 ++++ openssh/servconf.h 2015-06-24 11:40:03.740448292 +0200 +@@ -179,7 +179,8 @@ typedef struct { int num_permitted_opens; @@ -103,21 +102,10 @@ diff -up openssh-6.8p1/servconf.h.GSSAPIEnablek5users openssh-6.8p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-6.8p1/sshd_config.GSSAPIEnablek5users openssh-6.8p1/sshd_config ---- openssh-6.8p1/sshd_config.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 -+++ openssh-6.8p1/sshd_config 2015-03-18 13:04:21.528306762 +0100 -@@ -94,6 +94,7 @@ GSSAPIAuthentication yes - GSSAPICleanupCredentials no - #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 -up openssh-6.8p1/sshd_config.5.GSSAPIEnablek5users openssh-6.8p1/sshd_config.5 ---- openssh-6.8p1/sshd_config.5.GSSAPIEnablek5users 2015-03-18 13:04:21.506306815 +0100 -+++ openssh-6.8p1/sshd_config.5 2015-03-18 13:04:21.528306762 +0100 -@@ -576,6 +576,12 @@ on logout. +diff -up openssh/sshd_config.5.GSSAPIEnablek5users openssh/sshd_config.5 +--- openssh/sshd_config.5.GSSAPIEnablek5users 2015-06-24 11:40:03.741448290 +0200 ++++ openssh/sshd_config.5 2015-06-24 11:40:40.707354263 +0200 +@@ -628,6 +628,12 @@ on logout. The default is .Dq yes . Note that this option applies to protocol version 2 only. @@ -128,5 +116,16 @@ diff -up openssh-6.8p1/sshd_config.5.GSSAPIEnablek5users openssh-6.8p1/sshd_conf +The default is +.Dq no . .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. If + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +diff -up openssh/sshd_config.GSSAPIEnablek5users openssh/sshd_config +--- openssh/sshd_config.GSSAPIEnablek5users 2015-06-24 11:40:03.717448351 +0200 ++++ openssh/sshd_config 2015-06-24 11:40:03.740448292 +0200 +@@ -94,6 +94,7 @@ GSSAPIAuthentication yes + GSSAPICleanupCredentials no + #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/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 6f4f1e8..48bb1d0 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -133,7 +133,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + break; + + total += n; -+ buf = xrealloc(buf, total + READ_CHUNK, 1); ++ buf = xreallocarray(buf, total + READ_CHUNK, 1); + } while(total < MAX_READ_SIZE); + return buf; +} diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch index 6703c15..19f075e 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -163,7 +163,7 @@ index 413b845..54dd383 100644 + k5users_allowed_cmds[ncommands-1] = + xstrdup(pw->pw_shell); + k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, ++ xreallocarray(k5users_allowed_cmds, ++ncommands, + sizeof(*k5users_allowed_cmds)); + break; + } @@ -176,7 +176,7 @@ index 413b845..54dd383 100644 + k5users_allowed_cmds[ncommands-1] = + xstrdup(token); + k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, ++ xreallocarray(k5users_allowed_cmds, ++ncommands, + sizeof(*k5users_allowed_cmds)); + token = strtok(NULL, " \t\n"); + } diff --git a/openssh-6.6p1-gsskex.patch b/openssh-6.6p1-gsskex.patch index 42b6a10..1cfd53f 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -1,26 +1,25 @@ -diff -up openssh-6.8p1/Makefile.in.gsskex openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.gsskex 2015-03-18 11:24:48.875900767 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 12:34:36.468748216 +0100 -@@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ - atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ -+ kexgssc.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ -@@ -111,7 +112,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.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 \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ - roaming_common.o roaming_serv.o \ -diff -up openssh-6.8p1/auth2-gss.c.gsskex openssh-6.8p1/auth2-gss.c ---- openssh-6.8p1/auth2-gss.c.gsskex 2015-03-18 11:24:48.832900869 +0100 -+++ openssh-6.8p1/auth2-gss.c 2015-03-18 12:32:50.584011552 +0100 +diff -up openssh/auth2.c.gsskex openssh/auth2.c +--- openssh/auth2.c.gsskex 2015-06-24 11:07:36.180389924 +0200 ++++ openssh/auth2.c 2015-06-24 11:07:36.228389804 +0200 +@@ -70,6 +70,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif + +@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + &method_passwd, +diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c +--- openssh/auth2-gss.c.gsskex 2015-06-24 11:07:36.179389926 +0200 ++++ openssh/auth2-gss.c 2015-06-24 11:07:36.228389804 +0200 @@ -31,6 +31,7 @@ #include @@ -103,28 +102,9 @@ diff -up openssh-6.8p1/auth2-gss.c.gsskex openssh-6.8p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-6.8p1/auth2.c.gsskex openssh-6.8p1/auth2.c ---- openssh-6.8p1/auth2.c.gsskex 2015-03-18 11:24:48.832900869 +0100 -+++ openssh-6.8p1/auth2.c 2015-03-18 11:24:48.875900767 +0100 -@@ -70,6 +70,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif - -@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - &method_passwd, -diff -up openssh-6.8p1/clientloop.c.gsskex openssh-6.8p1/clientloop.c ---- openssh-6.8p1/clientloop.c.gsskex 2015-03-18 11:24:48.875900767 +0100 -+++ openssh-6.8p1/clientloop.c 2015-03-18 12:30:42.647329654 +0100 +diff -up openssh/clientloop.c.gsskex openssh/clientloop.c +--- openssh/clientloop.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/clientloop.c 2015-06-24 11:07:36.228389804 +0200 @@ -114,6 +114,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -152,10 +132,10 @@ diff -up openssh-6.8p1/clientloop.c.gsskex openssh-6.8p1/clientloop.c if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); active_state->kex->done = 0; -diff -up openssh-6.8p1/configure.ac.gsskex openssh-6.8p1/configure.ac ---- openssh-6.8p1/configure.ac.gsskex 2015-03-18 11:24:48.866900788 +0100 -+++ openssh-6.8p1/configure.ac 2015-03-18 11:24:48.876900765 +0100 -@@ -620,6 +620,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +diff -up openssh/configure.ac.gsskex openssh/configure.ac +--- openssh/configure.ac.gsskex 2015-06-24 11:07:36.214389839 +0200 ++++ openssh/configure.ac 2015-06-24 11:07:36.229389802 +0200 +@@ -625,6 +625,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -186,10 +166,10 @@ diff -up openssh-6.8p1/configure.ac.gsskex openssh-6.8p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c ---- openssh-6.8p1/gss-genr.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/gss-genr.c 2015-03-18 11:24:48.876900765 +0100 -@@ -40,12 +40,167 @@ +diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +--- openssh/gss-genr.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/gss-genr.c 2015-06-24 11:07:36.229389802 +0200 +@@ -41,12 +41,167 @@ #include "buffer.h" #include "log.h" #include "ssh2.h" @@ -357,7 +337,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de +@@ -199,7 +354,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -366,7 +346,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -228,8 +383,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -229,8 +384,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -409,7 +389,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -238,6 +427,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -429,7 +409,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) -@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha +@@ -251,11 +453,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha } int @@ -447,7 +427,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -264,6 +471,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -265,6 +472,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -458,7 +438,7 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -274,10 +485,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -526,9 +506,294 @@ diff -up openssh-6.8p1/gss-genr.c.gsskex openssh-6.8p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-6.8p1/gss-serv-krb5.c.gsskex openssh-6.8p1/gss-serv-krb5.c ---- openssh-6.8p1/gss-serv-krb5.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 11:24:48.876900765 +0100 +diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c +--- openssh/gss-serv.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/gss-serv.c 2015-06-24 11:11:53.171742794 +0200 +@@ -45,17 +45,19 @@ + #include "session.h" + #include "misc.h" + #include "servconf.h" ++#include "uidswap.h" + + #include "ssh-gss.h" ++#include "monitor_wrap.h" + + extern ServerOptions options; + + static ssh_gssapi_client gssapi_client = + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, +- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; ++ GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, {NULL, NULL, NULL}, 0, 0}; + + ssh_gssapi_mech gssapi_null_mech = +- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; ++ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; + + #ifdef KRB5 + extern ssh_gssapi_mech gssapi_kerberos_mech; +@@ -142,6 +144,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss + } + + /* Unprivileged */ ++char * ++ssh_gssapi_server_mechanisms() { ++ gss_OID_set supported; ++ ++ ssh_gssapi_supported_oids(&supported); ++ return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, ++ NULL, NULL)); ++} ++ ++/* Unprivileged */ ++int ++ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, ++ const char *dummy) { ++ Gssctxt *ctx = NULL; ++ int res; ++ ++ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); ++ ssh_gssapi_delete_ctx(&ctx); ++ ++ return (res); ++} ++ ++/* Unprivileged */ + void + ssh_gssapi_supported_oids(gss_OID_set *oidset) + { +@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o + gss_OID_set supported; + + gss_create_empty_oid_set(&min_status, oidset); +- gss_indicate_mechs(&min_status, &supported); ++ ++ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) ++ return; + + while (supported_mechs[i]->name != NULL) { + if (GSS_ERROR(gss_test_oid_set_member(&min_status, +@@ -277,8 +304,48 @@ OM_uint32 + ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + { + int i = 0; ++ int equal = 0; ++ gss_name_t new_name = GSS_C_NO_NAME; ++ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; ++ ++ if (options.gss_store_rekey && client->used && ctx->client_creds) { ++ if (client->mech->oid.length != ctx->oid->length || ++ (memcmp(client->mech->oid.elements, ++ ctx->oid->elements, ctx->oid->length) !=0)) { ++ debug("Rekeyed credentials have different mechanism"); ++ return GSS_S_COMPLETE; ++ } ++ ++ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &new_name, ++ NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } + +- gss_buffer_desc ename; ++ ctx->major = gss_compare_name(&ctx->minor, client->name, ++ new_name, &equal); ++ ++ if (GSS_ERROR(ctx->major)) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ ++ if (!equal) { ++ debug("Rekeyed credentials have different name"); ++ return GSS_S_COMPLETE; ++ } ++ ++ debug("Marking rekeyed credentials for export"); ++ ++ gss_release_name(&ctx->minor, &client->name); ++ gss_release_cred(&ctx->minor, &client->creds); ++ client->name = new_name; ++ client->creds = ctx->client_creds; ++ ctx->client_creds = GSS_C_NO_CREDENTIAL; ++ client->updated = 1; ++ return GSS_S_COMPLETE; ++ } + + client->mech = NULL; + +@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + if (client->mech == NULL) + return GSS_S_FAILURE; + ++ if (ctx->client_creds && ++ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, + &client->displayname, NULL))) { + ssh_gssapi_error(ctx); +@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + return (ctx->major); + } + ++ gss_release_buffer(&ctx->minor, &ename); ++ + /* We can't copy this structure, so we just move the pointer to it */ + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; +@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + void + ssh_gssapi_cleanup_creds(void) + { +- if (gssapi_client.store.filename != NULL) { +- /* Unlink probably isn't sufficient */ +- debug("removing gssapi cred file\"%s\"", +- gssapi_client.store.filename); +- unlink(gssapi_client.store.filename); ++ krb5_ccache ccache = NULL; ++ krb5_error_code problem; ++ ++ if (gssapi_client.store.data != NULL) { ++ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { ++ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { ++ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else { ++ krb5_free_context(gssapi_client.store.data); ++ gssapi_client.store.data = NULL; ++ } + } + } + +@@ -357,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int + + /* Privileged */ + int +-ssh_gssapi_userok(char *user) ++ssh_gssapi_userok(char *user, struct passwd *pw) + { + OM_uint32 lmin; + +@@ -367,9 +452,11 @@ ssh_gssapi_userok(char *user) + return 0; + } + if (gssapi_client.mech && gssapi_client.mech->userok) +- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) ++ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { ++ gssapi_client.used = 1; ++ gssapi_client.store.owner = pw; + return 1; +- else { ++ } else { + /* Destroy delegated credentials if userok fails */ + gss_release_buffer(&lmin, &gssapi_client.displayname); + gss_release_buffer(&lmin, &gssapi_client.exportedname); +@@ -383,14 +470,90 @@ ssh_gssapi_userok(char *user) + return (0); + } + +-/* Privileged */ +-OM_uint32 +-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) ++/* These bits are only used for rekeying. The unpriviledged child is running ++ * as the user, the monitor is root. ++ * ++ * In the child, we want to : ++ * *) Ask the monitor to store our credentials into the store we specify ++ * *) If it succeeds, maybe do a PAM update ++ */ ++ ++/* Stuff for PAM */ ++ ++#ifdef USE_PAM ++static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, ++ struct pam_response **resp, void *data) + { +- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, +- gssbuf, gssmic, NULL); ++ return (PAM_CONV_ERR); ++} ++#endif + +- return (ctx->major); ++void ++ssh_gssapi_rekey_creds() { ++ int ok; ++ int ret; ++#ifdef USE_PAM ++ pam_handle_t *pamh = NULL; ++ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; ++ char *envstr; ++#endif ++ ++ if (gssapi_client.store.filename == NULL && ++ gssapi_client.store.envval == NULL && ++ gssapi_client.store.envvar == NULL) ++ return; ++ ++ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); ++ ++ if (!ok) ++ return; ++ ++ debug("Rekeyed credentials stored successfully"); ++ ++ /* Actually managing to play with the ssh pam stack from here will ++ * be next to impossible. In any case, we may want different options ++ * 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) ++ return; ++ ++ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, ++ gssapi_client.store.envval); ++ ++ ret = pam_putenv(pamh, envstr); ++ if (!ret) ++ pam_setcred(pamh, PAM_REINITIALIZE_CRED); ++ pam_end(pamh, PAM_SUCCESS); ++#endif ++} ++ ++int ++ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { ++ int ok = 0; ++ ++ /* Check we've got credentials to store */ ++ if (!gssapi_client.updated) ++ return 0; ++ ++ gssapi_client.updated = 0; ++ ++ temporarily_use_uid(gssapi_client.store.owner); ++ if (gssapi_client.mech && gssapi_client.mech->updatecreds) ++ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); ++ else ++ debug("No update function for this mechanism"); ++ ++ restore_uid(); ++ ++ return ok; + } + + #endif +diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c +--- openssh/gss-serv-krb5.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/gss-serv-krb5.c 2015-06-24 11:07:36.229389802 +0200 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -656,343 +921,9 @@ diff -up openssh-6.8p1/gss-serv-krb5.c.gsskex openssh-6.8p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-6.8p1/gss-serv.c.gsskex openssh-6.8p1/gss-serv.c ---- openssh-6.8p1/gss-serv.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/gss-serv.c 2015-03-18 11:24:48.877900762 +0100 -@@ -44,15 +44,20 @@ - #include "channels.h" - #include "session.h" - #include "misc.h" -+#include "servconf.h" -+#include "uidswap.h" - - #include "ssh-gss.h" -+#include "monitor_wrap.h" -+ -+extern ServerOptions options; - - static ssh_gssapi_client gssapi_client = - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, -- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; -+ GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL}, 0, 0}; - - ssh_gssapi_mech gssapi_null_mech = -- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; -+ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; - - #ifdef KRB5 - extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -99,25 +104,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) - char lname[NI_MAXHOST]; - gss_OID_set oidset; - -- gss_create_empty_oid_set(&status, &oidset); -- gss_add_oid_set_member(&status, ctx->oid, &oidset); -- -- if (gethostname(lname, sizeof(lname))) { -- gss_release_oid_set(&status, &oidset); -- return (-1); -- } -+ if (options.gss_strict_acceptor) { -+ gss_create_empty_oid_set(&status, &oidset); -+ gss_add_oid_set_member(&status, ctx->oid, &oidset); -+ -+ if (gethostname(lname, sizeof(lname))) { -+ gss_release_oid_set(&status, &oidset); -+ return (-1); -+ } -+ -+ if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { -+ gss_release_oid_set(&status, &oidset); -+ return (ctx->major); -+ } -+ -+ if ((ctx->major = gss_acquire_cred(&ctx->minor, -+ ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) -+ ssh_gssapi_error(ctx); - -- if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { - gss_release_oid_set(&status, &oidset); - return (ctx->major); -- } -+ } else { -+ ctx->name = GSS_C_NO_NAME; -+ ctx->creds = GSS_C_NO_CREDENTIAL; -+ return GSS_S_COMPLETE; -+ } - -- if ((ctx->major = gss_acquire_cred(&ctx->minor, -- ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) -- ssh_gssapi_error(ctx); -- -- gss_release_oid_set(&status, &oidset); -- return (ctx->major); - } - - /* Privileged */ -@@ -132,6 +144,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss - } - - /* Unprivileged */ -+char * -+ssh_gssapi_server_mechanisms() { -+ gss_OID_set supported; -+ -+ ssh_gssapi_supported_oids(&supported); -+ return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, -+ NULL, NULL)); -+} -+ -+/* Unprivileged */ -+int -+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, -+ const char *dummy) { -+ Gssctxt *ctx = NULL; -+ int res; -+ -+ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); -+ ssh_gssapi_delete_ctx(&ctx); -+ -+ return (res); -+} -+ -+/* Unprivileged */ - void - ssh_gssapi_supported_oids(gss_OID_set *oidset) - { -@@ -141,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o - gss_OID_set supported; - - gss_create_empty_oid_set(&min_status, oidset); -- gss_indicate_mechs(&min_status, &supported); -+ -+ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) -+ return; - - while (supported_mechs[i]->name != NULL) { - if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -267,8 +304,48 @@ OM_uint32 - ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - { - int i = 0; -+ int equal = 0; -+ gss_name_t new_name = GSS_C_NO_NAME; -+ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; -+ -+ if (options.gss_store_rekey && client->used && ctx->client_creds) { -+ if (client->mech->oid.length != ctx->oid->length || -+ (memcmp(client->mech->oid.elements, -+ ctx->oid->elements, ctx->oid->length) !=0)) { -+ debug("Rekeyed credentials have different mechanism"); -+ return GSS_S_COMPLETE; -+ } -+ -+ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &new_name, -+ NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } - -- gss_buffer_desc ename; -+ ctx->major = gss_compare_name(&ctx->minor, client->name, -+ new_name, &equal); -+ -+ if (GSS_ERROR(ctx->major)) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ -+ if (!equal) { -+ debug("Rekeyed credentials have different name"); -+ return GSS_S_COMPLETE; -+ } -+ -+ debug("Marking rekeyed credentials for export"); -+ -+ gss_release_name(&ctx->minor, &client->name); -+ gss_release_cred(&ctx->minor, &client->creds); -+ client->name = new_name; -+ client->creds = ctx->client_creds; -+ ctx->client_creds = GSS_C_NO_CREDENTIAL; -+ client->updated = 1; -+ return GSS_S_COMPLETE; -+ } - - client->mech = NULL; - -@@ -283,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - if (client->mech == NULL) - return GSS_S_FAILURE; - -+ if (ctx->client_creds && -+ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ - if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, - &client->displayname, NULL))) { - ssh_gssapi_error(ctx); -@@ -300,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - return (ctx->major); - } - -+ gss_release_buffer(&ctx->minor, &ename); -+ - /* We can't copy this structure, so we just move the pointer to it */ - client->creds = ctx->client_creds; - ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -310,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - void - ssh_gssapi_cleanup_creds(void) - { -- if (gssapi_client.store.filename != NULL) { -- /* Unlink probably isn't sufficient */ -- debug("removing gssapi cred file\"%s\"", -- gssapi_client.store.filename); -- unlink(gssapi_client.store.filename); -+ krb5_ccache ccache = NULL; -+ krb5_error_code problem; -+ -+ if (gssapi_client.store.data != NULL) { -+ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else { -+ krb5_free_context(gssapi_client.store.data); -+ gssapi_client.store.data = NULL; -+ } - } - } - -@@ -347,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int - - /* Privileged */ - int --ssh_gssapi_userok(char *user) -+ssh_gssapi_userok(char *user, struct passwd *pw) - { - OM_uint32 lmin; - -@@ -357,9 +452,11 @@ ssh_gssapi_userok(char *user) - return 0; - } - if (gssapi_client.mech && gssapi_client.mech->userok) -- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) -+ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { -+ gssapi_client.used = 1; -+ gssapi_client.store.owner = pw; - return 1; -- else { -+ } else { - /* Destroy delegated credentials if userok fails */ - gss_release_buffer(&lmin, &gssapi_client.displayname); - gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -373,14 +470,90 @@ ssh_gssapi_userok(char *user) - return (0); - } - --/* Privileged */ --OM_uint32 --ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) -+/* These bits are only used for rekeying. The unpriviledged child is running -+ * as the user, the monitor is root. -+ * -+ * In the child, we want to : -+ * *) Ask the monitor to store our credentials into the store we specify -+ * *) If it succeeds, maybe do a PAM update -+ */ -+ -+/* Stuff for PAM */ -+ -+#ifdef USE_PAM -+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, -+ struct pam_response **resp, void *data) - { -- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, -- gssbuf, gssmic, NULL); -+ return (PAM_CONV_ERR); -+} -+#endif - -- return (ctx->major); -+void -+ssh_gssapi_rekey_creds() { -+ int ok; -+ int ret; -+#ifdef USE_PAM -+ pam_handle_t *pamh = NULL; -+ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; -+ char *envstr; -+#endif -+ -+ if (gssapi_client.store.filename == NULL && -+ gssapi_client.store.envval == NULL && -+ gssapi_client.store.envvar == NULL) -+ return; -+ -+ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -+ -+ if (!ok) -+ return; -+ -+ debug("Rekeyed credentials stored successfully"); -+ -+ /* Actually managing to play with the ssh pam stack from here will -+ * be next to impossible. In any case, we may want different options -+ * 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) -+ return; -+ -+ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, -+ gssapi_client.store.envval); -+ -+ ret = pam_putenv(pamh, envstr); -+ if (!ret) -+ pam_setcred(pamh, PAM_REINITIALIZE_CRED); -+ pam_end(pamh, PAM_SUCCESS); -+#endif -+} -+ -+int -+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { -+ int ok = 0; -+ -+ /* Check we've got credentials to store */ -+ if (!gssapi_client.updated) -+ return 0; -+ -+ gssapi_client.updated = 0; -+ -+ temporarily_use_uid(gssapi_client.store.owner); -+ if (gssapi_client.mech && gssapi_client.mech->updatecreds) -+ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); -+ else -+ debug("No update function for this mechanism"); -+ -+ restore_uid(); -+ -+ return ok; - } - - #endif -diff -up openssh-6.8p1/kex.c.gsskex openssh-6.8p1/kex.c ---- openssh-6.8p1/kex.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/kex.c 2015-03-18 12:29:33.452501699 +0100 +diff -up openssh/kex.c.gsskex openssh/kex.c +--- openssh/kex.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/kex.c 2015-06-24 11:07:36.230389799 +0200 @@ -55,6 +55,10 @@ #include "sshbuf.h" #include "digest.h" @@ -1029,48 +960,9 @@ diff -up openssh-6.8p1/kex.c.gsskex openssh-6.8p1/kex.c } return NULL; } -diff -up openssh-6.8p1/kex.h.gsskex openssh-6.8p1/kex.h ---- openssh-6.8p1/kex.h.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/kex.h 2015-03-18 12:28:17.600690296 +0100 -@@ -93,6 +93,11 @@ enum kex_exchange { - KEX_DH_GEX_SHA256, - KEX_ECDH_SHA2, - KEX_C25519_SHA256, -+#ifdef GSSAPI -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GEX_SHA1, -+#endif - KEX_MAX - }; - -@@ -139,6 +144,12 @@ struct kex { - u_int flags; - int hash_alg; - int ec_nid; -+#ifdef GSSAPI -+ int gss_deleg_creds; -+ int gss_trust_dns; -+ char *gss_host; -+ char *gss_client; -+#endif - char *client_version_string; - char *server_version_string; - int (*verify_host_key)(struct sshkey *, struct ssh *); -@@ -183,6 +194,10 @@ int kexecdh_client(struct ssh *); - int kexecdh_server(struct ssh *); - int kexc25519_client(struct ssh *); - int kexc25519_server(struct ssh *); -+#ifdef GSSAPI -+int kexgss_client(struct ssh *); -+int kexgss_server(struct ssh *); -+#endif - - int kex_dh_hash(const char *, const char *, - const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh-6.8p1/kexgssc.c.gsskex openssh-6.8p1/kexgssc.c ---- openssh-6.8p1/kexgssc.c.gsskex 2015-03-18 11:24:48.877900762 +0100 -+++ openssh-6.8p1/kexgssc.c 2015-03-18 11:24:48.877900762 +0100 +diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c +--- openssh/kexgssc.c.gsskex 2015-06-24 11:07:36.231389797 +0200 ++++ openssh/kexgssc.c 2015-06-24 11:07:36.230389799 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1410,9 +1302,9 @@ diff -up openssh-6.8p1/kexgssc.c.gsskex openssh-6.8p1/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh-6.8p1/kexgsss.c.gsskex openssh-6.8p1/kexgsss.c ---- openssh-6.8p1/kexgsss.c.gsskex 2015-03-18 11:24:48.878900760 +0100 -+++ openssh-6.8p1/kexgsss.c 2015-03-18 11:24:48.878900760 +0100 +diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c +--- openssh/kexgsss.c.gsskex 2015-06-24 11:07:36.231389797 +0200 ++++ openssh/kexgsss.c 2015-06-24 11:07:36.231389797 +0200 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1709,9 +1601,68 @@ diff -up openssh-6.8p1/kexgsss.c.gsskex openssh-6.8p1/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c ---- openssh-6.8p1/monitor.c.gsskex 2015-03-18 11:24:48.834900865 +0100 -+++ openssh-6.8p1/monitor.c 2015-03-18 12:24:38.971233895 +0100 +diff -up openssh/kex.h.gsskex openssh/kex.h +--- openssh/kex.h.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/kex.h 2015-06-24 11:07:36.230389799 +0200 +@@ -93,6 +93,11 @@ enum kex_exchange { + KEX_DH_GEX_SHA256, + KEX_ECDH_SHA2, + KEX_C25519_SHA256, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GEX_SHA1, ++#endif + KEX_MAX + }; + +@@ -139,6 +144,12 @@ struct kex { + u_int flags; + int hash_alg; + int ec_nid; ++#ifdef GSSAPI ++ int gss_deleg_creds; ++ int gss_trust_dns; ++ char *gss_host; ++ char *gss_client; ++#endif + char *client_version_string; + char *server_version_string; + int (*verify_host_key)(struct sshkey *, struct ssh *); +@@ -183,6 +194,10 @@ int kexecdh_client(struct ssh *); + int kexecdh_server(struct ssh *); + int kexc25519_client(struct ssh *); + int kexc25519_server(struct ssh *); ++#ifdef GSSAPI ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); ++#endif + + int kex_dh_hash(const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, +diff -up openssh/Makefile.in.gsskex openssh/Makefile.in +--- openssh/Makefile.in.gsskex 2015-06-24 11:07:36.223389817 +0200 ++++ openssh/Makefile.in 2015-06-24 11:07:36.228389804 +0200 +@@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ + atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ ++ kexgssc.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ + ssh-pkcs11.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ +@@ -111,7 +112,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw + auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o \ + monitor_mm.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 \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ + sftp-server.o sftp-common.o \ + roaming_common.o roaming_serv.o \ +diff -up openssh/monitor.c.gsskex openssh/monitor.c +--- openssh/monitor.c.gsskex 2015-06-24 11:07:36.180389924 +0200 ++++ openssh/monitor.c 2015-06-24 11:07:36.231389797 +0200 @@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); @@ -1762,7 +1713,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1892,6 +1909,13 @@ monitor_apply_keystate(struct monitor *p +@@ -1896,6 +1913,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1776,7 +1727,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1991,6 +2015,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -1995,6 +2019,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -1786,7 +1737,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2018,6 +2045,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2022,6 +2049,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1796,7 +1747,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2035,6 +2065,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2039,6 +2069,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1804,7 +1755,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c } return (0); } -@@ -2046,6 +2077,9 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -2050,6 +2081,9 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -1814,7 +1765,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2072,7 +2106,11 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2076,7 +2110,11 @@ mm_answer_gss_userok(int sock, Buffer *m { int authenticated; @@ -1827,7 +1778,7 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2085,5 +2123,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2089,5 +2127,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1901,9 +1852,9 @@ diff -up openssh-6.8p1/monitor.c.gsskex openssh-6.8p1/monitor.c + #endif /* GSSAPI */ -diff -up openssh-6.8p1/monitor.h.gsskex openssh-6.8p1/monitor.h ---- openssh-6.8p1/monitor.h.gsskex 2015-03-18 11:24:48.834900865 +0100 -+++ openssh-6.8p1/monitor.h 2015-03-18 11:24:48.878900760 +0100 +diff -up openssh/monitor.h.gsskex openssh/monitor.h +--- openssh/monitor.h.gsskex 2015-06-24 11:07:36.181389921 +0200 ++++ openssh/monitor.h 2015-06-24 11:07:36.231389797 +0200 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1913,10 +1864,10 @@ diff -up openssh-6.8p1/monitor.h.gsskex openssh-6.8p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-6.8p1/monitor_wrap.c.gsskex openssh-6.8p1/monitor_wrap.c ---- openssh-6.8p1/monitor_wrap.c.gsskex 2015-03-18 11:24:48.834900865 +0100 -+++ openssh-6.8p1/monitor_wrap.c 2015-03-18 11:24:48.878900760 +0100 -@@ -1087,7 +1087,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.gsskex 2015-06-24 11:07:36.181389921 +0200 ++++ openssh/monitor_wrap.c 2015-06-24 11:07:36.231389797 +0200 +@@ -1088,7 +1088,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1925,7 +1876,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.gsskex openssh-6.8p1/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -1104,5 +1104,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -1105,5 +1105,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1976,9 +1927,9 @@ diff -up openssh-6.8p1/monitor_wrap.c.gsskex openssh-6.8p1/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh-6.8p1/monitor_wrap.h.gsskex openssh-6.8p1/monitor_wrap.h ---- openssh-6.8p1/monitor_wrap.h.gsskex 2015-03-18 11:24:48.834900865 +0100 -+++ openssh-6.8p1/monitor_wrap.h 2015-03-18 11:24:48.878900760 +0100 +diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.gsskex 2015-06-24 11:07:36.181389921 +0200 ++++ openssh/monitor_wrap.h 2015-06-24 11:07:36.232389794 +0200 @@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1991,9 +1942,9 @@ diff -up openssh-6.8p1/monitor_wrap.h.gsskex openssh-6.8p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-6.8p1/readconf.c.gsskex openssh-6.8p1/readconf.c ---- openssh-6.8p1/readconf.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/readconf.c 2015-03-18 11:24:48.879900758 +0100 +diff -up openssh/readconf.c.gsskex openssh/readconf.c +--- openssh/readconf.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/readconf.c 2015-06-24 11:07:36.232389794 +0200 @@ -147,6 +147,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, @@ -2082,9 +2033,9 @@ diff -up openssh-6.8p1/readconf.c.gsskex openssh-6.8p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-6.8p1/readconf.h.gsskex openssh-6.8p1/readconf.h ---- openssh-6.8p1/readconf.h.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/readconf.h 2015-03-18 11:24:48.879900758 +0100 +diff -up openssh/readconf.h.gsskex openssh/readconf.h +--- openssh/readconf.h.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/readconf.h 2015-06-24 11:07:36.232389794 +0200 @@ -45,7 +45,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2098,9 +2049,9 @@ diff -up openssh-6.8p1/readconf.h.gsskex openssh-6.8p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-6.8p1/regress/cert-hostkey.sh.gsskex openssh-6.8p1/regress/cert-hostkey.sh ---- openssh-6.8p1/regress/cert-hostkey.sh.gsskex 2015-03-18 11:24:48.879900758 +0100 -+++ openssh-6.8p1/regress/cert-hostkey.sh 2015-03-18 12:15:49.556546478 +0100 +diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh +--- openssh/regress/cert-hostkey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/regress/cert-hostkey.sh 2015-06-24 11:07:36.232389794 +0200 @@ -25,7 +25,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca @@ -2110,9 +2061,9 @@ diff -up openssh-6.8p1/regress/cert-hostkey.sh.gsskex openssh-6.8p1/regress/cert type_has_legacy() { case $1 in -diff -up openssh-6.8p1/regress/cert-userkey.sh.gsskex openssh-6.8p1/regress/cert-userkey.sh ---- openssh-6.8p1/regress/cert-userkey.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/regress/cert-userkey.sh 2015-03-18 11:24:48.879900758 +0100 +diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh +--- openssh/regress/cert-userkey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/regress/cert-userkey.sh 2015-06-24 11:07:36.232389794 +0200 @@ -6,7 +6,7 @@ tid="certified user keys" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak @@ -2122,9 +2073,9 @@ diff -up openssh-6.8p1/regress/cert-userkey.sh.gsskex openssh-6.8p1/regress/cert type_has_legacy() { case $1 in -diff -up openssh-6.8p1/regress/kextype.sh.gsskex openssh-6.8p1/regress/kextype.sh ---- openssh-6.8p1/regress/kextype.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/regress/kextype.sh 2015-03-18 11:24:48.879900758 +0100 +diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh +--- openssh/regress/kextype.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/regress/kextype.sh 2015-06-24 11:07:36.233389792 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2135,9 +2086,9 @@ diff -up openssh-6.8p1/regress/kextype.sh.gsskex openssh-6.8p1/regress/kextype.s verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh-6.8p1/regress/rekey.sh.gsskex openssh-6.8p1/regress/rekey.sh ---- openssh-6.8p1/regress/rekey.sh.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/regress/rekey.sh 2015-03-18 11:24:48.879900758 +0100 +diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh +--- openssh/regress/rekey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/regress/rekey.sh 2015-06-24 11:07:36.233389792 +0200 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2158,21 +2109,21 @@ diff -up openssh-6.8p1/regress/rekey.sh.gsskex openssh-6.8p1/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.gsskex 2015-03-18 11:24:48.866900788 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 12:14:37.967721387 +0100 -@@ -114,7 +114,10 @@ initialize_server_options(ServerOptions +diff -up openssh/servconf.c.gsskex openssh/servconf.c +--- openssh/servconf.c.gsskex 2015-06-24 11:07:36.214389839 +0200 ++++ openssh/servconf.c 2015-06-24 11:20:08.026487223 +0200 +@@ -115,8 +115,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; + options->gss_keyex = -1; options->gss_cleanup_creds = -1; -+ options->gss_strict_acceptor = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -270,8 +273,14 @@ fill_default_server_options(ServerOption +@@ -276,10 +278,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2180,36 +2131,32 @@ diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c + options->gss_keyex = 0; if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; -+ if (options->gss_strict_acceptor == -1) -+ options->gss_strict_acceptor = 1; + if (options->gss_strict_acceptor == -1) + options->gss_strict_acceptor = 0; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -394,7 +403,8 @@ typedef enum { - sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, +@@ -404,7 +410,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, -- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -+ sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, +- sAcceptEnv, sPermitTunnel, + sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -465,10 +475,20 @@ static struct { - #ifdef GSSAPI +@@ -477,11 +483,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, -+ { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, -+ { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -+ { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, -+ { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -2218,7 +2165,7 @@ diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1170,10 +1190,22 @@ process_server_config_line(ServerOptions +@@ -1218,6 +1230,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2229,11 +2176,10 @@ diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; +@@ -1226,6 +1242,10 @@ process_server_config_line(ServerOptions + intptr = &options->gss_strict_acceptor; + goto parse_flag; -+ case sGssStrictAcceptor: -+ intptr = &options->gss_strict_acceptor; -+ goto parse_flag; -+ + case sGssStoreRekey: + intptr = &options->gss_store_rekey; + goto parse_flag; @@ -2241,7 +2187,7 @@ diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2134,6 +2166,9 @@ dump_config(ServerOptions *o) +@@ -2238,6 +2258,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2251,138 +2197,24 @@ diff -up openssh-6.8p1/servconf.c.gsskex openssh-6.8p1/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-6.8p1/servconf.h.gsskex openssh-6.8p1/servconf.h ---- openssh-6.8p1/servconf.h.gsskex 2015-03-18 11:24:48.866900788 +0100 -+++ openssh-6.8p1/servconf.h 2015-03-18 11:24:48.880900755 +0100 -@@ -115,7 +115,10 @@ typedef struct { +diff -up openssh/servconf.h.gsskex openssh/servconf.h +--- openssh/servconf.h.gsskex 2015-06-24 11:07:36.233389792 +0200 ++++ openssh/servconf.h 2015-06-24 11:21:20.888302354 +0200 +@@ -117,8 +117,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -+ int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ + int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ + int gss_store_rekey; int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-6.8p1/ssh-gss.h.gsskex openssh-6.8p1/ssh-gss.h ---- openssh-6.8p1/ssh-gss.h.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/ssh-gss.h 2015-03-18 11:24:48.880900755 +0100 -@@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 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,22 @@ - - #define SSH_GSS_OIDTYPE 0x06 - -+#define SSH2_MSG_KEXGSS_INIT 30 -+#define SSH2_MSG_KEXGSS_CONTINUE 31 -+#define SSH2_MSG_KEXGSS_COMPLETE 32 -+#define SSH2_MSG_KEXGSS_HOSTKEY 33 -+#define SSH2_MSG_KEXGSS_ERROR 34 -+#define SSH2_MSG_KEXGSS_GROUPREQ 40 -+#define SSH2_MSG_KEXGSS_GROUP 41 -+#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" -+#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" -+#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" -+ - typedef struct { - char *filename; - char *envvar; - char *envval; -+ struct passwd *owner; - void *data; - } ssh_gssapi_ccache; - -@@ -72,8 +84,11 @@ typedef struct { - gss_buffer_desc displayname; - gss_buffer_desc exportedname; - gss_cred_id_t creds; -+ gss_name_t name; - struct ssh_gssapi_mech_struct *mech; - ssh_gssapi_ccache store; -+ int used; -+ int updated; - } ssh_gssapi_client; - - typedef struct ssh_gssapi_mech_struct { -@@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); - void (*storecreds) (ssh_gssapi_client *); -+ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - - typedef struct { -@@ -94,10 +110,11 @@ typedef struct { - gss_OID oid; /* client */ - gss_cred_id_t creds; /* server */ - gss_name_t client; /* server */ -- gss_cred_id_t client_creds; /* server */ -+ gss_cred_id_t client_creds; /* both */ - } Gssctxt; - - extern ssh_gssapi_mech *supported_mechs[]; -+extern Gssctxt *gss_kex_context; - - int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); - void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); - void ssh_gssapi_delete_ctx(Gssctxt **); - OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); --int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); -+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); -+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); -+int ssh_gssapi_credentials_updated(Gssctxt *); - - /* In the server */ -+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, -+ const char *); -+char *ssh_gssapi_client_mechanisms(const char *, const char *); -+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, -+ const char *); -+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); -+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, -+ const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); --int ssh_gssapi_userok(char *name); -+int ssh_gssapi_userok(char *name, struct passwd *); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); - void ssh_gssapi_storecreds(void); - -+char *ssh_gssapi_server_mechanisms(void); -+int ssh_gssapi_oid_table_ok(); -+ -+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); -+ -+void ssh_gssapi_rekey_creds(void); - #endif /* GSSAPI */ - - #endif /* _SSH_GSS_H */ -diff -up openssh-6.8p1/ssh_config.gsskex openssh-6.8p1/ssh_config ---- openssh-6.8p1/ssh_config.gsskex 2015-03-18 11:24:48.861900800 +0100 -+++ openssh-6.8p1/ssh_config 2015-03-18 11:24:48.880900755 +0100 -@@ -26,6 +26,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP yes - # AddressFamily any -diff -up openssh-6.8p1/ssh_config.5.gsskex openssh-6.8p1/ssh_config.5 ---- openssh-6.8p1/ssh_config.5.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/ssh_config.5 2015-03-18 11:24:48.881900753 +0100 -@@ -743,11 +743,43 @@ Specifies whether user authentication ba +diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 +--- openssh/ssh_config.5.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/ssh_config.5 2015-06-24 11:07:36.234389789 +0200 +@@ -744,11 +744,43 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2427,9 +2259,21 @@ diff -up openssh-6.8p1/ssh_config.5.gsskex openssh-6.8p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-6.8p1/sshconnect2.c.gsskex openssh-6.8p1/sshconnect2.c ---- openssh-6.8p1/sshconnect2.c.gsskex 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sshconnect2.c 2015-03-18 11:32:36.879784546 +0100 +diff -up openssh/ssh_config.gsskex openssh/ssh_config +--- openssh/ssh_config.gsskex 2015-06-24 11:07:36.209389852 +0200 ++++ openssh/ssh_config 2015-06-24 11:07:36.234389789 +0200 +@@ -26,6 +26,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP yes + # AddressFamily any +diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c +--- openssh/sshconnect2.c.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/sshconnect2.c 2015-06-24 11:07:36.234389789 +0200 @@ -160,9 +160,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2629,10 +2473,10 @@ diff -up openssh-6.8p1/sshconnect2.c.gsskex openssh-6.8p1/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh-6.8p1/sshd.c.gsskex openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.gsskex 2015-03-18 11:24:48.869900781 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 11:35:53.260315986 +0100 -@@ -1831,10 +1831,13 @@ main(int ac, char **av) +diff -up openssh/sshd.c.gsskex openssh/sshd.c +--- openssh/sshd.c.gsskex 2015-06-24 11:07:36.217389832 +0200 ++++ openssh/sshd.c 2015-06-24 11:07:36.235389787 +0200 +@@ -1839,10 +1839,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2646,7 +2490,7 @@ diff -up openssh-6.8p1/sshd.c.gsskex openssh-6.8p1/sshd.c if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2580,6 +2583,48 @@ do_ssh2_kex(void) +@@ -2589,6 +2592,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2695,7 +2539,7 @@ diff -up openssh-6.8p1/sshd.c.gsskex openssh-6.8p1/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2594,6 +2639,13 @@ do_ssh2_kex(void) +@@ -2603,6 +2648,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2709,22 +2553,10 @@ diff -up openssh-6.8p1/sshd.c.gsskex openssh-6.8p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-6.8p1/sshd_config.gsskex openssh-6.8p1/sshd_config ---- openssh-6.8p1/sshd_config.gsskex 2015-03-18 11:24:48.869900781 +0100 -+++ openssh-6.8p1/sshd_config 2015-03-18 11:24:48.882900750 +0100 -@@ -91,6 +91,8 @@ ChallengeResponseAuthentication no - # GSSAPI options - GSSAPIAuthentication yes - GSSAPICleanupCredentials no -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -diff -up openssh-6.8p1/sshd_config.5.gsskex openssh-6.8p1/sshd_config.5 ---- openssh-6.8p1/sshd_config.5.gsskex 2015-03-18 11:24:48.882900750 +0100 -+++ openssh-6.8p1/sshd_config.5 2015-03-18 12:12:57.914965842 +0100 -@@ -564,12 +564,40 @@ Specifies whether user authentication ba +diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 +--- openssh/sshd_config.5.gsskex 2015-06-24 11:07:36.235389787 +0200 ++++ openssh/sshd_config.5 2015-06-24 11:23:13.490016656 +0200 +@@ -616,6 +616,12 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2737,26 +2569,10 @@ diff -up openssh-6.8p1/sshd_config.5.gsskex openssh-6.8p1/sshd_config.5 .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. +@@ -637,6 +643,11 @@ machine's default store. + This facility is provided to assist with operation on multi homed machines. The default is .Dq yes . - Note that this option applies to protocol version 2 only. -+.It Cm GSSAPIStrictAcceptorCheck -+Determines whether to be strict about the identity of the GSSAPI acceptor -+a client authenticates against. If -+.Dq yes -+then the client must authenticate against the -+.Pa host -+service on the current hostname. If -+.Dq no -+then the client may authenticate against any service key stored in the -+machine's default store. This facility is provided to assist with operation -+on multi homed machines. -+The default is -+.Dq yes . -+Note that this option applies only to protocol version 2 GSSAPI connections, -+and setting it to -+.Dq no -+may only work with recent Kerberos GSSAPI libraries. +.It Cm GSSAPIStoreCredentialsOnRekey +Controls whether the user's GSSAPI credentials should be updated following a +successful connection rekeying. This option can be used to accepted renewed @@ -2765,3 +2581,117 @@ diff -up openssh-6.8p1/sshd_config.5.gsskex openssh-6.8p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. +diff -up openssh/sshd_config.gsskex openssh/sshd_config +--- openssh/sshd_config.gsskex 2015-06-24 11:07:36.217389832 +0200 ++++ openssh/sshd_config 2015-06-24 11:07:36.235389787 +0200 +@@ -91,6 +91,8 @@ ChallengeResponseAuthentication no + # GSSAPI options + GSSAPIAuthentication yes + GSSAPICleanupCredentials no ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange no + + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h +--- openssh/ssh-gss.h.gsskex 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/ssh-gss.h 2015-06-24 11:07:36.234389789 +0200 +@@ -1,6 +1,6 @@ + /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 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,22 @@ + + #define SSH_GSS_OIDTYPE 0x06 + ++#define SSH2_MSG_KEXGSS_INIT 30 ++#define SSH2_MSG_KEXGSS_CONTINUE 31 ++#define SSH2_MSG_KEXGSS_COMPLETE 32 ++#define SSH2_MSG_KEXGSS_HOSTKEY 33 ++#define SSH2_MSG_KEXGSS_ERROR 34 ++#define SSH2_MSG_KEXGSS_GROUPREQ 40 ++#define SSH2_MSG_KEXGSS_GROUP 41 ++#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" ++#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" ++#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" ++ + typedef struct { + char *filename; + char *envvar; + char *envval; ++ struct passwd *owner; + void *data; + } ssh_gssapi_ccache; + +@@ -72,8 +84,11 @@ typedef struct { + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; ++ gss_name_t name; + struct ssh_gssapi_mech_struct *mech; + ssh_gssapi_ccache store; ++ int used; ++ int updated; + } ssh_gssapi_client; + + typedef struct ssh_gssapi_mech_struct { +@@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); + void (*storecreds) (ssh_gssapi_client *); ++ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + + typedef struct { +@@ -94,10 +110,11 @@ typedef struct { + gss_OID oid; /* client */ + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ +- gss_cred_id_t client_creds; /* server */ ++ gss_cred_id_t client_creds; /* both */ + } Gssctxt; + + extern ssh_gssapi_mech *supported_mechs[]; ++extern Gssctxt *gss_kex_context; + + int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); + void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); +@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); + void ssh_gssapi_delete_ctx(Gssctxt **); + OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); +-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); ++int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); ++OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); ++int ssh_gssapi_credentials_updated(Gssctxt *); + + /* In the server */ ++typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, ++ const char *); ++char *ssh_gssapi_client_mechanisms(const char *, const char *); ++char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, ++ const char *); ++gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); ++int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, ++ const char *); + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +-int ssh_gssapi_userok(char *name); ++int ssh_gssapi_userok(char *name, struct passwd *); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); + void ssh_gssapi_storecreds(void); + ++char *ssh_gssapi_server_mechanisms(void); ++int ssh_gssapi_oid_table_ok(); ++ ++int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); ++ ++void ssh_gssapi_rekey_creds(void); + #endif /* GSSAPI */ + + #endif /* _SSH_GSS_H */ diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index be79371..6018554 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,6 +1,24 @@ -diff -up openssh-6.8p1/HOWTO.ssh-keycat.keycat openssh-6.8p1/HOWTO.ssh-keycat ---- openssh-6.8p1/HOWTO.ssh-keycat.keycat 2015-03-18 11:13:43.063482958 +0100 -+++ openssh-6.8p1/HOWTO.ssh-keycat 2015-03-18 11:13:43.063482958 +0100 +diff -up openssh/auth2-pubkey.c.keycat openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.keycat 2015-06-24 10:57:50.158849606 +0200 ++++ openssh/auth2-pubkey.c 2015-06-24 11:04:23.989868638 +0200 +@@ -490,6 +490,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 @@ -14,9 +32,9 @@ diff -up openssh-6.8p1/HOWTO.ssh-keycat.keycat openssh-6.8p1/HOWTO.ssh-keycat + PubkeyAuthentication yes + + -diff -up openssh-6.8p1/Makefile.in.keycat openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.keycat 2015-03-18 11:13:43.061482963 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 11:14:22.480389291 +0100 +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 SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -52,27 +70,23 @@ diff -up openssh-6.8p1/Makefile.in.keycat openssh-6.8p1/Makefile.in $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff -up openssh-6.8p1/auth2-pubkey.c.keycat openssh-6.8p1/auth2-pubkey.c ---- openssh-6.8p1/auth2-pubkey.c.keycat 2015-03-18 11:13:43.053482982 +0100 -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-18 11:13:43.063482958 +0100 -@@ -623,6 +623,14 @@ user_key_command_allowed2(struct passwd - _exit(1); - } +diff -up openssh/openbsd-compat/port-linux.h.keycat openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.keycat 2015-06-24 10:57:50.150849626 +0200 ++++ openssh/openbsd-compat/port-linux.h 2015-06-24 10:57:50.160849601 +0200 +@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const + void ssh_selinux_change_context(const char *); + void ssh_selinux_setfscreatecon(const char *); -+#ifdef WITH_SELINUX -+ if (sshd_selinux_setup_env_variables() < 0) { -+ error ("failed to copy environment: %s", -+ strerror(errno)); -+ _exit(127); -+ } -+#endif -+ - execl(options.authorized_keys_command, - options.authorized_keys_command, user_pw->pw_name, NULL); ++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 -diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.keycat openssh-6.8p1/openbsd-compat/port-linux-sshd.c ---- openssh-6.8p1/openbsd-compat/port-linux-sshd.c.keycat 2015-03-18 11:13:43.057482972 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux-sshd.c 2015-03-18 11:13:43.063482958 +0100 + #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; @@ -166,23 +180,9 @@ diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.keycat openssh-6.8p1/ope return; if (getexeccon((security_context_t *)&ctx) != 0) { -diff -up openssh-6.8p1/openbsd-compat/port-linux.h.keycat openssh-6.8p1/openbsd-compat/port-linux.h ---- openssh-6.8p1/openbsd-compat/port-linux.h.keycat 2015-03-18 11:13:43.057482972 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 11:13:43.063482958 +0100 -@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); - -+int sshd_selinux_enabled(void); - void sshd_selinux_copy_context(void); - void sshd_selinux_setup_exec_context(char *); -+int sshd_selinux_setup_env_variables(void); - #endif - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-6.8p1/platform.c.keycat openssh-6.8p1/platform.c ---- openssh-6.8p1/platform.c.keycat 2015-03-18 11:13:43.055482977 +0100 -+++ openssh-6.8p1/platform.c 2015-03-18 11:13:43.063482958 +0100 +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 @@ -192,9 +192,9 @@ diff -up openssh-6.8p1/platform.c.keycat openssh-6.8p1/platform.c #endif #ifdef USE_SOLARIS_PROJECTS -diff -up openssh-6.8p1/ssh-keycat.c.keycat openssh-6.8p1/ssh-keycat.c ---- openssh-6.8p1/ssh-keycat.c.keycat 2015-03-18 11:13:43.064482956 +0100 -+++ openssh-6.8p1/ssh-keycat.c 2015-03-18 11:13:43.064482956 +0100 +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,238 @@ +/* + * Redistribution and use in source and binary forms, with or without diff --git a/openssh-6.7p1-audit.patch b/openssh-6.7p1-audit.patch index 614604e..b216062 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -1,18 +1,6 @@ -diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.audit 2015-03-20 13:41:15.065883826 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 -@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ -- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o -+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o - - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ -diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c ---- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 +diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c +--- openssh/audit-bsm.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/audit-bsm.c 2015-06-24 11:53:29.780390469 +0200 @@ -375,10 +375,23 @@ audit_connection_from(const char *host, #endif } @@ -38,7 +26,7 @@ diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c } void -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) +@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -92,9 +80,247 @@ diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c ---- openssh-6.8p1/audit-linux.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 +0100 +diff -up openssh/audit.c.audit openssh/audit.c +--- openssh/audit.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/audit.c 2015-06-24 11:53:29.781390467 +0200 +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + #ifdef SSH_AUDIT_EVENTS + +@@ -36,6 +37,11 @@ + #include "key.h" + #include "hostfile.h" + #include "auth.h" ++#include "ssh-gss.h" ++#include "monitor_wrap.h" ++#include "xmalloc.h" ++#include "misc.h" ++#include "servconf.h" + + /* + * Care must be taken when using this since it WILL NOT be initialized when +@@ -43,6 +49,7 @@ + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ + extern Authctxt *the_authctxt; ++extern ServerOptions options; + + /* Maybe add the audit class to struct Authmethod? */ + ssh_audit_event_t +@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) + const char * + audit_username(void) + { +- static const char unknownuser[] = "(unknown user)"; +- static const char invaliduser[] = "(invalid user)"; ++ static const char unknownuser[] = "(unknown)"; + +- if (the_authctxt == NULL || the_authctxt->user == NULL) ++ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) + return (unknownuser); +- if (!the_authctxt->valid) +- return (invaliduser); + return (the_authctxt->user); + } + +@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) + return(event_lookup[i].name); + } + ++void ++audit_key(int host_user, int *rv, const Key *key) ++{ ++ char *fp; ++ const char *crypto_name; ++ ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (key->type == KEY_RSA1) ++ crypto_name = "ssh-rsa1"; ++ else ++ crypto_name = key_ssh_name(key); ++ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0) ++ *rv = 0; ++ free(fp); ++} ++ ++void ++audit_unsupported(int what) ++{ ++ PRIVSEP(audit_unsupported_body(what)); ++} ++ ++void ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) ++{ ++ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); ++} ++ ++void ++audit_session_key_free(int ctos) ++{ ++ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); ++} ++ + # ifndef CUSTOM_SSH_AUDIT_EVENTS + /* + * Null implementations of audit functions. +@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) + } + + /* ++ * Called when a child process has called, or will soon call, ++ * audit_session_open. ++ */ ++void ++audit_count_session_open(void) ++{ ++ debug("audit count session open euid %d user %s", geteuid(), ++ audit_username()); ++} ++ ++/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * +@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li + /* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows +- * multiple sessions within a single connection. ++ * multiple sessions within a single connection. Returns a "handle" for ++ * audit_end_command. + */ +-void ++int + audit_run_command(const char *command) + { + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); ++ return 0; ++} ++ ++/* ++ * This will be called when the non-interactive command finishes. Note that ++ * it may be called multiple times for a single connection since SSH2 allows ++ * multiple sessions within a single connection. "handle" should come from ++ * the corresponding audit_run_command. ++ */ ++void ++audit_end_command(int handle, const char *command) ++{ ++ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), ++ audit_username(), command); ++} ++ ++/* ++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. ++ * ++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. ++ */ ++int ++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++{ ++ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, ++ sshkey_fingerprint_prefix(), fp, rv); ++} ++ ++/* ++ * This will be called when the protocol negotiation fails. ++ */ ++void ++audit_unsupported_body(int what) ++{ ++ debug("audit unsupported protocol euid %d type %d", geteuid(), what); ++} ++ ++/* ++ * This will be called on succesfull protocol negotiation. ++ */ ++void ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++ uid_t uid) ++{ ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, ++ (unsigned)uid); ++} ++ ++/* ++ * This will be called on succesfull session key discard ++ */ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ debug("audit session key discard euid %u direction %d from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); ++} ++ ++/* ++ * This will be called on destroy private part of the server key ++ */ ++void ++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", ++ geteuid(), fp, (long)pid, (unsigned)uid); ++} ++ ++/* ++ * This will be called on generation of the ephemeral server key ++ */ ++void ++audit_generate_ephemeral_server_key(const char *) ++{ ++ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp); + } + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh/audit.h.audit openssh/audit.h +--- openssh/audit.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/audit.h 2015-06-24 11:53:29.781390467 +0200 +@@ -28,6 +28,7 @@ + # define _SSH_AUDIT_H + + #include "loginrec.h" ++#include "key.h" + + enum ssh_audit_event_type { + SSH_LOGIN_EXCEED_MAXTRIES, +@@ -47,11 +48,25 @@ enum ssh_audit_event_type { + }; + typedef enum ssh_audit_event_type ssh_audit_event_t; + ++int listening_for_clients(void); ++ + void audit_connection_from(const char *, int); + void audit_event(ssh_audit_event_t); ++void audit_count_session_open(void); + void audit_session_open(struct logininfo *); + void audit_session_close(struct logininfo *); +-void audit_run_command(const char *); ++int audit_run_command(const char *); ++void audit_end_command(int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); ++int audit_keyusage(int, const char *, unsigned, char *, int); ++void audit_key(int, int *, const Key *); ++void audit_unsupported(int); ++void audit_kex(int, char *, char *, char *, char *); ++void audit_unsupported_body(int); ++void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(int ctos); ++void audit_session_key_free_body(int ctos, pid_t, uid_t); ++void audit_destroy_sensitive_data(const char *, pid_t, uid_t); ++void audit_generate_ephemeral_server_key(const char *); + + #endif /* _SSH_AUDIT_H */ +diff -up openssh/audit-linux.c.audit openssh/audit-linux.c +--- openssh/audit-linux.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/audit-linux.c 2015-06-24 11:53:29.781390467 +0200 @@ -35,13 +35,25 @@ #include "log.h" @@ -124,7 +350,7 @@ diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c { int audit_fd, rc, saved_errno; -@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char *username, +@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const if (audit_fd < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) @@ -139,7 +365,7 @@ diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char *username, +@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const if ((rc == -EPERM) && (geteuid() != 0)) rc = 0; errno = saved_errno; @@ -486,247 +712,9 @@ diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c ---- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 -@@ -28,6 +28,7 @@ - - #include - #include -+#include - - #ifdef SSH_AUDIT_EVENTS - -@@ -36,6 +37,11 @@ - #include "key.h" - #include "hostfile.h" - #include "auth.h" -+#include "ssh-gss.h" -+#include "monitor_wrap.h" -+#include "xmalloc.h" -+#include "misc.h" -+#include "servconf.h" - - /* - * Care must be taken when using this since it WILL NOT be initialized when -@@ -43,6 +49,7 @@ - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. - */ - extern Authctxt *the_authctxt; -+extern ServerOptions options; - - /* Maybe add the audit class to struct Authmethod? */ - ssh_audit_event_t -@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) - const char * - audit_username(void) - { -- static const char unknownuser[] = "(unknown user)"; -- static const char invaliduser[] = "(invalid user)"; -+ static const char unknownuser[] = "(unknown)"; - -- if (the_authctxt == NULL || the_authctxt->user == NULL) -+ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) - return (unknownuser); -- if (!the_authctxt->valid) -- return (invaliduser); - return (the_authctxt->user); - } - -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) - return(event_lookup[i].name); - } - -+void -+audit_key(int host_user, int *rv, const Key *key) -+{ -+ char *fp; -+ const char *crypto_name; -+ -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (key->type == KEY_RSA1) -+ crypto_name = "ssh-rsa1"; -+ else -+ crypto_name = key_ssh_name(key); -+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0) -+ *rv = 0; -+ free(fp); -+} -+ -+void -+audit_unsupported(int what) -+{ -+ PRIVSEP(audit_unsupported_body(what)); -+} -+ -+void -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) -+{ -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); -+} -+ -+void -+audit_session_key_free(int ctos) -+{ -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); -+} -+ - # ifndef CUSTOM_SSH_AUDIT_EVENTS - /* - * Null implementations of audit functions. -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) - } - - /* -+ * Called when a child process has called, or will soon call, -+ * audit_session_open. -+ */ -+void -+audit_count_session_open(void) -+{ -+ debug("audit count session open euid %d user %s", geteuid(), -+ audit_username()); -+} -+ -+/* - * Called when a user session is started. Argument is the tty allocated to - * the session, or NULL if no tty was allocated. - * -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) - /* - * This will be called when a user runs a non-interactive command. Note that - * it may be called multiple times for a single connection since SSH2 allows -- * multiple sessions within a single connection. -+ * multiple sessions within a single connection. Returns a "handle" for -+ * audit_end_command. - */ --void -+int - audit_run_command(const char *command) - { - debug("audit run command euid %d user %s command '%.200s'", geteuid(), - audit_username(), command); -+ return 0; -+} -+ -+/* -+ * This will be called when the non-interactive command finishes. Note that -+ * it may be called multiple times for a single connection since SSH2 allows -+ * multiple sessions within a single connection. "handle" should come from -+ * the corresponding audit_run_command. -+ */ -+void -+audit_end_command(int handle, const char *command) -+{ -+ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), -+ audit_username(), command); -+} -+ -+/* -+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. -+ * -+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. -+ */ -+int -+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) -+{ -+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", -+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, -+ sshkey_fingerprint_prefix(), fp, rv); -+} -+ -+/* -+ * This will be called when the protocol negotiation fails. -+ */ -+void -+audit_unsupported_body(int what) -+{ -+ debug("audit unsupported protocol euid %d type %d", geteuid(), what); -+} -+ -+/* -+ * This will be called on succesfull protocol negotiation. -+ */ -+void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, -+ uid_t uid) -+{ -+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, -+ (unsigned)uid); -+} -+ -+/* -+ * This will be called on succesfull session key discard -+ */ -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ debug("audit session key discard euid %u direction %d from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); -+} -+ -+/* -+ * This will be called on destroy private part of the server key -+ */ -+void -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) -+{ -+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", -+ geteuid(), fp, (long)pid, (unsigned)uid); -+} -+ -+/* -+ * This will be called on generation of the ephemeral server key -+ */ -+void -+audit_generate_ephemeral_server_key(const char *) -+{ -+ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp); - } - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h ---- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 -@@ -28,6 +28,7 @@ - # define _SSH_AUDIT_H - - #include "loginrec.h" -+#include "key.h" - - enum ssh_audit_event_type { - SSH_LOGIN_EXCEED_MAXTRIES, -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { - }; - typedef enum ssh_audit_event_type ssh_audit_event_t; - -+int listening_for_clients(void); -+ - void audit_connection_from(const char *, int); - void audit_event(ssh_audit_event_t); -+void audit_count_session_open(void); - void audit_session_open(struct logininfo *); - void audit_session_close(struct logininfo *); --void audit_run_command(const char *); -+int audit_run_command(const char *); -+void audit_end_command(int, const char *); - ssh_audit_event_t audit_classify_auth(const char *); -+int audit_keyusage(int, const char *, unsigned, char *, int); -+void audit_key(int, int *, const Key *); -+void audit_unsupported(int); -+void audit_kex(int, char *, char *, char *, char *); -+void audit_unsupported_body(int); -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); -+void audit_session_key_free(int ctos); -+void audit_session_key_free_body(int ctos, pid_t, uid_t); -+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); -+void audit_generate_ephemeral_server_key(const char *); - - #endif /* _SSH_AUDIT_H */ -diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c ---- openssh-6.8p1/auditstub.c.audit 2015-03-20 13:41:15.093883780 +0100 -+++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 +diff -up openssh/auditstub.c.audit openssh/auditstub.c +--- openssh/auditstub.c.audit 2015-06-24 11:53:29.782390464 +0200 ++++ openssh/auditstub.c 2015-06-24 11:53:29.782390464 +0200 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -778,10 +766,117 @@ diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c ---- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 -@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) +diff -up openssh/auth2.c.audit openssh/auth2.c +--- openssh/auth2.c.audit 2015-06-24 11:53:29.731390595 +0200 ++++ openssh/auth2.c 2015-06-24 11:53:29.783390462 +0200 +@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 + } else { + logit("input_userauth_request: invalid user %s", user); + authctxt->pw = fakepw(); +-#ifdef SSH_AUDIT_EVENTS +- PRIVSEP(audit_event(SSH_INVALID_USER)); +-#endif + } + #ifdef USE_PAM + if (options.use_pam) +diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c +--- openssh/auth2-hostbased.c.audit 2015-06-24 11:53:29.682390720 +0200 ++++ openssh/auth2-hostbased.c 2015-06-24 11:53:29.782390464 +0200 +@@ -146,7 +146,7 @@ userauth_hostbased(Authctxt *authctxt) + /* test for allowed key and correct signature */ + authenticated = 0; + if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && +- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), ++ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) + authenticated = 1; + +@@ -163,6 +163,18 @@ done: + return authenticated; + } + ++int ++hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++{ ++ int rv; ++ ++ rv = key_verify(key, sig, slen, data, datalen); ++#ifdef SSH_AUDIT_EVENTS ++ audit_key(0, &rv, key); ++#endif ++ return rv; ++} ++ + /* return 1 if given hostkey is allowed */ + int + hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, +diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.audit 2015-06-24 11:53:29.783390462 +0200 ++++ openssh/auth2-pubkey.c 2015-06-24 11:58:49.547572821 +0200 +@@ -175,7 +175,7 @@ userauth_pubkey(Authctxt *authctxt) + /* test for correct signature */ + authenticated = 0; + if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && +- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), ++ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) { + authenticated = 1; + /* Record the successful key to prevent reuse */ +@@ -253,6 +253,18 @@ pubkey_auth_info(Authctxt *authctxt, con + free(extra); + } + ++int ++user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++{ ++ int rv; ++ ++ rv = key_verify(key, sig, slen, data, datalen); ++#ifdef SSH_AUDIT_EVENTS ++ audit_key(1, &rv, key); ++#endif ++ return rv; ++} ++ + /* + * Splits 's' into an argument vector. Handles quoted string and basic + * escape characters (\\, \", \'). Caller must free the argument vector +diff -up openssh/auth.c.audit openssh/auth.c +--- openssh/auth.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/auth.c 2015-06-24 11:53:29.782390464 +0200 +@@ -643,9 +643,6 @@ getpwnamallow(const char *user) + record_failed_login(user, + get_canonical_hostname(options.use_dns), "ssh"); + #endif +-#ifdef SSH_AUDIT_EVENTS +- audit_event(SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(pw)) +diff -up openssh/auth.h.audit openssh/auth.h +--- openssh/auth.h.audit 2015-06-24 11:53:29.682390720 +0200 ++++ openssh/auth.h 2015-06-24 11:53:29.782390464 +0200 +@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt + + char *expand_authorized_keys(const char *, struct passwd *pw); + char *authorized_principals_file(struct passwd *); ++int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + + FILE *auth_openkeyfile(const char *, struct passwd *, int); + FILE *auth_openprincipals(const char *, struct passwd *, int); +@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc + int ssh1_session_key(BIGNUM *); + int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, + const u_char *, size_t, u_int); ++int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + + /* debug messages during authentication */ + void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); +diff -up openssh/auth-rsa.c.audit openssh/auth-rsa.c +--- openssh/auth-rsa.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/auth-rsa.c 2015-06-24 11:53:29.782390464 +0200 +@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNU { u_char buf[32], mdbuf[16]; struct ssh_digest_ctx *md; @@ -793,7 +888,7 @@ diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) +@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNU ssh_digest_free(md); /* Verify that the response is the original challenge. */ @@ -817,117 +912,10 @@ diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c } /* -diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c ---- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 -@@ -644,9 +644,6 @@ getpwnamallow(const char *user) - record_failed_login(user, - get_canonical_hostname(options.use_dns), "ssh"); - #endif --#ifdef SSH_AUDIT_EVENTS -- audit_event(SSH_INVALID_USER); --#endif /* SSH_AUDIT_EVENTS */ - return (NULL); - } - if (!allowed_user(pw)) -diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h ---- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100 -+++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 -@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt - - char *expand_authorized_keys(const char *, struct passwd *pw); - char *authorized_principals_file(struct passwd *); -+int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); - - FILE *auth_openkeyfile(const char *, struct passwd *, int); - FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc - int ssh1_session_key(BIGNUM *); - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, - const u_char *, size_t, u_int); -+int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); - - /* debug messages during authentication */ - void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-6.8p1/auth2-hostbased.c.audit openssh-6.8p1/auth2-hostbased.c ---- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 13:41:15.002883927 +0100 -+++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 13:41:15.093883780 +0100 -@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) - /* test for allowed key and correct signature */ - authenticated = 0; - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), -+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) - authenticated = 1; - -@@ -164,6 +164,18 @@ done: - return authenticated; - } - -+int -+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) -+{ -+ int rv; -+ -+ rv = key_verify(key, sig, slen, data, datalen); -+#ifdef SSH_AUDIT_EVENTS -+ audit_key(0, &rv, key); -+#endif -+ return rv; -+} -+ - /* return 1 if given hostkey is allowed */ - int - hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-6.8p1/auth2-pubkey.c.audit openssh-6.8p1/auth2-pubkey.c ---- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 13:41:15.013883910 +0100 -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 +0100 -@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) - /* test for correct signature */ - authenticated = 0; - if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), -+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) { - authenticated = 1; - /* Record the successful key to prevent reuse */ -@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con - free(extra); - } - -+int -+user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) -+{ -+ int rv; -+ -+ rv = key_verify(key, sig, slen, data, datalen); -+#ifdef SSH_AUDIT_EVENTS -+ audit_key(1, &rv, key); -+#endif -+ return rv; -+} -+ - static int - match_principals_option(const char *principal_list, struct sshkey_cert *cert) - { -diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c ---- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 +0100 -+++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 - } else { - logit("input_userauth_request: invalid user %s", user); - authctxt->pw = fakepw(); --#ifdef SSH_AUDIT_EVENTS -- PRIVSEP(audit_event(SSH_INVALID_USER)); --#endif - } - #ifdef USE_PAM - if (options.use_pam) -diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c ---- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 -@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v +diff -up openssh/cipher.c.audit openssh/cipher.c +--- openssh/cipher.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/cipher.c 2015-06-24 11:53:29.783390462 +0200 +@@ -57,26 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #endif @@ -954,9 +942,9 @@ diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h ---- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 +diff -up openssh/cipher.h.audit openssh/cipher.h +--- openssh/cipher.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/cipher.h 2015-06-24 11:53:29.783390462 +0200 @@ -62,7 +62,26 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -985,10 +973,10 @@ diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h struct sshcipher_ctx { int plaintext; int encrypt; -diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c ---- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 -+++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 -@@ -54,6 +55,7 @@ +diff -up openssh/kex.c.audit openssh/kex.c +--- openssh/kex.c.audit 2015-06-24 11:53:29.733390590 +0200 ++++ openssh/kex.c 2015-06-24 11:53:29.783390462 +0200 +@@ -54,6 +54,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -996,7 +984,7 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -486,8 +487,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -1010,7 +998,7 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -505,8 +510,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1024,7 +1012,7 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -523,8 +532,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1038,7 +1026,7 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -674,6 +687,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); @@ -1049,7 +1037,7 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i +@@ -849,3 +866,34 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1084,9 +1072,9 @@ diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} + -diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h ---- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 -+++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 +diff -up openssh/kex.h.audit openssh/kex.h +--- openssh/kex.h.audit 2015-06-24 11:53:29.733390590 +0200 ++++ openssh/kex.h 2015-06-24 11:53:29.784390459 +0200 @@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1096,9 +1084,9 @@ diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h ---- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 +diff -up openssh/key.h.audit openssh/key.h +--- openssh/key.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/key.h 2015-06-24 11:53:29.784390459 +0200 @@ -50,6 +50,7 @@ typedef struct sshkey Key; #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid @@ -1107,10 +1095,10 @@ diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h #define key_type_plain sshkey_type_plain #define key_cert_is_legacy sshkey_cert_is_legacy #define key_curve_name_to_nid sshkey_curve_name_to_nid -diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c ---- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 -@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh/mac.c.audit openssh/mac.c +--- openssh/mac.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/mac.c 2015-06-24 11:53:29.784390459 +0200 +@@ -226,6 +226,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1131,9 +1119,9 @@ diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h ---- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 +diff -up openssh/mac.h.audit openssh/mac.h +--- openssh/mac.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/mac.h 2015-06-24 11:53:29.784390459 +0200 @@ -47,5 +47,6 @@ int mac_init(struct sshmac *); int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, u_char *, size_t); @@ -1141,9 +1129,21 @@ diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c ---- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 +0100 -+++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 +diff -up openssh/Makefile.in.audit openssh/Makefile.in +--- openssh/Makefile.in.audit 2015-06-24 11:53:29.752390541 +0200 ++++ openssh/Makefile.in 2015-06-24 11:53:29.780390469 +0200 +@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ +- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o ++ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect1.o sshconnect2.o mux.o \ +diff -up openssh/monitor.c.audit openssh/monitor.c +--- openssh/monitor.c.audit 2015-06-24 11:53:29.759390523 +0200 ++++ openssh/monitor.c 2015-06-24 11:53:29.784390459 +0200 @@ -102,6 +102,7 @@ #include "ssh2.h" #include "roaming.h" @@ -1219,7 +1219,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c #endif #endif /* WITH_SSH1 */ {0, 0, NULL} -@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1467,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1231,7 +1231,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1477,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1240,7 +1240,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1497,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1259,7 +1259,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) +@@ -1558,6 +1598,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1272,7 +1272,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c session_unused(s->self); } -@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1840,6 +1886,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1281,7 +1281,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff +@@ -1882,11 +1930,43 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1326,7 +1326,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c free(cmd); return (0); } -@@ -1936,6 +2017,7 @@ +@@ -1943,6 +2023,7 @@ monitor_apply_keystate(struct monitor *p void mm_get_keystate(struct monitor *pmonitor) { @@ -1334,7 +1334,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1950,6 +2031,21 @@ mm_get_keystate(struct monitor *pmonitor mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); @@ -1356,7 +1356,7 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c } -@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -2216,3 +2312,87 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1444,9 +1444,9 @@ diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h ---- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 +0100 -+++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 +diff -up openssh/monitor.h.audit openssh/monitor.h +--- openssh/monitor.h.audit 2015-06-24 11:53:29.759390523 +0200 ++++ openssh/monitor.h 2015-06-24 11:53:29.785390457 +0200 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1462,10 +1462,10 @@ diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h }; -diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c ---- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 13:41:15.047883855 +0100 -+++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 +0100 -@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha +diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.audit 2015-06-24 11:53:29.734390587 +0200 ++++ openssh/monitor_wrap.c 2015-06-24 11:53:29.785390457 +0200 +@@ -462,7 +462,7 @@ mm_key_allowed(enum mm_keytype type, cha */ int @@ -1474,7 +1474,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c { Buffer m; u_char *blob; -@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -476,6 +476,7 @@ mm_key_verify(Key *key, u_char *sig, u_i return (0); buffer_init(&m); @@ -1482,7 +1482,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -493,6 +494,18 @@ mm_key_verify(Key *key, u_char *sig, u_i return (verified); } @@ -1501,7 +1501,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c void mm_send_keystate(struct monitor *monitor) { -@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -1006,10 +1019,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1514,7 +1514,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command +@@ -1017,6 +1031,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1541,7 +1541,7 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1152,3 +1186,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1614,11 +1614,11 @@ diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h ---- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 13:41:15.048883853 +0100 -+++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 +0100 +diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.audit 2015-06-24 11:53:29.734390587 +0200 ++++ openssh/monitor_wrap.h 2015-06-24 11:59:45.086430808 +0200 @@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char - int mm_user_key_allowed(struct passwd *, Key *); + int mm_user_key_allowed(struct passwd *, Key *, int); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); -int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); @@ -1641,9 +1641,9 @@ diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h #endif struct Session; -diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c ---- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 +0100 -+++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 +diff -up openssh/packet.c.audit openssh/packet.c +--- openssh/packet.c.audit 2015-06-24 11:53:29.665390763 +0200 ++++ openssh/packet.c 2015-06-24 11:53:29.786390454 +0200 @@ -67,6 +67,7 @@ #include "key.h" /* typedefs XXX */ @@ -1652,7 +1652,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c #include "crc32.h" #include "deattack.h" #include "compat.h" -@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -449,6 +450,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1666,7 +1666,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) +@@ -479,13 +487,6 @@ ssh_packet_close(struct ssh *ssh) if (!state->initialized) return; state->initialized = 0; @@ -1680,7 +1680,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); -@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) +@@ -517,14 +518,24 @@ ssh_packet_close(struct ssh *ssh) inflateEnd(stream); } } @@ -1709,7 +1709,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c free(ssh->state); ssh->state = NULL; } -@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod +@@ -944,6 +955,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod } if (state->newkeys[mode] != NULL) { debug("set_newkeys: rekeying"); @@ -1717,7 +1717,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; -@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2281,6 +2293,75 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1793,7 +1793,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c /* XXX TODO update roaming to new API (does not work anyway) */ /* * Save the state for the real connection, and use a separate state when -@@ -2272,18 +2373,12 @@ void +@@ -2290,18 +2371,12 @@ void ssh_packet_backup_state(struct ssh *ssh, struct ssh *backup_state) { @@ -1813,7 +1813,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c } /* XXX FIXME FIXME FIXME */ -@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh +@@ -2320,9 +2395,7 @@ ssh_packet_restore_state(struct ssh *ssh backup_state = ssh; ssh = tmp; ssh->state->connection_in = backup_state->state->connection_in; @@ -1823,7 +1823,7 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c len = sshbuf_len(backup_state->state->input); if (len > 0) { if ((r = sshbuf_putb(ssh->state->input, -@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh +@@ -2331,6 +2404,11 @@ ssh_packet_restore_state(struct ssh *ssh sshbuf_reset(backup_state->state->input); add_recv_bytes(len); } @@ -1835,9 +1835,9 @@ diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c } /* Reset after_authentication and reset compression in post-auth privsep */ -diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h ---- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 +diff -up openssh/packet.h.audit openssh/packet.h +--- openssh/packet.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/packet.h 2015-06-24 11:53:29.786390454 +0200 @@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); @@ -1853,9 +1853,25 @@ diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c ---- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 +0100 -+++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 +diff -up openssh/sandbox-seccomp-filter.c.audit openssh/sandbox-seccomp-filter.c +--- openssh/sandbox-seccomp-filter.c.audit 2015-06-24 11:53:29.788390449 +0200 ++++ openssh/sandbox-seccomp-filter.c 2015-06-24 12:00:37.459296890 +0200 +@@ -147,6 +147,12 @@ static const struct sock_filter preauth_ + #ifdef __NR_gettimeofday + SC_ALLOW(gettimeofday), + #endif ++#ifdef SSH_AUDIT_EVENTS ++ SC_ALLOW(getuid), ++#ifdef __NR_getuid32 /* not defined on x86_64 */ ++ SC_ALLOW(getuid32), ++#endif ++#endif + #ifdef __NR_madvise + SC_ALLOW(madvise), + #endif +diff -up openssh/session.c.audit openssh/session.c +--- openssh/session.c.audit 2015-06-24 11:53:29.760390520 +0200 ++++ openssh/session.c 2015-06-24 11:53:29.786390454 +0200 @@ -139,7 +139,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; @@ -1975,7 +1991,7 @@ diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c void session_close(Session *s) { -@@ -2540,6 +2593,10 @@ session_close(Session *s) +@@ -2540,6 +2595,10 @@ session_close(Session *s) debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1986,7 +2002,7 @@ diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2754,6 +2813,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -2002,16 +2018,16 @@ diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c void do_cleanup(Authctxt *authctxt) { -@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2802,5 +2870,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h ---- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 +diff -up openssh/session.h.audit openssh/session.h +--- openssh/session.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/session.h 2015-06-24 11:53:29.786390454 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2036,10 +2052,10 @@ diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 -@@ -121,6 +124,7 @@ +diff -up openssh/sshd.c.audit openssh/sshd.c +--- openssh/sshd.c.audit 2015-06-24 11:53:29.770390495 +0200 ++++ openssh/sshd.c 2015-06-24 11:53:29.787390451 +0200 +@@ -121,6 +121,7 @@ #endif #include "monitor_wrap.h" #include "roaming.h" @@ -2047,7 +2063,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" -@@ -260,7 +264,7 @@ Buffer loginmsg; +@@ -260,7 +261,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2056,7 +2072,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c void demote_sensitive_data(void); #ifdef WITH_SSH1 -@@ -281,6 +285,15 @@ close_listen_socks(void) +@@ -281,6 +282,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2072,7 +2088,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c static void close_startup_pipes(void) { -@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in +@@ -560,22 +570,45 @@ sshd_exchange_identification(int sock_in } } @@ -2121,7 +2137,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -589,6 +625,8 @@ void +@@ -589,6 +622,8 @@ void demote_sensitive_data(void) { Key *tmp; @@ -2130,7 +2146,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c int i; if (sensitive_data.server_key) { -@@ -597,13 +635,25 @@ demote_sensitive_data(void) +@@ -597,13 +632,25 @@ demote_sensitive_data(void) sensitive_data.server_key = tmp; } @@ -2156,7 +2172,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c } /* Certs do not need demotion */ } -@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2165,7 +2181,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) +@@ -759,6 +806,12 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); @@ -2178,7 +2194,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1288,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2186,7 +2202,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2242,6 +2321,7 @@ main(int ac, char **av) +@@ -2251,6 +2305,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2194,7 +2210,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c exit(0); } -@@ -2287,7 +2367,7 @@ main(int ac, char **av) +@@ -2296,7 +2351,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2203,7 +2219,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c } packet_set_timeout(options.client_alive_interval, -@@ -2301,6 +2381,9 @@ main(int ac, char **av) +@@ -2310,6 +2365,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2213,7 +2229,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) +@@ -2470,6 +2528,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); @@ -2224,7 +2240,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) +@@ -2529,7 +2591,7 @@ do_ssh1_kex(void) } /* Destroy the private and public keys. No longer. */ @@ -2233,7 +2249,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) +@@ -2712,6 +2774,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2250,7 +2266,7 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2714,9 +2823,14 @@ cleanup_exit(int i) +@@ -2723,9 +2795,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2266,10 +2282,10 @@ diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c ---- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 -@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh/sshkey.c.audit openssh/sshkey.c +--- openssh/sshkey.c.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/sshkey.c 2015-06-24 11:53:29.787390451 +0200 +@@ -317,6 +317,33 @@ sshkey_type_is_valid_ca(int type) } int @@ -2303,9 +2319,9 @@ diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h ---- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 +diff -up openssh/sshkey.h.audit openssh/sshkey.h +--- openssh/sshkey.h.audit 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/sshkey.h 2015-06-24 11:53:29.787390451 +0200 @@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); @@ -2314,19 +2330,3 @@ diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h int sshkey_is_cert(const struct sshkey *); int sshkey_type_is_cert(int); int sshkey_type_plain(int); -diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit openssh-6.8p1/sandbox-seccomp-filter.c ---- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 13:41:15.088883788 +0100 -+++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 13:41:15.097883774 +0100 -@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ - #ifdef __NR_time /* not defined on EABI ARM */ - SC_ALLOW(time), - #endif -+#ifdef SSH_AUDIT_EVENTS -+ SC_ALLOW(getuid), -+#ifdef __NR_getuid32 /* not defined on x86_64 */ -+ SC_ALLOW(getuid32), -+#endif -+#endif - SC_ALLOW(read), - SC_ALLOW(write), - SC_ALLOW(close), diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index fe3b349..4b8a26f 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -447,25 +447,3 @@ diff -up openssh-6.8p1/sshkey.c.coverity openssh-6.8p1/sshkey.c #include "match.h" /* openssh private key file format */ -diff --git a/sshd.c b/sshd.c -index 6ff8f6f..2f2fcf8 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1548,6 +1548,7 @@ main(int ac, char **av) - int keytype; - Authctxt *authctxt; - struct connection_info *connection_info = get_connection_info(0, 0); -+ char *addr = NULL; - - #ifdef HAVE_SECUREWARE - (void)set_auth_parameters(ac, av); -@@ -2261,7 +2262,8 @@ main(int ac, char **av) - /* Log the connection. */ - verbose("Connection from %s port %d on %s port %d", - remote_ip, remote_port, -- get_local_ipaddr(sock_in), get_local_port()); -+ (addr = get_local_ipaddr(sock_in)), get_local_port()); -+ free(addr); - - /* - * We don't want to listen forever unless the other side diff --git a/openssh-6.7p1-debian-restore-tcp-wrappers.patch b/openssh-6.7p1-debian-restore-tcp-wrappers.patch index 63d62a0..a41cf34 100644 --- a/openssh-6.7p1-debian-restore-tcp-wrappers.patch +++ b/openssh-6.7p1-debian-restore-tcp-wrappers.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.8p1/configure.ac.tcp_wrappers openssh-6.8p1/configure.ac ---- openssh-6.8p1/configure.ac.tcp_wrappers 2015-03-18 13:05:57.365071779 +0100 -+++ openssh-6.8p1/configure.ac 2015-03-18 13:05:57.408071673 +0100 -@@ -1440,6 +1440,62 @@ AC_ARG_WITH([skey], +diff -up openssh/configure.ac.tcp_wrappers openssh/configure.ac +--- openssh/configure.ac.tcp_wrappers 2015-06-24 11:41:04.519293694 +0200 ++++ openssh/configure.ac 2015-06-24 11:41:04.556293600 +0200 +@@ -1448,6 +1448,62 @@ AC_ARG_WITH([skey], ] ) @@ -64,7 +64,7 @@ diff -up openssh-6.8p1/configure.ac.tcp_wrappers openssh-6.8p1/configure.ac # Check whether user wants to use ldns LDNS_MSG="no" AC_ARG_WITH(ldns, -@@ -5026,6 +5082,7 @@ echo " KerberosV support +@@ -5034,6 +5090,7 @@ echo " KerberosV support echo " SELinux support: $SELINUX_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" @@ -72,10 +72,10 @@ diff -up openssh-6.8p1/configure.ac.tcp_wrappers openssh-6.8p1/configure.ac echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" -diff -up openssh-6.8p1/sshd.8.tcp_wrappers openssh-6.8p1/sshd.8 ---- openssh-6.8p1/sshd.8.tcp_wrappers 2015-03-18 13:05:57.377071749 +0100 -+++ openssh-6.8p1/sshd.8 2015-03-18 13:05:57.408071673 +0100 -@@ -858,6 +858,12 @@ the user's home directory becomes access +diff -up openssh/sshd.8.tcp_wrappers openssh/sshd.8 +--- openssh/sshd.8.tcp_wrappers 2015-06-24 11:41:04.527293674 +0200 ++++ openssh/sshd.8 2015-06-24 11:41:04.556293600 +0200 +@@ -860,6 +860,12 @@ the user's home directory becomes access This file should be writable only by the user, and need not be readable by anyone else. .Pp @@ -88,7 +88,7 @@ diff -up openssh-6.8p1/sshd.8.tcp_wrappers openssh-6.8p1/sshd.8 .It Pa /etc/hosts.equiv This file is for host-based authentication (see .Xr ssh 1 ) . -@@ -981,6 +987,7 @@ IPv6 address can be used everywhere wher +@@ -983,6 +989,7 @@ IPv6 address can be used everywhere wher .Xr ssh-keygen 1 , .Xr ssh-keyscan 1 , .Xr chroot 2 , @@ -96,9 +96,9 @@ diff -up openssh-6.8p1/sshd.8.tcp_wrappers openssh-6.8p1/sshd.8 .Xr login.conf 5 , .Xr moduli 5 , .Xr sshd_config 5 , -diff -up openssh-6.8p1/sshd.c.tcp_wrappers openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.tcp_wrappers 2015-03-18 13:05:57.402071688 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 13:06:48.199947136 +0100 +diff -up openssh/sshd.c.tcp_wrappers openssh/sshd.c +--- openssh/sshd.c.tcp_wrappers 2015-06-24 11:41:04.549293618 +0200 ++++ openssh/sshd.c 2015-06-24 11:41:53.331169536 +0200 @@ -125,6 +125,13 @@ #include "version.h" #include "ssherr.h" @@ -113,7 +113,7 @@ diff -up openssh-6.8p1/sshd.c.tcp_wrappers openssh-6.8p1/sshd.c #ifndef O_NOCTTY #define O_NOCTTY 0 #endif -@@ -2150,6 +2157,24 @@ main(int ac, char **av) +@@ -2158,6 +2165,24 @@ main(int ac, char **av) #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif @@ -137,4 +137,4 @@ diff -up openssh-6.8p1/sshd.c.tcp_wrappers openssh-6.8p1/sshd.c +#endif /* LIBWRAP */ /* Log the connection. */ - verbose("Connection from %s port %d on %s port %d", + laddr = get_local_ipaddr(sock_in); diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index 0aafdcc..9f8b490 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -1,63 +1,6 @@ -diff -up openssh-6.8p1/Makefile.in.fips openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.fips 2015-03-19 13:14:22.221212174 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-19 13:14:22.230212157 +0100 -@@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) - $(RANLIB) $@ - - ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) -- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) -+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) - - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o -- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o -- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o -- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o -- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -204,7 +204,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a - $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o -- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-6.8p1/cipher-ctr.c.fips openssh-6.8p1/cipher-ctr.c ---- openssh-6.8p1/cipher-ctr.c.fips 2015-03-19 13:14:22.155212302 +0100 -+++ openssh-6.8p1/cipher-ctr.c 2015-03-19 13:14:22.230212157 +0100 -@@ -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-6.8p1/cipher.c.fips openssh-6.8p1/cipher.c ---- openssh-6.8p1/cipher.c.fips 2015-03-19 13:14:22.224212169 +0100 -+++ openssh-6.8p1/cipher.c 2015-03-19 13:14:22.230212157 +0100 +diff -up openssh/cipher.c.fips openssh/cipher.c +--- openssh/cipher.c.fips 2015-06-24 12:00:58.730242500 +0200 ++++ openssh/cipher.c 2015-06-24 12:00:58.737242482 +0200 @@ -39,6 +39,8 @@ #include @@ -130,10 +73,23 @@ diff -up openssh-6.8p1/cipher.c.fips openssh-6.8p1/cipher.c if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff -up openssh-6.8p1/dh.h.fips openssh-6.8p1/dh.h ---- openssh-6.8p1/dh.h.fips 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/dh.h 2015-03-19 13:14:22.230212157 +0100 -@@ -45,6 +45,7 @@ u_int dh_estimate(int); +diff -up openssh/cipher-ctr.c.fips openssh/cipher-ctr.c +--- openssh/cipher-ctr.c.fips 2015-06-24 12:00:58.669242656 +0200 ++++ openssh/cipher-ctr.c 2015-06-24 12:00:58.736242484 +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/dh.h.fips openssh/dh.h +--- openssh/dh.h.fips 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/dh.h 2015-06-24 12:00:58.737242482 +0200 +@@ -46,6 +46,7 @@ u_int dh_estimate(int); /* Min and max values from RFC4419. */ #define DH_GRP_MIN 1024 @@ -141,9 +97,9 @@ diff -up openssh-6.8p1/dh.h.fips openssh-6.8p1/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh-6.8p1/entropy.c.fips openssh-6.8p1/entropy.c ---- openssh-6.8p1/entropy.c.fips 2015-03-19 13:14:22.147212317 +0100 -+++ openssh-6.8p1/entropy.c 2015-03-19 13:14:22.230212157 +0100 +diff -up openssh/entropy.c.fips openssh/entropy.c +--- openssh/entropy.c.fips 2015-06-24 12:00:58.662242674 +0200 ++++ openssh/entropy.c 2015-06-24 12:00:58.737242482 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -154,9 +110,9 @@ diff -up openssh-6.8p1/entropy.c.fips openssh-6.8p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c ---- openssh-6.8p1/kex.c.fips 2015-03-19 13:14:22.165212282 +0100 -+++ openssh-6.8p1/kex.c 2015-03-19 13:14:22.230212157 +0100 +diff -up openssh/kex.c.fips openssh/kex.c +--- openssh/kex.c.fips 2015-06-24 12:00:58.730242500 +0200 ++++ openssh/kex.c 2015-06-24 12:00:58.737242482 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL @@ -165,7 +121,7 @@ diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c #endif #include "ssh2.h" -@@ -107,6 +108,25 @@ static const struct kexalg kexalgs[] = { +@@ -108,6 +109,25 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; @@ -191,7 +147,7 @@ diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c char * kex_alg_list(char sep) { -@@ -134,7 +154,7 @@ kex_alg_by_name(const char *name) +@@ -135,7 +155,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -200,7 +156,7 @@ diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -160,7 +180,10 @@ kex_names_valid(const char *names) +@@ -161,7 +181,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -212,54 +168,47 @@ diff -up openssh-6.8p1/kex.c.fips openssh-6.8p1/kex.c free(s); return 0; } -diff -up openssh-6.8p1/kexgexc.c.fips openssh-6.8p1/kexgexc.c ---- openssh-6.8p1/kexgexc.c.fips 2015-03-19 13:14:22.196212223 +0100 -+++ openssh-6.8p1/kexgexc.c 2015-03-19 13:15:11.462117016 +0100 -@@ -28,6 +28,8 @@ +diff -up openssh/kexgexc.c.fips openssh/kexgexc.c +--- openssh/kexgexc.c.fips 2015-06-24 12:00:58.737242482 +0200 ++++ openssh/kexgexc.c 2015-06-24 12:02:26.996015709 +0200 +@@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL +#include -+ + #include #include - #include -@@ -62,7 +64,7 @@ kexgex_client(struct ssh *ssh) +@@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh) nbits = dh_estimate(kex->dh_need * 8); - kex->min = DH_GRP_MIN; + kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; kex->max = DH_GRP_MAX; + kex->nbits = nbits; + if (datafellows & SSH_BUG_DHGEX_LARGE) +diff -up openssh/kexgexs.c.fips openssh/kexgexs.c +--- openssh/kexgexs.c.fips 2015-06-24 12:00:58.738242479 +0200 ++++ openssh/kexgexs.c 2015-06-24 13:48:23.735320199 +0200 +@@ -81,11 +81,11 @@ input_kex_dh_gex_request(int type, u_int + (r = sshpkt_get_end(ssh)) != 0) + goto out; + kex->nbits = nbits; +- kex->min = min; ++ kex->min = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + kex->max = max; +- min = MAX(DH_GRP_MIN, min); ++ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); +- nbits = MAX(DH_GRP_MIN, nbits); ++ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); - /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. -diff -up openssh-6.8p1/kexgexs.c.fips openssh-6.8p1/kexgexs.c ---- openssh-6.8p1/kexgexs.c.fips 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/kexgexs.c 2015-03-19 13:14:22.231212155 +0100 -@@ -87,9 +87,9 @@ input_kex_dh_gex_request(int type, u_int - kex->nbits = nbits; - kex->min = min; - kex->max = max; -- min = MAX(DH_GRP_MIN, min); -+ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); -- nbits = MAX(DH_GRP_MIN, nbits); -+ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); - nbits = MIN(DH_GRP_MAX, nbits); - break; - case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: -@@ -99,7 +99,7 @@ input_kex_dh_gex_request(int type, u_int - goto out; - kex->nbits = nbits; - /* unused for old GEX */ -- kex->min = min = DH_GRP_MIN; -+ kex->min = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - kex->max = max = DH_GRP_MAX; - break; - default: -diff -up openssh-6.8p1/mac.c.fips openssh-6.8p1/mac.c ---- openssh-6.8p1/mac.c.fips 2015-03-19 13:14:22.224212169 +0100 -+++ openssh-6.8p1/mac.c 2015-03-19 13:14:22.231212155 +0100 + if (kex->max < kex->min || kex->nbits < kex->min || +diff -up openssh/mac.c.fips openssh/mac.c +--- openssh/mac.c.fips 2015-06-24 12:00:58.731242497 +0200 ++++ openssh/mac.c 2015-06-24 12:00:58.738242479 +0200 @@ -27,6 +27,8 @@ #include @@ -321,10 +270,54 @@ diff -up openssh-6.8p1/mac.c.fips openssh-6.8p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-6.8p1/myproposal.h.fips openssh-6.8p1/myproposal.h ---- openssh-6.8p1/myproposal.h.fips 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/myproposal.h 2015-03-19 13:14:22.231212155 +0100 -@@ -140,6 +140,28 @@ +diff -up openssh/Makefile.in.fips openssh/Makefile.in +--- openssh/Makefile.in.fips 2015-06-24 12:00:58.731242497 +0200 ++++ openssh/Makefile.in 2015-06-24 12:00:58.736242484 +0200 +@@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) + $(RANLIB) $@ + + ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) +- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) ++ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) + + sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) +- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) ++ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + + ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o +- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o +- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o +- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o +- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +@@ -204,7 +204,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a + $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o +- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) ++ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +diff -up openssh/myproposal.h.fips openssh/myproposal.h +--- openssh/myproposal.h.fips 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/myproposal.h 2015-06-24 12:00:58.738242479 +0200 +@@ -143,6 +143,28 @@ "hmac-sha1-96," \ "hmac-md5-96" @@ -353,9 +346,36 @@ diff -up openssh-6.8p1/myproposal.h.fips openssh-6.8p1/myproposal.h #else #define KEX_SERVER_KEX \ -diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c ---- openssh-6.8p1/ssh.c.fips 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/ssh.c 2015-03-19 13:14:22.232212153 +0100 +diff -up openssh/servconf.c.fips openssh/servconf.c +--- openssh/servconf.c.fips 2015-06-24 12:00:58.726242510 +0200 ++++ openssh/servconf.c 2015-06-24 13:49:40.164085648 +0200 +@@ -2319,8 +2319,10 @@ dump_config(ServerOptions *o) + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); + dump_cfg_string(sXAuthLocation, o->xauth_location); +- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); +- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); ++ dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : FIPS_mode() ++ ? KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT); ++ dump_cfg_string(sMacs, o->macs ? o->macs : FIPS_mode() ++ ? KEX_FIPS_MAC : KEX_SERVER_MAC); + 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); +@@ -2335,8 +2337,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); + dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); + dump_cfg_string(sHostKeyAgent, o->host_key_agent); +- dump_cfg_string(sKexAlgorithms, +- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); ++ dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : ++ FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); + dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? + o->hostbased_key_types : KEX_DEFAULT_PK_ALG); + dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? +diff -up openssh/ssh.c.fips openssh/ssh.c +--- openssh/ssh.c.fips 2015-06-23 02:34:47.000000000 +0200 ++++ openssh/ssh.c 2015-06-24 12:00:58.738242479 +0200 @@ -75,6 +75,8 @@ #include #include @@ -365,7 +385,7 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -523,6 +525,14 @@ main(int ac, char **av) +@@ -521,6 +523,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -380,7 +400,7 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -600,6 +610,9 @@ main(int ac, char **av) +@@ -598,6 +608,9 @@ main(int ac, char **av) "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -390,7 +410,7 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c options.protocol = SSH_PROTO_1; break; case '2': -@@ -941,7 +954,6 @@ main(int ac, char **av) +@@ -939,7 +952,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -398,7 +418,7 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c ERR_load_crypto_strings(); #endif -@@ -1115,6 +1127,10 @@ main(int ac, char **av) +@@ -1113,6 +1125,10 @@ main(int ac, char **av) seed_rng(); @@ -409,7 +429,7 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1192,6 +1208,12 @@ main(int ac, char **av) +@@ -1190,6 +1206,12 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; @@ -422,9 +442,9 @@ diff -up openssh-6.8p1/ssh.c.fips openssh-6.8p1/ssh.c /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff -up openssh-6.8p1/sshconnect2.c.fips openssh-6.8p1/sshconnect2.c ---- openssh-6.8p1/sshconnect2.c.fips 2015-03-19 13:14:22.188212238 +0100 -+++ openssh-6.8p1/sshconnect2.c 2015-03-19 13:14:22.232212153 +0100 +diff -up openssh/sshconnect2.c.fips openssh/sshconnect2.c +--- openssh/sshconnect2.c.fips 2015-06-24 12:00:58.698242582 +0200 ++++ openssh/sshconnect2.c 2015-06-24 12:00:58.739242477 +0200 @@ -46,6 +46,8 @@ #include #endif @@ -510,9 +530,9 @@ diff -up openssh-6.8p1/sshconnect2.c.fips openssh-6.8p1/sshconnect2.c #ifdef GSSAPI /* If we've got GSSAPI algorithms, then we also support the * 'null' hostkey, as a last resort */ -diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.fips 2015-03-19 13:14:22.226212165 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-19 13:14:22.232212153 +0100 +diff -up openssh/sshd.c.fips openssh/sshd.c +--- openssh/sshd.c.fips 2015-06-24 12:00:58.734242489 +0200 ++++ openssh/sshd.c 2015-06-24 12:00:58.739242477 +0200 @@ -66,6 +66,7 @@ #include #include @@ -530,7 +550,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1543,6 +1546,18 @@ main(int ac, char **av) +@@ -1548,6 +1551,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -549,7 +569,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1694,7 +1709,7 @@ main(int ac, char **av) +@@ -1700,7 +1715,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -558,7 +578,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1890,6 +1905,10 @@ main(int ac, char **av) +@@ -1901,6 +1916,10 @@ main(int ac, char **av) sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); free(fp); } @@ -569,7 +589,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; -@@ -2058,6 +2077,10 @@ main(int ac, char **av) +@@ -2069,6 +2088,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); @@ -580,7 +600,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2642,6 +2665,9 @@ do_ssh2_kex(void) +@@ -2654,6 +2677,9 @@ do_ssh2_kex(void) if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; @@ -590,7 +610,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c } myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2651,6 +2677,9 @@ do_ssh2_kex(void) +@@ -2663,6 +2689,9 @@ do_ssh2_kex(void) if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; @@ -600,7 +620,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c } if (options.compression == COMP_NONE) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = -@@ -2661,6 +2690,8 @@ do_ssh2_kex(void) +@@ -2673,6 +2702,8 @@ do_ssh2_kex(void) } if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; @@ -609,7 +629,7 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( myproposal[PROPOSAL_KEX_ALGS]); -@@ -2687,10 +2718,14 @@ do_ssh2_kex(void) +@@ -2699,10 +2730,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -628,9 +648,9 @@ diff -up openssh-6.8p1/sshd.c.fips openssh-6.8p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-6.8p1/sshkey.c.fips openssh-6.8p1/sshkey.c ---- openssh-6.8p1/sshkey.c.fips 2015-03-19 13:14:22.227212163 +0100 -+++ openssh-6.8p1/sshkey.c 2015-03-19 13:14:22.233212151 +0100 +diff -up openssh/sshkey.c.fips openssh/sshkey.c +--- openssh/sshkey.c.fips 2015-06-24 12:00:58.735242487 +0200 ++++ openssh/sshkey.c 2015-06-24 12:00:58.740242474 +0200 @@ -35,6 +35,7 @@ #include #include @@ -639,7 +659,7 @@ diff -up openssh-6.8p1/sshkey.c.fips openssh-6.8p1/sshkey.c #endif #include "crypto_api.h" -@@ -1562,6 +1563,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1586,6 +1587,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -648,30 +668,3 @@ diff -up openssh-6.8p1/sshkey.c.fips openssh-6.8p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff -up openssh-6.8p1/servconf.c.fips openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.fips 2015-03-19 13:14:22.210212196 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-19 13:14:22.233212151 +0100 -@@ -2226,8 +2226,10 @@ dump_config(ServerOptions *o) - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); - dump_cfg_string(sXAuthLocation, o->xauth_location); -- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); -- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); -+ dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : FIPS_mode() -+ ? KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT); -+ dump_cfg_string(sMacs, o->macs ? o->macs : FIPS_mode() -+ ? KEX_FIPS_MAC : KEX_SERVER_MAC); - dump_cfg_string(sBanner, o->banner); - dump_cfg_string(sForceCommand, o->adm_forced_command); - dump_cfg_string(sChrootDirectory, o->chroot_directory); -@@ -2240,8 +2242,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); - dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); - dump_cfg_string(sHostKeyAgent, o->host_key_agent); -- dump_cfg_string(sKexAlgorithms, -- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); -+ dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : -+ FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); - dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? - o->hostbased_key_types : KEX_DEFAULT_PK_ALG); - dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index 296e7ea..a555579 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -1,7 +1,7 @@ diff -up openssh-6.8p1/HOWTO.ldap-keys.ldap openssh-6.8p1/HOWTO.ldap-keys --- openssh-6.8p1/HOWTO.ldap-keys.ldap 2015-03-18 11:11:29.029801467 +0100 +++ openssh-6.8p1/HOWTO.ldap-keys 2015-03-18 11:11:29.029801467 +0100 -@@ -0,0 +1,119 @@ +@@ -0,0 +1,122 @@ + +HOW TO START + @@ -49,6 +49,9 @@ diff -up openssh-6.8p1/HOWTO.ldap-keys.ldap openssh-6.8p1/HOWTO.ldap-keys + * There are some debug options + * Example + /usr/libexec/openssh -s -f /etc/ldap.conf -w -d >> /tmp/ldapdebuglog.txt ++7) Configure SELinux boolean which allows ldap-helper to bind ldap server ++ Run this command ++ # setsebool -P authlogin_nsswitch_use_ldap on + +HOW TO MIGRATE FROM LPK + @@ -1739,7 +1742,7 @@ diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c + len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d", + (options.ssl == 0) ? "" : "s", options.host, options.port); + options.uri[MAXURILEN - 1] = 0; -+ options.uri = xrealloc (options.uri, len + 1, 1); ++ options.uri = xreallocarray(options.uri, len + 1, 1); + } + if (options.binddn == NULL) + options.binddn = ""; @@ -2668,3 +2671,51 @@ diff -up openssh-6.8p1/ssh-ldap.conf.5.ldap openssh-6.8p1/ssh-ldap.conf.5 +OpenSSH 5.5 + PKA-LDAP . +.Sh AUTHORS +.An Jan F. Chadima Aq jchadima@redhat.com +diff --git a/openssh-lpk-openldap.ldif b/openssh-lpk-openldap.ldif +new file mode 100644 +index 0000000..9adf4b8 +--- /dev/null ++++ b/openssh-lpk-openldap.ldif +@@ -0,0 +1,19 @@ ++# ++# LDAP Public Key Patch schema for use with openssh-ldappubkey ++# useful with PKA-LDAP also ++# ++# Author: Eric AUGE ++# ++# LDIF for openLDAP Directory Server. ++# Based on the original schema, modified by Jakub Jelen. ++# ++ ++dn: cn=openssh-lpk,cn=schema,cn=config ++objectClass: olcSchemaConfig ++cn: openssh-lpk ++olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 ++ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' ++ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ++olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 ++ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' ++ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) +diff --git a/openssh-lpk-sun.ldif b/openssh-lpk-sun.ldif +new file mode 100644 +index 0000000..9adf4b8 +--- /dev/null ++++ b/openssh-lpk-sun.ldif +@@ -0,0 +1,17 @@ ++# ++# LDAP Public Key Patch schema for use with openssh-ldappubkey ++# useful with PKA-LDAP also ++# ++# Author: Eric AUGE ++# ++# LDIF for Sun Directory Server. ++# Based on the original schema, modified by Jakub Jelen. ++# ++ ++dn: cn=schema ++attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 ++ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' ++ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ++objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 ++ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' ++ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) diff --git a/openssh-6.7p1-seccomp-aarch64.patch b/openssh-6.7p1-seccomp-aarch64.patch index 4285bd9..6e8c3b8 100644 --- a/openssh-6.7p1-seccomp-aarch64.patch +++ b/openssh-6.7p1-seccomp-aarch64.patch @@ -1,66 +1,14 @@ -diff --git a/configure.ac b/configure.ac -index 4065d0e..d59ad44 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - i*86-*) - seccomp_audit_arch=AUDIT_ARCH_I386 - ;; -- arm*-*) -+ aarch64*-*) -+ seccomp_audit_arch=AUDIT_ARCH_AARCH64 -+ ;; -+ arm*-*) - seccomp_audit_arch=AUDIT_ARCH_ARM -- ;; -+ ;; - esac - if test "x$seccomp_audit_arch" != "x" ; then - AC_MSG_RESULT(["$seccomp_audit_arch"]) -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 095b04a..52f6810 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = { - /* Load the syscall number for checking. */ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, - offsetof(struct seccomp_data, nr)), -- SC_DENY(open, EACCES), -- SC_DENY(stat, EACCES), -+ SC_DENY(openat, EACCES), -+#ifdef __NR_open -+ SC_DENY(open, EACCES), /* not on AArch64 */ -+#endif -+#ifdef __NR_fstat -+ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ -+#endif -+#if defined(__NR_stat64) && defined(__NR_fstat64) -+ SC_DENY(stat64, EACCES), /* ix86, arm */ -+ SC_DENY(fstat64, EACCES), -+#endif -+#ifdef __NR_newfstatat -+ SC_DENY(newfstatat, EACCES), /* Aarch64 */ -+#endif - SC_ALLOW(getpid), - SC_ALLOW(gettimeofday), - SC_ALLOW(clock_gettime), -@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = { - SC_ALLOW(shutdown), - #endif - SC_ALLOW(brk), -+#ifdef __NR_poll /* not on AArch64 */ - SC_ALLOW(poll), -+#endif +diff -up openssh/configure.ac.seccomp openssh/configure.ac +diff -up openssh/sandbox-seccomp-filter.c.seccomp openssh/sandbox-seccomp-filter.c +--- openssh/sandbox-seccomp-filter.c.seccomp 2015-06-24 11:45:44.001581471 +0200 ++++ openssh/sandbox-seccomp-filter.c 2015-06-24 11:51:54.032635297 +0200 +@@ -165,6 +165,9 @@ static const struct sock_filter preauth_ #ifdef __NR__newselect SC_ALLOW(_newselect), - #else -+#ifdef __NR_select /* not on AArch64 */ - SC_ALLOW(select), #endif +#ifdef __NR_pselect6 /* AArch64 */ + SC_ALLOW(pselect6), +#endif -+#endif - SC_ALLOW(madvise), - #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ - SC_ALLOW(mmap2), + #ifdef __NR_poll + SC_ALLOW(poll), + #endif diff --git a/openssh-6.7p1-sshdT-output.patch b/openssh-6.7p1-sshdT-output.patch deleted file mode 100644 index aa09346..0000000 --- a/openssh-6.7p1-sshdT-output.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff -up openssh-6.8p1/servconf.c.sshdt openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.sshdt 2015-03-18 13:07:24.457858235 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 13:09:27.253557396 +0100 -@@ -2118,6 +2118,8 @@ dump_cfg_strarray_oneline(ServerOpCodes - { - u_int i; - -+ if (count <= 0) -+ return; - printf("%s", lookup_opcode_name(code)); - for (i = 0; i < count; i++) - printf(" %s", vals[i]); -@@ -2156,7 +2158,7 @@ dump_config(ServerOptions *o) - - /* integer arguments */ - #ifdef USE_PAM -- dump_cfg_int(sUsePAM, o->use_pam); -+ dump_cfg_fmtint(sUsePAM, o->use_pam); - #endif - dump_cfg_int(sServerKeyBits, o->server_key_bits); - dump_cfg_int(sLoginGraceTime, o->login_grace_time); -@@ -2166,6 +2168,7 @@ dump_config(ServerOptions *o) - dump_cfg_int(sMaxSessions, o->max_sessions); - dump_cfg_int(sClientAliveInterval, o->client_alive_interval); - dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); -+ dump_cfg_int(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); - - /* formatted integer arguments */ - dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); -@@ -2213,6 +2216,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); -+ dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); - dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); -@@ -2231,7 +2235,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sRevokedKeys, o->revoked_keys_file); - dump_cfg_string(sAuthorizedPrincipalsFile, - o->authorized_principals_file); -- dump_cfg_string(sVersionAddendum, o->version_addendum); -+ dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' -+ ? "none" : o->version_addendum); - dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); - dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); - dump_cfg_string(sHostKeyAgent, o->host_key_agent); -@@ -2251,7 +2256,7 @@ dump_config(ServerOptions *o) - o->authorized_keys_files); - dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, - o->host_key_files); -- dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, -+ dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, - o->host_cert_files); - dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); - dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); diff --git a/openssh-6.8p1-880575.patch b/openssh-6.8p1-880575.patch deleted file mode 100644 index 9936282..0000000 --- a/openssh-6.8p1-880575.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- openssh-6.8p1/authfile.c.orig 2015-03-26 09:59:06.646924879 +0100 -+++ openssh-6.8p1/authfile.c 2015-03-26 09:59:19.310905998 +0100 -@@ -194,7 +194,7 @@ - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("Permissions 0%3.3o for '%s' are too open.", - (u_int)st.st_mode & 0777, filename); -- error("It is recommended that your private key files are NOT accessible by others."); -+ error("It is required that your private key files are NOT accessible by others."); - error("This private key will be ignored."); - return SSH_ERR_KEY_BAD_PERMISSIONS; - } diff --git a/openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch b/openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch similarity index 59% rename from openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch rename to openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch index f6997a2..358986b 100644 --- a/openssh-6.7p1-fix-ssh-copy-id-on-non-sh-shell.patch +++ b/openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch @@ -2,15 +2,14 @@ diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index 8e1091c..4bba5d6 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id -@@ -274,9 +274,9 @@ case "$REMOTE_VERSION" in +@@ -274,9 +274,7 @@ case "$REMOTE_VERSION" in populate_new_ids 0 fi [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " - umask 077 ; -+ exec sh -c 'umask 077 ; - mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; ++ exec sh -c 'umask 077; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1; if type restorecon >/dev/null 2>&1; then restorecon -F .ssh .ssh/authorized_keys; fi'" \ +- mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; - if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ -+ if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ || exit 1 ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) ;; diff --git a/openssh-6.8p1-memory-problems.patch b/openssh-6.8p1-memory-problems.patch new file mode 100644 index 0000000..db21660 --- /dev/null +++ b/openssh-6.8p1-memory-problems.patch @@ -0,0 +1,25 @@ +diff --git a/servconf.c b/servconf.c +index ad5869b..0255ed3 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1910,6 +1910,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + dst->n = src->n; \ + } while (0) + ++ u_int i; ++ + M_CP_INTOPT(password_authentication); + M_CP_INTOPT(gss_authentication); + M_CP_INTOPT(rsa_authentication); +@@ -1947,8 +1949,10 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + } while(0) + #define M_CP_STRARRAYOPT(n, num_n) do {\ + if (src->num_n != 0) { \ ++ for (i = 0; i < dst->num_n; i++) \ ++ free(dst->n[i]); \ + for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ +- dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ ++ dst->n[dst->num_n] = src->n[dst->num_n]; \ + } \ + } while(0) + diff --git a/openssh-6.8p1-sshdT-output.patch b/openssh-6.8p1-sshdT-output.patch new file mode 100644 index 0000000..7a843e7 --- /dev/null +++ b/openssh-6.8p1-sshdT-output.patch @@ -0,0 +1,27 @@ +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 ? o->ciphers : KEX_SERVER_ENCRYPT); + dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); +- 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); +diff -up openssh/ssh.1.sshdt openssh/ssh.1 +--- openssh/ssh.1.sshdt 2015-06-24 11:42:19.565102807 +0200 ++++ openssh/ssh.1 2015-06-24 11:42:29.042078701 +0200 +@@ -441,7 +441,11 @@ For full details of the options listed b + .It GatewayPorts + .It GlobalKnownHostsFile + .It GSSAPIAuthentication ++.It GSSAPIKeyExchange ++.It GSSAPIClientIdentity + .It GSSAPIDelegateCredentials ++.It GSSAPIRenewalForcesRekey ++.It GSSAPITrustDNS + .It HashKnownHosts + .It Host + .It HostbasedAuthentication diff --git a/openssh-6.8p1-gsissh.patch b/openssh-6.9p1-gsissh.patch similarity index 90% rename from openssh-6.8p1-gsissh.patch rename to openssh-6.9p1-gsissh.patch index 2ffe24a..974a1de 100644 --- a/openssh-6.8p1-gsissh.patch +++ b/openssh-6.9p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-6.8p1.orig/auth2.c openssh-6.8p1/auth2.c ---- openssh-6.8p1.orig/auth2.c 2015-04-13 20:23:30.749419514 +0200 -+++ openssh-6.8p1/auth2.c 2015-04-13 20:24:30.206740480 +0200 +diff -Nur openssh-6.9p1.orig/auth2.c openssh-6.9p1/auth2.c +--- openssh-6.9p1.orig/auth2.c 2015-07-05 06:20:20.854038226 +0200 ++++ openssh-6.9p1/auth2.c 2015-07-05 06:32:05.325048953 +0200 @@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -120,9 +120,9 @@ diff -Nur openssh-6.8p1.orig/auth2.c openssh-6.8p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-6.8p1.orig/auth2-gss.c openssh-6.8p1/auth2-gss.c ---- openssh-6.8p1.orig/auth2-gss.c 2015-04-13 20:23:30.664420485 +0200 -+++ openssh-6.8p1/auth2-gss.c 2015-04-13 20:31:12.831142116 +0200 +diff -Nur openssh-6.9p1.orig/auth2-gss.c openssh-6.9p1/auth2-gss.c +--- openssh-6.9p1.orig/auth2-gss.c 2015-07-05 06:20:20.757037262 +0200 ++++ openssh-6.9p1/auth2-gss.c 2015-07-05 06:32:05.326048963 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -303,9 +303,9 @@ diff -Nur openssh-6.8p1.orig/auth2-gss.c openssh-6.8p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-6.8p1.orig/auth.c openssh-6.8p1/auth.c ---- openssh-6.8p1.orig/auth.c 2015-04-13 20:23:30.748419526 +0200 -+++ openssh-6.8p1/auth.c 2015-04-13 20:24:30.208740457 +0200 +diff -Nur openssh-6.9p1.orig/auth.c openssh-6.9p1/auth.c +--- openssh-6.9p1.orig/auth.c 2015-07-05 06:20:20.855038236 +0200 ++++ openssh-6.9p1/auth.c 2015-07-05 06:32:05.327048973 +0200 @@ -75,6 +75,9 @@ #include "ssherr.h" #include "compat.h" @@ -350,7 +350,7 @@ diff -Nur openssh-6.8p1.orig/auth.c openssh-6.8p1/auth.c } -@@ -620,6 +641,10 @@ +@@ -619,6 +640,10 @@ #endif pw = getpwnam(user); @@ -361,7 +361,7 @@ diff -Nur openssh-6.8p1.orig/auth.c openssh-6.8p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -639,7 +664,8 @@ +@@ -638,7 +663,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -371,9 +371,9 @@ diff -Nur openssh-6.8p1.orig/auth.c openssh-6.8p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-6.8p1.orig/auth-pam.c openssh-6.8p1/auth-pam.c ---- openssh-6.8p1.orig/auth-pam.c 2015-04-13 20:23:30.769419286 +0200 -+++ openssh-6.8p1/auth-pam.c 2015-04-14 08:07:16.092353124 +0200 +diff -Nur openssh-6.9p1.orig/auth-pam.c openssh-6.9p1/auth-pam.c +--- openssh-6.9p1.orig/auth-pam.c 2015-07-05 06:20:20.874038425 +0200 ++++ openssh-6.9p1/auth-pam.c 2015-07-05 06:32:05.328048983 +0200 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -524,9 +524,9 @@ diff -Nur openssh-6.8p1.orig/auth-pam.c openssh-6.8p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-6.8p1.orig/auth-pam.h openssh-6.8p1/auth-pam.h ---- openssh-6.8p1.orig/auth-pam.h 2015-04-13 20:23:30.590421330 +0200 -+++ openssh-6.8p1/auth-pam.h 2015-04-13 20:24:30.209740445 +0200 +diff -Nur openssh-6.9p1.orig/auth-pam.h openssh-6.9p1/auth-pam.h +--- openssh-6.9p1.orig/auth-pam.h 2015-07-05 06:20:20.669036387 +0200 ++++ openssh-6.9p1/auth-pam.h 2015-07-05 06:32:05.328048983 +0200 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -534,9 +534,9 @@ diff -Nur openssh-6.8p1.orig/auth-pam.h openssh-6.8p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-6.8p1.orig/canohost.c openssh-6.8p1/canohost.c ---- openssh-6.8p1.orig/canohost.c 2015-04-13 20:23:30.694420142 +0200 -+++ openssh-6.8p1/canohost.c 2015-04-13 20:30:24.391695342 +0200 +diff -Nur openssh-6.9p1.orig/canohost.c openssh-6.9p1/canohost.c +--- openssh-6.9p1.orig/canohost.c 2015-07-05 06:20:20.795037639 +0200 ++++ openssh-6.9p1/canohost.c 2015-07-05 06:32:05.329048993 +0200 @@ -17,6 +17,7 @@ #include #include @@ -579,9 +579,9 @@ diff -Nur openssh-6.8p1.orig/canohost.c openssh-6.8p1/canohost.c + } + } +} -diff -Nur openssh-6.8p1.orig/canohost.h openssh-6.8p1/canohost.h ---- openssh-6.8p1.orig/canohost.h 2015-04-13 20:23:30.695420131 +0200 -+++ openssh-6.8p1/canohost.h 2015-04-13 20:24:30.210740434 +0200 +diff -Nur openssh-6.9p1.orig/canohost.h openssh-6.9p1/canohost.h +--- openssh-6.9p1.orig/canohost.h 2015-07-05 06:20:20.795037639 +0200 ++++ openssh-6.9p1/canohost.h 2015-07-05 06:32:05.329048993 +0200 @@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -589,10 +589,10 @@ diff -Nur openssh-6.8p1.orig/canohost.h openssh-6.8p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-6.8p1.orig/configure.ac openssh-6.8p1/configure.ac ---- openssh-6.8p1.orig/configure.ac 2015-04-13 20:23:30.736419663 +0200 -+++ openssh-6.8p1/configure.ac 2015-04-13 20:24:30.211740422 +0200 -@@ -4244,6 +4244,14 @@ +diff -Nur openssh-6.9p1.orig/configure.ac openssh-6.9p1/configure.ac +--- openssh-6.9p1.orig/configure.ac 2015-07-05 06:20:20.833038017 +0200 ++++ openssh-6.9p1/configure.ac 2015-07-05 06:32:05.331049013 +0200 +@@ -4249,6 +4249,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -607,7 +607,7 @@ diff -Nur openssh-6.8p1.orig/configure.ac openssh-6.8p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4283,6 +4291,50 @@ +@@ -4288,6 +4296,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -658,10 +658,10 @@ diff -Nur openssh-6.8p1.orig/configure.ac openssh-6.8p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-6.8p1.orig/gss-genr.c openssh-6.8p1/gss-genr.c ---- openssh-6.8p1.orig/gss-genr.c 2015-04-13 20:23:30.666420462 +0200 -+++ openssh-6.8p1/gss-genr.c 2015-04-13 20:24:30.212740411 +0200 -@@ -39,6 +39,7 @@ +diff -Nur openssh-6.9p1.orig/gss-genr.c openssh-6.9p1/gss-genr.c +--- openssh-6.9p1.orig/gss-genr.c 2015-07-05 06:20:20.760037292 +0200 ++++ openssh-6.9p1/gss-genr.c 2015-07-05 06:32:05.332049022 +0200 +@@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" #include "log.h" @@ -669,7 +669,7 @@ diff -Nur openssh-6.8p1.orig/gss-genr.c openssh-6.8p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -368,9 +369,18 @@ +@@ -369,9 +370,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -689,7 +689,7 @@ diff -Nur openssh-6.8p1.orig/gss-genr.c openssh-6.8p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -378,6 +388,7 @@ +@@ -379,6 +389,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -697,9 +697,9 @@ diff -Nur openssh-6.8p1.orig/gss-genr.c openssh-6.8p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-6.8p1.orig/gss-serv.c openssh-6.8p1/gss-serv.c ---- openssh-6.8p1.orig/gss-serv.c 2015-04-13 20:23:30.667420451 +0200 -+++ openssh-6.8p1/gss-serv.c 2015-04-13 20:24:30.214740388 +0200 +diff -Nur openssh-6.9p1.orig/gss-serv.c openssh-6.9p1/gss-serv.c +--- openssh-6.9p1.orig/gss-serv.c 2015-07-05 06:20:20.760037292 +0200 ++++ openssh-6.9p1/gss-serv.c 2015-07-05 06:32:05.333049032 +0200 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -713,7 +713,7 @@ diff -Nur openssh-6.8p1.orig/gss-serv.c openssh-6.8p1/gss-serv.c 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}, 0, 0}; +- GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, {NULL, NULL, NULL}, 0, 0}; + GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, + GSS_C_NO_CONTEXT, 0, 0}; @@ -938,9 +938,9 @@ diff -Nur openssh-6.8p1.orig/gss-serv.c openssh-6.8p1/gss-serv.c +} + #endif -diff -Nur openssh-6.8p1.orig/gss-serv-gsi.c openssh-6.8p1/gss-serv-gsi.c ---- openssh-6.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.8p1/gss-serv-gsi.c 2015-04-13 23:54:37.138628621 +0200 +diff -Nur openssh-6.9p1.orig/gss-serv-gsi.c openssh-6.9p1/gss-serv-gsi.c +--- openssh-6.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.9p1/gss-serv-gsi.c 2015-07-05 06:32:05.334049042 +0200 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1181,9 +1181,9 @@ diff -Nur openssh-6.8p1.orig/gss-serv-gsi.c openssh-6.8p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-6.8p1.orig/gss-serv-krb5.c openssh-6.8p1/gss-serv-krb5.c ---- openssh-6.8p1.orig/gss-serv-krb5.c 2015-04-13 20:23:30.722419823 +0200 -+++ openssh-6.8p1/gss-serv-krb5.c 2015-04-13 20:24:30.215740377 +0200 +diff -Nur openssh-6.9p1.orig/gss-serv-krb5.c openssh-6.9p1/gss-serv-krb5.c +--- openssh-6.9p1.orig/gss-serv-krb5.c 2015-07-05 06:20:20.827037957 +0200 ++++ openssh-6.9p1/gss-serv-krb5.c 2015-07-05 06:32:05.334049042 +0200 @@ -359,6 +359,34 @@ return found_principal; } @@ -1237,9 +1237,9 @@ diff -Nur openssh-6.8p1.orig/gss-serv-krb5.c openssh-6.8p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-6.8p1.orig/kexgsss.c openssh-6.8p1/kexgsss.c ---- openssh-6.8p1.orig/kexgsss.c 2015-04-13 20:23:30.668420439 +0200 -+++ openssh-6.8p1/kexgsss.c 2015-04-13 20:24:30.216740365 +0200 +diff -Nur openssh-6.9p1.orig/kexgsss.c openssh-6.9p1/kexgsss.c +--- openssh-6.9p1.orig/kexgsss.c 2015-07-05 06:20:20.762037311 +0200 ++++ openssh-6.9p1/kexgsss.c 2015-07-05 06:32:05.335049052 +0200 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1299,9 +1299,9 @@ diff -Nur openssh-6.8p1.orig/kexgsss.c openssh-6.8p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-6.8p1.orig/LICENSE.globus_usage openssh-6.8p1/LICENSE.globus_usage ---- openssh-6.8p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.8p1/LICENSE.globus_usage 2015-04-13 20:24:30.216740365 +0200 +diff -Nur openssh-6.9p1.orig/LICENSE.globus_usage openssh-6.9p1/LICENSE.globus_usage +--- openssh-6.9p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.9p1/LICENSE.globus_usage 2015-07-05 06:32:05.335049052 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1321,9 +1321,9 @@ diff -Nur openssh-6.8p1.orig/LICENSE.globus_usage openssh-6.8p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-6.8p1.orig/Makefile.in openssh-6.8p1/Makefile.in ---- openssh-6.8p1.orig/Makefile.in 2015-04-13 20:23:30.759419400 +0200 -+++ openssh-6.8p1/Makefile.in 2015-04-13 20:24:30.217740354 +0200 +diff -Nur openssh-6.9p1.orig/Makefile.in openssh-6.9p1/Makefile.in +--- openssh-6.9p1.orig/Makefile.in 2015-07-05 06:20:20.867038355 +0200 ++++ openssh-6.9p1/Makefile.in 2015-07-05 06:32:05.335049052 +0200 @@ -113,8 +113,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ @@ -1335,9 +1335,9 @@ diff -Nur openssh-6.8p1.orig/Makefile.in openssh-6.8p1/Makefile.in roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o -diff -Nur openssh-6.8p1.orig/misc.c openssh-6.8p1/misc.c ---- openssh-6.8p1.orig/misc.c 2015-04-13 20:23:30.719419857 +0200 -+++ openssh-6.8p1/misc.c 2015-04-13 20:24:30.218740342 +0200 +diff -Nur openssh-6.9p1.orig/misc.c openssh-6.9p1/misc.c +--- openssh-6.9p1.orig/misc.c 2015-07-05 06:20:20.825037938 +0200 ++++ openssh-6.9p1/misc.c 2015-07-05 06:32:05.336049062 +0200 @@ -160,11 +160,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1397,9 +1397,9 @@ diff -Nur openssh-6.8p1.orig/misc.c openssh-6.8p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-6.8p1.orig/misc.h openssh-6.8p1/misc.h ---- openssh-6.8p1.orig/misc.h 2015-04-13 20:23:30.698420097 +0200 -+++ openssh-6.8p1/misc.h 2015-04-13 20:24:30.218740342 +0200 +diff -Nur openssh-6.9p1.orig/misc.h openssh-6.9p1/misc.h +--- openssh-6.9p1.orig/misc.h 2015-07-05 06:20:20.799037679 +0200 ++++ openssh-6.9p1/misc.h 2015-07-05 06:32:05.336049062 +0200 @@ -61,6 +61,7 @@ void sock_set_v6only(int); @@ -1408,9 +1408,9 @@ diff -Nur openssh-6.8p1.orig/misc.h openssh-6.8p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-6.8p1.orig/monitor.c openssh-6.8p1/monitor.c ---- openssh-6.8p1.orig/monitor.c 2015-04-13 20:23:30.771419263 +0200 -+++ openssh-6.8p1/monitor.c 2015-04-13 20:24:30.220740320 +0200 +diff -Nur openssh-6.9p1.orig/monitor.c openssh-6.9p1/monitor.c +--- openssh-6.9p1.orig/monitor.c 2015-07-05 06:20:20.876038445 +0200 ++++ openssh-6.9p1/monitor.c 2015-07-05 06:32:05.338049082 +0200 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1506,7 +1506,7 @@ diff -Nur openssh-6.8p1.orig/monitor.c openssh-6.8p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2221,12 +2236,15 @@ +@@ -2225,12 +2240,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1523,7 +1523,7 @@ diff -Nur openssh-6.8p1.orig/monitor.c openssh-6.8p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2234,12 +2252,77 @@ +@@ -2238,12 +2256,77 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1602,9 +1602,9 @@ diff -Nur openssh-6.8p1.orig/monitor.c openssh-6.8p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-6.8p1.orig/monitor.h openssh-6.8p1/monitor.h ---- openssh-6.8p1.orig/monitor.h 2015-04-13 20:23:30.752419480 +0200 -+++ openssh-6.8p1/monitor.h 2015-04-13 20:24:30.221740308 +0200 +diff -Nur openssh-6.9p1.orig/monitor.h openssh-6.9p1/monitor.h +--- openssh-6.9p1.orig/monitor.h 2015-07-05 06:20:20.858038266 +0200 ++++ openssh-6.9p1/monitor.h 2015-07-05 06:32:05.339049092 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1618,10 +1618,10 @@ diff -Nur openssh-6.8p1.orig/monitor.h openssh-6.8p1/monitor.h }; struct mm_master; -diff -Nur openssh-6.8p1.orig/monitor_wrap.c openssh-6.8p1/monitor_wrap.c ---- openssh-6.8p1.orig/monitor_wrap.c 2015-04-13 20:23:30.771419263 +0200 -+++ openssh-6.8p1/monitor_wrap.c 2015-04-13 20:24:30.222740297 +0200 -@@ -1121,12 +1121,13 @@ +diff -Nur openssh-6.9p1.orig/monitor_wrap.c openssh-6.9p1/monitor_wrap.c +--- openssh-6.9p1.orig/monitor_wrap.c 2015-07-05 06:20:20.876038445 +0200 ++++ openssh-6.9p1/monitor_wrap.c 2015-07-05 06:32:05.339049092 +0200 +@@ -1122,12 +1122,13 @@ } int @@ -1636,7 +1636,7 @@ diff -Nur openssh-6.8p1.orig/monitor_wrap.c openssh-6.8p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1139,6 +1140,83 @@ +@@ -1140,6 +1141,83 @@ return (authenticated); } @@ -1720,9 +1720,9 @@ diff -Nur openssh-6.8p1.orig/monitor_wrap.c openssh-6.8p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-6.8p1.orig/monitor_wrap.h openssh-6.8p1/monitor_wrap.h ---- openssh-6.8p1.orig/monitor_wrap.h 2015-04-13 20:23:30.752419480 +0200 -+++ openssh-6.8p1/monitor_wrap.h 2015-04-13 20:24:30.223740285 +0200 +diff -Nur openssh-6.9p1.orig/monitor_wrap.h openssh-6.9p1/monitor_wrap.h +--- openssh-6.9p1.orig/monitor_wrap.h 2015-07-05 06:20:20.858038266 +0200 ++++ openssh-6.9p1/monitor_wrap.h 2015-07-05 06:32:05.340049102 +0200 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1738,9 +1738,9 @@ diff -Nur openssh-6.8p1.orig/monitor_wrap.h openssh-6.8p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-6.8p1.orig/readconf.c openssh-6.8p1/readconf.c ---- openssh-6.8p1.orig/readconf.c 2015-04-13 20:23:30.670420417 +0200 -+++ openssh-6.8p1/readconf.c 2015-04-13 20:24:30.224740274 +0200 +diff -Nur openssh-6.9p1.orig/readconf.c openssh-6.9p1/readconf.c +--- openssh-6.9p1.orig/readconf.c 2015-07-05 06:20:20.765037341 +0200 ++++ openssh-6.9p1/readconf.c 2015-07-05 06:32:05.341049112 +0200 @@ -1763,13 +1763,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1759,9 +1759,9 @@ diff -Nur openssh-6.8p1.orig/readconf.c openssh-6.8p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; if (options->password_authentication == -1) -diff -Nur openssh-6.8p1.orig/readconf.h openssh-6.8p1/readconf.h ---- openssh-6.8p1.orig/readconf.h 2015-04-13 20:23:30.670420417 +0200 -+++ openssh-6.8p1/readconf.h 2015-04-13 20:24:30.225740263 +0200 +diff -Nur openssh-6.9p1.orig/readconf.h openssh-6.9p1/readconf.h +--- openssh-6.9p1.orig/readconf.h 2015-07-05 06:20:20.765037341 +0200 ++++ openssh-6.9p1/readconf.h 2015-07-05 06:32:05.342049122 +0200 @@ -84,6 +84,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1771,10 +1771,10 @@ diff -Nur openssh-6.8p1.orig/readconf.h openssh-6.8p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c ---- openssh-6.8p1.orig/servconf.c 2015-04-13 20:23:30.772419252 +0200 -+++ openssh-6.8p1/servconf.c 2015-04-14 10:46:40.415664385 +0200 -@@ -74,6 +74,7 @@ +diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c +--- openssh-6.9p1.orig/servconf.c 2015-07-05 06:20:20.878038464 +0200 ++++ openssh-6.9p1/servconf.c 2015-07-05 06:24:25.111466911 +0200 +@@ -73,6 +73,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1782,7 +1782,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -114,9 +115,11 @@ +@@ -115,9 +116,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1794,7 +1794,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c options->gss_store_rekey = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; -@@ -160,6 +163,8 @@ +@@ -161,6 +164,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1803,7 +1803,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -186,6 +191,8 @@ +@@ -189,6 +194,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1812,7 +1812,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -274,13 +281,17 @@ +@@ -279,13 +286,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1826,13 +1826,13 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->gss_strict_acceptor == -1) - options->gss_strict_acceptor = 1; + options->gss_strict_acceptor = 0; + if (options->gsi_allow_limited_proxy == -1) + options->gsi_allow_limited_proxy = 0; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; if (options->password_authentication == -1) -@@ -388,7 +399,7 @@ +@@ -394,7 +405,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1841,7 +1841,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -409,10 +420,14 @@ +@@ -415,10 +426,14 @@ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1855,8 +1855,8 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c + sDisUsageStats, sUsageStatsTarg, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, sVersionAddendum, -@@ -436,8 +451,10 @@ + sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, +@@ -443,8 +458,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1867,13 +1867,12 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -482,16 +499,26 @@ +@@ -489,14 +506,24 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, + { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, - { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL }, +#ifdef GSI + { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL }, @@ -1888,13 +1887,12 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, - { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL }, + { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -554,6 +581,8 @@ +@@ -559,6 +586,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1903,7 +1901,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -967,6 +996,10 @@ +@@ -1013,6 +1042,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1914,7 +1912,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1200,6 +1233,10 @@ +@@ -1240,6 +1273,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1925,7 +1923,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1208,6 +1245,10 @@ +@@ -1248,6 +1285,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1936,7 +1934,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1216,6 +1257,12 @@ +@@ -1256,6 +1297,12 @@ intptr = &options->gss_store_rekey; goto parse_flag; @@ -1949,7 +1947,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1690,6 +1737,35 @@ +@@ -1730,6 +1777,35 @@ *charptr = xstrdup(arg); break; @@ -1985,7 +1983,7 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -1933,6 +2009,7 @@ +@@ -2006,6 +2082,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1993,10 +1991,10 @@ diff -Nur openssh-6.8p1.orig/servconf.c openssh-6.8p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-6.8p1.orig/servconf.h openssh-6.8p1/servconf.h ---- openssh-6.8p1.orig/servconf.h 2015-04-13 20:23:30.723419811 +0200 -+++ openssh-6.8p1/servconf.h 2015-04-13 20:24:30.228740228 +0200 -@@ -114,9 +114,12 @@ +diff -Nur openssh-6.9p1.orig/servconf.h openssh-6.9p1/servconf.h +--- openssh-6.9p1.orig/servconf.h 2015-07-05 06:20:20.829037977 +0200 ++++ openssh-6.9p1/servconf.h 2015-07-05 06:34:39.373582712 +0200 +@@ -116,9 +116,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -2006,10 +2004,10 @@ diff -Nur openssh-6.8p1.orig/servconf.h openssh-6.8p1/servconf.h int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + char *gss_creds_path; /* Use non-default credentials path */ - int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ + int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; int password_authentication; /* If true, permit password -@@ -172,6 +175,7 @@ +@@ -174,6 +177,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2017,7 +2015,7 @@ diff -Nur openssh-6.8p1.orig/servconf.h openssh-6.8p1/servconf.h int permit_tun; -@@ -180,6 +184,10 @@ +@@ -182,6 +186,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2027,11 +2025,11 @@ diff -Nur openssh-6.8p1.orig/servconf.h openssh-6.8p1/servconf.h + char *revoked_keys_file; char *trusted_user_ca_keys; - char *authorized_principals_file; -diff -Nur openssh-6.8p1.orig/ssh.1 openssh-6.8p1/ssh.1 ---- openssh-6.8p1.orig/ssh.1 2015-04-13 20:23:30.642420736 +0200 -+++ openssh-6.8p1/ssh.1 2015-04-13 20:24:30.229740217 +0200 -@@ -1298,6 +1298,18 @@ + char *authorized_keys_command; +diff -Nur openssh-6.9p1.orig/ssh.1 openssh-6.9p1/ssh.1 +--- openssh-6.9p1.orig/ssh.1 2015-07-05 06:20:20.837038057 +0200 ++++ openssh-6.9p1/ssh.1 2015-07-05 06:32:05.345049152 +0200 +@@ -1318,6 +1318,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2050,10 +2048,10 @@ diff -Nur openssh-6.8p1.orig/ssh.1 openssh-6.8p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-6.8p1.orig/ssh.c openssh-6.8p1/ssh.c ---- openssh-6.8p1.orig/ssh.c 2015-04-13 20:23:30.763419355 +0200 -+++ openssh-6.8p1/ssh.c 2015-04-13 22:10:01.137426177 +0200 -@@ -466,6 +466,32 @@ +diff -Nur openssh-6.9p1.orig/ssh.c openssh-6.9p1/ssh.c +--- openssh-6.9p1.orig/ssh.c 2015-07-05 06:20:20.868038365 +0200 ++++ openssh-6.9p1/ssh.c 2015-07-05 06:32:05.346049162 +0200 +@@ -464,6 +464,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2086,7 +2084,7 @@ diff -Nur openssh-6.8p1.orig/ssh.c openssh-6.8p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1131,8 +1157,12 @@ +@@ -1129,8 +1155,12 @@ logit("FIPS mode initialized"); } @@ -2100,9 +2098,9 @@ diff -Nur openssh-6.8p1.orig/ssh.c openssh-6.8p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-6.8p1.orig/ssh_config openssh-6.8p1/ssh_config ---- openssh-6.8p1.orig/ssh_config 2015-04-13 20:23:30.672420394 +0200 -+++ openssh-6.8p1/ssh_config 2015-04-13 20:24:30.230740205 +0200 +diff -Nur openssh-6.9p1.orig/ssh_config openssh-6.9p1/ssh_config +--- openssh-6.9p1.orig/ssh_config 2015-07-05 06:20:20.768037371 +0200 ++++ openssh-6.9p1/ssh_config 2015-07-05 06:32:05.346049162 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2118,9 +2116,9 @@ diff -Nur openssh-6.8p1.orig/ssh_config openssh-6.8p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-6.8p1.orig/ssh_config.5 openssh-6.8p1/ssh_config.5 ---- openssh-6.8p1.orig/ssh_config.5 2015-04-13 20:23:30.672420394 +0200 -+++ openssh-6.8p1/ssh_config.5 2015-04-13 20:24:30.231740194 +0200 +diff -Nur openssh-6.9p1.orig/ssh_config.5 openssh-6.9p1/ssh_config.5 +--- openssh-6.9p1.orig/ssh_config.5 2015-07-05 06:20:20.768037371 +0200 ++++ openssh-6.9p1/ssh_config.5 2015-07-05 06:32:05.347049172 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2134,9 +2132,9 @@ diff -Nur openssh-6.8p1.orig/ssh_config.5 openssh-6.8p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-6.8p1.orig/sshconnect2.c openssh-6.8p1/sshconnect2.c ---- openssh-6.8p1.orig/sshconnect2.c 2015-04-13 20:23:30.763419355 +0200 -+++ openssh-6.8p1/sshconnect2.c 2015-04-13 20:24:30.231740194 +0200 +diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c +--- openssh-6.9p1.orig/sshconnect2.c 2015-07-05 06:20:20.869038375 +0200 ++++ openssh-6.9p1/sshconnect2.c 2015-07-05 06:32:05.347049172 +0200 @@ -747,6 +747,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2198,10 +2196,10 @@ diff -Nur openssh-6.8p1.orig/sshconnect2.c openssh-6.8p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-6.8p1.orig/sshd.8 openssh-6.8p1/sshd.8 ---- openssh-6.8p1.orig/sshd.8 2015-04-13 20:23:30.727419766 +0200 -+++ openssh-6.8p1/sshd.8 2015-04-13 20:24:30.232740183 +0200 -@@ -766,6 +766,44 @@ +diff -Nur openssh-6.9p1.orig/sshd.8 openssh-6.9p1/sshd.8 +--- openssh-6.9p1.orig/sshd.8 2015-07-05 06:20:20.834038027 +0200 ++++ openssh-6.9p1/sshd.8 2015-07-05 06:32:05.348049182 +0200 +@@ -768,6 +768,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2246,9 +2244,9 @@ diff -Nur openssh-6.8p1.orig/sshd.8 openssh-6.8p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-6.8p1.orig/sshd.c openssh-6.8p1/sshd.c ---- openssh-6.8p1.orig/sshd.c 2015-04-13 20:23:30.776419206 +0200 -+++ openssh-6.8p1/sshd.c 2015-04-13 20:32:10.658481671 +0200 +diff -Nur openssh-6.9p1.orig/sshd.c openssh-6.9p1/sshd.c +--- openssh-6.9p1.orig/sshd.c 2015-07-05 06:20:20.880038484 +0200 ++++ openssh-6.9p1/sshd.c 2015-07-05 06:32:05.349049192 +0200 @@ -128,6 +128,7 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2257,7 +2255,7 @@ diff -Nur openssh-6.8p1.orig/sshd.c openssh-6.8p1/sshd.c #ifdef LIBWRAP #include -@@ -1788,6 +1789,13 @@ +@@ -1790,6 +1791,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2271,7 +2269,7 @@ diff -Nur openssh-6.8p1.orig/sshd.c openssh-6.8p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2348,7 +2356,7 @@ +@@ -2355,7 +2363,7 @@ #endif #ifdef GSSAPI @@ -2280,9 +2278,9 @@ diff -Nur openssh-6.8p1.orig/sshd.c openssh-6.8p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-6.8p1.orig/sshd_config openssh-6.8p1/sshd_config ---- openssh-6.8p1.orig/sshd_config 2015-04-13 20:23:30.723419811 +0200 -+++ openssh-6.8p1/sshd_config 2015-04-14 08:42:12.640139901 +0200 +diff -Nur openssh-6.9p1.orig/sshd_config openssh-6.9p1/sshd_config +--- openssh-6.9p1.orig/sshd_config 2015-07-05 06:20:20.850038186 +0200 ++++ openssh-6.9p1/sshd_config 2015-07-05 06:32:05.349049192 +0200 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2315,10 +2313,10 @@ diff -Nur openssh-6.8p1.orig/sshd_config openssh-6.8p1/sshd_config + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 -diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 ---- openssh-6.8p1.orig/sshd_config.5 2015-04-13 20:23:30.723419811 +0200 -+++ openssh-6.8p1/sshd_config.5 2015-04-14 07:58:57.173124634 +0200 -@@ -512,6 +512,15 @@ +diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 +--- openssh-6.9p1.orig/sshd_config.5 2015-07-05 06:20:20.850038186 +0200 ++++ openssh-6.9p1/sshd_config.5 2015-07-05 06:32:05.350049202 +0200 +@@ -564,6 +564,15 @@ See PATTERNS in .Xr ssh_config 5 for more information on patterns. @@ -2334,7 +2332,7 @@ diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: -@@ -564,6 +573,10 @@ +@@ -616,6 +625,10 @@ The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2345,7 +2343,7 @@ diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 .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. -@@ -582,6 +595,22 @@ +@@ -634,6 +647,22 @@ .Xr ksu 1 . The default is .Dq no . @@ -2366,9 +2364,9 @@ diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 +The default is +.Dq no . .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. If -@@ -1410,6 +1439,103 @@ + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -1461,6 +1490,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2471,8 +2469,8 @@ diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 +.Pp .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are - trusted to sign user certificates for authentication. -@@ -1475,6 +1601,12 @@ + trusted to sign user certificates for authentication, or +@@ -1528,6 +1654,12 @@ as a non-root user. The default is .Dq no . @@ -2485,9 +2483,9 @@ diff -Nur openssh-6.8p1.orig/sshd_config.5 openssh-6.8p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-6.8p1.orig/ssh-globus-usage.c openssh-6.8p1/ssh-globus-usage.c ---- openssh-6.8p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.8p1/ssh-globus-usage.c 2015-04-14 07:26:22.280670505 +0200 +diff -Nur openssh-6.9p1.orig/ssh-globus-usage.c openssh-6.9p1/ssh-globus-usage.c +--- openssh-6.9p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.9p1/ssh-globus-usage.c 2015-07-05 06:32:05.350049202 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2885,9 +2883,9 @@ diff -Nur openssh-6.8p1.orig/ssh-globus-usage.c openssh-6.8p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-6.8p1.orig/ssh-globus-usage.h openssh-6.8p1/ssh-globus-usage.h ---- openssh-6.8p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.8p1/ssh-globus-usage.h 2015-04-14 07:28:43.646038850 +0200 +diff -Nur openssh-6.9p1.orig/ssh-globus-usage.h openssh-6.9p1/ssh-globus-usage.h +--- openssh-6.9p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-6.9p1/ssh-globus-usage.h 2015-07-05 06:32:05.350049202 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2937,9 +2935,9 @@ diff -Nur openssh-6.8p1.orig/ssh-globus-usage.h openssh-6.8p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-6.8p1.orig/ssh-gss.h openssh-6.8p1/ssh-gss.h ---- openssh-6.8p1.orig/ssh-gss.h 2015-04-13 20:23:30.677420337 +0200 -+++ openssh-6.8p1/ssh-gss.h 2015-04-13 20:33:05.203858665 +0200 +diff -Nur openssh-6.9p1.orig/ssh-gss.h openssh-6.9p1/ssh-gss.h +--- openssh-6.9p1.orig/ssh-gss.h 2015-07-05 06:20:20.773037421 +0200 ++++ openssh-6.9p1/ssh-gss.h 2015-07-05 06:32:05.351049212 +0200 @@ -91,6 +91,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2984,11 +2982,11 @@ diff -Nur openssh-6.8p1.orig/ssh-gss.h openssh-6.8p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-6.8p1.orig/version.h openssh-6.8p1/version.h ---- openssh-6.8p1.orig/version.h 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/version.h 2015-04-14 07:47:24.569105583 +0200 +diff -Nur openssh-6.9p1.orig/version.h openssh-6.9p1/version.h +--- openssh-6.9p1.orig/version.h 2015-07-01 04:35:31.000000000 +0200 ++++ openssh-6.9p1/version.h 2015-07-05 06:32:05.351049212 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.72 2015/03/04 18:53:53 djm Exp $ */ + /* $OpenBSD: version.h,v 1.73 2015/07/01 01:55:13 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3004,7 +3002,7 @@ diff -Nur openssh-6.8p1.orig/version.h openssh-6.8p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20150323" + - #define SSH_VERSION "OpenSSH_6.8" + #define SSH_VERSION "OpenSSH_6.9" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-6.9p1-permit-root-login.patch b/openssh-6.9p1-permit-root-login.patch new file mode 100644 index 0000000..5d9df7c --- /dev/null +++ b/openssh-6.9p1-permit-root-login.patch @@ -0,0 +1,27 @@ +diff --git a/sshd_config b/sshd_config +index c9042ac..cf7d8e1 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -41,7 +41,7 @@ + # Authentication: + + #LoginGraceTime 2m +-#PermitRootLogin no ++#PermitRootLogin yes + #StrictModes yes + #MaxAuthTries 6 + #MaxSessions 10 +diff --git a/sshd_config.5 b/sshd_config.5 +index 2bc9360..d3148c2 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1093,7 +1093,7 @@ The argument must be + or + .Dq no . + The default is +-.Dq no . ++.Dq yes . + .Pp + If this option is set to + .Dq without-password , + diff --git a/sources b/sources index d5b3f7b..d719f82 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -08f72de6751acfbd0892b5f003922701 openssh-6.8p1.tar.gz +0b161c44fc31fbc6b76a6f8ae639f16f openssh-6.9p1.tar.gz From c93878a6e6dcacf649545099ae2ec0086069ca7e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 27 Jul 2015 10:50:57 +0200 Subject: [PATCH 014/146] Based on openssh-6.9p1-3.fc22 --- gsi-openssh.spec | 16 +++++-- openssh-6.7p1-audit.patch | 9 ++-- ...h-6.9p1-authentication-limits-bypass.patch | 47 +++++++++++++++++++ openssh-6.9p1-gsissh.patch | 6 +-- ...h => openssh-6.9p1-seccomp-secondary.patch | 18 +++++++ 5 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 openssh-6.9p1-authentication-limits-bypass.patch rename openssh-6.7p1-seccomp-aarch64.patch => openssh-6.9p1-seccomp-secondary.patch (53%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e3f2e5e..8fd679b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 6.9p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -154,8 +154,8 @@ Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.patch Patch922: openssh-6.8p1-sshdT-output.patch # fix ssh-copy-id on non-sh shells (#1045191) Patch923: openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch -# AArch64 has seccomp support since 3.19 kernel (#1195065) -Patch924: openssh-6.7p1-seccomp-aarch64.patch +# Seccomp support for secondary architectures (#1195065) +Patch924: openssh-6.9p1-seccomp-secondary.patch # Solve issue with ssh-copy-id and keys without trailing newline (#1093168) Patch925: openssh-6.7p1-ssh-copy-id-truncated-keys.patch # Add sftp option to force mode of created files (#1191055) @@ -165,6 +165,8 @@ Patch926: openssh-6.7p1-sftp-force-permission.patch Patch928: openssh-6.8p1-memory-problems.patch # Restore compatible default (#89216) Patch929: openssh-6.9p1-permit-root-login.patch +# authentication limits (MaxAuthTries) bypass [security] (#1245971) +Patch930: openssh-6.9p1-authentication-limits-bypass.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.9p1.patch @@ -322,6 +324,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch926 -p1 -b .sftp-force-mode %patch928 -p1 -b .memory %patch929 -p1 -b .root-login +%patch930 -p1 -b .kbd %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -387,7 +390,7 @@ fi --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ -%ifarch %{ix86} x86_64 %{arm} aarch64 +%ifarch %{ix86} x86_64 %{arm} aarch64 s390x x390 --with-sandbox=seccomp_filter \ %else --with-sandbox=rlimit \ @@ -546,8 +549,11 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Jul 27 2015 Mattias Ellert - 6.9p1-2 +- Based on openssh-6.9p1-3.fc22 + * Sun Jul 05 2015 Mattias Ellert - 6.9p1-1 -- Based on openssh-6.8p1-10.fc22 +- Based on openssh-6.9p1-1.fc22 * Wed Jun 17 2015 Fedora Release Engineering - 6.8p1-2.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild diff --git a/openssh-6.7p1-audit.patch b/openssh-6.7p1-audit.patch index b216062..59584a2 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -1356,7 +1356,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c } -@@ -2216,3 +2312,87 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -2216,3 +2312,86 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1440,7 +1440,6 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + free(fp); + buffer_clear(m); + -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ @@ -1458,7 +1457,7 @@ diff -up openssh/monitor.h.audit openssh/monitor.h + MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, + MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, + MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 ++ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124 }; @@ -1541,7 +1540,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1152,3 +1186,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1152,3 +1186,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1609,8 +1608,6 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + buffer_put_int64(&m, uid); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, -+ &m); + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ diff --git a/openssh-6.9p1-authentication-limits-bypass.patch b/openssh-6.9p1-authentication-limits-bypass.patch new file mode 100644 index 0000000..10bde94 --- /dev/null +++ b/openssh-6.9p1-authentication-limits-bypass.patch @@ -0,0 +1,47 @@ +From 5b64f85bb811246c59ebab70aed331f26ba37b18 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Sat, 18 Jul 2015 07:57:14 +0000 +Subject: upstream commit + +only query each keyboard-interactive device once per + authentication request regardless of how many times it is listed; ok markus@ + +Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1 +--- + auth2-chall.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/auth2-chall.c b/auth2-chall.c +index ddabe1a..4aff09d 100644 +--- a/auth2-chall.c ++++ b/auth2-chall.c +@@ -83,6 +83,7 @@ struct KbdintAuthctxt + void *ctxt; + KbdintDevice *device; + u_int nreq; ++ u_int devices_done; + }; + + #ifdef USE_PAM +@@ -169,11 +170,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) + if (len == 0) + break; + for (i = 0; devices[i]; i++) { +- if (!auth2_method_allowed(authctxt, ++ if ((kbdintctxt->devices_done & (1 << i)) != 0 || ++ !auth2_method_allowed(authctxt, + "keyboard-interactive", devices[i]->name)) + continue; +- if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) ++ if (strncmp(kbdintctxt->devices, devices[i]->name, ++ len) == 0) { + kbdintctxt->device = devices[i]; ++ kbdintctxt->devices_done |= 1 << i; ++ } + } + t = kbdintctxt->devices; + kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; +-- +cgit v0.11.2 + + diff --git a/openssh-6.9p1-gsissh.patch b/openssh-6.9p1-gsissh.patch index 974a1de..0244e15 100644 --- a/openssh-6.9p1-gsissh.patch +++ b/openssh-6.9p1-gsissh.patch @@ -1609,12 +1609,12 @@ diff -Nur openssh-6.9p1.orig/monitor.h openssh-6.9p1/monitor.h MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, -- MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 +- MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124 - -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125, ++ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, + MONITOR_REQ_GSSMECHS = 200, MONITOR_ANS_GSSMECHS = 201, + MONITOR_REQ_GSSLOCALNAME = 202, MONITOR_ANS_GSSLOCALNAME = 203, -+ MONITOR_REQ_GSSERR = 204, MONITOR_ANS_GSSERR = 205, ++ MONITOR_REQ_GSSERR = 204, MONITOR_ANS_GSSERR = 205 }; struct mm_master; diff --git a/openssh-6.7p1-seccomp-aarch64.patch b/openssh-6.9p1-seccomp-secondary.patch similarity index 53% rename from openssh-6.7p1-seccomp-aarch64.patch rename to openssh-6.9p1-seccomp-secondary.patch index 6e8c3b8..97e16d2 100644 --- a/openssh-6.7p1-seccomp-aarch64.patch +++ b/openssh-6.9p1-seccomp-secondary.patch @@ -12,3 +12,21 @@ diff -up openssh/sandbox-seccomp-filter.c.seccomp openssh/sandbox-seccomp-filter #ifdef __NR_poll SC_ALLOW(poll), #endif +diff --git a/configure.ac b/configure.ac +index 24378a7..0bed910 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -811,6 +811,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + aarch64*-*) + seccomp_audit_arch=AUDIT_ARCH_AARCH64 + ;; ++ s390x-*) ++ seccomp_audit_arch=AUDIT_ARCH_S390X ++ ;; ++ s390-*) ++ seccomp_audit_arch=AUDIT_ARCH_S390 ++ ;; + esac + if test "x$seccomp_audit_arch" != "x" ; then + AC_MSG_RESULT(["$seccomp_audit_arch"]) + From e2d7866367b5f1ad4b70c9310c40521b8bdc60ba Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 29 Jul 2015 10:12:11 +0200 Subject: [PATCH 015/146] Based on openssh-6.9p1-4.fc22 --- gsi-openssh.spec | 16 ++--- openssh-6.6.1p1-utf8-banner.patch | 99 +++++++++++---------------- openssh-6.7p1-fips.patch | 4 +- openssh-6.9p1-scp-progressmeter.patch | 42 ++++++++++++ 4 files changed, 92 insertions(+), 69 deletions(-) create mode 100644 openssh-6.9p1-scp-progressmeter.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 8fd679b..65f4dfe 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 6.9p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -167,6 +167,8 @@ Patch928: openssh-6.8p1-memory-problems.patch Patch929: openssh-6.9p1-permit-root-login.patch # authentication limits (MaxAuthTries) bypass [security] (#1245971) Patch930: openssh-6.9p1-authentication-limits-bypass.patch +# Handle terminal control characters in scp progressmeter (#1247204) +Patch931: openssh-6.9p1-scp-progressmeter.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.9p1.patch @@ -325,6 +327,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch928 -p1 -b .memory %patch929 -p1 -b .root-login %patch930 -p1 -b .kbd +%patch931 -p1 -b .progressmeter %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -493,14 +496,6 @@ getent passwd sshd >/dev/null || \ %postun server %systemd_postun_with_restart gsisshd.service -%triggerun server -- gsi-openssh-server < 5.8p2-1 -/usr/bin/systemd-sysv-convert --save gsisshd >/dev/null 2>&1 || : -/sbin/chkconfig --del gsisshd >/dev/null 2>&1 || : -/bin/systemctl try-restart gsisshd.service >/dev/null 2>&1 || : - -%triggerun server -- gsi-openssh-server < 5.9p1-6 -/bin/systemctl --no-reload disable gsisshd-keygen.service >/dev/null 2>&1 || : - %files %defattr(-,root,root) %{!?_licensedir:%global license %%doc} @@ -549,6 +544,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Jul 29 2015 Mattias Ellert - 6.9p1-3 +- Based on openssh-6.9p1-4.fc22 + * Mon Jul 27 2015 Mattias Ellert - 6.9p1-2 - Based on openssh-6.9p1-3.fc22 diff --git a/openssh-6.6.1p1-utf8-banner.patch b/openssh-6.6.1p1-utf8-banner.patch index 1513b6f..238c654 100644 --- a/openssh-6.6.1p1-utf8-banner.patch +++ b/openssh-6.6.1p1-utf8-banner.patch @@ -13,77 +13,24 @@ diff -up openssh-6.8p1/Makefile.in.utf8-banner openssh-6.8p1/Makefile.in diff -up openssh-6.8p1/misc.h.utf8-banner openssh-6.8p1/misc.h --- openssh-6.8p1/misc.h.utf8-banner 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/misc.h 2015-03-18 12:41:28.175713185 +0100 -@@ -135,4 +135,7 @@ char *read_passphrase(const char *, int) +@@ -135,4 +135,8 @@ char *read_passphrase(const char *, int) int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); +/* utf8_stringprep.c */ +int utf8_stringprep(const char *, char *, size_t); ++void sanitize_utf8(char *, const char *, size_t); + #endif /* _MISC_H */ diff -up openssh-6.8p1/sshconnect2.c.utf8-banner openssh-6.8p1/sshconnect2.c --- openssh-6.8p1/sshconnect2.c.utf8-banner 2015-03-18 12:41:28.161713220 +0100 +++ openssh-6.8p1/sshconnect2.c 2015-03-18 12:44:05.483317714 +0100 -@@ -33,6 +33,8 @@ - - #include - #include -+#include -+#include - #include - #include - #include -@@ -532,21 +534,51 @@ input_userauth_error(int type, u_int32_t - return 0; - } - -+/* Check whether we can display UTF-8 safely */ -+static int -+utf8_ok(void) -+{ -+ static int ret = -1; -+ char *cp; -+ -+ if (ret == -1) { -+ setlocale(LC_CTYPE, ""); -+ cp = nl_langinfo(CODESET); -+ ret = strcmp(cp, "UTF-8") == 0; -+ } -+ return ret; -+} -+ - /* ARGSUSED */ - int - input_userauth_banner(int type, u_int32_t seq, void *ctxt) - { - char *msg, *raw, *lang; -- u_int len; -+ u_int done, len; - - debug3("input_userauth_banner"); -+ - raw = packet_get_string(&len); - lang = packet_get_string(NULL); - if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { +@@ -532,7 +534,7 @@ input_userauth_error(int type, u_int32_t if (len > 65536) len = 65536; msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ - strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); -+ done = 0; -+ if (utf8_ok()) { -+ if (utf8_stringprep(raw, msg, len * 4 + 1) == 0) -+ done = 1; -+ else -+ debug2("%s: UTF8 stringprep failed", __func__); -+ } -+ /* -+ * Fallback to strnvis if UTF8 display not supported or -+ * conversion failed. -+ */ -+ if (!done) { -+ strnvis(msg, raw, len * 4 + 1, -+ VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); -+ } ++ sanitize_utf8(msg, raw, len); fprintf(stderr, "%s", msg); free(msg); } @@ -755,7 +702,7 @@ diff -up openssh-6.8p1/stringprep-tables.c.utf8-banner openssh-6.8p1/stringprep- diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringprep.c --- openssh-6.8p1/utf8_stringprep.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 +++ openssh-6.8p1/utf8_stringprep.c 2015-03-18 12:41:28.175713185 +0100 -@@ -0,0 +1,229 @@ +@@ -0,0 +1,265 @@ +/* + * Copyright (c) 2013 Damien Miller + * @@ -796,8 +743,12 @@ diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringpr +#include +#include +#include ++#include ++#include + ++#include "includes.h" +#include "misc.h" ++#include "log.h" + +struct u32_range { + u_int32_t lo, hi; /* Inclusive */ @@ -985,3 +936,35 @@ diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringpr + return 0; +} + ++/* Check whether we can display UTF-8 safely */ ++int ++utf8_ok(void) ++{ ++ static int ret = -1; ++ char *cp; ++ ++ if (ret == -1) { ++ setlocale(LC_CTYPE, ""); ++ cp = nl_langinfo(CODESET); ++ ret = strcmp(cp, "UTF-8") == 0; ++ } ++ return ret; ++} ++ ++void ++sanitize_utf8(char *target, const char *source, size_t length) ++{ ++ u_int done = 0; ++ if (utf8_ok()) { ++ if (utf8_stringprep(source, target, length * 4 + 1) == 0) ++ done = 1; ++ else ++ debug2("%s: UTF8 stringprep failed", __func__); ++ } ++ /* ++ * Fallback to strnvis if UTF8 display not supported or ++ * conversion failed. ++ */ ++ if (!done) ++ strnvis(target, source, length * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); ++} diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index 9f8b490..bd43f1c 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -284,8 +284,8 @@ diff -up openssh/Makefile.in.fips openssh/Makefile.in - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o - $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/openssh-6.9p1-scp-progressmeter.patch b/openssh-6.9p1-scp-progressmeter.patch new file mode 100644 index 0000000..c929708 --- /dev/null +++ b/openssh-6.9p1-scp-progressmeter.patch @@ -0,0 +1,42 @@ +diff --git a/progressmeter.c b/progressmeter.c +index 319b747..b54738c 100644 +--- a/progressmeter.c ++++ b/progressmeter.c +@@ -66,7 +66,8 @@ static void update_progress_meter(int); + + static time_t start; /* start progress */ + static time_t last_update; /* last progress update */ +-static const char *file; /* name of the file being transferred */ ++static char *file; /* name of the file being transferred */ ++static size_t file_len = 0; /* allocated length of file */ + static off_t start_pos; /* initial position of transfer */ + static off_t end_pos; /* ending position of transfer */ + static off_t cur_pos; /* transfer position as of last refresh */ +@@ -250,7 +251,11 @@ update_progress_meter(int ignore) + start_progress_meter(const char *f, off_t filesize, off_t *ctr) + { + start = last_update = monotime(); +- file = f; ++ if (strlen(f) > file_len) { ++ file_len = strlen(f); ++ file = realloc(file, file_len * 4 + 1); ++ } ++ sanitize_utf8(file, f, file_len); + start_pos = *ctr; + end_pos = filesize; + cur_pos = 0; +diff --git a/Makefile.in b/Makefile.in +index ac45b05..6978081 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -173,8 +173,8 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) + sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + +-scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o +- $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o ++ $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + + ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o + $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) From b6360055e2ef744eba637e2c907e4aab1bf52fcc Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 14 Aug 2015 15:24:20 +0200 Subject: [PATCH 016/146] Based on openssh-7.0p1-1.fc23 --- gsi-openssh.spec | 14 +- gsisshd-keygen.service | 2 +- openssh-6.2p1-vendor.patch | 122 +++---- openssh-6.6p1-GSSAPIEnablek5users.patch | 60 ++-- openssh-6.6p1-ctr-cavstest.patch | 4 +- openssh-6.6p1-gsskex.patch | 268 +++++++-------- openssh-6.6p1-kuserok.patch | 78 ++--- openssh-6.7p1-audit.patch | 258 +++++++------- openssh-6.7p1-fips.patch | 224 ++++++------ ...h-6.9p1-authentication-limits-bypass.patch | 47 --- openssh-6.9p1-permit-root-login.patch | 27 +- ...gsissh.patch => openssh-7.0p1-gsissh.patch | 318 +++++++++--------- sources | 2 +- 13 files changed, 665 insertions(+), 759 deletions(-) delete mode 100644 openssh-6.9p1-authentication-limits-bypass.patch rename openssh-6.9p1-gsissh.patch => openssh-7.0p1-gsissh.patch (91%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 65f4dfe..2fdde9a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 6.9p1 -%global openssh_rel 3 +%global openssh_ver 7.0p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -165,14 +165,12 @@ Patch926: openssh-6.7p1-sftp-force-permission.patch Patch928: openssh-6.8p1-memory-problems.patch # Restore compatible default (#89216) Patch929: openssh-6.9p1-permit-root-login.patch -# authentication limits (MaxAuthTries) bypass [security] (#1245971) -Patch930: openssh-6.9p1-authentication-limits-bypass.patch # Handle terminal control characters in scp progressmeter (#1247204) Patch931: openssh-6.9p1-scp-progressmeter.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-6.9p1.patch -Patch98: openssh-6.9p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch +Patch98: openssh-7.0p1-gsissh.patch License: BSD Group: Applications/Internet @@ -326,7 +324,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch926 -p1 -b .sftp-force-mode %patch928 -p1 -b .memory %patch929 -p1 -b .root-login -%patch930 -p1 -b .kbd %patch931 -p1 -b .progressmeter %patch200 -p1 -b .audit @@ -544,6 +541,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Aug 14 2015 Mattias Ellert - 7.0p1-1 +- Based on openssh-7.0p1-1.fc23 + * Wed Jul 29 2015 Mattias Ellert - 6.9p1-3 - Based on openssh-6.9p1-4.fc22 diff --git a/gsisshd-keygen.service b/gsisshd-keygen.service index a8e99a3..8382967 100644 --- a/gsisshd-keygen.service +++ b/gsisshd-keygen.service @@ -2,7 +2,7 @@ Description=gsissh Server Key Generation ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key ConditionPathExists=|!/etc/gsissh/ssh_host_ecdsa_key -ConditionPathExists=|!/etc/gsissh/ssh_host_ec25519_key +ConditionPathExists=|!/etc/gsissh/ssh_host_ed25519_key PartOf=gsisshd.service gsisshd.socket [Service] diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index cb95e5f..55353c2 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -1,7 +1,7 @@ -diff -up openssh/configure.ac.vendor openssh/configure.ac ---- openssh/configure.ac.vendor 2015-06-24 11:05:39.805679794 +0200 -+++ openssh/configure.ac 2015-06-24 11:05:39.835679719 +0200 -@@ -4751,6 +4751,12 @@ AC_ARG_WITH([lastlog], +diff -up openssh-7.0p1/configure.ac.vendor openssh-7.0p1/configure.ac +--- openssh-7.0p1/configure.ac.vendor 2015-08-12 11:14:54.102628399 +0200 ++++ openssh-7.0p1/configure.ac 2015-08-12 11:14:54.129628356 +0200 +@@ -4776,6 +4776,12 @@ AC_ARG_WITH([lastlog], fi ] ) @@ -14,7 +14,7 @@ diff -up openssh/configure.ac.vendor openssh/configure.ac dnl lastlog, [uw]tmpx? detection dnl NOTE: set the paths in the platform section to avoid the -@@ -5013,6 +5019,7 @@ echo " Translate v4 in v6 hack +@@ -5038,6 +5044,7 @@ echo " Translate v4 in v6 hack echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -22,10 +22,10 @@ diff -up openssh/configure.ac.vendor openssh/configure.ac echo "" -diff -up openssh/servconf.c.vendor openssh/servconf.c ---- openssh/servconf.c.vendor 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/servconf.c 2015-06-24 11:07:07.689460890 +0200 -@@ -147,6 +147,7 @@ initialize_server_options(ServerOptions +diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.vendor 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-12 11:15:33.201565712 +0200 +@@ -149,6 +149,7 @@ initialize_server_options(ServerOptions options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; @@ -42,16 +42,16 @@ diff -up openssh/servconf.c.vendor openssh/servconf.c if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) -@@ -397,7 +400,7 @@ typedef enum { +@@ -407,7 +410,7 @@ typedef enum { sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, - sBanner, sUseDNS, sHostbasedAuthentication, + sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, -@@ -517,6 +520,7 @@ static struct { +@@ -529,6 +532,7 @@ static struct { { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, @@ -59,7 +59,7 @@ diff -up openssh/servconf.c.vendor openssh/servconf.c { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1372,6 +1376,10 @@ process_server_config_line(ServerOptions +@@ -1389,6 +1393,10 @@ process_server_config_line(ServerOptions multistate_ptr = multistate_privsep; goto parse_multistate; @@ -70,7 +70,7 @@ diff -up openssh/servconf.c.vendor openssh/servconf.c case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -2249,6 +2257,7 @@ dump_config(ServerOptions *o) +@@ -2266,6 +2274,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); @@ -78,10 +78,10 @@ diff -up openssh/servconf.c.vendor openssh/servconf.c dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); -diff -up openssh/servconf.h.vendor openssh/servconf.h ---- openssh/servconf.h.vendor 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/servconf.h 2015-06-24 11:05:39.837679714 +0200 -@@ -154,6 +154,7 @@ typedef struct { +diff -up openssh-7.0p1/servconf.h.vendor openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.vendor 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-12 11:14:54.130628355 +0200 +@@ -155,6 +155,7 @@ typedef struct { int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ @@ -89,45 +89,12 @@ diff -up openssh/servconf.h.vendor openssh/servconf.h int use_dns; int client_alive_interval; /* * poke the client this often to -diff -up openssh-6.8p1/sshd.c.vendor openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.vendor 2015-03-18 11:17:56.669880305 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 11:17:56.697880239 +0100 -@@ -431,7 +431,7 @@ sshd_exchange_identification(int sock_in - } - - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", -- major, minor, SSH_VERSION, -+ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - *options.version_addendum == '\0' ? "" : " ", - options.version_addendum, newline); - -@@ -1737,7 +1737,8 @@ main(int ac, char **av) - exit(1); - } - -- debug("sshd version %s, %s", SSH_VERSION, -+ debug("sshd version %s, %s", -+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - #ifdef WITH_OPENSSL - SSLeay_version(SSLEAY_VERSION) - #else -diff -up openssh-6.8p1/sshd_config.vendor openssh-6.8p1/sshd_config ---- openssh-6.8p1/sshd_config.vendor 2015-03-18 11:17:56.697880239 +0100 -+++ openssh-6.8p1/sshd_config 2015-03-18 11:20:15.552550274 +0100 -@@ -119,6 +119,7 @@ UsePrivilegeSeparation sandbox # Defaul - #Compression delayed - #ClientAliveInterval 0 - #ClientAliveCountMax 3 -+#ShowPatchLevel no - #UseDNS no - #PidFile /var/run/sshd.pid - #MaxStartups 10:30:100 -diff -up openssh-6.8p1/sshd_config.0.vendor openssh-6.8p1/sshd_config.0 ---- openssh-6.8p1/sshd_config.0.vendor 2015-03-18 11:17:56.691880253 +0100 -+++ openssh-6.8p1/sshd_config.0 2015-03-18 11:17:56.697880239 +0100 -@@ -740,6 +740,11 @@ DESCRIPTION +diff -up openssh-7.0p1/sshd_config.0.vendor openssh-7.0p1/sshd_config.0 +--- openssh-7.0p1/sshd_config.0.vendor 2015-08-12 11:14:54.125628363 +0200 ++++ openssh-7.0p1/sshd_config.0 2015-08-12 11:14:54.130628355 +0200 +@@ -841,6 +841,11 @@ DESCRIPTION Defines the number of bits in the ephemeral protocol version 1 - server key. The minimum value is 512, and the default is 1024. + server key. The default and minimum value is 1024. + ShowPatchLevel + Specifies whether sshd will display the specific patch level of @@ -137,13 +104,13 @@ diff -up openssh-6.8p1/sshd_config.0.vendor openssh-6.8p1/sshd_config.0 StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. -diff -up openssh/sshd_config.5.vendor openssh/sshd_config.5 ---- openssh/sshd_config.5.vendor 2015-06-24 11:05:39.831679729 +0200 -+++ openssh/sshd_config.5 2015-06-24 11:05:39.837679714 +0200 -@@ -1344,6 +1344,13 @@ This option applies to protocol version +diff -up openssh-7.0p1/sshd_config.5.vendor openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.vendor 2015-08-12 11:14:54.125628363 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-12 11:14:54.131628353 +0200 +@@ -1411,6 +1411,13 @@ This option applies to protocol version .It Cm ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. - The minimum value is 512, and the default is 1024. + The default and minimum value is 1024. +.It Cm ShowPatchLevel +Specifies whether +.Nm sshd @@ -154,3 +121,36 @@ diff -up openssh/sshd_config.5.vendor openssh/sshd_config.5 .It Cm StreamLocalBindMask Sets the octal file creation mode mask .Pq umask +diff -up openssh-7.0p1/sshd_config.vendor openssh-7.0p1/sshd_config +--- openssh-7.0p1/sshd_config.vendor 2015-08-12 11:14:54.125628363 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-12 11:14:54.131628353 +0200 +@@ -119,6 +119,7 @@ UsePrivilegeSeparation sandbox # Defaul + #Compression delayed + #ClientAliveInterval 0 + #ClientAliveCountMax 3 ++#ShowPatchLevel no + #UseDNS no + #PidFile /var/run/sshd.pid + #MaxStartups 10:30:100 +diff -up openssh-7.0p1/sshd.c.vendor openssh-7.0p1/sshd.c +--- openssh-7.0p1/sshd.c.vendor 2015-08-12 11:14:54.100628403 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-12 11:14:54.131628353 +0200 +@@ -432,7 +432,7 @@ sshd_exchange_identification(int sock_in + } + + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", +- major, minor, SSH_VERSION, ++ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + *options.version_addendum == '\0' ? "" : " ", + options.version_addendum, newline); + +@@ -1749,7 +1749,8 @@ main(int ac, char **av) + exit(1); + } + +- debug("sshd version %s, %s", SSH_VERSION, ++ debug("sshd version %s, %s", ++ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + #ifdef WITH_OPENSSL + SSLeay_version(SSLEAY_VERSION) + #else diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index fc8f59d..ae0e5b2 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,6 +1,6 @@ -diff -up openssh/gss-serv-krb5.c.GSSAPIEnablek5users openssh/gss-serv-krb5.c ---- openssh/gss-serv-krb5.c.GSSAPIEnablek5users 2015-06-24 11:40:03.716448353 +0200 -+++ openssh/gss-serv-krb5.c 2015-06-24 11:40:03.739448295 +0200 +diff -up openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.0p1/gss-serv-krb5.c +--- openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users 2015-08-12 11:27:44.022407951 +0200 ++++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:27:44.047407912 +0200 @@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri FILE *fp; char file[MAXPATHLEN]; @@ -18,10 +18,10 @@ diff -up openssh/gss-serv-krb5.c.GSSAPIEnablek5users openssh/gss-serv-krb5.c return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c ---- openssh/servconf.c.GSSAPIEnablek5users 2015-06-24 11:40:03.728448323 +0200 -+++ openssh/servconf.c 2015-06-24 11:40:03.740448292 +0200 -@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions +diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.GSSAPIEnablek5users 2015-08-12 11:27:44.036407930 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-12 11:28:49.087306430 +0200 +@@ -173,6 +173,7 @@ initialize_server_options(ServerOptions options->version_addendum = NULL; options->fingerprint_hash = -1; options->use_kuserok = -1; @@ -29,25 +29,25 @@ diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -353,6 +354,8 @@ fill_default_server_options(ServerOption +@@ -351,6 +352,8 @@ fill_default_server_options(ServerOption + options->fwd_opts.streamlocal_bind_unlink = 0; + if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; - if (options->use_kuserok == -1) - options->use_kuserok = 1; + if (options->enable_k5users == -1) + options->enable_k5users = 0; - /* Turn privilege separation on by default */ - if (use_privsep == -1) - use_privsep = PRIVSEP_NOSANDBOX; -@@ -412,7 +415,7 @@ typedef enum { - sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, + if (options->use_kuserok == -1) + options->use_kuserok = 1; + +@@ -423,7 +426,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -490,12 +493,14 @@ static struct { +@@ -502,12 +505,14 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, @@ -62,7 +62,7 @@ diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1663,6 +1668,10 @@ process_server_config_line(ServerOptions +@@ -1680,6 +1685,10 @@ process_server_config_line(ServerOptions intptr = &options->use_kuserok; goto parse_flag; @@ -73,7 +73,7 @@ diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -2018,6 +2027,7 @@ copy_set_server_options(ServerOptions *d +@@ -2035,6 +2044,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -81,7 +81,7 @@ diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2300,6 +2310,7 @@ dump_config(ServerOptions *o) +@@ -2317,6 +2327,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -89,10 +89,10 @@ diff -up openssh/servconf.c.GSSAPIEnablek5users openssh/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh/servconf.h.GSSAPIEnablek5users openssh/servconf.h ---- openssh/servconf.h.GSSAPIEnablek5users 2015-06-24 11:40:03.717448351 +0200 -+++ openssh/servconf.h 2015-06-24 11:40:03.740448292 +0200 -@@ -179,7 +179,8 @@ typedef struct { +diff -up openssh-7.0p1/servconf.h.GSSAPIEnablek5users openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.GSSAPIEnablek5users 2015-08-12 11:27:44.022407951 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-12 11:27:44.048407911 +0200 +@@ -180,7 +180,8 @@ typedef struct { int num_permitted_opens; @@ -102,10 +102,10 @@ diff -up openssh/servconf.h.GSSAPIEnablek5users openssh/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh/sshd_config.5.GSSAPIEnablek5users openssh/sshd_config.5 ---- openssh/sshd_config.5.GSSAPIEnablek5users 2015-06-24 11:40:03.741448290 +0200 -+++ openssh/sshd_config.5 2015-06-24 11:40:40.707354263 +0200 -@@ -628,6 +628,12 @@ on logout. +diff -up openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users 2015-08-12 11:27:44.023407950 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-12 11:27:44.048407911 +0200 +@@ -633,6 +633,12 @@ on logout. The default is .Dq yes . Note that this option applies to protocol version 2 only. @@ -118,9 +118,9 @@ diff -up openssh/sshd_config.5.GSSAPIEnablek5users openssh/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -diff -up openssh/sshd_config.GSSAPIEnablek5users openssh/sshd_config ---- openssh/sshd_config.GSSAPIEnablek5users 2015-06-24 11:40:03.717448351 +0200 -+++ openssh/sshd_config 2015-06-24 11:40:03.740448292 +0200 +diff -up openssh-7.0p1/sshd_config.GSSAPIEnablek5users openssh-7.0p1/sshd_config +--- openssh-7.0p1/sshd_config.GSSAPIEnablek5users 2015-08-12 11:27:44.023407950 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-12 11:27:44.048407911 +0200 @@ -94,6 +94,7 @@ GSSAPIAuthentication yes GSSAPICleanupCredentials no #GSSAPIStrictAcceptorCheck yes diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 48bb1d0..db9f47b 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -141,8 +141,8 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c +int main (int argc, char *argv[]) +{ + -+ const Cipher *c; -+ CipherContext cc; ++ const struct sshcipher *c; ++ struct sshcipher_ctx cc; + char *algo = "aes128-ctr"; + char *hexkey = NULL; + char *hexiv = "00000000000000000000000000000000"; diff --git a/openssh-6.6p1-gsskex.patch b/openssh-6.6p1-gsskex.patch index 1cfd53f..cdf70b6 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -1,6 +1,6 @@ -diff -up openssh/auth2.c.gsskex openssh/auth2.c ---- openssh/auth2.c.gsskex 2015-06-24 11:07:36.180389924 +0200 -+++ openssh/auth2.c 2015-06-24 11:07:36.228389804 +0200 +diff -up openssh-7.0p1/auth2.c.gsskex openssh-7.0p1/auth2.c +--- openssh-7.0p1/auth2.c.gsskex 2015-08-12 11:15:43.625548999 +0200 ++++ openssh-7.0p1/auth2.c 2015-08-12 11:15:43.692548892 +0200 @@ -70,6 +70,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; @@ -17,9 +17,9 @@ diff -up openssh/auth2.c.gsskex openssh/auth2.c &method_gssapi, #endif &method_passwd, -diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c ---- openssh/auth2-gss.c.gsskex 2015-06-24 11:07:36.179389926 +0200 -+++ openssh/auth2-gss.c 2015-06-24 11:07:36.228389804 +0200 +diff -up openssh-7.0p1/auth2-gss.c.gsskex openssh-7.0p1/auth2-gss.c +--- openssh-7.0p1/auth2-gss.c.gsskex 2015-08-12 11:15:43.624549001 +0200 ++++ openssh-7.0p1/auth2-gss.c 2015-08-12 11:15:43.692548892 +0200 @@ -31,6 +31,7 @@ #include @@ -102,10 +102,10 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh/clientloop.c.gsskex openssh/clientloop.c ---- openssh/clientloop.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/clientloop.c 2015-06-24 11:07:36.228389804 +0200 -@@ -114,6 +114,10 @@ +diff -up openssh-7.0p1/clientloop.c.gsskex openssh-7.0p1/clientloop.c +--- openssh-7.0p1/clientloop.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/clientloop.c 2015-08-12 11:15:43.693548890 +0200 +@@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -116,7 +116,7 @@ diff -up openssh/clientloop.c.gsskex openssh/clientloop.c /* import options */ extern Options options; -@@ -1596,6 +1600,15 @@ client_loop(int have_pty, int escape_cha +@@ -1610,6 +1614,15 @@ client_loop(int have_pty, int escape_cha /* Do channel operations unless rekeying in progress. */ if (!rekeying) { channel_after_select(readset, writeset); @@ -132,9 +132,9 @@ diff -up openssh/clientloop.c.gsskex openssh/clientloop.c if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); active_state->kex->done = 0; -diff -up openssh/configure.ac.gsskex openssh/configure.ac ---- openssh/configure.ac.gsskex 2015-06-24 11:07:36.214389839 +0200 -+++ openssh/configure.ac 2015-06-24 11:07:36.229389802 +0200 +diff -up openssh-7.0p1/configure.ac.gsskex openssh-7.0p1/configure.ac +--- openssh-7.0p1/configure.ac.gsskex 2015-08-12 11:15:43.675548919 +0200 ++++ openssh-7.0p1/configure.ac 2015-08-12 11:15:43.694548889 +0200 @@ -625,6 +625,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], @@ -166,9 +166,9 @@ diff -up openssh/configure.ac.gsskex openssh/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c ---- openssh/gss-genr.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/gss-genr.c 2015-06-24 11:07:36.229389802 +0200 +diff -up openssh-7.0p1/gss-genr.c.gsskex openssh-7.0p1/gss-genr.c +--- openssh-7.0p1/gss-genr.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/gss-genr.c 2015-08-12 11:15:43.694548889 +0200 @@ -41,12 +41,167 @@ #include "buffer.h" #include "log.h" @@ -506,9 +506,9 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c ---- openssh/gss-serv.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/gss-serv.c 2015-06-24 11:11:53.171742794 +0200 +diff -up openssh-7.0p1/gss-serv.c.gsskex openssh-7.0p1/gss-serv.c +--- openssh-7.0p1/gss-serv.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/gss-serv.c 2015-08-12 11:15:43.694548889 +0200 @@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" @@ -791,9 +791,9 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c } #endif -diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c ---- openssh/gss-serv-krb5.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/gss-serv-krb5.c 2015-06-24 11:07:36.229389802 +0200 +diff -up openssh-7.0p1/gss-serv-krb5.c.gsskex openssh-7.0p1/gss-serv-krb5.c +--- openssh-7.0p1/gss-serv-krb5.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:15:43.694548889 +0200 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -921,9 +921,9 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh/kex.c.gsskex openssh/kex.c ---- openssh/kex.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/kex.c 2015-06-24 11:07:36.230389799 +0200 +diff -up openssh-7.0p1/kex.c.gsskex openssh-7.0p1/kex.c +--- openssh-7.0p1/kex.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/kex.c 2015-08-12 11:15:43.695548887 +0200 @@ -55,6 +55,10 @@ #include "sshbuf.h" #include "digest.h" @@ -960,9 +960,9 @@ diff -up openssh/kex.c.gsskex openssh/kex.c } return NULL; } -diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c ---- openssh/kexgssc.c.gsskex 2015-06-24 11:07:36.231389797 +0200 -+++ openssh/kexgssc.c 2015-06-24 11:07:36.230389799 +0200 +diff -up openssh-7.0p1/kexgssc.c.gsskex openssh-7.0p1/kexgssc.c +--- openssh-7.0p1/kexgssc.c.gsskex 2015-08-12 11:15:43.695548887 +0200 ++++ openssh-7.0p1/kexgssc.c 2015-08-12 11:15:43.695548887 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1302,9 +1302,9 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c ---- openssh/kexgsss.c.gsskex 2015-06-24 11:07:36.231389797 +0200 -+++ openssh/kexgsss.c 2015-06-24 11:07:36.231389797 +0200 +diff -up openssh-7.0p1/kexgsss.c.gsskex openssh-7.0p1/kexgsss.c +--- openssh-7.0p1/kexgsss.c.gsskex 2015-08-12 11:15:43.695548887 +0200 ++++ openssh-7.0p1/kexgsss.c 2015-08-12 11:15:43.695548887 +0200 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1601,9 +1601,9 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh/kex.h.gsskex openssh/kex.h ---- openssh/kex.h.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/kex.h 2015-06-24 11:07:36.230389799 +0200 +diff -up openssh-7.0p1/kex.h.gsskex openssh-7.0p1/kex.h +--- openssh-7.0p1/kex.h.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/kex.h 2015-08-12 11:17:44.694354889 +0200 @@ -93,6 +93,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, @@ -1628,8 +1628,8 @@ diff -up openssh/kex.h.gsskex openssh/kex.h +#endif char *client_version_string; char *server_version_string; - int (*verify_host_key)(struct sshkey *, struct ssh *); -@@ -183,6 +194,10 @@ int kexecdh_client(struct ssh *); + char *failed_choice; +@@ -186,6 +197,10 @@ int kexecdh_client(struct ssh *); int kexecdh_server(struct ssh *); int kexc25519_client(struct ssh *); int kexc25519_server(struct ssh *); @@ -1640,9 +1640,9 @@ diff -up openssh/kex.h.gsskex openssh/kex.h int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh/Makefile.in.gsskex openssh/Makefile.in ---- openssh/Makefile.in.gsskex 2015-06-24 11:07:36.223389817 +0200 -+++ openssh/Makefile.in 2015-06-24 11:07:36.228389804 +0200 +diff -up openssh-7.0p1/Makefile.in.gsskex openssh-7.0p1/Makefile.in +--- openssh-7.0p1/Makefile.in.gsskex 2015-08-12 11:15:43.686548901 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-12 11:15:43.695548887 +0200 @@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ @@ -1660,9 +1660,9 @@ diff -up openssh/Makefile.in.gsskex openssh/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ -diff -up openssh/monitor.c.gsskex openssh/monitor.c ---- openssh/monitor.c.gsskex 2015-06-24 11:07:36.180389924 +0200 -+++ openssh/monitor.c 2015-06-24 11:07:36.231389797 +0200 +diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c +--- openssh-7.0p1/monitor.c.gsskex 2015-08-12 11:15:43.626548998 +0200 ++++ openssh-7.0p1/monitor.c 2015-08-12 11:15:43.696548885 +0200 @@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); @@ -1852,9 +1852,9 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c + #endif /* GSSAPI */ -diff -up openssh/monitor.h.gsskex openssh/monitor.h ---- openssh/monitor.h.gsskex 2015-06-24 11:07:36.181389921 +0200 -+++ openssh/monitor.h 2015-06-24 11:07:36.231389797 +0200 +diff -up openssh-7.0p1/monitor.h.gsskex openssh-7.0p1/monitor.h +--- openssh-7.0p1/monitor.h.gsskex 2015-08-12 11:15:43.626548998 +0200 ++++ openssh-7.0p1/monitor.h 2015-08-12 11:15:43.696548885 +0200 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1864,10 +1864,10 @@ diff -up openssh/monitor.h.gsskex openssh/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.gsskex 2015-06-24 11:07:36.181389921 +0200 -+++ openssh/monitor_wrap.c 2015-06-24 11:07:36.231389797 +0200 -@@ -1088,7 +1088,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff -up openssh-7.0p1/monitor_wrap.c.gsskex openssh-7.0p1/monitor_wrap.c +--- openssh-7.0p1/monitor_wrap.c.gsskex 2015-08-12 11:15:43.626548998 +0200 ++++ openssh-7.0p1/monitor_wrap.c 2015-08-12 11:15:43.697548884 +0200 +@@ -1087,7 +1087,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1876,7 +1876,7 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -1105,5 +1105,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -1104,5 +1104,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1927,9 +1927,9 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.gsskex 2015-06-24 11:07:36.181389921 +0200 -+++ openssh/monitor_wrap.h 2015-06-24 11:07:36.232389794 +0200 +diff -up openssh-7.0p1/monitor_wrap.h.gsskex openssh-7.0p1/monitor_wrap.h +--- openssh-7.0p1/monitor_wrap.h.gsskex 2015-08-12 11:15:43.626548998 +0200 ++++ openssh-7.0p1/monitor_wrap.h 2015-08-12 11:15:43.697548884 +0200 @@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1942,9 +1942,9 @@ diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh/readconf.c.gsskex openssh/readconf.c ---- openssh/readconf.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/readconf.c 2015-06-24 11:07:36.232389794 +0200 +diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c +--- openssh-7.0p1/readconf.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-12 11:15:43.697548884 +0200 @@ -147,6 +147,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, @@ -1954,7 +1954,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -191,10 +193,19 @@ static struct { +@@ -192,10 +194,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1974,7 +1974,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, -@@ -892,10 +903,30 @@ parse_time: +@@ -894,10 +905,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2018,7 +2018,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1728,8 +1764,14 @@ fill_default_options(Options * options) +@@ -1729,8 +1765,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2033,9 +2033,9 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh/readconf.h.gsskex openssh/readconf.h ---- openssh/readconf.h.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/readconf.h 2015-06-24 11:07:36.232389794 +0200 +diff -up openssh-7.0p1/readconf.h.gsskex openssh-7.0p1/readconf.h +--- openssh-7.0p1/readconf.h.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/readconf.h 2015-08-12 11:15:43.697548884 +0200 @@ -45,7 +45,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2049,33 +2049,33 @@ diff -up openssh/readconf.h.gsskex openssh/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh ---- openssh/regress/cert-hostkey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/regress/cert-hostkey.sh 2015-06-24 11:07:36.232389794 +0200 -@@ -25,7 +25,7 @@ touch $OBJ/host_revoked_plain +diff -up openssh-7.0p1/regress/cert-hostkey.sh.gsskex openssh-7.0p1/regress/cert-hostkey.sh +--- openssh-7.0p1/regress/cert-hostkey.sh.gsskex 2015-08-12 11:15:43.698548882 +0200 ++++ openssh-7.0p1/regress/cert-hostkey.sh 2015-08-12 11:16:52.511438554 +0200 +@@ -46,7 +46,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` - type_has_legacy() { - case $1 in -diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh ---- openssh/regress/cert-userkey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/regress/cert-userkey.sh 2015-06-24 11:07:36.232389794 +0200 -@@ -6,7 +6,7 @@ tid="certified user keys" - rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* + # Prepare certificate, plain key and CA KRLs + ${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" +diff -up openssh-7.0p1/regress/cert-userkey.sh.gsskex openssh-7.0p1/regress/cert-userkey.sh +--- openssh-7.0p1/regress/cert-userkey.sh.gsskex 2015-08-12 11:15:43.698548882 +0200 ++++ openssh-7.0p1/regress/cert-userkey.sh 2015-08-12 11:20:30.110089677 +0200 +@@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` - type_has_legacy() { - case $1 in -diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh ---- openssh/regress/kextype.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/regress/kextype.sh 2015-06-24 11:07:36.233389792 +0200 + kname() { + n=`echo "$1" | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/'` +diff -up openssh-7.0p1/regress/kextype.sh.gsskex openssh-7.0p1/regress/kextype.sh +--- openssh-7.0p1/regress/kextype.sh.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/regress/kextype.sh 2015-08-12 11:15:43.698548882 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2086,9 +2086,9 @@ diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh ---- openssh/regress/rekey.sh.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/regress/rekey.sh 2015-06-24 11:07:36.233389792 +0200 +diff -up openssh-7.0p1/regress/rekey.sh.gsskex openssh-7.0p1/regress/rekey.sh +--- openssh-7.0p1/regress/rekey.sh.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/regress/rekey.sh 2015-08-12 11:15:43.698548882 +0200 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2109,10 +2109,10 @@ diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh/servconf.c.gsskex openssh/servconf.c ---- openssh/servconf.c.gsskex 2015-06-24 11:07:36.214389839 +0200 -+++ openssh/servconf.c 2015-06-24 11:20:08.026487223 +0200 -@@ -115,8 +115,10 @@ initialize_server_options(ServerOptions +diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.gsskex 2015-08-12 11:15:43.676548918 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-12 11:22:32.686893730 +0200 +@@ -117,8 +117,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -2138,8 +2138,8 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -404,7 +410,7 @@ typedef enum { - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, +@@ -415,7 +421,7 @@ typedef enum { + sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, - sAcceptEnv, sPermitTunnel, @@ -2147,7 +2147,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -477,11 +483,17 @@ static struct { +@@ -489,11 +495,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2165,7 +2165,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1218,6 +1230,10 @@ process_server_config_line(ServerOptions +@@ -1235,6 +1247,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2176,7 +2176,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1226,6 +1242,10 @@ process_server_config_line(ServerOptions +@@ -1243,6 +1259,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2187,7 +2187,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2238,6 +2258,9 @@ dump_config(ServerOptions *o) +@@ -2255,6 +2275,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2197,10 +2197,10 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh/servconf.h.gsskex openssh/servconf.h ---- openssh/servconf.h.gsskex 2015-06-24 11:07:36.233389792 +0200 -+++ openssh/servconf.h 2015-06-24 11:21:20.888302354 +0200 -@@ -117,8 +117,10 @@ typedef struct { +diff -up openssh-7.0p1/servconf.h.gsskex openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.gsskex 2015-08-12 11:15:43.676548918 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-12 11:15:43.700548879 +0200 +@@ -118,8 +118,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2211,10 +2211,10 @@ diff -up openssh/servconf.h.gsskex openssh/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 ---- openssh/ssh_config.5.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/ssh_config.5 2015-06-24 11:07:36.234389789 +0200 -@@ -744,11 +744,43 @@ Specifies whether user authentication ba +diff -up openssh-7.0p1/ssh_config.5.gsskex openssh-7.0p1/ssh_config.5 +--- openssh-7.0p1/ssh_config.5.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/ssh_config.5 2015-08-12 11:15:43.700548879 +0200 +@@ -749,11 +749,43 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2259,9 +2259,9 @@ diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh/ssh_config.gsskex openssh/ssh_config ---- openssh/ssh_config.gsskex 2015-06-24 11:07:36.209389852 +0200 -+++ openssh/ssh_config 2015-06-24 11:07:36.234389789 +0200 +diff -up openssh-7.0p1/ssh_config.gsskex openssh-7.0p1/ssh_config +--- openssh-7.0p1/ssh_config.gsskex 2015-08-12 11:15:43.667548932 +0200 ++++ openssh-7.0p1/ssh_config 2015-08-12 11:15:43.700548879 +0200 @@ -26,6 +26,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -2271,9 +2271,9 @@ diff -up openssh/ssh_config.gsskex openssh/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ---- openssh/sshconnect2.c.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/sshconnect2.c 2015-06-24 11:07:36.234389789 +0200 +diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c +--- openssh-7.0p1/sshconnect2.c.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-12 11:25:12.486644393 +0200 @@ -160,9 +160,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2306,12 +2306,12 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + } +#endif + - if (options.ciphers == (char *)-1) { - logit("No valid ciphers for protocol version 2 given, using defaults."); - options.ciphers = NULL; -@@ -200,6 +225,17 @@ ssh_kex2(char *host, struct sockaddr *ho myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( - myproposal[PROPOSAL_KEX_ALGS]); + options.kex_algorithms); + myproposal[PROPOSAL_ENC_ALGS_CTOS] = +@@ -193,6 +218,17 @@ ssh_kex2(char *host, struct sockaddr *ho + order_hostkeyalgs(host, hostaddr, port)); + } +#ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the @@ -2327,7 +2327,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); -@@ -217,11 +253,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -210,11 +246,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2359,7 +2359,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); if (options.use_roaming && !kex->roaming) { -@@ -313,6 +369,7 @@ int input_gssapi_token(int type, u_int32 +@@ -306,6 +362,7 @@ int input_gssapi_token(int type, u_int32 int input_gssapi_hash(int type, u_int32_t, void *); int input_gssapi_error(int, u_int32_t, void *); int input_gssapi_errtok(int, u_int32_t, void *); @@ -2367,7 +2367,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c #endif void userauth(Authctxt *, char *); -@@ -328,6 +385,11 @@ static char *authmethods_get(void); +@@ -321,6 +378,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2379,7 +2379,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -634,19 +696,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -627,19 +689,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2413,7 +2413,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -743,8 +817,8 @@ input_gssapi_response(int type, u_int32_ +@@ -736,8 +810,8 @@ input_gssapi_response(int type, u_int32_ { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -2424,7 +2424,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -857,6 +931,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -850,6 +924,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); return 0; } @@ -2473,10 +2473,10 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh/sshd.c.gsskex openssh/sshd.c ---- openssh/sshd.c.gsskex 2015-06-24 11:07:36.217389832 +0200 -+++ openssh/sshd.c 2015-06-24 11:07:36.235389787 +0200 -@@ -1839,10 +1839,13 @@ main(int ac, char **av) +diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c +--- openssh-7.0p1/sshd.c.gsskex 2015-08-12 11:15:43.679548913 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-12 11:15:43.702548876 +0200 +@@ -1843,10 +1843,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2490,7 +2490,7 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2589,6 +2592,48 @@ do_ssh2_kex(void) +@@ -2582,6 +2585,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2539,7 +2539,7 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2603,6 +2648,13 @@ do_ssh2_kex(void) +@@ -2596,6 +2641,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2553,10 +2553,10 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 ---- openssh/sshd_config.5.gsskex 2015-06-24 11:07:36.235389787 +0200 -+++ openssh/sshd_config.5 2015-06-24 11:23:13.490016656 +0200 -@@ -616,6 +616,12 @@ Specifies whether user authentication ba +diff -up openssh-7.0p1/sshd_config.5.gsskex openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.gsskex 2015-08-12 11:15:43.677548916 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-12 11:15:43.702548876 +0200 +@@ -621,6 +621,12 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2569,7 +2569,7 @@ diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. -@@ -637,6 +643,11 @@ machine's default store. +@@ -642,6 +648,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Dq yes . @@ -2581,9 +2581,9 @@ diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -diff -up openssh/sshd_config.gsskex openssh/sshd_config ---- openssh/sshd_config.gsskex 2015-06-24 11:07:36.217389832 +0200 -+++ openssh/sshd_config 2015-06-24 11:07:36.235389787 +0200 +diff -up openssh-7.0p1/sshd_config.gsskex openssh-7.0p1/sshd_config +--- openssh-7.0p1/sshd_config.gsskex 2015-08-12 11:15:43.679548913 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-12 11:15:43.702548876 +0200 @@ -91,6 +91,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes @@ -2593,9 +2593,9 @@ diff -up openssh/sshd_config.gsskex openssh/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/ssh-gss.h.gsskex openssh/ssh-gss.h ---- openssh/ssh-gss.h.gsskex 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/ssh-gss.h 2015-06-24 11:07:36.234389789 +0200 +diff -up openssh-7.0p1/ssh-gss.h.gsskex openssh-7.0p1/ssh-gss.h +--- openssh-7.0p1/ssh-gss.h.gsskex 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/ssh-gss.h 2015-08-12 11:15:43.702548876 +0200 @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 9e93051..0e6215d 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,6 +1,6 @@ -diff -up openssh-6.8p1/auth-krb5.c.kuserok openssh-6.8p1/auth-krb5.c ---- openssh-6.8p1/auth-krb5.c.kuserok 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth-krb5.c 2015-03-18 12:37:14.349351304 +0100 +diff -up openssh-7.0p1/auth-krb5.c.kuserok openssh-7.0p1/auth-krb5.c +--- openssh-7.0p1/auth-krb5.c.kuserok 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/auth-krb5.c 2015-08-12 11:26:21.874536127 +0200 @@ -55,6 +55,21 @@ extern ServerOptions options; @@ -35,9 +35,9 @@ diff -up openssh-6.8p1/auth-krb5.c.kuserok openssh-6.8p1/auth-krb5.c problem = -1; goto out; } -diff -up openssh-6.8p1/gss-serv-krb5.c.kuserok openssh-6.8p1/gss-serv-krb5.c ---- openssh-6.8p1/gss-serv-krb5.c.kuserok 2015-03-18 12:37:14.346351312 +0100 -+++ openssh-6.8p1/gss-serv-krb5.c 2015-03-18 12:37:14.349351304 +0100 +diff -up openssh-7.0p1/gss-serv-krb5.c.kuserok openssh-7.0p1/gss-serv-krb5.c +--- openssh-7.0p1/gss-serv-krb5.c.kuserok 2015-08-12 11:26:21.868536137 +0200 ++++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:26:21.875536126 +0200 @@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr int); @@ -172,10 +172,10 @@ diff -up openssh-6.8p1/gss-serv-krb5.c.kuserok openssh-6.8p1/gss-serv-krb5.c } if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; -diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.kuserok 2015-03-18 12:37:14.342351322 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 12:38:36.133145700 +0100 -@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions +diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.kuserok 2015-08-12 11:26:21.865536141 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-12 11:27:14.126454598 +0200 +@@ -172,6 +172,7 @@ initialize_server_options(ServerOptions options->ip_qos_bulk = -1; options->version_addendum = NULL; options->fingerprint_hash = -1; @@ -183,16 +183,16 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption +@@ -350,6 +351,8 @@ fill_default_server_options(ServerOption options->fwd_opts.streamlocal_bind_unlink = 0; if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->use_kuserok == -1) + options->use_kuserok = 1; - /* Turn privilege separation on by default */ - if (use_privsep == -1) - use_privsep = PRIVSEP_NOSANDBOX; -@@ -388,7 +391,7 @@ typedef enum { + + if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 || + kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || +@@ -404,7 +407,7 @@ typedef enum { sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -201,7 +201,7 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, -@@ -464,11 +467,13 @@ static struct { +@@ -483,11 +486,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -215,7 +215,7 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1614,6 +1619,10 @@ process_server_config_line(ServerOptions +@@ -1671,6 +1676,10 @@ process_server_config_line(ServerOptions *activep = value; break; @@ -226,7 +226,7 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -1935,6 +1944,7 @@ copy_set_server_options(ServerOptions *d +@@ -2023,6 +2032,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -234,7 +234,7 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2194,6 +2204,7 @@ dump_config(ServerOptions *o) +@@ -2304,6 +2314,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); @@ -242,10 +242,10 @@ diff -up openssh-6.8p1/servconf.c.kuserok openssh-6.8p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.8p1/servconf.h.kuserok openssh-6.8p1/servconf.h ---- openssh-6.8p1/servconf.h.kuserok 2015-03-18 12:37:14.342351322 +0100 -+++ openssh-6.8p1/servconf.h 2015-03-18 12:37:14.350351302 +0100 -@@ -177,6 +177,7 @@ typedef struct { +diff -up openssh-7.0p1/servconf.h.kuserok openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.kuserok 2015-08-12 11:26:21.865536141 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-12 11:26:21.876536124 +0200 +@@ -180,6 +180,7 @@ typedef struct { int num_permitted_opens; @@ -253,21 +253,10 @@ diff -up openssh-6.8p1/servconf.h.kuserok openssh-6.8p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-6.8p1/sshd_config.kuserok openssh-6.8p1/sshd_config ---- openssh-6.8p1/sshd_config.kuserok 2015-03-18 12:37:14.344351317 +0100 -+++ openssh-6.8p1/sshd_config 2015-03-18 12:37:14.350351302 +0100 -@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - GSSAPIAuthentication yes -diff -up openssh-6.8p1/sshd_config.5.kuserok openssh-6.8p1/sshd_config.5 ---- openssh-6.8p1/sshd_config.5.kuserok 2015-03-18 12:37:14.343351319 +0100 -+++ openssh-6.8p1/sshd_config.5 2015-03-18 12:39:23.373026939 +0100 -@@ -779,6 +779,10 @@ Specifies whether to automatically destr +diff -up openssh-7.0p1/sshd_config.5.kuserok openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.kuserok 2015-08-12 11:26:21.867536138 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-12 11:26:21.877536123 +0200 +@@ -872,6 +872,10 @@ Specifies whether to automatically destr file on logout. The default is .Dq yes . @@ -278,7 +267,7 @@ diff -up openssh-6.8p1/sshd_config.5.kuserok openssh-6.8p1/sshd_config.5 .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. -@@ -1017,6 +1021,7 @@ Available keywords are +@@ -1116,6 +1120,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -286,3 +275,14 @@ diff -up openssh-6.8p1/sshd_config.5.kuserok openssh-6.8p1/sshd_config.5 .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , +diff -up openssh-7.0p1/sshd_config.kuserok openssh-7.0p1/sshd_config +--- openssh-7.0p1/sshd_config.kuserok 2015-08-12 11:26:21.867536138 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-12 11:26:21.876536124 +0200 +@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + GSSAPIAuthentication yes diff --git a/openssh-6.7p1-audit.patch b/openssh-6.7p1-audit.patch index 59584a2..ac59f0a 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -1,6 +1,6 @@ -diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c ---- openssh/audit-bsm.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/audit-bsm.c 2015-06-24 11:53:29.780390469 +0200 +diff -up openssh-7.0p1/audit-bsm.c.audit openssh-7.0p1/audit-bsm.c +--- openssh-7.0p1/audit-bsm.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/audit-bsm.c 2015-08-12 11:33:00.409914290 +0200 @@ -375,10 +375,23 @@ audit_connection_from(const char *host, #endif } @@ -80,9 +80,9 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh/audit.c.audit openssh/audit.c ---- openssh/audit.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/audit.c 2015-06-24 11:53:29.781390467 +0200 +diff -up openssh-7.0p1/audit.c.audit openssh-7.0p1/audit.c +--- openssh-7.0p1/audit.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/audit.c 2015-08-12 11:33:00.410914289 +0200 @@ -28,6 +28,7 @@ #include @@ -280,9 +280,9 @@ diff -up openssh/audit.c.audit openssh/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/audit.h.audit openssh/audit.h ---- openssh/audit.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/audit.h 2015-06-24 11:53:29.781390467 +0200 +diff -up openssh-7.0p1/audit.h.audit openssh-7.0p1/audit.h +--- openssh-7.0p1/audit.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/audit.h 2015-08-12 11:33:00.410914289 +0200 @@ -28,6 +28,7 @@ # define _SSH_AUDIT_H @@ -318,9 +318,9 @@ diff -up openssh/audit.h.audit openssh/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh/audit-linux.c.audit openssh/audit-linux.c ---- openssh/audit-linux.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/audit-linux.c 2015-06-24 11:53:29.781390467 +0200 +diff -up openssh-7.0p1/audit-linux.c.audit openssh-7.0p1/audit-linux.c +--- openssh-7.0p1/audit-linux.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/audit-linux.c 2015-08-12 11:33:00.411914287 +0200 @@ -35,13 +35,25 @@ #include "log.h" @@ -612,7 +612,7 @@ diff -up openssh/audit-linux.c.audit openssh/audit-linux.c +#ifdef AUDIT_CRYPTO_SESSION + char buf[AUDIT_LOG_SIZE]; + int audit_fd, audit_ok; -+ const Cipher *cipher = cipher_by_name(enc); ++ const struct sshcipher *cipher = cipher_by_name(enc); + char *s; + + snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", @@ -712,9 +712,9 @@ diff -up openssh/audit-linux.c.audit openssh/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh/auditstub.c.audit openssh/auditstub.c ---- openssh/auditstub.c.audit 2015-06-24 11:53:29.782390464 +0200 -+++ openssh/auditstub.c 2015-06-24 11:53:29.782390464 +0200 +diff -up openssh-7.0p1/auditstub.c.audit openssh-7.0p1/auditstub.c +--- openssh-7.0p1/auditstub.c.audit 2015-08-12 11:33:00.411914287 +0200 ++++ openssh-7.0p1/auditstub.c 2015-08-12 11:33:00.411914287 +0200 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -766,9 +766,9 @@ diff -up openssh/auditstub.c.audit openssh/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh/auth2.c.audit openssh/auth2.c ---- openssh/auth2.c.audit 2015-06-24 11:53:29.731390595 +0200 -+++ openssh/auth2.c 2015-06-24 11:53:29.783390462 +0200 +diff -up openssh-7.0p1/auth2.c.audit openssh-7.0p1/auth2.c +--- openssh-7.0p1/auth2.c.audit 2015-08-12 11:33:00.349914384 +0200 ++++ openssh-7.0p1/auth2.c 2015-08-12 11:33:00.411914287 +0200 @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { logit("input_userauth_request: invalid user %s", user); @@ -779,9 +779,9 @@ diff -up openssh/auth2.c.audit openssh/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.audit 2015-06-24 11:53:29.682390720 +0200 -+++ openssh/auth2-hostbased.c 2015-06-24 11:53:29.782390464 +0200 +diff -up openssh-7.0p1/auth2-hostbased.c.audit openssh-7.0p1/auth2-hostbased.c +--- openssh-7.0p1/auth2-hostbased.c.audit 2015-08-12 11:33:00.303914456 +0200 ++++ openssh-7.0p1/auth2-hostbased.c 2015-08-12 11:33:00.412914286 +0200 @@ -146,7 +146,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; @@ -810,9 +810,9 @@ diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.audit 2015-06-24 11:53:29.783390462 +0200 -+++ openssh/auth2-pubkey.c 2015-06-24 11:58:49.547572821 +0200 +diff -up openssh-7.0p1/auth2-pubkey.c.audit openssh-7.0p1/auth2-pubkey.c +--- openssh-7.0p1/auth2-pubkey.c.audit 2015-08-12 11:33:00.318914432 +0200 ++++ openssh-7.0p1/auth2-pubkey.c 2015-08-12 11:33:00.412914286 +0200 @@ -175,7 +175,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; @@ -841,10 +841,10 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh/auth.c.audit openssh/auth.c ---- openssh/auth.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/auth.c 2015-06-24 11:53:29.782390464 +0200 -@@ -643,9 +643,6 @@ getpwnamallow(const char *user) +diff -up openssh-7.0p1/auth.c.audit openssh-7.0p1/auth.c +--- openssh-7.0p1/auth.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/auth.c 2015-08-12 11:33:00.412914286 +0200 +@@ -645,9 +645,6 @@ getpwnamallow(const char *user) record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); #endif @@ -854,9 +854,9 @@ diff -up openssh/auth.c.audit openssh/auth.c return (NULL); } if (!allowed_user(pw)) -diff -up openssh/auth.h.audit openssh/auth.h ---- openssh/auth.h.audit 2015-06-24 11:53:29.682390720 +0200 -+++ openssh/auth.h 2015-06-24 11:53:29.782390464 +0200 +diff -up openssh-7.0p1/auth.h.audit openssh-7.0p1/auth.h +--- openssh-7.0p1/auth.h.audit 2015-08-12 11:33:00.302914457 +0200 ++++ openssh-7.0p1/auth.h 2015-08-12 11:33:00.412914286 +0200 @@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt char *expand_authorized_keys(const char *, struct passwd *pw); @@ -873,9 +873,9 @@ diff -up openssh/auth.h.audit openssh/auth.h /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh/auth-rsa.c.audit openssh/auth-rsa.c ---- openssh/auth-rsa.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/auth-rsa.c 2015-06-24 11:53:29.782390464 +0200 +diff -up openssh-7.0p1/auth-rsa.c.audit openssh-7.0p1/auth-rsa.c +--- openssh-7.0p1/auth-rsa.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/auth-rsa.c 2015-08-12 11:33:00.412914286 +0200 @@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNU { u_char buf[32], mdbuf[16]; @@ -912,9 +912,9 @@ diff -up openssh/auth-rsa.c.audit openssh/auth-rsa.c } /* -diff -up openssh/cipher.c.audit openssh/cipher.c ---- openssh/cipher.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/cipher.c 2015-06-24 11:53:29.783390462 +0200 +diff -up openssh-7.0p1/cipher.c.audit openssh-7.0p1/cipher.c +--- openssh-7.0p1/cipher.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/cipher.c 2015-08-12 11:33:00.412914286 +0200 @@ -57,26 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #endif @@ -942,9 +942,9 @@ diff -up openssh/cipher.c.audit openssh/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh/cipher.h.audit openssh/cipher.h ---- openssh/cipher.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/cipher.h 2015-06-24 11:53:29.783390462 +0200 +diff -up openssh-7.0p1/cipher.h.audit openssh-7.0p1/cipher.h +--- openssh-7.0p1/cipher.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/cipher.h 2015-08-12 11:33:00.413914284 +0200 @@ -62,7 +62,26 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -973,9 +973,9 @@ diff -up openssh/cipher.h.audit openssh/cipher.h struct sshcipher_ctx { int plaintext; int encrypt; -diff -up openssh/kex.c.audit openssh/kex.c ---- openssh/kex.c.audit 2015-06-24 11:53:29.733390590 +0200 -+++ openssh/kex.c 2015-06-24 11:53:29.783390462 +0200 +diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c +--- openssh-7.0p1/kex.c.audit 2015-08-12 11:33:00.351914381 +0200 ++++ openssh-7.0p1/kex.c 2015-08-12 11:33:00.413914284 +0200 @@ -54,6 +54,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -984,7 +984,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -486,8 +487,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -549,8 +550,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -998,7 +998,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -505,8 +510,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -568,8 +573,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1012,7 +1012,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -523,8 +532,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -586,8 +595,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1026,7 +1026,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -674,6 +687,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -753,6 +766,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); @@ -1037,7 +1037,7 @@ diff -up openssh/kex.c.audit openssh/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -849,3 +866,34 @@ dump_digest(char *msg, u_char *digest, i +@@ -928,3 +945,34 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1072,10 +1072,10 @@ diff -up openssh/kex.c.audit openssh/kex.c + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} + -diff -up openssh/kex.h.audit openssh/kex.h ---- openssh/kex.h.audit 2015-06-24 11:53:29.733390590 +0200 -+++ openssh/kex.h 2015-06-24 11:53:29.784390459 +0200 -@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); +diff -up openssh-7.0p1/kex.h.audit openssh-7.0p1/kex.h +--- openssh-7.0p1/kex.h.audit 2015-08-12 11:33:00.352914379 +0200 ++++ openssh-7.0p1/kex.h 2015-08-12 11:33:00.413914284 +0200 +@@ -202,6 +202,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1084,20 +1084,20 @@ diff -up openssh/kex.h.audit openssh/kex.h int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh/key.h.audit openssh/key.h ---- openssh/key.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/key.h 2015-06-24 11:53:29.784390459 +0200 +diff -up openssh-7.0p1/key.h.audit openssh-7.0p1/key.h +--- openssh-7.0p1/key.h.audit 2015-08-12 11:33:00.413914284 +0200 ++++ openssh-7.0p1/key.h 2015-08-12 11:33:45.908843298 +0200 @@ -50,6 +50,7 @@ typedef struct sshkey Key; #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid #define key_is_cert sshkey_is_cert +#define key_is_private sshkey_is_private #define key_type_plain sshkey_type_plain - #define key_cert_is_legacy sshkey_cert_is_legacy #define key_curve_name_to_nid sshkey_curve_name_to_nid -diff -up openssh/mac.c.audit openssh/mac.c ---- openssh/mac.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/mac.c 2015-06-24 11:53:29.784390459 +0200 + #define key_curve_nid_to_bits sshkey_curve_nid_to_bits +diff -up openssh-7.0p1/mac.c.audit openssh-7.0p1/mac.c +--- openssh-7.0p1/mac.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/mac.c 2015-08-12 11:33:00.413914284 +0200 @@ -226,6 +226,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1119,9 +1119,9 @@ diff -up openssh/mac.c.audit openssh/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh/mac.h.audit openssh/mac.h ---- openssh/mac.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/mac.h 2015-06-24 11:53:29.784390459 +0200 +diff -up openssh-7.0p1/mac.h.audit openssh-7.0p1/mac.h +--- openssh-7.0p1/mac.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/mac.h 2015-08-12 11:33:00.413914284 +0200 @@ -47,5 +47,6 @@ int mac_init(struct sshmac *); int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, u_char *, size_t); @@ -1129,9 +1129,9 @@ diff -up openssh/mac.h.audit openssh/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh/Makefile.in.audit openssh/Makefile.in ---- openssh/Makefile.in.audit 2015-06-24 11:53:29.752390541 +0200 -+++ openssh/Makefile.in 2015-06-24 11:53:29.780390469 +0200 +diff -up openssh-7.0p1/Makefile.in.audit openssh-7.0p1/Makefile.in +--- openssh-7.0p1/Makefile.in.audit 2015-08-12 11:33:00.402914301 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-12 11:33:00.414914283 +0200 @@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ @@ -1141,9 +1141,9 @@ diff -up openssh/Makefile.in.audit openssh/Makefile.in SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ -diff -up openssh/monitor.c.audit openssh/monitor.c ---- openssh/monitor.c.audit 2015-06-24 11:53:29.759390523 +0200 -+++ openssh/monitor.c 2015-06-24 11:53:29.784390459 +0200 +diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c +--- openssh-7.0p1/monitor.c.audit 2015-08-12 11:33:00.378914339 +0200 ++++ openssh-7.0p1/monitor.c 2015-08-12 11:33:00.414914283 +0200 @@ -102,6 +102,7 @@ #include "ssh2.h" #include "roaming.h" @@ -1443,9 +1443,9 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor.h.audit openssh/monitor.h ---- openssh/monitor.h.audit 2015-06-24 11:53:29.759390523 +0200 -+++ openssh/monitor.h 2015-06-24 11:53:29.785390457 +0200 +diff -up openssh-7.0p1/monitor.h.audit openssh-7.0p1/monitor.h +--- openssh-7.0p1/monitor.h.audit 2015-08-12 11:33:00.378914339 +0200 ++++ openssh-7.0p1/monitor.h 2015-08-12 11:33:00.414914283 +0200 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1461,9 +1461,9 @@ diff -up openssh/monitor.h.audit openssh/monitor.h }; -diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.audit 2015-06-24 11:53:29.734390587 +0200 -+++ openssh/monitor_wrap.c 2015-06-24 11:53:29.785390457 +0200 +diff -up openssh-7.0p1/monitor_wrap.c.audit openssh-7.0p1/monitor_wrap.c +--- openssh-7.0p1/monitor_wrap.c.audit 2015-08-12 11:33:00.353914378 +0200 ++++ openssh-7.0p1/monitor_wrap.c 2015-08-12 11:33:00.414914283 +0200 @@ -462,7 +462,7 @@ mm_key_allowed(enum mm_keytype type, cha */ @@ -1500,7 +1500,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c void mm_send_keystate(struct monitor *monitor) { -@@ -1006,10 +1019,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1513,7 +1513,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -1017,6 +1031,26 @@ mm_audit_run_command(const char *command +@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1540,7 +1540,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1152,3 +1186,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1151,3 +1185,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1611,9 +1611,9 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.audit 2015-06-24 11:53:29.734390587 +0200 -+++ openssh/monitor_wrap.h 2015-06-24 11:59:45.086430808 +0200 +diff -up openssh-7.0p1/monitor_wrap.h.audit openssh-7.0p1/monitor_wrap.h +--- openssh-7.0p1/monitor_wrap.h.audit 2015-08-12 11:33:00.353914378 +0200 ++++ openssh-7.0p1/monitor_wrap.h 2015-08-12 11:33:00.415914281 +0200 @@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char int mm_user_key_allowed(struct passwd *, Key *, int); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); @@ -1638,9 +1638,9 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h #endif struct Session; -diff -up openssh/packet.c.audit openssh/packet.c ---- openssh/packet.c.audit 2015-06-24 11:53:29.665390763 +0200 -+++ openssh/packet.c 2015-06-24 11:53:29.786390454 +0200 +diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c +--- openssh-7.0p1/packet.c.audit 2015-08-12 11:33:00.288914479 +0200 ++++ openssh-7.0p1/packet.c 2015-08-12 11:33:00.415914281 +0200 @@ -67,6 +67,7 @@ #include "key.h" /* typedefs XXX */ @@ -1714,7 +1714,7 @@ diff -up openssh/packet.c.audit openssh/packet.c if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; -@@ -2281,6 +2293,75 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2292,6 +2304,75 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1790,7 +1790,7 @@ diff -up openssh/packet.c.audit openssh/packet.c /* XXX TODO update roaming to new API (does not work anyway) */ /* * Save the state for the real connection, and use a separate state when -@@ -2290,18 +2371,12 @@ void +@@ -2301,18 +2382,12 @@ void ssh_packet_backup_state(struct ssh *ssh, struct ssh *backup_state) { @@ -1810,7 +1810,7 @@ diff -up openssh/packet.c.audit openssh/packet.c } /* XXX FIXME FIXME FIXME */ -@@ -2320,9 +2395,7 @@ ssh_packet_restore_state(struct ssh *ssh +@@ -2331,9 +2406,7 @@ ssh_packet_restore_state(struct ssh *ssh backup_state = ssh; ssh = tmp; ssh->state->connection_in = backup_state->state->connection_in; @@ -1820,7 +1820,7 @@ diff -up openssh/packet.c.audit openssh/packet.c len = sshbuf_len(backup_state->state->input); if (len > 0) { if ((r = sshbuf_putb(ssh->state->input, -@@ -2331,6 +2404,11 @@ ssh_packet_restore_state(struct ssh *ssh +@@ -2342,6 +2415,11 @@ ssh_packet_restore_state(struct ssh *ssh sshbuf_reset(backup_state->state->input); add_recv_bytes(len); } @@ -1832,9 +1832,9 @@ diff -up openssh/packet.c.audit openssh/packet.c } /* Reset after_authentication and reset compression in post-auth privsep */ -diff -up openssh/packet.h.audit openssh/packet.h ---- openssh/packet.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/packet.h 2015-06-24 11:53:29.786390454 +0200 +diff -up openssh-7.0p1/packet.h.audit openssh-7.0p1/packet.h +--- openssh-7.0p1/packet.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/packet.h 2015-08-12 11:33:00.415914281 +0200 @@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); @@ -1850,10 +1850,10 @@ diff -up openssh/packet.h.audit openssh/packet.h +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh/sandbox-seccomp-filter.c.audit openssh/sandbox-seccomp-filter.c ---- openssh/sandbox-seccomp-filter.c.audit 2015-06-24 11:53:29.788390449 +0200 -+++ openssh/sandbox-seccomp-filter.c 2015-06-24 12:00:37.459296890 +0200 -@@ -147,6 +147,12 @@ static const struct sock_filter preauth_ +diff -up openssh-7.0p1/sandbox-seccomp-filter.c.audit openssh-7.0p1/sandbox-seccomp-filter.c +--- openssh-7.0p1/sandbox-seccomp-filter.c.audit 2015-08-12 11:33:00.394914314 +0200 ++++ openssh-7.0p1/sandbox-seccomp-filter.c 2015-08-12 11:33:00.415914281 +0200 +@@ -150,6 +150,12 @@ static const struct sock_filter preauth_ #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), #endif @@ -1866,9 +1866,9 @@ diff -up openssh/sandbox-seccomp-filter.c.audit openssh/sandbox-seccomp-filter.c #ifdef __NR_madvise SC_ALLOW(madvise), #endif -diff -up openssh/session.c.audit openssh/session.c ---- openssh/session.c.audit 2015-06-24 11:53:29.760390520 +0200 -+++ openssh/session.c 2015-06-24 11:53:29.786390454 +0200 +diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c +--- openssh-7.0p1/session.c.audit 2015-08-12 11:33:00.379914337 +0200 ++++ openssh-7.0p1/session.c 2015-08-12 11:33:00.416914280 +0200 @@ -139,7 +139,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; @@ -2022,9 +2022,9 @@ diff -up openssh/session.c.audit openssh/session.c - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff -up openssh/session.h.audit openssh/session.h ---- openssh/session.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/session.h 2015-06-24 11:53:29.786390454 +0200 +diff -up openssh-7.0p1/session.h.audit openssh-7.0p1/session.h +--- openssh-7.0p1/session.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/session.h 2015-08-12 11:33:00.416914280 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2049,10 +2049,10 @@ diff -up openssh/session.h.audit openssh/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh/sshd.c.audit openssh/sshd.c ---- openssh/sshd.c.audit 2015-06-24 11:53:29.770390495 +0200 -+++ openssh/sshd.c 2015-06-24 11:53:29.787390451 +0200 -@@ -121,6 +121,7 @@ +diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c +--- openssh-7.0p1/sshd.c.audit 2015-08-12 11:33:00.388914323 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-12 11:33:00.417914278 +0200 +@@ -122,6 +122,7 @@ #endif #include "monitor_wrap.h" #include "roaming.h" @@ -2060,7 +2060,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" -@@ -260,7 +261,7 @@ Buffer loginmsg; +@@ -261,7 +262,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2069,7 +2069,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c void demote_sensitive_data(void); #ifdef WITH_SSH1 -@@ -281,6 +282,15 @@ close_listen_socks(void) +@@ -282,6 +283,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2085,7 +2085,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void close_startup_pipes(void) { -@@ -560,22 +570,45 @@ sshd_exchange_identification(int sock_in +@@ -561,22 +571,45 @@ sshd_exchange_identification(int sock_in } } @@ -2134,7 +2134,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -589,6 +622,8 @@ void +@@ -590,6 +623,8 @@ void demote_sensitive_data(void) { Key *tmp; @@ -2143,7 +2143,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c int i; if (sensitive_data.server_key) { -@@ -597,13 +632,25 @@ demote_sensitive_data(void) +@@ -598,13 +633,25 @@ demote_sensitive_data(void) sensitive_data.server_key = tmp; } @@ -2169,7 +2169,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c } /* Certs do not need demotion */ } -@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -676,7 +723,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2178,7 +2178,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -759,6 +806,12 @@ privsep_postauth(Authctxt *authctxt) +@@ -760,6 +807,12 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); @@ -2191,7 +2191,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1288,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1292,6 +1345,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2199,7 +2199,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2251,6 +2305,7 @@ main(int ac, char **av) +@@ -2255,6 +2309,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2207,7 +2207,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c exit(0); } -@@ -2296,7 +2351,7 @@ main(int ac, char **av) +@@ -2300,7 +2355,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2216,7 +2216,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c } packet_set_timeout(options.client_alive_interval, -@@ -2310,6 +2365,9 @@ main(int ac, char **av) +@@ -2314,6 +2369,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2226,7 +2226,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2470,6 +2528,10 @@ do_ssh1_kex(void) +@@ -2474,6 +2532,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); @@ -2237,7 +2237,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2529,7 +2591,7 @@ do_ssh1_kex(void) +@@ -2533,7 +2595,7 @@ do_ssh1_kex(void) } /* Destroy the private and public keys. No longer. */ @@ -2246,7 +2246,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2712,6 +2774,16 @@ do_ssh2_kex(void) +@@ -2705,6 +2767,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2263,7 +2263,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2723,9 +2795,14 @@ cleanup_exit(int i) +@@ -2716,9 +2788,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2279,22 +2279,20 @@ diff -up openssh/sshd.c.audit openssh/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh/sshkey.c.audit openssh/sshkey.c ---- openssh/sshkey.c.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/sshkey.c 2015-06-24 11:53:29.787390451 +0200 -@@ -317,6 +317,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-7.0p1/sshkey.c.audit openssh-7.0p1/sshkey.c +--- openssh-7.0p1/sshkey.c.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/sshkey.c 2015-08-12 11:33:00.417914278 +0200 +@@ -299,6 +299,31 @@ sshkey_type_is_valid_ca(int type) } int +sshkey_is_private(const struct sshkey *k) +{ + switch (k->type) { -+ case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_RSA1: + case KEY_RSA: + return k->rsa->d != NULL; -+ case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_DSA: + return k->dsa->priv_key != NULL; @@ -2316,10 +2314,10 @@ diff -up openssh/sshkey.c.audit openssh/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh/sshkey.h.audit openssh/sshkey.h ---- openssh/sshkey.h.audit 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/sshkey.h 2015-06-24 11:53:29.787390451 +0200 -@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-7.0p1/sshkey.h.audit openssh-7.0p1/sshkey.h +--- openssh-7.0p1/sshkey.h.audit 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/sshkey.h 2015-08-12 11:33:00.417914278 +0200 +@@ -132,6 +132,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index bd43f1c..923793d 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh/cipher.c.fips openssh/cipher.c ---- openssh/cipher.c.fips 2015-06-24 12:00:58.730242500 +0200 -+++ openssh/cipher.c 2015-06-24 12:00:58.737242482 +0200 +diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c +--- openssh-7.0p1/cipher.c.fips 2015-08-12 11:34:11.722803020 +0200 ++++ openssh-7.0p1/cipher.c 2015-08-12 11:34:11.733803003 +0200 @@ -39,6 +39,8 @@ #include @@ -73,9 +73,9 @@ diff -up openssh/cipher.c.fips openssh/cipher.c if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff -up openssh/cipher-ctr.c.fips openssh/cipher-ctr.c ---- openssh/cipher-ctr.c.fips 2015-06-24 12:00:58.669242656 +0200 -+++ openssh/cipher-ctr.c 2015-06-24 12:00:58.736242484 +0200 +diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c +--- openssh-7.0p1/cipher-ctr.c.fips 2015-08-12 11:34:11.650803133 +0200 ++++ openssh-7.0p1/cipher-ctr.c 2015-08-12 11:34:11.734803002 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -86,9 +86,9 @@ diff -up openssh/cipher-ctr.c.fips openssh/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh/dh.h.fips openssh/dh.h ---- openssh/dh.h.fips 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/dh.h 2015-06-24 12:00:58.737242482 +0200 +diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h +--- openssh-7.0p1/dh.h.fips 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/dh.h 2015-08-12 11:34:11.734803002 +0200 @@ -46,6 +46,7 @@ u_int dh_estimate(int); /* Min and max values from RFC4419. */ @@ -97,9 +97,9 @@ diff -up openssh/dh.h.fips openssh/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh/entropy.c.fips openssh/entropy.c ---- openssh/entropy.c.fips 2015-06-24 12:00:58.662242674 +0200 -+++ openssh/entropy.c 2015-06-24 12:00:58.737242482 +0200 +diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c +--- openssh-7.0p1/entropy.c.fips 2015-08-12 11:34:11.643803144 +0200 ++++ openssh-7.0p1/entropy.c 2015-08-12 11:34:11.734803002 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -110,9 +110,9 @@ diff -up openssh/entropy.c.fips openssh/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh/kex.c.fips openssh/kex.c ---- openssh/kex.c.fips 2015-06-24 12:00:58.730242500 +0200 -+++ openssh/kex.c 2015-06-24 12:00:58.737242482 +0200 +diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c +--- openssh-7.0p1/kex.c.fips 2015-08-12 11:34:11.723803019 +0200 ++++ openssh-7.0p1/kex.c 2015-08-12 11:34:11.734803002 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL @@ -168,9 +168,9 @@ diff -up openssh/kex.c.fips openssh/kex.c free(s); return 0; } -diff -up openssh/kexgexc.c.fips openssh/kexgexc.c ---- openssh/kexgexc.c.fips 2015-06-24 12:00:58.737242482 +0200 -+++ openssh/kexgexc.c 2015-06-24 12:02:26.996015709 +0200 +diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c +--- openssh-7.0p1/kexgexc.c.fips 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/kexgexc.c 2015-08-12 11:34:11.734803002 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -188,9 +188,9 @@ diff -up openssh/kexgexc.c.fips openssh/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh/kexgexs.c.fips openssh/kexgexs.c ---- openssh/kexgexs.c.fips 2015-06-24 12:00:58.738242479 +0200 -+++ openssh/kexgexs.c 2015-06-24 13:48:23.735320199 +0200 +diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c +--- openssh-7.0p1/kexgexs.c.fips 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/kexgexs.c 2015-08-12 11:34:11.735803000 +0200 @@ -81,11 +81,11 @@ input_kex_dh_gex_request(int type, u_int (r = sshpkt_get_end(ssh)) != 0) goto out; @@ -206,9 +206,9 @@ diff -up openssh/kexgexs.c.fips openssh/kexgexs.c nbits = MIN(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh/mac.c.fips openssh/mac.c ---- openssh/mac.c.fips 2015-06-24 12:00:58.731242497 +0200 -+++ openssh/mac.c 2015-06-24 12:00:58.738242479 +0200 +diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c +--- openssh-7.0p1/mac.c.fips 2015-08-12 11:34:11.725803016 +0200 ++++ openssh-7.0p1/mac.c 2015-08-12 11:34:11.735803000 +0200 @@ -27,6 +27,8 @@ #include @@ -270,9 +270,9 @@ diff -up openssh/mac.c.fips openssh/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh/Makefile.in.fips openssh/Makefile.in ---- openssh/Makefile.in.fips 2015-06-24 12:00:58.731242497 +0200 -+++ openssh/Makefile.in 2015-06-24 12:00:58.736242484 +0200 +diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in +--- openssh-7.0p1/Makefile.in.fips 2015-08-12 11:34:11.725803016 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-12 11:34:11.735803000 +0200 @@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -314,10 +314,10 @@ diff -up openssh/Makefile.in.fips openssh/Makefile.in sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh/myproposal.h.fips openssh/myproposal.h ---- openssh/myproposal.h.fips 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/myproposal.h 2015-06-24 12:00:58.738242479 +0200 -@@ -143,6 +143,28 @@ +diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h +--- openssh-7.0p1/myproposal.h.fips 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/myproposal.h 2015-08-12 11:34:11.735803000 +0200 +@@ -138,6 +138,28 @@ "hmac-sha1-96," \ "hmac-md5-96" @@ -346,10 +346,45 @@ diff -up openssh/myproposal.h.fips openssh/myproposal.h #else #define KEX_SERVER_KEX \ -diff -up openssh/servconf.c.fips openssh/servconf.c ---- openssh/servconf.c.fips 2015-06-24 12:00:58.726242510 +0200 -+++ openssh/servconf.c 2015-06-24 13:49:40.164085648 +0200 -@@ -2319,8 +2319,10 @@ dump_config(ServerOptions *o) +diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c +--- openssh-7.0p1/readconf.c.fips 2015-08-12 14:37:39.206466634 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-12 14:47:00.342350208 +0200 +@@ -1897,9 +1897,12 @@ fill_default_options(Options * options) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->update_hostkeys == -1) + options->update_hostkeys = 0; +- if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || +- kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || +- kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || ++ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT ++ : KEX_CLIENT_ENCRYPT), &options->ciphers) != 0 || ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC ++ : KEX_CLIENT_MAC), &options->macs) != 0 || ++ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS ++ : KEX_CLIENT_KEX), &options->kex_algorithms) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, + &options->hostbased_key_types) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, +diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.fips 2015-08-12 11:34:11.714803033 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-12 14:50:14.608951396 +0200 +@@ -357,9 +357,12 @@ fill_default_server_options(ServerOption + if (options->use_kuserok == -1) + options->use_kuserok = 1; + +- if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 || +- kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || +- kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 || ++ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT ++ : KEX_SERVER_ENCRYPT), &options->ciphers) != 0 || ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC ++ : KEX_SERVER_MAC), &options->macs) != 0 || ++ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS ++ : KEX_SERVER_KEX), &options->kex_algorithms) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, + &options->hostbased_key_types) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, +@@ -2336,8 +2339,10 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); @@ -362,7 +397,7 @@ diff -up openssh/servconf.c.fips openssh/servconf.c 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); -@@ -2335,8 +2337,8 @@ dump_config(ServerOptions *o) +@@ -2352,8 +2357,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); @@ -372,10 +407,10 @@ diff -up openssh/servconf.c.fips openssh/servconf.c + FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? o->hostbased_key_types : KEX_DEFAULT_PK_ALG); - dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? -diff -up openssh/ssh.c.fips openssh/ssh.c ---- openssh/ssh.c.fips 2015-06-23 02:34:47.000000000 +0200 -+++ openssh/ssh.c 2015-06-24 12:00:58.738242479 +0200 + dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? +diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c +--- openssh-7.0p1/ssh.c.fips 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/ssh.c 2015-08-12 11:34:11.736802999 +0200 @@ -75,6 +75,8 @@ #include #include @@ -385,7 +420,7 @@ diff -up openssh/ssh.c.fips openssh/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -521,6 +523,14 @@ main(int ac, char **av) +@@ -522,6 +524,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -400,7 +435,7 @@ diff -up openssh/ssh.c.fips openssh/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -598,6 +608,9 @@ main(int ac, char **av) +@@ -599,6 +609,9 @@ main(int ac, char **av) "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -410,7 +445,7 @@ diff -up openssh/ssh.c.fips openssh/ssh.c options.protocol = SSH_PROTO_1; break; case '2': -@@ -939,7 +952,6 @@ main(int ac, char **av) +@@ -940,7 +953,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -418,7 +453,7 @@ diff -up openssh/ssh.c.fips openssh/ssh.c ERR_load_crypto_strings(); #endif -@@ -1113,6 +1125,10 @@ main(int ac, char **av) +@@ -1114,6 +1126,10 @@ main(int ac, char **av) seed_rng(); @@ -429,7 +464,7 @@ diff -up openssh/ssh.c.fips openssh/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1190,6 +1206,12 @@ main(int ac, char **av) +@@ -1191,6 +1207,12 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; @@ -442,10 +477,10 @@ diff -up openssh/ssh.c.fips openssh/ssh.c /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff -up openssh/sshconnect2.c.fips openssh/sshconnect2.c ---- openssh/sshconnect2.c.fips 2015-06-24 12:00:58.698242582 +0200 -+++ openssh/sshconnect2.c 2015-06-24 12:00:58.739242477 +0200 -@@ -46,6 +46,8 @@ +diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c +--- openssh-7.0p1/sshconnect2.c.fips 2015-08-12 11:34:11.678803089 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-12 11:34:11.737802997 +0200 +@@ -44,6 +44,8 @@ #include #endif @@ -454,7 +489,7 @@ diff -up openssh/sshconnect2.c.fips openssh/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -172,20 +174,25 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -170,20 +172,25 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -494,45 +529,9 @@ diff -up openssh/sshconnect2.c.fips openssh/sshconnect2.c } } #endif -@@ -197,6 +204,10 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; -+ - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -212,7 +223,11 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } -+ - if (options.hostkeyalgorithms != NULL) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - compat_pkalg_proposal(options.hostkeyalgorithms); -@@ -224,9 +239,11 @@ ssh_kex2(char *host, struct sockaddr *ho - } - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; -+ else if (FIPS_mode()) -+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; -+ - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( - myproposal[PROPOSAL_KEX_ALGS]); -- - #ifdef GSSAPI - /* If we've got GSSAPI algorithms, then we also support the - * 'null' hostkey, as a last resort */ -diff -up openssh/sshd.c.fips openssh/sshd.c ---- openssh/sshd.c.fips 2015-06-24 12:00:58.734242489 +0200 -+++ openssh/sshd.c 2015-06-24 12:00:58.739242477 +0200 +diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c +--- openssh-7.0p1/sshd.c.fips 2015-08-12 11:34:11.729803010 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-12 11:34:11.738802995 +0200 @@ -66,6 +66,7 @@ #include #include @@ -550,7 +549,7 @@ diff -up openssh/sshd.c.fips openssh/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1548,6 +1551,18 @@ main(int ac, char **av) +@@ -1552,6 +1555,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -569,7 +568,7 @@ diff -up openssh/sshd.c.fips openssh/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1700,7 +1715,7 @@ main(int ac, char **av) +@@ -1704,7 +1719,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -578,7 +577,7 @@ diff -up openssh/sshd.c.fips openssh/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1901,6 +1916,10 @@ main(int ac, char **av) +@@ -1905,6 +1920,10 @@ main(int ac, char **av) sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); free(fp); } @@ -589,7 +588,7 @@ diff -up openssh/sshd.c.fips openssh/sshd.c if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; -@@ -2069,6 +2088,10 @@ main(int ac, char **av) +@@ -2073,6 +2092,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); @@ -600,36 +599,7 @@ diff -up openssh/sshd.c.fips openssh/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2654,6 +2677,9 @@ do_ssh2_kex(void) - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2663,6 +2689,9 @@ do_ssh2_kex(void) - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } - if (options.compression == COMP_NONE) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = -@@ -2673,6 +2702,8 @@ do_ssh2_kex(void) - } - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; -+ else if (FIPS_mode()) -+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; - - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( - myproposal[PROPOSAL_KEX_ALGS]); -@@ -2699,10 +2730,14 @@ do_ssh2_kex(void) +@@ -2692,10 +2715,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -648,9 +618,9 @@ diff -up openssh/sshd.c.fips openssh/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh/sshkey.c.fips openssh/sshkey.c ---- openssh/sshkey.c.fips 2015-06-24 12:00:58.735242487 +0200 -+++ openssh/sshkey.c 2015-06-24 12:00:58.740242474 +0200 +diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c +--- openssh-7.0p1/sshkey.c.fips 2015-08-12 11:34:11.729803010 +0200 ++++ openssh-7.0p1/sshkey.c 2015-08-12 11:34:11.738802995 +0200 @@ -35,6 +35,7 @@ #include #include @@ -659,7 +629,7 @@ diff -up openssh/sshkey.c.fips openssh/sshkey.c #endif #include "crypto_api.h" -@@ -1586,6 +1587,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { diff --git a/openssh-6.9p1-authentication-limits-bypass.patch b/openssh-6.9p1-authentication-limits-bypass.patch deleted file mode 100644 index 10bde94..0000000 --- a/openssh-6.9p1-authentication-limits-bypass.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5b64f85bb811246c59ebab70aed331f26ba37b18 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Sat, 18 Jul 2015 07:57:14 +0000 -Subject: upstream commit - -only query each keyboard-interactive device once per - authentication request regardless of how many times it is listed; ok markus@ - -Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1 ---- - auth2-chall.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/auth2-chall.c b/auth2-chall.c -index ddabe1a..4aff09d 100644 ---- a/auth2-chall.c -+++ b/auth2-chall.c -@@ -83,6 +83,7 @@ struct KbdintAuthctxt - void *ctxt; - KbdintDevice *device; - u_int nreq; -+ u_int devices_done; - }; - - #ifdef USE_PAM -@@ -169,11 +170,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) - if (len == 0) - break; - for (i = 0; devices[i]; i++) { -- if (!auth2_method_allowed(authctxt, -+ if ((kbdintctxt->devices_done & (1 << i)) != 0 || -+ !auth2_method_allowed(authctxt, - "keyboard-interactive", devices[i]->name)) - continue; -- if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) -+ if (strncmp(kbdintctxt->devices, devices[i]->name, -+ len) == 0) { - kbdintctxt->device = devices[i]; -+ kbdintctxt->devices_done |= 1 << i; -+ } - } - t = kbdintctxt->devices; - kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; --- -cgit v0.11.2 - - diff --git a/openssh-6.9p1-permit-root-login.patch b/openssh-6.9p1-permit-root-login.patch index 5d9df7c..6b4c4da 100644 --- a/openssh-6.9p1-permit-root-login.patch +++ b/openssh-6.9p1-permit-root-login.patch @@ -1,27 +1,12 @@ -diff --git a/sshd_config b/sshd_config -index c9042ac..cf7d8e1 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -41,7 +41,7 @@ +diff -up openssh-7.0p1/sshd_config.root-login openssh-7.0p1/sshd_config +--- openssh-7.0p1/sshd_config.root-login 2015-08-12 11:29:12.919269245 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-12 11:31:03.653096466 +0200 +@@ -46,7 +46,7 @@ SyslogFacility AUTHPRIV # Authentication: #LoginGraceTime 2m --#PermitRootLogin no -+#PermitRootLogin yes +-#PermitRootLogin prohibit-password ++PermitRootLogin yes #StrictModes yes #MaxAuthTries 6 #MaxSessions 10 -diff --git a/sshd_config.5 b/sshd_config.5 -index 2bc9360..d3148c2 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1093,7 +1093,7 @@ The argument must be - or - .Dq no . - The default is --.Dq no . -+.Dq yes . - .Pp - If this option is set to - .Dq without-password , - diff --git a/openssh-6.9p1-gsissh.patch b/openssh-7.0p1-gsissh.patch similarity index 91% rename from openssh-6.9p1-gsissh.patch rename to openssh-7.0p1-gsissh.patch index 0244e15..cd744f2 100644 --- a/openssh-6.9p1-gsissh.patch +++ b/openssh-7.0p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-6.9p1.orig/auth2.c openssh-6.9p1/auth2.c ---- openssh-6.9p1.orig/auth2.c 2015-07-05 06:20:20.854038226 +0200 -+++ openssh-6.9p1/auth2.c 2015-07-05 06:32:05.325048953 +0200 +diff -Nur openssh-7.0p1.orig/auth2.c openssh-7.0p1/auth2.c +--- openssh-7.0p1.orig/auth2.c 2015-08-14 15:14:30.846969900 +0200 ++++ openssh-7.0p1/auth2.c 2015-08-14 15:14:58.052661231 +0200 @@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -120,9 +120,9 @@ diff -Nur openssh-6.9p1.orig/auth2.c openssh-6.9p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-6.9p1.orig/auth2-gss.c openssh-6.9p1/auth2-gss.c ---- openssh-6.9p1.orig/auth2-gss.c 2015-07-05 06:20:20.757037262 +0200 -+++ openssh-6.9p1/auth2-gss.c 2015-07-05 06:32:05.326048963 +0200 +diff -Nur openssh-7.0p1.orig/auth2-gss.c openssh-7.0p1/auth2-gss.c +--- openssh-7.0p1.orig/auth2-gss.c 2015-08-14 15:14:30.776970694 +0200 ++++ openssh-7.0p1/auth2-gss.c 2015-08-14 15:14:58.053661220 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -303,9 +303,9 @@ diff -Nur openssh-6.9p1.orig/auth2-gss.c openssh-6.9p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-6.9p1.orig/auth.c openssh-6.9p1/auth.c ---- openssh-6.9p1.orig/auth.c 2015-07-05 06:20:20.855038236 +0200 -+++ openssh-6.9p1/auth.c 2015-07-05 06:32:05.327048973 +0200 +diff -Nur openssh-7.0p1.orig/auth.c openssh-7.0p1/auth.c +--- openssh-7.0p1.orig/auth.c 2015-08-14 15:14:30.847969888 +0200 ++++ openssh-7.0p1/auth.c 2015-08-14 15:14:58.053661220 +0200 @@ -75,6 +75,9 @@ #include "ssherr.h" #include "compat.h" @@ -350,7 +350,7 @@ diff -Nur openssh-6.9p1.orig/auth.c openssh-6.9p1/auth.c } -@@ -619,6 +640,10 @@ +@@ -621,6 +642,10 @@ #endif pw = getpwnam(user); @@ -361,7 +361,7 @@ diff -Nur openssh-6.9p1.orig/auth.c openssh-6.9p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -638,7 +663,8 @@ +@@ -640,7 +665,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -371,9 +371,9 @@ diff -Nur openssh-6.9p1.orig/auth.c openssh-6.9p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-6.9p1.orig/auth-pam.c openssh-6.9p1/auth-pam.c ---- openssh-6.9p1.orig/auth-pam.c 2015-07-05 06:20:20.874038425 +0200 -+++ openssh-6.9p1/auth-pam.c 2015-07-05 06:32:05.328048983 +0200 +diff -Nur openssh-7.0p1.orig/auth-pam.c openssh-7.0p1/auth-pam.c +--- openssh-7.0p1.orig/auth-pam.c 2015-08-14 15:14:30.863969707 +0200 ++++ openssh-7.0p1/auth-pam.c 2015-08-14 15:14:58.054661208 +0200 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -524,9 +524,9 @@ diff -Nur openssh-6.9p1.orig/auth-pam.c openssh-6.9p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-6.9p1.orig/auth-pam.h openssh-6.9p1/auth-pam.h ---- openssh-6.9p1.orig/auth-pam.h 2015-07-05 06:20:20.669036387 +0200 -+++ openssh-6.9p1/auth-pam.h 2015-07-05 06:32:05.328048983 +0200 +diff -Nur openssh-7.0p1.orig/auth-pam.h openssh-7.0p1/auth-pam.h +--- openssh-7.0p1.orig/auth-pam.h 2015-08-14 15:14:30.715971386 +0200 ++++ openssh-7.0p1/auth-pam.h 2015-08-14 15:14:58.055661197 +0200 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -534,9 +534,9 @@ diff -Nur openssh-6.9p1.orig/auth-pam.h openssh-6.9p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-6.9p1.orig/canohost.c openssh-6.9p1/canohost.c ---- openssh-6.9p1.orig/canohost.c 2015-07-05 06:20:20.795037639 +0200 -+++ openssh-6.9p1/canohost.c 2015-07-05 06:32:05.329048993 +0200 +diff -Nur openssh-7.0p1.orig/canohost.c openssh-7.0p1/canohost.c +--- openssh-7.0p1.orig/canohost.c 2015-08-14 15:14:30.802970399 +0200 ++++ openssh-7.0p1/canohost.c 2015-08-14 15:14:58.055661197 +0200 @@ -17,6 +17,7 @@ #include #include @@ -579,9 +579,9 @@ diff -Nur openssh-6.9p1.orig/canohost.c openssh-6.9p1/canohost.c + } + } +} -diff -Nur openssh-6.9p1.orig/canohost.h openssh-6.9p1/canohost.h ---- openssh-6.9p1.orig/canohost.h 2015-07-05 06:20:20.795037639 +0200 -+++ openssh-6.9p1/canohost.h 2015-07-05 06:32:05.329048993 +0200 +diff -Nur openssh-7.0p1.orig/canohost.h openssh-7.0p1/canohost.h +--- openssh-7.0p1.orig/canohost.h 2015-08-14 15:14:30.802970399 +0200 ++++ openssh-7.0p1/canohost.h 2015-08-14 15:14:58.055661197 +0200 @@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -589,10 +589,10 @@ diff -Nur openssh-6.9p1.orig/canohost.h openssh-6.9p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-6.9p1.orig/configure.ac openssh-6.9p1/configure.ac ---- openssh-6.9p1.orig/configure.ac 2015-07-05 06:20:20.833038017 +0200 -+++ openssh-6.9p1/configure.ac 2015-07-05 06:32:05.331049013 +0200 -@@ -4249,6 +4249,14 @@ +diff -Nur openssh-7.0p1.orig/configure.ac openssh-7.0p1/configure.ac +--- openssh-7.0p1.orig/configure.ac 2015-08-14 15:14:30.832970059 +0200 ++++ openssh-7.0p1/configure.ac 2015-08-14 15:14:58.057661174 +0200 +@@ -4280,6 +4280,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -607,7 +607,7 @@ diff -Nur openssh-6.9p1.orig/configure.ac openssh-6.9p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4288,6 +4296,50 @@ +@@ -4319,6 +4327,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -658,9 +658,9 @@ diff -Nur openssh-6.9p1.orig/configure.ac openssh-6.9p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-6.9p1.orig/gss-genr.c openssh-6.9p1/gss-genr.c ---- openssh-6.9p1.orig/gss-genr.c 2015-07-05 06:20:20.760037292 +0200 -+++ openssh-6.9p1/gss-genr.c 2015-07-05 06:32:05.332049022 +0200 +diff -Nur openssh-7.0p1.orig/gss-genr.c openssh-7.0p1/gss-genr.c +--- openssh-7.0p1.orig/gss-genr.c 2015-08-14 15:14:30.777970683 +0200 ++++ openssh-7.0p1/gss-genr.c 2015-08-14 15:14:58.057661174 +0200 @@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -697,9 +697,9 @@ diff -Nur openssh-6.9p1.orig/gss-genr.c openssh-6.9p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-6.9p1.orig/gss-serv.c openssh-6.9p1/gss-serv.c ---- openssh-6.9p1.orig/gss-serv.c 2015-07-05 06:20:20.760037292 +0200 -+++ openssh-6.9p1/gss-serv.c 2015-07-05 06:32:05.333049032 +0200 +diff -Nur openssh-7.0p1.orig/gss-serv.c openssh-7.0p1/gss-serv.c +--- openssh-7.0p1.orig/gss-serv.c 2015-08-14 15:14:30.778970671 +0200 ++++ openssh-7.0p1/gss-serv.c 2015-08-14 15:14:58.058661163 +0200 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -938,9 +938,9 @@ diff -Nur openssh-6.9p1.orig/gss-serv.c openssh-6.9p1/gss-serv.c +} + #endif -diff -Nur openssh-6.9p1.orig/gss-serv-gsi.c openssh-6.9p1/gss-serv-gsi.c ---- openssh-6.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.9p1/gss-serv-gsi.c 2015-07-05 06:32:05.334049042 +0200 +diff -Nur openssh-7.0p1.orig/gss-serv-gsi.c openssh-7.0p1/gss-serv-gsi.c +--- openssh-7.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.0p1/gss-serv-gsi.c 2015-08-14 15:14:58.058661163 +0200 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1181,9 +1181,9 @@ diff -Nur openssh-6.9p1.orig/gss-serv-gsi.c openssh-6.9p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-6.9p1.orig/gss-serv-krb5.c openssh-6.9p1/gss-serv-krb5.c ---- openssh-6.9p1.orig/gss-serv-krb5.c 2015-07-05 06:20:20.827037957 +0200 -+++ openssh-6.9p1/gss-serv-krb5.c 2015-07-05 06:32:05.334049042 +0200 +diff -Nur openssh-7.0p1.orig/gss-serv-krb5.c openssh-7.0p1/gss-serv-krb5.c +--- openssh-7.0p1.orig/gss-serv-krb5.c 2015-08-14 15:14:30.820970195 +0200 ++++ openssh-7.0p1/gss-serv-krb5.c 2015-08-14 15:14:58.058661163 +0200 @@ -359,6 +359,34 @@ return found_principal; } @@ -1237,9 +1237,9 @@ diff -Nur openssh-6.9p1.orig/gss-serv-krb5.c openssh-6.9p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-6.9p1.orig/kexgsss.c openssh-6.9p1/kexgsss.c ---- openssh-6.9p1.orig/kexgsss.c 2015-07-05 06:20:20.762037311 +0200 -+++ openssh-6.9p1/kexgsss.c 2015-07-05 06:32:05.335049052 +0200 +diff -Nur openssh-7.0p1.orig/kexgsss.c openssh-7.0p1/kexgsss.c +--- openssh-7.0p1.orig/kexgsss.c 2015-08-14 15:14:30.779970660 +0200 ++++ openssh-7.0p1/kexgsss.c 2015-08-14 15:14:58.058661163 +0200 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1299,9 +1299,9 @@ diff -Nur openssh-6.9p1.orig/kexgsss.c openssh-6.9p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-6.9p1.orig/LICENSE.globus_usage openssh-6.9p1/LICENSE.globus_usage ---- openssh-6.9p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.9p1/LICENSE.globus_usage 2015-07-05 06:32:05.335049052 +0200 +diff -Nur openssh-7.0p1.orig/LICENSE.globus_usage openssh-7.0p1/LICENSE.globus_usage +--- openssh-7.0p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.0p1/LICENSE.globus_usage 2015-08-14 15:14:58.058661163 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1321,9 +1321,9 @@ diff -Nur openssh-6.9p1.orig/LICENSE.globus_usage openssh-6.9p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-6.9p1.orig/Makefile.in openssh-6.9p1/Makefile.in ---- openssh-6.9p1.orig/Makefile.in 2015-07-05 06:20:20.867038355 +0200 -+++ openssh-6.9p1/Makefile.in 2015-07-05 06:32:05.335049052 +0200 +diff -Nur openssh-7.0p1.orig/Makefile.in openssh-7.0p1/Makefile.in +--- openssh-7.0p1.orig/Makefile.in 2015-08-14 15:14:30.857969775 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-14 15:14:58.059661152 +0200 @@ -113,8 +113,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ @@ -1335,9 +1335,9 @@ diff -Nur openssh-6.9p1.orig/Makefile.in openssh-6.9p1/Makefile.in roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o -diff -Nur openssh-6.9p1.orig/misc.c openssh-6.9p1/misc.c ---- openssh-6.9p1.orig/misc.c 2015-07-05 06:20:20.825037938 +0200 -+++ openssh-6.9p1/misc.c 2015-07-05 06:32:05.336049062 +0200 +diff -Nur openssh-7.0p1.orig/misc.c openssh-7.0p1/misc.c +--- openssh-7.0p1.orig/misc.c 2015-08-14 15:14:30.819970206 +0200 ++++ openssh-7.0p1/misc.c 2015-08-14 15:14:58.059661152 +0200 @@ -160,11 +160,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1397,9 +1397,9 @@ diff -Nur openssh-6.9p1.orig/misc.c openssh-6.9p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-6.9p1.orig/misc.h openssh-6.9p1/misc.h ---- openssh-6.9p1.orig/misc.h 2015-07-05 06:20:20.799037679 +0200 -+++ openssh-6.9p1/misc.h 2015-07-05 06:32:05.336049062 +0200 +diff -Nur openssh-7.0p1.orig/misc.h openssh-7.0p1/misc.h +--- openssh-7.0p1.orig/misc.h 2015-08-14 15:14:30.804970376 +0200 ++++ openssh-7.0p1/misc.h 2015-08-14 15:14:58.059661152 +0200 @@ -61,6 +61,7 @@ void sock_set_v6only(int); @@ -1408,9 +1408,9 @@ diff -Nur openssh-6.9p1.orig/misc.h openssh-6.9p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-6.9p1.orig/monitor.c openssh-6.9p1/monitor.c ---- openssh-6.9p1.orig/monitor.c 2015-07-05 06:20:20.876038445 +0200 -+++ openssh-6.9p1/monitor.c 2015-07-05 06:32:05.338049082 +0200 +diff -Nur openssh-7.0p1.orig/monitor.c openssh-7.0p1/monitor.c +--- openssh-7.0p1.orig/monitor.c 2015-08-14 15:14:30.864969696 +0200 ++++ openssh-7.0p1/monitor.c 2015-08-14 15:14:58.060661140 +0200 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1602,9 +1602,9 @@ diff -Nur openssh-6.9p1.orig/monitor.c openssh-6.9p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-6.9p1.orig/monitor.h openssh-6.9p1/monitor.h ---- openssh-6.9p1.orig/monitor.h 2015-07-05 06:20:20.858038266 +0200 -+++ openssh-6.9p1/monitor.h 2015-07-05 06:32:05.339049092 +0200 +diff -Nur openssh-7.0p1.orig/monitor.h openssh-7.0p1/monitor.h +--- openssh-7.0p1.orig/monitor.h 2015-08-14 15:14:30.849969866 +0200 ++++ openssh-7.0p1/monitor.h 2015-08-14 15:14:58.060661140 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1618,10 +1618,10 @@ diff -Nur openssh-6.9p1.orig/monitor.h openssh-6.9p1/monitor.h }; struct mm_master; -diff -Nur openssh-6.9p1.orig/monitor_wrap.c openssh-6.9p1/monitor_wrap.c ---- openssh-6.9p1.orig/monitor_wrap.c 2015-07-05 06:20:20.876038445 +0200 -+++ openssh-6.9p1/monitor_wrap.c 2015-07-05 06:32:05.339049092 +0200 -@@ -1122,12 +1122,13 @@ +diff -Nur openssh-7.0p1.orig/monitor_wrap.c openssh-7.0p1/monitor_wrap.c +--- openssh-7.0p1.orig/monitor_wrap.c 2015-08-14 15:14:30.864969696 +0200 ++++ openssh-7.0p1/monitor_wrap.c 2015-08-14 15:14:58.060661140 +0200 +@@ -1121,12 +1121,13 @@ } int @@ -1636,7 +1636,7 @@ diff -Nur openssh-6.9p1.orig/monitor_wrap.c openssh-6.9p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1140,6 +1141,83 @@ +@@ -1139,6 +1140,83 @@ return (authenticated); } @@ -1720,9 +1720,9 @@ diff -Nur openssh-6.9p1.orig/monitor_wrap.c openssh-6.9p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-6.9p1.orig/monitor_wrap.h openssh-6.9p1/monitor_wrap.h ---- openssh-6.9p1.orig/monitor_wrap.h 2015-07-05 06:20:20.858038266 +0200 -+++ openssh-6.9p1/monitor_wrap.h 2015-07-05 06:32:05.340049102 +0200 +diff -Nur openssh-7.0p1.orig/monitor_wrap.h openssh-7.0p1/monitor_wrap.h +--- openssh-7.0p1.orig/monitor_wrap.h 2015-08-14 15:14:30.850969854 +0200 ++++ openssh-7.0p1/monitor_wrap.h 2015-08-14 15:14:58.061661129 +0200 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1738,10 +1738,10 @@ diff -Nur openssh-6.9p1.orig/monitor_wrap.h openssh-6.9p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-6.9p1.orig/readconf.c openssh-6.9p1/readconf.c ---- openssh-6.9p1.orig/readconf.c 2015-07-05 06:20:20.765037341 +0200 -+++ openssh-6.9p1/readconf.c 2015-07-05 06:32:05.341049112 +0200 -@@ -1763,13 +1763,13 @@ +diff -Nur openssh-7.0p1.orig/readconf.c openssh-7.0p1/readconf.c +--- openssh-7.0p1.orig/readconf.c 2015-08-14 15:14:30.858969764 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-14 15:14:58.061661129 +0200 +@@ -1764,13 +1764,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1759,9 +1759,9 @@ diff -Nur openssh-6.9p1.orig/readconf.c openssh-6.9p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; if (options->password_authentication == -1) -diff -Nur openssh-6.9p1.orig/readconf.h openssh-6.9p1/readconf.h ---- openssh-6.9p1.orig/readconf.h 2015-07-05 06:20:20.765037341 +0200 -+++ openssh-6.9p1/readconf.h 2015-07-05 06:32:05.342049122 +0200 +diff -Nur openssh-7.0p1.orig/readconf.h openssh-7.0p1/readconf.h +--- openssh-7.0p1.orig/readconf.h 2015-08-14 15:14:30.781970637 +0200 ++++ openssh-7.0p1/readconf.h 2015-08-14 15:14:58.062661118 +0200 @@ -84,6 +84,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1771,10 +1771,10 @@ diff -Nur openssh-6.9p1.orig/readconf.h openssh-6.9p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c ---- openssh-6.9p1.orig/servconf.c 2015-07-05 06:20:20.878038464 +0200 -+++ openssh-6.9p1/servconf.c 2015-07-05 06:24:25.111466911 +0200 -@@ -73,6 +73,7 @@ +diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c +--- openssh-7.0p1.orig/servconf.c 2015-08-14 15:14:30.865969684 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-14 15:14:58.063661106 +0200 +@@ -74,6 +74,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1782,7 +1782,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -115,9 +116,11 @@ +@@ -117,9 +118,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1794,7 +1794,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c options->gss_store_rekey = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; -@@ -161,6 +164,8 @@ +@@ -163,6 +166,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1803,7 +1803,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -189,6 +194,8 @@ +@@ -191,6 +196,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1832,7 +1832,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; if (options->password_authentication == -1) -@@ -394,7 +405,7 @@ +@@ -407,7 +418,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1841,9 +1841,9 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -415,10 +426,14 @@ - sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, +@@ -429,10 +440,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, @@ -1856,7 +1856,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -443,8 +458,10 @@ +@@ -457,8 +472,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1867,7 +1867,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -489,14 +506,24 @@ +@@ -504,14 +521,24 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1892,7 +1892,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -559,6 +586,8 @@ +@@ -574,6 +601,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1901,7 +1901,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1013,6 +1042,10 @@ +@@ -1029,6 +1058,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1912,7 +1912,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1240,6 +1273,10 @@ +@@ -1260,6 +1293,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1923,7 +1923,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1248,6 +1285,10 @@ +@@ -1268,6 +1305,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1934,7 +1934,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1256,6 +1297,12 @@ +@@ -1276,6 +1317,12 @@ intptr = &options->gss_store_rekey; goto parse_flag; @@ -1947,7 +1947,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1730,6 +1777,35 @@ +@@ -1750,6 +1797,35 @@ *charptr = xstrdup(arg); break; @@ -1983,7 +1983,7 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2006,6 +2082,7 @@ +@@ -2026,6 +2102,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1991,10 +1991,10 @@ diff -Nur openssh-6.9p1.orig/servconf.c openssh-6.9p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-6.9p1.orig/servconf.h openssh-6.9p1/servconf.h ---- openssh-6.9p1.orig/servconf.h 2015-07-05 06:20:20.829037977 +0200 -+++ openssh-6.9p1/servconf.h 2015-07-05 06:34:39.373582712 +0200 -@@ -116,9 +116,12 @@ +diff -Nur openssh-7.0p1.orig/servconf.h openssh-7.0p1/servconf.h +--- openssh-7.0p1.orig/servconf.h 2015-08-14 15:14:30.821970183 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-14 15:14:58.063661106 +0200 +@@ -117,9 +117,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -2007,7 +2007,7 @@ diff -Nur openssh-6.9p1.orig/servconf.h openssh-6.9p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; int password_authentication; /* If true, permit password -@@ -174,6 +177,7 @@ +@@ -175,6 +178,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2015,7 +2015,7 @@ diff -Nur openssh-6.9p1.orig/servconf.h openssh-6.9p1/servconf.h int permit_tun; -@@ -182,6 +186,10 @@ +@@ -183,6 +187,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2026,10 +2026,10 @@ diff -Nur openssh-6.9p1.orig/servconf.h openssh-6.9p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-6.9p1.orig/ssh.1 openssh-6.9p1/ssh.1 ---- openssh-6.9p1.orig/ssh.1 2015-07-05 06:20:20.837038057 +0200 -+++ openssh-6.9p1/ssh.1 2015-07-05 06:32:05.345049152 +0200 -@@ -1318,6 +1318,18 @@ +diff -Nur openssh-7.0p1.orig/ssh.1 openssh-7.0p1/ssh.1 +--- openssh-7.0p1.orig/ssh.1 2015-08-14 15:14:30.827970115 +0200 ++++ openssh-7.0p1/ssh.1 2015-08-14 15:14:58.064661095 +0200 +@@ -1405,6 +1405,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2048,10 +2048,10 @@ diff -Nur openssh-6.9p1.orig/ssh.1 openssh-6.9p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-6.9p1.orig/ssh.c openssh-6.9p1/ssh.c ---- openssh-6.9p1.orig/ssh.c 2015-07-05 06:20:20.868038365 +0200 -+++ openssh-6.9p1/ssh.c 2015-07-05 06:32:05.346049162 +0200 -@@ -464,6 +464,32 @@ +diff -Nur openssh-7.0p1.orig/ssh.c openssh-7.0p1/ssh.c +--- openssh-7.0p1.orig/ssh.c 2015-08-14 15:14:30.859969752 +0200 ++++ openssh-7.0p1/ssh.c 2015-08-14 15:14:58.064661095 +0200 +@@ -465,6 +465,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2084,7 +2084,7 @@ diff -Nur openssh-6.9p1.orig/ssh.c openssh-6.9p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1129,8 +1155,12 @@ +@@ -1130,8 +1156,12 @@ logit("FIPS mode initialized"); } @@ -2098,9 +2098,9 @@ diff -Nur openssh-6.9p1.orig/ssh.c openssh-6.9p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-6.9p1.orig/ssh_config openssh-6.9p1/ssh_config ---- openssh-6.9p1.orig/ssh_config 2015-07-05 06:20:20.768037371 +0200 -+++ openssh-6.9p1/ssh_config 2015-07-05 06:32:05.346049162 +0200 +diff -Nur openssh-7.0p1.orig/ssh_config openssh-7.0p1/ssh_config +--- openssh-7.0p1.orig/ssh_config 2015-08-14 15:14:30.783970615 +0200 ++++ openssh-7.0p1/ssh_config 2015-08-14 15:14:58.065661084 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2116,9 +2116,9 @@ diff -Nur openssh-6.9p1.orig/ssh_config openssh-6.9p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-6.9p1.orig/ssh_config.5 openssh-6.9p1/ssh_config.5 ---- openssh-6.9p1.orig/ssh_config.5 2015-07-05 06:20:20.768037371 +0200 -+++ openssh-6.9p1/ssh_config.5 2015-07-05 06:32:05.347049172 +0200 +diff -Nur openssh-7.0p1.orig/ssh_config.5 openssh-7.0p1/ssh_config.5 +--- openssh-7.0p1.orig/ssh_config.5 2015-08-14 15:14:30.783970615 +0200 ++++ openssh-7.0p1/ssh_config.5 2015-08-14 15:14:58.065661084 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2132,10 +2132,10 @@ diff -Nur openssh-6.9p1.orig/ssh_config.5 openssh-6.9p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c ---- openssh-6.9p1.orig/sshconnect2.c 2015-07-05 06:20:20.869038375 +0200 -+++ openssh-6.9p1/sshconnect2.c 2015-07-05 06:32:05.347049172 +0200 -@@ -747,6 +747,11 @@ +diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c +--- openssh-7.0p1.orig/sshconnect2.c 2015-08-14 15:14:30.859969752 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-14 15:14:58.066661072 +0200 +@@ -698,6 +698,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2147,7 +2147,7 @@ diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -984,6 +989,15 @@ +@@ -935,6 +940,15 @@ return 0; } @@ -2163,7 +2163,7 @@ diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -1001,8 +1015,16 @@ +@@ -952,8 +966,16 @@ return (0); } @@ -2180,7 +2180,7 @@ diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -1013,7 +1035,15 @@ +@@ -964,7 +986,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2196,10 +2196,10 @@ diff -Nur openssh-6.9p1.orig/sshconnect2.c openssh-6.9p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-6.9p1.orig/sshd.8 openssh-6.9p1/sshd.8 ---- openssh-6.9p1.orig/sshd.8 2015-07-05 06:20:20.834038027 +0200 -+++ openssh-6.9p1/sshd.8 2015-07-05 06:32:05.348049182 +0200 -@@ -768,6 +768,44 @@ +diff -Nur openssh-7.0p1.orig/sshd.8 openssh-7.0p1/sshd.8 +--- openssh-7.0p1.orig/sshd.8 2015-08-14 15:14:30.824970149 +0200 ++++ openssh-7.0p1/sshd.8 2015-08-14 15:14:58.066661072 +0200 +@@ -765,6 +765,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2244,10 +2244,10 @@ diff -Nur openssh-6.9p1.orig/sshd.8 openssh-6.9p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-6.9p1.orig/sshd.c openssh-6.9p1/sshd.c ---- openssh-6.9p1.orig/sshd.c 2015-07-05 06:20:20.880038484 +0200 -+++ openssh-6.9p1/sshd.c 2015-07-05 06:32:05.349049192 +0200 -@@ -128,6 +128,7 @@ +diff -Nur openssh-7.0p1.orig/sshd.c openssh-7.0p1/sshd.c +--- openssh-7.0p1.orig/sshd.c 2015-08-14 15:14:30.867969662 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-14 15:14:58.067661061 +0200 +@@ -129,6 +129,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -2255,7 +2255,7 @@ diff -Nur openssh-6.9p1.orig/sshd.c openssh-6.9p1/sshd.c #ifdef LIBWRAP #include -@@ -1790,6 +1791,13 @@ +@@ -1794,6 +1795,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2269,7 +2269,7 @@ diff -Nur openssh-6.9p1.orig/sshd.c openssh-6.9p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2355,7 +2363,7 @@ +@@ -2359,7 +2367,7 @@ #endif #ifdef GSSAPI @@ -2278,9 +2278,9 @@ diff -Nur openssh-6.9p1.orig/sshd.c openssh-6.9p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-6.9p1.orig/sshd_config openssh-6.9p1/sshd_config ---- openssh-6.9p1.orig/sshd_config 2015-07-05 06:20:20.850038186 +0200 -+++ openssh-6.9p1/sshd_config 2015-07-05 06:32:05.349049192 +0200 +diff -Nur openssh-7.0p1.orig/sshd_config openssh-7.0p1/sshd_config +--- openssh-7.0p1.orig/sshd_config 2015-08-14 15:14:30.841969957 +0200 ++++ openssh-7.0p1/sshd_config 2015-08-14 15:14:58.068661050 +0200 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2313,10 +2313,10 @@ diff -Nur openssh-6.9p1.orig/sshd_config openssh-6.9p1/sshd_config + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 -diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 ---- openssh-6.9p1.orig/sshd_config.5 2015-07-05 06:20:20.850038186 +0200 -+++ openssh-6.9p1/sshd_config.5 2015-07-05 06:32:05.350049202 +0200 -@@ -564,6 +564,15 @@ +diff -Nur openssh-7.0p1.orig/sshd_config.5 openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1.orig/sshd_config.5 2015-08-14 15:14:30.821970183 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-14 15:14:58.068661050 +0200 +@@ -569,6 +569,15 @@ See PATTERNS in .Xr ssh_config 5 for more information on patterns. @@ -2332,7 +2332,7 @@ diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: -@@ -616,6 +625,10 @@ +@@ -621,6 +630,10 @@ The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2343,7 +2343,7 @@ diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 .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. -@@ -634,6 +647,22 @@ +@@ -639,6 +652,22 @@ .Xr ksu 1 . The default is .Dq no . @@ -2366,7 +2366,7 @@ diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1461,6 +1490,103 @@ +@@ -1528,6 +1557,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2470,7 +2470,7 @@ diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -1528,6 +1654,12 @@ +@@ -1604,6 +1730,12 @@ as a non-root user. The default is .Dq no . @@ -2483,9 +2483,9 @@ diff -Nur openssh-6.9p1.orig/sshd_config.5 openssh-6.9p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-6.9p1.orig/ssh-globus-usage.c openssh-6.9p1/ssh-globus-usage.c ---- openssh-6.9p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.9p1/ssh-globus-usage.c 2015-07-05 06:32:05.350049202 +0200 +diff -Nur openssh-7.0p1.orig/ssh-globus-usage.c openssh-7.0p1/ssh-globus-usage.c +--- openssh-7.0p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.0p1/ssh-globus-usage.c 2015-08-14 15:14:58.069661038 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2883,9 +2883,9 @@ diff -Nur openssh-6.9p1.orig/ssh-globus-usage.c openssh-6.9p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-6.9p1.orig/ssh-globus-usage.h openssh-6.9p1/ssh-globus-usage.h ---- openssh-6.9p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-6.9p1/ssh-globus-usage.h 2015-07-05 06:32:05.350049202 +0200 +diff -Nur openssh-7.0p1.orig/ssh-globus-usage.h openssh-7.0p1/ssh-globus-usage.h +--- openssh-7.0p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.0p1/ssh-globus-usage.h 2015-08-14 15:14:58.069661038 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2935,9 +2935,9 @@ diff -Nur openssh-6.9p1.orig/ssh-globus-usage.h openssh-6.9p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-6.9p1.orig/ssh-gss.h openssh-6.9p1/ssh-gss.h ---- openssh-6.9p1.orig/ssh-gss.h 2015-07-05 06:20:20.773037421 +0200 -+++ openssh-6.9p1/ssh-gss.h 2015-07-05 06:32:05.351049212 +0200 +diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h +--- openssh-7.0p1.orig/ssh-gss.h 2015-08-14 15:14:30.788970558 +0200 ++++ openssh-7.0p1/ssh-gss.h 2015-08-14 15:14:58.069661038 +0200 @@ -91,6 +91,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2982,11 +2982,11 @@ diff -Nur openssh-6.9p1.orig/ssh-gss.h openssh-6.9p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-6.9p1.orig/version.h openssh-6.9p1/version.h ---- openssh-6.9p1.orig/version.h 2015-07-01 04:35:31.000000000 +0200 -+++ openssh-6.9p1/version.h 2015-07-05 06:32:05.351049212 +0200 +diff -Nur openssh-7.0p1.orig/version.h openssh-7.0p1/version.h +--- openssh-7.0p1.orig/version.h 2015-08-11 10:57:29.000000000 +0200 ++++ openssh-7.0p1/version.h 2015-08-14 15:14:58.069661038 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.73 2015/07/01 01:55:13 djm Exp $ */ + /* $OpenBSD: version.h,v 1.74 2015/08/02 09:56:42 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3000,9 +3000,9 @@ diff -Nur openssh-6.9p1.orig/version.h openssh-6.9p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20150323" ++#define NCSA_VERSION " GSI_GSSAPI_20150812" + - #define SSH_VERSION "OpenSSH_6.9" + #define SSH_VERSION "OpenSSH_7.0" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/sources b/sources index d719f82..30ece94 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -0b161c44fc31fbc6b76a6f8ae639f16f openssh-6.9p1.tar.gz +831883f251ac34f0ab9c812acc24ee69 openssh-7.0p1.tar.gz From ae3d65d08a65fdfd966a62ca974cdaf470d702b1 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 24 Aug 2015 21:05:12 +0200 Subject: [PATCH 017/146] Based on openssh-7.1p1-1.fc23 --- gsi-openssh.spec | 19 +- openssh-6.7p1-fips.patch | 76 ++-- openssh-7.0p1-gssKexAlgorithms.patch | 405 ++++++++++++++++++ openssh-7.0p1-show-more-fingerprints.patch | 318 ++++++++++++++ ...gsissh.patch => openssh-7.1p1-gsissh.patch | 318 +++++++------- openssh-7.1p1-hostkeyalgorithms.patch | 46 ++ sources | 2 +- 7 files changed, 985 insertions(+), 199 deletions(-) create mode 100644 openssh-7.0p1-gssKexAlgorithms.patch create mode 100644 openssh-7.0p1-show-more-fingerprints.patch rename openssh-7.0p1-gsissh.patch => openssh-7.1p1-gsissh.patch (90%) create mode 100644 openssh-7.1p1-hostkeyalgorithms.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 2fdde9a..f49de66 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,7 +30,7 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.0p1 +%global openssh_ver 7.1p1 %global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication @@ -167,10 +167,17 @@ Patch928: openssh-6.8p1-memory-problems.patch Patch929: openssh-6.9p1-permit-root-login.patch # Handle terminal control characters in scp progressmeter (#1247204) Patch931: openssh-6.9p1-scp-progressmeter.patch +# Add GSSAPIKexAlgorithms option for server and client application +Patch932: openssh-7.0p1-gssKexAlgorithms.patch +# Possibility to validate legacy systems by more fingerprints (#1249626)(#2439) +Patch933: openssh-7.0p1-show-more-fingerprints.patch +# Brokend HostKeyAlgorthms on server using + sign +# from http://lists.mindrot.org/pipermail/openssh-unix-dev/2015-August/034324.html +Patch934: openssh-7.1p1-hostkeyalgorithms.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch -Patch98: openssh-7.0p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.1p1.patch +Patch98: openssh-7.1p1-gsissh.patch License: BSD Group: Applications/Internet @@ -325,6 +332,9 @@ This version of OpenSSH has been modified to support GSI authentication. %patch928 -p1 -b .memory %patch929 -p1 -b .root-login %patch931 -p1 -b .progressmeter +%patch932 -p1 -b .gsskexalg +%patch933 -p1 -b .fingerprint +%patch934 -p1 -b .hosttkey %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -541,6 +551,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Aug 24 2015 Mattias Ellert - 7.1p1-1 +- Based on openssh-7.1p1-1.fc23 + * Fri Aug 14 2015 Mattias Ellert - 7.0p1-1 - Based on openssh-7.0p1-1.fc23 diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index 923793d..9a743b1 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -1,6 +1,6 @@ diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c ---- openssh-7.0p1/cipher.c.fips 2015-08-12 11:34:11.722803020 +0200 -+++ openssh-7.0p1/cipher.c 2015-08-12 11:34:11.733803003 +0200 +--- openssh-7.0p1/cipher.c.fips 2015-08-19 12:36:51.144412908 +0200 ++++ openssh-7.0p1/cipher.c 2015-08-19 12:36:51.150412894 +0200 @@ -39,6 +39,8 @@ #include @@ -74,8 +74,8 @@ diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c return c->number; return -1; diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c ---- openssh-7.0p1/cipher-ctr.c.fips 2015-08-12 11:34:11.650803133 +0200 -+++ openssh-7.0p1/cipher-ctr.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/cipher-ctr.c.fips 2015-08-19 12:36:51.079413054 +0200 ++++ openssh-7.0p1/cipher-ctr.c 2015-08-19 12:36:51.150412894 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -88,7 +88,7 @@ diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c } diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h --- openssh-7.0p1/dh.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/dh.h 2015-08-12 11:34:11.734803002 +0200 ++++ openssh-7.0p1/dh.h 2015-08-19 12:36:51.150412894 +0200 @@ -46,6 +46,7 @@ u_int dh_estimate(int); /* Min and max values from RFC4419. */ @@ -98,8 +98,8 @@ diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h /* diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c ---- openssh-7.0p1/entropy.c.fips 2015-08-12 11:34:11.643803144 +0200 -+++ openssh-7.0p1/entropy.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/entropy.c.fips 2015-08-19 12:36:51.070413074 +0200 ++++ openssh-7.0p1/entropy.c 2015-08-19 12:36:51.150412894 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -111,8 +111,8 @@ diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.fips 2015-08-12 11:34:11.723803019 +0200 -+++ openssh-7.0p1/kex.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/kex.c.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/kex.c 2015-08-19 12:36:51.151412892 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL @@ -170,7 +170,7 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c } diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c --- openssh-7.0p1/kexgexc.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexc.c 2015-08-12 11:34:11.734803002 +0200 ++++ openssh-7.0p1/kexgexc.c 2015-08-19 12:36:51.151412892 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -190,7 +190,7 @@ diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c if (datafellows & SSH_BUG_DHGEX_LARGE) diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c --- openssh-7.0p1/kexgexs.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexs.c 2015-08-12 11:34:11.735803000 +0200 ++++ openssh-7.0p1/kexgexs.c 2015-08-19 12:36:51.151412892 +0200 @@ -81,11 +81,11 @@ input_kex_dh_gex_request(int type, u_int (r = sshpkt_get_end(ssh)) != 0) goto out; @@ -207,8 +207,8 @@ diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c if (kex->max < kex->min || kex->nbits < kex->min || diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c ---- openssh-7.0p1/mac.c.fips 2015-08-12 11:34:11.725803016 +0200 -+++ openssh-7.0p1/mac.c 2015-08-12 11:34:11.735803000 +0200 +--- openssh-7.0p1/mac.c.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/mac.c 2015-08-19 12:36:51.151412892 +0200 @@ -27,6 +27,8 @@ #include @@ -271,8 +271,8 @@ diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c continue; if (mac != NULL) diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in ---- openssh-7.0p1/Makefile.in.fips 2015-08-12 11:34:11.725803016 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-12 11:34:11.735803000 +0200 +--- openssh-7.0p1/Makefile.in.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-19 12:36:51.151412892 +0200 @@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -316,7 +316,7 @@ diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h --- openssh-7.0p1/myproposal.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/myproposal.h 2015-08-12 11:34:11.735803000 +0200 ++++ openssh-7.0p1/myproposal.h 2015-08-19 12:36:51.151412892 +0200 @@ -138,6 +138,28 @@ "hmac-sha1-96," \ "hmac-md5-96" @@ -347,10 +347,10 @@ diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h #define KEX_SERVER_KEX \ diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c ---- openssh-7.0p1/readconf.c.fips 2015-08-12 14:37:39.206466634 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-12 14:47:00.342350208 +0200 -@@ -1897,9 +1897,12 @@ fill_default_options(Options * options) - options->fingerprint_hash = SSH_FP_HASH_DEFAULT; +--- openssh-7.0p1/readconf.c.fips 2015-08-19 12:36:51.138412921 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-19 12:36:51.152412889 +0200 +@@ -1915,9 +1915,12 @@ fill_default_options(Options * options) + } if (options->update_hostkeys == -1) options->update_hostkeys = 0; - if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || @@ -366,9 +366,9 @@ diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.fips 2015-08-12 11:34:11.714803033 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 14:50:14.608951396 +0200 -@@ -357,9 +357,12 @@ fill_default_server_options(ServerOption +--- openssh-7.0p1/servconf.c.fips 2015-08-19 12:36:51.139412919 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-19 12:36:51.152412889 +0200 +@@ -361,9 +361,12 @@ fill_default_server_options(ServerOption if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -382,9 +382,9 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c + kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS + : KEX_SERVER_KEX), &options->kex_algorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->hostbased_key_types) != 0 || + &options->hostkeyalgorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -@@ -2336,8 +2339,10 @@ dump_config(ServerOptions *o) +@@ -2355,8 +2358,10 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); @@ -397,7 +397,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c 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); -@@ -2352,8 +2357,8 @@ dump_config(ServerOptions *o) +@@ -2371,8 +2376,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); @@ -410,7 +410,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c --- openssh-7.0p1/ssh.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/ssh.c 2015-08-12 11:34:11.736802999 +0200 ++++ openssh-7.0p1/ssh.c 2015-08-19 12:36:51.153412887 +0200 @@ -75,6 +75,8 @@ #include #include @@ -478,8 +478,8 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1/sshconnect2.c.fips 2015-08-12 11:34:11.678803089 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-12 11:34:11.737802997 +0200 +--- openssh-7.0p1/sshconnect2.c.fips 2015-08-19 12:36:51.140412916 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:39:52.455004667 +0200 @@ -44,6 +44,8 @@ #include #endif @@ -489,7 +489,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -170,20 +172,25 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -170,21 +172,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -502,7 +502,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c - else - gss_host = host; - -- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); +- 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], @@ -520,7 +521,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c + else + gss_host = host; + -+ gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); ++ 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], @@ -530,8 +532,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c } #endif diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.fips 2015-08-12 11:34:11.729803010 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-12 11:34:11.738802995 +0200 +--- openssh-7.0p1/sshd.c.fips 2015-08-19 12:36:51.148412898 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-19 12:36:51.153412887 +0200 @@ -66,6 +66,7 @@ #include #include @@ -619,8 +621,8 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c ---- openssh-7.0p1/sshkey.c.fips 2015-08-12 11:34:11.729803010 +0200 -+++ openssh-7.0p1/sshkey.c 2015-08-12 11:34:11.738802995 +0200 +--- openssh-7.0p1/sshkey.c.fips 2015-08-19 12:36:51.148412898 +0200 ++++ openssh-7.0p1/sshkey.c 2015-08-19 12:36:51.154412885 +0200 @@ -35,6 +35,7 @@ #include #include @@ -629,7 +631,7 @@ diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c #endif #include "crypto_api.h" -@@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1552,6 +1553,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch new file mode 100644 index 0000000..9ea42e3 --- /dev/null +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -0,0 +1,405 @@ +diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c +--- openssh-7.0p1/gss-genr.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 ++++ openssh-7.0p1/gss-genr.c 2015-08-19 12:28:38.078518839 +0200 +@@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() { + */ + + char * +-ssh_gssapi_client_mechanisms(const char *host, const char *client) { ++ssh_gssapi_client_mechanisms(const char *host, const char *client, ++ const char *kex) { + gss_OID_set gss_supported; + OM_uint32 min_status; + +@@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char + return NULL; + + return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, +- host, client)); ++ host, client, kex)); + } + + char * + ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, +- const char *host, const char *client) { ++ const char *host, const char *client, const char *kex) { + Buffer buf; + size_t i; + int oidpos, enclen; +@@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + char deroid[2]; + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; ++ char *s, *cp, *p; + + if (gss_enc2oid != NULL) { + for (i = 0; gss_enc2oid[i].encoded != NULL; i++) +@@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + buffer_init(&buf); + + oidpos = 0; ++ s = cp = xstrdup(kex); + for (i = 0; i < gss_supported->count; i++) { + if (gss_supported->elements[i].length < 128 && + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { +@@ -131,26 +134,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + enclen = __b64_ntop(digest, EVP_MD_size(evp_md), + encoded, EVP_MD_size(evp_md) * 2); + +- if (oidpos != 0) +- buffer_put_char(&buf, ','); +- +- buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, +- sizeof(KEX_GSS_GEX_SHA1_ID) - 1); +- buffer_append(&buf, encoded, enclen); +- buffer_put_char(&buf, ','); +- buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, +- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); +- buffer_append(&buf, encoded, enclen); +- buffer_put_char(&buf, ','); +- buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, +- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); +- buffer_append(&buf, encoded, enclen); ++ cp = strncpy(s, kex, strlen(kex)); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (buffer_len(&buf) != 0) ++ buffer_put_char(&buf, ','); ++ buffer_append(&buf, p, ++ strlen(p)); ++ buffer_append(&buf, encoded, enclen); ++ } + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); + gss_enc2oid[oidpos].encoded = encoded; + oidpos++; + } + } ++ free(s); + gss_enc2oid[oidpos].oid = NULL; + gss_enc2oid[oidpos].encoded = NULL; + +diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c +--- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 ++++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200 +@@ -150,7 +150,7 @@ ssh_gssapi_server_mechanisms() { + + ssh_gssapi_supported_oids(&supported); + return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, +- NULL, NULL)); ++ NULL, NULL, options.gss_kex_algorithms)); + } + + /* Unprivileged */ +diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c +--- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200 ++++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200 +@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char + return 0; + } + ++/* Validate GSS KEX method name list */ ++int ++gss_kex_names_valid(const char *names) ++{ ++ char *s, *cp, *p; ++ ++ if (names == NULL || *names == '\0') ++ return 0; ++ s = cp = xstrdup(names); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (strncmp(p, "gss-", 4) != 0 ++ || kex_alg_by_name(p) == NULL) { ++ error("Unsupported KEX algorithm \"%.100s\"", p); ++ free(s); ++ return 0; ++ } ++ } ++ debug3("gss kex names ok: [%s]", names); ++ free(s); ++ return 1; ++} ++ + /* put algorithm proposal into buffer */ + int + kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) +diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h +--- openssh-7.0p1/kex.h.gsskexalg 2015-08-19 12:28:38.078518839 +0200 ++++ openssh-7.0p1/kex.h 2015-08-19 12:30:52.404218958 +0200 +@@ -173,6 +173,7 @@ int kex_names_valid(const char *); + char *kex_alg_list(char); + char *kex_names_cat(const char *, const char *); + int kex_assemble_names(const char *, char **); ++int gss_kex_names_valid(const char *); + + int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); + int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); +diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c +--- openssh-7.0p1/readconf.c.gsskexalg 2015-08-19 12:28:38.026518955 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-19 12:31:28.333138747 +0200 +@@ -61,6 +61,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + /* Format of the configuration file: + +@@ -148,7 +149,7 @@ typedef enum { + oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, + oAddressFamily, oGssAuthentication, oGssDelegateCreds, + oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, +- oGssServerIdentity, ++ oGssServerIdentity, oGssKexAlgorithms, + oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, + oSendEnv, oControlPath, oControlMaster, oControlPersist, + oHashKnownHosts, +@@ -200,6 +201,7 @@ static struct { + { "gssapiclientidentity", oGssClientIdentity }, + { "gssapiserveridentity", oGssServerIdentity }, + { "gssapirenewalforcesrekey", oGssRenewalRekey }, ++ { "gssapikexalgorithms", oGssKexAlgorithms }, + #else + { "gssapiauthentication", oUnsupported }, + { "gssapikeyexchange", oUnsupported }, +@@ -207,6 +209,7 @@ static struct { + { "gssapitrustdns", oUnsupported }, + { "gssapiclientidentity", oUnsupported }, + { "gssapirenewalforcesrekey", oUnsupported }, ++ { "gssapikexalgorithms", oUnsupported }, + #endif + { "fallbacktorsh", oDeprecated }, + { "usersh", oDeprecated }, +@@ -929,6 +932,18 @@ parse_time: + intptr = &options->gss_renewal_rekey; + goto parse_flag; + ++ case oGssKexAlgorithms: ++ arg = strdelim(&s); ++ if (!arg || *arg == '\0') ++ fatal("%.200s line %d: Missing argument.", ++ filename, linenum); ++ if (!gss_kex_names_valid(arg)) ++ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", ++ filename, linenum, arg ? arg : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; +@@ -1638,6 +1653,7 @@ initialize_options(Options * options) + options->gss_renewal_rekey = -1; + options->gss_client_identity = NULL; + options->gss_server_identity = NULL; ++ options->gss_kex_algorithms = NULL; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->kbd_interactive_devices = NULL; +@@ -1773,6 +1789,8 @@ fill_default_options(Options * options) + options->gss_trust_dns = 0; + if (options->gss_renewal_rekey == -1) + options->gss_renewal_rekey = 0; ++ if (options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) +diff -up openssh-7.0p1/readconf.h.gsskexalg openssh-7.0p1/readconf.h +--- openssh-7.0p1/readconf.h.gsskexalg 2015-08-19 12:28:38.026518955 +0200 ++++ openssh-7.0p1/readconf.h 2015-08-19 12:28:38.079518836 +0200 +@@ -51,6 +51,7 @@ typedef struct { + int gss_renewal_rekey; /* Credential renewal forces rekey */ + char *gss_client_identity; /* Principal to initiate GSSAPI with */ + char *gss_server_identity; /* GSSAPI target principal */ ++ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ + int password_authentication; /* Try password + * authentication. */ + int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ +diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.gsskexalg 2015-08-19 12:28:38.074518847 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-19 12:33:13.599902732 +0200 +@@ -57,6 +57,7 @@ + #include "auth.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + static void add_listen_addr(ServerOptions *, char *, int); + static void add_one_listen_addr(ServerOptions *, char *, int); +@@ -121,6 +122,7 @@ initialize_server_options(ServerOptions + options->gss_cleanup_creds = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; ++ options->gss_kex_algorithms = NULL; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; +@@ -288,6 +290,8 @@ fill_default_server_options(ServerOption + options->gss_strict_acceptor = 0; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; ++ if (options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) +@@ -427,7 +431,7 @@ typedef enum { + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, +- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, sAllowAgentForwarding, + sHostCertificate, +@@ -506,6 +510,7 @@ static struct { + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, + { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, ++ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, + #else + { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, +@@ -513,6 +518,7 @@ static struct { + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, + { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, ++ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, + #endif + { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, +@@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions + intptr = &options->gss_store_rekey; + goto parse_flag; + ++ case sGssKexAlgorithms: ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') ++ fatal("%.200s line %d: Missing argument.", ++ filename, linenum); ++ if (!gss_kex_names_valid(arg)) ++ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", ++ filename, linenum, arg ? arg : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; +@@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); ++ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); + #endif + dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(sKbdInteractiveAuthentication, +diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.gsskexalg 2015-08-19 12:28:38.080518834 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-19 12:34:46.328693944 +0200 +@@ -122,6 +122,7 @@ typedef struct { + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ + int gss_store_rekey; ++ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ + int password_authentication; /* If true, permit password + * authentication. */ + int kbd_interactive_authentication; /* If true, permit */ +diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1 +--- openssh-7.0p1/ssh.1.gsskexalg 2015-08-19 12:28:38.081518832 +0200 ++++ openssh-7.0p1/ssh.1 2015-08-19 12:35:31.741591692 +0200 +@@ -496,6 +496,7 @@ For full details of the options listed b + .It GSSAPIDelegateCredentials + .It GSSAPIRenewalForcesRekey + .It GSSAPITrustDNS ++.It GSSAPIKexAlgorithms + .It HashKnownHosts + .It Host + .It HostbasedAuthentication +diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5 +--- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200 ++++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200 +@@ -786,6 +786,18 @@ command line will be passed untouched to + The default is + .Dq no . + This option only applies to protocol version 2 connections using GSSAPI. ++.It Cm GSSAPIKexAlgorithms ++The list of key exchange algorithms that are offered for GSSAPI ++key exchange. Possible values are ++.Bd -literal -offset 3n ++gss-gex-sha1-, ++gss-group1-sha1-, ++gss-group14-sha1- ++.Ed ++.Pp ++The default is ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c +--- openssh-7.0p1/sshconnect2.c.gsskexalg 2015-08-19 12:28:38.045518912 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:28:38.081518832 +0200 +@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho + else + gss_host = host; + +- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); ++ 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], +diff -up openssh-7.0p1/sshd_config.5.gsskexalg openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.gsskexalg 2015-08-19 12:28:38.082518830 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-19 12:36:25.121471501 +0200 +@@ -659,6 +659,18 @@ Controls whether the user's GSSAPI crede + successful connection rekeying. This option can be used to accepted renewed + or updated credentials from a compatible client. The default is + .Dq no . ++.It Cm GSSAPIKexAlgorithms ++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- ++.Ed ++.Pp ++The default is ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a comma-separated pattern list. +diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h +--- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200 ++++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200 +@@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds; + #define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" + #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" + ++#define GSS_KEX_DEFAULT_KEX \ ++ KEX_GSS_GEX_SHA1_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID ++ + typedef struct { + char *filename; + char *envvar; +@@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct + /* In the server */ + typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, + const char *); +-char *ssh_gssapi_client_mechanisms(const char *, const char *); ++char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); + char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, +- const char *); ++ const char *, const char *); + gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); + int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, + const char *); diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch new file mode 100644 index 0000000..368f152 --- /dev/null +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -0,0 +1,318 @@ +From e1d58c44bd911e5ee4dddb6205e16eb9a03cc736 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 7 Aug 2015 10:18:54 +0200 +Subject: [PATCH] Possibility tu specify more fingerprint algorithms on client + side for smother transition + +--- + clientloop.c | 8 ++++---- + readconf.c | 43 +++++++++++++++++++++++++++++-------------- + readconf.h | 4 +++- + ssh_config.5 | 4 ++-- + sshconnect.c | 48 +++++++++++++++++++++++++++--------------------- + sshconnect2.c | 6 +++--- + 6 files changed, 68 insertions(+), 45 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index 87ceb3d..4553114 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -2194,7 +2194,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) + if (ctx->keys_seen[i] != 2) + continue; + if ((fp = sshkey_fingerprint(ctx->keys[i], +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Learned new hostkey: %s %s", + sshkey_type(ctx->keys[i]), fp); +@@ -2202,7 +2202,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) + } + for (i = 0; i < ctx->nold; i++) { + if ((fp = sshkey_fingerprint(ctx->old_keys[i], +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", + sshkey_type(ctx->old_keys[i]), fp); +@@ -2245,7 +2245,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) + (r = hostfile_replace_entries(options.user_hostfiles[0], + ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, + options.hash_known_hosts, 0, +- options.fingerprint_hash)) != 0) ++ options.fingerprint_hash[0])) != 0) + error("%s: hostfile_replace_entries failed: %s", + __func__, ssh_err(r)); + } +@@ -2358,7 +2358,7 @@ client_input_hostkeys(void) + error("%s: parse key: %s", __func__, ssh_err(r)); + goto out; + } +- fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT); + debug3("%s: received %s key %s", __func__, + sshkey_type(key), fp); +diff --git a/readconf.c b/readconf.c +index 1d03bdf..6af4c62 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1471,16 +1471,18 @@ parse_keytypes: + goto parse_string; + + case oFingerprintHash: +- intptr = &options->fingerprint_hash; +- arg = strdelim(&s); +- if (!arg || *arg == '\0') +- fatal("%.200s line %d: Missing argument.", +- filename, linenum); +- if ((value = ssh_digest_alg_by_name(arg)) == -1) +- fatal("%.200s line %d: Invalid hash algorithm \"%s\".", +- filename, linenum, arg); +- if (*activep && *intptr == -1) +- *intptr = value; ++ if (*activep && options->num_fingerprint_hash == 0) ++ while ((arg = strdelim(&s)) != NULL && *arg != '\0') { ++ value = ssh_digest_alg_by_name(arg); ++ if (value == -1) ++ fatal("%s line %d: unknown fingerprints algorithm specs: %s.", ++ filename, linenum, arg); ++ if (options->num_fingerprint_hash >= SSH_DIGEST_MAX) ++ fatal("%s line %d: too many fingerprints algorithm specs.", ++ filename, linenum); ++ options->fingerprint_hash[ ++ options->num_fingerprint_hash++] = value; ++ } + break; + + case oUpdateHostkeys: +@@ -1673,7 +1675,7 @@ initialize_options(Options * options) + options->canonicalize_fallback_local = -1; + options->canonicalize_hostname = -1; + options->revoked_host_keys = NULL; +- options->fingerprint_hash = -1; ++ options->num_fingerprint_hash = 0; + options->update_hostkeys = -1; + options->hostbased_key_types = NULL; + options->pubkey_key_types = NULL; +@@ -1851,8 +1853,10 @@ fill_default_options(Options * options) + options->canonicalize_fallback_local = 1; + if (options->canonicalize_hostname == -1) + options->canonicalize_hostname = SSH_CANONICALISE_NO; +- if (options->fingerprint_hash == -1) +- options->fingerprint_hash = SSH_FP_HASH_DEFAULT; ++ if (options->num_fingerprint_hash == 0) { ++ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_SHA256; ++ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_MD5; ++ } + if (options->update_hostkeys == -1) + options->update_hostkeys = 0; + if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || +@@ -2189,6 +2193,17 @@ dump_cfg_strarray(OpCodes code, u_int count, char **vals) + } + + static void ++dump_cfg_fmtarray(OpCodes code, u_int count, int *vals) ++{ ++ u_int i; ++ ++ printf("%s", lookup_opcode_name(code)); ++ for (i = 0; i < count; i++) ++ printf(" %s", fmt_intarg(code, vals[i])); ++ printf("\n"); ++} ++ ++static void + dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) + { + u_int i; +@@ -2259,7 +2274,6 @@ dump_client_config(Options *o, const char *host) + dump_cfg_fmtint(oControlMaster, o->control_master); + dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); + dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); +- dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(oForwardAgent, o->forward_agent); + dump_cfg_fmtint(oForwardX11, o->forward_x11); + dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); +@@ -2328,6 +2342,7 @@ dump_client_config(Options *o, const char *host) + dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); + dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); + dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); ++ dump_cfg_fmtarray(oFingerprintHash, o->num_fingerprint_hash, o->fingerprint_hash); + + /* Special cases */ + +diff --git a/readconf.h b/readconf.h +index bb2d552..d817f92 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -21,6 +21,7 @@ + #define MAX_SEND_ENV 256 + #define SSH_MAX_HOSTS_FILES 32 + #define MAX_CANON_DOMAINS 32 ++#define MAX_SSH_DIGESTS 32 + #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) + + struct allowed_cname { +@@ -146,7 +147,8 @@ typedef struct { + + char *revoked_host_keys; + +- int fingerprint_hash; ++ int num_fingerprint_hash; ++ int fingerprint_hash[MAX_SSH_DIGESTS]; + + int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ + +diff --git a/ssh_config.5 b/ssh_config.5 +index 5b0975f..e8e6458 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -647,13 +647,13 @@ or + The default is + .Dq no . + .It Cm FingerprintHash +-Specifies the hash algorithm used when displaying key fingerprints. ++Specifies the hash algorithms used when displaying key fingerprints. + Valid options are: + .Dq md5 + and + .Dq sha256 . + The default is +-.Dq sha256 . ++.Dq "sha256 md5". + .It Cm ForwardAgent + Specifies whether the connection to the authentication agent (if any) + will be forwarded to the remote machine. +diff --git a/sshconnect.c b/sshconnect.c +index f41960c..e12932f 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -920,9 +920,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, + "of known hosts.", type, ip); + } else if (options.visual_host_key) { + fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT); ++ options.fingerprint_hash[0], SSH_FP_DEFAULT); + ra = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_RANDOMART); ++ options.fingerprint_hash[0], SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + logit("Host key fingerprint is %s\n%s\n", fp, ra); +@@ -964,12 +964,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, + else + snprintf(msg1, sizeof(msg1), "."); + /* The default */ +- fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT); +- ra = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_RANDOMART); +- if (fp == NULL || ra == NULL) +- fatal("%s: sshkey_fingerprint fail", __func__); + msg2[0] = '\0'; + if (options.verify_host_key_dns) { + if (matching_host_key_dns) +@@ -983,16 +977,28 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, + } + snprintf(msg, sizeof(msg), + "The authenticity of host '%.200s (%s)' can't be " +- "established%s\n" +- "%s key fingerprint is %s.%s%s\n%s" ++ "established%s\n", host, ip, msg1); ++ for (i = 0; i < options.num_fingerprint_hash; i++) { ++ fp = sshkey_fingerprint(host_key, ++ options.fingerprint_hash[i], SSH_FP_DEFAULT); ++ ra = sshkey_fingerprint(host_key, ++ options.fingerprint_hash[i], SSH_FP_RANDOMART); ++ if (fp == NULL || ra == NULL) ++ fatal("%s: sshkey_fingerprint fail", __func__); ++ len = strlen(msg); ++ snprintf(msg+len, sizeof(msg)-len, ++ "%s key fingerprint is %s.%s%s\n%s", ++ type, fp, ++ options.visual_host_key ? "\n" : "", ++ options.visual_host_key ? ra : "", ++ msg2); ++ free(ra); ++ free(fp); ++ } ++ len = strlen(msg); ++ snprintf(msg+len, sizeof(msg)-len, + "Are you sure you want to continue connecting " +- "(yes/no)? ", +- host, ip, msg1, type, fp, +- options.visual_host_key ? "\n" : "", +- options.visual_host_key ? ra : "", +- msg2); +- free(ra); +- free(fp); ++ "(yes/no)? "); + if (!confirm(msg)) + goto fail; + hostkey_trusted = 1; /* user explicitly confirmed */ +@@ -1241,7 +1247,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) + struct sshkey *plain = NULL; + + if ((fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { + error("%s: fingerprint host key: %s", __func__, ssh_err(r)); + r = -1; + goto out; +@@ -1405,9 +1411,9 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) + if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) + continue; + fp = sshkey_fingerprint(found->key, +- options.fingerprint_hash, SSH_FP_DEFAULT); ++ options.fingerprint_hash[0], SSH_FP_DEFAULT); + ra = sshkey_fingerprint(found->key, +- options.fingerprint_hash, SSH_FP_RANDOMART); ++ options.fingerprint_hash[0], SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + logit("WARNING: %s key found for host %s\n" +@@ -1430,7 +1436,7 @@ warn_changed_key(Key *host_key) + { + char *fp; + +- fp = sshkey_fingerprint(host_key, options.fingerprint_hash, ++ fp = sshkey_fingerprint(host_key, options.fingerprint_hash[0], + SSH_FP_DEFAULT); + if (fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); +diff --git a/sshconnect2.c b/sshconnect2.c +index 7751031..82ed92e 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -589,7 +589,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) + key->type, pktype); + goto done; + } +- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + goto done; + debug2("input_userauth_pk_ok: fp %s", fp); +@@ -1009,7 +1009,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) + int have_sig = 1; + char *fp; + +- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + return 0; + debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); +@@ -1635,7 +1635,7 @@ userauth_hostbased(Authctxt *authctxt) + goto out; + } + +- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; +-- +2.1.0 + + diff --git a/openssh-7.0p1-gsissh.patch b/openssh-7.1p1-gsissh.patch similarity index 90% rename from openssh-7.0p1-gsissh.patch rename to openssh-7.1p1-gsissh.patch index cd744f2..2d29bca 100644 --- a/openssh-7.0p1-gsissh.patch +++ b/openssh-7.1p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-7.0p1.orig/auth2.c openssh-7.0p1/auth2.c ---- openssh-7.0p1.orig/auth2.c 2015-08-14 15:14:30.846969900 +0200 -+++ openssh-7.0p1/auth2.c 2015-08-14 15:14:58.052661231 +0200 +diff -Nur openssh-7.1p1.orig/auth2.c openssh-7.1p1/auth2.c +--- openssh-7.1p1.orig/auth2.c 2015-08-24 19:39:35.652354251 +0200 ++++ openssh-7.1p1/auth2.c 2015-08-24 19:40:08.238717475 +0200 @@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -120,9 +120,9 @@ diff -Nur openssh-7.0p1.orig/auth2.c openssh-7.0p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.0p1.orig/auth2-gss.c openssh-7.0p1/auth2-gss.c ---- openssh-7.0p1.orig/auth2-gss.c 2015-08-14 15:14:30.776970694 +0200 -+++ openssh-7.0p1/auth2-gss.c 2015-08-14 15:14:58.053661220 +0200 +diff -Nur openssh-7.1p1.orig/auth2-gss.c openssh-7.1p1/auth2-gss.c +--- openssh-7.1p1.orig/auth2-gss.c 2015-08-24 19:39:35.525352836 +0200 ++++ openssh-7.1p1/auth2-gss.c 2015-08-24 19:40:08.239717486 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -303,9 +303,9 @@ diff -Nur openssh-7.0p1.orig/auth2-gss.c openssh-7.0p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.0p1.orig/auth.c openssh-7.0p1/auth.c ---- openssh-7.0p1.orig/auth.c 2015-08-14 15:14:30.847969888 +0200 -+++ openssh-7.0p1/auth.c 2015-08-14 15:14:58.053661220 +0200 +diff -Nur openssh-7.1p1.orig/auth.c openssh-7.1p1/auth.c +--- openssh-7.1p1.orig/auth.c 2015-08-24 19:39:35.653354263 +0200 ++++ openssh-7.1p1/auth.c 2015-08-24 19:40:08.240717497 +0200 @@ -75,6 +75,9 @@ #include "ssherr.h" #include "compat.h" @@ -371,9 +371,9 @@ diff -Nur openssh-7.0p1.orig/auth.c openssh-7.0p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-7.0p1.orig/auth-pam.c openssh-7.0p1/auth-pam.c ---- openssh-7.0p1.orig/auth-pam.c 2015-08-14 15:14:30.863969707 +0200 -+++ openssh-7.0p1/auth-pam.c 2015-08-14 15:14:58.054661208 +0200 +diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c +--- openssh-7.1p1.orig/auth-pam.c 2015-08-24 19:39:35.673354486 +0200 ++++ openssh-7.1p1/auth-pam.c 2015-08-24 19:40:08.241717508 +0200 @@ -122,6 +122,10 @@ */ typedef pthread_t sp_pthread_t; @@ -524,9 +524,9 @@ diff -Nur openssh-7.0p1.orig/auth-pam.c openssh-7.0p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-7.0p1.orig/auth-pam.h openssh-7.0p1/auth-pam.h ---- openssh-7.0p1.orig/auth-pam.h 2015-08-14 15:14:30.715971386 +0200 -+++ openssh-7.0p1/auth-pam.h 2015-08-14 15:14:58.055661197 +0200 +diff -Nur openssh-7.1p1.orig/auth-pam.h openssh-7.1p1/auth-pam.h +--- openssh-7.1p1.orig/auth-pam.h 2015-08-24 19:39:35.441351900 +0200 ++++ openssh-7.1p1/auth-pam.h 2015-08-24 19:40:08.242717519 +0200 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -534,9 +534,9 @@ diff -Nur openssh-7.0p1.orig/auth-pam.h openssh-7.0p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.0p1.orig/canohost.c openssh-7.0p1/canohost.c ---- openssh-7.0p1.orig/canohost.c 2015-08-14 15:14:30.802970399 +0200 -+++ openssh-7.0p1/canohost.c 2015-08-14 15:14:58.055661197 +0200 +diff -Nur openssh-7.1p1.orig/canohost.c openssh-7.1p1/canohost.c +--- openssh-7.1p1.orig/canohost.c 2015-08-24 19:39:35.563353259 +0200 ++++ openssh-7.1p1/canohost.c 2015-08-24 19:40:08.242717519 +0200 @@ -17,6 +17,7 @@ #include #include @@ -579,9 +579,9 @@ diff -Nur openssh-7.0p1.orig/canohost.c openssh-7.0p1/canohost.c + } + } +} -diff -Nur openssh-7.0p1.orig/canohost.h openssh-7.0p1/canohost.h ---- openssh-7.0p1.orig/canohost.h 2015-08-14 15:14:30.802970399 +0200 -+++ openssh-7.0p1/canohost.h 2015-08-14 15:14:58.055661197 +0200 +diff -Nur openssh-7.1p1.orig/canohost.h openssh-7.1p1/canohost.h +--- openssh-7.1p1.orig/canohost.h 2015-08-24 19:39:35.563353259 +0200 ++++ openssh-7.1p1/canohost.h 2015-08-24 19:40:08.243717530 +0200 @@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -589,9 +589,9 @@ diff -Nur openssh-7.0p1.orig/canohost.h openssh-7.0p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.0p1.orig/configure.ac openssh-7.0p1/configure.ac ---- openssh-7.0p1.orig/configure.ac 2015-08-14 15:14:30.832970059 +0200 -+++ openssh-7.0p1/configure.ac 2015-08-14 15:14:58.057661174 +0200 +diff -Nur openssh-7.1p1.orig/configure.ac openssh-7.1p1/configure.ac +--- openssh-7.1p1.orig/configure.ac 2015-08-24 19:39:35.612353806 +0200 ++++ openssh-7.1p1/configure.ac 2015-08-24 19:40:08.245717553 +0200 @@ -4280,6 +4280,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -658,9 +658,9 @@ diff -Nur openssh-7.0p1.orig/configure.ac openssh-7.0p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-7.0p1.orig/gss-genr.c openssh-7.0p1/gss-genr.c ---- openssh-7.0p1.orig/gss-genr.c 2015-08-14 15:14:30.777970683 +0200 -+++ openssh-7.0p1/gss-genr.c 2015-08-14 15:14:58.057661174 +0200 +diff -Nur openssh-7.1p1.orig/gss-genr.c openssh-7.1p1/gss-genr.c +--- openssh-7.1p1.orig/gss-genr.c 2015-08-24 19:39:35.628353984 +0200 ++++ openssh-7.1p1/gss-genr.c 2015-08-24 19:40:08.245717553 +0200 @@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -669,7 +669,7 @@ diff -Nur openssh-7.0p1.orig/gss-genr.c openssh-7.0p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -369,9 +370,18 @@ +@@ -368,9 +369,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -689,7 +689,7 @@ diff -Nur openssh-7.0p1.orig/gss-genr.c openssh-7.0p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -379,6 +389,7 @@ +@@ -378,6 +388,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -697,9 +697,9 @@ diff -Nur openssh-7.0p1.orig/gss-genr.c openssh-7.0p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.0p1.orig/gss-serv.c openssh-7.0p1/gss-serv.c ---- openssh-7.0p1.orig/gss-serv.c 2015-08-14 15:14:30.778970671 +0200 -+++ openssh-7.0p1/gss-serv.c 2015-08-14 15:14:58.058661163 +0200 +diff -Nur openssh-7.1p1.orig/gss-serv.c openssh-7.1p1/gss-serv.c +--- openssh-7.1p1.orig/gss-serv.c 2015-08-24 19:39:35.629353995 +0200 ++++ openssh-7.1p1/gss-serv.c 2015-08-24 19:40:08.246717564 +0200 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -938,9 +938,9 @@ diff -Nur openssh-7.0p1.orig/gss-serv.c openssh-7.0p1/gss-serv.c +} + #endif -diff -Nur openssh-7.0p1.orig/gss-serv-gsi.c openssh-7.0p1/gss-serv-gsi.c ---- openssh-7.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.0p1/gss-serv-gsi.c 2015-08-14 15:14:58.058661163 +0200 +diff -Nur openssh-7.1p1.orig/gss-serv-gsi.c openssh-7.1p1/gss-serv-gsi.c +--- openssh-7.1p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.1p1/gss-serv-gsi.c 2015-08-24 19:40:08.246717564 +0200 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1181,9 +1181,9 @@ diff -Nur openssh-7.0p1.orig/gss-serv-gsi.c openssh-7.0p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.0p1.orig/gss-serv-krb5.c openssh-7.0p1/gss-serv-krb5.c ---- openssh-7.0p1.orig/gss-serv-krb5.c 2015-08-14 15:14:30.820970195 +0200 -+++ openssh-7.0p1/gss-serv-krb5.c 2015-08-14 15:14:58.058661163 +0200 +diff -Nur openssh-7.1p1.orig/gss-serv-krb5.c openssh-7.1p1/gss-serv-krb5.c +--- openssh-7.1p1.orig/gss-serv-krb5.c 2015-08-24 19:39:35.592353583 +0200 ++++ openssh-7.1p1/gss-serv-krb5.c 2015-08-24 19:40:08.246717564 +0200 @@ -359,6 +359,34 @@ return found_principal; } @@ -1237,9 +1237,9 @@ diff -Nur openssh-7.0p1.orig/gss-serv-krb5.c openssh-7.0p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.0p1.orig/kexgsss.c openssh-7.0p1/kexgsss.c ---- openssh-7.0p1.orig/kexgsss.c 2015-08-14 15:14:30.779970660 +0200 -+++ openssh-7.0p1/kexgsss.c 2015-08-14 15:14:58.058661163 +0200 +diff -Nur openssh-7.1p1.orig/kexgsss.c openssh-7.1p1/kexgsss.c +--- openssh-7.1p1.orig/kexgsss.c 2015-08-24 19:39:35.530352892 +0200 ++++ openssh-7.1p1/kexgsss.c 2015-08-24 19:40:08.247717575 +0200 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1299,9 +1299,9 @@ diff -Nur openssh-7.0p1.orig/kexgsss.c openssh-7.0p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.0p1.orig/LICENSE.globus_usage openssh-7.0p1/LICENSE.globus_usage ---- openssh-7.0p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.0p1/LICENSE.globus_usage 2015-08-14 15:14:58.058661163 +0200 +diff -Nur openssh-7.1p1.orig/LICENSE.globus_usage openssh-7.1p1/LICENSE.globus_usage +--- openssh-7.1p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.1p1/LICENSE.globus_usage 2015-08-24 19:40:08.247717575 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1321,9 +1321,9 @@ diff -Nur openssh-7.0p1.orig/LICENSE.globus_usage openssh-7.0p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.0p1.orig/Makefile.in openssh-7.0p1/Makefile.in ---- openssh-7.0p1.orig/Makefile.in 2015-08-14 15:14:30.857969775 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-14 15:14:58.059661152 +0200 +diff -Nur openssh-7.1p1.orig/Makefile.in openssh-7.1p1/Makefile.in +--- openssh-7.1p1.orig/Makefile.in 2015-08-24 19:39:35.667354419 +0200 ++++ openssh-7.1p1/Makefile.in 2015-08-24 19:40:08.247717575 +0200 @@ -113,8 +113,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ @@ -1335,9 +1335,9 @@ diff -Nur openssh-7.0p1.orig/Makefile.in openssh-7.0p1/Makefile.in roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o -diff -Nur openssh-7.0p1.orig/misc.c openssh-7.0p1/misc.c ---- openssh-7.0p1.orig/misc.c 2015-08-14 15:14:30.819970206 +0200 -+++ openssh-7.0p1/misc.c 2015-08-14 15:14:58.059661152 +0200 +diff -Nur openssh-7.1p1.orig/misc.c openssh-7.1p1/misc.c +--- openssh-7.1p1.orig/misc.c 2015-08-24 19:39:35.590353560 +0200 ++++ openssh-7.1p1/misc.c 2015-08-24 19:40:08.248717586 +0200 @@ -160,11 +160,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1397,9 +1397,9 @@ diff -Nur openssh-7.0p1.orig/misc.c openssh-7.0p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.0p1.orig/misc.h openssh-7.0p1/misc.h ---- openssh-7.0p1.orig/misc.h 2015-08-14 15:14:30.804970376 +0200 -+++ openssh-7.0p1/misc.h 2015-08-14 15:14:58.059661152 +0200 +diff -Nur openssh-7.1p1.orig/misc.h openssh-7.1p1/misc.h +--- openssh-7.1p1.orig/misc.h 2015-08-24 19:39:35.567353304 +0200 ++++ openssh-7.1p1/misc.h 2015-08-24 19:40:08.248717586 +0200 @@ -61,6 +61,7 @@ void sock_set_v6only(int); @@ -1408,9 +1408,9 @@ diff -Nur openssh-7.0p1.orig/misc.h openssh-7.0p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.0p1.orig/monitor.c openssh-7.0p1/monitor.c ---- openssh-7.0p1.orig/monitor.c 2015-08-14 15:14:30.864969696 +0200 -+++ openssh-7.0p1/monitor.c 2015-08-14 15:14:58.060661140 +0200 +diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c +--- openssh-7.1p1.orig/monitor.c 2015-08-24 19:39:35.674354497 +0200 ++++ openssh-7.1p1/monitor.c 2015-08-24 19:40:08.248717586 +0200 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1602,9 +1602,9 @@ diff -Nur openssh-7.0p1.orig/monitor.c openssh-7.0p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.0p1.orig/monitor.h openssh-7.0p1/monitor.h ---- openssh-7.0p1.orig/monitor.h 2015-08-14 15:14:30.849969866 +0200 -+++ openssh-7.0p1/monitor.h 2015-08-14 15:14:58.060661140 +0200 +diff -Nur openssh-7.1p1.orig/monitor.h openssh-7.1p1/monitor.h +--- openssh-7.1p1.orig/monitor.h 2015-08-24 19:39:35.657354307 +0200 ++++ openssh-7.1p1/monitor.h 2015-08-24 19:40:08.249717597 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1618,9 +1618,9 @@ diff -Nur openssh-7.0p1.orig/monitor.h openssh-7.0p1/monitor.h }; struct mm_master; -diff -Nur openssh-7.0p1.orig/monitor_wrap.c openssh-7.0p1/monitor_wrap.c ---- openssh-7.0p1.orig/monitor_wrap.c 2015-08-14 15:14:30.864969696 +0200 -+++ openssh-7.0p1/monitor_wrap.c 2015-08-14 15:14:58.060661140 +0200 +diff -Nur openssh-7.1p1.orig/monitor_wrap.c openssh-7.1p1/monitor_wrap.c +--- openssh-7.1p1.orig/monitor_wrap.c 2015-08-24 19:39:35.675354508 +0200 ++++ openssh-7.1p1/monitor_wrap.c 2015-08-24 19:40:08.249717597 +0200 @@ -1121,12 +1121,13 @@ } @@ -1720,9 +1720,9 @@ diff -Nur openssh-7.0p1.orig/monitor_wrap.c openssh-7.0p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.0p1.orig/monitor_wrap.h openssh-7.0p1/monitor_wrap.h ---- openssh-7.0p1.orig/monitor_wrap.h 2015-08-14 15:14:30.850969854 +0200 -+++ openssh-7.0p1/monitor_wrap.h 2015-08-14 15:14:58.061661129 +0200 +diff -Nur openssh-7.1p1.orig/monitor_wrap.h openssh-7.1p1/monitor_wrap.h +--- openssh-7.1p1.orig/monitor_wrap.h 2015-08-24 19:39:35.658354318 +0200 ++++ openssh-7.1p1/monitor_wrap.h 2015-08-24 19:40:08.249717597 +0200 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1738,10 +1738,10 @@ diff -Nur openssh-7.0p1.orig/monitor_wrap.h openssh-7.0p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.0p1.orig/readconf.c openssh-7.0p1/readconf.c ---- openssh-7.0p1.orig/readconf.c 2015-08-14 15:14:30.858969764 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-14 15:14:58.061661129 +0200 -@@ -1764,13 +1764,13 @@ +diff -Nur openssh-7.1p1.orig/readconf.c openssh-7.1p1/readconf.c +--- openssh-7.1p1.orig/readconf.c 2015-08-24 19:39:35.668354430 +0200 ++++ openssh-7.1p1/readconf.c 2015-08-24 19:40:08.250717609 +0200 +@@ -1782,13 +1782,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1758,11 +1758,11 @@ diff -Nur openssh-7.0p1.orig/readconf.c openssh-7.0p1/readconf.c + options->gss_trust_dns = 1; if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; - if (options->password_authentication == -1) -diff -Nur openssh-7.0p1.orig/readconf.h openssh-7.0p1/readconf.h ---- openssh-7.0p1.orig/readconf.h 2015-08-14 15:14:30.781970637 +0200 -+++ openssh-7.0p1/readconf.h 2015-08-14 15:14:58.062661118 +0200 -@@ -84,6 +84,8 @@ + if (options->gss_kex_algorithms == NULL) +diff -Nur openssh-7.1p1.orig/readconf.h openssh-7.1p1/readconf.h +--- openssh-7.1p1.orig/readconf.h 2015-08-24 19:39:35.639354106 +0200 ++++ openssh-7.1p1/readconf.h 2015-08-24 19:40:08.250717609 +0200 +@@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1771,10 +1771,10 @@ diff -Nur openssh-7.0p1.orig/readconf.h openssh-7.0p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c ---- openssh-7.0p1.orig/servconf.c 2015-08-14 15:14:30.865969684 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-14 15:14:58.063661106 +0200 -@@ -74,6 +74,7 @@ +diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c +--- openssh-7.1p1.orig/servconf.c 2015-08-24 19:39:35.676354519 +0200 ++++ openssh-7.1p1/servconf.c 2015-08-24 19:46:25.995931916 +0200 +@@ -75,6 +75,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1782,7 +1782,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -117,9 +118,11 @@ +@@ -118,9 +119,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1792,9 +1792,9 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c options->gss_strict_acceptor = -1; + options->gsi_allow_limited_proxy = -1; options->gss_store_rekey = -1; + options->gss_kex_algorithms = NULL; options->password_authentication = -1; - options->kbd_interactive_authentication = -1; -@@ -163,6 +166,8 @@ +@@ -165,6 +168,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1803,7 +1803,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -191,6 +196,8 @@ +@@ -193,6 +198,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1826,13 +1826,14 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->gss_strict_acceptor == -1) - options->gss_strict_acceptor = 0; +- options->gss_strict_acceptor = 0; ++ options->gss_strict_acceptor = 1; + if (options->gsi_allow_limited_proxy == -1) + options->gsi_allow_limited_proxy = 0; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; - if (options->password_authentication == -1) -@@ -407,7 +418,7 @@ + if (options->gss_kex_algorithms == NULL) +@@ -411,7 +422,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1841,7 +1842,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -429,10 +440,14 @@ +@@ -433,10 +444,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1849,14 +1850,14 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, + sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, + sDisUsageStats, sUsageStatsTarg, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -457,8 +472,10 @@ +@@ -461,8 +476,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1867,7 +1868,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -504,14 +521,24 @@ +@@ -508,7 +525,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1882,7 +1883,8 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, - { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, +@@ -516,7 +540,10 @@ + { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, @@ -1892,7 +1894,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -574,6 +601,8 @@ +@@ -580,6 +607,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1901,7 +1903,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1029,6 +1058,10 @@ +@@ -1035,6 +1064,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1912,7 +1914,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1260,6 +1293,10 @@ +@@ -1266,6 +1299,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1923,7 +1925,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1268,6 +1305,10 @@ +@@ -1274,6 +1311,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1934,9 +1936,9 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1276,6 +1317,12 @@ - intptr = &options->gss_store_rekey; - goto parse_flag; +@@ -1294,6 +1335,12 @@ + options->gss_kex_algorithms = xstrdup(arg); + break; +#ifdef GSI + case sGsiAllowLimitedProxy: @@ -1947,7 +1949,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1750,6 +1797,35 @@ +@@ -1768,6 +1815,35 @@ *charptr = xstrdup(arg); break; @@ -1983,7 +1985,7 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2026,6 +2102,7 @@ +@@ -2044,6 +2120,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1991,9 +1993,9 @@ diff -Nur openssh-7.0p1.orig/servconf.c openssh-7.0p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-7.0p1.orig/servconf.h openssh-7.0p1/servconf.h ---- openssh-7.0p1.orig/servconf.h 2015-08-14 15:14:30.821970183 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-14 15:14:58.063661106 +0200 +diff -Nur openssh-7.1p1.orig/servconf.h openssh-7.1p1/servconf.h +--- openssh-7.1p1.orig/servconf.h 2015-08-24 19:39:35.632354029 +0200 ++++ openssh-7.1p1/servconf.h 2015-08-24 19:40:08.253717642 +0200 @@ -117,9 +117,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if @@ -2006,8 +2008,8 @@ diff -Nur openssh-7.0p1.orig/servconf.h openssh-7.0p1/servconf.h + char *gss_creds_path; /* Use non-default credentials path */ int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; - int password_authentication; /* If true, permit password -@@ -175,6 +178,7 @@ + char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ +@@ -176,6 +179,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2015,7 +2017,7 @@ diff -Nur openssh-7.0p1.orig/servconf.h openssh-7.0p1/servconf.h int permit_tun; -@@ -183,6 +187,10 @@ +@@ -184,6 +188,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2026,10 +2028,10 @@ diff -Nur openssh-7.0p1.orig/servconf.h openssh-7.0p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.0p1.orig/ssh.1 openssh-7.0p1/ssh.1 ---- openssh-7.0p1.orig/ssh.1 2015-08-14 15:14:30.827970115 +0200 -+++ openssh-7.0p1/ssh.1 2015-08-14 15:14:58.064661095 +0200 -@@ -1405,6 +1405,18 @@ +diff -Nur openssh-7.1p1.orig/ssh.1 openssh-7.1p1/ssh.1 +--- openssh-7.1p1.orig/ssh.1 2015-08-24 19:39:35.633354040 +0200 ++++ openssh-7.1p1/ssh.1 2015-08-24 19:40:08.253717642 +0200 +@@ -1406,6 +1406,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2048,9 +2050,9 @@ diff -Nur openssh-7.0p1.orig/ssh.1 openssh-7.0p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.0p1.orig/ssh.c openssh-7.0p1/ssh.c ---- openssh-7.0p1.orig/ssh.c 2015-08-14 15:14:30.859969752 +0200 -+++ openssh-7.0p1/ssh.c 2015-08-14 15:14:58.064661095 +0200 +diff -Nur openssh-7.1p1.orig/ssh.c openssh-7.1p1/ssh.c +--- openssh-7.1p1.orig/ssh.c 2015-08-24 19:39:35.669354441 +0200 ++++ openssh-7.1p1/ssh.c 2015-08-24 19:40:08.254717653 +0200 @@ -465,6 +465,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2098,9 +2100,9 @@ diff -Nur openssh-7.0p1.orig/ssh.c openssh-7.0p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.0p1.orig/ssh_config openssh-7.0p1/ssh_config ---- openssh-7.0p1.orig/ssh_config 2015-08-14 15:14:30.783970615 +0200 -+++ openssh-7.0p1/ssh_config 2015-08-14 15:14:58.065661084 +0200 +diff -Nur openssh-7.1p1.orig/ssh_config openssh-7.1p1/ssh_config +--- openssh-7.1p1.orig/ssh_config 2015-08-24 19:39:35.537352970 +0200 ++++ openssh-7.1p1/ssh_config 2015-08-24 19:40:08.254717653 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2116,9 +2118,9 @@ diff -Nur openssh-7.0p1.orig/ssh_config openssh-7.0p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.0p1.orig/ssh_config.5 openssh-7.0p1/ssh_config.5 ---- openssh-7.0p1.orig/ssh_config.5 2015-08-14 15:14:30.783970615 +0200 -+++ openssh-7.0p1/ssh_config.5 2015-08-14 15:14:58.065661084 +0200 +diff -Nur openssh-7.1p1.orig/ssh_config.5 openssh-7.1p1/ssh_config.5 +--- openssh-7.1p1.orig/ssh_config.5 2015-08-24 19:39:35.640354118 +0200 ++++ openssh-7.1p1/ssh_config.5 2015-08-24 19:40:08.255717664 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2132,10 +2134,10 @@ diff -Nur openssh-7.0p1.orig/ssh_config.5 openssh-7.0p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1.orig/sshconnect2.c 2015-08-14 15:14:30.859969752 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-14 15:14:58.066661072 +0200 -@@ -698,6 +698,11 @@ +diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c +--- openssh-7.1p1.orig/sshconnect2.c 2015-08-24 19:39:35.669354441 +0200 ++++ openssh-7.1p1/sshconnect2.c 2015-08-24 19:40:08.255717664 +0200 +@@ -699,6 +699,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2147,7 +2149,7 @@ diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -935,6 +940,15 @@ +@@ -936,6 +941,15 @@ return 0; } @@ -2163,7 +2165,7 @@ diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -952,8 +966,16 @@ +@@ -953,8 +967,16 @@ return (0); } @@ -2180,7 +2182,7 @@ diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -964,7 +986,15 @@ +@@ -965,7 +987,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2196,9 +2198,9 @@ diff -Nur openssh-7.0p1.orig/sshconnect2.c openssh-7.0p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.0p1.orig/sshd.8 openssh-7.0p1/sshd.8 ---- openssh-7.0p1.orig/sshd.8 2015-08-14 15:14:30.824970149 +0200 -+++ openssh-7.0p1/sshd.8 2015-08-14 15:14:58.066661072 +0200 +diff -Nur openssh-7.1p1.orig/sshd.8 openssh-7.1p1/sshd.8 +--- openssh-7.1p1.orig/sshd.8 2015-08-24 19:39:35.599353661 +0200 ++++ openssh-7.1p1/sshd.8 2015-08-24 19:40:08.256717676 +0200 @@ -765,6 +765,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2244,9 +2246,9 @@ diff -Nur openssh-7.0p1.orig/sshd.8 openssh-7.0p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.0p1.orig/sshd.c openssh-7.0p1/sshd.c ---- openssh-7.0p1.orig/sshd.c 2015-08-14 15:14:30.867969662 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-14 15:14:58.067661061 +0200 +diff -Nur openssh-7.1p1.orig/sshd.c openssh-7.1p1/sshd.c +--- openssh-7.1p1.orig/sshd.c 2015-08-24 19:39:35.678354541 +0200 ++++ openssh-7.1p1/sshd.c 2015-08-24 19:40:08.257717686 +0200 @@ -129,6 +129,7 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2278,9 +2280,9 @@ diff -Nur openssh-7.0p1.orig/sshd.c openssh-7.0p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.0p1.orig/sshd_config openssh-7.0p1/sshd_config ---- openssh-7.0p1.orig/sshd_config 2015-08-14 15:14:30.841969957 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-14 15:14:58.068661050 +0200 +diff -Nur openssh-7.1p1.orig/sshd_config openssh-7.1p1/sshd_config +--- openssh-7.1p1.orig/sshd_config 2015-08-24 19:39:35.623353928 +0200 ++++ openssh-7.1p1/sshd_config 2015-08-24 19:40:08.257717686 +0200 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2313,9 +2315,9 @@ diff -Nur openssh-7.0p1.orig/sshd_config openssh-7.0p1/sshd_config + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 -diff -Nur openssh-7.0p1.orig/sshd_config.5 openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1.orig/sshd_config.5 2015-08-14 15:14:30.821970183 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-14 15:14:58.068661050 +0200 +diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 +--- openssh-7.1p1.orig/sshd_config.5 2015-08-24 19:39:35.635354062 +0200 ++++ openssh-7.1p1/sshd_config.5 2015-08-24 19:40:08.258717698 +0200 @@ -569,6 +569,15 @@ See PATTERNS in .Xr ssh_config 5 @@ -2366,7 +2368,7 @@ diff -Nur openssh-7.0p1.orig/sshd_config.5 openssh-7.0p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1528,6 +1557,103 @@ +@@ -1540,6 +1569,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2470,7 +2472,7 @@ diff -Nur openssh-7.0p1.orig/sshd_config.5 openssh-7.0p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -1604,6 +1730,12 @@ +@@ -1616,6 +1742,12 @@ as a non-root user. The default is .Dq no . @@ -2483,9 +2485,9 @@ diff -Nur openssh-7.0p1.orig/sshd_config.5 openssh-7.0p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-7.0p1.orig/ssh-globus-usage.c openssh-7.0p1/ssh-globus-usage.c ---- openssh-7.0p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.0p1/ssh-globus-usage.c 2015-08-14 15:14:58.069661038 +0200 +diff -Nur openssh-7.1p1.orig/ssh-globus-usage.c openssh-7.1p1/ssh-globus-usage.c +--- openssh-7.1p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.1p1/ssh-globus-usage.c 2015-08-24 19:40:08.258717698 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2883,9 +2885,9 @@ diff -Nur openssh-7.0p1.orig/ssh-globus-usage.c openssh-7.0p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.0p1.orig/ssh-globus-usage.h openssh-7.0p1/ssh-globus-usage.h ---- openssh-7.0p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.0p1/ssh-globus-usage.h 2015-08-14 15:14:58.069661038 +0200 +diff -Nur openssh-7.1p1.orig/ssh-globus-usage.h openssh-7.1p1/ssh-globus-usage.h +--- openssh-7.1p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.1p1/ssh-globus-usage.h 2015-08-24 19:40:08.259717709 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2935,10 +2937,10 @@ diff -Nur openssh-7.0p1.orig/ssh-globus-usage.h openssh-7.0p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h ---- openssh-7.0p1.orig/ssh-gss.h 2015-08-14 15:14:30.788970558 +0200 -+++ openssh-7.0p1/ssh-gss.h 2015-08-14 15:14:58.069661038 +0200 -@@ -91,6 +91,7 @@ +diff -Nur openssh-7.1p1.orig/ssh-gss.h openssh-7.1p1/ssh-gss.h +--- openssh-7.1p1.orig/ssh-gss.h 2015-08-24 19:39:35.635354062 +0200 ++++ openssh-7.1p1/ssh-gss.h 2015-08-24 19:40:08.259717709 +0200 +@@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; ssh_gssapi_ccache store; @@ -2946,7 +2948,7 @@ diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -111,7 +112,7 @@ +@@ -115,7 +116,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2955,7 +2957,7 @@ diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -144,6 +145,9 @@ +@@ -148,6 +149,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2965,7 +2967,7 @@ diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -154,7 +158,7 @@ +@@ -158,7 +162,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -2974,7 +2976,7 @@ diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h 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); -@@ -166,6 +170,7 @@ +@@ -170,6 +174,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -2982,11 +2984,11 @@ diff -Nur openssh-7.0p1.orig/ssh-gss.h openssh-7.0p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.0p1.orig/version.h openssh-7.0p1/version.h ---- openssh-7.0p1.orig/version.h 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/version.h 2015-08-14 15:14:58.069661038 +0200 +diff -Nur openssh-7.1p1.orig/version.h openssh-7.1p1/version.h +--- openssh-7.1p1.orig/version.h 2015-08-21 06:49:03.000000000 +0200 ++++ openssh-7.1p1/version.h 2015-08-24 19:41:34.830682670 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.74 2015/08/02 09:56:42 djm Exp $ */ + /* $OpenBSD: version.h,v 1.75 2015/08/21 03:45:26 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3002,7 +3004,7 @@ diff -Nur openssh-7.0p1.orig/version.h openssh-7.0p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20150812" + - #define SSH_VERSION "OpenSSH_7.0" + #define SSH_VERSION "OpenSSH_7.1" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-7.1p1-hostkeyalgorithms.patch b/openssh-7.1p1-hostkeyalgorithms.patch new file mode 100644 index 0000000..4a22cdc --- /dev/null +++ b/openssh-7.1p1-hostkeyalgorithms.patch @@ -0,0 +1,46 @@ +diff --git a/readconf.c b/readconf.c +index 374e741..23d74fb 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -2229,6 +2229,10 @@ dump_client_config(Options *o, const char *host) + int i; + char vbuf[5]; + ++ /* This is normally prepared in ssh_kex2 */ ++ if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) ++ fatal("%s: kex_assemble_names failed", __func__); ++ + /* Most interesting options first: user, host, port */ + dump_cfg_string(oUser, o->user); + dump_cfg_string(oHostName, host); +@@ -2289,7 +2293,7 @@ dump_client_config(Options *o, const char *host) + dump_cfg_string(oBindAddress, o->bind_address); + dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); + dump_cfg_string(oControlPath, o->control_path); +- dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); ++ dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); + dump_cfg_string(oHostKeyAlias, o->host_key_alias); + dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); + dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); +diff --git a/servconf.c b/servconf.c +index 04404a4..08c8139 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -242,8 +242,6 @@ fill_default_server_options(ServerOptions *options) + options->hostbased_authentication = 0; + if (options->hostbased_uses_name_from_packet_only == -1) + options->hostbased_uses_name_from_packet_only = 0; +- if (options->hostkeyalgorithms == NULL) +- options->hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->pubkey_authentication == -1) +@@ -329,6 +327,8 @@ fill_default_server_options(ServerOptions *options) + kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || + kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ &options->hostkeyalgorithms) != 0 || ++ kex_assemble_names(KEX_DEFAULT_PK_ALG, + &options->hostbased_key_types) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, + &options->pubkey_key_types) != 0) diff --git a/sources b/sources index 30ece94..43ddb92 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -831883f251ac34f0ab9c812acc24ee69 openssh-7.0p1.tar.gz +8709736bc8a8c253bc4eeb4829888ca5 openssh-7.1p1.tar.gz From e3fc8ce78b6c808e79af3c6c8346bbe81fbb5403 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 8 Oct 2015 11:22:22 +0200 Subject: [PATCH 018/146] Based on openssh-7.1p1-3.fc23 --- gsi-openssh.spec | 5 ++- openssh-6.6.1p1-selinux-contexts.patch | 35 +++++++++++++++ openssh-6.6p1-gsskex.patch | 51 +++++++++++++++++++++- openssh-6.6p1-role-mls.patch | 19 +++++--- openssh-6.7p1-fips.patch | 15 +++---- openssh-7.0p1-gssKexAlgorithms.patch | 10 ++++- openssh-7.0p1-show-more-fingerprints.patch | 14 ++++++ 7 files changed, 131 insertions(+), 18 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f49de66..83cdc6d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.1p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -551,6 +551,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Oct 08 2015 Mattias Ellert - 7.1p1-2 +- Based on openssh-7.1p1-3.fc23 + * Mon Aug 24 2015 Mattias Ellert - 7.1p1-1 - Based on openssh-7.1p1-1.fc23 diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 425ffda..052843f 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -116,3 +116,38 @@ index 2871fe9..39b9c08 100644 #endif /* Change our root directory */ +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 12c014e..c5ef2ff 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -35,7 +35,6 @@ + + #ifdef WITH_SELINUX + #include +-#include + #include + + #ifndef SSH_SELINUX_UNCONFINED_TYPE +@@ -110,6 +109,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) + security_context_t new_tty_ctx = NULL; + security_context_t user_ctx = NULL; + security_context_t old_tty_ctx = NULL; ++ security_class_t class; + + if (!ssh_selinux_enabled()) + return; +@@ -129,8 +129,13 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) + goto out; + } + ++ class = string_to_security_class("chr_file"); ++ if (!class) { ++ error("string_to_security_class failed to translate security class context"); ++ goto out; ++ } + if (security_compute_relabel(user_ctx, old_tty_ctx, +- SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { ++ class, &new_tty_ctx) != 0) { + error("%s: security_compute_relabel: %s", + __func__, strerror(errno)); + goto out; diff --git a/openssh-6.6p1-gsskex.patch b/openssh-6.6p1-gsskex.patch index cdf70b6..2feb7b5 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-6.6p1-gsskex.patch @@ -2290,7 +2290,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c + if (options.gss_keyex) { + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ orig = options.kex_algorithms; + + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); @@ -2300,7 +2300,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c + gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); + if (gss) { + debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ xasprintf(&options.kex_algorithms, + "%s,%s", gss, orig); + } + } @@ -2476,6 +2476,18 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c --- openssh-7.0p1/sshd.c.gsskex 2015-08-12 11:15:43.679548913 +0200 +++ openssh-7.0p1/sshd.c 2015-08-12 11:15:43.702548876 +0200 +@@ -1043,8 +1043,9 @@ notify_hostkeys(struct ssh *ssh) + } + debug3("%s: sent %d hostkeys", __func__, nkeys); + if (nkeys == 0) +- fatal("%s: no hostkeys", __func__); +- packet_send(); ++ debug3("%s: no hostkeys", __func__); ++ else ++ packet_send(); + sshbuf_free(buf); + } + @@ -1843,10 +1843,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; @@ -2695,3 +2707,38 @@ diff -up openssh-7.0p1/ssh-gss.h.gsskex openssh-7.0p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ + +diff -up openssh-7.1p1/sshkey.c.gsskex openssh-7.1p1/sshkey.c +--- openssh-7.1p1/sshkey.c.gsskex 2015-09-17 15:54:32.135673460 +0200 ++++ openssh-7.1p1/sshkey.c 2015-09-17 15:55:23.014666159 +0200 +@@ -112,6 +112,7 @@ static const struct keytype keytypes[] = + # endif /* OPENSSL_HAS_NISTP521 */ + # endif /* OPENSSL_HAS_ECC */ + #endif /* WITH_OPENSSL */ ++ { "null", "null", KEY_NULL, 0, 0 }, + { NULL, NULL, -1, -1, 0 } + }; + +diff -up openssh-7.1p1/sshkey.h.gsskex openssh-7.1p1/sshkey.h +--- openssh-7.1p1/sshkey.h.gsskex 2015-09-17 15:54:32.135673460 +0200 ++++ openssh-7.1p1/sshkey.h 2015-09-17 15:55:45.885662877 +0200 +@@ -62,6 +62,7 @@ enum sshkey_types { + KEY_DSA_CERT, + KEY_ECDSA_CERT, + KEY_ED25519_CERT, ++ KEY_NULL, + KEY_UNSPEC + }; + +diff --git a/auth.c b/auth.c +index 4d1fbbe..5db39c4 100644 +--- a/auth.c ++++ b/auth.c +@@ -354,6 +354,7 @@ auth_root_allowed(const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || ++ strcmp(method, "gssapi-keyex") == 0 || + strcmp(method, "gssapi-with-mic") == 0) + return 1; + break; diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index da164d3..0c9d422 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -378,7 +378,7 @@ diff -up openssh-6.8p1/openbsd-compat/Makefile.in.role-mls openssh-6.8p1/openbsd diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/openbsd-compat/port-linux-sshd.c --- openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls 2015-03-18 11:04:21.048817114 +0100 +++ openssh-6.8p1/openbsd-compat/port-linux-sshd.c 2015-03-18 11:04:21.048817114 +0100 -@@ -0,0 +1,415 @@ +@@ -0,0 +1,424 @@ +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2014 Petr Lautrbach @@ -419,11 +419,9 @@ diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/o + +#ifdef WITH_SELINUX +#include -+#include +#include +#include +#include -+#include + +#ifdef HAVE_LINUX_AUDIT +#include @@ -488,10 +486,21 @@ diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/o +{ + struct av_decision avd; + int retval; -+ unsigned int bit = CONTEXT__CONTAINS; ++ access_vector_t bit; ++ security_class_t class; + + debug("%s: src:%s dst:%s", __func__, src, dst); -+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); ++ class = string_to_security_class("context"); ++ if (!class) { ++ error("string_to_security_class failed to translate security class context"); ++ return 1; ++ } ++ bit = string_to_av_perm(class, "contains"); ++ if (!bit) { ++ error("string_to_av_perm failed to translate av perm contains"); ++ return 1; ++ } ++ retval = security_compute_av(src, dst, class, bit, &avd); + if (retval || ((bit & avd.allowed) != bit)) + return 0; + diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index 9a743b1..62f9e26 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -191,12 +191,9 @@ diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c --- openssh-7.0p1/kexgexs.c.fips 2015-08-11 10:57:29.000000000 +0200 +++ openssh-7.0p1/kexgexs.c 2015-08-19 12:36:51.151412892 +0200 -@@ -81,11 +81,11 @@ input_kex_dh_gex_request(int type, u_int - (r = sshpkt_get_end(ssh)) != 0) - goto out; +@@ -81,9 +81,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; -- kex->min = min; -+ kex->min = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; + kex->min = min; kex->max = max; - min = MAX(DH_GRP_MIN, min); + min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); @@ -495,7 +492,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c if (options.gss_keyex) { - /* Add the GSSAPI mechanisms currently supported on this - * client to the key exchange algorithm proposal */ -- orig = myproposal[PROPOSAL_KEX_ALGS]; +- orig = options.kex_algorithms; - - if (options.gss_trust_dns) - gss_host = (char *)get_canonical_hostname(1); @@ -506,7 +503,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c - options.gss_client_identity, options.gss_kex_algorithms); - if (gss) { - debug("Offering GSSAPI proposal: %s", gss); -- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], +- xasprintf(&options.kex_algorithms, - "%s,%s", gss, orig); + if (FIPS_mode()) { + logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); @@ -514,7 +511,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c + } else { + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ orig = options.kex_algorithms; + + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); @@ -525,7 +522,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c + options.gss_client_identity, options.gss_kex_algorithms); + if (gss) { + debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ xasprintf(&options.kex_algorithms, + "%s,%s", gss, orig); + } } diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 9ea42e3..8ecc207 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -94,6 +94,14 @@ diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c --- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200 +++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200 +@@ -50,6 +50,7 @@ + #include "dispatch.h" + #include "monitor.h" + #include "roaming.h" ++#include "xmalloc.h" + + #include "ssherr.h" + #include "sshbuf.h" @@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char return 0; } @@ -354,7 +362,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c + options.gss_client_identity, options.gss_kex_algorithms); if (gss) { debug("Offering GSSAPI proposal: %s", gss); - xasprintf(&myproposal[PROPOSAL_KEX_ALGS], + xasprintf(&options.kex_algorithms, diff -up openssh-7.0p1/sshd_config.5.gsskexalg openssh-7.0p1/sshd_config.5 --- openssh-7.0p1/sshd_config.5.gsskexalg 2015-08-19 12:28:38.082518830 +0200 +++ openssh-7.0p1/sshd_config.5 2015-08-19 12:36:25.121471501 +0200 diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index 368f152..52f9535 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -312,6 +312,20 @@ index 7751031..82ed92e 100644 SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; +diff --git a/ssh-keysign.c b/ssh-keysign.c +index 1dca3e2..23bff7d 100644 +--- a/ssh-keysign.c ++++ b/ssh-keysign.c +@@ -275,7 +275,7 @@ main(int argc, char **argv) + } + } + if (!found) { +- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + fatal("no matching hostkey found for key %s %s", + -- 2.1.0 From adf76a364f61be03657d864bb3e531388c23e69f Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 19 Jan 2016 15:55:56 +0100 Subject: [PATCH 019/146] Based on openssh-7.1p2-1.fc23 --- gsi-openssh.spec | 40 +- gsisshd-keygen.service | 6 +- gsisshd.service | 2 +- openssh-5.8p1-glob.patch | 8 +- openssh-6.4p1-legacy-ssh-copy-id.patch | 57 -- openssh-6.6p1-privsep-selinux.patch | 73 ++- openssh-6.7p1-audit.patch | 8 +- ...ssh-6.7p1-ssh-copy-id-truncated-keys.patch | 13 - ....8p1-fix-ssh-copy-id-on-non-sh-shell.patch | 15 - openssh-7.0p1-gssKexAlgorithms.patch | 21 +- openssh-7.1p1-gsissh.patch | 6 +- openssh-7.1p1-gssapi-documentation.patch | 47 ++ openssh-7.1p1-iutf8.patch | 31 + openssh-7.1p1-ssh-copy-id.patch | 532 ++++++++++++++++++ sources | 2 +- 15 files changed, 719 insertions(+), 142 deletions(-) delete mode 100644 openssh-6.4p1-legacy-ssh-copy-id.patch delete mode 100644 openssh-6.7p1-ssh-copy-id-truncated-keys.patch delete mode 100644 openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch create mode 100644 openssh-7.1p1-gssapi-documentation.patch create mode 100644 openssh-7.1p1-iutf8.patch create mode 100644 openssh-7.1p1-ssh-copy-id.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 83cdc6d..e530518 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.1p1 -%global openssh_rel 2 +%global openssh_ver 7.1p2 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -118,13 +118,15 @@ 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 +# Documentation about GSSAPI +# from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655 +Patch803: openssh-7.1p1-gssapi-documentation.patch + Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 Patch901: openssh-6.6p1-kuserok.patch # use default_ccache_name from /etc/krb5.conf (#991186) Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch -# Run ssh-copy-id in the legacy mode when SSH_COPY_ID_LEGACY variable is set (#969375 -Patch905: openssh-6.4p1-legacy-ssh-copy-id.patch # Use tty allocation for a remote scp (#985650) Patch906: openssh-6.4p1-fromto-remote.patch # set a client's address right after a connection is set @@ -152,12 +154,8 @@ Patch920: openssh-6.6.1p1-ip-port-config-parser.patch Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.patch # apply upstream patch and make sshd -T more consistent (#1187521) Patch922: openssh-6.8p1-sshdT-output.patch -# fix ssh-copy-id on non-sh shells (#1045191) -Patch923: openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch # Seccomp support for secondary architectures (#1195065) Patch924: openssh-6.9p1-seccomp-secondary.patch -# Solve issue with ssh-copy-id and keys without trailing newline (#1093168) -Patch925: openssh-6.7p1-ssh-copy-id-truncated-keys.patch # Add sftp option to force mode of created files (#1191055) Patch926: openssh-6.7p1-sftp-force-permission.patch # Memory problems @@ -174,6 +172,12 @@ Patch933: openssh-7.0p1-show-more-fingerprints.patch # Brokend HostKeyAlgorthms on server using + sign # from http://lists.mindrot.org/pipermail/openssh-unix-dev/2015-August/034324.html Patch934: openssh-7.1p1-hostkeyalgorithms.patch +# Updated version of ssh-copy-id +# http://git.hands.com/ssh-copy-id +Patch935: openssh-7.1p1-ssh-copy-id.patch +# Preserve IUTF8 tty mode flag over ssh connections (#1270248) +# https://bugzilla.mindrot.org/show_bug.cgi?id=2477 +Patch936: openssh-7.1p1-iutf8.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.1p1.patch @@ -308,11 +312,11 @@ This version of OpenSSH has been modified to support GSI authentication. %patch800 -p1 -b .gsskex %patch801 -p1 -b .force_krb +%patch803 -p1 -b .gss-docs %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok %patch902 -p1 -b .ccache_name -%patch905 -p1 -b .legacy-ssh-copy-id %patch906 -p1 -b .fromto-remote %patch911 -p1 -b .set_remote_ipaddr %patch912 -p1 -b .utf8-banner @@ -325,16 +329,16 @@ This version of OpenSSH has been modified to support GSI authentication. %patch802 -p1 -b .GSSAPIEnablek5users %patch921 -p1 -b .tcp_wrappers %patch922 -p1 -b .sshdt -%patch923 -p1 -b .ssh-copy-id %patch924 -p1 -b .seccomp -%patch925 -p1 -b .newline %patch926 -p1 -b .sftp-force-mode %patch928 -p1 -b .memory %patch929 -p1 -b .root-login %patch931 -p1 -b .progressmeter %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint -%patch934 -p1 -b .hosttkey +%patch934 -p1 -b .hostkey +%patch935 -p1 -b .ssh-copy-id +%patch936 -p1 -b .iutf8 %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -426,10 +430,10 @@ make SSH_PROGRAM=%{_bindir}/gsissh \ ASKPASS_PROGRAM=%{_libexecdir}/openssh/ssh-askpass # Add generation of HMAC checksums of the final stripped binaries -%define __spec_install_post \ - %{?__debug_package:%{__debug_install_post}} \ - %{__arch_install_post} \ - %{__os_install_post} \ +%global __spec_install_post \ + %%{?__debug_package:%%{__debug_install_post}} \ + %%{__arch_install_post} \ + %%{__os_install_post} \ fipshmac -d $RPM_BUILD_ROOT%{_libdir}/fipscheck $RPM_BUILD_ROOT%{_bindir}/gsissh $RPM_BUILD_ROOT%{_sbindir}/gsisshd \ %{nil} @@ -505,7 +509,6 @@ getent passwd sshd >/dev/null || \ %files %defattr(-,root,root) -%{!?_licensedir:%global license %%doc} %license LICENCE LICENSE.globus_usage %doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh @@ -551,6 +554,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Jan 19 2016 Mattias Ellert - 7.1p2-1 +- Based on openssh-7.1p2-1.fc23 + * Thu Oct 08 2015 Mattias Ellert - 7.1p1-2 - Based on openssh-7.1p1-3.fc23 diff --git a/gsisshd-keygen.service b/gsisshd-keygen.service index 8382967..546e82e 100644 --- a/gsisshd-keygen.service +++ b/gsisshd-keygen.service @@ -1,8 +1,8 @@ [Unit] Description=gsissh Server Key Generation -ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key -ConditionPathExists=|!/etc/gsissh/ssh_host_ecdsa_key -ConditionPathExists=|!/etc/gsissh/ssh_host_ed25519_key +ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_rsa_key +ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_ecdsa_key +ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_ed25519_key PartOf=gsisshd.service gsisshd.socket [Service] diff --git a/gsisshd.service b/gsisshd.service index 8f18090..f778281 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -5,7 +5,7 @@ After=network.target gsisshd-keygen.service Wants=gsisshd-keygen.service [Service] -EnvironmentFile=/etc/sysconfig/gsisshd +EnvironmentFile=-/etc/sysconfig/gsisshd ExecStart=/usr/sbin/gsisshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process diff --git a/openssh-5.8p1-glob.patch b/openssh-5.8p1-glob.patch index fe8a3d4..5fcd070 100644 --- a/openssh-5.8p1-glob.patch +++ b/openssh-5.8p1-glob.patch @@ -12,12 +12,14 @@ diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index 742b4b9..acae399 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c -@@ -130,7 +130,7 @@ typedef char Char; +@@ -130,8 +130,8 @@ typedef char Char; + #define M_CLASS META(':') #define ismeta(c) (((c)&M_QUOTE) != 0) - #define GLOB_LIMIT_MALLOC 65536 +-#define GLOB_LIMIT_MALLOC 65536 -#define GLOB_LIMIT_STAT 128 -+#define GLOB_LIMIT_STAT 1024 ++#define GLOB_LIMIT_MALLOC 65536*64 ++#define GLOB_LIMIT_STAT 128*64 #define GLOB_LIMIT_READDIR 16384 /* Limit of recursion during matching attempts. */ diff --git a/openssh-6.4p1-legacy-ssh-copy-id.patch b/openssh-6.4p1-legacy-ssh-copy-id.patch deleted file mode 100644 index ba8d949..0000000 --- a/openssh-6.4p1-legacy-ssh-copy-id.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff -up openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id.1 ---- openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id 2013-03-22 00:17:37.000000000 +0100 -+++ openssh-6.4p1/contrib/ssh-copy-id.1 2014-01-28 17:12:49.197542425 +0100 -@@ -180,6 +180,19 @@ should prove enlightening (N.B. the mode - .Fl W - option, rather than - .Xr nc 1 ) . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -+.Pp -+.It Pa SSH_COPY_ID_LEGACY -+If the -+.Cm SSH_COPY_ID_LEGACY -+environment variable is set, the -+.Nm -+is run in a legacy mode. In this mode, the -+.Nm -+doesn't check an existence of a private key and doesn't do remote checks -+of the remote server versions or if public keys are already installed. -+.El - .Sh "SEE ALSO" - .Xr ssh 1 , - .Xr ssh-agent 1 , -diff -up openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id ---- openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id 2013-06-05 14:48:45.000000000 +0200 -+++ openssh-6.4p1/contrib/ssh-copy-id 2014-01-28 17:11:51.538833032 +0100 -@@ -77,7 +77,7 @@ use_id_file() { - PUB_ID_FILE="$L_ID_FILE.pub" - fi - -- PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) -+ [ "x$SSH_COPY_ID_LEGACY" != "x" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) - - # check that the files are readable - for f in $PUB_ID_FILE $PRIV_ID_FILE ; do -@@ -243,7 +243,7 @@ populate_new_ids() { - printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 - } - --REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | -+[ "x$SSH_COPY_ID_LEGACY" != "x" ] || REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | - sed -ne 's/.*remote software version //p') - - case "$REMOTE_VERSION" in -@@ -268,7 +268,11 @@ case "$REMOTE_VERSION" in - ;; - *) - # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect -- populate_new_ids 0 -+ if [ "x$SSH_COPY_ID_LEGACY" != "x" ]; then -+ NEW_IDS=`eval "$GET_ID"` -+ else -+ populate_new_ids 0 -+ fi - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " - umask 077 ; - mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 6507647..87f53df 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -2,7 +2,7 @@ diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c index c18524e..d04f4ed 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -409,6 +409,25 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -409,6 +409,28 @@ sshd_selinux_setup_exec_context(char *pwname) debug3("%s: done", __func__); } @@ -19,8 +19,11 @@ index c18524e..d04f4ed 100644 + 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) -+ logit("%s: setcon failed with %s", __func__, strerror (errno)); ++ fatal("%s: setcon failed with %s", __func__, strerror (errno)); + freecon(ctx); + } +} @@ -44,6 +47,15 @@ diff --git a/session.c b/session.c index 2bcf818..b5dc144 100644 --- a/session.c +++ b/session.c +@@ -1532,7 +1532,7 @@ void + do_setusercontext(struct passwd *pw) + { + char *chroot_path, *tmp; +-#ifdef USE_LIBIAF ++#if defined(USE_LIBIAF) || defined(WITH_SELINUX) + int doing_chroot = 0; + #endif + @@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *pw) pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, @@ -54,19 +66,37 @@ index 2bcf818..b5dc144 100644 safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); -@@ -1565,6 +1568,12 @@ do_setusercontext(struct passwd *pw) +@@ -1557,7 +1557,7 @@ do_setusercontext(struct passwd *pw) + /* Make sure we don't attempt to chroot again */ + free(options.chroot_directory); + options.chroot_directory = NULL; +-#ifdef USE_LIBIAF ++#if defined(USE_LIBIAF) || defined(WITH_SELINUX) + doing_chroot = 1; + #endif + } +@@ -1565,6 +1568,11 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif + +#ifdef WITH_SELINUX -+ if (options.chroot_directory == NULL || -+ strcasecmp(options.chroot_directory, "none") == 0) ++ if (doing_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"); +@@ -1588,9 +1588,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); @@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; @@ -92,17 +122,26 @@ index 07f9926..a97f8b7 100644 /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, -@@ -768,6 +772,13 @@ privsep_postauth(Authctxt *authctxt) - do_setusercontext(authctxt->pw); +@@ -755,6 +755,9 @@ privsep_postauth(Authctxt *authctxt) - skip: -+#ifdef WITH_SELINUX -+ /* switch SELinux content for root too */ -+ if (authctxt->pw->pw_uid == 0) { -+ sshd_selinux_copy_context(); -+ } -+#endif -+ - /* It is safe now to apply the key state */ - monitor_apply_keystate(pmonitor); + #ifdef DISABLE_FD_PASSING + if (1) { ++#elif defined(WITH_SELINUX) ++ if (options.use_login) { ++ /* even root user can be confined by SELinux */ + #else + if (authctxt->pw->pw_uid == 0 || options.use_login) { + #endif +diff --git a/session.c b/session.c +index 684f867..09048bc 100644 +--- a/session.c ++++ b/session.c +@@ -1538,7 +1538,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) { diff --git a/openssh-6.7p1-audit.patch b/openssh-6.7p1-audit.patch index ac59f0a..106cda1 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-6.7p1-audit.patch @@ -1569,7 +1569,7 @@ diff -up openssh-7.0p1/monitor_wrap.c.audit openssh-7.0p1/monitor_wrap.c + buffer_init(&m); + buffer_put_int(&m, ctos); + buffer_put_cstring(&m, cipher); -+ buffer_put_cstring(&m, (mac ? mac : "")); ++ buffer_put_cstring(&m, (mac ? mac : "")); + buffer_put_cstring(&m, compress); + buffer_put_cstring(&m, fps); + buffer_put_int64(&m, pid); @@ -2282,13 +2282,14 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c diff -up openssh-7.0p1/sshkey.c.audit openssh-7.0p1/sshkey.c --- openssh-7.0p1/sshkey.c.audit 2015-08-11 10:57:29.000000000 +0200 +++ openssh-7.0p1/sshkey.c 2015-08-12 11:33:00.417914278 +0200 -@@ -299,6 +299,31 @@ sshkey_type_is_valid_ca(int type) +@@ -299,6 +299,33 @@ sshkey_type_is_valid_ca(int type) } int +sshkey_is_private(const struct sshkey *k) +{ + switch (k->type) { ++#ifdef WITH_OPENSSL + case KEY_RSA_CERT: + case KEY_RSA1: + case KEY_RSA: @@ -2300,7 +2301,8 @@ diff -up openssh-7.0p1/sshkey.c.audit openssh-7.0p1/sshkey.c + case KEY_ECDSA_CERT: + case KEY_ECDSA: + return EC_KEY_get0_private_key(k->ecdsa) != NULL; -+#endif ++#endif /* OPENSSL_HAS_ECC */ ++#endif /* WITH_OPENSSL */ + case KEY_ED25519_CERT: + case KEY_ED25519: + return (k->ed25519_pk != NULL); diff --git a/openssh-6.7p1-ssh-copy-id-truncated-keys.patch b/openssh-6.7p1-ssh-copy-id-truncated-keys.patch deleted file mode 100644 index f4c91a4..0000000 --- a/openssh-6.7p1-ssh-copy-id-truncated-keys.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index 4bba5d6..ed1208e 100644 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -207,7 +207,7 @@ populate_new_ids() { - printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 - NEW_IDS=$( - eval $GET_ID | { -- while read ID ; do -+ while read ID || [[ -n $ID ]]; do - printf '%s\n' "$ID" > $L_TMP_ID_FILE - - # the next line assumes $PRIV_ID_FILE only set if using a single id file - this diff --git a/openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch b/openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch deleted file mode 100644 index 358986b..0000000 --- a/openssh-6.8p1-fix-ssh-copy-id-on-non-sh-shell.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index 8e1091c..4bba5d6 100644 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -274,9 +274,7 @@ case "$REMOTE_VERSION" in - populate_new_ids 0 - fi - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " -- umask 077 ; -+ exec sh -c 'umask 077; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1; if type restorecon >/dev/null 2>&1; then restorecon -F .ssh .ssh/authorized_keys; fi'" \ -- mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; -- if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ - || exit 1 - ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) - ;; diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 8ecc207..6a469ff 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -206,12 +206,14 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1773,6 +1789,8 @@ fill_default_options(Options * options) +@@ -1773,6 +1789,10 @@ fill_default_options(Options * options) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; ++#ifdef GSSAPI + if (options->gss_kex_algorithms == NULL) + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); ++#endif if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -245,12 +247,14 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -288,6 +290,8 @@ fill_default_server_options(ServerOption +@@ -288,6 +290,10 @@ fill_default_server_options(ServerOption options->gss_strict_acceptor = 0; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; ++#ifdef GSSAPI + if (options->gss_kex_algorithms == NULL) + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); ++#endif if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -363,13 +367,12 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c if (gss) { debug("Offering GSSAPI proposal: %s", gss); xasprintf(&options.kex_algorithms, -diff -up openssh-7.0p1/sshd_config.5.gsskexalg openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1/sshd_config.5.gsskexalg 2015-08-19 12:28:38.082518830 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-19 12:36:25.121471501 +0200 -@@ -659,6 +659,18 @@ Controls whether the user's GSSAPI crede - successful connection rekeying. This option can be used to accepted renewed - or updated credentials from a compatible client. The default is - .Dq no . +--- openssh-7.1p1/sshd_config.5.gsskexalg 2015-12-10 15:32:48.105418092 +0100 ++++ openssh-7.1p1/sshd_config.5 2015-12-10 15:33:47.771279548 +0100 +@@ -663,6 +663,18 @@ or updated credentials from a compatible + For this to work + .Cm GSSAPIKeyExchange + needs to be enabled in the server and also used by the client. +.It Cm GSSAPIKexAlgorithms +The list of key exchange algorithms that are accepted by GSSAPI +key exchange. Possible values are diff --git a/openssh-7.1p1-gsissh.patch b/openssh-7.1p1-gsissh.patch index 2d29bca..ca0df11 100644 --- a/openssh-7.1p1-gsissh.patch +++ b/openssh-7.1p1-gsissh.patch @@ -1758,7 +1758,7 @@ diff -Nur openssh-7.1p1.orig/readconf.c openssh-7.1p1/readconf.c + options->gss_trust_dns = 1; if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; - if (options->gss_kex_algorithms == NULL) + #ifdef GSSAPI diff -Nur openssh-7.1p1.orig/readconf.h openssh-7.1p1/readconf.h --- openssh-7.1p1.orig/readconf.h 2015-08-24 19:39:35.639354106 +0200 +++ openssh-7.1p1/readconf.h 2015-08-24 19:40:08.250717609 +0200 @@ -1832,7 +1832,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c + options->gsi_allow_limited_proxy = 0; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; - if (options->gss_kex_algorithms == NULL) + #ifdef GSSAPI @@ -411,7 +422,7 @@ typedef enum { sBadOption, /* == unknown option */ @@ -3006,7 +3006,7 @@ diff -Nur openssh-7.1p1.orig/version.h openssh-7.1p1/version.h + #define SSH_VERSION "OpenSSH_7.1" - #define SSH_PORTABLE "p1" + #define SSH_PORTABLE "p2" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE \ + NCSA_VERSION GSI_VERSION KRB5_VERSION diff --git a/openssh-7.1p1-gssapi-documentation.patch b/openssh-7.1p1-gssapi-documentation.patch new file mode 100644 index 0000000..4887cc0 --- /dev/null +++ b/openssh-7.1p1-gssapi-documentation.patch @@ -0,0 +1,47 @@ +diff -up openssh-7.1p1/ssh_config.5.gss-docs openssh-7.1p1/ssh_config.5 +--- openssh-7.1p1/ssh_config.5.gss-docs 2015-12-10 15:28:47.451966457 +0100 ++++ openssh-7.1p1/ssh_config.5 2015-12-10 15:30:28.070738047 +0100 +@@ -773,15 +773,26 @@ Note that this option applies to protoco + If set to + .Dq yes + then renewal of the client's GSSAPI credentials will force the rekeying of the +-ssh connection. With a compatible server, this can delegate the renewed ++ssh connection. With a compatible server, this will delegate the renewed + credentials to a session on the server. ++.Pp ++Checks are made to ensure that credentials are only propagated when the new ++credentials match the old ones on the originating client and where the ++receiving server still has the old set in its cache. ++.Pp + The default is + .Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. + .It Cm GSSAPITrustDns + Set to +-.Dq yes to indicate that the DNS is trusted to securely canonicalize ++.Dq yes ++to indicate that the DNS is trusted to securely canonicalize + the name of the host being connected to. If +-.Dq no, the hostname entered on the ++.Dq no , ++the hostname entered on the + command line will be passed untouched to the GSSAPI library. + The default is + .Dq no . +diff -up openssh-7.1p1/sshd_config.5.gss-docs openssh-7.1p1/sshd_config.5 +--- openssh-7.1p1/sshd_config.5.gss-docs 2015-12-10 15:28:47.453966452 +0100 ++++ openssh-7.1p1/sshd_config.5 2015-12-10 15:28:47.461966434 +0100 +@@ -653,6 +653,10 @@ Controls whether the user's GSSAPI crede + successful connection rekeying. This option can be used to accepted renewed + or updated credentials from a compatible client. The default is + .Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a comma-separated pattern list. diff --git a/openssh-7.1p1-iutf8.patch b/openssh-7.1p1-iutf8.patch new file mode 100644 index 0000000..89de5c7 --- /dev/null +++ b/openssh-7.1p1-iutf8.patch @@ -0,0 +1,31 @@ +diff --git a/PROTOCOL b/PROTOCOL +index 131adfe..c828087 100644 +--- a/PROTOCOL ++++ b/PROTOCOL +@@ -328,6 +328,11 @@ a server may offer multiple keys of the same type for a period (to + give clients an opportunity to learn them using this extension) before + removing the deprecated key from those offered. + ++2.6. connection: add IUTF8 terminal mode flag ++ ++OpenSSH supports the IUTF8 terminal mode flag and encodes it in "pty-req" ++messages as opcode value 42. ++ + 3. SFTP protocol changes + + 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK +diff --git a/ttymodes.h b/ttymodes.h +index 4d848fe..396ae88 100644 +--- a/ttymodes.h ++++ b/ttymodes.h +@@ -127,6 +127,9 @@ TTYMODE(IXOFF, c_iflag, 40) + #ifdef IMAXBEL + TTYMODE(IMAXBEL,c_iflag, 41) + #endif /* IMAXBEL */ ++#ifdef IUTF8 ++TTYMODE(IUTF8, c_iflag, 42) ++#endif /* IUTF8 */ + + TTYMODE(ISIG, c_lflag, 50) + TTYMODE(ICANON, c_lflag, 51) + diff --git a/openssh-7.1p1-ssh-copy-id.patch b/openssh-7.1p1-ssh-copy-id.patch new file mode 100644 index 0000000..a4e6f7d --- /dev/null +++ b/openssh-7.1p1-ssh-copy-id.patch @@ -0,0 +1,532 @@ +From 1a52b2d612b1d0c2a15dfcdc8da560704909ec72 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Sat, 27 Jul 2013 14:16:52 +0100 +Subject: [PATCH] echo --> printf "%s: ERROR... (for consistency) + +--- + ssh-copy-id | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index ae88e99..516b87f 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -200,7 +200,7 @@ populate_new_ids() { + umask 0177 + local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) + if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then +- echo "mktemp failed" 1>&2 ++ printf '%s: ERROR: mktemp failed\n' "$0" >&2 + exit 1 + fi + trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT +-- +1.9.1 + + + +From baebbb9e18e4a1af7554d939710eacb665a24b68 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Wed, 25 Nov 2015 17:05:39 +0100 +Subject: [PATCH] Deal with remote user shell being e.g. tcsh (fixes: 2206) + +as suggested by Jakub Jelen +--- + ssh-copy-id | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 516b87f..6a0447a 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -269,10 +269,8 @@ case "$REMOTE_VERSION" in + *) + # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect + populate_new_ids 0 +- [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " +- umask 077 ; +- mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; +- if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ ++ [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ ++ ssh "$@" "exec sh -c 'umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ + || exit 1 + ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) + ;; +-- +1.9.1 + + + +From 35f05e39cda8670b3f6797330a3e521fda509a4c Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Wed, 25 Nov 2015 21:14:00 +0100 +Subject: [PATCH] set LogLevel to ensure that it's not set to 'None' (closes: + 2214) + +As pointed out by Sami Haahtinen , +the LogLevel is set to 'None' we'll not get the +Permission Denied we're looking for. +--- + ssh-copy-id | 1 + + 1 file changed, 1 insertion(+) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 6a0447a..70d3866 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -215,6 +215,7 @@ populate_new_ids() { + # The point being that if file based, ssh needs the private key, which it cannot + # find if only given the contents of the .pub file in an unrelated tmpfile + ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ ++ -o LogLevel=INFO \ + -o PreferredAuthentications=publickey \ + -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr +Date: Wed, 25 Nov 2015 22:30:43 +0100 +Subject: [PATCH] set ControlPath=none (closes: 2488) +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +Thanks to Salvador Fandiño for the patch +This seems to be the same problem as described in 2195 +--- + ssh-copy-id | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 70d3866..7df7fad 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -215,6 +215,7 @@ populate_new_ids() { + # The point being that if file based, ssh needs the private key, which it cannot + # find if only given the contents of the .pub file in an unrelated tmpfile + ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ ++ -o ControlPath=none \ + -o LogLevel=INFO \ + -o PreferredAuthentications=publickey \ + -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr &2 + } + +-REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | ++REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 | + sed -ne 's/.*remote software version //p') + + case "$REMOTE_VERSION" in +-- +1.9.1 + + + +From 6fa6f1e3dbec32636e77d01228ceecfa3851c7e8 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Wed, 25 Nov 2015 23:24:13 +0100 +Subject: [PATCH] add -f (forced) option to install keys unconditionally + (closes: 2110) + +Thanks for the patch from Petr Lautrbach +which inspired this. +--- + ssh-copy-id | 15 +++++++++++++-- + ssh-copy-id.1 | 5 +++++ + 2 files changed, 18 insertions(+), 2 deletions(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 7df7fad..3121171 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -59,7 +59,10 @@ fi + DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) + + usage () { +- printf 'Usage: %s [-h|-?|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 ++ printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 ++ printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 ++ printf '\t-n: dry run -- no keys are actually copied\n' >&2 ++ printf '\t-h|-?: print this help\n' >&2 + exit 1 + } + +@@ -121,7 +124,7 @@ do + } + shift + ;; +- -n|-h|-\?) ++ -f|-n|-h|-\?) + OPT="$1" + OPTARG= + shift +@@ -154,6 +157,9 @@ do + -o|-p) + SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" + ;; ++ -f) ++ FORCED=1 ++ ;; + -n) + DRY_RUN=1 + ;; +@@ -194,6 +200,11 @@ fi + populate_new_ids() { + local L_SUCCESS="$1" + ++ if [ "$FORCED" ] ; then ++ NEW_IDS=$(eval $GET_ID) ++ return ++ fi ++ + # repopulate "$@" inside this function + eval set -- "$SSH_OPTS" + +diff --git $1/contrib/ssh-copy-id.1 $1/contrib/ssh-copy-id.1 +index 67a59e4..8850cce 100644 +--- $1/contrib/ssh-copy-id.1 ++++ $1/contrib/ssh-copy-id.1 +@@ -29,6 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + .Nd use locally available keys to authorise logins on a remote machine + .Sh SYNOPSIS + .Nm ++.Op Fl f + .Op Fl n + .Op Fl i Op Ar identity_file + .Op Fl p Ar port +@@ -76,6 +77,10 @@ is used. + Note that this can be used to ensure that the keys copied have the + comment one prefers and/or extra options applied, by ensuring that the + key file has these set as preferred before the copy is attempted. ++.It Fl f ++Forced mode: doesn't check if the keys are present on the remote server. ++This means that it does not need the private key. Of course, this can result ++in more than one copy of the key being installed on the remote system. + .It Fl n + do a dry-run. Instead of installing keys on the remote system simply + prints the key(s) that would have been installed. +-- +1.9.1 + + + +From ab185eea5a03cdd846c909d83e5dd0a07a44fb54 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Wed, 25 Nov 2015 23:47:06 +0100 +Subject: [PATCH] deal with #2331 by suggesting the use of the -f option + +--- + ssh-copy-id | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 3121171..8666cea 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -250,7 +250,8 @@ populate_new_ids() { + exit 1 + fi + if [ -z "$NEW_IDS" ] ; then +- printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n\n' "$0" >&2 ++ printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 ++ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 + exit 0 + fi + printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 +-- +1.9.1 + + + +From de78897ada50ed12f4b0c9faa6e935ce82ee49a6 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Thu, 26 Nov 2015 00:25:56 +0100 +Subject: [PATCH] handle keys with missing trailing newline (closes: 2350) + +--- + ssh-copy-id | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 8666cea..362b49b 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -218,7 +218,7 @@ populate_new_ids() { + printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 + NEW_IDS=$( + eval $GET_ID | { +- while read ID ; do ++ while read ID || [ "$ID" ] ; do + printf '%s\n' "$ID" > $L_TMP_ID_FILE + + # the next line assumes $PRIV_ID_FILE only set if using a single id file - this +-- +1.9.1 + + + +From 6b903ab99a3f0107bb0dbde748a4372033bab00c Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Thu, 26 Nov 2015 00:36:09 +0100 +Subject: [PATCH] add a cd to ensure we're in the remote's home directory + (closes: 2349) + +--- + ssh-copy-id | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 362b49b..2932936 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -284,7 +284,7 @@ case "$REMOTE_VERSION" in + # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect + populate_new_ids 0 + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ +- ssh "$@" "exec sh -c 'umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ ++ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ + || exit 1 + ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) + ;; +-- +1.9.1 + + + +From 441892cbf4ff96fd96908582b8170f51890b5deb Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Sat, 28 Nov 2015 14:42:36 +0100 +Subject: [PATCH] add comment about why the ugly one-line remote command is as + it is + +In case anyone looks here for the details: + * tcsh doesn't support multi-line strings, + which is why it's a one-liner. + * tcsh doesn't do 2>&1, and fish doesn't do + 'command || command' which is why we're runnig this under + sh (which is very likely to be a POSIX shell on any vaguely + Unix-like system) + * The 'cd' is there to make sure we're in the home dir, because + there was a bug report about having a cd in ~/.bashrc that resulted + in a .ssh being created elsewhere. + * the 'exec' ensures that we're not relying on anything beyond the + (hopefully POSIX) shell that's available as 'sh' on the remote system +--- + ssh-copy-id | 1 + + 1 file changed, 1 insertion(+) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 2932936..04c03eb 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -283,6 +283,7 @@ case "$REMOTE_VERSION" in + *) + # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect + populate_new_ids 0 ++ # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh. + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ + ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ + || exit 1 +-- +1.9.1 + + + +From 8b59b122d321b97badd15c41e1a22863aa922a02 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Sat, 28 Nov 2015 14:46:47 +0100 +Subject: [PATCH] with '-f' there's no need to have access to the private key + +--- + ssh-copy-id | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 04c03eb..d3ff83b 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -80,7 +80,7 @@ use_id_file() { + PUB_ID_FILE="$L_ID_FILE.pub" + fi + +- PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) ++ [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) + + # check that the files are readable + for f in $PUB_ID_FILE $PRIV_ID_FILE ; do +-- +1.9.1 + + + +From 1b931894de0614099255244be789ad097fd0948a Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Sat, 28 Nov 2015 14:47:35 +0100 +Subject: [PATCH] if the private key is missing, point out that '-f' might be + what's needed + +--- + ssh-copy-id | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index d3ff83b..f0b01aa 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -85,7 +85,9 @@ use_id_file() { + # check that the files are readable + for f in $PUB_ID_FILE $PRIV_ID_FILE ; do + ErrMSG=$( { : < $f ; } 2>&1 ) || { +- printf "\n%s: ERROR: failed to open ID file '%s': %s\n\n" "$0" "$f" "$(printf "%s\n" "$ErrMSG" | sed -e 's/.*: *//')" ++ local 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 + } + done +-- +1.9.1 + + + +From fd3e8b115e160a1332773cd8e06a3305d0d680ab Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Sat, 28 Nov 2015 21:10:39 +0100 +Subject: [PATCH] +INFO message to mitigate the surprise described in #2196 + +--- + ssh-copy-id | 1 + + 1 file changed, 1 insertion(+) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index f0b01aa..994194e 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -91,6 +91,7 @@ use_id_file() { + exit 1 + } + done ++ printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" $PUB_ID_FILE >&2 + GET_ID="cat \"$PUB_ID_FILE\"" + } + +-- +1.9.1 + + + +From 783ef08b0a757402aba67313f08f8dbfa9bf85f3 Mon Sep 17 00:00:00 2001 +From: Philip Hands +Date: Mon, 30 Nov 2015 20:46:19 +0100 +Subject: [PATCH] deal with $HOME and id filenames that include a space + +--- + ssh-copy-id | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id +index 994194e..afde8b1 100755 +--- $1/contrib/ssh-copy-id ++++ $1/contrib/ssh-copy-id +@@ -56,7 +56,7 @@ then + fi + fi + +-DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) ++DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" + + usage () { + printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 +@@ -83,15 +83,15 @@ use_id_file() { + [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) + + # check that the files are readable +- for f in $PUB_ID_FILE $PRIV_ID_FILE ; do +- ErrMSG=$( { : < $f ; } 2>&1 ) || { ++ for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do ++ ErrMSG=$( { : < "$f" ; } 2>&1 ) || { + local 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 + } + done +- printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" $PUB_ID_FILE >&2 ++ printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 + GET_ID="cat \"$PUB_ID_FILE\"" + } + +@@ -217,12 +217,13 @@ populate_new_ids() { + printf '%s: ERROR: mktemp failed\n' "$0" >&2 + exit 1 + fi +- trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT ++ local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" ++ 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 + NEW_IDS=$( + eval $GET_ID | { + while read ID || [ "$ID" ] ; do +- printf '%s\n' "$ID" > $L_TMP_ID_FILE ++ printf '%s\n' "$ID" > "$L_TMP_ID_FILE" + + # the next line assumes $PRIV_ID_FILE only set if using a single id file - this + # assumption will break if we implement the possibility of multiple -i options. +@@ -246,7 +247,7 @@ populate_new_ids() { + done + } + ) +- rm -f $L_TMP_ID_FILE* && trap - EXIT TERM INT QUIT ++ eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT + + if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then + printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 +-- +1.9.1 + + +diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id +index afde8b1..cd52764 100644 +--- a/contrib/ssh-copy-id ++++ b/contrib/ssh-copy-id +@@ -99,6 +99,8 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then + GET_ID="ssh-add -L" + fi + ++[ "x$SSH_COPY_ID_LEGACY" != "x" ] && FORCED=1 ++ + while test "$#" -gt 0 + do + [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { +diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1 +index 8850cce..62f112d 100644 +--- a/contrib/ssh-copy-id.1 ++++ b/contrib/ssh-copy-id.1 +@@ -185,6 +185,22 @@ should prove enlightening (N.B. the modern approach is to use the + .Fl W + option, rather than + .Xr nc 1 ) . ++.Sh ENVIRONMENT ++.Bl -tag -width Ds ++.Pp ++.It Pa SSH_COPY_ID_LEGACY ++If the ++.Cm SSH_COPY_ID_LEGACY ++environment variable is set, the ++.Nm ++is run in a legacy mode. In this mode, the ++.Nm ++doesn't check an existence of a private key and doesn't do remote checks ++of the remote server versions or if public keys are already installed ++(equivalent to ++.Fl f ++switch). ++.El + .Sh "SEE ALSO" + .Xr ssh 1 , + .Xr ssh-agent 1 , diff --git a/sources b/sources index 43ddb92..0d63d38 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -8709736bc8a8c253bc4eeb4829888ca5 openssh-7.1p1.tar.gz +4d8547670e2a220d5ef805ad9e47acf2 openssh-7.1p2.tar.gz From d8907457dc63bc7191c1f408a3b4f6249ccf4e77 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 29 Jan 2016 17:24:42 +0100 Subject: [PATCH 020/146] Based on openssh-7.1p2-2.fc23 --- gsi-openssh.spec | 13 +- openssh-7.1p2-fallback-x11-untrusted.patch | 352 +++++++++++++++++++++ 2 files changed, 360 insertions(+), 5 deletions(-) create mode 100644 openssh-7.1p2-fallback-x11-untrusted.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e530518..89485f6 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.1p2 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -74,7 +74,7 @@ Patch501: openssh-6.7p1-ldap.patch #? Patch502: openssh-6.6p1-keycat.patch -#http6://bugzilla.mindrot.org/show_bug.cgi?id=1644 +#https://bugzilla.mindrot.org/show_bug.cgi?id=1644 Patch601: openssh-6.6p1-allow-ip-opts.patch #http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/crypto/dist/ssh/Attic/sftp-glob.c.diff?r1=1.13&r2=1.13.12.1&f=h Patch603: openssh-5.8p1-glob.patch @@ -178,6 +178,8 @@ Patch935: openssh-7.1p1-ssh-copy-id.patch # Preserve IUTF8 tty mode flag over ssh connections (#1270248) # https://bugzilla.mindrot.org/show_bug.cgi?id=2477 Patch936: openssh-7.1p1-iutf8.patch +# CVE-2016-1908: possible fallback from untrusted to trusted X11 forwarding +Patch937: openssh-7.1p2-fallback-x11-untrusted.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.1p1.patch @@ -339,6 +341,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch934 -p1 -b .hostkey %patch935 -p1 -b .ssh-copy-id %patch936 -p1 -b .iutf8 +%patch937 -p1 -b .x11-fallback %patch200 -p1 -b .audit %patch700 -p1 -b .fips @@ -508,7 +511,6 @@ getent passwd sshd >/dev/null || \ %systemd_postun_with_restart gsisshd.service %files -%defattr(-,root,root) %license LICENCE LICENSE.globus_usage %doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh @@ -520,7 +522,6 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8* %files clients -%defattr(-,root,root) %attr(0755,root,root) %{_bindir}/gsissh %attr(0644,root,root) %{_libdir}/fipscheck/gsissh.hmac %attr(0644,root,root) %{_mandir}/man1/gsissh.1* @@ -534,7 +535,6 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man1/gsisftp.1* %files server -%defattr(-,root,root) %dir %attr(0711,root,root) %{_var}/empty/gsisshd %attr(0755,root,root) %{_sbindir}/gsisshd %attr(0755,root,root) %{_sbindir}/gsisshd-keygen @@ -554,6 +554,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Jan 29 2016 Mattias Ellert - 7.1p2-2 +- Based on openssh-7.1p2-2.fc23 + * Tue Jan 19 2016 Mattias Ellert - 7.1p2-1 - Based on openssh-7.1p2-1.fc23 diff --git a/openssh-7.1p2-fallback-x11-untrusted.patch b/openssh-7.1p2-fallback-x11-untrusted.patch new file mode 100644 index 0000000..1fecbfd --- /dev/null +++ b/openssh-7.1p2-fallback-x11-untrusted.patch @@ -0,0 +1,352 @@ +From f98a09cacff7baad8748c9aa217afd155a4d493f Mon Sep 17 00:00:00 2001 +From: "mmcc@openbsd.org" +Date: Tue, 20 Oct 2015 03:36:35 +0000 +Subject: [PATCH] upstream commit + +Replace a function-local allocation with stack memory. + +ok djm@ + +Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e +--- + clientloop.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index 87ceb3d..1e05cba 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -311,11 +311,10 @@ client_x11_get_proto(const char *display, const char *xauth_path, + static char proto[512], data[512]; + FILE *f; + int got_data = 0, generated = 0, do_unlink = 0, i; +- char *xauthdir, *xauthfile; ++ char xauthdir[PATH_MAX] = "", xauthfile[PATH_MAX] = ""; + struct stat st; + u_int now, x11_timeout_real; + +- xauthdir = xauthfile = NULL; + *_proto = proto; + *_data = data; + proto[0] = data[0] = '\0'; +@@ -343,8 +342,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, + display = xdisplay; + } + if (trusted == 0) { +- xauthdir = xmalloc(PATH_MAX); +- xauthfile = xmalloc(PATH_MAX); + mktemp_proto(xauthdir, PATH_MAX); + /* + * The authentication cookie should briefly outlive +@@ -407,8 +404,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, + unlink(xauthfile); + rmdir(xauthdir); + } +- free(xauthdir); +- free(xauthfile); + + /* + * If we didn't get authentication data, just make up some +-- +2.5.0 + +From ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Wed, 13 Jan 2016 23:04:47 +0000 +Subject: [PATCH] upstream commit + +eliminate fallback from untrusted X11 forwarding to trusted + forwarding when the X server disables the SECURITY extension; Reported by + Thomas Hoger; ok deraadt@ + +Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 +--- + clientloop.c | 114 ++++++++++++++++++++++++++++++++++++----------------------- + clientloop.h | 4 +-- + mux.c | 22 ++++++------ + ssh.c | 23 +++++------- + 4 files changed, 93 insertions(+), 70 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index f555451..c0386d5 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -288,6 +288,9 @@ client_x11_display_valid(const char *display) + { + size_t i, dlen; + ++ if (display == NULL) ++ return 0; ++ + dlen = strlen(display); + for (i = 0; i < dlen; i++) { + if (!isalnum((u_char)display[i]) && +@@ -301,34 +304,33 @@ client_x11_display_valid(const char *display) + + #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" + #define X11_TIMEOUT_SLACK 60 +-void ++int + client_x11_get_proto(const char *display, const char *xauth_path, + u_int trusted, u_int timeout, char **_proto, char **_data) + { +- char cmd[1024]; +- char line[512]; +- char xdisplay[512]; ++ char cmd[1024], line[512], xdisplay[512]; ++ char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; + static char proto[512], data[512]; + FILE *f; +- int got_data = 0, generated = 0, do_unlink = 0, i; +- char xauthdir[PATH_MAX] = "", xauthfile[PATH_MAX] = ""; ++ int got_data = 0, generated = 0, do_unlink = 0, i, r; + struct stat st; + u_int now, x11_timeout_real; + + *_proto = proto; + *_data = data; +- proto[0] = data[0] = '\0'; ++ proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; + +- if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { +- debug("No xauth program."); +- } else if (!client_x11_display_valid(display)) { +- logit("DISPLAY '%s' invalid, falling back to fake xauth data", ++ if (!client_x11_display_valid(display)) { ++ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", + display); +- } else { +- if (display == NULL) { +- debug("x11_get_proto: DISPLAY not set"); +- return; +- } ++ return -1; ++ } ++ if (xauth_path != NULL && stat(xauth_path, &st) == -1) { ++ debug("No xauth program."); ++ xauth_path = NULL; ++ } ++ ++ if (xauth_path != NULL) { + /* + * Handle FamilyLocal case where $DISPLAY does + * not match an authorization entry. For this we +@@ -337,43 +339,60 @@ client_x11_get_proto(const char *display, const char *xauth_path, + * is not perfect. + */ + if (strncmp(display, "localhost:", 10) == 0) { +- snprintf(xdisplay, sizeof(xdisplay), "unix:%s", +- display + 10); ++ if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", ++ display + 10)) < 0 || ++ (size_t)r >= sizeof(xdisplay)) { ++ error("%s: display name too long", __func__); ++ return -1; ++ } + display = xdisplay; + } + if (trusted == 0) { +- mktemp_proto(xauthdir, PATH_MAX); + /* ++ * Generate an untrusted X11 auth cookie. ++ * + * The authentication cookie should briefly outlive + * ssh's willingness to forward X11 connections to + * avoid nasty fail-open behaviour in the X server. + */ ++ mktemp_proto(xauthdir, sizeof(xauthdir)); ++ if (mkdtemp(xauthdir) == NULL) { ++ error("%s: mkdtemp: %s", ++ __func__, strerror(errno)); ++ return -1; ++ } ++ do_unlink = 1; ++ if ((r = snprintf(xauthfile, sizeof(xauthfile), ++ "%s/xauthfile", xauthdir)) < 0 || ++ (size_t)r >= sizeof(xauthfile)) { ++ error("%s: xauthfile path too long", __func__); ++ unlink(xauthfile); ++ rmdir(xauthdir); ++ return -1; ++ } ++ + if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) + x11_timeout_real = UINT_MAX; + else + x11_timeout_real = timeout + X11_TIMEOUT_SLACK; +- if (mkdtemp(xauthdir) != NULL) { +- do_unlink = 1; +- snprintf(xauthfile, PATH_MAX, "%s/xauthfile", +- xauthdir); +- snprintf(cmd, sizeof(cmd), +- "%s -f %s generate %s " SSH_X11_PROTO +- " untrusted timeout %u 2>" _PATH_DEVNULL, +- xauth_path, xauthfile, display, +- x11_timeout_real); +- debug2("x11_get_proto: %s", cmd); +- if (x11_refuse_time == 0) { +- now = monotime() + 1; +- if (UINT_MAX - timeout < now) +- x11_refuse_time = UINT_MAX; +- else +- x11_refuse_time = now + timeout; +- channel_set_x11_refuse_time( +- x11_refuse_time); +- } +- if (system(cmd) == 0) +- generated = 1; ++ if ((r = snprintf(cmd, sizeof(cmd), ++ "%s -f %s generate %s " SSH_X11_PROTO ++ " untrusted timeout %u 2>" _PATH_DEVNULL, ++ xauth_path, xauthfile, display, ++ x11_timeout_real)) < 0 || ++ (size_t)r >= sizeof(cmd)) ++ fatal("%s: cmd too long", __func__); ++ debug2("%s: %s", __func__, cmd); ++ if (x11_refuse_time == 0) { ++ now = monotime() + 1; ++ if (UINT_MAX - timeout < now) ++ x11_refuse_time = UINT_MAX; ++ else ++ x11_refuse_time = now + timeout; ++ channel_set_x11_refuse_time(x11_refuse_time); + } ++ if (system(cmd) == 0) ++ generated = 1; + } + + /* +@@ -395,9 +414,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, + got_data = 1; + if (f) + pclose(f); +- } else +- error("Warning: untrusted X11 forwarding setup failed: " +- "xauth key data not generated"); ++ } + } + + if (do_unlink) { +@@ -405,6 +422,13 @@ client_x11_get_proto(const char *display, const char *xauth_path, + rmdir(xauthdir); + } + ++ /* Don't fall back to fake X11 data for untrusted forwarding */ ++ if (!trusted && !got_data) { ++ error("Warning: untrusted X11 forwarding setup failed: " ++ "xauth key data not generated"); ++ return -1; ++ } ++ + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the +@@ -427,6 +451,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, + rnd >>= 8; + } + } ++ ++ return 0; + } + + /* +diff --git a/clientloop.h b/clientloop.h +index 338d451..f4d4c69 100644 +--- a/clientloop.h ++++ b/clientloop.h +@@ -39,7 +39,7 @@ + + /* Client side main loop for the interactive session. */ + int client_loop(int, int, int); +-void client_x11_get_proto(const char *, const char *, u_int, u_int, ++int client_x11_get_proto(const char *, const char *, u_int, u_int, + char **, char **); + void client_global_request_reply_fwd(int, u_int32_t, void *); + void client_session2_setup(int, int, int, const char *, struct termios *, +diff --git a/mux.c b/mux.c +index f9c3af6..6bf53eb 100644 +--- a/mux.c ++++ b/mux.c +@@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg) + char *proto, *data; + + /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, ++ if (client_x11_get_proto(display, options.xauth_location, + options.forward_x11_trusted, options.forward_x11_timeout, +- &proto, &data); +- /* Request forwarding with authentication spoofing. */ +- debug("Requesting X11 forwarding with authentication " +- "spoofing."); +- x11_request_forwarding_with_spoofing(id, display, proto, +- data, 1); +- client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); +- /* XXX exit_on_forward_failure */ ++ &proto, &data) == 0) { ++ /* Request forwarding with authentication spoofing. */ ++ debug("Requesting X11 forwarding with authentication " ++ "spoofing."); ++ x11_request_forwarding_with_spoofing(id, display, proto, ++ data, 1); ++ /* XXX exit_on_forward_failure */ ++ client_expect_confirm(id, "X11 forwarding", ++ CONFIRM_WARN); ++ } + } + + if (cctx->want_agent_fwd && options.forward_agent) { +diff --git a/ssh.c b/ssh.c +index 81704ab..096c5b5 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -1626,6 +1626,7 @@ ssh_session(void) + struct winsize ws; + char *cp; + const char *display; ++ char *proto = NULL, *data = NULL; + + /* Enable compression if requested. */ + if (options.compression) { +@@ -1696,13 +1697,9 @@ ssh_session(void) + display = getenv("DISPLAY"); + if (display == NULL && options.forward_x11) + debug("X11 forwarding requested but DISPLAY not set"); +- if (options.forward_x11 && display != NULL) { +- char *proto, *data; +- /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, +- options.forward_x11_trusted, +- options.forward_x11_timeout, +- &proto, &data); ++ if (options.forward_x11 && client_x11_get_proto(display, ++ options.xauth_location, options.forward_x11_trusted, ++ options.forward_x11_timeout, &proto, &data) == 0) { + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication " + "spoofing."); +@@ -1792,6 +1789,7 @@ ssh_session2_setup(int id, int success, void *arg) + extern char **environ; + const char *display; + int interactive = tty_flag; ++ char *proto = NULL, *data = NULL; + + if (!success) + return; /* No need for error message, channels code sens one */ +@@ -1799,12 +1797,9 @@ ssh_session2_setup(int id, int success, void *arg) + display = getenv("DISPLAY"); + if (display == NULL && options.forward_x11) + debug("X11 forwarding requested but DISPLAY not set"); +- if (options.forward_x11 && display != NULL) { +- char *proto, *data; +- /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, +- options.forward_x11_trusted, +- options.forward_x11_timeout, &proto, &data); ++ if (options.forward_x11 && client_x11_get_proto(display, ++ options.xauth_location, options.forward_x11_trusted, ++ options.forward_x11_timeout, &proto, &data) == 0) { + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication " + "spoofing."); +-- +2.5.0 From 9eea03bdb048da643cdf743f9c127c87a57d4687 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 1 Feb 2016 16:07:36 +0100 Subject: [PATCH 021/146] Based on openssh-7.1p2-3.fc23 --- gsi-openssh.spec | 5 ++++- gsisshd.service | 4 +++- openssh-7.1p2-fallback-x11-untrusted.patch | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 89485f6..78ba89c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.1p2 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -554,6 +554,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Feb 01 2016 Mattias Ellert - 7.1p2-3 +- Based on openssh-7.1p2-3.fc23 + * Fri Jan 29 2016 Mattias Ellert - 7.1p2-2 - Based on openssh-7.1p2-2.fc23 diff --git a/gsisshd.service b/gsisshd.service index f778281..2c11964 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -5,8 +5,10 @@ After=network.target gsisshd-keygen.service Wants=gsisshd-keygen.service [Service] +Type=forking +PIDFile=/var/run/gsisshd.pid EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd -D $OPTIONS +ExecStart=/usr/sbin/gsisshd $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/openssh-7.1p2-fallback-x11-untrusted.patch b/openssh-7.1p2-fallback-x11-untrusted.patch index 1fecbfd..2822e3f 100644 --- a/openssh-7.1p2-fallback-x11-untrusted.patch +++ b/openssh-7.1p2-fallback-x11-untrusted.patch @@ -113,7 +113,7 @@ index f555451..c0386d5 100644 - } else if (!client_x11_display_valid(display)) { - logit("DISPLAY '%s' invalid, falling back to fake xauth data", + if (!client_x11_display_valid(display)) { -+ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", ++ debug("DISPLAY \"%s\" invalid; disabling X11 forwarding", display); - } else { - if (display == NULL) { From 414c76f11231f956d0680416dd6f68e4f66fde8b Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 3 Feb 2016 23:23:17 +0000 Subject: [PATCH 022/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 78ba89c..fc5cae7 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -554,6 +554,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Feb 03 2016 Fedora Release Engineering - 7.1p2-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + * Mon Feb 01 2016 Mattias Ellert - 7.1p2-3 - Based on openssh-7.1p2-3.fc23 From 1d944e946b428dc3906a26bff6d499752cfefa53 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 2 Mar 2016 17:20:42 +0100 Subject: [PATCH 023/146] Based on openssh-7.1p2-4.fc23 --- gsi-openssh.spec | 13 +- openssh-5.8p1-glob.patch | 26 ---- openssh-6.6p1-privsep-selinux.patch | 2 +- openssh-7.1p2-audit-race-condition.patch | 143 +++++++++++++++++++++ openssh-7.1p2-fallback-x11-untrusted.patch | 37 +++++- 5 files changed, 188 insertions(+), 33 deletions(-) delete mode 100644 openssh-5.8p1-glob.patch create mode 100644 openssh-7.1p2-audit-race-condition.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index fc5cae7..9539f97 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.1p2 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -63,6 +63,8 @@ Patch103: openssh-5.8p1-packet.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event Patch200: openssh-6.7p1-audit.patch +# Audit race condition in forked child (#1310684) +Patch201: openssh-7.1p2-audit-race-condition.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-6.6p1-role-mls.patch @@ -76,8 +78,6 @@ Patch502: openssh-6.6p1-keycat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1644 Patch601: openssh-6.6p1-allow-ip-opts.patch -#http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/crypto/dist/ssh/Attic/sftp-glob.c.diff?r1=1.13&r2=1.13.12.1&f=h -Patch603: openssh-5.8p1-glob.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1893 Patch604: openssh-6.6p1-keyperm.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1925 @@ -295,7 +295,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch502 -p1 -b .keycat %patch601 -p1 -b .ip-opts -%patch603 -p1 -b .glob %patch604 -p1 -b .keyperm %patch606 -p1 -b .ipv6man %patch607 -p1 -b .sigpipe @@ -344,6 +343,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch937 -p1 -b .x11-fallback %patch200 -p1 -b .audit +%patch201 -p1 -b .audit-race %patch700 -p1 -b .fips %patch100 -p1 -b .coverity @@ -554,6 +554,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Mar 02 2016 Mattias Ellert - 7.1p2-4 +- Based on openssh-7.1p2-4.fc23 + * Wed Feb 03 2016 Fedora Release Engineering - 7.1p2-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild diff --git a/openssh-5.8p1-glob.patch b/openssh-5.8p1-glob.patch deleted file mode 100644 index 5fcd070..0000000 --- a/openssh-5.8p1-glob.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -up openssh-5.8p1/sftp-glob.c.glob openssh-5.8p1/sftp-glob.c ---- openssh-5.8p1/sftp-glob.c.glob 2011-03-07 20:17:34.000000000 +0100 -+++ openssh-5.8p1/sftp-glob.c 2011-03-07 20:18:47.000000000 +0100 -@@ -145,5 +145,5 @@ remote_glob(struct sftp_conn *conn, cons - memset(&cur, 0, sizeof(cur)); - cur.conn = conn; - -- return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); -+ return(glob(pattern, flags | GLOB_LIMIT | GLOB_ALTDIRFUNC, errfunc, pglob)); - } -diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c -index 742b4b9..acae399 100644 ---- a/openbsd-compat/glob.c -+++ b/openbsd-compat/glob.c -@@ -130,8 +130,8 @@ typedef char Char; - #define M_CLASS META(':') - #define ismeta(c) (((c)&M_QUOTE) != 0) - --#define GLOB_LIMIT_MALLOC 65536 --#define GLOB_LIMIT_STAT 128 -+#define GLOB_LIMIT_MALLOC 65536*64 -+#define GLOB_LIMIT_STAT 128*64 - #define GLOB_LIMIT_READDIR 16384 - - /* Limit of recursion during matching attempts. */ - diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 87f53df..d7817e5 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -141,7 +141,7 @@ index 684f867..09048bc 100644 platform_setusercontext(pw); - if (platform_privileged_uidswap()) { -+ if (platform_privileged_uidswap() && !is_child) { ++ 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) { diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch new file mode 100644 index 0000000..04039a7 --- /dev/null +++ b/openssh-7.1p2-audit-race-condition.patch @@ -0,0 +1,143 @@ +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 89a1762..fe98e08 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -1251,4 +1251,48 @@ mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); + buffer_free(&m); + } ++ ++int mm_forward_audit_messages(int fdin) ++{ ++ u_char buf[4]; ++ u_int blen, msg_len; ++ Buffer m; ++ int ret = 0; ++ ++ debug3("%s: entering", __func__); ++ buffer_init(&m); ++ do { ++ blen = atomicio(read, fdin, buf, sizeof(buf)); ++ if (blen == 0) /* closed pipe */ ++ break; ++ if (blen != sizeof(buf)) { ++ error("%s: Failed to read the buffer from child", __func__); ++ ret = -1; ++ break; ++ } ++ ++ msg_len = get_u32(buf); ++ if (msg_len > 256 * 1024) ++ fatal("%s: read: bad msg_len %d", __func__, msg_len); ++ buffer_clear(&m); ++ buffer_append_space(&m, msg_len); ++ if (atomicio(read, fdin, buffer_ptr(&m), msg_len) != msg_len) { ++ error("%s: Failed to read the the buffer conent from the child", __func__); ++ ret = -1; ++ break; ++ } ++ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || ++ atomicio(vwrite, pmonitor->m_recvfd, buffer_ptr(&m), msg_len) != msg_len) { ++ error("%s: Failed to write the messag to the monitor", __func__); ++ ret = -1; ++ break; ++ } ++ } while (1); ++ buffer_free(&m); ++ return ret; ++} ++void mm_set_monitor_pipe(int fd) ++{ ++ pmonitor->m_recvfd = fd; ++} + #endif /* SSH_AUDIT_EVENTS */ +diff --git a/monitor_wrap.h b/monitor_wrap.h +index e73134e..fbfe395 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -86,6 +86,8 @@ void mm_audit_unsupported_body(int); + void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); + void mm_audit_session_key_free_body(int, pid_t, uid_t); + void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); ++int mm_forward_audit_messages(int); ++void mm_set_monitor_pipe(int); + #endif + + struct Session; +diff --git a/session.c b/session.c +index 8949fd1..9afb764 100644 +--- a/session.c ++++ b/session.c +@@ -159,6 +159,10 @@ static Session *sessions = NULL; + login_cap_t *lc; + #endif + ++#ifdef SSH_AUDIT_EVENTS ++int paudit[2]; ++#endif ++ + static int is_child = 0; + + static int have_dev_log = 1; +@@ -875,6 +879,8 @@ do_exec(Session *s, const char *command) + } + if (s->command != NULL && s->ptyfd == -1) + s->command_handle = PRIVSEP(audit_run_command(s->command)); ++ if (pipe(paudit) < 0) ++ fatal("pipe: %s", strerror(errno)); + #endif + if (s->ttyfd != -1) + ret = do_exec_pty(s, command); +@@ -890,6 +896,20 @@ do_exec(Session *s, const char *command) + */ + buffer_clear(&loginmsg); + ++#ifdef SSH_AUDIT_EVENTS ++ close(paudit[1]); ++ 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, ++ * because the messages might get mixed up. ++ * Continue after the pipe gets closed (all messages sent). ++ */ ++ ret = mm_forward_audit_messages(paudit[0]); ++ } ++ close(paudit[0]); ++#endif /* SSH_AUDIT_EVENTS */ ++ + return ret; + } + +@@ -1707,12 +1727,28 @@ do_child(Session *s, const char *command) + struct passwd *pw = s->pw; + int r = 0; + ++#ifdef SSH_AUDIT_EVENTS ++ 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); ++#endif ++ + /* remove hostkey from the child's memory */ +- destroy_sensitive_data(1); +- /* Don't audit this - both us and the parent would be talking to the +- monitor over a single socket, with no synchronization. */ ++ destroy_sensitive_data(use_privsep); ++ /* ++ * We can audit this, because wer hacked the pipe to direct the ++ * messages over postauth child. But this message requires answer ++ * which we can't do using one-way pipe. ++ */ + packet_destroy_all(0, 1); + ++#ifdef SSH_AUDIT_EVENTS ++ /* Notify parent that we are done */ ++ close(pparent); ++#endif ++ + /* Force a password change */ + if (s->authctxt->force_pwchange) { + do_setusercontext(pw); diff --git a/openssh-7.1p2-fallback-x11-untrusted.patch b/openssh-7.1p2-fallback-x11-untrusted.patch index 2822e3f..3fdf5fe 100644 --- a/openssh-7.1p2-fallback-x11-untrusted.patch +++ b/openssh-7.1p2-fallback-x11-untrusted.patch @@ -113,7 +113,7 @@ index f555451..c0386d5 100644 - } else if (!client_x11_display_valid(display)) { - logit("DISPLAY '%s' invalid, falling back to fake xauth data", + if (!client_x11_display_valid(display)) { -+ debug("DISPLAY \"%s\" invalid; disabling X11 forwarding", ++ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", display); - } else { - if (display == NULL) { @@ -350,3 +350,38 @@ index 81704ab..096c5b5 100644 "spoofing."); -- 2.5.0 + +From 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a Mon Sep 17 00:00:00 2001 +From: "millert@openbsd.org" +Date: Mon, 1 Feb 2016 21:18:17 +0000 +Subject: upstream commit + +Avoid ugly "DISPLAY "(null)" invalid; disabling X11 + forwarding" message when DISPLAY is not set. This could also result in a + crash on systems with a printf that doesn't handle NULL. OK djm@ + +Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412 +--- + clientloop.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index f8f9a3f..f0a08f2 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -318,8 +318,9 @@ client_x11_get_proto(const char *display, const char *xauth_path, + proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; + + if (!client_x11_display_valid(display)) { +- logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", +- display); ++ if (display != NULL) ++ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", ++ display); + return -1; + } + if (xauth_path != NULL && stat(xauth_path, &st) == -1) { +-- +cgit v0.11.2 + + From 845bd874e8eb5ce084d3dc0a6f9fb934f3188cf5 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 4 Mar 2016 17:18:15 +0100 Subject: [PATCH 024/146] Based on openssh-7.2p1-2.fc23 --- gsi-openssh.spec | 28 +- openssh-6.6.1p1-log-in-chroot.patch | 15 +- openssh-6.6.1p1-selinux-contexts.patch | 2 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 2 +- openssh-6.6p1-ctr-cavstest.patch | 4 +- openssh-6.6p1-keycat.patch | 4 +- openssh-6.6p1-kuserok.patch | 4 +- openssh-6.6p1-privsep-selinux.patch | 26 +- openssh-6.6p1-role-mls.patch | 2 +- openssh-6.6p1-set_remote_ipaddr.patch | 2 +- openssh-6.7p1-coverity.patch | 4 +- openssh-6.7p1-kdf-cavs.patch | 8 +- openssh-6.7p1-ldap.patch | 16 +- openssh-7.0p1-gssKexAlgorithms.patch | 4 +- openssh-7.0p1-show-more-fingerprints.patch | 21 +- openssh-7.1p1-hostkeyalgorithms.patch | 46 -- openssh-7.1p1-ssh-copy-id.patch | 532 ------------------ openssh-7.1p2-audit-race-condition.patch | 2 +- openssh-7.1p2-fallback-x11-untrusted.patch | 387 ------------- ...1-audit.patch => openssh-7.2p1-audit.patch | 380 ++++++------- ...7p1-fips.patch => openssh-7.2p1-fips.patch | 188 +++---- ...gsissh.patch => openssh-7.2p1-gsissh.patch | 352 ++++++------ ...gsskex.patch => openssh-7.2p1-gsskex.patch | 353 ++++++------ sources | 2 +- 24 files changed, 679 insertions(+), 1705 deletions(-) delete mode 100644 openssh-7.1p1-hostkeyalgorithms.patch delete mode 100644 openssh-7.1p1-ssh-copy-id.patch delete mode 100644 openssh-7.1p2-fallback-x11-untrusted.patch rename openssh-6.7p1-audit.patch => openssh-7.2p1-audit.patch (84%) rename openssh-6.7p1-fips.patch => openssh-7.2p1-fips.patch (76%) rename openssh-7.1p1-gsissh.patch => openssh-7.2p1-gsissh.patch (90%) rename openssh-6.6p1-gsskex.patch => openssh-7.2p1-gsskex.patch (88%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9539f97..e84c1a3 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.1p2 -%global openssh_rel 4 +%global openssh_ver 7.2p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -62,7 +62,7 @@ Patch103: openssh-5.8p1-packet.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event -Patch200: openssh-6.7p1-audit.patch +Patch200: openssh-7.2p1-audit.patch # Audit race condition in forked child (#1310684) Patch201: openssh-7.1p2-audit-race-condition.patch @@ -88,7 +88,7 @@ Patch607: openssh-5.8p2-sigpipe.patch Patch609: openssh-5.5p1-x11.patch #? -Patch700: openssh-6.7p1-fips.patch +Patch700: openssh-7.2p1-fips.patch #? Patch702: openssh-5.1p1-askpass-progress.patch #? @@ -112,7 +112,7 @@ Patch714: openssh-6.7p1-kdf-cavs.patch #http://www.sxw.org.uk/computing/patches/openssh.html #changed cache storage type - #848228 -Patch800: openssh-6.6p1-gsskex.patch +Patch800: openssh-7.2p1-gsskex.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) @@ -169,21 +169,13 @@ Patch931: openssh-6.9p1-scp-progressmeter.patch Patch932: openssh-7.0p1-gssKexAlgorithms.patch # Possibility to validate legacy systems by more fingerprints (#1249626)(#2439) Patch933: openssh-7.0p1-show-more-fingerprints.patch -# Brokend HostKeyAlgorthms on server using + sign -# from http://lists.mindrot.org/pipermail/openssh-unix-dev/2015-August/034324.html -Patch934: openssh-7.1p1-hostkeyalgorithms.patch -# Updated version of ssh-copy-id -# http://git.hands.com/ssh-copy-id -Patch935: openssh-7.1p1-ssh-copy-id.patch # Preserve IUTF8 tty mode flag over ssh connections (#1270248) # https://bugzilla.mindrot.org/show_bug.cgi?id=2477 Patch936: openssh-7.1p1-iutf8.patch -# CVE-2016-1908: possible fallback from untrusted to trusted X11 forwarding -Patch937: openssh-7.1p2-fallback-x11-untrusted.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.1p1.patch -Patch98: openssh-7.1p1-gsissh.patch +# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch +Patch98: openssh-7.2p1-gsissh.patch License: BSD Group: Applications/Internet @@ -337,10 +329,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch931 -p1 -b .progressmeter %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint -%patch934 -p1 -b .hostkey -%patch935 -p1 -b .ssh-copy-id %patch936 -p1 -b .iutf8 -%patch937 -p1 -b .x11-fallback %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -554,6 +543,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Mar 04 2016 Mattias Ellert - 7.2p1-1 +- Based on openssh-7.2p1-2.fc23 + * Wed Mar 02 2016 Mattias Ellert - 7.1p2-4 - Based on openssh-7.1p2-4.fc23 diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 7590812..5889005 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -117,15 +117,14 @@ diff -up openssh-6.8p1/monitor.h.log-in-chroot openssh-6.8p1/monitor.h diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c --- openssh-6.8p1/session.c.log-in-chroot 2015-03-18 12:59:29.675022359 +0100 +++ openssh-6.8p1/session.c 2015-03-18 12:59:29.696022308 +0100 -@@ -161,6 +161,8 @@ login_cap_t *lc; +@@ -161,6 +161,7 @@ login_cap_t *lc; static int is_child = 0; - + static int in_chroot = 0; +static int have_dev_log = 1; -+ + /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; - static char *auth_sock_dir = NULL; @@ -506,8 +508,8 @@ do_exec_no_pty(Session *s, const char *c is_child = 1; @@ -150,8 +149,8 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c @@ -780,6 +782,7 @@ do_exec(Session *s, const char *command) int ret; - const char *forced = NULL; - char session_type[1024], *tty = NULL; + const char *forced = NULL, *tty = NULL; + char session_type[1024]; + struct stat dev_log_stat; if (options.adm_forced_command) { @@ -164,7 +163,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c + have_dev_log = 0; + } + - verbose("Starting session: %s%s%s for %s from %.200s port %d", + verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", @@ -1678,14 +1685,6 @@ child_close_fds(void) @@ -233,8 +232,8 @@ diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; @@ -1515,7 +1515,7 @@ sftp_server_main(int argc, char **argv, - extern char *__progname; + ssh_malloc_init(); /* must be called before any mallocs */ __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); diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 052843f..5a9233b 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -115,7 +115,7 @@ index 2871fe9..39b9c08 100644 + sshd_selinux_change_privsep_preauth_context(); #endif - /* Change our root directory */ + /* Demote the child */ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 12c014e..c5ef2ff 100644 --- a/openbsd-compat/port-linux.c diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index ae0e5b2..16333c3 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -106,9 +106,9 @@ diff -up openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users openssh-7.0p1/sshd_conf --- openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users 2015-08-12 11:27:44.023407950 +0200 +++ openssh-7.0p1/sshd_config.5 2015-08-12 11:27:44.048407911 +0200 @@ -633,6 +633,12 @@ on logout. + on logout. The default is .Dq yes . - Note that this option applies to protocol version 2 only. +.It Cm GSSAPIEnablek5users +Specifies whether to look at .k5users file for GSSAPI authentication +access control. Further details are described in diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index db9f47b..591ae6c 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -25,8 +25,8 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -326,6 +330,7 @@ install-files: $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 6018554..8d86014 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -59,8 +59,8 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -321,6 +325,7 @@ install-files: $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 0e6215d..ebb0196 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -190,8 +190,8 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c + if (options->use_kuserok == -1) + options->use_kuserok = 1; - if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 || - kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || + assemble_algorithms(options); + @@ -404,7 +407,7 @@ typedef enum { sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index d7817e5..3433fd6 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -47,15 +47,6 @@ diff --git a/session.c b/session.c index 2bcf818..b5dc144 100644 --- a/session.c +++ b/session.c -@@ -1532,7 +1532,7 @@ void - do_setusercontext(struct passwd *pw) - { - char *chroot_path, *tmp; --#ifdef USE_LIBIAF -+#if defined(USE_LIBIAF) || defined(WITH_SELINUX) - int doing_chroot = 0; - #endif - @@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *pw) pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, @@ -66,22 +57,13 @@ index 2bcf818..b5dc144 100644 safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); -@@ -1557,7 +1557,7 @@ do_setusercontext(struct passwd *pw) - /* Make sure we don't attempt to chroot again */ - free(options.chroot_directory); - options.chroot_directory = NULL; --#ifdef USE_LIBIAF -+#if defined(USE_LIBIAF) || defined(WITH_SELINUX) - doing_chroot = 1; - #endif - } @@ -1565,6 +1568,11 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif + +#ifdef WITH_SELINUX -+ if (doing_chroot == 0) ++ if (in_chroot == 0) + sshd_selinux_copy_context(); +#endif } else if (options.chroot_directory != NULL && @@ -119,9 +101,9 @@ index 07f9926..a97f8b7 100644 + ssh_selinux_change_context("sshd_net_t"); +#endif + - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, + /* Demote the child */ + if (getuid() == 0 || geteuid() == 0) { + /* Change our root directory */ @@ -755,6 +755,9 @@ privsep_postauth(Authctxt *authctxt) #ifdef DISABLE_FD_PASSING diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index 0c9d422..5ec22c4 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -355,7 +355,7 @@ diff -up openssh-6.8p1/monitor_wrap.h.role-mls openssh-6.8p1/monitor_wrap.h +++ openssh-6.8p1/monitor_wrap.h 2015-03-18 11:10:32.343936171 +0100 @@ -42,6 +42,9 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int); + int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); diff --git a/openssh-6.6p1-set_remote_ipaddr.patch b/openssh-6.6p1-set_remote_ipaddr.patch index 14ff48c..f601e3d 100644 --- a/openssh-6.6p1-set_remote_ipaddr.patch +++ b/openssh-6.6p1-set_remote_ipaddr.patch @@ -59,9 +59,9 @@ diff -up openssh-6.8p1/sshconnect.c.set_remote_ipaddr openssh-6.8p1/sshconnect.c --- openssh-6.8p1/sshconnect.c.set_remote_ipaddr 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/sshconnect.c 2015-03-18 12:40:58.096788804 +0100 @@ -65,6 +65,7 @@ - #include "version.h" #include "authfile.h" #include "ssherr.h" + #include "authfd.h" +#include "canohost.h" char *client_version_string = NULL; diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 4b8a26f..8834903 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -415,8 +415,8 @@ diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c --- openssh-6.8p1/sshd.c.coverity 2015-03-18 17:21:51.893264839 +0100 +++ openssh-6.8p1/sshd.c 2015-03-18 17:21:58.284251454 +0100 @@ -778,8 +778,10 @@ privsep_preauth(Authctxt *authctxt) - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); + + privsep_preauth_child(); setproctitle("%s", "[net]"); - if (box != NULL) + if (box != NULL) { diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index d219791..2f5874a 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -22,11 +22,11 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) -+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o roaming_dummy.o -+ $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o ++ $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -331,6 +335,8 @@ install-files: fi diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index a555579..1c3cb3e 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -148,8 +148,8 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in LIBOPENSSH_OBJS=\ ssh_api.o \ @@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ + sandbox-solaris.o -MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out -MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 @@ -165,8 +165,8 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in +ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -311,6 +317,10 @@ install-files: $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) @@ -187,9 +187,9 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in + $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ + $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ + fi - -rm -f $(DESTDIR)$(bindir)/slogin - ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + + install-sysconf: + if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ @@ -356,6 +370,13 @@ install-sysconf: else \ echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ @@ -218,9 +218,9 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 regress-prep: + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac --- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 6a469ff..6988f2f 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -95,9 +95,9 @@ diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c --- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200 +++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200 @@ -50,6 +50,7 @@ + #include "misc.h" #include "dispatch.h" #include "monitor.h" - #include "roaming.h" +#include "xmalloc.h" #include "ssherr.h" @@ -336,9 +336,9 @@ diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5 --- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200 +++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200 @@ -786,6 +786,18 @@ command line will be passed untouched to + command line will be passed untouched to the GSSAPI library. The default is .Dq no . - This option only applies to protocol version 2 connections using GSSAPI. +.It Cm GSSAPIKexAlgorithms +The list of key exchange algorithms that are offered for GSSAPI +key exchange. Possible values are diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index 52f9535..52c7d73 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -199,7 +199,7 @@ index f41960c..e12932f 100644 + options.fingerprint_hash[0], SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); - logit("Host key fingerprint is %s\n%s\n", fp, ra); + logit("Host key fingerprint is %s\n%s", fp, ra); @@ -964,12 +964,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, else snprintf(msg1, sizeof(msg1), "."); @@ -295,14 +295,14 @@ index 7751031..82ed92e 100644 goto done; debug2("input_userauth_pk_ok: fp %s", fp); @@ -1009,7 +1009,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) - int have_sig = 1; + int matched, ret = -1, have_sig = 1; char *fp; - if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, + if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) return 0; - debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); + debug3("%s: %s %s", __func__, key_type(id->key), fp); @@ -1635,7 +1635,7 @@ userauth_hostbased(Authctxt *authctxt) goto out; } @@ -323,10 +323,23 @@ index 1dca3e2..23bff7d 100644 - if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); + fatal("%s: sshkey_fingerprint failed", __progname); fatal("no matching hostkey found for key %s %s", -- 2.1.0 +diff --git a/sshconnect.c b/sshconnect.c +index de7ace6..f16e606 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -1262,7 +1262,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) + + if (sshkey_is_cert(host_key)) { + if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { + error("%s: fingerprint CA key: %s", + __func__, ssh_err(r)); + r = -1; diff --git a/openssh-7.1p1-hostkeyalgorithms.patch b/openssh-7.1p1-hostkeyalgorithms.patch deleted file mode 100644 index 4a22cdc..0000000 --- a/openssh-7.1p1-hostkeyalgorithms.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff --git a/readconf.c b/readconf.c -index 374e741..23d74fb 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -2229,6 +2229,10 @@ dump_client_config(Options *o, const char *host) - int i; - char vbuf[5]; - -+ /* This is normally prepared in ssh_kex2 */ -+ if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) -+ fatal("%s: kex_assemble_names failed", __func__); -+ - /* Most interesting options first: user, host, port */ - dump_cfg_string(oUser, o->user); - dump_cfg_string(oHostName, host); -@@ -2289,7 +2293,7 @@ dump_client_config(Options *o, const char *host) - dump_cfg_string(oBindAddress, o->bind_address); - dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); - dump_cfg_string(oControlPath, o->control_path); -- dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); -+ dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); - dump_cfg_string(oHostKeyAlias, o->host_key_alias); - dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); - dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); -diff --git a/servconf.c b/servconf.c -index 04404a4..08c8139 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -242,8 +242,6 @@ fill_default_server_options(ServerOptions *options) - options->hostbased_authentication = 0; - if (options->hostbased_uses_name_from_packet_only == -1) - options->hostbased_uses_name_from_packet_only = 0; -- if (options->hostkeyalgorithms == NULL) -- options->hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); - if (options->rsa_authentication == -1) - options->rsa_authentication = 1; - if (options->pubkey_authentication == -1) -@@ -329,6 +327,8 @@ fill_default_server_options(ServerOptions *options) - kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || - kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ &options->hostkeyalgorithms) != 0 || -+ kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->hostbased_key_types) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->pubkey_key_types) != 0) diff --git a/openssh-7.1p1-ssh-copy-id.patch b/openssh-7.1p1-ssh-copy-id.patch deleted file mode 100644 index a4e6f7d..0000000 --- a/openssh-7.1p1-ssh-copy-id.patch +++ /dev/null @@ -1,532 +0,0 @@ -From 1a52b2d612b1d0c2a15dfcdc8da560704909ec72 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 27 Jul 2013 14:16:52 +0100 -Subject: [PATCH] echo --> printf "%s: ERROR... (for consistency) - ---- - ssh-copy-id | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index ae88e99..516b87f 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -200,7 +200,7 @@ populate_new_ids() { - umask 0177 - local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) - if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then -- echo "mktemp failed" 1>&2 -+ printf '%s: ERROR: mktemp failed\n' "$0" >&2 - exit 1 - fi - trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT --- -1.9.1 - - - -From baebbb9e18e4a1af7554d939710eacb665a24b68 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Wed, 25 Nov 2015 17:05:39 +0100 -Subject: [PATCH] Deal with remote user shell being e.g. tcsh (fixes: 2206) - -as suggested by Jakub Jelen ---- - ssh-copy-id | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 516b87f..6a0447a 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -269,10 +269,8 @@ case "$REMOTE_VERSION" in - *) - # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect - populate_new_ids 0 -- [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " -- umask 077 ; -- mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; -- if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ -+ [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ -+ ssh "$@" "exec sh -c 'umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ - || exit 1 - ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) - ;; --- -1.9.1 - - - -From 35f05e39cda8670b3f6797330a3e521fda509a4c Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Wed, 25 Nov 2015 21:14:00 +0100 -Subject: [PATCH] set LogLevel to ensure that it's not set to 'None' (closes: - 2214) - -As pointed out by Sami Haahtinen , -the LogLevel is set to 'None' we'll not get the -Permission Denied we're looking for. ---- - ssh-copy-id | 1 + - 1 file changed, 1 insertion(+) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 6a0447a..70d3866 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -215,6 +215,7 @@ populate_new_ids() { - # The point being that if file based, ssh needs the private key, which it cannot - # find if only given the contents of the .pub file in an unrelated tmpfile - ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ -+ -o LogLevel=INFO \ - -o PreferredAuthentications=publickey \ - -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr -Date: Wed, 25 Nov 2015 22:30:43 +0100 -Subject: [PATCH] set ControlPath=none (closes: 2488) -MIME-Version: 1.0 -Content-Type: text/plain; charset=utf8 -Content-Transfer-Encoding: 8bit - -Thanks to Salvador Fandiño for the patch -This seems to be the same problem as described in 2195 ---- - ssh-copy-id | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 70d3866..7df7fad 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -215,6 +215,7 @@ populate_new_ids() { - # The point being that if file based, ssh needs the private key, which it cannot - # find if only given the contents of the .pub file in an unrelated tmpfile - ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ -+ -o ControlPath=none \ - -o LogLevel=INFO \ - -o PreferredAuthentications=publickey \ - -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr &2 - } - --REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | -+REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 | - sed -ne 's/.*remote software version //p') - - case "$REMOTE_VERSION" in --- -1.9.1 - - - -From 6fa6f1e3dbec32636e77d01228ceecfa3851c7e8 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Wed, 25 Nov 2015 23:24:13 +0100 -Subject: [PATCH] add -f (forced) option to install keys unconditionally - (closes: 2110) - -Thanks for the patch from Petr Lautrbach -which inspired this. ---- - ssh-copy-id | 15 +++++++++++++-- - ssh-copy-id.1 | 5 +++++ - 2 files changed, 18 insertions(+), 2 deletions(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 7df7fad..3121171 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -59,7 +59,10 @@ fi - DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) - - usage () { -- printf 'Usage: %s [-h|-?|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 -+ printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 -+ printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 -+ printf '\t-n: dry run -- no keys are actually copied\n' >&2 -+ printf '\t-h|-?: print this help\n' >&2 - exit 1 - } - -@@ -121,7 +124,7 @@ do - } - shift - ;; -- -n|-h|-\?) -+ -f|-n|-h|-\?) - OPT="$1" - OPTARG= - shift -@@ -154,6 +157,9 @@ do - -o|-p) - SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" - ;; -+ -f) -+ FORCED=1 -+ ;; - -n) - DRY_RUN=1 - ;; -@@ -194,6 +200,11 @@ fi - populate_new_ids() { - local L_SUCCESS="$1" - -+ if [ "$FORCED" ] ; then -+ NEW_IDS=$(eval $GET_ID) -+ return -+ fi -+ - # repopulate "$@" inside this function - eval set -- "$SSH_OPTS" - -diff --git $1/contrib/ssh-copy-id.1 $1/contrib/ssh-copy-id.1 -index 67a59e4..8850cce 100644 ---- $1/contrib/ssh-copy-id.1 -+++ $1/contrib/ssh-copy-id.1 -@@ -29,6 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - .Nd use locally available keys to authorise logins on a remote machine - .Sh SYNOPSIS - .Nm -+.Op Fl f - .Op Fl n - .Op Fl i Op Ar identity_file - .Op Fl p Ar port -@@ -76,6 +77,10 @@ is used. - Note that this can be used to ensure that the keys copied have the - comment one prefers and/or extra options applied, by ensuring that the - key file has these set as preferred before the copy is attempted. -+.It Fl f -+Forced mode: doesn't check if the keys are present on the remote server. -+This means that it does not need the private key. Of course, this can result -+in more than one copy of the key being installed on the remote system. - .It Fl n - do a dry-run. Instead of installing keys on the remote system simply - prints the key(s) that would have been installed. --- -1.9.1 - - - -From ab185eea5a03cdd846c909d83e5dd0a07a44fb54 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Wed, 25 Nov 2015 23:47:06 +0100 -Subject: [PATCH] deal with #2331 by suggesting the use of the -f option - ---- - ssh-copy-id | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 3121171..8666cea 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -250,7 +250,8 @@ populate_new_ids() { - exit 1 - fi - if [ -z "$NEW_IDS" ] ; then -- printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n\n' "$0" >&2 -+ printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 -+ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 - exit 0 - fi - printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 --- -1.9.1 - - - -From de78897ada50ed12f4b0c9faa6e935ce82ee49a6 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Thu, 26 Nov 2015 00:25:56 +0100 -Subject: [PATCH] handle keys with missing trailing newline (closes: 2350) - ---- - ssh-copy-id | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 8666cea..362b49b 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -218,7 +218,7 @@ populate_new_ids() { - printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 - NEW_IDS=$( - eval $GET_ID | { -- while read ID ; do -+ while read ID || [ "$ID" ] ; do - printf '%s\n' "$ID" > $L_TMP_ID_FILE - - # the next line assumes $PRIV_ID_FILE only set if using a single id file - this --- -1.9.1 - - - -From 6b903ab99a3f0107bb0dbde748a4372033bab00c Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Thu, 26 Nov 2015 00:36:09 +0100 -Subject: [PATCH] add a cd to ensure we're in the remote's home directory - (closes: 2349) - ---- - ssh-copy-id | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 362b49b..2932936 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -284,7 +284,7 @@ case "$REMOTE_VERSION" in - # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect - populate_new_ids 0 - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ -- ssh "$@" "exec sh -c 'umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ -+ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ - || exit 1 - ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) - ;; --- -1.9.1 - - - -From 441892cbf4ff96fd96908582b8170f51890b5deb Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 28 Nov 2015 14:42:36 +0100 -Subject: [PATCH] add comment about why the ugly one-line remote command is as - it is - -In case anyone looks here for the details: - * tcsh doesn't support multi-line strings, - which is why it's a one-liner. - * tcsh doesn't do 2>&1, and fish doesn't do - 'command || command' which is why we're runnig this under - sh (which is very likely to be a POSIX shell on any vaguely - Unix-like system) - * The 'cd' is there to make sure we're in the home dir, because - there was a bug report about having a cd in ~/.bashrc that resulted - in a .ssh being created elsewhere. - * the 'exec' ensures that we're not relying on anything beyond the - (hopefully POSIX) shell that's available as 'sh' on the remote system ---- - ssh-copy-id | 1 + - 1 file changed, 1 insertion(+) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 2932936..04c03eb 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -283,6 +283,7 @@ case "$REMOTE_VERSION" in - *) - # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect - populate_new_ids 0 -+ # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh. - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ - ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ - || exit 1 --- -1.9.1 - - - -From 8b59b122d321b97badd15c41e1a22863aa922a02 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 28 Nov 2015 14:46:47 +0100 -Subject: [PATCH] with '-f' there's no need to have access to the private key - ---- - ssh-copy-id | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 04c03eb..d3ff83b 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -80,7 +80,7 @@ use_id_file() { - PUB_ID_FILE="$L_ID_FILE.pub" - fi - -- PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) -+ [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) - - # check that the files are readable - for f in $PUB_ID_FILE $PRIV_ID_FILE ; do --- -1.9.1 - - - -From 1b931894de0614099255244be789ad097fd0948a Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 28 Nov 2015 14:47:35 +0100 -Subject: [PATCH] if the private key is missing, point out that '-f' might be - what's needed - ---- - ssh-copy-id | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index d3ff83b..f0b01aa 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -85,7 +85,9 @@ use_id_file() { - # check that the files are readable - for f in $PUB_ID_FILE $PRIV_ID_FILE ; do - ErrMSG=$( { : < $f ; } 2>&1 ) || { -- printf "\n%s: ERROR: failed to open ID file '%s': %s\n\n" "$0" "$f" "$(printf "%s\n" "$ErrMSG" | sed -e 's/.*: *//')" -+ local 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 - } - done --- -1.9.1 - - - -From fd3e8b115e160a1332773cd8e06a3305d0d680ab Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 28 Nov 2015 21:10:39 +0100 -Subject: [PATCH] +INFO message to mitigate the surprise described in #2196 - ---- - ssh-copy-id | 1 + - 1 file changed, 1 insertion(+) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index f0b01aa..994194e 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -91,6 +91,7 @@ use_id_file() { - exit 1 - } - done -+ printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" $PUB_ID_FILE >&2 - GET_ID="cat \"$PUB_ID_FILE\"" - } - --- -1.9.1 - - - -From 783ef08b0a757402aba67313f08f8dbfa9bf85f3 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Mon, 30 Nov 2015 20:46:19 +0100 -Subject: [PATCH] deal with $HOME and id filenames that include a space - ---- - ssh-copy-id | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git $1/contrib/ssh-copy-id $1/contrib/ssh-copy-id -index 994194e..afde8b1 100755 ---- $1/contrib/ssh-copy-id -+++ $1/contrib/ssh-copy-id -@@ -56,7 +56,7 @@ then - fi - fi - --DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) -+DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" - - usage () { - printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 -@@ -83,15 +83,15 @@ use_id_file() { - [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) - - # check that the files are readable -- for f in $PUB_ID_FILE $PRIV_ID_FILE ; do -- ErrMSG=$( { : < $f ; } 2>&1 ) || { -+ for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do -+ ErrMSG=$( { : < "$f" ; } 2>&1 ) || { - local 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 - } - done -- printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" $PUB_ID_FILE >&2 -+ printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 - GET_ID="cat \"$PUB_ID_FILE\"" - } - -@@ -217,12 +217,13 @@ populate_new_ids() { - printf '%s: ERROR: mktemp failed\n' "$0" >&2 - exit 1 - fi -- trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT -+ local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" -+ 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 - NEW_IDS=$( - eval $GET_ID | { - while read ID || [ "$ID" ] ; do -- printf '%s\n' "$ID" > $L_TMP_ID_FILE -+ printf '%s\n' "$ID" > "$L_TMP_ID_FILE" - - # the next line assumes $PRIV_ID_FILE only set if using a single id file - this - # assumption will break if we implement the possibility of multiple -i options. -@@ -246,7 +247,7 @@ populate_new_ids() { - done - } - ) -- rm -f $L_TMP_ID_FILE* && trap - EXIT TERM INT QUIT -+ eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT - - if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then - printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 --- -1.9.1 - - -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index afde8b1..cd52764 100644 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -99,6 +99,8 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then - GET_ID="ssh-add -L" - fi - -+[ "x$SSH_COPY_ID_LEGACY" != "x" ] && FORCED=1 -+ - while test "$#" -gt 0 - do - [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { -diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1 -index 8850cce..62f112d 100644 ---- a/contrib/ssh-copy-id.1 -+++ b/contrib/ssh-copy-id.1 -@@ -185,6 +185,22 @@ should prove enlightening (N.B. the modern approach is to use the - .Fl W - option, rather than - .Xr nc 1 ) . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -+.Pp -+.It Pa SSH_COPY_ID_LEGACY -+If the -+.Cm SSH_COPY_ID_LEGACY -+environment variable is set, the -+.Nm -+is run in a legacy mode. In this mode, the -+.Nm -+doesn't check an existence of a private key and doesn't do remote checks -+of the remote server versions or if public keys are already installed -+(equivalent to -+.Fl f -+switch). -+.El - .Sh "SEE ALSO" - .Xr ssh 1 , - .Xr ssh-agent 1 , diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 04039a7..0a58fb4 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -77,7 +77,7 @@ index 8949fd1..9afb764 100644 +#endif + static int is_child = 0; - + static int in_chroot = 0; static int have_dev_log = 1; @@ -875,6 +879,8 @@ do_exec(Session *s, const char *command) } diff --git a/openssh-7.1p2-fallback-x11-untrusted.patch b/openssh-7.1p2-fallback-x11-untrusted.patch deleted file mode 100644 index 3fdf5fe..0000000 --- a/openssh-7.1p2-fallback-x11-untrusted.patch +++ /dev/null @@ -1,387 +0,0 @@ -From f98a09cacff7baad8748c9aa217afd155a4d493f Mon Sep 17 00:00:00 2001 -From: "mmcc@openbsd.org" -Date: Tue, 20 Oct 2015 03:36:35 +0000 -Subject: [PATCH] upstream commit - -Replace a function-local allocation with stack memory. - -ok djm@ - -Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e ---- - clientloop.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/clientloop.c b/clientloop.c -index 87ceb3d..1e05cba 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -311,11 +311,10 @@ client_x11_get_proto(const char *display, const char *xauth_path, - static char proto[512], data[512]; - FILE *f; - int got_data = 0, generated = 0, do_unlink = 0, i; -- char *xauthdir, *xauthfile; -+ char xauthdir[PATH_MAX] = "", xauthfile[PATH_MAX] = ""; - struct stat st; - u_int now, x11_timeout_real; - -- xauthdir = xauthfile = NULL; - *_proto = proto; - *_data = data; - proto[0] = data[0] = '\0'; -@@ -343,8 +342,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, - display = xdisplay; - } - if (trusted == 0) { -- xauthdir = xmalloc(PATH_MAX); -- xauthfile = xmalloc(PATH_MAX); - mktemp_proto(xauthdir, PATH_MAX); - /* - * The authentication cookie should briefly outlive -@@ -407,8 +404,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, - unlink(xauthfile); - rmdir(xauthdir); - } -- free(xauthdir); -- free(xauthfile); - - /* - * If we didn't get authentication data, just make up some --- -2.5.0 - -From ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 13 Jan 2016 23:04:47 +0000 -Subject: [PATCH] upstream commit - -eliminate fallback from untrusted X11 forwarding to trusted - forwarding when the X server disables the SECURITY extension; Reported by - Thomas Hoger; ok deraadt@ - -Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 ---- - clientloop.c | 114 ++++++++++++++++++++++++++++++++++++----------------------- - clientloop.h | 4 +-- - mux.c | 22 ++++++------ - ssh.c | 23 +++++------- - 4 files changed, 93 insertions(+), 70 deletions(-) - -diff --git a/clientloop.c b/clientloop.c -index f555451..c0386d5 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -288,6 +288,9 @@ client_x11_display_valid(const char *display) - { - size_t i, dlen; - -+ if (display == NULL) -+ return 0; -+ - dlen = strlen(display); - for (i = 0; i < dlen; i++) { - if (!isalnum((u_char)display[i]) && -@@ -301,34 +304,33 @@ client_x11_display_valid(const char *display) - - #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" - #define X11_TIMEOUT_SLACK 60 --void -+int - client_x11_get_proto(const char *display, const char *xauth_path, - u_int trusted, u_int timeout, char **_proto, char **_data) - { -- char cmd[1024]; -- char line[512]; -- char xdisplay[512]; -+ char cmd[1024], line[512], xdisplay[512]; -+ char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; - static char proto[512], data[512]; - FILE *f; -- int got_data = 0, generated = 0, do_unlink = 0, i; -- char xauthdir[PATH_MAX] = "", xauthfile[PATH_MAX] = ""; -+ int got_data = 0, generated = 0, do_unlink = 0, i, r; - struct stat st; - u_int now, x11_timeout_real; - - *_proto = proto; - *_data = data; -- proto[0] = data[0] = '\0'; -+ proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; - -- if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { -- debug("No xauth program."); -- } else if (!client_x11_display_valid(display)) { -- logit("DISPLAY '%s' invalid, falling back to fake xauth data", -+ if (!client_x11_display_valid(display)) { -+ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", - display); -- } else { -- if (display == NULL) { -- debug("x11_get_proto: DISPLAY not set"); -- return; -- } -+ return -1; -+ } -+ if (xauth_path != NULL && stat(xauth_path, &st) == -1) { -+ debug("No xauth program."); -+ xauth_path = NULL; -+ } -+ -+ if (xauth_path != NULL) { - /* - * Handle FamilyLocal case where $DISPLAY does - * not match an authorization entry. For this we -@@ -337,43 +339,60 @@ client_x11_get_proto(const char *display, const char *xauth_path, - * is not perfect. - */ - if (strncmp(display, "localhost:", 10) == 0) { -- snprintf(xdisplay, sizeof(xdisplay), "unix:%s", -- display + 10); -+ if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", -+ display + 10)) < 0 || -+ (size_t)r >= sizeof(xdisplay)) { -+ error("%s: display name too long", __func__); -+ return -1; -+ } - display = xdisplay; - } - if (trusted == 0) { -- mktemp_proto(xauthdir, PATH_MAX); - /* -+ * Generate an untrusted X11 auth cookie. -+ * - * The authentication cookie should briefly outlive - * ssh's willingness to forward X11 connections to - * avoid nasty fail-open behaviour in the X server. - */ -+ mktemp_proto(xauthdir, sizeof(xauthdir)); -+ if (mkdtemp(xauthdir) == NULL) { -+ error("%s: mkdtemp: %s", -+ __func__, strerror(errno)); -+ return -1; -+ } -+ do_unlink = 1; -+ if ((r = snprintf(xauthfile, sizeof(xauthfile), -+ "%s/xauthfile", xauthdir)) < 0 || -+ (size_t)r >= sizeof(xauthfile)) { -+ error("%s: xauthfile path too long", __func__); -+ unlink(xauthfile); -+ rmdir(xauthdir); -+ return -1; -+ } -+ - if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) - x11_timeout_real = UINT_MAX; - else - x11_timeout_real = timeout + X11_TIMEOUT_SLACK; -- if (mkdtemp(xauthdir) != NULL) { -- do_unlink = 1; -- snprintf(xauthfile, PATH_MAX, "%s/xauthfile", -- xauthdir); -- snprintf(cmd, sizeof(cmd), -- "%s -f %s generate %s " SSH_X11_PROTO -- " untrusted timeout %u 2>" _PATH_DEVNULL, -- xauth_path, xauthfile, display, -- x11_timeout_real); -- debug2("x11_get_proto: %s", cmd); -- if (x11_refuse_time == 0) { -- now = monotime() + 1; -- if (UINT_MAX - timeout < now) -- x11_refuse_time = UINT_MAX; -- else -- x11_refuse_time = now + timeout; -- channel_set_x11_refuse_time( -- x11_refuse_time); -- } -- if (system(cmd) == 0) -- generated = 1; -+ if ((r = snprintf(cmd, sizeof(cmd), -+ "%s -f %s generate %s " SSH_X11_PROTO -+ " untrusted timeout %u 2>" _PATH_DEVNULL, -+ xauth_path, xauthfile, display, -+ x11_timeout_real)) < 0 || -+ (size_t)r >= sizeof(cmd)) -+ fatal("%s: cmd too long", __func__); -+ debug2("%s: %s", __func__, cmd); -+ if (x11_refuse_time == 0) { -+ now = monotime() + 1; -+ if (UINT_MAX - timeout < now) -+ x11_refuse_time = UINT_MAX; -+ else -+ x11_refuse_time = now + timeout; -+ channel_set_x11_refuse_time(x11_refuse_time); - } -+ if (system(cmd) == 0) -+ generated = 1; - } - - /* -@@ -395,9 +414,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, - got_data = 1; - if (f) - pclose(f); -- } else -- error("Warning: untrusted X11 forwarding setup failed: " -- "xauth key data not generated"); -+ } - } - - if (do_unlink) { -@@ -405,6 +422,13 @@ client_x11_get_proto(const char *display, const char *xauth_path, - rmdir(xauthdir); - } - -+ /* Don't fall back to fake X11 data for untrusted forwarding */ -+ if (!trusted && !got_data) { -+ error("Warning: untrusted X11 forwarding setup failed: " -+ "xauth key data not generated"); -+ return -1; -+ } -+ - /* - * If we didn't get authentication data, just make up some - * data. The forwarding code will check the validity of the -@@ -427,6 +451,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, - rnd >>= 8; - } - } -+ -+ return 0; - } - - /* -diff --git a/clientloop.h b/clientloop.h -index 338d451..f4d4c69 100644 ---- a/clientloop.h -+++ b/clientloop.h -@@ -39,7 +39,7 @@ - - /* Client side main loop for the interactive session. */ - int client_loop(int, int, int); --void client_x11_get_proto(const char *, const char *, u_int, u_int, -+int client_x11_get_proto(const char *, const char *, u_int, u_int, - char **, char **); - void client_global_request_reply_fwd(int, u_int32_t, void *); - void client_session2_setup(int, int, int, const char *, struct termios *, -diff --git a/mux.c b/mux.c -index f9c3af6..6bf53eb 100644 ---- a/mux.c -+++ b/mux.c -@@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg) - char *proto, *data; - - /* Get reasonable local authentication information. */ -- client_x11_get_proto(display, options.xauth_location, -+ if (client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, options.forward_x11_timeout, -- &proto, &data); -- /* Request forwarding with authentication spoofing. */ -- debug("Requesting X11 forwarding with authentication " -- "spoofing."); -- x11_request_forwarding_with_spoofing(id, display, proto, -- data, 1); -- client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); -- /* XXX exit_on_forward_failure */ -+ &proto, &data) == 0) { -+ /* Request forwarding with authentication spoofing. */ -+ debug("Requesting X11 forwarding with authentication " -+ "spoofing."); -+ x11_request_forwarding_with_spoofing(id, display, proto, -+ data, 1); -+ /* XXX exit_on_forward_failure */ -+ client_expect_confirm(id, "X11 forwarding", -+ CONFIRM_WARN); -+ } - } - - if (cctx->want_agent_fwd && options.forward_agent) { -diff --git a/ssh.c b/ssh.c -index 81704ab..096c5b5 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -1626,6 +1626,7 @@ ssh_session(void) - struct winsize ws; - char *cp; - const char *display; -+ char *proto = NULL, *data = NULL; - - /* Enable compression if requested. */ - if (options.compression) { -@@ -1696,13 +1697,9 @@ ssh_session(void) - display = getenv("DISPLAY"); - if (display == NULL && options.forward_x11) - debug("X11 forwarding requested but DISPLAY not set"); -- if (options.forward_x11 && display != NULL) { -- char *proto, *data; -- /* Get reasonable local authentication information. */ -- client_x11_get_proto(display, options.xauth_location, -- options.forward_x11_trusted, -- options.forward_x11_timeout, -- &proto, &data); -+ if (options.forward_x11 && client_x11_get_proto(display, -+ options.xauth_location, options.forward_x11_trusted, -+ options.forward_x11_timeout, &proto, &data) == 0) { - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication " - "spoofing."); -@@ -1792,6 +1789,7 @@ ssh_session2_setup(int id, int success, void *arg) - extern char **environ; - const char *display; - int interactive = tty_flag; -+ char *proto = NULL, *data = NULL; - - if (!success) - return; /* No need for error message, channels code sens one */ -@@ -1799,12 +1797,9 @@ ssh_session2_setup(int id, int success, void *arg) - display = getenv("DISPLAY"); - if (display == NULL && options.forward_x11) - debug("X11 forwarding requested but DISPLAY not set"); -- if (options.forward_x11 && display != NULL) { -- char *proto, *data; -- /* Get reasonable local authentication information. */ -- client_x11_get_proto(display, options.xauth_location, -- options.forward_x11_trusted, -- options.forward_x11_timeout, &proto, &data); -+ if (options.forward_x11 && client_x11_get_proto(display, -+ options.xauth_location, options.forward_x11_trusted, -+ options.forward_x11_timeout, &proto, &data) == 0) { - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication " - "spoofing."); --- -2.5.0 - -From 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a Mon Sep 17 00:00:00 2001 -From: "millert@openbsd.org" -Date: Mon, 1 Feb 2016 21:18:17 +0000 -Subject: upstream commit - -Avoid ugly "DISPLAY "(null)" invalid; disabling X11 - forwarding" message when DISPLAY is not set. This could also result in a - crash on systems with a printf that doesn't handle NULL. OK djm@ - -Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412 ---- - clientloop.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/clientloop.c b/clientloop.c -index f8f9a3f..f0a08f2 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -318,8 +318,9 @@ client_x11_get_proto(const char *display, const char *xauth_path, - proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; - - if (!client_x11_display_valid(display)) { -- logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", -- display); -+ if (display != NULL) -+ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", -+ display); - return -1; - } - if (xauth_path != NULL && stat(xauth_path, &st) == -1) { --- -cgit v0.11.2 - - diff --git a/openssh-6.7p1-audit.patch b/openssh-7.2p1-audit.patch similarity index 84% rename from openssh-6.7p1-audit.patch rename to openssh-7.2p1-audit.patch index 106cda1..e7574b5 100644 --- a/openssh-6.7p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.0p1/audit-bsm.c.audit openssh-7.0p1/audit-bsm.c ---- openssh-7.0p1/audit-bsm.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/audit-bsm.c 2015-08-12 11:33:00.409914290 +0200 +diff -up openssh-7.2p1/audit-bsm.c.audit openssh-7.2p1/audit-bsm.c +--- openssh-7.2p1/audit-bsm.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/audit-bsm.c 2016-02-12 18:24:34.212825181 +0100 @@ -375,10 +375,23 @@ audit_connection_from(const char *host, #endif } @@ -80,9 +80,9 @@ diff -up openssh-7.0p1/audit-bsm.c.audit openssh-7.0p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-7.0p1/audit.c.audit openssh-7.0p1/audit.c ---- openssh-7.0p1/audit.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/audit.c 2015-08-12 11:33:00.410914289 +0200 +diff -up openssh-7.2p1/audit.c.audit openssh-7.2p1/audit.c +--- openssh-7.2p1/audit.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/audit.c 2016-02-12 18:24:34.216825179 +0100 @@ -28,6 +28,7 @@ #include @@ -280,9 +280,9 @@ diff -up openssh-7.0p1/audit.c.audit openssh-7.0p1/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.0p1/audit.h.audit openssh-7.0p1/audit.h ---- openssh-7.0p1/audit.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/audit.h 2015-08-12 11:33:00.410914289 +0200 +diff -up openssh-7.2p1/audit.h.audit openssh-7.2p1/audit.h +--- openssh-7.2p1/audit.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/audit.h 2016-02-12 18:24:34.216825179 +0100 @@ -28,6 +28,7 @@ # define _SSH_AUDIT_H @@ -318,9 +318,9 @@ diff -up openssh-7.0p1/audit.h.audit openssh-7.0p1/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh-7.0p1/audit-linux.c.audit openssh-7.0p1/audit-linux.c ---- openssh-7.0p1/audit-linux.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/audit-linux.c 2015-08-12 11:33:00.411914287 +0200 +diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c +--- openssh-7.2p1/audit-linux.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/audit-linux.c 2016-02-12 18:24:34.219825178 +0100 @@ -35,13 +35,25 @@ #include "log.h" @@ -712,9 +712,9 @@ diff -up openssh-7.0p1/audit-linux.c.audit openssh-7.0p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-7.0p1/auditstub.c.audit openssh-7.0p1/auditstub.c ---- openssh-7.0p1/auditstub.c.audit 2015-08-12 11:33:00.411914287 +0200 -+++ openssh-7.0p1/auditstub.c 2015-08-12 11:33:00.411914287 +0200 +diff -up openssh-7.2p1/auditstub.c.audit openssh-7.2p1/auditstub.c +--- openssh-7.2p1/auditstub.c.audit 2016-02-12 18:24:34.219825178 +0100 ++++ openssh-7.2p1/auditstub.c 2016-02-12 18:24:34.219825178 +0100 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -766,9 +766,9 @@ diff -up openssh-7.0p1/auditstub.c.audit openssh-7.0p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-7.0p1/auth2.c.audit openssh-7.0p1/auth2.c ---- openssh-7.0p1/auth2.c.audit 2015-08-12 11:33:00.349914384 +0200 -+++ openssh-7.0p1/auth2.c 2015-08-12 11:33:00.411914287 +0200 +diff -up openssh-7.2p1/auth2.c.audit openssh-7.2p1/auth2.c +--- openssh-7.2p1/auth2.c.audit 2016-02-12 18:24:34.148825205 +0100 ++++ openssh-7.2p1/auth2.c 2016-02-12 18:24:34.219825178 +0100 @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { logit("input_userauth_request: invalid user %s", user); @@ -779,9 +779,9 @@ diff -up openssh-7.0p1/auth2.c.audit openssh-7.0p1/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-7.0p1/auth2-hostbased.c.audit openssh-7.0p1/auth2-hostbased.c ---- openssh-7.0p1/auth2-hostbased.c.audit 2015-08-12 11:33:00.303914456 +0200 -+++ openssh-7.0p1/auth2-hostbased.c 2015-08-12 11:33:00.412914286 +0200 +diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c +--- openssh-7.2p1/auth2-hostbased.c.audit 2016-02-12 18:24:34.109825220 +0100 ++++ openssh-7.2p1/auth2-hostbased.c 2016-02-12 18:24:34.220825178 +0100 @@ -146,7 +146,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; @@ -810,10 +810,10 @@ diff -up openssh-7.0p1/auth2-hostbased.c.audit openssh-7.0p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-7.0p1/auth2-pubkey.c.audit openssh-7.0p1/auth2-pubkey.c ---- openssh-7.0p1/auth2-pubkey.c.audit 2015-08-12 11:33:00.318914432 +0200 -+++ openssh-7.0p1/auth2-pubkey.c 2015-08-12 11:33:00.412914286 +0200 -@@ -175,7 +175,7 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c +--- openssh-7.2p1/auth2-pubkey.c.audit 2016-02-12 18:24:34.122825215 +0100 ++++ openssh-7.2p1/auth2-pubkey.c 2016-02-12 18:24:34.220825178 +0100 +@@ -178,7 +178,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && @@ -822,7 +822,7 @@ diff -up openssh-7.0p1/auth2-pubkey.c.audit openssh-7.0p1/auth2-pubkey.c buffer_len(&b))) == 1) { authenticated = 1; /* Record the successful key to prevent reuse */ -@@ -253,6 +253,18 @@ pubkey_auth_info(Authctxt *authctxt, con +@@ -258,6 +258,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } @@ -841,10 +841,10 @@ diff -up openssh-7.0p1/auth2-pubkey.c.audit openssh-7.0p1/auth2-pubkey.c /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh-7.0p1/auth.c.audit openssh-7.0p1/auth.c ---- openssh-7.0p1/auth.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/auth.c 2015-08-12 11:33:00.412914286 +0200 -@@ -645,9 +645,6 @@ getpwnamallow(const char *user) +diff -up openssh-7.2p1/auth.c.audit openssh-7.2p1/auth.c +--- openssh-7.2p1/auth.c.audit 2016-02-12 18:24:34.148825205 +0100 ++++ openssh-7.2p1/auth.c 2016-02-12 18:24:34.220825178 +0100 +@@ -646,9 +646,6 @@ getpwnamallow(const char *user) record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); #endif @@ -854,9 +854,9 @@ diff -up openssh-7.0p1/auth.c.audit openssh-7.0p1/auth.c return (NULL); } if (!allowed_user(pw)) -diff -up openssh-7.0p1/auth.h.audit openssh-7.0p1/auth.h ---- openssh-7.0p1/auth.h.audit 2015-08-12 11:33:00.302914457 +0200 -+++ openssh-7.0p1/auth.h 2015-08-12 11:33:00.412914286 +0200 +diff -up openssh-7.2p1/auth.h.audit openssh-7.2p1/auth.h +--- openssh-7.2p1/auth.h.audit 2016-02-12 18:24:34.108825221 +0100 ++++ openssh-7.2p1/auth.h 2016-02-12 18:32:46.085636046 +0100 @@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt char *expand_authorized_keys(const char *, struct passwd *pw); @@ -868,14 +868,14 @@ diff -up openssh-7.0p1/auth.h.audit openssh-7.0p1/auth.h @@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc int ssh1_session_key(BIGNUM *); int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, - const u_char *, size_t, u_int); + const u_char *, size_t, const char *, u_int); +int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-7.0p1/auth-rsa.c.audit openssh-7.0p1/auth-rsa.c ---- openssh-7.0p1/auth-rsa.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/auth-rsa.c 2015-08-12 11:33:00.412914286 +0200 +diff -up openssh-7.2p1/auth-rsa.c.audit openssh-7.2p1/auth-rsa.c +--- openssh-7.2p1/auth-rsa.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/auth-rsa.c 2016-02-12 18:24:34.221825177 +0100 @@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNU { u_char buf[32], mdbuf[16]; @@ -912,9 +912,9 @@ diff -up openssh-7.0p1/auth-rsa.c.audit openssh-7.0p1/auth-rsa.c } /* -diff -up openssh-7.0p1/cipher.c.audit openssh-7.0p1/cipher.c ---- openssh-7.0p1/cipher.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/cipher.c 2015-08-12 11:33:00.412914286 +0200 +diff -up openssh-7.2p1/cipher.c.audit openssh-7.2p1/cipher.c +--- openssh-7.2p1/cipher.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/cipher.c 2016-02-12 18:24:34.221825177 +0100 @@ -57,26 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #endif @@ -942,9 +942,9 @@ diff -up openssh-7.0p1/cipher.c.audit openssh-7.0p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-7.0p1/cipher.h.audit openssh-7.0p1/cipher.h ---- openssh-7.0p1/cipher.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/cipher.h 2015-08-12 11:33:00.413914284 +0200 +diff -up openssh-7.2p1/cipher.h.audit openssh-7.2p1/cipher.h +--- openssh-7.2p1/cipher.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/cipher.h 2016-02-12 18:24:34.221825177 +0100 @@ -62,7 +62,26 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -973,9 +973,9 @@ diff -up openssh-7.0p1/cipher.h.audit openssh-7.0p1/cipher.h struct sshcipher_ctx { int plaintext; int encrypt; -diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.audit 2015-08-12 11:33:00.351914381 +0200 -+++ openssh-7.0p1/kex.c 2015-08-12 11:33:00.413914284 +0200 +diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c +--- openssh-7.2p1/kex.c.audit 2016-02-12 18:24:34.201825185 +0100 ++++ openssh-7.2p1/kex.c 2016-02-12 18:24:34.221825177 +0100 @@ -54,6 +54,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -984,7 +984,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -549,8 +550,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -669,8 +670,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -998,7 +998,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -568,8 +573,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -688,8 +693,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1012,7 +1012,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -586,8 +595,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -706,8 +715,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1026,7 +1026,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -753,6 +766,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -878,6 +891,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); @@ -1037,7 +1037,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -928,3 +945,34 @@ dump_digest(char *msg, u_char *digest, i +@@ -1052,3 +1069,34 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1054,7 +1054,7 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c + } + + if (enc->iv) { -+ memset(enc->iv, 0, enc->block_size); ++ memset(enc->iv, 0, enc->iv_len); + free(enc->iv); + } + @@ -1072,10 +1072,10 @@ diff -up openssh-7.0p1/kex.c.audit openssh-7.0p1/kex.c + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} + -diff -up openssh-7.0p1/kex.h.audit openssh-7.0p1/kex.h ---- openssh-7.0p1/kex.h.audit 2015-08-12 11:33:00.352914379 +0200 -+++ openssh-7.0p1/kex.h 2015-08-12 11:33:00.413914284 +0200 -@@ -202,6 +202,8 @@ int kexgss_client(struct ssh *); +diff -up openssh-7.2p1/kex.h.audit openssh-7.2p1/kex.h +--- openssh-7.2p1/kex.h.audit 2016-02-12 18:24:34.201825185 +0100 ++++ openssh-7.2p1/kex.h 2016-02-12 18:24:34.222825177 +0100 +@@ -206,6 +206,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1084,9 +1084,9 @@ diff -up openssh-7.0p1/kex.h.audit openssh-7.0p1/kex.h int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.0p1/key.h.audit openssh-7.0p1/key.h ---- openssh-7.0p1/key.h.audit 2015-08-12 11:33:00.413914284 +0200 -+++ openssh-7.0p1/key.h 2015-08-12 11:33:45.908843298 +0200 +diff -up openssh-7.2p1/key.h.audit openssh-7.2p1/key.h +--- openssh-7.2p1/key.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/key.h 2016-02-12 18:24:34.222825177 +0100 @@ -50,6 +50,7 @@ typedef struct sshkey Key; #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid @@ -1095,9 +1095,9 @@ diff -up openssh-7.0p1/key.h.audit openssh-7.0p1/key.h #define key_type_plain sshkey_type_plain #define key_curve_name_to_nid sshkey_curve_name_to_nid #define key_curve_nid_to_bits sshkey_curve_nid_to_bits -diff -up openssh-7.0p1/mac.c.audit openssh-7.0p1/mac.c ---- openssh-7.0p1/mac.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/mac.c 2015-08-12 11:33:00.413914284 +0200 +diff -up openssh-7.2p1/mac.c.audit openssh-7.2p1/mac.c +--- openssh-7.2p1/mac.c.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/mac.c 2016-02-12 18:24:34.222825177 +0100 @@ -226,6 +226,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1119,9 +1119,9 @@ diff -up openssh-7.0p1/mac.c.audit openssh-7.0p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-7.0p1/mac.h.audit openssh-7.0p1/mac.h ---- openssh-7.0p1/mac.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/mac.h 2015-08-12 11:33:00.413914284 +0200 +diff -up openssh-7.2p1/mac.h.audit openssh-7.2p1/mac.h +--- openssh-7.2p1/mac.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/mac.h 2016-02-12 18:24:34.222825177 +0100 @@ -47,5 +47,6 @@ int mac_init(struct sshmac *); int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, u_char *, size_t); @@ -1129,30 +1129,30 @@ diff -up openssh-7.0p1/mac.h.audit openssh-7.0p1/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-7.0p1/Makefile.in.audit openssh-7.0p1/Makefile.in ---- openssh-7.0p1/Makefile.in.audit 2015-08-12 11:33:00.402914301 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-12 11:33:00.414914283 +0200 -@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ +diff -up openssh-7.2p1/Makefile.in.audit openssh-7.2p1/Makefile.in +--- openssh-7.2p1/Makefile.in.audit 2016-02-12 18:24:34.222825177 +0100 ++++ openssh-7.2p1/Makefile.in 2016-02-12 18:33:38.858629492 +0100 +@@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ -- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o -+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o + kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ +- platform-pledge.o ++ platform-pledge.o auditstub.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ -diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c ---- openssh-7.0p1/monitor.c.audit 2015-08-12 11:33:00.378914339 +0200 -+++ openssh-7.0p1/monitor.c 2015-08-12 11:33:00.414914283 +0200 -@@ -102,6 +102,7 @@ + sshconnect.o sshconnect1.o sshconnect2.o mux.o +diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c +--- openssh-7.2p1/monitor.c.audit 2016-02-12 18:24:34.176825195 +0100 ++++ openssh-7.2p1/monitor.c 2016-02-12 18:34:05.184629882 +0100 +@@ -101,6 +101,7 @@ + #include "compat.h" #include "ssh2.h" - #include "roaming.h" #include "authfd.h" +#include "audit.h" #include "match.h" #include "ssherr.h" -@@ -117,6 +118,8 @@ extern Buffer auth_debug; +@@ -116,6 +117,8 @@ extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; @@ -1161,7 +1161,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c /* State exported from the child */ static struct sshbuf *child_state; -@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe +@@ -166,6 +169,11 @@ int mm_answer_gss_updatecreds(int, Buffe #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); @@ -1173,7 +1173,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c #endif static int monitor_read_log(struct monitor *); -@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -225,6 +233,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1184,7 +1184,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -263,6 +275,11 @@ struct mon_table mon_dispatch_postauth20 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1196,7 +1196,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c #endif {0, 0, NULL} }; -@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] +@@ -295,6 +312,10 @@ struct mon_table mon_dispatch_proto15[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1207,7 +1207,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c #endif #endif /* WITH_SSH1 */ {0, 0, NULL} -@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 +@@ -308,6 +329,11 @@ struct mon_table mon_dispatch_postauth15 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, @@ -1219,7 +1219,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c #endif #endif /* WITH_SSH1 */ {0, 0, NULL} -@@ -1467,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1464,9 +1490,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1231,7 +1231,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1477,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1474,6 +1502,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1240,7 +1240,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1497,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1494,7 +1524,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1259,7 +1259,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1558,6 +1598,12 @@ mm_session_close(Session *s) +@@ -1555,6 +1595,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1272,7 +1272,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c session_unused(s->self); } -@@ -1840,6 +1886,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1837,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1281,7 +1281,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1882,11 +1930,43 @@ mm_answer_audit_command(int socket, Buff +@@ -1879,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1326,7 +1326,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c free(cmd); return (0); } -@@ -1943,6 +2023,7 @@ monitor_apply_keystate(struct monitor *p +@@ -1940,6 +2020,7 @@ monitor_apply_keystate(struct monitor *p void mm_get_keystate(struct monitor *pmonitor) { @@ -1334,7 +1334,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1950,6 +2031,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1947,6 +2028,21 @@ mm_get_keystate(struct monitor *pmonitor mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); @@ -1356,7 +1356,7 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c } -@@ -2216,3 +2312,86 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -2213,3 +2309,86 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1443,9 +1443,9 @@ diff -up openssh-7.0p1/monitor.c.audit openssh-7.0p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.0p1/monitor.h.audit openssh-7.0p1/monitor.h ---- openssh-7.0p1/monitor.h.audit 2015-08-12 11:33:00.378914339 +0200 -+++ openssh-7.0p1/monitor.h 2015-08-12 11:33:00.414914283 +0200 +diff -up openssh-7.2p1/monitor.h.audit openssh-7.2p1/monitor.h +--- openssh-7.2p1/monitor.h.audit 2016-02-12 18:24:34.177825194 +0100 ++++ openssh-7.2p1/monitor.h 2016-02-12 18:24:34.224825176 +0100 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1461,9 +1461,9 @@ diff -up openssh-7.0p1/monitor.h.audit openssh-7.0p1/monitor.h }; -diff -up openssh-7.0p1/monitor_wrap.c.audit openssh-7.0p1/monitor_wrap.c ---- openssh-7.0p1/monitor_wrap.c.audit 2015-08-12 11:33:00.353914378 +0200 -+++ openssh-7.0p1/monitor_wrap.c 2015-08-12 11:33:00.414914283 +0200 +diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c +--- openssh-7.2p1/monitor_wrap.c.audit 2016-02-12 18:24:34.151825204 +0100 ++++ openssh-7.2p1/monitor_wrap.c 2016-02-12 18:24:34.224825176 +0100 @@ -462,7 +462,7 @@ mm_key_allowed(enum mm_keytype type, cha */ @@ -1611,9 +1611,9 @@ diff -up openssh-7.0p1/monitor_wrap.c.audit openssh-7.0p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.0p1/monitor_wrap.h.audit openssh-7.0p1/monitor_wrap.h ---- openssh-7.0p1/monitor_wrap.h.audit 2015-08-12 11:33:00.353914378 +0200 -+++ openssh-7.0p1/monitor_wrap.h 2015-08-12 11:33:00.415914281 +0200 +diff -up openssh-7.2p1/monitor_wrap.h.audit openssh-7.2p1/monitor_wrap.h +--- openssh-7.2p1/monitor_wrap.h.audit 2016-02-12 18:24:34.152825204 +0100 ++++ openssh-7.2p1/monitor_wrap.h 2016-02-12 18:24:34.224825176 +0100 @@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char int mm_user_key_allowed(struct passwd *, Key *, int); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); @@ -1638,9 +1638,9 @@ diff -up openssh-7.0p1/monitor_wrap.h.audit openssh-7.0p1/monitor_wrap.h #endif struct Session; -diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c ---- openssh-7.0p1/packet.c.audit 2015-08-12 11:33:00.288914479 +0200 -+++ openssh-7.0p1/packet.c 2015-08-12 11:33:00.415914281 +0200 +diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c +--- openssh-7.2p1/packet.c.audit 2016-02-12 18:24:34.095825226 +0100 ++++ openssh-7.2p1/packet.c 2016-02-12 18:43:47.268638489 +0100 @@ -67,6 +67,7 @@ #include "key.h" /* typedefs XXX */ @@ -1649,7 +1649,7 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c #include "crc32.h" #include "deattack.h" #include "compat.h" -@@ -449,6 +450,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -456,6 +457,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1663,7 +1663,7 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -479,13 +487,6 @@ ssh_packet_close(struct ssh *ssh) +@@ -500,13 +508,6 @@ ssh_packet_close(struct ssh *ssh) if (!state->initialized) return; state->initialized = 0; @@ -1677,7 +1677,7 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); -@@ -517,14 +518,24 @@ ssh_packet_close(struct ssh *ssh) +@@ -538,12 +539,22 @@ ssh_packet_close(struct ssh *ssh) inflateEnd(stream); } } @@ -1692,10 +1692,8 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c + error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); + audit_session_key_free(2); + } - if (ssh->remote_ipaddr) { - free(ssh->remote_ipaddr); - ssh->remote_ipaddr = NULL; - } + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + if (state->connection_in == state->connection_out) { + shutdown(state->connection_out, SHUT_RDWR); + close(state->connection_out); @@ -1706,15 +1704,15 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c free(ssh->state); ssh->state = NULL; } -@@ -944,6 +955,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - } - if (state->newkeys[mode] != NULL) { - debug("set_newkeys: rekeying"); +@@ -968,6 +979,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_read.blocks, + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); + audit_session_key_free(mode); if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; -@@ -2292,6 +2304,75 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2408,6 +2420,75 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1787,55 +1785,13 @@ diff -up openssh-7.0p1/packet.c.audit openssh-7.0p1/packet.c + } +} + - /* XXX TODO update roaming to new API (does not work anyway) */ - /* - * Save the state for the real connection, and use a separate state when -@@ -2301,18 +2382,12 @@ void - ssh_packet_backup_state(struct ssh *ssh, - struct ssh *backup_state) - { -- struct ssh *tmp; -- - close(ssh->state->connection_in); - ssh->state->connection_in = -1; - close(ssh->state->connection_out); - ssh->state->connection_out = -1; -- if (backup_state) -- tmp = backup_state; -- else -- tmp = ssh_alloc_session_state(); - backup_state = ssh; -- ssh = tmp; -+ ssh = ssh_alloc_session_state(); - } - - /* XXX FIXME FIXME FIXME */ -@@ -2331,9 +2406,7 @@ ssh_packet_restore_state(struct ssh *ssh - backup_state = ssh; - ssh = tmp; - ssh->state->connection_in = backup_state->state->connection_in; -- backup_state->state->connection_in = -1; - ssh->state->connection_out = backup_state->state->connection_out; -- backup_state->state->connection_out = -1; - len = sshbuf_len(backup_state->state->input); - if (len > 0) { - if ((r = sshbuf_putb(ssh->state->input, -@@ -2342,6 +2415,11 @@ ssh_packet_restore_state(struct ssh *ssh - sshbuf_reset(backup_state->state->input); - add_recv_bytes(len); - } -+ backup_state->state->connection_in = -1; -+ backup_state->state->connection_out = -1; -+ packet_destroy_state(backup_state->state); -+ free(backup_state); -+ backup_state = NULL; - } - /* Reset after_authentication and reset compression in post-auth privsep */ -diff -up openssh-7.0p1/packet.h.audit openssh-7.0p1/packet.h ---- openssh-7.0p1/packet.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/packet.h 2015-08-12 11:33:00.415914281 +0200 -@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); + static int + ssh_packet_set_postauth(struct ssh *ssh) +diff -up openssh-7.2p1/packet.h.audit openssh-7.2p1/packet.h +--- openssh-7.2p1/packet.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/packet.h 2016-02-12 18:24:34.226825175 +0100 +@@ -186,7 +186,7 @@ int sshpkt_get_end(struct ssh *ssh); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); /* OLD API */ @@ -1844,16 +1800,16 @@ diff -up openssh-7.0p1/packet.h.audit openssh-7.0p1/packet.h #include "opacket.h" #if !defined(WITH_OPENSSL) -@@ -203,4 +203,5 @@ extern struct ssh *active_state; +@@ -200,4 +200,5 @@ extern struct ssh *active_state; # undef EC_POINT #endif +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-7.0p1/sandbox-seccomp-filter.c.audit openssh-7.0p1/sandbox-seccomp-filter.c ---- openssh-7.0p1/sandbox-seccomp-filter.c.audit 2015-08-12 11:33:00.394914314 +0200 -+++ openssh-7.0p1/sandbox-seccomp-filter.c 2015-08-12 11:33:00.415914281 +0200 -@@ -150,6 +150,12 @@ static const struct sock_filter preauth_ +diff -up openssh-7.2p1/sandbox-seccomp-filter.c.audit openssh-7.2p1/sandbox-seccomp-filter.c +--- openssh-7.2p1/sandbox-seccomp-filter.c.audit 2016-02-12 18:24:34.193825188 +0100 ++++ openssh-7.2p1/sandbox-seccomp-filter.c 2016-02-12 18:24:34.226825175 +0100 +@@ -153,6 +153,12 @@ static const struct sock_filter preauth_ #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), #endif @@ -1866,9 +1822,9 @@ diff -up openssh-7.0p1/sandbox-seccomp-filter.c.audit openssh-7.0p1/sandbox-secc #ifdef __NR_madvise SC_ALLOW(madvise), #endif -diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c ---- openssh-7.0p1/session.c.audit 2015-08-12 11:33:00.379914337 +0200 -+++ openssh-7.0p1/session.c 2015-08-12 11:33:00.416914280 +0200 +diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c +--- openssh-7.2p1/session.c.audit 2016-02-12 18:24:34.177825194 +0100 ++++ openssh-7.2p1/session.c 2016-02-12 18:24:34.226825175 +0100 @@ -139,7 +139,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; @@ -1894,7 +1850,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c s->ptymaster = ptymaster; packet_set_interactive(1, @@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) - get_remote_port()); + s->self); #ifdef SSH_AUDIT_EVENTS + if (s->command != NULL || s->command_handle != -1) @@ -1915,7 +1871,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command +@@ -1695,7 +1707,10 @@ do_child(Session *s, const char *command int r = 0; /* remove hostkey from the child's memory */ @@ -1927,7 +1883,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1934,6 +1949,7 @@ session_unused(int id) +@@ -1925,6 +1940,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1935,7 +1891,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha +@@ -2007,6 +2023,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1955,7 +1911,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c session_by_tty(char *tty) { int i; -@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta +@@ -2523,6 +2552,32 @@ session_exit_message(Session *s, int sta chan_write_failed(c); } @@ -1988,8 +1944,8 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c void session_close(Session *s) { -@@ -2540,6 +2595,10 @@ session_close(Session *s) - debug("session_close: session %d pid %ld", s->self, (long)s->pid); +@@ -2531,6 +2586,10 @@ session_close(Session *s) + if (s->ttyfd != -1) session_pty_cleanup(s); +#ifdef SSH_AUDIT_EVENTS @@ -1999,7 +1955,7 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2754,6 +2813,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2745,6 +2804,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -2015,16 +1971,16 @@ diff -up openssh-7.0p1/session.c.audit openssh-7.0p1/session.c void do_cleanup(Authctxt *authctxt) { -@@ -2802,5 +2870,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2793,5 +2861,5 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff -up openssh-7.0p1/session.h.audit openssh-7.0p1/session.h ---- openssh-7.0p1/session.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/session.h 2015-08-12 11:33:00.416914280 +0200 +diff -up openssh-7.2p1/session.h.audit openssh-7.2p1/session.h +--- openssh-7.2p1/session.h.audit 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/session.h 2016-02-12 18:24:34.226825175 +0100 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2049,18 +2005,18 @@ diff -up openssh-7.0p1/session.h.audit openssh-7.0p1/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.audit 2015-08-12 11:33:00.388914323 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-12 11:33:00.417914278 +0200 -@@ -122,6 +122,7 @@ +diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c +--- openssh-7.2p1/sshd.c.audit 2016-02-12 18:24:34.189825190 +0100 ++++ openssh-7.2p1/sshd.c 2016-02-12 18:44:44.650639338 +0100 +@@ -121,6 +121,7 @@ + #include "ssh-gss.h" #endif #include "monitor_wrap.h" - #include "roaming.h" +#include "audit.h" #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" -@@ -261,7 +262,7 @@ Buffer loginmsg; +@@ -260,7 +261,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2069,7 +2025,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c void demote_sensitive_data(void); #ifdef WITH_SSH1 -@@ -282,6 +283,15 @@ close_listen_socks(void) +@@ -281,6 +282,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2085,7 +2041,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c static void close_startup_pipes(void) { -@@ -561,22 +571,45 @@ sshd_exchange_identification(int sock_in +@@ -560,22 +570,45 @@ sshd_exchange_identification(int sock_in } } @@ -2134,7 +2090,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -590,6 +623,8 @@ void +@@ -589,6 +622,8 @@ void demote_sensitive_data(void) { Key *tmp; @@ -2143,7 +2099,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c int i; if (sensitive_data.server_key) { -@@ -598,13 +633,25 @@ demote_sensitive_data(void) +@@ -597,13 +632,25 @@ demote_sensitive_data(void) sensitive_data.server_key = tmp; } @@ -2169,7 +2125,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c } /* Certs do not need demotion */ } -@@ -676,7 +723,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2191,7 +2147,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1292,6 +1345,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1293,6 +1346,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2199,7 +2155,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2255,6 +2309,7 @@ main(int ac, char **av) +@@ -2256,6 +2310,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2207,7 +2163,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c exit(0); } -@@ -2300,7 +2355,7 @@ main(int ac, char **av) +@@ -2301,7 +2356,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2216,7 +2172,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c } packet_set_timeout(options.client_alive_interval, -@@ -2314,6 +2369,9 @@ main(int ac, char **av) +@@ -2315,6 +2370,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2226,7 +2182,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2474,6 +2532,10 @@ do_ssh1_kex(void) +@@ -2475,6 +2533,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); @@ -2237,7 +2193,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2533,7 +2595,7 @@ do_ssh1_kex(void) +@@ -2534,7 +2596,7 @@ do_ssh1_kex(void) } /* Destroy the private and public keys. No longer. */ @@ -2246,7 +2202,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2705,6 +2767,16 @@ do_ssh2_kex(void) +@@ -2708,6 +2770,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2263,7 +2219,7 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2716,9 +2788,14 @@ cleanup_exit(int i) +@@ -2719,9 +2791,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2279,10 +2235,10 @@ diff -up openssh-7.0p1/sshd.c.audit openssh-7.0p1/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-7.0p1/sshkey.c.audit openssh-7.0p1/sshkey.c ---- openssh-7.0p1/sshkey.c.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/sshkey.c 2015-08-12 11:33:00.417914278 +0200 -@@ -299,6 +299,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-7.2p1/sshkey.c.audit openssh-7.2p1/sshkey.c +--- openssh-7.2p1/sshkey.c.audit 2016-02-12 18:24:34.157825202 +0100 ++++ openssh-7.2p1/sshkey.c 2016-02-12 18:24:34.228825175 +0100 +@@ -303,6 +303,33 @@ sshkey_type_is_valid_ca(int type) } int @@ -2316,10 +2272,10 @@ diff -up openssh-7.0p1/sshkey.c.audit openssh-7.0p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-7.0p1/sshkey.h.audit openssh-7.0p1/sshkey.h ---- openssh-7.0p1/sshkey.h.audit 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/sshkey.h 2015-08-12 11:33:00.417914278 +0200 -@@ -132,6 +132,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-7.2p1/sshkey.h.audit openssh-7.2p1/sshkey.h +--- openssh-7.2p1/sshkey.h.audit 2016-02-12 18:24:34.157825202 +0100 ++++ openssh-7.2p1/sshkey.h 2016-02-12 18:24:34.228825175 +0100 +@@ -133,6 +133,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); diff --git a/openssh-6.7p1-fips.patch b/openssh-7.2p1-fips.patch similarity index 76% rename from openssh-6.7p1-fips.patch rename to openssh-7.2p1-fips.patch index 62f9e26..ebab58d 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c ---- openssh-7.0p1/cipher.c.fips 2015-08-19 12:36:51.144412908 +0200 -+++ openssh-7.0p1/cipher.c 2015-08-19 12:36:51.150412894 +0200 +diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c +--- openssh-7.2p1/cipher.c.fips 2016-02-12 18:53:56.083665235 +0100 ++++ openssh-7.2p1/cipher.c 2016-02-12 18:53:56.090665235 +0100 @@ -39,6 +39,8 @@ #include @@ -73,9 +73,9 @@ diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c ---- openssh-7.0p1/cipher-ctr.c.fips 2015-08-19 12:36:51.079413054 +0200 -+++ openssh-7.0p1/cipher-ctr.c 2015-08-19 12:36:51.150412894 +0200 +diff -up openssh-7.2p1/cipher-ctr.c.fips openssh-7.2p1/cipher-ctr.c +--- openssh-7.2p1/cipher-ctr.c.fips 2016-02-12 18:53:56.013665228 +0100 ++++ openssh-7.2p1/cipher-ctr.c 2016-02-12 18:53:56.090665235 +0100 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -86,20 +86,20 @@ diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h ---- openssh-7.0p1/dh.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/dh.h 2015-08-19 12:36:51.150412894 +0200 -@@ -46,6 +46,7 @@ u_int dh_estimate(int); - - /* Min and max values from RFC4419. */ - #define DH_GRP_MIN 1024 +diff -up openssh-7.2p1/dh.h.fips openssh-7.2p1/dh.h +--- openssh-7.2p1/dh.h.fips 2016-02-12 18:53:56.090665235 +0100 ++++ openssh-7.2p1/dh.h 2016-02-12 18:54:48.425670204 +0100 +@@ -49,6 +49,7 @@ u_int dh_estimate(int); + * Miniumum increased in light of DH precomputation attacks. + */ + #define DH_GRP_MIN 2048 +#define DH_GRP_MIN_FIPS 2048 #define DH_GRP_MAX 8192 /* -diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c ---- openssh-7.0p1/entropy.c.fips 2015-08-19 12:36:51.070413074 +0200 -+++ openssh-7.0p1/entropy.c 2015-08-19 12:36:51.150412894 +0200 +diff -up openssh-7.2p1/entropy.c.fips openssh-7.2p1/entropy.c +--- openssh-7.2p1/entropy.c.fips 2016-02-12 18:53:56.005665227 +0100 ++++ openssh-7.2p1/entropy.c 2016-02-12 18:53:56.091665235 +0100 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -110,9 +110,9 @@ diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.fips 2015-08-19 12:36:51.145412905 +0200 -+++ openssh-7.0p1/kex.c 2015-08-19 12:36:51.151412892 +0200 +diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c +--- openssh-7.2p1/kex.c.fips 2016-02-12 18:53:56.084665234 +0100 ++++ openssh-7.2p1/kex.c 2016-02-12 18:53:56.091665235 +0100 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL @@ -121,7 +121,7 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c #endif #include "ssh2.h" -@@ -108,6 +109,25 @@ static const struct kexalg kexalgs[] = { +@@ -121,6 +122,25 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; @@ -147,7 +147,7 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c char * kex_alg_list(char sep) { -@@ -135,7 +155,7 @@ kex_alg_by_name(const char *name) +@@ -148,7 +168,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -156,7 +156,7 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -161,7 +181,10 @@ kex_names_valid(const char *names) +@@ -174,7 +194,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -168,9 +168,9 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c free(s); return 0; } -diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c ---- openssh-7.0p1/kexgexc.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexc.c 2015-08-19 12:36:51.151412892 +0200 +diff -up openssh-7.2p1/kexgexc.c.fips openssh-7.2p1/kexgexc.c +--- openssh-7.2p1/kexgexc.c.fips 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/kexgexc.c 2016-02-12 18:53:56.091665235 +0100 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -188,12 +188,12 @@ diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c ---- openssh-7.0p1/kexgexs.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexs.c 2015-08-19 12:36:51.151412892 +0200 -@@ -81,9 +81,9 @@ input_kex_dh_gex_request(int type, u_int +diff -up openssh-7.2p1/kexgexs.c.fips openssh-7.2p1/kexgexs.c +--- openssh-7.2p1/kexgexs.c.fips 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/kexgexs.c 2016-02-12 18:53:56.091665235 +0100 +@@ -83,9 +83,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; - kex->min = min; + kex->min = min; kex->max = max; - min = MAX(DH_GRP_MIN, min); + min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); @@ -203,9 +203,9 @@ diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c nbits = MIN(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c ---- openssh-7.0p1/mac.c.fips 2015-08-19 12:36:51.145412905 +0200 -+++ openssh-7.0p1/mac.c 2015-08-19 12:36:51.151412892 +0200 +diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c +--- openssh-7.2p1/mac.c.fips 2016-02-12 18:53:56.084665234 +0100 ++++ openssh-7.2p1/mac.c 2016-02-12 18:53:56.091665235 +0100 @@ -27,6 +27,8 @@ #include @@ -267,9 +267,9 @@ diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in ---- openssh-7.0p1/Makefile.in.fips 2015-08-19 12:36:51.145412905 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-19 12:36:51.151412892 +0200 +diff -up openssh-7.2p1/Makefile.in.fips openssh-7.2p1/Makefile.in +--- openssh-7.2p1/Makefile.in.fips 2016-02-12 18:53:56.085665235 +0100 ++++ openssh-7.2p1/Makefile.in 2016-02-12 18:53:56.092665235 +0100 @@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -296,27 +296,27 @@ diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in - $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o -- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o +- $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -204,7 +204,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a - $(LD) -o $@ ssh-cavs.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o -- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o +- $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) ++ $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h ---- openssh-7.0p1/myproposal.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/myproposal.h 2015-08-19 12:36:51.151412892 +0200 -@@ -138,6 +138,28 @@ - "hmac-sha1-96," \ - "hmac-md5-96" +diff -up openssh-7.2p1/myproposal.h.fips openssh-7.2p1/myproposal.h +--- openssh-7.2p1/myproposal.h.fips 2016-02-12 18:53:56.092665235 +0100 ++++ openssh-7.2p1/myproposal.h 2016-02-12 18:55:42.137675304 +0100 +@@ -129,6 +129,28 @@ + + #define KEX_CLIENT_MAC KEX_SERVER_MAC +#define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ @@ -340,13 +340,13 @@ diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h + "hmac-sha1" +#endif + - #else + #else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ -diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c ---- openssh-7.0p1/readconf.c.fips 2015-08-19 12:36:51.138412921 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-19 12:36:51.152412889 +0200 -@@ -1915,9 +1915,12 @@ fill_default_options(Options * options) +diff -up openssh-7.2p1/readconf.c.fips openssh-7.2p1/readconf.c +--- openssh-7.2p1/readconf.c.fips 2016-02-12 18:53:56.073665234 +0100 ++++ openssh-7.2p1/readconf.c 2016-02-12 18:53:56.092665235 +0100 +@@ -1969,9 +1969,12 @@ fill_default_options(Options * options) } if (options->update_hostkeys == -1) options->update_hostkeys = 0; @@ -362,26 +362,26 @@ diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c kex_assemble_names(KEX_DEFAULT_PK_ALG, &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.fips 2015-08-19 12:36:51.139412919 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-19 12:36:51.152412889 +0200 -@@ -361,9 +361,12 @@ fill_default_server_options(ServerOption - if (options->use_kuserok == -1) - options->use_kuserok = 1; - -- if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 || -- kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || -- kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 || +diff -up openssh-7.2p1/servconf.c.fips openssh-7.2p1/servconf.c +--- openssh-7.2p1/servconf.c.fips 2016-02-12 18:53:56.068665233 +0100 ++++ openssh-7.2p1/servconf.c 2016-02-12 18:56:52.185681954 +0100 +@@ -188,9 +188,12 @@ option_clear_or_none(const char *o) + static void + assemble_algorithms(ServerOptions *o) + { +- if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || +- kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || +- kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || + if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT -+ : KEX_SERVER_ENCRYPT), &options->ciphers) != 0 || ++ : KEX_SERVER_ENCRYPT), &o->ciphers) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC -+ : KEX_SERVER_MAC), &options->macs) != 0 || ++ : KEX_SERVER_MAC), &o->macs) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS -+ : KEX_SERVER_KEX), &options->kex_algorithms) != 0 || ++ : KEX_SERVER_KEX), &o->kex_algorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->hostkeyalgorithms) != 0 || + &o->hostkeyalgorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -@@ -2355,8 +2358,10 @@ dump_config(ServerOptions *o) +@@ -2376,8 +2379,10 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); @@ -394,7 +394,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c 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); -@@ -2371,8 +2376,8 @@ dump_config(ServerOptions *o) +@@ -2392,8 +2397,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); @@ -405,9 +405,9 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? o->hostbased_key_types : KEX_DEFAULT_PK_ALG); dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? -diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c ---- openssh-7.0p1/ssh.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/ssh.c 2015-08-19 12:36:51.153412887 +0200 +diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c +--- openssh-7.2p1/ssh.c.fips 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/ssh.c 2016-02-12 18:53:56.093665236 +0100 @@ -75,6 +75,8 @@ #include #include @@ -417,7 +417,7 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -522,6 +524,14 @@ main(int ac, char **av) +@@ -531,6 +533,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -432,7 +432,7 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -599,6 +609,9 @@ main(int ac, char **av) +@@ -608,6 +618,9 @@ main(int ac, char **av) "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -442,7 +442,7 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c options.protocol = SSH_PROTO_1; break; case '2': -@@ -940,7 +953,6 @@ main(int ac, char **av) +@@ -952,7 +965,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -450,7 +450,7 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c ERR_load_crypto_strings(); #endif -@@ -1114,6 +1126,10 @@ main(int ac, char **av) +@@ -1126,6 +1138,10 @@ main(int ac, char **av) seed_rng(); @@ -461,7 +461,7 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1191,6 +1207,12 @@ main(int ac, char **av) +@@ -1206,6 +1222,12 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; @@ -474,9 +474,9 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1/sshconnect2.c.fips 2015-08-19 12:36:51.140412916 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:39:52.455004667 +0200 +diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c +--- openssh-7.2p1/sshconnect2.c.fips 2016-02-12 18:53:56.074665234 +0100 ++++ openssh-7.2p1/sshconnect2.c 2016-02-12 18:53:56.094665236 +0100 @@ -44,6 +44,8 @@ #include #endif @@ -486,7 +486,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -170,21 +172,26 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -171,21 +173,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -528,9 +528,9 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c } } #endif -diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.fips 2015-08-19 12:36:51.148412898 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-19 12:36:51.153412887 +0200 +diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c +--- openssh-7.2p1/sshd.c.fips 2016-02-12 18:53:56.088665235 +0100 ++++ openssh-7.2p1/sshd.c 2016-02-12 18:53:56.094665236 +0100 @@ -66,6 +66,7 @@ #include #include @@ -548,7 +548,7 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1552,6 +1555,18 @@ main(int ac, char **av) +@@ -1555,6 +1558,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -567,7 +567,7 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1704,7 +1719,7 @@ main(int ac, char **av) +@@ -1707,7 +1722,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -576,7 +576,7 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1905,6 +1920,10 @@ main(int ac, char **av) +@@ -1906,6 +1921,10 @@ main(int ac, char **av) sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); free(fp); } @@ -587,7 +587,7 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; -@@ -2073,6 +2092,10 @@ main(int ac, char **av) +@@ -2074,6 +2093,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); @@ -598,7 +598,7 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2692,10 +2715,14 @@ do_ssh2_kex(void) +@@ -2695,10 +2718,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -617,9 +617,9 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c ---- openssh-7.0p1/sshkey.c.fips 2015-08-19 12:36:51.148412898 +0200 -+++ openssh-7.0p1/sshkey.c 2015-08-19 12:36:51.154412885 +0200 +diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c +--- openssh-7.2p1/sshkey.c.fips 2016-02-12 18:53:56.089665235 +0100 ++++ openssh-7.2p1/sshkey.c 2016-02-12 18:53:56.095665236 +0100 @@ -35,6 +35,7 @@ #include #include @@ -628,7 +628,7 @@ diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c #endif #include "crypto_api.h" -@@ -1552,6 +1553,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { diff --git a/openssh-7.1p1-gsissh.patch b/openssh-7.2p1-gsissh.patch similarity index 90% rename from openssh-7.1p1-gsissh.patch rename to openssh-7.2p1-gsissh.patch index ca0df11..4ca7374 100644 --- a/openssh-7.1p1-gsissh.patch +++ b/openssh-7.2p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-7.1p1.orig/auth2.c openssh-7.1p1/auth2.c ---- openssh-7.1p1.orig/auth2.c 2015-08-24 19:39:35.652354251 +0200 -+++ openssh-7.1p1/auth2.c 2015-08-24 19:40:08.238717475 +0200 +diff -Nur openssh-7.2p1.orig/auth2.c openssh-7.2p1/auth2.c +--- openssh-7.2p1.orig/auth2.c 2016-03-02 19:04:36.376960285 +0100 ++++ openssh-7.2p1/auth2.c 2016-03-02 19:05:41.290212928 +0100 @@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -120,9 +120,9 @@ diff -Nur openssh-7.1p1.orig/auth2.c openssh-7.1p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.1p1.orig/auth2-gss.c openssh-7.1p1/auth2-gss.c ---- openssh-7.1p1.orig/auth2-gss.c 2015-08-24 19:39:35.525352836 +0200 -+++ openssh-7.1p1/auth2-gss.c 2015-08-24 19:40:08.239717486 +0200 +diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c +--- openssh-7.2p1.orig/auth2-gss.c 2016-03-02 19:04:36.311961033 +0100 ++++ openssh-7.2p1/auth2-gss.c 2016-03-02 19:05:41.290212928 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -303,9 +303,9 @@ diff -Nur openssh-7.1p1.orig/auth2-gss.c openssh-7.1p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.1p1.orig/auth.c openssh-7.1p1/auth.c ---- openssh-7.1p1.orig/auth.c 2015-08-24 19:39:35.653354263 +0200 -+++ openssh-7.1p1/auth.c 2015-08-24 19:40:08.240717497 +0200 +diff -Nur openssh-7.2p1.orig/auth.c openssh-7.2p1/auth.c +--- openssh-7.2p1.orig/auth.c 2016-03-02 19:04:36.376960285 +0100 ++++ openssh-7.2p1/auth.c 2016-03-02 19:05:41.291212916 +0100 @@ -75,6 +75,9 @@ #include "ssherr.h" #include "compat.h" @@ -350,7 +350,7 @@ diff -Nur openssh-7.1p1.orig/auth.c openssh-7.1p1/auth.c } -@@ -621,6 +642,10 @@ +@@ -622,6 +643,10 @@ #endif pw = getpwnam(user); @@ -361,7 +361,7 @@ diff -Nur openssh-7.1p1.orig/auth.c openssh-7.1p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -640,7 +665,8 @@ +@@ -641,7 +666,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", @@ -371,10 +371,10 @@ diff -Nur openssh-7.1p1.orig/auth.c openssh-7.1p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c ---- openssh-7.1p1.orig/auth-pam.c 2015-08-24 19:39:35.673354486 +0200 -+++ openssh-7.1p1/auth-pam.c 2015-08-24 19:40:08.241717508 +0200 -@@ -122,6 +122,10 @@ +diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c +--- openssh-7.2p1.orig/auth-pam.c 2016-03-02 19:04:36.394960078 +0100 ++++ openssh-7.2p1/auth-pam.c 2016-03-02 19:05:41.292212905 +0100 +@@ -123,6 +123,10 @@ */ typedef pthread_t sp_pthread_t; #else @@ -385,7 +385,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c typedef pid_t sp_pthread_t; #endif -@@ -277,6 +281,56 @@ +@@ -278,6 +282,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -442,7 +442,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -299,7 +353,7 @@ +@@ -300,7 +354,7 @@ static void import_environments(Buffer *b) { @@ -451,7 +451,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c u_int i, num_env; int err; -@@ -309,6 +363,17 @@ +@@ -310,6 +364,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -469,7 +469,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -475,6 +540,13 @@ +@@ -476,6 +541,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -483,7 +483,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -495,6 +567,11 @@ +@@ -496,6 +568,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -495,7 +495,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -912,6 +989,18 @@ +@@ -913,6 +990,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -514,7 +514,7 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1209,6 +1298,9 @@ +@@ -1210,6 +1299,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -524,9 +524,9 @@ diff -Nur openssh-7.1p1.orig/auth-pam.c openssh-7.1p1/auth-pam.c sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", -diff -Nur openssh-7.1p1.orig/auth-pam.h openssh-7.1p1/auth-pam.h ---- openssh-7.1p1.orig/auth-pam.h 2015-08-24 19:39:35.441351900 +0200 -+++ openssh-7.1p1/auth-pam.h 2015-08-24 19:40:08.242717519 +0200 +diff -Nur openssh-7.2p1.orig/auth-pam.h openssh-7.2p1/auth-pam.h +--- openssh-7.2p1.orig/auth-pam.h 2016-03-02 19:04:36.265961563 +0100 ++++ openssh-7.2p1/auth-pam.h 2016-03-02 19:05:41.292212905 +0100 @@ -46,5 +46,6 @@ void sshpam_cleanup(void); int sshpam_auth_passwd(Authctxt *, const char *); @@ -534,9 +534,9 @@ diff -Nur openssh-7.1p1.orig/auth-pam.h openssh-7.1p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.1p1.orig/canohost.c openssh-7.1p1/canohost.c ---- openssh-7.1p1.orig/canohost.c 2015-08-24 19:39:35.563353259 +0200 -+++ openssh-7.1p1/canohost.c 2015-08-24 19:40:08.242717519 +0200 +diff -Nur openssh-7.2p1.orig/canohost.c openssh-7.2p1/canohost.c +--- openssh-7.2p1.orig/canohost.c 2016-03-02 19:04:36.333960780 +0100 ++++ openssh-7.2p1/canohost.c 2016-03-02 19:05:41.292212905 +0100 @@ -17,6 +17,7 @@ #include #include @@ -579,9 +579,9 @@ diff -Nur openssh-7.1p1.orig/canohost.c openssh-7.1p1/canohost.c + } + } +} -diff -Nur openssh-7.1p1.orig/canohost.h openssh-7.1p1/canohost.h ---- openssh-7.1p1.orig/canohost.h 2015-08-24 19:39:35.563353259 +0200 -+++ openssh-7.1p1/canohost.h 2015-08-24 19:40:08.243717530 +0200 +diff -Nur openssh-7.2p1.orig/canohost.h openssh-7.2p1/canohost.h +--- openssh-7.2p1.orig/canohost.h 2016-03-02 19:04:36.334960769 +0100 ++++ openssh-7.2p1/canohost.h 2016-03-02 19:05:41.292212905 +0100 @@ -27,4 +27,6 @@ int get_sock_port(int, int); void clear_cached_addr(void); @@ -589,10 +589,10 @@ diff -Nur openssh-7.1p1.orig/canohost.h openssh-7.1p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.1p1.orig/configure.ac openssh-7.1p1/configure.ac ---- openssh-7.1p1.orig/configure.ac 2015-08-24 19:39:35.612353806 +0200 -+++ openssh-7.1p1/configure.ac 2015-08-24 19:40:08.245717553 +0200 -@@ -4280,6 +4280,14 @@ +diff -Nur openssh-7.2p1.orig/configure.ac openssh-7.2p1/configure.ac +--- openssh-7.2p1.orig/configure.ac 2016-03-02 19:04:36.356960515 +0100 ++++ openssh-7.2p1/configure.ac 2016-03-02 19:05:41.293212893 +0100 +@@ -4330,6 +4330,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -607,7 +607,7 @@ diff -Nur openssh-7.1p1.orig/configure.ac openssh-7.1p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4319,6 +4327,50 @@ +@@ -4369,6 +4377,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -658,9 +658,9 @@ diff -Nur openssh-7.1p1.orig/configure.ac openssh-7.1p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-7.1p1.orig/gss-genr.c openssh-7.1p1/gss-genr.c ---- openssh-7.1p1.orig/gss-genr.c 2015-08-24 19:39:35.628353984 +0200 -+++ openssh-7.1p1/gss-genr.c 2015-08-24 19:40:08.245717553 +0200 +diff -Nur openssh-7.2p1.orig/gss-genr.c openssh-7.2p1/gss-genr.c +--- openssh-7.2p1.orig/gss-genr.c 2016-03-02 19:04:36.363960435 +0100 ++++ openssh-7.2p1/gss-genr.c 2016-03-02 19:05:41.294212882 +0100 @@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -697,9 +697,9 @@ diff -Nur openssh-7.1p1.orig/gss-genr.c openssh-7.1p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.1p1.orig/gss-serv.c openssh-7.1p1/gss-serv.c ---- openssh-7.1p1.orig/gss-serv.c 2015-08-24 19:39:35.629353995 +0200 -+++ openssh-7.1p1/gss-serv.c 2015-08-24 19:40:08.246717564 +0200 +diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c +--- openssh-7.2p1.orig/gss-serv.c 2016-03-02 19:04:36.363960435 +0100 ++++ openssh-7.2p1/gss-serv.c 2016-03-02 19:05:41.294212882 +0100 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -938,9 +938,9 @@ diff -Nur openssh-7.1p1.orig/gss-serv.c openssh-7.1p1/gss-serv.c +} + #endif -diff -Nur openssh-7.1p1.orig/gss-serv-gsi.c openssh-7.1p1/gss-serv-gsi.c ---- openssh-7.1p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.1p1/gss-serv-gsi.c 2015-08-24 19:40:08.246717564 +0200 +diff -Nur openssh-7.2p1.orig/gss-serv-gsi.c openssh-7.2p1/gss-serv-gsi.c +--- openssh-7.2p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.2p1/gss-serv-gsi.c 2016-03-02 19:05:41.294212882 +0100 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1181,9 +1181,9 @@ diff -Nur openssh-7.1p1.orig/gss-serv-gsi.c openssh-7.1p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.1p1.orig/gss-serv-krb5.c openssh-7.1p1/gss-serv-krb5.c ---- openssh-7.1p1.orig/gss-serv-krb5.c 2015-08-24 19:39:35.592353583 +0200 -+++ openssh-7.1p1/gss-serv-krb5.c 2015-08-24 19:40:08.246717564 +0200 +diff -Nur openssh-7.2p1.orig/gss-serv-krb5.c openssh-7.2p1/gss-serv-krb5.c +--- openssh-7.2p1.orig/gss-serv-krb5.c 2016-03-02 19:04:36.348960607 +0100 ++++ openssh-7.2p1/gss-serv-krb5.c 2016-03-02 19:05:41.295212870 +0100 @@ -359,6 +359,34 @@ return found_principal; } @@ -1237,9 +1237,9 @@ diff -Nur openssh-7.1p1.orig/gss-serv-krb5.c openssh-7.1p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.1p1.orig/kexgsss.c openssh-7.1p1/kexgsss.c ---- openssh-7.1p1.orig/kexgsss.c 2015-08-24 19:39:35.530352892 +0200 -+++ openssh-7.1p1/kexgsss.c 2015-08-24 19:40:08.247717575 +0200 +diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c +--- openssh-7.2p1.orig/kexgsss.c 2016-03-02 19:04:36.314960999 +0100 ++++ openssh-7.2p1/kexgsss.c 2016-03-02 19:05:41.295212870 +0100 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1299,9 +1299,9 @@ diff -Nur openssh-7.1p1.orig/kexgsss.c openssh-7.1p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.1p1.orig/LICENSE.globus_usage openssh-7.1p1/LICENSE.globus_usage ---- openssh-7.1p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.1p1/LICENSE.globus_usage 2015-08-24 19:40:08.247717575 +0200 +diff -Nur openssh-7.2p1.orig/LICENSE.globus_usage openssh-7.2p1/LICENSE.globus_usage +--- openssh-7.2p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.2p1/LICENSE.globus_usage 2016-03-02 19:05:41.295212870 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1321,9 +1321,9 @@ diff -Nur openssh-7.1p1.orig/LICENSE.globus_usage openssh-7.1p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.1p1.orig/Makefile.in openssh-7.1p1/Makefile.in ---- openssh-7.1p1.orig/Makefile.in 2015-08-24 19:39:35.667354419 +0200 -+++ openssh-7.1p1/Makefile.in 2015-08-24 19:40:08.247717575 +0200 +diff -Nur openssh-7.2p1.orig/Makefile.in openssh-7.2p1/Makefile.in +--- openssh-7.2p1.orig/Makefile.in 2016-03-02 19:04:36.389960135 +0100 ++++ openssh-7.2p1/Makefile.in 2016-03-02 19:09:08.722825330 +0100 @@ -113,8 +113,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ @@ -1332,13 +1332,13 @@ diff -Nur openssh-7.1p1.orig/Makefile.in openssh-7.1p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ + ssh-globus-usage.o \ - roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o -diff -Nur openssh-7.1p1.orig/misc.c openssh-7.1p1/misc.c ---- openssh-7.1p1.orig/misc.c 2015-08-24 19:39:35.590353560 +0200 -+++ openssh-7.1p1/misc.c 2015-08-24 19:40:08.248717586 +0200 -@@ -160,11 +160,14 @@ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ + sandbox-solaris.o +diff -Nur openssh-7.2p1.orig/misc.c openssh-7.2p1/misc.c +--- openssh-7.2p1.orig/misc.c 2016-03-02 19:04:36.347960619 +0100 ++++ openssh-7.2p1/misc.c 2016-03-02 19:05:41.296212859 +0100 +@@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1354,7 +1354,7 @@ diff -Nur openssh-7.1p1.orig/misc.c openssh-7.1p1/misc.c int wspace = 0; if (*s == NULL) -@@ -172,6 +175,21 @@ +@@ -173,6 +176,21 @@ old = *s; @@ -1376,7 +1376,7 @@ diff -Nur openssh-7.1p1.orig/misc.c openssh-7.1p1/misc.c *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); -@@ -227,6 +245,20 @@ +@@ -228,6 +246,20 @@ return copy; } @@ -1397,9 +1397,9 @@ diff -Nur openssh-7.1p1.orig/misc.c openssh-7.1p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.1p1.orig/misc.h openssh-7.1p1/misc.h ---- openssh-7.1p1.orig/misc.h 2015-08-24 19:39:35.567353304 +0200 -+++ openssh-7.1p1/misc.h 2015-08-24 19:40:08.248717586 +0200 +diff -Nur openssh-7.2p1.orig/misc.h openssh-7.2p1/misc.h +--- openssh-7.2p1.orig/misc.h 2016-03-02 19:04:36.335960757 +0100 ++++ openssh-7.2p1/misc.h 2016-03-02 19:05:41.296212859 +0100 @@ -61,6 +61,7 @@ void sock_set_v6only(int); @@ -1408,10 +1408,10 @@ diff -Nur openssh-7.1p1.orig/misc.h openssh-7.1p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c ---- openssh-7.1p1.orig/monitor.c 2015-08-24 19:39:35.674354497 +0200 -+++ openssh-7.1p1/monitor.c 2015-08-24 19:40:08.248717586 +0200 -@@ -164,6 +164,9 @@ +diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c +--- openssh-7.2p1.orig/monitor.c 2016-03-02 19:04:36.396960055 +0100 ++++ openssh-7.2p1/monitor.c 2016-03-02 19:05:41.297212847 +0100 +@@ -163,6 +163,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1421,7 +1421,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -217,7 +220,7 @@ +@@ -216,7 +219,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1430,7 +1430,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -225,7 +228,7 @@ +@@ -224,7 +227,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1439,7 +1439,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -255,6 +258,9 @@ +@@ -254,6 +257,9 @@ {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, @@ -1449,7 +1449,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c #endif {0, 0, NULL} }; -@@ -264,6 +270,8 @@ +@@ -263,6 +269,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1458,7 +1458,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -304,7 +312,7 @@ +@@ -303,7 +311,7 @@ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM @@ -1467,7 +1467,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -399,6 +407,8 @@ +@@ -398,6 +406,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1476,7 +1476,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_proto15; -@@ -513,6 +523,8 @@ +@@ -512,6 +522,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1485,7 +1485,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -844,14 +856,17 @@ +@@ -840,14 +852,17 @@ debug3("%s", __func__); @@ -1506,7 +1506,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2225,12 +2240,15 @@ +@@ -2222,12 +2237,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1523,7 +1523,7 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2238,12 +2256,77 @@ +@@ -2235,12 +2253,77 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1602,9 +1602,9 @@ diff -Nur openssh-7.1p1.orig/monitor.c openssh-7.1p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.1p1.orig/monitor.h openssh-7.1p1/monitor.h ---- openssh-7.1p1.orig/monitor.h 2015-08-24 19:39:35.657354307 +0200 -+++ openssh-7.1p1/monitor.h 2015-08-24 19:40:08.249717597 +0200 +diff -Nur openssh-7.2p1.orig/monitor.h openssh-7.2p1/monitor.h +--- openssh-7.2p1.orig/monitor.h 2016-03-02 19:04:36.379960251 +0100 ++++ openssh-7.2p1/monitor.h 2016-03-02 19:05:41.298212836 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1618,9 +1618,9 @@ diff -Nur openssh-7.1p1.orig/monitor.h openssh-7.1p1/monitor.h }; struct mm_master; -diff -Nur openssh-7.1p1.orig/monitor_wrap.c openssh-7.1p1/monitor_wrap.c ---- openssh-7.1p1.orig/monitor_wrap.c 2015-08-24 19:39:35.675354508 +0200 -+++ openssh-7.1p1/monitor_wrap.c 2015-08-24 19:40:08.249717597 +0200 +diff -Nur openssh-7.2p1.orig/monitor_wrap.c openssh-7.2p1/monitor_wrap.c +--- openssh-7.2p1.orig/monitor_wrap.c 2016-03-02 19:04:36.396960055 +0100 ++++ openssh-7.2p1/monitor_wrap.c 2016-03-02 19:05:41.298212836 +0100 @@ -1121,12 +1121,13 @@ } @@ -1720,9 +1720,9 @@ diff -Nur openssh-7.1p1.orig/monitor_wrap.c openssh-7.1p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.1p1.orig/monitor_wrap.h openssh-7.1p1/monitor_wrap.h ---- openssh-7.1p1.orig/monitor_wrap.h 2015-08-24 19:39:35.658354318 +0200 -+++ openssh-7.1p1/monitor_wrap.h 2015-08-24 19:40:08.249717597 +0200 +diff -Nur openssh-7.2p1.orig/monitor_wrap.h openssh-7.2p1/monitor_wrap.h +--- openssh-7.2p1.orig/monitor_wrap.h 2016-03-02 19:04:36.385960182 +0100 ++++ openssh-7.2p1/monitor_wrap.h 2016-03-02 19:05:41.298212836 +0100 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1738,10 +1738,10 @@ diff -Nur openssh-7.1p1.orig/monitor_wrap.h openssh-7.1p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.1p1.orig/readconf.c openssh-7.1p1/readconf.c ---- openssh-7.1p1.orig/readconf.c 2015-08-24 19:39:35.668354430 +0200 -+++ openssh-7.1p1/readconf.c 2015-08-24 19:40:08.250717609 +0200 -@@ -1782,13 +1782,13 @@ +diff -Nur openssh-7.2p1.orig/readconf.c openssh-7.2p1/readconf.c +--- openssh-7.2p1.orig/readconf.c 2016-03-02 19:04:36.390960124 +0100 ++++ openssh-7.2p1/readconf.c 2016-03-02 19:05:41.299212824 +0100 +@@ -1830,13 +1830,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1759,9 +1759,9 @@ diff -Nur openssh-7.1p1.orig/readconf.c openssh-7.1p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.1p1.orig/readconf.h openssh-7.1p1/readconf.h ---- openssh-7.1p1.orig/readconf.h 2015-08-24 19:39:35.639354106 +0200 -+++ openssh-7.1p1/readconf.h 2015-08-24 19:40:08.250717609 +0200 +diff -Nur openssh-7.2p1.orig/readconf.h openssh-7.2p1/readconf.h +--- openssh-7.2p1.orig/readconf.h 2016-03-02 19:04:36.370960354 +0100 ++++ openssh-7.2p1/readconf.h 2016-03-02 19:05:41.299212824 +0100 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1771,9 +1771,9 @@ diff -Nur openssh-7.1p1.orig/readconf.h openssh-7.1p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c ---- openssh-7.1p1.orig/servconf.c 2015-08-24 19:39:35.676354519 +0200 -+++ openssh-7.1p1/servconf.c 2015-08-24 19:46:25.995931916 +0200 +diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c +--- openssh-7.2p1.orig/servconf.c 2016-03-02 19:04:36.397960043 +0100 ++++ openssh-7.2p1/servconf.c 2016-03-02 19:05:41.300212813 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1803,7 +1803,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -193,6 +198,8 @@ +@@ -210,6 +215,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1812,7 +1812,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -279,13 +286,17 @@ +@@ -296,13 +303,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1833,7 +1833,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -411,7 +422,7 @@ +@@ -420,7 +431,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1842,7 +1842,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -433,10 +444,14 @@ +@@ -442,10 +453,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1857,7 +1857,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -461,8 +476,10 @@ +@@ -470,8 +485,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1868,7 +1868,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -508,7 +525,14 @@ +@@ -517,7 +534,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1883,7 +1883,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -516,7 +540,10 @@ +@@ -525,7 +549,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1894,7 +1894,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -580,6 +607,8 @@ +@@ -593,6 +620,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1903,7 +1903,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1035,6 +1064,10 @@ +@@ -1048,6 +1077,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1914,7 +1914,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1266,6 +1299,10 @@ +@@ -1279,6 +1312,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1925,7 +1925,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1274,6 +1311,10 @@ +@@ -1287,6 +1324,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1936,7 +1936,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1294,6 +1335,12 @@ +@@ -1307,6 +1348,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1949,7 +1949,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1768,6 +1815,35 @@ +@@ -1777,6 +1824,35 @@ *charptr = xstrdup(arg); break; @@ -1985,7 +1985,7 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2044,6 +2120,7 @@ +@@ -2053,6 +2129,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1993,9 +1993,9 @@ diff -Nur openssh-7.1p1.orig/servconf.c openssh-7.1p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-7.1p1.orig/servconf.h openssh-7.1p1/servconf.h ---- openssh-7.1p1.orig/servconf.h 2015-08-24 19:39:35.632354029 +0200 -+++ openssh-7.1p1/servconf.h 2015-08-24 19:40:08.253717642 +0200 +diff -Nur openssh-7.2p1.orig/servconf.h openssh-7.2p1/servconf.h +--- openssh-7.2p1.orig/servconf.h 2016-03-02 19:04:36.366960400 +0100 ++++ openssh-7.2p1/servconf.h 2016-03-02 19:05:41.300212813 +0100 @@ -117,9 +117,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if @@ -2028,10 +2028,10 @@ diff -Nur openssh-7.1p1.orig/servconf.h openssh-7.1p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.1p1.orig/ssh.1 openssh-7.1p1/ssh.1 ---- openssh-7.1p1.orig/ssh.1 2015-08-24 19:39:35.633354040 +0200 -+++ openssh-7.1p1/ssh.1 2015-08-24 19:40:08.253717642 +0200 -@@ -1406,6 +1406,18 @@ +diff -Nur openssh-7.2p1.orig/ssh.1 openssh-7.2p1/ssh.1 +--- openssh-7.2p1.orig/ssh.1 2016-03-02 19:04:36.366960400 +0100 ++++ openssh-7.2p1/ssh.1 2016-03-02 19:05:41.301212801 +0100 +@@ -1407,6 +1407,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2050,10 +2050,10 @@ diff -Nur openssh-7.1p1.orig/ssh.1 openssh-7.1p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.1p1.orig/ssh.c openssh-7.1p1/ssh.c ---- openssh-7.1p1.orig/ssh.c 2015-08-24 19:39:35.669354441 +0200 -+++ openssh-7.1p1/ssh.c 2015-08-24 19:40:08.254717653 +0200 -@@ -465,6 +465,32 @@ +diff -Nur openssh-7.2p1.orig/ssh.c openssh-7.2p1/ssh.c +--- openssh-7.2p1.orig/ssh.c 2016-03-02 19:04:36.391960112 +0100 ++++ openssh-7.2p1/ssh.c 2016-03-02 19:05:41.301212801 +0100 +@@ -475,6 +475,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2086,7 +2086,7 @@ diff -Nur openssh-7.1p1.orig/ssh.c openssh-7.1p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1130,8 +1156,12 @@ +@@ -1143,8 +1169,12 @@ logit("FIPS mode initialized"); } @@ -2100,9 +2100,9 @@ diff -Nur openssh-7.1p1.orig/ssh.c openssh-7.1p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.1p1.orig/ssh_config openssh-7.1p1/ssh_config ---- openssh-7.1p1.orig/ssh_config 2015-08-24 19:39:35.537352970 +0200 -+++ openssh-7.1p1/ssh_config 2015-08-24 19:40:08.254717653 +0200 +diff -Nur openssh-7.2p1.orig/ssh_config openssh-7.2p1/ssh_config +--- openssh-7.2p1.orig/ssh_config 2016-03-02 19:04:36.318960953 +0100 ++++ openssh-7.2p1/ssh_config 2016-03-02 19:05:41.302212790 +0100 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2118,9 +2118,9 @@ diff -Nur openssh-7.1p1.orig/ssh_config openssh-7.1p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.1p1.orig/ssh_config.5 openssh-7.1p1/ssh_config.5 ---- openssh-7.1p1.orig/ssh_config.5 2015-08-24 19:39:35.640354118 +0200 -+++ openssh-7.1p1/ssh_config.5 2015-08-24 19:40:08.255717664 +0200 +diff -Nur openssh-7.2p1.orig/ssh_config.5 openssh-7.2p1/ssh_config.5 +--- openssh-7.2p1.orig/ssh_config.5 2016-03-02 19:04:36.370960354 +0100 ++++ openssh-7.2p1/ssh_config.5 2016-03-02 19:05:41.302212790 +0100 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2134,10 +2134,10 @@ diff -Nur openssh-7.1p1.orig/ssh_config.5 openssh-7.1p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c ---- openssh-7.1p1.orig/sshconnect2.c 2015-08-24 19:39:35.669354441 +0200 -+++ openssh-7.1p1/sshconnect2.c 2015-08-24 19:40:08.255717664 +0200 -@@ -699,6 +699,11 @@ +diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c +--- openssh-7.2p1.orig/sshconnect2.c 2016-03-02 19:04:36.391960112 +0100 ++++ openssh-7.2p1/sshconnect2.c 2016-03-02 19:05:41.303212778 +0100 +@@ -728,6 +728,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2149,7 +2149,7 @@ diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -936,6 +941,15 @@ +@@ -965,6 +970,15 @@ return 0; } @@ -2165,7 +2165,7 @@ diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -953,8 +967,16 @@ +@@ -982,8 +996,16 @@ return (0); } @@ -2182,7 +2182,7 @@ diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -965,7 +987,15 @@ +@@ -994,7 +1016,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2198,10 +2198,10 @@ diff -Nur openssh-7.1p1.orig/sshconnect2.c openssh-7.1p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.1p1.orig/sshd.8 openssh-7.1p1/sshd.8 ---- openssh-7.1p1.orig/sshd.8 2015-08-24 19:39:35.599353661 +0200 -+++ openssh-7.1p1/sshd.8 2015-08-24 19:40:08.256717676 +0200 -@@ -765,6 +765,44 @@ +diff -Nur openssh-7.2p1.orig/sshd.8 openssh-7.2p1/sshd.8 +--- openssh-7.2p1.orig/sshd.8 2016-03-02 19:04:36.352960561 +0100 ++++ openssh-7.2p1/sshd.8 2016-03-02 19:05:41.303212778 +0100 +@@ -795,6 +795,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2246,10 +2246,10 @@ diff -Nur openssh-7.1p1.orig/sshd.8 openssh-7.1p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.1p1.orig/sshd.c openssh-7.1p1/sshd.c ---- openssh-7.1p1.orig/sshd.c 2015-08-24 19:39:35.678354541 +0200 -+++ openssh-7.1p1/sshd.c 2015-08-24 19:40:08.257717686 +0200 -@@ -129,6 +129,7 @@ +diff -Nur openssh-7.2p1.orig/sshd.c openssh-7.2p1/sshd.c +--- openssh-7.2p1.orig/sshd.c 2016-03-02 19:04:36.399960020 +0100 ++++ openssh-7.2p1/sshd.c 2016-03-02 19:05:41.304212767 +0100 +@@ -128,6 +128,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -2257,7 +2257,7 @@ diff -Nur openssh-7.1p1.orig/sshd.c openssh-7.1p1/sshd.c #ifdef LIBWRAP #include -@@ -1794,6 +1795,13 @@ +@@ -1797,6 +1798,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2271,7 +2271,7 @@ diff -Nur openssh-7.1p1.orig/sshd.c openssh-7.1p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2359,7 +2367,7 @@ +@@ -2362,7 +2370,7 @@ #endif #ifdef GSSAPI @@ -2280,9 +2280,9 @@ diff -Nur openssh-7.1p1.orig/sshd.c openssh-7.1p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.1p1.orig/sshd_config openssh-7.1p1/sshd_config ---- openssh-7.1p1.orig/sshd_config 2015-08-24 19:39:35.623353928 +0200 -+++ openssh-7.1p1/sshd_config 2015-08-24 19:40:08.257717686 +0200 +diff -Nur openssh-7.2p1.orig/sshd_config openssh-7.2p1/sshd_config +--- openssh-7.2p1.orig/sshd_config 2016-03-02 19:04:36.361960458 +0100 ++++ openssh-7.2p1/sshd_config 2016-03-02 19:05:41.304212767 +0100 @@ -90,10 +90,11 @@ #KerberosUseKuserok yes @@ -2315,10 +2315,10 @@ diff -Nur openssh-7.1p1.orig/sshd_config openssh-7.1p1/sshd_config + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 -diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 ---- openssh-7.1p1.orig/sshd_config.5 2015-08-24 19:39:35.635354062 +0200 -+++ openssh-7.1p1/sshd_config.5 2015-08-24 19:40:08.258717698 +0200 -@@ -569,6 +569,15 @@ +diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 +--- openssh-7.2p1.orig/sshd_config.5 2016-03-02 19:04:36.367960389 +0100 ++++ openssh-7.2p1/sshd_config.5 2016-03-02 19:07:15.338130138 +0100 +@@ -570,6 +570,15 @@ See PATTERNS in .Xr ssh_config 5 for more information on patterns. @@ -2334,10 +2334,10 @@ diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: -@@ -621,6 +630,10 @@ +@@ -623,6 +632,10 @@ + Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . - Note that this option applies to protocol version 2 only. +.It Cm GSSAPIDelegateCredentials +Specifies whether delegated credentials are stored in the user's environment. +The default is @@ -2368,7 +2368,7 @@ diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1540,6 +1569,103 @@ +@@ -1552,6 +1581,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2472,7 +2472,7 @@ diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -1616,6 +1742,12 @@ +@@ -1628,6 +1754,12 @@ as a non-root user. The default is .Dq no . @@ -2485,9 +2485,9 @@ diff -Nur openssh-7.1p1.orig/sshd_config.5 openssh-7.1p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-7.1p1.orig/ssh-globus-usage.c openssh-7.1p1/ssh-globus-usage.c ---- openssh-7.1p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.1p1/ssh-globus-usage.c 2015-08-24 19:40:08.258717698 +0200 +diff -Nur openssh-7.2p1.orig/ssh-globus-usage.c openssh-7.2p1/ssh-globus-usage.c +--- openssh-7.2p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.2p1/ssh-globus-usage.c 2016-03-02 19:05:41.306212744 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2885,9 +2885,9 @@ diff -Nur openssh-7.1p1.orig/ssh-globus-usage.c openssh-7.1p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.1p1.orig/ssh-globus-usage.h openssh-7.1p1/ssh-globus-usage.h ---- openssh-7.1p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.1p1/ssh-globus-usage.h 2015-08-24 19:40:08.259717709 +0200 +diff -Nur openssh-7.2p1.orig/ssh-globus-usage.h openssh-7.2p1/ssh-globus-usage.h +--- openssh-7.2p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.2p1/ssh-globus-usage.h 2016-03-02 19:05:41.306212744 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2937,9 +2937,9 @@ diff -Nur openssh-7.1p1.orig/ssh-globus-usage.h openssh-7.1p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.1p1.orig/ssh-gss.h openssh-7.1p1/ssh-gss.h ---- openssh-7.1p1.orig/ssh-gss.h 2015-08-24 19:39:35.635354062 +0200 -+++ openssh-7.1p1/ssh-gss.h 2015-08-24 19:40:08.259717709 +0200 +diff -Nur openssh-7.2p1.orig/ssh-gss.h openssh-7.2p1/ssh-gss.h +--- openssh-7.2p1.orig/ssh-gss.h 2016-03-02 19:04:36.367960389 +0100 ++++ openssh-7.2p1/ssh-gss.h 2016-03-02 19:05:41.306212744 +0100 @@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2984,11 +2984,11 @@ diff -Nur openssh-7.1p1.orig/ssh-gss.h openssh-7.1p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.1p1.orig/version.h openssh-7.1p1/version.h ---- openssh-7.1p1.orig/version.h 2015-08-21 06:49:03.000000000 +0200 -+++ openssh-7.1p1/version.h 2015-08-24 19:41:34.830682670 +0200 +diff -Nur openssh-7.2p1.orig/version.h openssh-7.2p1/version.h +--- openssh-7.2p1.orig/version.h 2016-02-26 04:40:04.000000000 +0100 ++++ openssh-7.2p1/version.h 2016-03-02 19:10:52.953628948 +0100 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.75 2015/08/21 03:45:26 djm Exp $ */ + /* $OpenBSD: version.h,v 1.76 2016/02/23 09:14:34 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3004,9 +3004,9 @@ diff -Nur openssh-7.1p1.orig/version.h openssh-7.1p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20150812" + - #define SSH_VERSION "OpenSSH_7.1" + #define SSH_VERSION "OpenSSH_7.2" - #define SSH_PORTABLE "p2" + #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE \ + NCSA_VERSION GSI_VERSION KRB5_VERSION diff --git a/openssh-6.6p1-gsskex.patch b/openssh-7.2p1-gsskex.patch similarity index 88% rename from openssh-6.6p1-gsskex.patch rename to openssh-7.2p1-gsskex.patch index 2feb7b5..ab08b96 100644 --- a/openssh-6.6p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.0p1/auth2.c.gsskex openssh-7.0p1/auth2.c ---- openssh-7.0p1/auth2.c.gsskex 2015-08-12 11:15:43.625548999 +0200 -+++ openssh-7.0p1/auth2.c 2015-08-12 11:15:43.692548892 +0200 +diff -up openssh-7.2p1/auth2.c.gsskex openssh-7.2p1/auth2.c +--- openssh-7.2p1/auth2.c.gsskex 2016-02-19 10:01:04.829969345 +0100 ++++ openssh-7.2p1/auth2.c 2016-02-19 10:01:04.865969325 +0100 @@ -70,6 +70,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; @@ -17,9 +17,9 @@ diff -up openssh-7.0p1/auth2.c.gsskex openssh-7.0p1/auth2.c &method_gssapi, #endif &method_passwd, -diff -up openssh-7.0p1/auth2-gss.c.gsskex openssh-7.0p1/auth2-gss.c ---- openssh-7.0p1/auth2-gss.c.gsskex 2015-08-12 11:15:43.624549001 +0200 -+++ openssh-7.0p1/auth2-gss.c 2015-08-12 11:15:43.692548892 +0200 +diff -up openssh-7.2p1/auth2-gss.c.gsskex openssh-7.2p1/auth2-gss.c +--- openssh-7.2p1/auth2-gss.c.gsskex 2016-02-19 10:01:04.829969345 +0100 ++++ openssh-7.2p1/auth2-gss.c 2016-02-19 10:01:04.865969325 +0100 @@ -31,6 +31,7 @@ #include @@ -102,10 +102,21 @@ diff -up openssh-7.0p1/auth2-gss.c.gsskex openssh-7.0p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-7.0p1/clientloop.c.gsskex openssh-7.0p1/clientloop.c ---- openssh-7.0p1/clientloop.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/clientloop.c 2015-08-12 11:15:43.693548890 +0200 -@@ -115,6 +115,10 @@ +diff -up openssh-7.2p1/auth.c.gsskex openssh-7.2p1/auth.c +--- openssh-7.2p1/auth.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/auth.c 2016-02-19 10:01:04.866969324 +0100 +@@ -354,6 +354,7 @@ auth_root_allowed(const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || ++ strcmp(method, "gssapi-keyex") == 0 || + strcmp(method, "gssapi-with-mic") == 0) + return 1; + break; +diff -up openssh-7.2p1/clientloop.c.gsskex openssh-7.2p1/clientloop.c +--- openssh-7.2p1/clientloop.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/clientloop.c 2016-02-19 10:01:04.866969324 +0100 +@@ -114,6 +114,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -116,11 +127,14 @@ diff -up openssh-7.0p1/clientloop.c.gsskex openssh-7.0p1/clientloop.c /* import options */ extern Options options; -@@ -1610,6 +1614,15 @@ client_loop(int have_pty, int escape_cha +@@ -1662,9 +1666,18 @@ client_loop(int have_pty, int escape_cha + break; + /* Do channel operations unless rekeying in progress. */ - if (!rekeying) { +- if (!ssh_packet_is_rekeying(active_state)) ++ if (!ssh_packet_is_rekeying(active_state)) { channel_after_select(readset, writeset); -+ + +#ifdef GSSAPI + if (options.gss_renewal_rekey && + ssh_gssapi_credentials_updated(GSS_C_NO_CONTEXT)) { @@ -128,14 +142,15 @@ diff -up openssh-7.0p1/clientloop.c.gsskex openssh-7.0p1/clientloop.c + need_rekeying = 1; + } +#endif ++ } + - if (need_rekeying || packet_need_rekeying()) { - debug("need rekeying"); - active_state->kex->done = 0; -diff -up openssh-7.0p1/configure.ac.gsskex openssh-7.0p1/configure.ac ---- openssh-7.0p1/configure.ac.gsskex 2015-08-12 11:15:43.675548919 +0200 -+++ openssh-7.0p1/configure.ac 2015-08-12 11:15:43.694548889 +0200 -@@ -625,6 +625,30 @@ main() { if (NSVersionOfRunTimeLibrary(" + /* Buffer input from the connection. */ + client_process_net_input(readset); + +diff -up openssh-7.2p1/configure.ac.gsskex openssh-7.2p1/configure.ac +--- openssh-7.2p1/configure.ac.gsskex 2016-02-19 10:01:04.857969329 +0100 ++++ openssh-7.2p1/configure.ac 2016-02-19 10:01:04.867969323 +0100 +@@ -632,6 +632,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -166,9 +181,9 @@ diff -up openssh-7.0p1/configure.ac.gsskex openssh-7.0p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-7.0p1/gss-genr.c.gsskex openssh-7.0p1/gss-genr.c ---- openssh-7.0p1/gss-genr.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/gss-genr.c 2015-08-12 11:15:43.694548889 +0200 +diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c +--- openssh-7.2p1/gss-genr.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/gss-genr.c 2016-02-19 10:01:04.867969323 +0100 @@ -41,12 +41,167 @@ #include "buffer.h" #include "log.h" @@ -506,9 +521,9 @@ diff -up openssh-7.0p1/gss-genr.c.gsskex openssh-7.0p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-7.0p1/gss-serv.c.gsskex openssh-7.0p1/gss-serv.c ---- openssh-7.0p1/gss-serv.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/gss-serv.c 2015-08-12 11:15:43.694548889 +0200 +diff -up openssh-7.2p1/gss-serv.c.gsskex openssh-7.2p1/gss-serv.c +--- openssh-7.2p1/gss-serv.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/gss-serv.c 2016-02-19 10:01:04.867969323 +0100 @@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" @@ -791,9 +806,9 @@ diff -up openssh-7.0p1/gss-serv.c.gsskex openssh-7.0p1/gss-serv.c } #endif -diff -up openssh-7.0p1/gss-serv-krb5.c.gsskex openssh-7.0p1/gss-serv-krb5.c ---- openssh-7.0p1/gss-serv-krb5.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:15:43.694548889 +0200 +diff -up openssh-7.2p1/gss-serv-krb5.c.gsskex openssh-7.2p1/gss-serv-krb5.c +--- openssh-7.2p1/gss-serv-krb5.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/gss-serv-krb5.c 2016-02-19 10:01:04.867969323 +0100 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -921,10 +936,10 @@ diff -up openssh-7.0p1/gss-serv-krb5.c.gsskex openssh-7.0p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-7.0p1/kex.c.gsskex openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kex.c 2015-08-12 11:15:43.695548887 +0200 -@@ -55,6 +55,10 @@ +diff -up openssh-7.2p1/kex.c.gsskex openssh-7.2p1/kex.c +--- openssh-7.2p1/kex.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/kex.c 2016-02-19 10:01:04.868969323 +0100 +@@ -54,6 +54,10 @@ #include "sshbuf.h" #include "digest.h" @@ -935,7 +950,7 @@ diff -up openssh-7.0p1/kex.c.gsskex openssh-7.0p1/kex.c #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 -@@ -95,6 +99,11 @@ static const struct kexalg kexalgs[] = { +@@ -107,6 +111,11 @@ static const struct kexalg kexalgs[] = { #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -947,7 +962,7 @@ diff -up openssh-7.0p1/kex.c.gsskex openssh-7.0p1/kex.c { NULL, -1, -1, -1}, }; -@@ -128,6 +137,12 @@ kex_alg_by_name(const char *name) +@@ -140,6 +149,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -960,9 +975,9 @@ diff -up openssh-7.0p1/kex.c.gsskex openssh-7.0p1/kex.c } return NULL; } -diff -up openssh-7.0p1/kexgssc.c.gsskex openssh-7.0p1/kexgssc.c ---- openssh-7.0p1/kexgssc.c.gsskex 2015-08-12 11:15:43.695548887 +0200 -+++ openssh-7.0p1/kexgssc.c 2015-08-12 11:15:43.695548887 +0200 +diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c +--- openssh-7.2p1/kexgssc.c.gsskex 2016-02-19 10:01:04.868969323 +0100 ++++ openssh-7.2p1/kexgssc.c 2016-02-19 10:01:04.868969323 +0100 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1302,9 +1317,9 @@ diff -up openssh-7.0p1/kexgssc.c.gsskex openssh-7.0p1/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh-7.0p1/kexgsss.c.gsskex openssh-7.0p1/kexgsss.c ---- openssh-7.0p1/kexgsss.c.gsskex 2015-08-12 11:15:43.695548887 +0200 -+++ openssh-7.0p1/kexgsss.c 2015-08-12 11:15:43.695548887 +0200 +diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c +--- openssh-7.2p1/kexgsss.c.gsskex 2016-02-19 10:01:04.868969323 +0100 ++++ openssh-7.2p1/kexgsss.c 2016-02-19 10:01:04.868969323 +0100 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1601,10 +1616,10 @@ diff -up openssh-7.0p1/kexgsss.c.gsskex openssh-7.0p1/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh-7.0p1/kex.h.gsskex openssh-7.0p1/kex.h ---- openssh-7.0p1/kex.h.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kex.h 2015-08-12 11:17:44.694354889 +0200 -@@ -93,6 +93,11 @@ enum kex_exchange { +diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h +--- openssh-7.2p1/kex.h.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/kex.h 2016-02-19 10:01:04.868969323 +0100 +@@ -92,6 +92,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, @@ -1616,7 +1631,7 @@ diff -up openssh-7.0p1/kex.h.gsskex openssh-7.0p1/kex.h KEX_MAX }; -@@ -139,6 +144,12 @@ struct kex { +@@ -140,6 +145,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1629,7 +1644,7 @@ diff -up openssh-7.0p1/kex.h.gsskex openssh-7.0p1/kex.h char *client_version_string; char *server_version_string; char *failed_choice; -@@ -186,6 +197,10 @@ int kexecdh_client(struct ssh *); +@@ -189,6 +200,10 @@ int kexecdh_client(struct ssh *); int kexecdh_server(struct ssh *); int kexc25519_client(struct ssh *); int kexc25519_server(struct ssh *); @@ -1640,9 +1655,9 @@ diff -up openssh-7.0p1/kex.h.gsskex openssh-7.0p1/kex.h int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh-7.0p1/Makefile.in.gsskex openssh-7.0p1/Makefile.in ---- openssh-7.0p1/Makefile.in.gsskex 2015-08-12 11:15:43.686548901 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-12 11:15:43.695548887 +0200 +diff -up openssh-7.2p1/Makefile.in.gsskex openssh-7.2p1/Makefile.in +--- openssh-7.2p1/Makefile.in.gsskex 2016-02-19 10:01:04.864969325 +0100 ++++ openssh-7.2p1/Makefile.in 2016-02-19 10:01:04.868969323 +0100 @@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ @@ -1659,11 +1674,11 @@ diff -up openssh-7.0p1/Makefile.in.gsskex openssh-7.0p1/Makefile.in + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ - roaming_common.o roaming_serv.o \ -diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c ---- openssh-7.0p1/monitor.c.gsskex 2015-08-12 11:15:43.626548998 +0200 -+++ openssh-7.0p1/monitor.c 2015-08-12 11:15:43.696548885 +0200 -@@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ +diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c +--- openssh-7.2p1/monitor.c.gsskex 2016-02-19 10:01:04.830969345 +0100 ++++ openssh-7.2p1/monitor.c 2016-02-19 10:01:04.869969322 +0100 +@@ -159,6 +159,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1672,7 +1687,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c #endif #ifdef SSH_AUDIT_EVENTS -@@ -240,11 +242,18 @@ struct mon_table mon_dispatch_proto20[] +@@ -239,11 +241,18 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, @@ -1691,7 +1706,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -359,6 +368,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -358,6 +367,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1702,7 +1717,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c } else { mon_dispatch = mon_dispatch_proto15; -@@ -467,6 +480,10 @@ monitor_child_postauth(struct monitor *p +@@ -466,6 +479,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1713,7 +1728,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1896,6 +1913,13 @@ monitor_apply_keystate(struct monitor *p +@@ -1893,6 +1910,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1727,7 +1742,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1995,6 +2019,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -1992,6 +2016,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -1737,7 +1752,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2022,6 +2049,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2019,6 +2046,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1747,7 +1762,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2039,6 +2069,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2036,6 +2066,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1755,7 +1770,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c } return (0); } -@@ -2050,6 +2081,9 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -2047,6 +2078,9 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -1765,7 +1780,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2076,7 +2110,11 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2073,7 +2107,11 @@ mm_answer_gss_userok(int sock, Buffer *m { int authenticated; @@ -1778,7 +1793,7 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2089,5 +2127,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2086,5 +2124,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1852,9 +1867,9 @@ diff -up openssh-7.0p1/monitor.c.gsskex openssh-7.0p1/monitor.c + #endif /* GSSAPI */ -diff -up openssh-7.0p1/monitor.h.gsskex openssh-7.0p1/monitor.h ---- openssh-7.0p1/monitor.h.gsskex 2015-08-12 11:15:43.626548998 +0200 -+++ openssh-7.0p1/monitor.h 2015-08-12 11:15:43.696548885 +0200 +diff -up openssh-7.2p1/monitor.h.gsskex openssh-7.2p1/monitor.h +--- openssh-7.2p1/monitor.h.gsskex 2016-02-19 10:01:04.830969345 +0100 ++++ openssh-7.2p1/monitor.h 2016-02-19 10:01:04.869969322 +0100 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1864,9 +1879,9 @@ diff -up openssh-7.0p1/monitor.h.gsskex openssh-7.0p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-7.0p1/monitor_wrap.c.gsskex openssh-7.0p1/monitor_wrap.c ---- openssh-7.0p1/monitor_wrap.c.gsskex 2015-08-12 11:15:43.626548998 +0200 -+++ openssh-7.0p1/monitor_wrap.c 2015-08-12 11:15:43.697548884 +0200 +diff -up openssh-7.2p1/monitor_wrap.c.gsskex openssh-7.2p1/monitor_wrap.c +--- openssh-7.2p1/monitor_wrap.c.gsskex 2016-02-19 10:01:04.830969345 +0100 ++++ openssh-7.2p1/monitor_wrap.c 2016-02-19 10:01:04.869969322 +0100 @@ -1087,7 +1087,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } @@ -1927,9 +1942,9 @@ diff -up openssh-7.0p1/monitor_wrap.c.gsskex openssh-7.0p1/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh-7.0p1/monitor_wrap.h.gsskex openssh-7.0p1/monitor_wrap.h ---- openssh-7.0p1/monitor_wrap.h.gsskex 2015-08-12 11:15:43.626548998 +0200 -+++ openssh-7.0p1/monitor_wrap.h 2015-08-12 11:15:43.697548884 +0200 +diff -up openssh-7.2p1/monitor_wrap.h.gsskex openssh-7.2p1/monitor_wrap.h +--- openssh-7.2p1/monitor_wrap.h.gsskex 2016-02-19 10:01:04.830969345 +0100 ++++ openssh-7.2p1/monitor_wrap.h 2016-02-19 10:01:04.869969322 +0100 @@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1942,10 +1957,10 @@ diff -up openssh-7.0p1/monitor_wrap.h.gsskex openssh-7.0p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c ---- openssh-7.0p1/readconf.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-12 11:15:43.697548884 +0200 -@@ -147,6 +147,8 @@ typedef enum { +diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c +--- openssh-7.2p1/readconf.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/readconf.c 2016-02-19 10:01:04.870969322 +0100 +@@ -148,6 +148,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -1954,7 +1969,7 @@ diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -192,10 +194,19 @@ static struct { +@@ -193,10 +195,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1974,7 +1989,7 @@ diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, -@@ -894,10 +905,30 @@ parse_time: +@@ -926,10 +937,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2005,7 +2020,7 @@ diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1601,7 +1632,12 @@ initialize_options(Options * options) +@@ -1648,7 +1679,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2018,7 +2033,7 @@ diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1729,8 +1765,14 @@ fill_default_options(Options * options) +@@ -1777,8 +1813,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2033,9 +2048,9 @@ diff -up openssh-7.0p1/readconf.c.gsskex openssh-7.0p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-7.0p1/readconf.h.gsskex openssh-7.0p1/readconf.h ---- openssh-7.0p1/readconf.h.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/readconf.h 2015-08-12 11:15:43.697548884 +0200 +diff -up openssh-7.2p1/readconf.h.gsskex openssh-7.2p1/readconf.h +--- openssh-7.2p1/readconf.h.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/readconf.h 2016-02-19 10:01:04.870969322 +0100 @@ -45,7 +45,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2049,9 +2064,9 @@ diff -up openssh-7.0p1/readconf.h.gsskex openssh-7.0p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-7.0p1/regress/cert-hostkey.sh.gsskex openssh-7.0p1/regress/cert-hostkey.sh ---- openssh-7.0p1/regress/cert-hostkey.sh.gsskex 2015-08-12 11:15:43.698548882 +0200 -+++ openssh-7.0p1/regress/cert-hostkey.sh 2015-08-12 11:16:52.511438554 +0200 +diff -up openssh-7.2p1/regress/cert-hostkey.sh.gsskex openssh-7.2p1/regress/cert-hostkey.sh +--- openssh-7.2p1/regress/cert-hostkey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/regress/cert-hostkey.sh 2016-02-19 10:01:04.870969322 +0100 @@ -46,7 +46,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca @@ -2061,9 +2076,9 @@ diff -up openssh-7.0p1/regress/cert-hostkey.sh.gsskex openssh-7.0p1/regress/cert # Prepare certificate, plain key and CA KRLs ${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" -diff -up openssh-7.0p1/regress/cert-userkey.sh.gsskex openssh-7.0p1/regress/cert-userkey.sh ---- openssh-7.0p1/regress/cert-userkey.sh.gsskex 2015-08-12 11:15:43.698548882 +0200 -+++ openssh-7.0p1/regress/cert-userkey.sh 2015-08-12 11:20:30.110089677 +0200 +diff -up openssh-7.2p1/regress/cert-userkey.sh.gsskex openssh-7.2p1/regress/cert-userkey.sh +--- openssh-7.2p1/regress/cert-userkey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/regress/cert-userkey.sh 2016-02-19 10:01:04.870969322 +0100 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2073,9 +2088,9 @@ diff -up openssh-7.0p1/regress/cert-userkey.sh.gsskex openssh-7.0p1/regress/cert kname() { n=`echo "$1" | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/'` -diff -up openssh-7.0p1/regress/kextype.sh.gsskex openssh-7.0p1/regress/kextype.sh ---- openssh-7.0p1/regress/kextype.sh.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/regress/kextype.sh 2015-08-12 11:15:43.698548882 +0200 +diff -up openssh-7.2p1/regress/kextype.sh.gsskex openssh-7.2p1/regress/kextype.sh +--- openssh-7.2p1/regress/kextype.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/regress/kextype.sh 2016-02-19 10:01:04.870969322 +0100 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2086,9 +2101,9 @@ diff -up openssh-7.0p1/regress/kextype.sh.gsskex openssh-7.0p1/regress/kextype.s verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh-7.0p1/regress/rekey.sh.gsskex openssh-7.0p1/regress/rekey.sh ---- openssh-7.0p1/regress/rekey.sh.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/regress/rekey.sh 2015-08-12 11:15:43.698548882 +0200 +diff -up openssh-7.2p1/regress/rekey.sh.gsskex openssh-7.2p1/regress/rekey.sh +--- openssh-7.2p1/regress/rekey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/regress/rekey.sh 2016-02-19 10:01:04.870969322 +0100 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2109,9 +2124,9 @@ diff -up openssh-7.0p1/regress/rekey.sh.gsskex openssh-7.0p1/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.gsskex 2015-08-12 11:15:43.676548918 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 11:22:32.686893730 +0200 +diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c +--- openssh-7.2p1/servconf.c.gsskex 2016-02-19 10:01:04.857969329 +0100 ++++ openssh-7.2p1/servconf.c 2016-02-19 10:01:04.870969322 +0100 @@ -117,8 +117,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -2123,7 +2138,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -276,10 +278,14 @@ fill_default_server_options(ServerOption +@@ -288,10 +290,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2138,7 +2153,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -415,7 +421,7 @@ typedef enum { +@@ -422,7 +428,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -2147,7 +2162,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -489,11 +495,17 @@ static struct { +@@ -496,11 +502,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2165,7 +2180,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1235,6 +1247,10 @@ process_server_config_line(ServerOptions +@@ -1246,6 +1258,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2176,7 +2191,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1243,6 +1259,10 @@ process_server_config_line(ServerOptions +@@ -1254,6 +1270,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2187,7 +2202,7 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2255,6 +2275,9 @@ dump_config(ServerOptions *o) +@@ -2274,6 +2294,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2197,9 +2212,9 @@ diff -up openssh-7.0p1/servconf.c.gsskex openssh-7.0p1/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-7.0p1/servconf.h.gsskex openssh-7.0p1/servconf.h ---- openssh-7.0p1/servconf.h.gsskex 2015-08-12 11:15:43.676548918 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-12 11:15:43.700548879 +0200 +diff -up openssh-7.2p1/servconf.h.gsskex openssh-7.2p1/servconf.h +--- openssh-7.2p1/servconf.h.gsskex 2016-02-19 10:01:04.857969329 +0100 ++++ openssh-7.2p1/servconf.h 2016-02-19 10:01:04.871969321 +0100 @@ -118,8 +118,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -2211,19 +2226,18 @@ diff -up openssh-7.0p1/servconf.h.gsskex openssh-7.0p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-7.0p1/ssh_config.5.gsskex openssh-7.0p1/ssh_config.5 ---- openssh-7.0p1/ssh_config.5.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/ssh_config.5 2015-08-12 11:15:43.700548879 +0200 -@@ -749,11 +749,43 @@ Specifies whether user authentication ba +diff -up openssh-7.2p1/ssh_config.5.gsskex openssh-7.2p1/ssh_config.5 +--- openssh-7.2p1/ssh_config.5.gsskex 2016-02-19 10:01:04.871969321 +0100 ++++ openssh-7.2p1/ssh_config.5 2016-02-19 10:05:58.630146245 +0100 +@@ -824,10 +824,40 @@ The default is + Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . - Note that this option applies to protocol version 2 only. +.It Cm GSSAPIKeyExchange +Specifies whether key exchange based on GSSAPI may be used. When using +GSSAPI key exchange the server need not have a host key. +The default is +.Dq no . -+Note that this option applies to protocol version 2 only. +.It Cm GSSAPIClientIdentity +If set, specifies the GSSAPI client identity that ssh should use when +connecting to the server. The default is unset, which means that the default @@ -2237,8 +2251,6 @@ diff -up openssh-7.0p1/ssh_config.5.gsskex openssh-7.0p1/ssh_config.5 Forward (delegate) credentials to the server. The default is .Dq no . --Note that this option applies to protocol version 2 only. -+Note that this option applies to protocol version 2 connections using GSSAPI. +.It Cm GSSAPIRenewalForcesRekey +If set to +.Dq yes @@ -2255,13 +2267,12 @@ diff -up openssh-7.0p1/ssh_config.5.gsskex openssh-7.0p1/ssh_config.5 +command line will be passed untouched to the GSSAPI library. +The default is +.Dq no . -+This option only applies to protocol version 2 connections using GSSAPI. .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-7.0p1/ssh_config.gsskex openssh-7.0p1/ssh_config ---- openssh-7.0p1/ssh_config.gsskex 2015-08-12 11:15:43.667548932 +0200 -+++ openssh-7.0p1/ssh_config 2015-08-12 11:15:43.700548879 +0200 +diff -up openssh-7.2p1/ssh_config.gsskex openssh-7.2p1/ssh_config +--- openssh-7.2p1/ssh_config.gsskex 2016-02-19 10:01:04.852969332 +0100 ++++ openssh-7.2p1/ssh_config 2016-02-19 10:01:04.871969321 +0100 @@ -26,6 +26,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -2271,10 +2282,10 @@ diff -up openssh-7.0p1/ssh_config.gsskex openssh-7.0p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1/sshconnect2.c.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-12 11:25:12.486644393 +0200 -@@ -160,9 +160,34 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c +--- openssh-7.2p1/sshconnect2.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/sshconnect2.c 2016-02-19 10:01:04.872969321 +0100 +@@ -161,9 +161,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2306,10 +2317,10 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c + } +#endif + - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( - options.kex_algorithms); - myproposal[PROPOSAL_ENC_ALGS_CTOS] = -@@ -193,6 +218,17 @@ ssh_kex2(char *host, struct sockaddr *ho + if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) + fatal("%s: kex_names_cat", __func__); + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); +@@ -195,6 +220,17 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2327,7 +2338,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); -@@ -210,11 +246,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -212,11 +248,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2358,8 +2369,8 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c + dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); - if (options.use_roaming && !kex->roaming) { -@@ -306,6 +362,7 @@ int input_gssapi_token(int type, u_int32 + /* remove ext-info from the KEX proposals for rekeying */ +@@ -311,6 +367,7 @@ int input_gssapi_token(int type, u_int32 int input_gssapi_hash(int type, u_int32_t, void *); int input_gssapi_error(int, u_int32_t, void *); int input_gssapi_errtok(int, u_int32_t, void *); @@ -2367,7 +2378,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c #endif void userauth(Authctxt *, char *); -@@ -321,6 +378,11 @@ static char *authmethods_get(void); +@@ -326,6 +383,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2379,7 +2390,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -627,19 +689,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -656,19 +718,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2413,7 +2424,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -736,8 +810,8 @@ input_gssapi_response(int type, u_int32_ +@@ -765,8 +839,8 @@ input_gssapi_response(int type, u_int32_ { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -2424,7 +2435,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -850,6 +924,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -879,6 +953,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); return 0; } @@ -2473,10 +2484,10 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskex openssh-7.0p1/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.gsskex 2015-08-12 11:15:43.679548913 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-12 11:15:43.702548876 +0200 -@@ -1043,8 +1043,9 @@ notify_hostkeys(struct ssh *ssh) +diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c +--- openssh-7.2p1/sshd.c.gsskex 2016-02-19 10:01:04.860969328 +0100 ++++ openssh-7.2p1/sshd.c 2016-02-19 10:01:04.872969321 +0100 +@@ -974,8 +974,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %d hostkeys", __func__, nkeys); if (nkeys == 0) @@ -2488,7 +2499,7 @@ diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c sshbuf_free(buf); } -@@ -1843,10 +1843,13 @@ main(int ac, char **av) +@@ -1845,10 +1846,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2502,7 +2513,7 @@ diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2582,6 +2585,48 @@ do_ssh2_kex(void) +@@ -2586,6 +2590,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2551,7 +2562,7 @@ diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2596,6 +2641,13 @@ do_ssh2_kex(void) +@@ -2600,6 +2646,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2565,23 +2576,22 @@ diff -up openssh-7.0p1/sshd.c.gsskex openssh-7.0p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-7.0p1/sshd_config.5.gsskex openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1/sshd_config.5.gsskex 2015-08-12 11:15:43.677548916 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-12 11:15:43.702548876 +0200 -@@ -621,6 +621,12 @@ Specifies whether user authentication ba +diff -up openssh-7.2p1/sshd_config.5.gsskex openssh-7.2p1/sshd_config.5 +--- openssh-7.2p1/sshd_config.5.gsskex 2016-02-19 10:01:04.858969329 +0100 ++++ openssh-7.2p1/sshd_config.5 2016-02-19 10:06:26.651172355 +0100 +@@ -623,6 +623,11 @@ The default is + Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . - Note that this option applies to protocol version 2 only. +.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. +The default is +.Dq no . -+Note that this option applies to protocol version 2 only. .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. -@@ -642,6 +648,11 @@ machine's default store. +@@ -643,6 +648,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Dq yes . @@ -2593,9 +2603,9 @@ diff -up openssh-7.0p1/sshd_config.5.gsskex openssh-7.0p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -diff -up openssh-7.0p1/sshd_config.gsskex openssh-7.0p1/sshd_config ---- openssh-7.0p1/sshd_config.gsskex 2015-08-12 11:15:43.679548913 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-12 11:15:43.702548876 +0200 +diff -up openssh-7.2p1/sshd_config.gsskex openssh-7.2p1/sshd_config +--- openssh-7.2p1/sshd_config.gsskex 2016-02-19 10:01:04.860969328 +0100 ++++ openssh-7.2p1/sshd_config 2016-02-19 10:01:04.873969320 +0100 @@ -91,6 +91,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes @@ -2605,9 +2615,9 @@ diff -up openssh-7.0p1/sshd_config.gsskex openssh-7.0p1/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-7.0p1/ssh-gss.h.gsskex openssh-7.0p1/ssh-gss.h ---- openssh-7.0p1/ssh-gss.h.gsskex 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/ssh-gss.h 2015-08-12 11:15:43.702548876 +0200 +diff -up openssh-7.2p1/ssh-gss.h.gsskex openssh-7.2p1/ssh-gss.h +--- openssh-7.2p1/ssh-gss.h.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/ssh-gss.h 2016-02-19 10:01:04.873969320 +0100 @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* @@ -2707,21 +2717,20 @@ diff -up openssh-7.0p1/ssh-gss.h.gsskex openssh-7.0p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ - -diff -up openssh-7.1p1/sshkey.c.gsskex openssh-7.1p1/sshkey.c ---- openssh-7.1p1/sshkey.c.gsskex 2015-09-17 15:54:32.135673460 +0200 -+++ openssh-7.1p1/sshkey.c 2015-09-17 15:55:23.014666159 +0200 -@@ -112,6 +112,7 @@ static const struct keytype keytypes[] = +diff -up openssh-7.2p1/sshkey.c.gsskex openssh-7.2p1/sshkey.c +--- openssh-7.2p1/sshkey.c.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/sshkey.c 2016-02-19 10:01:04.874969320 +0100 +@@ -115,6 +115,7 @@ static const struct keytype keytypes[] = # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ -+ { "null", "null", KEY_NULL, 0, 0 }, - { NULL, NULL, -1, -1, 0 } ++ { "null", "null", KEY_NULL, 0, 0, 1 }, + { NULL, NULL, -1, -1, 0, 0 } }; -diff -up openssh-7.1p1/sshkey.h.gsskex openssh-7.1p1/sshkey.h ---- openssh-7.1p1/sshkey.h.gsskex 2015-09-17 15:54:32.135673460 +0200 -+++ openssh-7.1p1/sshkey.h 2015-09-17 15:55:45.885662877 +0200 +diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h +--- openssh-7.2p1/sshkey.h.gsskex 2016-02-12 11:47:25.000000000 +0100 ++++ openssh-7.2p1/sshkey.h 2016-02-19 10:01:04.874969320 +0100 @@ -62,6 +62,7 @@ enum sshkey_types { KEY_DSA_CERT, KEY_ECDSA_CERT, @@ -2730,15 +2739,3 @@ diff -up openssh-7.1p1/sshkey.h.gsskex openssh-7.1p1/sshkey.h KEY_UNSPEC }; -diff --git a/auth.c b/auth.c -index 4d1fbbe..5db39c4 100644 ---- a/auth.c -+++ b/auth.c -@@ -354,6 +354,7 @@ auth_root_allowed(const char *method) - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -+ strcmp(method, "gssapi-keyex") == 0 || - strcmp(method, "gssapi-with-mic") == 0) - return 1; - break; diff --git a/sources b/sources index 0d63d38..03053e3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -4d8547670e2a220d5ef805ad9e47acf2 openssh-7.1p2.tar.gz +b984775f0cfff1f7ff18b8797fce8a28 openssh-7.2p1.tar.gz From 873d1aca8077dab3dfde363f282b21dcc9e1562b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 16 Apr 2016 15:10:16 +0200 Subject: [PATCH 025/146] Based on openssh-8.2p2-2.fc23 --- gsi-openssh.spec | 7 +- gsisshd-keygen | 18 ++- openssh-7.2p1-audit.patch | 110 +++++++++--------- openssh-7.2p1-gsskex.patch | 38 ++++++ ...gsissh.patch => openssh-7.2p2-gsissh.patch | 2 +- sources | 2 +- 6 files changed, 115 insertions(+), 62 deletions(-) rename openssh-7.2p1-gsissh.patch => openssh-7.2p2-gsissh.patch (99%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e84c1a3..f8ab0bd 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,7 +30,7 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.2p1 +%global openssh_ver 7.2p2 %global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication @@ -175,7 +175,7 @@ Patch936: openssh-7.1p1-iutf8.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch -Patch98: openssh-7.2p1-gsissh.patch +Patch98: openssh-7.2p2-gsissh.patch License: BSD Group: Applications/Internet @@ -543,6 +543,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat Apr 16 2016 Mattias Ellert - 7.2p2-1 +- Based on openssh-7.2p2-2.fc23 + * Fri Mar 04 2016 Mattias Ellert - 7.2p1-1 - Based on openssh-7.2p1-2.fc23 diff --git a/gsisshd-keygen b/gsisshd-keygen index b313c87..eeef6ce 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -6,8 +6,22 @@ # variable. AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519" -# source function library -. /etc/rc.d/init.d/functions +if [ -f /etc/rc.d/init.d/functions ]; then + # source function library + . /etc/rc.d/init.d/functions +else + # minimal implementation of success and failure function + success() + { + echo -en $"[ OK ]\r" + return 0 + } + failure() + { + echo -en $"[FAILED]\r" + return 1 + } +fi # Some functions to make the below more readable KEYGEN=/usr/bin/gsissh-keygen diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index e7574b5..43798ab 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -224,9 +224,9 @@ diff -up openssh-7.2p1/audit.c.audit openssh-7.2p1/audit.c +int +audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) +{ -+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", ++ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s, result %d", + host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, -+ sshkey_fingerprint_prefix(), fp, rv); ++ fp, rv); +} + +/* @@ -291,8 +291,16 @@ diff -up openssh-7.2p1/audit.h.audit openssh-7.2p1/audit.h enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { +@@ -45,13 +46,33 @@ enum ssh_audit_event_type { + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN }; ++ ++enum ssh_audit_kex { ++ SSH_AUDIT_UNSUPPORTED_CIPHER, ++ SSH_AUDIT_UNSUPPORTED_MAC, ++ SSH_AUDIT_UNSUPPORTED_COMPRESSION ++}; typedef enum ssh_audit_event_type ssh_audit_event_t; +int listening_for_clients(void); @@ -365,7 +373,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const +@@ -65,35 +77,150 @@ linux_audit_record_event(int uid, const if ((rc == -EPERM) && (geteuid() != 0)) rc = 0; errno = saved_errno; @@ -406,7 +414,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + else + goto fatal_report; /* Must prevent login */ + } -+ ++ + if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) + event = SSH_AUDIT_UNKNOWN; + @@ -439,7 +447,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return 1; /* No audit support in kernel */ -+ else ++ else + return 0; /* Must prevent login */ + } + snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port()); @@ -447,10 +455,6 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; -+ /* is the fingerprint_prefix() still needed? -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d", -+ type, bits, sshkey_fingerprint_prefix(), fp, get_remote_port()); -+ */ + snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", + type, bits, fp, get_remote_port()); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, @@ -479,7 +483,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c audit_run_command(const char *command) { - /* not implemented */ -+ if (!user_login_count++) ++ if (!user_login_count++) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_LOGIN); + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), @@ -492,7 +496,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c +{ + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_END); -+ if (user_login_count && !--user_login_count) ++ if (user_login_count && !--user_login_count) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_LOGOUT); +} @@ -509,7 +513,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c - if (linux_audit_record_event(li->uid, NULL, li->hostname, - NULL, li->line, 1) == 0) - fatal("linux_audit_write_entry failed: %s", strerror(errno)); -+ if (!user_login_count++) ++ if (!user_login_count++) + linux_audit_user_logxxx(li->uid, NULL, li->hostname, + NULL, li->line, 1, AUDIT_USER_LOGIN); + linux_audit_user_logxxx(li->uid, NULL, li->hostname, @@ -522,7 +526,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c - /* not implemented */ + linux_audit_user_logxxx(li->uid, NULL, li->hostname, + NULL, li->line, 1, AUDIT_USER_END); -+ if (user_login_count && !--user_login_count) ++ if (user_login_count && !--user_login_count) + linux_audit_user_logxxx(li->uid, NULL, li->hostname, + NULL, li->line, 1, AUDIT_USER_LOGOUT); } @@ -625,7 +629,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return; /* No audit support in kernel */ -+ else ++ else + fatal("cannot open audit"); /* Must prevent login */ + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, @@ -991,7 +995,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(0); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_CIPHER); +#endif return SSH_ERR_NO_CIPHER_ALG_MATCH; + } @@ -1005,7 +1009,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(1); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_MAC); +#endif return SSH_ERR_NO_MAC_ALG_MATCH; + } @@ -1019,7 +1023,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(2); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_COMPRESSION); +#endif return SSH_ERR_NO_COMPRESS_ALG_MATCH; + } @@ -1037,7 +1041,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1052,3 +1069,34 @@ dump_digest(char *msg, u_char *digest, i +@@ -1052,3 +1069,33 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1071,10 +1075,9 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c + mac_destroy(&newkeys->mac); + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} -+ diff -up openssh-7.2p1/kex.h.audit openssh-7.2p1/kex.h ---- openssh-7.2p1/kex.h.audit 2016-02-12 18:24:34.201825185 +0100 -+++ openssh-7.2p1/kex.h 2016-02-12 18:24:34.222825177 +0100 +--- openssh-7.2p1/kex.h.audit 2016-03-04 14:25:52.627329892 +0100 ++++ openssh-7.2p1/kex.h 2016-03-04 14:25:52.639329883 +0100 @@ -206,6 +206,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1690,7 +1693,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c + error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); + if ((r = cipher_cleanup(&state->receive_context)) != 0) + error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); -+ audit_session_key_free(2); ++ audit_session_key_free(MODE_MAX); + } free(ssh->remote_ipaddr); ssh->remote_ipaddr = NULL; @@ -1712,7 +1715,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; -@@ -2408,6 +2420,75 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2408,6 +2420,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1769,18 +1772,15 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c +packet_destroy_all(int audit_it, int privsep) +{ + if (audit_it) -+ audit_it = (active_state != NULL && packet_state_has_keys(active_state->state)) -+ || (backup_state != NULL && packet_state_has_keys(backup_state->state)); ++ audit_it = (active_state != NULL && packet_state_has_keys(active_state->state)); + if (active_state != NULL) + packet_destroy_state(active_state->state); -+ if (backup_state != NULL) -+ packet_destroy_state(backup_state->state); + if (audit_it) { +#ifdef SSH_AUDIT_EVENTS + if (privsep) -+ audit_session_key_free(2); ++ audit_session_key_free(MODE_MAX); + else -+ audit_session_key_free_body(2, getpid(), getuid()); ++ audit_session_key_free_body(MODE_MAX, getpid(), getuid()); +#endif + } +} @@ -1789,17 +1789,8 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c static int ssh_packet_set_postauth(struct ssh *ssh) diff -up openssh-7.2p1/packet.h.audit openssh-7.2p1/packet.h ---- openssh-7.2p1/packet.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/packet.h 2016-02-12 18:24:34.226825175 +0100 -@@ -186,7 +186,7 @@ int sshpkt_get_end(struct ssh *ssh); - const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); - - /* OLD API */ --extern struct ssh *active_state; -+extern struct ssh *active_state, *backup_state; - #include "opacket.h" - - #if !defined(WITH_OPENSSL) +--- openssh-7.2p1/packet.h.audit 2016-02-26 04:40:04.000000000 +0100 ++++ openssh-7.2p1/packet.h 2016-03-04 14:25:52.640329883 +0100 @@ -200,4 +200,5 @@ extern struct ssh *active_state; # undef EC_POINT #endif @@ -1838,7 +1829,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); -+#ifndef HAVE_OSF_SIA ++#if !defined(HAVE_OSF_SIA) && defined(SSH_AUDIT_EVENTS) + /* do_login in the child did not affect state in this process, + compensate. From an architectural standpoint, this is extremely + ugly. */ @@ -1902,7 +1893,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c + if (s->used) + return s; + } -+ debug("session_by_id: unknown id %d", id); ++ debug("%s: unknown id %d", __func__, id); + session_dump(); + return NULL; +} @@ -1979,8 +1970,8 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c + session_destroy_all(do_cleanup_one_session); } diff -up openssh-7.2p1/session.h.audit openssh-7.2p1/session.h ---- openssh-7.2p1/session.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/session.h 2016-02-12 18:24:34.226825175 +0100 +--- openssh-7.2p1/session.h.audit 2016-02-26 04:40:04.000000000 +0100 ++++ openssh-7.2p1/session.h 2016-03-04 14:25:52.641329882 +0100 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2041,7 +2032,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c static void close_startup_pipes(void) { -@@ -560,22 +570,45 @@ sshd_exchange_identification(int sock_in +@@ -560,22 +570,49 @@ sshd_exchange_identification(int sock_in } } @@ -2055,15 +2046,17 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c +destroy_sensitive_data(int privsep) { int i; ++#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; ++ pid = getpid(); ++ uid = getuid(); ++#endif if (sensitive_data.server_key) { key_free(sensitive_data.server_key); sensitive_data.server_key = NULL; } -+ pid = getpid(); -+ uid = getuid(); for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + char *fp; @@ -2075,12 +2068,14 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c key_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = NULL; + if (fp != NULL) { ++#ifdef SSH_AUDIT_EVENTS + if (privsep) + PRIVSEP(audit_destroy_sensitive_data(fp, + pid, uid)); + else + audit_destroy_sensitive_data(fp, + pid, uid); ++#endif + free(fp); + } } @@ -2090,21 +2085,22 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -589,6 +622,8 @@ void - demote_sensitive_data(void) +@@ -590,7 +627,13 @@ demote_sensitive_data(void) { Key *tmp; + int i; ++#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; - int i; - - if (sensitive_data.server_key) { -@@ -597,13 +632,25 @@ demote_sensitive_data(void) - sensitive_data.server_key = tmp; - } + pid = getpid(); + uid = getuid(); ++#endif + if (sensitive_data.server_key) { + tmp = key_demote(sensitive_data.server_key); + key_free(sensitive_data.server_key); +@@ -599,11 +642,23 @@ demote_sensitive_data(void) + for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + char *fp; @@ -2119,7 +2115,9 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c if (tmp->type == KEY_RSA1) sensitive_data.ssh1_host_key = tmp; + if (fp != NULL) { ++#ifdef SSH_AUDIT_EVENTS + audit_destroy_sensitive_data(fp, pid, uid); ++#endif + free(fp); + } } diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index ab08b96..4544c54 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -2739,3 +2739,41 @@ diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h KEY_UNSPEC }; +diff --git a/kexgsss.c b/kexgsss.c +index b2f9658..2d33ff7 100644 +--- a/kexgsss.c ++++ b/kexgsss.c +@@ -69,6 +69,7 @@ kexgss_server(struct ssh *ssh) + u_char *kbuf; + DH *dh; + int min = -1, max = -1, nbits = -1; ++ int cmin = -1, cmax = -1; /* client proposal */ + BIGNUM *shared_secret = NULL; + BIGNUM *dh_client_pub = NULL; + int type = 0; +@@ -107,11 +108,12 @@ kexgss_server(struct ssh *ssh) + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange"); + packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); +- min = packet_get_int(); ++ /* store client proposal to provide valid signature */ ++ cmin = packet_get_int(); + nbits = packet_get_int(); +- max = packet_get_int(); +- min = MAX(DH_GRP_MIN, min); +- max = MIN(DH_GRP_MAX, max); ++ cmax = packet_get_int(); ++ min = MAX(DH_GRP_MIN, cmin); ++ max = MIN(DH_GRP_MAX, cmax); + packet_check_eom(); + if (max < min || nbits < min || max < nbits) + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", +@@ -234,7 +236,7 @@ kexgss_server(struct ssh *ssh) + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, +- min, nbits, max, ++ cmin, nbits, cmax, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, diff --git a/openssh-7.2p1-gsissh.patch b/openssh-7.2p2-gsissh.patch similarity index 99% rename from openssh-7.2p1-gsissh.patch rename to openssh-7.2p2-gsissh.patch index 4ca7374..ed64b48 100644 --- a/openssh-7.2p1-gsissh.patch +++ b/openssh-7.2p2-gsissh.patch @@ -3006,7 +3006,7 @@ diff -Nur openssh-7.2p1.orig/version.h openssh-7.2p1/version.h + #define SSH_VERSION "OpenSSH_7.2" - #define SSH_PORTABLE "p1" + #define SSH_PORTABLE "p2" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE \ + NCSA_VERSION GSI_VERSION KRB5_VERSION diff --git a/sources b/sources index 03053e3..7c814f0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -b984775f0cfff1f7ff18b8797fce8a28 openssh-7.2p1.tar.gz +13009a9156510d8f27e752659075cced openssh-7.2p2.tar.gz From 5fd763c594f3ea1e050a3be2dac578b562e7a40b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 16 Apr 2016 17:30:25 +0200 Subject: [PATCH 026/146] Based on openssh-7.2p2-4.fc24 --- gsi-openssh.spec | 18 ++-- gsisshd-keygen | 198 +++++++-------------------------------- gsisshd-keygen.service | 11 --- gsisshd-keygen.target | 5 + gsisshd-keygen@.service | 11 +++ gsisshd.service | 4 +- gsisshd.sysconfig | 10 +- gsisshd@.service | 4 +- openssh-7.2p1-fips.patch | 60 ++++++++++++ 9 files changed, 130 insertions(+), 191 deletions(-) delete mode 100644 gsisshd-keygen.service create mode 100644 gsisshd-keygen.target create mode 100644 gsisshd-keygen@.service diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f8ab0bd..7f4cc92 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.2p2 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -46,9 +46,10 @@ Source7: gsisshd.sysconfig Source9: gsisshd@.service Source10: gsisshd.socket Source11: gsisshd.service -Source12: gsisshd-keygen.service +Source12: gsisshd-keygen@.service Source13: gsisshd-keygen Source14: gsisshd.tmpfiles +Source15: gsisshd-keygen.target Source99: README.sshd-and-gsisshd #? @@ -443,12 +444,13 @@ install -d $RPM_BUILD_ROOT%{_libexecdir}/gsissh install -d $RPM_BUILD_ROOT%{_libdir}/fipscheck install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/gsisshd install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/gsisshd -install -m755 %{SOURCE13} $RPM_BUILD_ROOT/%{_sbindir}/sshd-keygen 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 install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.service -install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd-keygen.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 -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/gsissh.conf rm $RPM_BUILD_ROOT%{_bindir}/ssh-add @@ -526,9 +528,9 @@ getent passwd sshd >/dev/null || \ %files server %dir %attr(0711,root,root) %{_var}/empty/gsisshd %attr(0755,root,root) %{_sbindir}/gsisshd -%attr(0755,root,root) %{_sbindir}/gsisshd-keygen %attr(0644,root,root) %{_libdir}/fipscheck/gsisshd.hmac %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* %attr(0644,root,root) %{_mandir}/man5/gsimoduli.5* %attr(0644,root,root) %{_mandir}/man8/gsisshd.8* @@ -539,10 +541,14 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd.service %attr(0644,root,root) %{_unitdir}/gsisshd@.service %attr(0644,root,root) %{_unitdir}/gsisshd.socket -%attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service +%attr(0644,root,root) %{_unitdir}/gsisshd-keygen@.service +%attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat Apr 16 2016 Mattias Ellert - 7.2p2-2 +- Based on openssh-7.2p2-4.fc24 + * Sat Apr 16 2016 Mattias Ellert - 7.2p2-1 - Based on openssh-7.2p2-2.fc23 diff --git a/gsisshd-keygen b/gsisshd-keygen index eeef6ce..af0a740 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -1,168 +1,40 @@ #!/bin/bash # Create the host keys for the gsissh server. -# -# The creation is controlled by the $AUTOCREATE_SERVER_KEYS environment -# variable. -AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519" - -if [ -f /etc/rc.d/init.d/functions ]; then - # source function library - . /etc/rc.d/init.d/functions -else - # minimal implementation of success and failure function - success() - { - echo -en $"[ OK ]\r" - return 0 - } - failure() - { - echo -en $"[FAILED]\r" - return 1 - } -fi - -# Some functions to make the below more readable -KEYGEN=/usr/bin/gsissh-keygen -RSA1_KEY=/etc/gsissh/ssh_host_key -RSA_KEY=/etc/gsissh/ssh_host_rsa_key -DSA_KEY=/etc/gsissh/ssh_host_dsa_key -ECDSA_KEY=/etc/gsissh/ssh_host_ecdsa_key -ED25519_KEY=/etc/gsissh/ssh_host_ed25519_key - -# pull in sysconfig settings -[ -f /etc/sysconfig/gsisshd ] && . /etc/sysconfig/gsisshd - -fips_enabled() { - if [ -r /proc/sys/crypto/fips_enabled ]; then - cat /proc/sys/crypto/fips_enabled - else - echo 0 - fi -} - -do_rsa1_keygen() { - if [ ! -s $RSA1_KEY -a `fips_enabled` -eq 0 ]; then - echo -n $"Generating SSH1 RSA host key: " - rm -f $RSA1_KEY - if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then - chgrp ssh_keys $RSA1_KEY - chmod 640 $RSA1_KEY - chmod 644 $RSA1_KEY.pub - if [ -x /sbin/restorecon ]; then - /sbin/restorecon $RSA1_KEY{,.pub} - fi - success $"RSA1 key generation" - echo - else - failure $"RSA1 key generation" - echo - exit 1 - fi - fi -} - -do_rsa_keygen() { - if [ ! -s $RSA_KEY ]; then - echo -n $"Generating SSH2 RSA host key: " - rm -f $RSA_KEY - if test ! -f $RSA_KEY && $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then - chgrp ssh_keys $RSA_KEY - chmod 640 $RSA_KEY - chmod 644 $RSA_KEY.pub - if [ -x /sbin/restorecon ]; then - /sbin/restorecon $RSA_KEY{,.pub} - fi - success $"RSA key generation" - echo - else - failure $"RSA key generation" - echo - exit 1 - fi - fi -} - -do_dsa_keygen() { - if [ ! -s $DSA_KEY -a `fips_enabled` -eq 0 ]; then - echo -n $"Generating SSH2 DSA host key: " - rm -f $DSA_KEY - if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then - chgrp ssh_keys $DSA_KEY - chmod 640 $DSA_KEY - chmod 644 $DSA_KEY.pub - if [ -x /sbin/restorecon ]; then - /sbin/restorecon $DSA_KEY{,.pub} - fi - success $"DSA key generation" - echo - else - failure $"DSA key generation" - echo - exit 1 - fi - fi -} - -do_ecdsa_keygen() { - if [ ! -s $ECDSA_KEY ]; then - echo -n $"Generating SSH2 ECDSA host key: " - rm -f $ECDSA_KEY - if test ! -f $ECDSA_KEY && $KEYGEN -q -t ecdsa -f $ECDSA_KEY -C '' -N '' >&/dev/null; then - chgrp ssh_keys $ECDSA_KEY - chmod 640 $ECDSA_KEY - chmod 644 $ECDSA_KEY.pub - if [ -x /sbin/restorecon ]; then - /sbin/restorecon $ECDSA_KEY{,.pub} - fi - success $"ECDSA key generation" - echo - else - failure $"ECDSA key generation" - echo - exit 1 - fi - fi -} - -do_ed25519_keygen() { - if [ ! -s $ED25519_KEY -a `fips_enabled` -eq 0 ]; then - echo -n $"Generating SSH2 ED25519 host key: " - rm -f $ED25519_KEY - if test ! -f $ED25519_KEY && $KEYGEN -q -t ed25519 -f $ED25519_KEY -C '' -N '' >&/dev/null; then - chgrp ssh_keys $ED25519_KEY - chmod 640 $ED25519_KEY - chmod 644 $ED25519_KEY.pub - if [ -x /sbin/restorecon ]; then - /sbin/restorecon $ED25519_KEY{,.pub} - fi - success $"ED25519 key generation" - echo - else - failure $"ED25519 key generation" - echo - exit 1 - fi - fi -} - -if [ "x${AUTOCREATE_SERVER_KEYS}" == "xNO" ]; then - exit 0 -fi - -# legacy options -case $AUTOCREATE_SERVER_KEYS in - NODSA) AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519";; - RSAONLY) AUTOCREATE_SERVER_KEYS="RSA";; - YES) AUTOCREATE_SERVER_KEYS="DSA RSA ECDSA ED25519";; +KEYTYPE=$1 +case $KEYTYPE in + "dsa") ;& # disabled in FIPS + "ed25519") + FIPS=/proc/sys/crypto/fips_enabled + if [[ -r "$FIPS" && $(cat $FIPS) == "1" ]]; then + exit 0 + fi ;; + "rsa") ;; # always ok + "ecdsa") ;; + *) # wrong argument + exit 12 ;; esac +KEY=/etc/gsissh/ssh_host_${KEYTYPE}_key -for KEY in $AUTOCREATE_SERVER_KEYS; do - case $KEY in - DSA) do_dsa_keygen;; - RSA) do_rsa_keygen;; - ECDSA) do_ecdsa_keygen;; - ED25519) do_ed25519_keygen;; - esac -done +KEYGEN=/usr/bin/gsissh-keygen +if [[ ! -x $KEYGEN ]]; then + exit 13 +fi + +# remove old keys +rm -f $KEY{,.pub} + +# create new keys +if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then + exit 1 +fi + +# sanitize permissions +/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} +fi + +exit 0 diff --git a/gsisshd-keygen.service b/gsisshd-keygen.service deleted file mode 100644 index 546e82e..0000000 --- a/gsisshd-keygen.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=gsissh Server Key Generation -ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_rsa_key -ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_ecdsa_key -ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_ed25519_key -PartOf=gsisshd.service gsisshd.socket - -[Service] -ExecStart=/usr/sbin/gsisshd-keygen -Type=oneshot -RemainAfterExit=yes diff --git a/gsisshd-keygen.target b/gsisshd-keygen.target new file mode 100644 index 0000000..ec894d0 --- /dev/null +++ b/gsisshd-keygen.target @@ -0,0 +1,5 @@ +[Unit] +Wants=gsisshd-keygen@rsa.service +Wants=gsisshd-keygen@ecdsa.service +Wants=gsisshd-keygen@ed25519.service +PartOf=gsisshd.service diff --git a/gsisshd-keygen@.service b/gsisshd-keygen@.service new file mode 100644 index 0000000..6b2898b --- /dev/null +++ b/gsisshd-keygen@.service @@ -0,0 +1,11 @@ +[Unit] +Description=gsissh %i Server Key Generation +ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_%i_key + +[Service] +Type=oneshot +EnvironmentFile=-/etc/sysconfig/gsisshd +ExecStart=/usr/libexec/gsissh/sshd-keygen %i + +[Install] +WantedBy=gsisshd-keygen.target diff --git a/gsisshd.service b/gsisshd.service index 2c11964..0ac73ab 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -1,8 +1,8 @@ [Unit] Description=gsissh server daemon Documentation=man:gsisshd(8) man:gsisshd_config(5) -After=network.target gsisshd-keygen.service -Wants=gsisshd-keygen.service +After=network.target gsisshd-keygen.target +Wants=gsisshd-keygen.target [Service] Type=forking diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index e666ab9..93b83b7 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -1,12 +1,8 @@ -# Configuration file for the sshd service. +# Configuration file for the gsisshd service. # The server keys are automatically generated if they are missing. -# To change the automatic creation uncomment and change the appropriate -# line. Accepted key types are: DSA RSA ECDSA ED25519. -# The default is "RSA ECDSA ED25519" - -# AUTOCREATE_SERVER_KEYS="" -# AUTOCREATE_SERVER_KEYS="RSA ECDSA ED25519" +# To change the automatic creation, adjust gsisshd.service options for +# example using systemctl enable gsisshd-config@dsa.service for DSA keys # Do not change this option unless you have hardware random # generator and you REALLY know what you are doing diff --git a/gsisshd@.service b/gsisshd@.service index 2f59be2..3f5ecbd 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -1,8 +1,8 @@ [Unit] Description=gsissh per-connection server daemon Documentation=man:gsisshd(8) man:gsisshd_config(5) -Wants=gsisshd-keygen.service -After=gsisshd-keygen.service +Wants=gsisshd-keygen.target +After=gsisshd-keygen.target [Service] EnvironmentFile=-/etc/sysconfig/gsisshd diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index ebab58d..b350d18 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -637,3 +637,63 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } +diff --git a/cipher.c b/cipher.c +index f282907..51bbffb 100644 +--- a/cipher.c ++++ b/cipher.c +@@ -112,12 +112,6 @@ static const struct sshcipher fips_ciphers[] = { + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, +-#ifdef OPENSSL_HAVE_EVPGCM +- { "aes128-gcm@openssh.com", +- SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, +- { "aes256-gcm@openssh.com", +- SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, +-#endif + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } + }; + +diff --git a/kex.c b/kex.c +index f07a636..4ce5843 100644 +--- a/kex.c ++++ b/kex.c +@@ -123,8 +123,6 @@ static const struct kexalg kexalgs[] = { + }; + + static const struct kexalg kexalgs_fips[] = { +- { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, +- { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + #ifdef HAVE_EVP_SHA256 + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, + #endif +diff --git a/myproposal.h b/myproposal.h +index 7efe312..bcf2ae1 100644 +--- a/myproposal.h ++++ b/myproposal.h +@@ -131,9 +131,7 @@ + + #define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ +- KEX_SHA256_METHODS \ +- "diffie-hellman-group-exchange-sha1," \ +- "diffie-hellman-group14-sha1" ++ KEX_SHA256_METHODS + #define KEX_FIPS_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-cbc,3des-cbc," \ +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index a3975eb..5224084 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -112,6 +112,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_open + SC_DENY(open, EACCES), + #endif ++#ifdef __NR_socket ++ SC_DENY(socket, EACCES), ++#endif + #ifdef __NR_openat + SC_DENY(openat, EACCES), + #endif + From 7ecf78753c562bffbdcba3d1cf6d3cd72eacf613 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 12 May 2016 13:10:52 +0200 Subject: [PATCH 027/146] Based on openssh-7.2p2-5.fc24 --- gsi-openssh.spec | 8 +++++++- gsisshd.sysconfig | 4 +++- openssh-7.2p2-CVE-2015-8325.patch | 32 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 openssh-7.2p2-CVE-2015-8325.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 7f4cc92..5356392 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.2p2 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -173,6 +173,8 @@ Patch933: openssh-7.0p1-show-more-fingerprints.patch # Preserve IUTF8 tty mode flag over ssh connections (#1270248) # https://bugzilla.mindrot.org/show_bug.cgi?id=2477 Patch936: openssh-7.1p1-iutf8.patch +# CVE-2015-8325: ignore PAM environment vars when UseLogin=yes +Patch937: openssh-7.2p2-CVE-2015-8325.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -331,6 +333,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint %patch936 -p1 -b .iutf8 +%patch937 -p1 -b .pam_uselogin_cve %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -546,6 +549,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu May 12 2016 Mattias Ellert - 7.2p2-3 +- Based on openssh-7.2p2-5.fc24 + * Sat Apr 16 2016 Mattias Ellert - 7.2p2-2 - Based on openssh-7.2p2-4.fc24 diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 93b83b7..482f734 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -2,7 +2,9 @@ # The server keys are automatically generated if they are missing. # To change the automatic creation, adjust gsisshd.service options for -# example using systemctl enable gsisshd-config@dsa.service for DSA keys +# 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. # Do not change this option unless you have hardware random # generator and you REALLY know what you are doing diff --git a/openssh-7.2p2-CVE-2015-8325.patch b/openssh-7.2p2-CVE-2015-8325.patch new file mode 100644 index 0000000..4224051 --- /dev/null +++ b/openssh-7.2p2-CVE-2015-8325.patch @@ -0,0 +1,32 @@ +From 85bdcd7c92fe7ff133bbc4e10a65c91810f88755 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Wed, 13 Apr 2016 10:39:57 +1000 +Subject: ignore PAM environment vars when UseLogin=yes + +If PAM is configured to read user-specified environment variables +and UseLogin=yes in sshd_config, then a hostile local user may +attack /bin/login via LD_PRELOAD or similar environment variables +set via PAM. + +CVE-2015-8325, found by Shayan Sadigh, via Colin Watson +--- + session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/session.c b/session.c +index 4859245..4653b09 100644 +--- a/session.c ++++ b/session.c +@@ -1322,7 +1322,7 @@ do_setup_env(Session *s, const char *shell) + * Pull in any environment variables that may have + * been set by PAM. + */ +- if (options.use_pam) { ++ if (options.use_pam && !options.use_login) { + char **p; + + p = fetch_pam_child_environment(); +-- +cgit v0.11.2 + + From 8c873b6826044fc658eb44be532e90cdd01030d4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 26 Jun 2016 05:47:09 +0200 Subject: [PATCH 028/146] Based on openssh-7.2p2-8.fc24 --- gsi-openssh.spec | 38 ++++---- openssh-6.6.1p1-localdomain.patch | 12 --- openssh-6.6p1-entropy.patch | 10 +++ openssh-6.6p1-redhat.patch | 12 ++- openssh-6.7p1-coverity.patch | 48 ---------- openssh-6.7p1-sftp-force-permission.patch | 41 ++++++--- openssh-6.9p1-seccomp-secondary.patch | 34 ++++---- openssh-7.2p1-fips.patch | 8 ++ ...penssh-7.2p2-UsePAM-UseLogin-warning.patch | 17 +++- openssh-7.2p2-certificats-regress.patch | 38 ++++++++ openssh-7.2p2-k5login_directory.patch | 87 +++++++++++++++++++ ...5.5p1-x11.patch => openssh-7.2p2-x11.patch | 18 ++-- 12 files changed, 245 insertions(+), 118 deletions(-) delete mode 100644 openssh-6.6.1p1-localdomain.patch rename openssh-6.6p1-log-usepam-no.patch => openssh-7.2p2-UsePAM-UseLogin-warning.patch (63%) create mode 100644 openssh-7.2p2-certificats-regress.patch create mode 100644 openssh-7.2p2-k5login_directory.patch rename openssh-5.5p1-x11.patch => openssh-7.2p2-x11.patch (77%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 5356392..eada75f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.2p2 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -52,11 +52,11 @@ Source14: gsisshd.tmpfiles Source15: gsisshd-keygen.target Source99: README.sshd-and-gsisshd -#? +#https://bugzilla.mindrot.org/show_bug.cgi?id=2581 Patch100: openssh-6.7p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 #https://bugzilla.redhat.com/show_bug.cgi?id=735889 -Patch102: openssh-5.8p1-getaddrinfo.patch +#Patch102: openssh-5.8p1-getaddrinfo.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1889 Patch103: openssh-5.8p1-packet.patch @@ -79,23 +79,21 @@ 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 +#https://bugzilla.mindrot.org/show_bug.cgi?id=1893 (WONTFIX) Patch604: openssh-6.6p1-keyperm.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1925 +#(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-5.5p1-x11.patch +Patch609: openssh-7.2p2-x11.patch #? Patch700: openssh-7.2p1-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 -#? -Patch706: openssh-6.6.1p1-localdomain.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) Patch707: openssh-6.6p1-redhat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :) @@ -103,7 +101,7 @@ Patch708: openssh-6.6p1-entropy.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) Patch709: openssh-6.2p1-vendor.patch # warn users for unsupported UsePAM=no (#757545) -Patch711: openssh-6.6p1-log-usepam-no.patch +Patch711: openssh-7.2p2-UsePAM-UseLogin-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 @@ -122,12 +120,14 @@ Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch # Documentation about GSSAPI # from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655 Patch803: openssh-7.1p1-gssapi-documentation.patch +# use default_ccache_name from /etc/krb5.conf (#991186) +Patch804: openssh-6.3p1-krb5-use-default_ccache_name.patch +# Respect k5login_directory option in krk5.conf (#1328243) +Patch805: openssh-7.2p2-k5login_directory.patch Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 Patch901: openssh-6.6p1-kuserok.patch -# use default_ccache_name from /etc/krb5.conf (#991186) -Patch902: openssh-6.3p1-krb5-use-default_ccache_name.patch # Use tty allocation for a remote scp (#985650) Patch906: openssh-6.4p1-fromto-remote.patch # set a client's address right after a connection is set @@ -175,6 +175,8 @@ Patch933: openssh-7.0p1-show-more-fingerprints.patch Patch936: openssh-7.1p1-iutf8.patch # CVE-2015-8325: ignore PAM environment vars when UseLogin=yes Patch937: openssh-7.2p2-CVE-2015-8325.patch +# Regression in certificate based authentication (#1333498) +Patch938: openssh-7.2p2-certificats-regress.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -189,7 +191,7 @@ Obsoletes: %{name}-clients-fips, %{name}-server-fips %if %{ldap} BuildRequires: openldap-devel %endif -BuildRequires: autoconf, automake, perl, zlib-devel +BuildRequires: autoconf, automake, perl, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel @@ -297,7 +299,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch702 -p1 -b .progress %patch703 -p1 -b .grab-info -%patch706 -p1 -b .localdomain %patch707 -p1 -b .redhat %patch708 -p1 -b .entropy %patch709 -p1 -b .vendor @@ -309,10 +310,11 @@ This version of OpenSSH has been modified to support GSI authentication. %patch800 -p1 -b .gsskex %patch801 -p1 -b .force_krb %patch803 -p1 -b .gss-docs +%patch804 -p1 -b .ccache_name +%patch805 -p1 -b .k5login %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok -%patch902 -p1 -b .ccache_name %patch906 -p1 -b .fromto-remote %patch911 -p1 -b .set_remote_ipaddr %patch912 -p1 -b .utf8-banner @@ -334,6 +336,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch933 -p1 -b .fingerprint %patch936 -p1 -b .iutf8 %patch937 -p1 -b .pam_uselogin_cve +%patch938 -p1 -b .certificates %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -400,7 +403,7 @@ fi --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ -%ifarch %{ix86} x86_64 %{arm} aarch64 s390x x390 +%ifnarch ppc --with-sandbox=seccomp_filter \ %else --with-sandbox=rlimit \ @@ -549,6 +552,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sun Jun 26 2016 Mattias Ellert - 7.2p2-4 +- Based on openssh-7.2p2-8.fc24 + * Thu May 12 2016 Mattias Ellert - 7.2p2-3 - Based on openssh-7.2p2-5.fc24 diff --git a/openssh-6.6.1p1-localdomain.patch b/openssh-6.6.1p1-localdomain.patch deleted file mode 100644 index 4995171..0000000 --- a/openssh-6.6.1p1-localdomain.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/ssh_config b/ssh_config -index 03a228f..49a4f6c 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -46,3 +46,7 @@ - # VisualHostKey no - # ProxyCommand ssh -q -W %h:%p gateway.example.com - # RekeyLimit 1G 1h -+# -+# Uncomment this if you want to use .local domain -+# Host *.local -+# CheckHostIP no diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index 6076165..9daa63c 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -280,3 +280,13 @@ index cb866b5..adcaaf9 100644 .Sh IPV6 IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. .Sh SEE ALSO +diff -up openssh-6.8p1/openbsd-compat/port-linux.h.coverity openssh-6.8p1/openbsd-compat/port-linux.h +--- openssh-6.8p1/openbsd-compat/port-linux.h.coverity 2015-03-18 17:21:51.861264906 +0100 ++++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 17:21:51.897264831 +0100 +@@ -37,4 +37,6 @@ void oom_adjust_restore(void); + void oom_adjust_setup(void); + #endif + ++void linux_seed(void); ++ + #endif /* ! _PORT_LINUX_H */ diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index 12f4a9f..ec73cae 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -2,10 +2,14 @@ diff --git a/ssh_config b/ssh_config index 49a4f6c..3f83c40 100644 --- a/ssh_config +++ b/ssh_config -@@ -50,3 +50,15 @@ - # Uncomment this if you want to use .local domain - # Host *.local - # CheckHostIP no +@@ -46,3 +46,19 @@ + # VisualHostKey no + # ProxyCommand ssh -q -W %h:%p gateway.example.com + # RekeyLimit 1G 1h ++# ++# Uncomment this if you want to use .local domain ++# Host *.local ++# CheckHostIP no + +Host * + GSSAPIAuthentication yes diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 8834903..73fe662 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -48,33 +48,6 @@ diff -up openssh-6.8p1/channels.c.coverity openssh-6.8p1/channels.c set_nonblock(efd); } } -@@ -3972,13 +3972,13 @@ connect_local_xsocket_path(const char *p - int sock; - struct sockaddr_un addr; - -+ if (len <= 0) -+ return -1; - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - error("socket: %.100s", strerror(errno)); - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; -- if (len <= 0) -- return -1; - if (len > sizeof addr.sun_path) - len = sizeof addr.sun_path; - memcpy(addr.sun_path, pathname, len); -diff -up openssh-6.8p1/entropy.c.coverity openssh-6.8p1/entropy.c ---- openssh-6.8p1/entropy.c.coverity 2015-03-18 17:21:51.891264843 +0100 -+++ openssh-6.8p1/entropy.c 2015-03-18 17:21:51.897264831 +0100 -@@ -46,6 +46,7 @@ - #include - - #include "openbsd-compat/openssl-compat.h" -+#include "openbsd-compat/port-linux.h" - - #include "ssh.h" - #include "misc.h" diff -up openssh-6.8p1/monitor.c.coverity openssh-6.8p1/monitor.c --- openssh-6.8p1/monitor.c.coverity 2015-03-18 17:21:51.887264852 +0100 +++ openssh-6.8p1/monitor.c 2015-03-18 17:21:51.897264831 +0100 @@ -137,16 +110,6 @@ diff -up openssh-6.8p1/openbsd-compat/bindresvport.c.coverity openssh-6.8p1/open int i; if (sa == NULL) { -diff -up openssh-6.8p1/openbsd-compat/port-linux.h.coverity openssh-6.8p1/openbsd-compat/port-linux.h ---- openssh-6.8p1/openbsd-compat/port-linux.h.coverity 2015-03-18 17:21:51.861264906 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 17:21:51.897264831 +0100 -@@ -37,4 +37,6 @@ void oom_adjust_restore(void); - void oom_adjust_setup(void); - #endif - -+void linux_seed(void); -+ - #endif /* ! _PORT_LINUX_H */ diff -up openssh-6.8p1/scp.c.coverity openssh-6.8p1/scp.c --- openssh-6.8p1/scp.c.coverity 2015-03-18 17:21:51.868264891 +0100 +++ openssh-6.8p1/scp.c 2015-03-18 17:21:58.281251460 +0100 @@ -436,14 +399,3 @@ diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c } -diff -up openssh-6.8p1/sshkey.c.coverity openssh-6.8p1/sshkey.c ---- openssh-6.8p1/sshkey.c.coverity 2015-03-18 17:21:58.285251452 +0100 -+++ openssh-6.8p1/sshkey.c 2015-03-18 17:45:32.232705363 +0100 -@@ -58,6 +58,7 @@ - #include "digest.h" - #define SSHKEY_INTERNAL - #include "sshkey.h" -+#include "log.h" - #include "match.h" - - /* openssh private key file format */ diff --git a/openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch index 1a88e50..512996b 100644 --- a/openssh-6.7p1-sftp-force-permission.patch +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -1,6 +1,6 @@ -diff -up openssh-6.8p1/sftp-server.8.sftp-force-mode openssh-6.8p1/sftp-server.8 ---- openssh-6.8p1/sftp-server.8.sftp-force-mode 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sftp-server.8 2015-03-18 13:18:05.898306477 +0100 +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 blacklisted_requests .Op Fl p Ar whitelisted_requests @@ -20,10 +20,10 @@ diff -up openssh-6.8p1/sftp-server.8.sftp-force-mode openssh-6.8p1/sftp-server.8 .El .Pp On some systems, -diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c ---- openssh-6.8p1/sftp-server.c.sftp-force-mode 2015-03-18 13:18:05.883306513 +0100 -+++ openssh-6.8p1/sftp-server.c 2015-03-18 13:18:36.697232193 +0100 -@@ -70,6 +70,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; @@ -34,18 +34,35 @@ diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c /* SSH2_FXP_INIT received */ static int init_done; -@@ -693,6 +697,10 @@ 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; ++ mode_t old_umask; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ +@@ -692,6 +697,10 @@ process_open(u_int32_t id) debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; + if (permforce == 1) { /* Force perm if -m is set */ + mode = permforcemode; -+ (void)umask(0); /* so umask does not interfere */ ++ old_umask = umask(0); /* so umask does not interfere */ + } logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && -@@ -1495,7 +1503,7 @@ sftp_server_usage(void) +@@ -713,6 +722,8 @@ process_open(u_int32_t id) + } + } + } ++ if (permforce == 1) ++ (void) umask(old_umask); /* restore umask to something sane */ + if (status != SSH2_FX_OK) + send_status(id, status); + free(name); +@@ -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 blacklisted_requests] " @@ -54,7 +71,7 @@ diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c " %s -Q protocol_feature\n", __progname, __progname); exit(1); -@@ -1520,7 +1528,7 @@ sftp_server_main(int argc, char **argv, +@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv, pw = pwcopy(user_pw); while (!skipargs && (ch = getopt(argc, argv, @@ -63,7 +80,7 @@ diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c switch (ch) { case 'Q': if (strcasecmp(optarg, "requests") != 0) { -@@ -1580,6 +1588,15 @@ sftp_server_main(int argc, char **argv, +@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv, fatal("Invalid umask \"%s\"", optarg); (void)umask((mode_t)mask); break; diff --git a/openssh-6.9p1-seccomp-secondary.patch b/openssh-6.9p1-seccomp-secondary.patch index 97e16d2..dce205d 100644 --- a/openssh-6.9p1-seccomp-secondary.patch +++ b/openssh-6.9p1-seccomp-secondary.patch @@ -1,22 +1,8 @@ -diff -up openssh/configure.ac.seccomp openssh/configure.ac -diff -up openssh/sandbox-seccomp-filter.c.seccomp openssh/sandbox-seccomp-filter.c ---- openssh/sandbox-seccomp-filter.c.seccomp 2015-06-24 11:45:44.001581471 +0200 -+++ openssh/sandbox-seccomp-filter.c 2015-06-24 11:51:54.032635297 +0200 -@@ -165,6 +165,9 @@ static const struct sock_filter preauth_ - #ifdef __NR__newselect - SC_ALLOW(_newselect), - #endif -+#ifdef __NR_pselect6 /* AArch64 */ -+ SC_ALLOW(pselect6), -+#endif - #ifdef __NR_poll - SC_ALLOW(poll), - #endif diff --git a/configure.ac b/configure.ac index 24378a7..0bed910 100644 --- a/configure.ac +++ b/configure.ac -@@ -811,6 +811,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -811,6 +811,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) aarch64*-*) seccomp_audit_arch=AUDIT_ARCH_AARCH64 ;; @@ -25,6 +11,24 @@ index 24378a7..0bed910 100644 + ;; + s390-*) + seccomp_audit_arch=AUDIT_ARCH_S390 ++ ;; ++ powerpc64-*) ++ seccomp_audit_arch=AUDIT_ARCH_PPC64 ++ ;; ++ powerpc64le-*) ++ seccomp_audit_arch=AUDIT_ARCH_PPC64LE ++ ;; ++ mips-*) ++ seccomp_audit_arch=AUDIT_ARCH_MIPS ++ ;; ++ mipsel-*) ++ seccomp_audit_arch=AUDIT_ARCH_MIPSEL ++ ;; ++ mips64-*) ++ seccomp_audit_arch=AUDIT_ARCH_MIPS64 ++ ;; ++ mips64el-*) ++ seccomp_audit_arch=AUDIT_ARCH_MIPSEL64 + ;; esac if test "x$seccomp_audit_arch" != "x" ; then diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index b350d18..7050d71 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -628,6 +628,14 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c #endif #include "crypto_api.h" +@@ -58,6 +58,7 @@ + #include "digest.h" + #define SSHKEY_INTERNAL + #include "sshkey.h" ++#include "log.h" + #include "match.h" + + /* openssh private key file format */ @@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || diff --git a/openssh-6.6p1-log-usepam-no.patch b/openssh-7.2p2-UsePAM-UseLogin-warning.patch similarity index 63% rename from openssh-6.6p1-log-usepam-no.patch rename to openssh-7.2p2-UsePAM-UseLogin-warning.patch index bd3048c..bf1999b 100644 --- a/openssh-6.6p1-log-usepam-no.patch +++ b/openssh-7.2p2-UsePAM-UseLogin-warning.patch @@ -1,11 +1,14 @@ diff --git a/sshd.c b/sshd.c -index a7b8b6a..24ab272 100644 --- a/sshd.c +++ b/sshd.c -@@ -1620,6 +1620,10 @@ main(int ac, char **av) +@@ -1701,6 +1701,14 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, &cfg, NULL); ++ /* 'UseLogin yes' is not supported in Fedora */ ++ if (options.use_login) ++ logit("WARNING: 'UseLogin yes' is not supported in Fedora and may cause several problems."); ++ + /* '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."); @@ -14,7 +17,6 @@ index a7b8b6a..24ab272 100644 /* Fill in default values for those options not explicitly set. */ diff --git a/sshd_config b/sshd_config -index 36cb27a..c1b7c03 100644 --- a/sshd_config +++ b/sshd_config @@ -101,6 +101,8 @@ GSSAPICleanupCredentials no @@ -26,3 +28,12 @@ index 36cb27a..c1b7c03 100644 UsePAM yes #AllowAgentForwarding yes +@@ -113,6 +115,8 @@ X11Forwarding yes + #PrintMotd yes + #PrintLastLog yes + #TCPKeepAlive yes ++# WARNING: 'UseLogin yes' is not supported in Fedora and may cause several ++# problems. + #UseLogin no + #UsePrivilegeSeparation sandbox + #PermitUserEnvironment no diff --git a/openssh-7.2p2-certificats-regress.patch b/openssh-7.2p2-certificats-regress.patch new file mode 100644 index 0000000..8b08319 --- /dev/null +++ b/openssh-7.2p2-certificats-regress.patch @@ -0,0 +1,38 @@ +commit c38905ba391434834da86abfc988a2b8b9b62477 +Author: djm@openbsd.org +Date: Mon Mar 14 16:20:54 2016 +0000 + + upstream commit + + unbreak authentication using lone certificate keys in + ssh-agent: when attempting pubkey auth with a certificate, if no separate + private key is found among the keys then try with the certificate key itself. + + bz#2550 reported by Peter Moody + + Upstream-ID: f939cd76d68e6a9a3d1711b5a943d6ed1e623966 + +diff --git a/sshconnect2.c b/sshconnect2.c +index f79c96b..1cf48a2 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: sshconnect2.c,v 1.239 2016/02/23 01:34:14 djm Exp $ */ ++/* $OpenBSD: sshconnect2.c,v 1.240 2016/03/14 16:20:54 djm Exp $ */ + /* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2008 Damien Miller. All rights reserved. +@@ -1112,12 +1112,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) + "certificate", __func__, id->filename, + id->agent_fd != -1 ? " from agent" : ""); + } else { +- /* XXX maybe verbose/error? */ +- debug("%s: no private key for certificate " ++ debug("%s: no separate private key for certificate " + "\"%s\"", __func__, id->filename); +- free(blob); +- buffer_free(&b); +- return 0; + } + } + diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch new file mode 100644 index 0000000..308c452 --- /dev/null +++ b/openssh-7.2p2-k5login_directory.patch @@ -0,0 +1,87 @@ +diff --git a/auth-krb5.c b/auth-krb5.c +index 2b02a04..19b9364 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -375,6 +375,22 @@ cleanup: + return -1; + } + ++/* ++ * Reads k5login_directory option from the krb5.conf ++ */ ++krb5_error_code ++ssh_krb5_get_k5login_directory(krb5_context ctx, char **k5login_directory) { ++ profile_t p; ++ int ret = 0; ++ ++ ret = krb5_get_profile(ctx, &p); ++ if (ret) ++ return ret; ++ ++ return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL, ++ k5login_directory); ++} ++ + krb5_error_code + ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { + profile_t p; +diff --git a/auth.h b/auth.h +index f9d191c..c432d2f 100644 +--- a/auth.h ++++ b/auth.h +@@ -222,5 +222,7 @@ int sys_auth_passwd(Authctxt *, const char *); + #if defined(KRB5) && !defined(HEIMDAL) + #include + krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, ++ char **k5login_directory); + #endif + #endif +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index a7c0c5f..df8cc9a 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists() + { + char file[MAXPATHLEN]; + struct passwd *pw = the_authctxt->pw; ++ char *k5login_directory = NULL; ++ int ret = 0; ++ ++ ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory); ++ 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. ++ */ ++ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); ++ } else { ++ /* If set, the library will look for a local user's k5login file ++ * within the named directory, with a filename corresponding to the ++ * local username. ++ */ ++ snprintf(file, sizeof(file), "%s%s%s", k5login_directory, ++ k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "", ++ pw->pw_name); ++ } ++ 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 5c4f15b..135e290 100644 +--- a/sshd.8 ++++ b/sshd.8 +@@ -806,6 +806,10 @@ rlogin/rsh. + These files enforce GSSAPI/Kerberos authentication access control. + Further details are described in + .Xr ksu 1 . ++The location of the k5login file depends on the configuration option ++.Cm k5login_directory ++in the ++.Xr krb5.conf 5 . + .Pp + .It Pa ~/.ssh/ + This directory is the default location for all user-specific configuration diff --git a/openssh-5.5p1-x11.patch b/openssh-7.2p2-x11.patch similarity index 77% rename from openssh-5.5p1-x11.patch rename to openssh-7.2p2-x11.patch index 70a3c85..09e56e9 100644 --- a/openssh-5.5p1-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -1,7 +1,7 @@ -diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c ---- openssh-5.3p1/channels.c.bz595935 2010-08-12 14:19:28.000000000 +0200 -+++ openssh-5.3p1/channels.c 2010-08-12 14:33:51.000000000 +0200 -@@ -3185,7 +3185,7 @@ x11_create_display_inet(int x11_display_ +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 @@ -10,14 +10,16 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c { int sock; struct sockaddr_un addr; -@@ -3195,11 +3195,14 @@ connect_local_xsocket_path(const char *p + ++ if (len <= 0) ++ return -1; + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) error("socket: %.100s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) -+ if (len <= 0) -+ return -1; + if (len > sizeof addr.sun_path) + len = sizeof addr.sun_path; + memcpy(addr.sun_path, pathname, len); @@ -28,7 +30,7 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c return -1; } -@@ -3207,8 +3210,18 @@ static int +@@ -4012,8 +4015,18 @@ static int connect_local_xsocket(u_int dnr) { char buf[1024]; From 1ad3d9f3435a82b03644553cf697caf0d05aa84d Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 3 Jul 2016 07:48:50 +0200 Subject: [PATCH 029/146] Based on openssh-7.2p2-9.fc24 --- gsi-openssh.spec | 5 ++++- openssh-7.2p2-UsePAM-UseLogin-warning.patch | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index eada75f..d3da3a3 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.2p2 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -552,6 +552,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sun Jul 03 2016 Mattias Ellert - 7.2p2-5 +- Based on openssh-7.2p2-9.fc24 + * Sun Jun 26 2016 Mattias Ellert - 7.2p2-4 - Based on openssh-7.2p2-8.fc24 diff --git a/openssh-7.2p2-UsePAM-UseLogin-warning.patch b/openssh-7.2p2-UsePAM-UseLogin-warning.patch index bf1999b..9d01df9 100644 --- a/openssh-7.2p2-UsePAM-UseLogin-warning.patch +++ b/openssh-7.2p2-UsePAM-UseLogin-warning.patch @@ -6,7 +6,7 @@ diff --git a/sshd.c b/sshd.c &cfg, NULL); + /* 'UseLogin yes' is not supported in Fedora */ -+ if (options.use_login) ++ if (options.use_login == 1) + logit("WARNING: 'UseLogin yes' is not supported in Fedora and may cause several problems."); + + /* 'UsePAM no' is not supported in Fedora */ From 0bd6bf86e4246fac4e0505b05c37a835eebad67e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 18 Jul 2016 20:30:44 +0200 Subject: [PATCH 030/146] Based on openssh-7.2p2-10.fc24 --- gsi-openssh.spec | 17 +- openssh-7.2p1-audit.patch | 6 +- openssh-7.2p1-fips.patch | 2 +- openssh-7.2p2-expose-pam.patch | 517 +++++++++++++++++++++++++++ openssh-7.2p2-gsissh.patch | 19 +- openssh-7.2p2-s390-closefrom.patch | 52 +++ openssh-7.2p2-user-enumeration.patch | 215 +++++++++++ 7 files changed, 815 insertions(+), 13 deletions(-) create mode 100644 openssh-7.2p2-expose-pam.patch create mode 100644 openssh-7.2p2-s390-closefrom.patch create mode 100644 openssh-7.2p2-user-enumeration.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d3da3a3..58f8aba 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.2p2 -%global openssh_rel 5 +%global openssh_rel 6 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -177,6 +177,15 @@ Patch936: openssh-7.1p1-iutf8.patch Patch937: openssh-7.2p2-CVE-2015-8325.patch # Regression in certificate based authentication (#1333498) Patch938: openssh-7.2p2-certificats-regress.patch +# make s390 use /dev/ crypto devices -- ignore closefrom +Patch939: openssh-7.2p2-s390-closefrom.patch +# expose more information to PAM +# https://github.com/openssh/openssh-portable/pull/47 +Patch940: openssh-7.2p2-expose-pam.patch +# Prevent user enumeration via covert timing channel (#1357443) +# https://github.com/openssh/openssh-portable/commit/9286875a +# https://github.com/openssh/openssh-portable/commit/283b97ff +Patch941: openssh-7.2p2-user-enumeration.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -337,6 +346,9 @@ This version of OpenSSH has been modified to support GSI authentication. %patch936 -p1 -b .iutf8 %patch937 -p1 -b .pam_uselogin_cve %patch938 -p1 -b .certificates +%patch939 -p1 -b .s390-dev +%patch940 -p1 -b .expose-pam +%patch941 -p1 -b .user-enumeration %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -552,6 +564,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Jul 18 2016 Mattias Ellert - 7.2p2-6 +- Based on openssh-7.2p2-10.fc24 + * Sun Jul 03 2016 Mattias Ellert - 7.2p2-5 - Based on openssh-7.2p2-9.fc24 diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index 43798ab..35bed50 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -792,9 +792,9 @@ diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) + buffer_len(&b))) == 1) { authenticated = 1; - + authctxt->last_details = pubkey; @@ -163,6 +163,18 @@ done: return authenticated; } @@ -825,7 +825,7 @@ diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c + PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; - /* Record the successful key to prevent reuse */ + authctxt->last_details = pubkey; @@ -258,6 +258,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index 7050d71..f9fc406 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -634,8 +634,8 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c #include "sshkey.h" +#include "log.h" #include "match.h" + #include "xmalloc.h" - /* openssh private key file format */ @@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch new file mode 100644 index 0000000..49f6436 --- /dev/null +++ b/openssh-7.2p2-expose-pam.patch @@ -0,0 +1,517 @@ +diff -up openssh-7.2p2/auth2.c.expose-pam openssh-7.2p2/auth2.c +--- openssh-7.2p2/auth2.c.expose-pam 2016-07-18 12:30:12.064783302 +0200 ++++ openssh-7.2p2/auth2.c 2016-07-18 12:30:12.124783255 +0200 +@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int + const char *submethod) + { + char *methods; ++ char *prev_auth_details; + int partial = 0; + + if (!authctxt->valid && authenticated) +@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int + if (authctxt->postponed) + return; + ++ if (authenticated || partial) { ++ prev_auth_details = authctxt->auth_details; ++ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", ++ prev_auth_details ? prev_auth_details : "", ++ prev_auth_details ? ", " : "", method, ++ authctxt->last_details ? ": " : "", ++ authctxt->last_details ? authctxt->last_details : ""); ++ free(prev_auth_details); ++ } ++ free(authctxt->last_details); ++ authctxt->last_details = NULL; ++ + #ifdef USE_PAM + if (options.use_pam && authenticated) { + if (!PRIVSEP(do_pam_account())) { +diff -up openssh-7.2p2/auth2-gss.c.expose-pam openssh-7.2p2/auth2-gss.c +--- openssh-7.2p2/auth2-gss.c.expose-pam 2016-07-18 12:30:12.123783256 +0200 ++++ openssh-7.2p2/auth2-gss.c 2016-07-18 12:32:08.034692086 +0200 +@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); + ++ if (authenticated) ++ authctxt->last_details = ssh_gssapi_get_displayname(); ++ + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); +@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple + else + logit("GSSAPI MIC check failed"); + ++ if (authenticated) ++ authctxt->last_details = ssh_gssapi_get_displayname(); ++ + buffer_free(&b); + if (micuser != authctxt->user) + free(micuser); +diff -up openssh-7.2p2/auth2-hostbased.c.expose-pam openssh-7.2p2/auth2-hostbased.c +--- openssh-7.2p2/auth2-hostbased.c.expose-pam 2016-07-18 12:30:12.027783331 +0200 ++++ openssh-7.2p2/auth2-hostbased.c 2016-07-18 12:30:12.124783255 +0200 +@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) + { + Buffer b; + Key *key = NULL; +- char *pkalg, *cuser, *chost, *service; ++ char *pkalg, *cuser, *chost, *service, *pubkey; + u_char *pkblob, *sig; + u_int alen, blen, slen; + int pktype; +@@ -140,15 +140,21 @@ userauth_hostbased(Authctxt *authctxt) + buffer_dump(&b); + #endif + +- pubkey_auth_info(authctxt, key, +- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); ++ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); ++ auth_info(authctxt, ++ "%s, client user \"%.100s\", client host \"%.100s\"", ++ pubkey, cuser, chost); + + /* test for allowed key and correct signature */ + authenticated = 0; + if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && + PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), +- buffer_len(&b))) == 1) ++ buffer_len(&b))) == 1) { + authenticated = 1; ++ authctxt->last_details = pubkey; ++ } else { ++ free(pubkey); ++ } + + buffer_free(&b); + done: +diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c +--- openssh-7.2p2/auth2-pubkey.c.expose-pam 2016-07-18 12:30:12.039783322 +0200 ++++ openssh-7.2p2/auth2-pubkey.c 2016-07-18 12:30:12.124783255 +0200 +@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) + { + Buffer b; + Key *key = NULL; +- char *pkalg, *userstyle, *fp = NULL; ++ char *pkalg, *userstyle, *pubkey, *fp = NULL; + u_char *pkblob, *sig; + u_int alen, blen, slen; + int have_sig, pktype; +@@ -173,7 +173,8 @@ userauth_pubkey(Authctxt *authctxt) + #ifdef DEBUG_PK + buffer_dump(&b); + #endif +- pubkey_auth_info(authctxt, key, NULL); ++ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); ++ auth_info(authctxt, "%s", pubkey); + + /* test for correct signature */ + authenticated = 0; +@@ -181,9 +182,12 @@ userauth_pubkey(Authctxt *authctxt) + PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) { + authenticated = 1; ++ authctxt->last_details = pubkey; + /* Record the successful key to prevent reuse */ + auth2_record_userkey(authctxt, key); + key = NULL; /* Don't free below */ ++ } else { ++ free(pubkey); + } + buffer_free(&b); + free(sig); +@@ -224,7 +228,7 @@ done: + void + pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) + { +- char *fp, *extra; ++ char *extra, *pubkey; + va_list ap; + int i; + +@@ -234,27 +238,13 @@ pubkey_auth_info(Authctxt *authctxt, con + i = vasprintf(&extra, fmt, ap); + va_end(ap); + if (i < 0 || extra == NULL) +- fatal("%s: vasprintf failed", __func__); ++ fatal("%s: vasprintf failed", __func__); + } + +- if (key_is_cert(key)) { +- fp = sshkey_fingerprint(key->cert->signature_key, +- options.fingerprint_hash, SSH_FP_DEFAULT); +- auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", +- key_type(key), key->cert->key_id, +- (unsigned long long)key->cert->serial, +- key_type(key->cert->signature_key), +- fp == NULL ? "(null)" : fp, +- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); +- free(fp); +- } else { +- fp = sshkey_fingerprint(key, options.fingerprint_hash, +- SSH_FP_DEFAULT); +- auth_info(authctxt, "%s %s%s%s", key_type(key), +- fp == NULL ? "(null)" : fp, +- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); +- free(fp); +- } ++ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); ++ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", ++ extra == NULL ? "" : extra); ++ free(pubkey); + free(extra); + } + +diff -up openssh-7.2p2/auth.h.expose-pam openssh-7.2p2/auth.h +--- openssh-7.2p2/auth.h.expose-pam 2016-07-18 12:30:12.077783292 +0200 ++++ openssh-7.2p2/auth.h 2016-07-18 12:30:12.123783256 +0200 +@@ -84,6 +84,9 @@ struct Authctxt { + + struct sshkey **prev_userkeys; + u_int nprev_userkeys; ++ ++ char *last_details; ++ char *auth_details; + }; + /* + * Every authentication method has to handle authentication requests for +diff -up openssh-7.2p2/auth-pam.c.expose-pam openssh-7.2p2/auth-pam.c +--- openssh-7.2p2/auth-pam.c.expose-pam 2016-07-18 12:30:12.026783332 +0200 ++++ openssh-7.2p2/auth-pam.c 2016-07-18 12:30:12.123783256 +0200 +@@ -689,6 +689,11 @@ sshpam_init_ctx(Authctxt *authctxt) + return (NULL); + } + ++ /* Notify PAM about any already successful auth methods */ ++ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY && ++ authctxt->auth_details) ++ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); ++ + ctxt = xcalloc(1, sizeof *ctxt); + + /* Start the authentication thread */ +diff -up openssh-7.2p2/gss-serv.c.expose-pam openssh-7.2p2/gss-serv.c +--- openssh-7.2p2/gss-serv.c.expose-pam 2016-07-18 12:30:12.124783255 +0200 ++++ openssh-7.2p2/gss-serv.c 2016-07-18 12:33:08.835644264 +0200 +@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int + } + + /* Privileged */ ++char* ++ssh_gssapi_get_displayname(void) ++{ ++ if (gssapi_client.displayname.length != 0 && ++ gssapi_client.displayname.value != NULL) ++ return strdup((char *)gssapi_client.displayname.value); ++ return NULL; ++} ++ ++/* Privileged */ + int + ssh_gssapi_userok(char *user, struct passwd *pw) + { +diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c +--- openssh-7.2p2/monitor.c.expose-pam 2016-07-18 12:30:12.093783279 +0200 ++++ openssh-7.2p2/monitor.c 2016-07-18 12:30:12.124783255 +0200 +@@ -349,6 +349,7 @@ monitor_child_preauth(Authctxt *_authctx + { + struct mon_table *ent; + int authenticated = 0, partial = 0; ++ char *prev_auth_details; + + debug3("preauth child monitor started"); + +@@ -386,6 +387,18 @@ monitor_child_preauth(Authctxt *_authctx + auth_submethod = NULL; + authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); + ++ if (authenticated) { ++ prev_auth_details = authctxt->auth_details; ++ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", ++ prev_auth_details ? prev_auth_details : "", ++ prev_auth_details ? ", " : "", auth_method, ++ authctxt->last_details ? ": " : "", ++ authctxt->last_details ? authctxt->last_details : ""); ++ free(prev_auth_details); ++ } ++ free(authctxt->last_details); ++ authctxt->last_details = NULL; ++ + /* Special handling for multiple required authentications */ + if (options.num_auth_methods != 0) { + if (!compat20) +@@ -1498,6 +1511,10 @@ mm_answer_keyverify(int sock, Buffer *m) + debug3("%s: key %p signature %s", + __func__, key, (verified == 1) ? "verified" : "unverified"); + ++ if (verified == 1) ++ authctxt->last_details = sshkey_format_oneline(key, ++ options.fingerprint_hash); ++ + /* If auth was successful then record key to ensure it isn't reused */ + if (verified == 1 && key_blobtype == MM_USERKEY) + auth2_record_userkey(authctxt, key); +@@ -2140,6 +2157,9 @@ mm_answer_gss_userok(int sock, Buffer *m + + auth_method = "gssapi-with-mic"; + ++ if (authenticated) ++ authctxt->last_details = ssh_gssapi_get_displayname(); ++ + /* Monitor loop will terminate if authenticated */ + return (authenticated); + } +diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c +--- openssh-7.2p2/servconf.c.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/servconf.c 2016-07-18 12:34:38.170574004 +0200 +@@ -176,6 +176,7 @@ initialize_server_options(ServerOptions + options->fingerprint_hash = -1; + options->use_kuserok = -1; + options->enable_k5users = -1; ++ options->expose_auth_methods = -1; + } + + /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +@@ -374,6 +375,8 @@ fill_default_server_options(ServerOption + options->enable_k5users = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; ++ if (options->expose_auth_methods == -1) ++ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; + + assemble_algorithms(options); + +@@ -451,6 +454,7 @@ typedef enum { + sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, + sStreamLocalBindMask, sStreamLocalBindUnlink, + sAllowStreamLocalForwarding, sFingerprintHash, ++ sExposeAuthenticationMethods, + sDeprecated, sUnsupported + } ServerOpCodes; + +@@ -606,6 +610,7 @@ static struct { + { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, + { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, + { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, ++ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, + { NULL, sBadOption, 0 } + }; + +@@ -994,6 +999,12 @@ static const struct multistate multistat + { "local", FORWARD_LOCAL }, + { NULL, -1 } + }; ++static const struct multistate multistate_exposeauthmeth[] = { ++ { "never", EXPOSE_AUTHMETH_NEVER }, ++ { "pam-only", EXPOSE_AUTHMETH_PAMONLY }, ++ { "pam-and-env", EXPOSE_AUTHMETH_PAMENV }, ++ { NULL, -1} ++}; + + int + process_server_config_line(ServerOptions *options, char *line, +@@ -1918,6 +1929,11 @@ process_server_config_line(ServerOptions + options->fingerprint_hash = value; + break; + ++ case sExposeAuthenticationMethods: ++ intptr = &options->expose_auth_methods; ++ multistate_ptr = multistate_exposeauthmeth; ++ goto parse_multistate; ++ + case sDeprecated: + logit("%s line %d: Deprecated option %s", + filename, linenum, arg); +@@ -2076,6 +2092,7 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(enable_k5users); + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); ++ M_CP_INTOPT(expose_auth_methods); + + /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ + #define M_CP_STROPT(n) do {\ +@@ -2181,6 +2198,8 @@ fmt_intarg(ServerOpCodes code, int val) + return fmt_multistate_int(val, multistate_tcpfwd); + case sFingerprintHash: + return ssh_digest_alg_name(val); ++ case sExposeAuthenticationMethods: ++ return fmt_multistate_int(val, multistate_exposeauthmeth); + case sProtocol: + switch (val) { + case SSH_PROTO_1: +@@ -2374,6 +2393,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); ++ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff -up openssh-7.2p2/servconf.h.expose-pam openssh-7.2p2/servconf.h +--- openssh-7.2p2/servconf.h.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/servconf.h 2016-07-18 12:30:12.125783254 +0200 +@@ -48,6 +48,11 @@ + #define FORWARD_LOCAL (1<<1) + #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) + ++/* Expose AuthenticationMethods */ ++#define EXPOSE_AUTHMETH_NEVER 0 ++#define EXPOSE_AUTHMETH_PAMONLY 1 ++#define EXPOSE_AUTHMETH_PAMENV 2 ++ + #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ + #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ + +@@ -201,6 +206,8 @@ typedef struct { + char *auth_methods[MAX_AUTH_METHODS]; + + int fingerprint_hash; ++ ++ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ + } ServerOptions; + + /* Information about the incoming connection as used by Match */ +diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c +--- openssh-7.2p2/session.c.expose-pam 2016-07-18 12:30:12.120783258 +0200 ++++ openssh-7.2p2/session.c 2016-07-18 12:30:12.125783254 +0200 +@@ -1180,6 +1180,12 @@ copy_environment(char **source, char *** + } + *var_val++ = '\0'; + ++ if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV && ++ strcmp(var_name, "SSH_USER_AUTH") == 0) { ++ free(var_name); ++ continue; ++ } ++ + debug3("Copy environment: %s=%s", var_name, var_val); + child_set_env(env, envsize, var_name, var_val); + +@@ -1359,6 +1365,11 @@ do_setup_env(Session *s, const char *she + } + #endif /* USE_PAM */ + ++ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV && ++ s->authctxt->auth_details) ++ child_set_env(&env, &envsize, "SSH_USER_AUTH", ++ s->authctxt->auth_details); ++ + if (auth_sock_name != NULL) + child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, + auth_sock_name); +@@ -2798,6 +2809,9 @@ do_cleanup(Authctxt *authctxt) + if (authctxt == NULL) + return; + ++ free(authctxt->auth_details); ++ authctxt->auth_details = NULL; ++ + #ifdef USE_PAM + if (options.use_pam) { + sshpam_cleanup(); +diff -up openssh-7.2p2/ssh.1.expose-pam openssh-7.2p2/ssh.1 +--- openssh-7.2p2/ssh.1.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/ssh.1 2016-07-18 12:30:12.126783253 +0200 +@@ -1396,6 +1396,10 @@ server IP address, and server port numbe + This variable contains the original command line if a forced command + is executed. + It can be used to extract the original arguments. ++.It Ev SSH_USER_AUTH ++This variable contains, for SSH2 only, a comma-separated list of authentication ++methods that were successfuly used to authenticate. When possible, these ++methods are extended with detailed information on the credential used. + .It Ev SSH_TTY + This is set to the name of the tty (path to the device) associated + with the current shell or command. +diff -up openssh-7.2p2/sshd_config.5.expose-pam openssh-7.2p2/sshd_config.5 +--- openssh-7.2p2/sshd_config.5.expose-pam 2016-07-18 12:30:12.113783263 +0200 ++++ openssh-7.2p2/sshd_config.5 2016-07-18 12:30:12.126783253 +0200 +@@ -570,6 +570,21 @@ and finally + See PATTERNS in + .Xr ssh_config 5 + for more information on patterns. ++.It Cm ExposeAuthenticationMethods ++When using SSH2, this option controls the exposure of the list of ++successful authentication methods to PAM during the authentication ++and to the shell environment via the ++.Cm SSH_USER_AUTH ++variable. See the description of this variable for more details. ++Valid options are: ++.Dq never ++(Do not expose successful authentication methods), ++.Dq pam-only ++(Only expose them to PAM during authentication, not afterwards), ++.Dq pam-and-env ++(Expose them to PAM and keep them in the shell environment). ++The default is ++.Dq never . + .It Cm FingerprintHash + Specifies the hash algorithm used when logging key fingerprints. + Valid options are: +diff -up openssh-7.2p2/ssh-gss.h.expose-pam openssh-7.2p2/ssh-gss.h +--- openssh-7.2p2/ssh-gss.h.expose-pam 2016-07-18 12:30:12.125783254 +0200 ++++ openssh-7.2p2/ssh-gss.h 2016-07-18 12:35:01.906555328 +0200 +@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt + const char *); + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); + int ssh_gssapi_userok(char *name, struct passwd *); ++char* ssh_gssapi_get_displayname(void); + 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); +diff -up openssh-7.2p2/sshkey.c.expose-pam openssh-7.2p2/sshkey.c +--- openssh-7.2p2/sshkey.c.expose-pam 2016-07-18 12:30:12.071783296 +0200 ++++ openssh-7.2p2/sshkey.c 2016-07-18 12:30:12.126783253 +0200 +@@ -58,6 +58,7 @@ + #define SSHKEY_INTERNAL + #include "sshkey.h" + #include "match.h" ++#include "xmalloc.h" + + /* openssh private key file format */ + #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" +@@ -1190,6 +1191,30 @@ sshkey_fingerprint(const struct sshkey * + return retval; + } + ++char * ++sshkey_format_oneline(const struct sshkey *key, int dgst_alg) ++{ ++ char *fp, *result; ++ ++ if (sshkey_is_cert(key)) { ++ fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg, ++ SSH_FP_DEFAULT); ++ xasprintf(&result, "%s ID %s (serial %llu) CA %s %s", ++ sshkey_type(key), key->cert->key_id, ++ (unsigned long long)key->cert->serial, ++ sshkey_type(key->cert->signature_key), ++ fp == NULL ? "(null)" : fp); ++ free(fp); ++ } else { ++ fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT); ++ xasprintf(&result, "%s %s", sshkey_type(key), ++ fp == NULL ? "(null)" : fp); ++ free(fp); ++ } ++ ++ return result; ++} ++ + #ifdef WITH_SSH1 + /* + * Reads a multiple-precision integer in decimal from the buffer, and advances +diff -up openssh-7.2p2/sshkey.h.expose-pam openssh-7.2p2/sshkey.h +--- openssh-7.2p2/sshkey.h.expose-pam 2016-07-18 12:30:12.071783296 +0200 ++++ openssh-7.2p2/sshkey.h 2016-07-18 12:30:12.127783252 +0200 +@@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s + int, enum sshkey_fp_rep); + int sshkey_fingerprint_raw(const struct sshkey *k, + int, u_char **retp, size_t *lenp); ++char *sshkey_format_oneline(const struct sshkey *k, int dgst_alg); + const char *sshkey_type(const struct sshkey *); + const char *sshkey_cert_type(const struct sshkey *); + int sshkey_write(const struct sshkey *, FILE *); diff --git a/openssh-7.2p2-gsissh.patch b/openssh-7.2p2-gsissh.patch index ed64b48..771ec18 100644 --- a/openssh-7.2p2-gsissh.patch +++ b/openssh-7.2p2-gsissh.patch @@ -258,8 +258,8 @@ diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c + authenticated = 0; + } - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + if (authenticated) + authctxt->last_details = ssh_gssapi_get_displayname(); @@ -316,9 +368,16 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -522,8 +522,8 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c + sshpam_check_userchanged(); + } sshpam_password = NULL; + free(fake); if (sshpam_err == PAM_SUCCESS && authctxt->valid) { - debug("PAM: password authentication accepted for %.100s", diff -Nur openssh-7.2p1.orig/auth-pam.h openssh-7.2p1/auth-pam.h --- openssh-7.2p1.orig/auth-pam.h 2016-03-02 19:04:36.265961563 +0100 +++ openssh-7.2p1/auth-pam.h 2016-03-02 19:05:41.292212905 +0100 @@ -1523,7 +1523,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2235,12 +2253,77 @@ +@@ -2235,15 +2253,80 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1533,6 +1533,9 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c + else + auth_method = "gssapi-with-mic"; + if (authenticated) + authctxt->last_details = ssh_gssapi_get_displayname(); + /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2319,9 +2322,9 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 --- openssh-7.2p1.orig/sshd_config.5 2016-03-02 19:04:36.367960389 +0100 +++ openssh-7.2p1/sshd_config.5 2016-03-02 19:07:15.338130138 +0100 @@ -570,6 +570,15 @@ - See PATTERNS in - .Xr ssh_config 5 - for more information on patterns. + (Expose them to PAM and keep them in the shell environment). + The default is + .Dq never . +.It Cm DisableUsageStats +This keyword can be followed by one of the keywords "true", "enabled", "yes", +"on" or "1" to disable reporting of usage metrics. Or it can be set to "false", @@ -2973,9 +2976,9 @@ diff -Nur openssh-7.2p1.orig/ssh-gss.h openssh-7.2p1/ssh-gss.h OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -int ssh_gssapi_userok(char *name, struct passwd *); +int ssh_gssapi_userok(char *name, struct passwd *, int gssapi_keyex); + char* ssh_gssapi_get_displayname(void); 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); @@ -170,6 +174,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); diff --git a/openssh-7.2p2-s390-closefrom.patch b/openssh-7.2p2-s390-closefrom.patch new file mode 100644 index 0000000..301a523 --- /dev/null +++ b/openssh-7.2p2-s390-closefrom.patch @@ -0,0 +1,52 @@ +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 + +--- + openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +--- a/openbsd-compat/bsd-closefrom.c ++++ b/openbsd-compat/bsd-closefrom.c +@@ -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)) ++#ifdef __s390__ ++ { ++ /* ++ * the filedescriptors used to communicate with ++ * the device drivers to provide hardware support ++ * should survive. HF ++ */ ++ char fpath[PATH_MAX], lpath[PATH_MAX]; ++ len = snprintf(fpath, sizeof(fpath), "%s/%s", ++ fdpath, dent->d_name); ++ if (len > 0 && (size_t)len <= sizeof(fpath)) { ++ len = readlink(fpath, lpath, sizeof(lpath)); ++ if (len > 0) { ++ lpath[len] = 0; ++ if (strstr(lpath, "dev/z90crypt") ++ || strstr(lpath, "dev/zcrypt") ++ || strstr(lpath, "dev/prandom") ++ || strstr(lpath, "dev/shm/icastats")) ++ fd = -1; ++ } ++ } ++ if (fd >= 0) ++ (void) close((int) fd); ++ } ++#else + (void) close((int) fd); ++#endif + } + (void) closedir(dirp); + } else + diff --git a/openssh-7.2p2-user-enumeration.patch b/openssh-7.2p2-user-enumeration.patch new file mode 100644 index 0000000..91ccccf --- /dev/null +++ b/openssh-7.2p2-user-enumeration.patch @@ -0,0 +1,215 @@ +From 9286875a73b2de7736b5e50692739d314cd8d9dc Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Fri, 15 Jul 2016 13:32:45 +1000 +Subject: [PATCH] Determine appropriate salt for invalid users. + +When sshd is processing a non-PAM login for a non-existent user it uses +the string from the fakepw structure as the salt for crypt(3)ing the +password supplied by the client. That string has a Blowfish prefix, so on +systems that don't understand that crypt will fail fast due to an invalid +salt, and even on those that do it may have significantly different timing +from the hash methods used for real accounts (eg sha512). This allows +user enumeration by, eg, sending large password strings. This was noted +by EddieEzra.Harari at verint.com (CVE-2016-6210). + +To mitigate, use the same hash algorithm that root uses for hashing +passwords for users that do not exist on the system. ok djm@ +--- + auth-passwd.c | 12 ++++++++---- + openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 42 insertions(+), 4 deletions(-) + +diff --git a/auth-passwd.c b/auth-passwd.c +index 63ccf3c..530b5d4 100644 +--- a/auth-passwd.c ++++ b/auth-passwd.c +@@ -193,7 +193,7 @@ int + sys_auth_passwd(Authctxt *authctxt, const char *password) + { + struct passwd *pw = authctxt->pw; +- char *encrypted_password; ++ char *encrypted_password, *salt = NULL; + + /* Just use the supplied fake password if authctxt is invalid */ + char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; +@@ -202,9 +202,13 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) + if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) + return (1); + +- /* Encrypt the candidate password using the proper salt. */ +- encrypted_password = xcrypt(password, +- (pw_password[0] && pw_password[1]) ? pw_password : "xx"); ++ /* ++ * Encrypt the candidate password using the proper salt, or pass a ++ * NULL and let xcrypt pick one. ++ */ ++ if (authctxt->valid && pw_password[0] && pw_password[1]) ++ salt = pw_password; ++ encrypted_password = xcrypt(password, salt); + + /* + * Authentication is accepted if the encrypted passwords +diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c +index 8577cbd..8913bb8 100644 +--- a/openbsd-compat/xcrypt.c ++++ b/openbsd-compat/xcrypt.c +@@ -25,6 +25,7 @@ + #include "includes.h" + + #include ++#include + #include + #include + +@@ -62,11 +63,44 @@ + # define crypt DES_crypt + # endif + ++/* ++ * Pick an appropriate password encryption type and salt for the running ++ * system. ++ */ ++static const char * ++pick_salt(void) ++{ ++ struct passwd *pw; ++ char *passwd, *p; ++ size_t typelen; ++ static char salt[32]; ++ ++ if (salt[0] != '\0') ++ return salt; ++ strlcpy(salt, "xx", sizeof(salt)); ++ if ((pw = getpwuid(0)) == NULL) ++ return salt; ++ passwd = shadow_pw(pw); ++ if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL) ++ return salt; /* no $, DES */ ++ typelen = p - passwd + 1; ++ strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); ++ explicit_bzero(passwd, strlen(passwd)); ++ return salt; ++} ++ + char * + xcrypt(const char *password, const char *salt) + { + char *crypted; + ++ /* ++ * If we don't have a salt we are encrypting a fake password for ++ * for timing purposes. Pick an appropriate salt. ++ */ ++ if (salt == NULL) ++ salt = pick_salt(); ++ + # ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + +From 283b97ff33ea2c641161950849931bd578de6946 Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Fri, 15 Jul 2016 13:49:44 +1000 +Subject: [PATCH] Mitigate timing of disallowed users PAM logins. + +When sshd decides to not allow a login (eg PermitRootLogin=no) and +it's using PAM, it sends a fake password to PAM so that the timing for +the failure is not noticeably different whether or not the password +is correct. This behaviour can be detected by sending a very long +password string which is slower to hash than the fake password. + +Mitigate by constructing an invalid password that is the same length +as the one from the client and thus takes the same time to hash. +Diff from djm@ +--- + auth-pam.c | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/auth-pam.c b/auth-pam.c +index 451de78..465b5a7 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -232,7 +232,6 @@ static int sshpam_account_status = -1; + static char **sshpam_env = NULL; + static Authctxt *sshpam_authctxt = NULL; + static const char *sshpam_password = NULL; +-static char badpw[] = "\b\n\r\177INCORRECT"; + + /* Some PAM implementations don't implement this */ + #ifndef HAVE_PAM_GETENVLIST +@@ -795,12 +794,35 @@ sshpam_query(void *ctx, char **name, char **info, + return (-1); + } + ++/* ++ * Returns a junk password of identical length to that the user supplied. ++ * Used to mitigate timing attacks against crypt(3)/PAM stacks that ++ * vary processing time in proportion to password length. ++ */ ++static char * ++fake_password(const char *wire_password) ++{ ++ const char junk[] = "\b\n\r\177INCORRECT"; ++ char *ret = NULL; ++ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; ++ ++ if (l >= INT_MAX) ++ fatal("%s: password length too long: %zu", __func__, l); ++ ++ ret = malloc(l + 1); ++ for (i = 0; i < l; i++) ++ ret[i] = junk[i % (sizeof(junk) - 1)]; ++ ret[i] = '\0'; ++ return ret; ++} ++ + /* XXX - see also comment in auth-chall.c:verify_response */ + static int + sshpam_respond(void *ctx, u_int num, char **resp) + { + Buffer buffer; + struct pam_ctxt *ctxt = ctx; ++ char *fake; + + debug2("PAM: %s entering, %u responses", __func__, num); + switch (ctxt->pam_done) { +@@ -821,8 +843,11 @@ sshpam_respond(void *ctx, u_int num, char **resp) + (sshpam_authctxt->pw->pw_uid != 0 || + options.permit_root_login == PERMIT_YES)) + buffer_put_cstring(&buffer, *resp); +- else +- buffer_put_cstring(&buffer, badpw); ++ else { ++ fake = fake_password(*resp); ++ buffer_put_cstring(&buffer, fake); ++ free(fake); ++ } + if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { + buffer_free(&buffer); + return (-1); +@@ -1166,6 +1191,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + { + int flags = (options.permit_empty_passwd == 0 ? + PAM_DISALLOW_NULL_AUTHTOK : 0); ++ char *fake = NULL; + + if (!options.use_pam || sshpam_handle == NULL) + fatal("PAM: %s called when PAM disabled or failed to " +@@ -1181,7 +1207,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + */ + if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && + options.permit_root_login != PERMIT_YES)) +- sshpam_password = badpw; ++ sshpam_password = fake = fake_password(password); + + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&passwd_conv); +@@ -1191,6 +1217,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + + sshpam_err = pam_authenticate(sshpam_handle, flags); + sshpam_password = NULL; ++ free(fake); + if (sshpam_err == PAM_SUCCESS && authctxt->valid) { + debug("PAM: password authentication accepted for %.100s", + authctxt->user); + From a0915d8c5e0869e35aac3ad354e1160c65e067d1 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 15 Aug 2016 16:22:23 +0200 Subject: [PATCH 031/146] Based on openssh-7.3p1-3.fc25 --- gsi-openssh.spec | 55 +- openssh-5.8p1-packet.patch | 6 +- openssh-6.1p1-gssapi-canohost.patch | 2 +- openssh-6.6.1p1-log-in-chroot.patch | 2 +- openssh-6.6.1p1-servconf-parser.patch | 12 - openssh-6.6.1p1-utf8-banner.patch | 970 ------------------ openssh-6.6p1-allow-ip-opts.patch | 31 +- openssh-6.6p1-ctr-cavstest.patch | 2 +- openssh-6.6p1-entropy.patch | 2 +- openssh-6.6p1-keycat.patch | 48 +- openssh-6.6p1-kuserok.patch | 2 +- openssh-6.6p1-redhat.patch | 15 +- openssh-6.6p1-role-mls.patch | 220 ++-- openssh-6.6p1-set_remote_ipaddr.patch | 84 -- openssh-6.7p1-coverity.patch | 134 +-- openssh-6.9p1-scp-progressmeter.patch | 42 - openssh-6.9p1-seccomp-secondary.patch | 36 - openssh-7.0p1-show-more-fingerprints.patch | 2 +- openssh-7.1p1-iutf8.patch | 31 - openssh-7.2p1-audit.patch | 463 ++++----- openssh-7.2p1-fips.patch | 18 +- openssh-7.2p1-gsskex.patch | 363 +++++-- openssh-7.2p2-CVE-2015-8325.patch | 32 - openssh-7.2p2-certificats-regress.patch | 38 - openssh-7.2p2-chroot-capabilities.patch | 102 ++ openssh-7.2p2-expose-pam.patch | 4 +- openssh-7.2p2-user-enumeration.patch | 215 ---- ...gsissh.patch => openssh-7.3p1-gsissh.patch | 436 ++++---- sources | 2 +- 29 files changed, 1067 insertions(+), 2302 deletions(-) delete mode 100644 openssh-6.6.1p1-servconf-parser.patch delete mode 100644 openssh-6.6.1p1-utf8-banner.patch delete mode 100644 openssh-6.6p1-set_remote_ipaddr.patch delete mode 100644 openssh-6.9p1-scp-progressmeter.patch delete mode 100644 openssh-6.9p1-seccomp-secondary.patch delete mode 100644 openssh-7.1p1-iutf8.patch delete mode 100644 openssh-7.2p2-CVE-2015-8325.patch delete mode 100644 openssh-7.2p2-certificats-regress.patch create mode 100644 openssh-7.2p2-chroot-capabilities.patch delete mode 100644 openssh-7.2p2-user-enumeration.patch rename openssh-7.2p2-gsissh.patch => openssh-7.3p1-gsissh.patch (89%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 58f8aba..32b9d2f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.2p2 -%global openssh_rel 6 +%global openssh_ver 7.3p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -130,16 +130,6 @@ Patch900: openssh-6.1p1-gssapi-canohost.patch Patch901: openssh-6.6p1-kuserok.patch # Use tty allocation for a remote scp (#985650) Patch906: openssh-6.4p1-fromto-remote.patch -# set a client's address right after a connection is set -# http://bugzilla.mindrot.org/show_bug.cgi?id=2257 -Patch911: openssh-6.6p1-set_remote_ipaddr.patch -# apply RFC3454 stringprep to banners when possible -# https://bugzilla.mindrot.org/show_bug.cgi?id=2058 -# slightly changed patch from comment 10 -Patch912: openssh-6.6.1p1-utf8-banner.patch -# fix parsing of empty options in sshd_conf -# https://bugzilla.mindrot.org/show_bug.cgi?id=2281 -Patch914: openssh-6.6.1p1-servconf-parser.patch # privsep_preauth: use SELinux context from selinux-policy (#1008580) Patch916: openssh-6.6.1p1-selinux-contexts.patch # use different values for DH for Cisco servers (#1026430) @@ -155,8 +145,6 @@ Patch920: openssh-6.6.1p1-ip-port-config-parser.patch Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.patch # apply upstream patch and make sshd -T more consistent (#1187521) Patch922: openssh-6.8p1-sshdT-output.patch -# Seccomp support for secondary architectures (#1195065) -Patch924: openssh-6.9p1-seccomp-secondary.patch # Add sftp option to force mode of created files (#1191055) Patch926: openssh-6.7p1-sftp-force-permission.patch # Memory problems @@ -164,32 +152,21 @@ Patch926: openssh-6.7p1-sftp-force-permission.patch Patch928: openssh-6.8p1-memory-problems.patch # Restore compatible default (#89216) Patch929: openssh-6.9p1-permit-root-login.patch -# Handle terminal control characters in scp progressmeter (#1247204) -Patch931: openssh-6.9p1-scp-progressmeter.patch # Add GSSAPIKexAlgorithms option for server and client application Patch932: openssh-7.0p1-gssKexAlgorithms.patch # Possibility to validate legacy systems by more fingerprints (#1249626)(#2439) Patch933: openssh-7.0p1-show-more-fingerprints.patch -# Preserve IUTF8 tty mode flag over ssh connections (#1270248) -# https://bugzilla.mindrot.org/show_bug.cgi?id=2477 -Patch936: openssh-7.1p1-iutf8.patch -# CVE-2015-8325: ignore PAM environment vars when UseLogin=yes -Patch937: openssh-7.2p2-CVE-2015-8325.patch -# Regression in certificate based authentication (#1333498) -Patch938: openssh-7.2p2-certificats-regress.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch # expose more information to PAM # https://github.com/openssh/openssh-portable/pull/47 Patch940: openssh-7.2p2-expose-pam.patch -# Prevent user enumeration via covert timing channel (#1357443) -# https://github.com/openssh/openssh-portable/commit/9286875a -# https://github.com/openssh/openssh-portable/commit/283b97ff -Patch941: openssh-7.2p2-user-enumeration.patch +# Rework SELinux context handling with chroot (#1357860) +Patch942: openssh-7.2p2-chroot-capabilities.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch -Patch98: openssh-7.2p2-gsissh.patch +Patch98: openssh-7.3p1-gsissh.patch License: BSD Group: Applications/Internet @@ -207,6 +184,7 @@ BuildRequires: pam-devel BuildRequires: tcp_wrappers-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j +BuildRequires: libcap-ng-devel %if %{kerberos5} BuildRequires: krb5-devel @@ -325,9 +303,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok %patch906 -p1 -b .fromto-remote -%patch911 -p1 -b .set_remote_ipaddr -%patch912 -p1 -b .utf8-banner -%patch914 -p1 -b .servconf %patch916 -p1 -b .contexts #%patch917 -p1 -b .cisco-dh # investigate %patch918 -p1 -b .log-in-chroot @@ -336,19 +311,14 @@ This version of OpenSSH has been modified to support GSI authentication. %patch802 -p1 -b .GSSAPIEnablek5users %patch921 -p1 -b .tcp_wrappers %patch922 -p1 -b .sshdt -%patch924 -p1 -b .seccomp %patch926 -p1 -b .sftp-force-mode %patch928 -p1 -b .memory %patch929 -p1 -b .root-login -%patch931 -p1 -b .progressmeter %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint -%patch936 -p1 -b .iutf8 -%patch937 -p1 -b .pam_uselogin_cve -%patch938 -p1 -b .certificates %patch939 -p1 -b .s390-dev %patch940 -p1 -b .expose-pam -%patch941 -p1 -b .user-enumeration +%patch942 -p1 -b .chroot-cap %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -451,6 +421,7 @@ make SSH_PROGRAM=%{_bindir}/gsissh \ %install rm -rf $RPM_BUILD_ROOT 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%{_libexecdir}/gsissh mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/gsisshd make install DESTDIR=$RPM_BUILD_ROOT @@ -462,6 +433,7 @@ install -d $RPM_BUILD_ROOT%{_libexecdir}/gsissh install -d $RPM_BUILD_ROOT%{_libdir}/fipscheck 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/etc/gsissh/ssh_config.d/05-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 @@ -493,8 +465,6 @@ for f in $RPM_BUILD_ROOT%{_bindir}/* \ $RPM_BUILD_ROOT%{_mandir}/man*/* ; do mv $f `dirname $f`/gsi`basename $f` done -ln -sf gsissh $RPM_BUILD_ROOT%{_bindir}/gsislogin -ln -sf gsissh.1 $RPM_BUILD_ROOT%{_mandir}/man1/gsislogin.1 perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* @@ -537,8 +507,8 @@ getent passwd sshd >/dev/null || \ %attr(0755,root,root) %{_bindir}/gsiscp %attr(0644,root,root) %{_mandir}/man1/gsiscp.1* %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config -%attr(0755,root,root) %{_bindir}/gsislogin -%attr(0644,root,root) %{_mandir}/man1/gsislogin.1* +%dir %attr(0755,root,root) %{_sysconfdir}/gsissh/ssh_config.d/ +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config.d/05-redhat.conf %attr(0644,root,root) %{_mandir}/man5/gsissh_config.5* %attr(0755,root,root) %{_bindir}/gsisftp %attr(0644,root,root) %{_mandir}/man1/gsisftp.1* @@ -564,6 +534,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Aug 15 2016 Mattias Ellert - 7.3p1-1 +- Based on openssh-7.3p1-3.fc25 + * Mon Jul 18 2016 Mattias Ellert - 7.2p2-6 - Based on openssh-7.2p2-10.fc24 diff --git a/openssh-5.8p1-packet.patch b/openssh-5.8p1-packet.patch index baccb53..2389903 100644 --- a/openssh-5.8p1-packet.patch +++ b/openssh-5.8p1-packet.patch @@ -7,6 +7,6 @@ diff -up openssh-6.8p1/packet.c.packet openssh-6.8p1/packet.c + if (!state) + return 0; - /* filedescriptors in and out are the same, so it's a socket */ - if (state->connection_in == state->connection_out) - return 1; + if (state->connection_in == -1 || state->connection_out == -1) + return 0; + diff --git a/openssh-6.1p1-gssapi-canohost.patch b/openssh-6.1p1-gssapi-canohost.patch index eb5c2e6..124ac7f 100644 --- a/openssh-6.1p1-gssapi-canohost.patch +++ b/openssh-6.1p1-gssapi-canohost.patch @@ -12,7 +12,7 @@ diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c gss_host = options.gss_server_identity; - else if (options.gss_trust_dns) + else if (options.gss_trust_dns) { - gss_host = get_canonical_hostname(1); + gss_host = get_canonical_hostname(active_state, 1); + if ( strcmp( gss_host, "UNKNOWN" ) == 0 ) + gss_host = authctxt->host; + } diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 5889005..46d8382 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -247,8 +247,8 @@ diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c - log_init(__progname, log_level, log_facility, log_stderr); + log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); - #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* + * On platforms where we can, avoid making /proc/self/{mem,maps} diff -up openssh-6.8p1/sftp.h.log-in-chroot openssh-6.8p1/sftp.h --- openssh-6.8p1/sftp.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/sftp.h 2015-03-18 12:59:29.696022308 +0100 diff --git a/openssh-6.6.1p1-servconf-parser.patch b/openssh-6.6.1p1-servconf-parser.patch deleted file mode 100644 index 1439e80..0000000 --- a/openssh-6.6.1p1-servconf-parser.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh/servconf.c.servconf openssh/servconf.c ---- openssh/servconf.c.servconf 2015-06-24 11:26:26.186527736 +0200 -+++ openssh/servconf.c 2015-06-24 11:26:39.847493075 +0200 -@@ -1815,6 +1815,8 @@ process_server_config_line(ServerOptions - break; - - case sAuthenticationMethods: -+ if (cp == NULL || *cp == '\0') -+ fatal("%.200s line %d: Missing argument.", filename, linenum); - if (options->num_auth_methods == 0) { - while ((arg = strdelim(&cp)) && *arg != '\0') { - if (options->num_auth_methods >= diff --git a/openssh-6.6.1p1-utf8-banner.patch b/openssh-6.6.1p1-utf8-banner.patch deleted file mode 100644 index 238c654..0000000 --- a/openssh-6.6.1p1-utf8-banner.patch +++ /dev/null @@ -1,970 +0,0 @@ -diff -up openssh-6.8p1/Makefile.in.utf8-banner openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.utf8-banner 2015-03-18 12:41:28.174713188 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 12:45:52.723048114 +0100 -@@ -94,7 +94,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ -- ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ -+ ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o utf8_stringprep.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ -diff -up openssh-6.8p1/misc.h.utf8-banner openssh-6.8p1/misc.h ---- openssh-6.8p1/misc.h.utf8-banner 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/misc.h 2015-03-18 12:41:28.175713185 +0100 -@@ -135,4 +135,8 @@ char *read_passphrase(const char *, int) - int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); - int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); - -+/* utf8_stringprep.c */ -+int utf8_stringprep(const char *, char *, size_t); -+void sanitize_utf8(char *, const char *, size_t); -+ - #endif /* _MISC_H */ -diff -up openssh-6.8p1/sshconnect2.c.utf8-banner openssh-6.8p1/sshconnect2.c ---- openssh-6.8p1/sshconnect2.c.utf8-banner 2015-03-18 12:41:28.161713220 +0100 -+++ openssh-6.8p1/sshconnect2.c 2015-03-18 12:44:05.483317714 +0100 -@@ -532,7 +534,7 @@ input_userauth_error(int type, u_int32_t - if (len > 65536) - len = 65536; - msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ -- strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); -+ sanitize_utf8(msg, raw, len); - fprintf(stderr, "%s", msg); - free(msg); - } -diff -up openssh-6.8p1/stringprep-tables.c.utf8-banner openssh-6.8p1/stringprep-tables.c ---- openssh-6.8p1/stringprep-tables.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 -+++ openssh-6.8p1/stringprep-tables.c 2015-03-18 12:41:28.175713185 +0100 -@@ -0,0 +1,661 @@ -+/* Public domain. */ -+ -+/* $OpenBSD$ */ -+ -+/* -+ * Tables for RFC3454 stringprep algorithm, updated with a table of allocated -+ * characters generated from Unicode.6.2's UnicodeData.txt -+ * -+ * Intended to be included directly from utf8_stringprep.c -+ */ -+ -+/* Unassigned characters in Unicode 6.2 */ -+static const struct u32_range unassigned[] = { -+ { 0x0378, 0x0379 }, -+ { 0x037F, 0x0383 }, -+ { 0x038B, 0x038B }, -+ { 0x038D, 0x038D }, -+ { 0x03A2, 0x03A2 }, -+ { 0x0528, 0x0530 }, -+ { 0x0557, 0x0558 }, -+ { 0x0560, 0x0560 }, -+ { 0x0588, 0x0588 }, -+ { 0x058B, 0x058E }, -+ { 0x0590, 0x0590 }, -+ { 0x05C8, 0x05CF }, -+ { 0x05EB, 0x05EF }, -+ { 0x05F5, 0x05FF }, -+ { 0x0605, 0x0605 }, -+ { 0x061C, 0x061D }, -+ { 0x070E, 0x070E }, -+ { 0x074B, 0x074C }, -+ { 0x07B2, 0x07BF }, -+ { 0x07FB, 0x07FF }, -+ { 0x082E, 0x082F }, -+ { 0x083F, 0x083F }, -+ { 0x085C, 0x085D }, -+ { 0x085F, 0x089F }, -+ { 0x08A1, 0x08A1 }, -+ { 0x08AD, 0x08E3 }, -+ { 0x08FF, 0x08FF }, -+ { 0x0978, 0x0978 }, -+ { 0x0980, 0x0980 }, -+ { 0x0984, 0x0984 }, -+ { 0x098D, 0x098E }, -+ { 0x0991, 0x0992 }, -+ { 0x09A9, 0x09A9 }, -+ { 0x09B1, 0x09B1 }, -+ { 0x09B3, 0x09B5 }, -+ { 0x09BA, 0x09BB }, -+ { 0x09C5, 0x09C6 }, -+ { 0x09C9, 0x09CA }, -+ { 0x09CF, 0x09D6 }, -+ { 0x09D8, 0x09DB }, -+ { 0x09DE, 0x09DE }, -+ { 0x09E4, 0x09E5 }, -+ { 0x09FC, 0x0A00 }, -+ { 0x0A04, 0x0A04 }, -+ { 0x0A0B, 0x0A0E }, -+ { 0x0A11, 0x0A12 }, -+ { 0x0A29, 0x0A29 }, -+ { 0x0A31, 0x0A31 }, -+ { 0x0A34, 0x0A34 }, -+ { 0x0A37, 0x0A37 }, -+ { 0x0A3A, 0x0A3B }, -+ { 0x0A3D, 0x0A3D }, -+ { 0x0A43, 0x0A46 }, -+ { 0x0A49, 0x0A4A }, -+ { 0x0A4E, 0x0A50 }, -+ { 0x0A52, 0x0A58 }, -+ { 0x0A5D, 0x0A5D }, -+ { 0x0A5F, 0x0A65 }, -+ { 0x0A76, 0x0A80 }, -+ { 0x0A84, 0x0A84 }, -+ { 0x0A8E, 0x0A8E }, -+ { 0x0A92, 0x0A92 }, -+ { 0x0AA9, 0x0AA9 }, -+ { 0x0AB1, 0x0AB1 }, -+ { 0x0AB4, 0x0AB4 }, -+ { 0x0ABA, 0x0ABB }, -+ { 0x0AC6, 0x0AC6 }, -+ { 0x0ACA, 0x0ACA }, -+ { 0x0ACE, 0x0ACF }, -+ { 0x0AD1, 0x0ADF }, -+ { 0x0AE4, 0x0AE5 }, -+ { 0x0AF2, 0x0B00 }, -+ { 0x0B04, 0x0B04 }, -+ { 0x0B0D, 0x0B0E }, -+ { 0x0B11, 0x0B12 }, -+ { 0x0B29, 0x0B29 }, -+ { 0x0B31, 0x0B31 }, -+ { 0x0B34, 0x0B34 }, -+ { 0x0B3A, 0x0B3B }, -+ { 0x0B45, 0x0B46 }, -+ { 0x0B49, 0x0B4A }, -+ { 0x0B4E, 0x0B55 }, -+ { 0x0B58, 0x0B5B }, -+ { 0x0B5E, 0x0B5E }, -+ { 0x0B64, 0x0B65 }, -+ { 0x0B78, 0x0B81 }, -+ { 0x0B84, 0x0B84 }, -+ { 0x0B8B, 0x0B8D }, -+ { 0x0B91, 0x0B91 }, -+ { 0x0B96, 0x0B98 }, -+ { 0x0B9B, 0x0B9B }, -+ { 0x0B9D, 0x0B9D }, -+ { 0x0BA0, 0x0BA2 }, -+ { 0x0BA5, 0x0BA7 }, -+ { 0x0BAB, 0x0BAD }, -+ { 0x0BBA, 0x0BBD }, -+ { 0x0BC3, 0x0BC5 }, -+ { 0x0BC9, 0x0BC9 }, -+ { 0x0BCE, 0x0BCF }, -+ { 0x0BD1, 0x0BD6 }, -+ { 0x0BD8, 0x0BE5 }, -+ { 0x0BFB, 0x0C00 }, -+ { 0x0C04, 0x0C04 }, -+ { 0x0C0D, 0x0C0D }, -+ { 0x0C11, 0x0C11 }, -+ { 0x0C29, 0x0C29 }, -+ { 0x0C34, 0x0C34 }, -+ { 0x0C3A, 0x0C3C }, -+ { 0x0C45, 0x0C45 }, -+ { 0x0C49, 0x0C49 }, -+ { 0x0C4E, 0x0C54 }, -+ { 0x0C57, 0x0C57 }, -+ { 0x0C5A, 0x0C5F }, -+ { 0x0C64, 0x0C65 }, -+ { 0x0C70, 0x0C77 }, -+ { 0x0C80, 0x0C81 }, -+ { 0x0C84, 0x0C84 }, -+ { 0x0C8D, 0x0C8D }, -+ { 0x0C91, 0x0C91 }, -+ { 0x0CA9, 0x0CA9 }, -+ { 0x0CB4, 0x0CB4 }, -+ { 0x0CBA, 0x0CBB }, -+ { 0x0CC5, 0x0CC5 }, -+ { 0x0CC9, 0x0CC9 }, -+ { 0x0CCE, 0x0CD4 }, -+ { 0x0CD7, 0x0CDD }, -+ { 0x0CDF, 0x0CDF }, -+ { 0x0CE4, 0x0CE5 }, -+ { 0x0CF0, 0x0CF0 }, -+ { 0x0CF3, 0x0D01 }, -+ { 0x0D04, 0x0D04 }, -+ { 0x0D0D, 0x0D0D }, -+ { 0x0D11, 0x0D11 }, -+ { 0x0D3B, 0x0D3C }, -+ { 0x0D45, 0x0D45 }, -+ { 0x0D49, 0x0D49 }, -+ { 0x0D4F, 0x0D56 }, -+ { 0x0D58, 0x0D5F }, -+ { 0x0D64, 0x0D65 }, -+ { 0x0D76, 0x0D78 }, -+ { 0x0D80, 0x0D81 }, -+ { 0x0D84, 0x0D84 }, -+ { 0x0D97, 0x0D99 }, -+ { 0x0DB2, 0x0DB2 }, -+ { 0x0DBC, 0x0DBC }, -+ { 0x0DBE, 0x0DBF }, -+ { 0x0DC7, 0x0DC9 }, -+ { 0x0DCB, 0x0DCE }, -+ { 0x0DD5, 0x0DD5 }, -+ { 0x0DD7, 0x0DD7 }, -+ { 0x0DE0, 0x0DF1 }, -+ { 0x0DF5, 0x0E00 }, -+ { 0x0E3B, 0x0E3E }, -+ { 0x0E5C, 0x0E80 }, -+ { 0x0E83, 0x0E83 }, -+ { 0x0E85, 0x0E86 }, -+ { 0x0E89, 0x0E89 }, -+ { 0x0E8B, 0x0E8C }, -+ { 0x0E8E, 0x0E93 }, -+ { 0x0E98, 0x0E98 }, -+ { 0x0EA0, 0x0EA0 }, -+ { 0x0EA4, 0x0EA4 }, -+ { 0x0EA6, 0x0EA6 }, -+ { 0x0EA8, 0x0EA9 }, -+ { 0x0EAC, 0x0EAC }, -+ { 0x0EBA, 0x0EBA }, -+ { 0x0EBE, 0x0EBF }, -+ { 0x0EC5, 0x0EC5 }, -+ { 0x0EC7, 0x0EC7 }, -+ { 0x0ECE, 0x0ECF }, -+ { 0x0EDA, 0x0EDB }, -+ { 0x0EE0, 0x0EFF }, -+ { 0x0F48, 0x0F48 }, -+ { 0x0F6D, 0x0F70 }, -+ { 0x0F98, 0x0F98 }, -+ { 0x0FBD, 0x0FBD }, -+ { 0x0FCD, 0x0FCD }, -+ { 0x0FDB, 0x0FFF }, -+ { 0x10C6, 0x10C6 }, -+ { 0x10C8, 0x10CC }, -+ { 0x10CE, 0x10CF }, -+ { 0x1249, 0x1249 }, -+ { 0x124E, 0x124F }, -+ { 0x1257, 0x1257 }, -+ { 0x1259, 0x1259 }, -+ { 0x125E, 0x125F }, -+ { 0x1289, 0x1289 }, -+ { 0x128E, 0x128F }, -+ { 0x12B1, 0x12B1 }, -+ { 0x12B6, 0x12B7 }, -+ { 0x12BF, 0x12BF }, -+ { 0x12C1, 0x12C1 }, -+ { 0x12C6, 0x12C7 }, -+ { 0x12D7, 0x12D7 }, -+ { 0x1311, 0x1311 }, -+ { 0x1316, 0x1317 }, -+ { 0x135B, 0x135C }, -+ { 0x137D, 0x137F }, -+ { 0x139A, 0x139F }, -+ { 0x13F5, 0x13FF }, -+ { 0x169D, 0x169F }, -+ { 0x16F1, 0x16FF }, -+ { 0x170D, 0x170D }, -+ { 0x1715, 0x171F }, -+ { 0x1737, 0x173F }, -+ { 0x1754, 0x175F }, -+ { 0x176D, 0x176D }, -+ { 0x1771, 0x1771 }, -+ { 0x1774, 0x177F }, -+ { 0x17DE, 0x17DF }, -+ { 0x17EA, 0x17EF }, -+ { 0x17FA, 0x17FF }, -+ { 0x180F, 0x180F }, -+ { 0x181A, 0x181F }, -+ { 0x1878, 0x187F }, -+ { 0x18AB, 0x18AF }, -+ { 0x18F6, 0x18FF }, -+ { 0x191D, 0x191F }, -+ { 0x192C, 0x192F }, -+ { 0x193C, 0x193F }, -+ { 0x1941, 0x1943 }, -+ { 0x196E, 0x196F }, -+ { 0x1975, 0x197F }, -+ { 0x19AC, 0x19AF }, -+ { 0x19CA, 0x19CF }, -+ { 0x19DB, 0x19DD }, -+ { 0x1A1C, 0x1A1D }, -+ { 0x1A5F, 0x1A5F }, -+ { 0x1A7D, 0x1A7E }, -+ { 0x1A8A, 0x1A8F }, -+ { 0x1A9A, 0x1A9F }, -+ { 0x1AAE, 0x1AFF }, -+ { 0x1B4C, 0x1B4F }, -+ { 0x1B7D, 0x1B7F }, -+ { 0x1BF4, 0x1BFB }, -+ { 0x1C38, 0x1C3A }, -+ { 0x1C4A, 0x1C4C }, -+ { 0x1C80, 0x1CBF }, -+ { 0x1CC8, 0x1CCF }, -+ { 0x1CF7, 0x1CFF }, -+ { 0x1DE7, 0x1DFB }, -+ { 0x1F16, 0x1F17 }, -+ { 0x1F1E, 0x1F1F }, -+ { 0x1F46, 0x1F47 }, -+ { 0x1F4E, 0x1F4F }, -+ { 0x1F58, 0x1F58 }, -+ { 0x1F5A, 0x1F5A }, -+ { 0x1F5C, 0x1F5C }, -+ { 0x1F5E, 0x1F5E }, -+ { 0x1F7E, 0x1F7F }, -+ { 0x1FB5, 0x1FB5 }, -+ { 0x1FC5, 0x1FC5 }, -+ { 0x1FD4, 0x1FD5 }, -+ { 0x1FDC, 0x1FDC }, -+ { 0x1FF0, 0x1FF1 }, -+ { 0x1FF5, 0x1FF5 }, -+ { 0x1FFF, 0x1FFF }, -+ { 0x2065, 0x2069 }, -+ { 0x2072, 0x2073 }, -+ { 0x208F, 0x208F }, -+ { 0x209D, 0x209F }, -+ { 0x20BB, 0x20CF }, -+ { 0x20F1, 0x20FF }, -+ { 0x218A, 0x218F }, -+ { 0x23F4, 0x23FF }, -+ { 0x2427, 0x243F }, -+ { 0x244B, 0x245F }, -+ { 0x2700, 0x2700 }, -+ { 0x2B4D, 0x2B4F }, -+ { 0x2B5A, 0x2BFF }, -+ { 0x2C2F, 0x2C2F }, -+ { 0x2C5F, 0x2C5F }, -+ { 0x2CF4, 0x2CF8 }, -+ { 0x2D26, 0x2D26 }, -+ { 0x2D28, 0x2D2C }, -+ { 0x2D2E, 0x2D2F }, -+ { 0x2D68, 0x2D6E }, -+ { 0x2D71, 0x2D7E }, -+ { 0x2D97, 0x2D9F }, -+ { 0x2DA7, 0x2DA7 }, -+ { 0x2DAF, 0x2DAF }, -+ { 0x2DB7, 0x2DB7 }, -+ { 0x2DBF, 0x2DBF }, -+ { 0x2DC7, 0x2DC7 }, -+ { 0x2DCF, 0x2DCF }, -+ { 0x2DD7, 0x2DD7 }, -+ { 0x2DDF, 0x2DDF }, -+ { 0x2E3C, 0x2E7F }, -+ { 0x2E9A, 0x2E9A }, -+ { 0x2EF4, 0x2EFF }, -+ { 0x2FD6, 0x2FEF }, -+ { 0x2FFC, 0x2FFF }, -+ { 0x3040, 0x3040 }, -+ { 0x3097, 0x3098 }, -+ { 0x3100, 0x3104 }, -+ { 0x312E, 0x3130 }, -+ { 0x318F, 0x318F }, -+ { 0x31BB, 0x31BF }, -+ { 0x31E4, 0x31EF }, -+ { 0x321F, 0x321F }, -+ { 0x32FF, 0x32FF }, -+ { 0x4DB6, 0x4DBF }, -+ { 0x9FA6, 0x9FCB }, -+ { 0x9FCD, 0x9FFF }, -+ { 0xA48D, 0xA48F }, -+ { 0xA4C7, 0xA4CF }, -+ { 0xA62C, 0xA63F }, -+ { 0xA698, 0xA69E }, -+ { 0xA6F8, 0xA6FF }, -+ { 0xA78F, 0xA78F }, -+ { 0xA794, 0xA79F }, -+ { 0xA7AB, 0xA7F7 }, -+ { 0xA82C, 0xA82F }, -+ { 0xA83A, 0xA83F }, -+ { 0xA878, 0xA87F }, -+ { 0xA8C5, 0xA8CD }, -+ { 0xA8DA, 0xA8DF }, -+ { 0xA8FC, 0xA8FF }, -+ { 0xA954, 0xA95E }, -+ { 0xA97D, 0xA97F }, -+ { 0xA9CE, 0xA9CE }, -+ { 0xA9DA, 0xA9DD }, -+ { 0xA9E0, 0xA9FF }, -+ { 0xAA37, 0xAA3F }, -+ { 0xAA4E, 0xAA4F }, -+ { 0xAA5A, 0xAA5B }, -+ { 0xAA7C, 0xAA7F }, -+ { 0xAAC3, 0xAADA }, -+ { 0xAAF7, 0xAB00 }, -+ { 0xAB07, 0xAB08 }, -+ { 0xAB0F, 0xAB10 }, -+ { 0xAB17, 0xAB1F }, -+ { 0xAB27, 0xAB27 }, -+ { 0xAB2F, 0xABBF }, -+ { 0xABEE, 0xABEF }, -+ { 0xABFA, 0xABFF }, -+ { 0xD7A4, 0xD7AF }, -+ { 0xD7C7, 0xD7CA }, -+ { 0xD7FC, 0xD7FF }, -+ { 0xFA6E, 0xFA6F }, -+ { 0xFADA, 0xFAFF }, -+ { 0xFB07, 0xFB12 }, -+ { 0xFB18, 0xFB1C }, -+ { 0xFB37, 0xFB37 }, -+ { 0xFB3D, 0xFB3D }, -+ { 0xFB3F, 0xFB3F }, -+ { 0xFB42, 0xFB42 }, -+ { 0xFB45, 0xFB45 }, -+ { 0xFBC2, 0xFBD2 }, -+ { 0xFD40, 0xFD4F }, -+ { 0xFD90, 0xFD91 }, -+ { 0xFDC8, 0xFDCF }, -+ { 0xFDFE, 0xFDFF }, -+ { 0xFE1A, 0xFE1F }, -+ { 0xFE27, 0xFE2F }, -+ { 0xFE53, 0xFE53 }, -+ { 0xFE67, 0xFE67 }, -+ { 0xFE6C, 0xFE6F }, -+ { 0xFE75, 0xFE75 }, -+ { 0xFEFD, 0xFEFE }, -+ { 0xFF00, 0xFF00 }, -+ { 0xFFBF, 0xFFC1 }, -+ { 0xFFC8, 0xFFC9 }, -+ { 0xFFD0, 0xFFD1 }, -+ { 0xFFD8, 0xFFD9 }, -+ { 0xFFDD, 0xFFDF }, -+ { 0xFFE7, 0xFFE7 }, -+ { 0xFFEF, 0xFFF8 }, -+ { 0x1000C, 0x1000C }, -+ { 0x10027, 0x10027 }, -+ { 0x1003B, 0x1003B }, -+ { 0x1003E, 0x1003E }, -+ { 0x1004E, 0x1004F }, -+ { 0x1005E, 0x1007F }, -+ { 0x100FB, 0x100FF }, -+ { 0x10103, 0x10106 }, -+ { 0x10134, 0x10136 }, -+ { 0x1018B, 0x1018F }, -+ { 0x1019C, 0x101CF }, -+ { 0x101FE, 0x1027F }, -+ { 0x1029D, 0x1029F }, -+ { 0x102D1, 0x102FF }, -+ { 0x1031F, 0x1031F }, -+ { 0x10324, 0x1032F }, -+ { 0x1034B, 0x1037F }, -+ { 0x1039E, 0x1039E }, -+ { 0x103C4, 0x103C7 }, -+ { 0x103D6, 0x103FF }, -+ { 0x1049E, 0x1049F }, -+ { 0x104AA, 0x107FF }, -+ { 0x10806, 0x10807 }, -+ { 0x10809, 0x10809 }, -+ { 0x10836, 0x10836 }, -+ { 0x10839, 0x1083B }, -+ { 0x1083D, 0x1083E }, -+ { 0x10856, 0x10856 }, -+ { 0x10860, 0x108FF }, -+ { 0x1091C, 0x1091E }, -+ { 0x1093A, 0x1093E }, -+ { 0x10940, 0x1097F }, -+ { 0x109B8, 0x109BD }, -+ { 0x109C0, 0x109FF }, -+ { 0x10A04, 0x10A04 }, -+ { 0x10A07, 0x10A0B }, -+ { 0x10A14, 0x10A14 }, -+ { 0x10A18, 0x10A18 }, -+ { 0x10A34, 0x10A37 }, -+ { 0x10A3B, 0x10A3E }, -+ { 0x10A48, 0x10A4F }, -+ { 0x10A59, 0x10A5F }, -+ { 0x10A80, 0x10AFF }, -+ { 0x10B36, 0x10B38 }, -+ { 0x10B56, 0x10B57 }, -+ { 0x10B73, 0x10B77 }, -+ { 0x10B80, 0x10BFF }, -+ { 0x10C49, 0x10E5F }, -+ { 0x10E7F, 0x10FFF }, -+ { 0x1104E, 0x11051 }, -+ { 0x11070, 0x1107F }, -+ { 0x110C2, 0x110CF }, -+ { 0x110E9, 0x110EF }, -+ { 0x110FA, 0x110FF }, -+ { 0x11135, 0x11135 }, -+ { 0x11144, 0x1117F }, -+ { 0x111C9, 0x111CF }, -+ { 0x111DA, 0x1167F }, -+ { 0x116B8, 0x116BF }, -+ { 0x116CA, 0x11FFF }, -+ { 0x1236F, 0x123FF }, -+ { 0x12463, 0x1246F }, -+ { 0x12474, 0x12FFF }, -+ { 0x1342F, 0x167FF }, -+ { 0x16A39, 0x16EFF }, -+ { 0x16F45, 0x16F4F }, -+ { 0x16F7F, 0x16F8E }, -+ { 0x16FA0, 0x1AFFF }, -+ { 0x1B002, 0x1CFFF }, -+ { 0x1D0F6, 0x1D0FF }, -+ { 0x1D127, 0x1D128 }, -+ { 0x1D1DE, 0x1D1FF }, -+ { 0x1D246, 0x1D2FF }, -+ { 0x1D357, 0x1D35F }, -+ { 0x1D372, 0x1D3FF }, -+ { 0x1D455, 0x1D455 }, -+ { 0x1D49D, 0x1D49D }, -+ { 0x1D4A0, 0x1D4A1 }, -+ { 0x1D4A3, 0x1D4A4 }, -+ { 0x1D4A7, 0x1D4A8 }, -+ { 0x1D4AD, 0x1D4AD }, -+ { 0x1D4BA, 0x1D4BA }, -+ { 0x1D4BC, 0x1D4BC }, -+ { 0x1D4C4, 0x1D4C4 }, -+ { 0x1D506, 0x1D506 }, -+ { 0x1D50B, 0x1D50C }, -+ { 0x1D515, 0x1D515 }, -+ { 0x1D51D, 0x1D51D }, -+ { 0x1D53A, 0x1D53A }, -+ { 0x1D53F, 0x1D53F }, -+ { 0x1D545, 0x1D545 }, -+ { 0x1D547, 0x1D549 }, -+ { 0x1D551, 0x1D551 }, -+ { 0x1D6A6, 0x1D6A7 }, -+ { 0x1D7CC, 0x1D7CD }, -+ { 0x1D800, 0x1EDFF }, -+ { 0x1EE04, 0x1EE04 }, -+ { 0x1EE20, 0x1EE20 }, -+ { 0x1EE23, 0x1EE23 }, -+ { 0x1EE25, 0x1EE26 }, -+ { 0x1EE28, 0x1EE28 }, -+ { 0x1EE33, 0x1EE33 }, -+ { 0x1EE38, 0x1EE38 }, -+ { 0x1EE3A, 0x1EE3A }, -+ { 0x1EE3C, 0x1EE41 }, -+ { 0x1EE43, 0x1EE46 }, -+ { 0x1EE48, 0x1EE48 }, -+ { 0x1EE4A, 0x1EE4A }, -+ { 0x1EE4C, 0x1EE4C }, -+ { 0x1EE50, 0x1EE50 }, -+ { 0x1EE53, 0x1EE53 }, -+ { 0x1EE55, 0x1EE56 }, -+ { 0x1EE58, 0x1EE58 }, -+ { 0x1EE5A, 0x1EE5A }, -+ { 0x1EE5C, 0x1EE5C }, -+ { 0x1EE5E, 0x1EE5E }, -+ { 0x1EE60, 0x1EE60 }, -+ { 0x1EE63, 0x1EE63 }, -+ { 0x1EE65, 0x1EE66 }, -+ { 0x1EE6B, 0x1EE6B }, -+ { 0x1EE73, 0x1EE73 }, -+ { 0x1EE78, 0x1EE78 }, -+ { 0x1EE7D, 0x1EE7D }, -+ { 0x1EE7F, 0x1EE7F }, -+ { 0x1EE8A, 0x1EE8A }, -+ { 0x1EE9C, 0x1EEA0 }, -+ { 0x1EEA4, 0x1EEA4 }, -+ { 0x1EEAA, 0x1EEAA }, -+ { 0x1EEBC, 0x1EEEF }, -+ { 0x1EEF2, 0x1EFFF }, -+ { 0x1F02C, 0x1F02F }, -+ { 0x1F094, 0x1F09F }, -+ { 0x1F0AF, 0x1F0B0 }, -+ { 0x1F0BF, 0x1F0C0 }, -+ { 0x1F0D0, 0x1F0D0 }, -+ { 0x1F0E0, 0x1F0FF }, -+ { 0x1F10B, 0x1F10F }, -+ { 0x1F12F, 0x1F12F }, -+ { 0x1F16C, 0x1F16F }, -+ { 0x1F19B, 0x1F1E5 }, -+ { 0x1F203, 0x1F20F }, -+ { 0x1F23B, 0x1F23F }, -+ { 0x1F249, 0x1F24F }, -+ { 0x1F252, 0x1F2FF }, -+ { 0x1F321, 0x1F32F }, -+ { 0x1F336, 0x1F336 }, -+ { 0x1F37D, 0x1F37F }, -+ { 0x1F394, 0x1F39F }, -+ { 0x1F3C5, 0x1F3C5 }, -+ { 0x1F3CB, 0x1F3DF }, -+ { 0x1F3F1, 0x1F3FF }, -+ { 0x1F43F, 0x1F43F }, -+ { 0x1F441, 0x1F441 }, -+ { 0x1F4F8, 0x1F4F8 }, -+ { 0x1F4FD, 0x1F4FF }, -+ { 0x1F53E, 0x1F53F }, -+ { 0x1F544, 0x1F54F }, -+ { 0x1F568, 0x1F5FA }, -+ { 0x1F641, 0x1F644 }, -+ { 0x1F650, 0x1F67F }, -+ { 0x1F6C6, 0x1F6FF }, -+ { 0x1F774, 0x1FFFD }, -+ { 0x2A6D7, 0x2A6FF }, -+ { 0x2A701, 0x2B733 }, -+ { 0x2B735, 0x2B73F }, -+ { 0x2B741, 0x2B81C }, -+ { 0x2B81E, 0x2F7FF }, -+ { 0x2FA1E, 0x2FFFD }, -+ { 0x30000, 0x3FFFD }, -+ { 0x40000, 0x4FFFD }, -+ { 0x50000, 0x5FFFD }, -+ { 0x60000, 0x6FFFD }, -+ { 0x70000, 0x7FFFD }, -+ { 0x80000, 0x8FFFD }, -+ { 0x90000, 0x9FFFD }, -+ { 0xA0000, 0xAFFFD }, -+ { 0xB0000, 0xBFFFD }, -+ { 0xC0000, 0xCFFFD }, -+ { 0xD0000, 0xDFFFD }, -+ { 0xE0000, 0xE0000 }, -+ { 0xE0002, 0xE001F }, -+ { 0xE0080, 0xE00FF }, -+ { 0xE01F0, 0xEFFFD }, -+}; -+ -+/* RFC3454 Table B.1 */ -+static const struct u32_range map_to_nothing[] = { -+ { 0x00AD, 0x00AD }, -+ { 0x034F, 0x034F }, -+ { 0x1806, 0x1806 }, -+ { 0x180B, 0x180D }, -+ { 0x200B, 0x200D }, -+ { 0x2060, 0x2060 }, -+ { 0xFE00, 0xFE0F }, -+ { 0xFEFF, 0xFEFF }, -+}; -+ -+/* Local: allow tab, CR and LF */ -+static const struct u32_range whitelist[] = { -+ { 0x09, 0x09 }, -+ { 0x0a, 0x0a }, -+ { 0x0d, 0x0d }, -+}; -+ -+/* RFC3454 Tables in appendix C */ -+static const struct u32_range prohibited[] = { -+ /* C.2.1 ASCII control characters */ -+ { 0x0000, 0x001F }, -+ { 0x007F, 0x007F }, -+ /* C.2.2 Non-ASCII control characters */ -+ { 0x0080, 0x009F }, -+ { 0x06DD, 0x06DD }, -+ { 0x070F, 0x070F }, -+ { 0x180E, 0x180E }, -+ { 0x200C, 0x200C }, -+ { 0x200D, 0x200D }, -+ { 0x2028, 0x2028 }, -+ { 0x2029, 0x2029 }, -+ { 0x2060, 0x2060 }, -+ { 0x2061, 0x2061 }, -+ { 0x2062, 0x2062 }, -+ { 0x2063, 0x2063 }, -+ { 0x206A, 0x206F }, -+ { 0xFEFF, 0xFEFF }, -+ { 0xFFF9, 0xFFFC }, -+ { 0x1D173, 0x1D17A }, -+ /* C.3 Private use */ -+ { 0xE000, 0xF8FF }, -+ { 0xF0000, 0xFFFFD }, -+ { 0x100000, 0x10FFFD }, -+ /* C.4 Non-character code points */ -+ { 0xFDD0, 0xFDEF }, -+ { 0xFFFE, 0xFFFF }, -+ { 0x1FFFE, 0x1FFFF }, -+ { 0x2FFFE, 0x2FFFF }, -+ { 0x3FFFE, 0x3FFFF }, -+ { 0x4FFFE, 0x4FFFF }, -+ { 0x5FFFE, 0x5FFFF }, -+ { 0x6FFFE, 0x6FFFF }, -+ { 0x7FFFE, 0x7FFFF }, -+ { 0x8FFFE, 0x8FFFF }, -+ { 0x9FFFE, 0x9FFFF }, -+ { 0xAFFFE, 0xAFFFF }, -+ { 0xBFFFE, 0xBFFFF }, -+ { 0xCFFFE, 0xCFFFF }, -+ { 0xDFFFE, 0xDFFFF }, -+ { 0xEFFFE, 0xEFFFF }, -+ { 0xFFFFE, 0xFFFFF }, -+ { 0x10FFFE, 0x10FFFF }, -+ /* C.5 Surrogate codes */ -+ { 0xD800, 0xDFFF }, -+ /* C.6 Inappropriate for plain text */ -+ { 0xFFF9, 0xFFF9 }, -+ { 0xFFFA, 0xFFFA }, -+ { 0xFFFB, 0xFFFB }, -+ { 0xFFFC, 0xFFFC }, -+ { 0xFFFD, 0xFFFD }, -+ /* C.7 Inappropriate for canonical representation */ -+ { 0x2FF0, 0x2FFB }, -+ /* C.8 Change display properties or are deprecated */ -+ { 0x0340, 0x0340 }, -+ { 0x0341, 0x0341 }, -+ { 0x200E, 0x200E }, -+ { 0x200F, 0x200F }, -+ { 0x202A, 0x202A }, -+ { 0x202B, 0x202B }, -+ { 0x202C, 0x202C }, -+ { 0x202D, 0x202D }, -+ { 0x202E, 0x202E }, -+ { 0x206A, 0x206A }, -+ { 0x206B, 0x206B }, -+ { 0x206C, 0x206C }, -+ { 0x206D, 0x206D }, -+ { 0x206E, 0x206E }, -+ { 0x206F, 0x206F }, -+ /* C.9 Tagging characters */ -+ { 0xE0001, 0xE0001 }, -+ { 0xE0020, 0xE007F }, -+}; -+ -diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringprep.c ---- openssh-6.8p1/utf8_stringprep.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 -+++ openssh-6.8p1/utf8_stringprep.c 2015-03-18 12:41:28.175713185 +0100 -@@ -0,0 +1,265 @@ -+/* -+ * Copyright (c) 2013 Damien Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * This is a simple RFC3454 stringprep profile to sanitise UTF-8 strings -+ * from untrusted sources. -+ * -+ * It is intended to be used prior to display of untrusted strings only. -+ * It should not be used for logging because of bi-di ambiguity. It -+ * should also not be used in any case where lack of normalisation may -+ * cause problems. -+ * -+ * This profile uses the prohibition and mapping tables from RFC3454 -+ * (listed below) but the unassigned character table has been updated to -+ * Unicode 6.2. It uses a local whitelist of whitespace characters (\n, -+ * \a and \t). Unicode normalisation and bi-di testing are not used. -+ * -+ * XXX: implement bi-di handling (needed for logs) -+ * XXX: implement KC normalisation (needed for passing to libs/syscalls) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "includes.h" -+#include "misc.h" -+#include "log.h" -+ -+struct u32_range { -+ u_int32_t lo, hi; /* Inclusive */ -+}; -+ -+#include "stringprep-tables.c" -+ -+/* Returns 1 if code 'c' appears in the table or 0 otherwise */ -+static int -+code_in_table(u_int32_t c, const struct u32_range *table, size_t tlen) -+{ -+ const struct u32_range *e, *end = (void *)(tlen + (char *)table); -+ -+ for (e = table; e < end; e++) { -+ if (c >= e->lo && c <= e->hi) -+ return 1; -+ } -+ return 0; -+} -+ -+/* -+ * Decode the next valid UCS character from a UTF-8 string, skipping past bad -+ * codes. Returns the decoded character or 0 for end-of-string and updates -+ * nextc to point to the start of the next character (if any). -+ * had_error is set if an invalid code was encountered. -+ */ -+static u_int32_t -+decode_utf8(const char *in, const char **nextc, int *had_error) -+{ -+ int state = 0; -+ size_t i; -+ u_int32_t c, e; -+ -+ e = c = 0; -+ for (i = 0; in[i] != '\0'; i++) { -+ e = (u_char)in[i]; -+ /* Invalid code point state */ -+ if (state == -1) { -+ /* -+ * Continue eating continuation characters until -+ * a new start character comes along. -+ */ -+ if ((e & 0xc0) == 0x80) -+ continue; -+ state = 0; -+ } -+ -+ /* New code point state */ -+ if (state == 0) { -+ if ((e & 0x80) == 0) { /* 7 bit code */ -+ c = e & 0x7f; -+ goto have_code; -+ } else if ((e & 0xe0) == 0xc0) { /* 11 bit code point */ -+ state = 1; -+ c = (e & 0x1f) << 6; -+ } else if ((e & 0xf0) == 0xe0) { /* 16 bit code point */ -+ state = 2; -+ c = (e & 0xf) << 12; -+ } else if ((e & 0xf8) == 0xf0) { /* 21 bit code point */ -+ state = 3; -+ c = (e & 0x7) << 18; -+ } else { -+ /* A five or six byte header, or 0xff */ -+ goto bad_encoding; -+ } -+ /* -+ * Check that the header byte has some non-zero data -+ * after masking off the length marker. If not it is -+ * an invalid encoding. -+ */ -+ if (c == 0) { -+ bad_encoding: -+ c = 0; -+ state = -1; -+ if (had_error != NULL) -+ *had_error = 1; -+ } -+ continue; -+ } -+ -+ /* Sanity check: should never happen */ -+ if (state < 1 || state > 5) { -+ *nextc = NULL; -+ if (had_error != NULL) -+ *had_error = 1; -+ return 0; -+ } -+ /* Multibyte code point state */ -+ state--; -+ c |= (e & 0x3f) << (state * 6); -+ if (state > 0) -+ continue; -+ -+ /* RFC3629 bans codepoints > U+10FFFF */ -+ if (c > 0x10FFFF) { -+ if (had_error != NULL) -+ *had_error = 1; -+ continue; -+ } -+ have_code: -+ *nextc = in + i + 1; -+ return c; -+ } -+ if (state != 0 && had_error != NULL) -+ *had_error = 1; -+ *nextc = in + i; -+ return 0; -+} -+ -+/* -+ * Attempt to encode a UCS character as a UTF-8 sequence. Returns the number -+ * of characters used or -1 on error (insufficient space or bad code). -+ */ -+static int -+encode_utf8(u_int32_t c, char *s, size_t slen) -+{ -+ size_t i, need; -+ u_char h; -+ -+ if (c < 0x80) { -+ if (slen >= 1) { -+ s[0] = (char)c; -+ } -+ return 1; -+ } else if (c < 0x800) { -+ need = 2; -+ h = 0xc0; -+ } else if (c < 0x10000) { -+ need = 3; -+ h = 0xe0; -+ } else if (c < 0x200000) { -+ need = 4; -+ h = 0xf0; -+ } else { -+ /* Invalid code point > U+10FFFF */ -+ return -1; -+ } -+ if (need > slen) -+ return -1; -+ for (i = 0; i < need; i++) { -+ s[i] = (i == 0 ? h : 0x80); -+ s[i] |= (c >> (need - i - 1) * 6) & 0x3f; -+ } -+ return need; -+} -+ -+ -+/* -+ * Normalise a UTF-8 string using the RFC3454 stringprep algorithm. -+ * Returns 0 on success or -1 on failure (prohibited code or insufficient -+ * length in the output string. -+ * Requires an output buffer at most the same length as the input. -+ */ -+int -+utf8_stringprep(const char *in, char *out, size_t olen) -+{ -+ int r; -+ size_t o; -+ u_int32_t c; -+ -+ if (olen < 1) -+ return -1; -+ -+ for (o = 0; (c = decode_utf8(in, &in, NULL)) != 0;) { -+ /* Mapping */ -+ if (code_in_table(c, map_to_nothing, sizeof(map_to_nothing))) -+ continue; -+ -+ /* Prohibitied output */ -+ if (code_in_table(c, prohibited, sizeof(prohibited)) && -+ !code_in_table(c, whitelist, sizeof(whitelist))) -+ return -1; -+ -+ /* Map unassigned code points to U+FFFD */ -+ if (code_in_table(c, unassigned, sizeof(unassigned))) -+ c = 0xFFFD; -+ -+ /* Encode the character */ -+ r = encode_utf8(c, out + o, olen - o - 1); -+ if (r < 0) -+ return -1; -+ o += r; -+ } -+ out[o] = '\0'; -+ return 0; -+} -+ -+/* Check whether we can display UTF-8 safely */ -+int -+utf8_ok(void) -+{ -+ static int ret = -1; -+ char *cp; -+ -+ if (ret == -1) { -+ setlocale(LC_CTYPE, ""); -+ cp = nl_langinfo(CODESET); -+ ret = strcmp(cp, "UTF-8") == 0; -+ } -+ return ret; -+} -+ -+void -+sanitize_utf8(char *target, const char *source, size_t length) -+{ -+ u_int done = 0; -+ if (utf8_ok()) { -+ if (utf8_stringprep(source, target, length * 4 + 1) == 0) -+ done = 1; -+ else -+ debug2("%s: UTF8 stringprep failed", __func__); -+ } -+ /* -+ * Fallback to strnvis if UTF8 display not supported or -+ * conversion failed. -+ */ -+ if (!done) -+ strnvis(target, source, length * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); -+} diff --git a/openssh-6.6p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch index e56d8aa..953d613 100644 --- a/openssh-6.6p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -1,20 +1,19 @@ -diff --git a/canohost.c b/canohost.c -index a61a8c9..97ce58c 100644 ---- a/canohost.c -+++ b/canohost.c -@@ -165,12 +165,29 @@ check_ip_options(int sock, char *ipaddr) - option_size = sizeof(options); - if (getsockopt(sock, ipproto, IP_OPTIONS, options, +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) { - text[0] = '\0'; - for (i = 0; i < option_size; i++) - snprintf(text + i*3, sizeof(text) - i*3, -- " %2.2x", options[i]); -- fatal("Connection from %.100s with IP options:%.800s", -- ipaddr, text); +- " %2.2x", opts[i]); +- fatal("Connection from %.100s port %d with IP opts: %.800s", +- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); + i = 0; + do { -+ switch (options[i]) { ++ switch (opts[i]) { + case 0: + case 1: + ++i; @@ -22,7 +21,7 @@ index a61a8c9..97ce58c 100644 + case 130: + case 133: + case 134: -+ i += options[i + 1]; ++ i += opts[i + 1]; + break; + default: + /* Fail, fatally, if we detect either loose or strict @@ -30,11 +29,11 @@ index a61a8c9..97ce58c 100644 + text[0] = '\0'; + for (i = 0; i < option_size; i++) + snprintf(text + i*3, sizeof(text) - i*3, -+ " %2.2x", options[i]); -+ fatal("Connection from %.100s with IP options:%.800s", -+ ipaddr, text); ++ " %2.2x", opts[i]); ++ fatal("Connection from %.100s port %d with IP options:%.800s", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); + } + } while (i < option_size); } + return; #endif /* IP_OPTIONS */ - } diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 591ae6c..9383a98 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -20,7 +20,7 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in ssh_api.o \ @@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o - $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index 9daa63c..b023ddc 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -18,7 +18,7 @@ index 843225d..041bbab 100644 +++ b/openbsd-compat/Makefile.in @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 8d86014..fd87fd5 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -43,6 +43,14 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHLIBS=@SSHLIBS@ + SSHDLIBS=@SSHDLIBS@ ++KEYCATLIBS=@KEYCATLIBS@ + LIBEDIT=@LIBEDIT@ + AR=@AR@ + AWK=@AWK@ @@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ @@ -57,7 +65,7 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o -+ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) ++ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -434,3 +442,41 @@ diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c + } + return ev; +} +diff --git a/configure.ac b/configure.ac +index 3bbccfd..6481f1f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2952,6 +2952,7 @@ AC_ARG_WITH([pam], + PAM_MSG="yes" + + SSHDLIBS="$SSHDLIBS -lpam" ++ KEYCATLIBS="$KEYCATLIBS -lpam" + AC_DEFINE([USE_PAM], [1], + [Define if you want to enable PAM support]) + +@@ -3105,6 +3106,7 @@ + ;; + *) + SSHDLIBS="$SSHDLIBS -ldl" ++ KEYCATLIBS="$KEYCATLIBS -ldl" + ;; + esac + fi +@@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux], + ) + AC_SUBST([SSHLIBS]) + AC_SUBST([SSHDLIBS]) ++AC_SUBST([KEYCATLIBS]) + + # Check whether user wants Kerberos 5 support + KRB5_MSG="no" +@@ -5031,6 +5034,9 @@ fi + if test ! -z "${SSHLIBS}"; then + echo " +for ssh: ${SSHLIBS}" + fi ++if test ! -z "${KEYCATLIBS}"; then ++echo " +for ssh-keycat: ${KEYCATLIBS}" ++fi + + echo "" + diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index ebb0196..192b9c3 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -235,7 +235,7 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c M_CP_INTOPT(rekey_interval); @@ -2304,6 +2314,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); + dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index ec73cae..10b0b9e 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -2,21 +2,32 @@ diff --git a/ssh_config b/ssh_config index 49a4f6c..3f83c40 100644 --- a/ssh_config +++ b/ssh_config -@@ -46,3 +46,19 @@ +@@ -46,3 +46,7 @@ # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h +# ++# To modify the system-wide ssh configuration, create a file under ++# /etc/ssh/ssh_config.d/ which will get automatically included below ++Include /etc/ssh/ssh_config.d/*.conf +diff --git a/ssh_config_redhat b/ssh_config_redhat +new file mode 100644 +index 0000000..9082a13 +--- /dev/null ++++ b/ssh_config_redhat +@@ -0,0 +1,17 @@ +# Uncomment this if you want to use .local domain +# Host *.local +# CheckHostIP no + +Host * + GSSAPIAuthentication yes ++ +# If this option is set to yes then remote X11 clients will have full access +# to the original X11 display. As virtually no X11 client supports the untrusted +# mode correctly we set this to yes. + ForwardX11Trusted yes ++ +# 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 @@ -52,8 +63,8 @@ index c735429..e68ddee 100644 # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h @@ -36,6 +40,7 @@ + # Logging - # obsoletes QuietMode and FascistLogging #SyslogFacility AUTH +SyslogFacility AUTHPRIV #LogLevel INFO diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index 5ec22c4..8c9485e 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.8p1/auth-pam.c.role-mls openssh-6.8p1/auth-pam.c ---- openssh-6.8p1/auth-pam.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth-pam.c 2015-03-18 11:04:21.045817122 +0100 -@@ -1068,7 +1068,7 @@ is_pam_session_open(void) +diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c +--- openssh/auth-pam.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth-pam.c 2016-07-26 12:37:48.793593333 +0200 +@@ -1095,7 +1095,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ int @@ -10,9 +10,9 @@ diff -up openssh-6.8p1/auth-pam.c.role-mls openssh-6.8p1/auth-pam.c { int ret = 1; #ifdef HAVE_PAM_PUTENV -diff -up openssh-6.8p1/auth-pam.h.role-mls openssh-6.8p1/auth-pam.h ---- openssh-6.8p1/auth-pam.h.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth-pam.h 2015-03-18 11:04:21.045817122 +0100 +diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h +--- openssh/auth-pam.h.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth-pam.h 2016-07-26 12:37:48.793593333 +0200 @@ -38,7 +38,7 @@ void do_pam_session(void); void do_pam_set_tty(const char *); void do_pam_setcred(int ); @@ -22,9 +22,9 @@ diff -up openssh-6.8p1/auth-pam.h.role-mls openssh-6.8p1/auth-pam.h char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh-6.8p1/auth.h.role-mls openssh-6.8p1/auth.h ---- openssh-6.8p1/auth.h.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth.h 2015-03-18 11:04:21.045817122 +0100 +diff -up openssh/auth.h.role-mls openssh/auth.h +--- openssh/auth.h.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth.h 2016-07-26 12:37:48.793593333 +0200 @@ -62,6 +62,9 @@ struct Authctxt { char *service; struct passwd *pw; /* set if 'valid' */ @@ -35,9 +35,9 @@ diff -up openssh-6.8p1/auth.h.role-mls openssh-6.8p1/auth.h void *kbdintctxt; char *info; /* Extra info for next auth_log */ #ifdef BSD_AUTH -diff -up openssh-6.8p1/auth1.c.role-mls openssh-6.8p1/auth1.c ---- openssh-6.8p1/auth1.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth1.c 2015-03-18 11:04:21.046817119 +0100 +diff -up openssh/auth1.c.role-mls openssh/auth1.c +--- openssh/auth1.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth1.c 2016-07-26 12:37:48.793593333 +0200 @@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) { u_int ulen; @@ -73,9 +73,9 @@ diff -up openssh-6.8p1/auth1.c.role-mls openssh-6.8p1/auth1.c /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh-6.8p1/auth2-gss.c.role-mls openssh-6.8p1/auth2-gss.c ---- openssh-6.8p1/auth2-gss.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth2-gss.c 2015-03-18 11:04:21.046817119 +0100 +diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c +--- openssh/auth2-gss.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth2-gss.c 2016-07-26 12:37:48.794593332 +0200 @@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -108,10 +108,10 @@ diff -up openssh-6.8p1/auth2-gss.c.role-mls openssh-6.8p1/auth2-gss.c free(mic.value); authctxt->postponed = 0; -diff -up openssh-6.8p1/auth2-hostbased.c.role-mls openssh-6.8p1/auth2-hostbased.c ---- openssh-6.8p1/auth2-hostbased.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth2-hostbased.c 2015-03-18 11:04:21.046817119 +0100 -@@ -122,7 +122,15 @@ userauth_hostbased(Authctxt *authctxt) +diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c +--- openssh/auth2-hostbased.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth2-hostbased.c 2016-07-26 12:37:48.794593332 +0200 +@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) buffer_put_string(&b, session_id2, session_id2_len); /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -128,10 +128,10 @@ diff -up openssh-6.8p1/auth2-hostbased.c.role-mls openssh-6.8p1/auth2-hostbased. buffer_put_cstring(&b, service); buffer_put_cstring(&b, "hostbased"); buffer_put_string(&b, pkalg, alen); -diff -up openssh-6.8p1/auth2-pubkey.c.role-mls openssh-6.8p1/auth2-pubkey.c ---- openssh-6.8p1/auth2-pubkey.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-18 11:04:21.046817119 +0100 -@@ -145,9 +145,11 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth2-pubkey.c 2016-07-26 12:37:48.794593332 +0200 +@@ -151,9 +151,11 @@ userauth_pubkey(Authctxt *authctxt) } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -145,9 +145,9 @@ diff -up openssh-6.8p1/auth2-pubkey.c.role-mls openssh-6.8p1/auth2-pubkey.c buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, -diff -up openssh-6.8p1/auth2.c.role-mls openssh-6.8p1/auth2.c ---- openssh-6.8p1/auth2.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/auth2.c 2015-03-18 11:04:21.046817119 +0100 +diff -up openssh/auth2.c.role-mls openssh/auth2.c +--- openssh/auth2.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/auth2.c 2016-07-26 12:37:48.794593332 +0200 @@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ctxt; Authmethod *m = NULL; @@ -187,10 +187,10 @@ diff -up openssh-6.8p1/auth2.c.role-mls openssh-6.8p1/auth2.c userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); -diff -up openssh-6.8p1/misc.c.role-mls openssh-6.8p1/misc.c ---- openssh-6.8p1/misc.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/misc.c 2015-03-18 11:04:21.046817119 +0100 -@@ -431,6 +431,7 @@ char * +diff -up openssh/misc.c.role-mls openssh/misc.c +--- openssh/misc.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/misc.c 2016-07-26 12:37:48.794593332 +0200 +@@ -432,6 +432,7 @@ char * colon(char *cp) { int flag = 0; @@ -198,7 +198,7 @@ diff -up openssh-6.8p1/misc.c.role-mls openssh-6.8p1/misc.c if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -446,6 +447,13 @@ colon(char *cp) +@@ -447,6 +448,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -212,10 +212,10 @@ diff -up openssh-6.8p1/misc.c.role-mls openssh-6.8p1/misc.c } return NULL; } -diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c ---- openssh-6.8p1/monitor.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/monitor.c 2015-03-18 11:04:21.047817117 +0100 -@@ -127,6 +127,9 @@ int mm_answer_sign(int, Buffer *); +diff -up openssh/monitor.c.role-mls openssh/monitor.c +--- openssh/monitor.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/monitor.c 2016-07-26 12:44:19.363379490 +0200 +@@ -128,6 +128,9 @@ int mm_answer_sign(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); @@ -225,7 +225,7 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c int mm_answer_authpassword(int, Buffer *); int mm_answer_bsdauthquery(int, Buffer *); int mm_answer_bsdauthrespond(int, Buffer *); -@@ -206,6 +209,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -207,6 +210,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 +235,7 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -862,6 +868,9 @@ mm_answer_pwnamallow(int sock, Buffer *m +@@ -863,6 +869,9 @@ mm_answer_pwnamallow(int sock, Buffer *m else { /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -245,7 +245,7 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); } #ifdef USE_PAM -@@ -903,6 +912,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -904,6 +913,25 @@ mm_answer_authserv(int sock, Buffer *m) return (0); } @@ -271,25 +271,25 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c int mm_answer_authpassword(int sock, Buffer *m) { -@@ -1291,7 +1319,7 @@ static int - monitor_valid_userblob(u_char *data, u_int datalen) +@@ -1300,7 +1328,7 @@ monitor_valid_userblob(u_char *data, u_i { Buffer b; -- char *p, *userstyle; -+ char *p, *r, *userstyle; + u_char *p; +- char *userstyle, *cp; ++ char *userstyle, *r, *cp; u_int len; int fail = 0; -@@ -1317,6 +1345,8 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1326,6 +1354,8 @@ monitor_valid_userblob(u_char *data, u_i if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; - p = buffer_get_cstring(&b, NULL); + cp = buffer_get_cstring(&b, NULL); + if ((r = strchr(p, '/')) != NULL) + *r = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1352,7 +1382,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1361,7 +1391,7 @@ monitor_valid_hostbasedblob(u_char *data char *chost) { Buffer b; @@ -298,7 +298,7 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c u_int len; int fail = 0; -@@ -1369,6 +1399,8 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1378,6 +1408,8 @@ monitor_valid_hostbasedblob(u_char *data if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -307,9 +307,9 @@ diff -up openssh-6.8p1/monitor.c.role-mls openssh-6.8p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh-6.8p1/monitor.h.role-mls openssh-6.8p1/monitor.h ---- openssh-6.8p1/monitor.h.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/monitor.h 2015-03-18 11:04:21.047817117 +0100 +diff -up openssh/monitor.h.role-mls openssh/monitor.h +--- openssh/monitor.h.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/monitor.h 2016-07-26 12:37:48.795593331 +0200 @@ -57,6 +57,10 @@ enum monitor_reqtype { MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, @@ -321,10 +321,10 @@ diff -up openssh-6.8p1/monitor.h.role-mls openssh-6.8p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff -up openssh-6.8p1/monitor_wrap.c.role-mls openssh-6.8p1/monitor_wrap.c ---- openssh-6.8p1/monitor_wrap.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/monitor_wrap.c 2015-03-18 11:04:21.047817117 +0100 -@@ -347,6 +347,25 @@ mm_inform_authserv(char *service, char * +diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/monitor_wrap.c 2016-07-26 12:37:48.795593331 +0200 +@@ -346,6 +346,25 @@ mm_inform_authserv(char *service, char * buffer_free(&m); } @@ -350,9 +350,9 @@ diff -up openssh-6.8p1/monitor_wrap.c.role-mls openssh-6.8p1/monitor_wrap.c /* Do the password authentication */ int mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh-6.8p1/monitor_wrap.h.role-mls openssh-6.8p1/monitor_wrap.h ---- openssh-6.8p1/monitor_wrap.h.role-mls 2015-03-18 11:04:21.047817117 +0100 -+++ openssh-6.8p1/monitor_wrap.h 2015-03-18 11:10:32.343936171 +0100 +diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/monitor_wrap.h 2016-07-26 12:37:48.795593331 +0200 @@ -42,6 +42,9 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); @@ -363,21 +363,21 @@ diff -up openssh-6.8p1/monitor_wrap.h.role-mls openssh-6.8p1/monitor_wrap.h struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct Authctxt *, char *); -diff -up openssh-6.8p1/openbsd-compat/Makefile.in.role-mls openssh-6.8p1/openbsd-compat/Makefile.in ---- openssh-6.8p1/openbsd-compat/Makefile.in.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/openbsd-compat/Makefile.in 2015-03-18 11:04:21.047817117 +0100 +diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in +--- openssh/openbsd-compat/Makefile.in.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/openbsd-compat/Makefile.in 2016-07-26 12:37:48.795593331 +0200 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/openbsd-compat/port-linux-sshd.c ---- openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls 2015-03-18 11:04:21.048817114 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux-sshd.c 2015-03-18 11:04:21.048817114 +0100 +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 2016-07-26 12:37:48.796593331 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2016-07-26 12:37:48.796593331 +0200 @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2005 Daniel Walsh @@ -803,9 +803,9 @@ diff -up openssh-6.8p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-6.8p1/o +#endif +#endif + -diff -up openssh-6.8p1/openbsd-compat/port-linux.c.role-mls openssh-6.8p1/openbsd-compat/port-linux.c ---- openssh-6.8p1/openbsd-compat/port-linux.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux.c 2015-03-18 11:04:21.048817114 +0100 +diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c +--- openssh/openbsd-compat/port-linux.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/openbsd-compat/port-linux.c 2016-07-26 12:37:48.796593331 +0200 @@ -103,37 +103,6 @@ ssh_selinux_getctxbyname(char *pwname) return sc; } @@ -844,51 +844,7 @@ diff -up openssh-6.8p1/openbsd-compat/port-linux.c.role-mls openssh-6.8p1/openbs /* Set the TTY context for the specified user */ void ssh_selinux_setup_pty(char *pwname, const char *tty) -diff -up openssh-6.8p1/openbsd-compat/port-linux.h.role-mls openssh-6.8p1/openbsd-compat/port-linux.h ---- openssh-6.8p1/openbsd-compat/port-linux.h.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 11:04:21.048817114 +0100 -@@ -22,9 +22,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-6.8p1/platform.c.role-mls openssh-6.8p1/platform.c ---- openssh-6.8p1/platform.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/platform.c 2015-03-18 11:04:21.048817114 +0100 -@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(stru - } - #endif /* HAVE_SETPCRED */ - #ifdef WITH_SELINUX -- ssh_selinux_setup_exec_context(pw->pw_name); -+ sshd_selinux_setup_exec_context(pw->pw_name); - #endif - } - -diff -up openssh-6.8p1/sshd.c.role-mls openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.role-mls 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 11:04:21.048817114 +0100 -@@ -2220,6 +2220,9 @@ main(int ac, char **av) - restore_uid(); - } - #endif -+#ifdef WITH_SELINUX -+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name); -+#endif - #ifdef USE_PAM - if (options.use_pam) { - do_pam_setcred(1); -diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 22ea8ef..2660085 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -116,7 +116,11 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) +@@ -147,7 +116,11 @@ ssh_selinux_setup_pty(char *pwname, cons debug3("%s: setting TTY context on %s", __func__, tty); @@ -901,3 +857,43 @@ index 22ea8ef..2660085 100644 /* 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 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/openbsd-compat/port-linux.h 2016-07-26 12:37:48.796593331 +0200 +@@ -22,9 +22,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/platform.c.role-mls openssh/platform.c +--- openssh/platform.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/platform.c 2016-07-26 12:37:48.796593331 +0200 +@@ -186,7 +186,7 @@ platform_setusercontext_post_groups(stru + } + #endif /* HAVE_SETPCRED */ + #ifdef WITH_SELINUX +- ssh_selinux_setup_exec_context(pw->pw_name); ++ sshd_selinux_setup_exec_context(pw->pw_name); + #endif + } + +diff -up openssh/sshd.c.role-mls openssh/sshd.c +--- openssh/sshd.c.role-mls 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/sshd.c 2016-07-26 12:37:48.796593331 +0200 +@@ -2295,6 +2295,9 @@ main(int ac, char **av) + restore_uid(); + } + #endif ++#ifdef WITH_SELINUX ++ sshd_selinux_setup_exec_context(authctxt->pw->pw_name); ++#endif + #ifdef USE_PAM + if (options.use_pam) { + do_pam_setcred(1); diff --git a/openssh-6.6p1-set_remote_ipaddr.patch b/openssh-6.6p1-set_remote_ipaddr.patch deleted file mode 100644 index f601e3d..0000000 --- a/openssh-6.6p1-set_remote_ipaddr.patch +++ /dev/null @@ -1,84 +0,0 @@ -diff -up openssh-6.8p1/canohost.c.set_remote_ipaddr openssh-6.8p1/canohost.c ---- openssh-6.8p1/canohost.c.set_remote_ipaddr 2015-03-18 12:40:03.702925550 +0100 -+++ openssh-6.8p1/canohost.c 2015-03-18 12:40:03.749925432 +0100 -@@ -349,6 +349,21 @@ clear_cached_addr(void) - cached_port = -1; - } - -+void set_remote_ipaddr(void) { -+ if (canonical_host_ip != NULL) -+ free(canonical_host_ip); -+ -+ if (active_state != NULL && packet_connection_is_on_socket()) { -+ canonical_host_ip = -+ get_peer_ipaddr(packet_get_connection_in()); -+ if (canonical_host_ip == NULL) -+ cleanup_exit(255); -+ } else { -+ /* If not on socket, return UNKNOWN. */ -+ canonical_host_ip = xstrdup("UNKNOWN"); -+ } -+} -+ - /* - * Returns the IP-address of the remote host as a string. The returned - * string must not be freed. -@@ -358,17 +373,9 @@ const char * - get_remote_ipaddr(void) - { - /* Check whether we have cached the ipaddr. */ -- if (canonical_host_ip == NULL) { -- if (packet_connection_is_on_socket()) { -- canonical_host_ip = -- get_peer_ipaddr(packet_get_connection_in()); -- if (canonical_host_ip == NULL) -- cleanup_exit(255); -- } else { -- /* If not on socket, return UNKNOWN. */ -- canonical_host_ip = xstrdup("UNKNOWN"); -- } -- } -+ if (canonical_host_ip == NULL) -+ set_remote_ipaddr(); -+ - return canonical_host_ip; - } - -diff -up openssh-6.8p1/canohost.h.set_remote_ipaddr openssh-6.8p1/canohost.h ---- openssh-6.8p1/canohost.h.set_remote_ipaddr 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/canohost.h 2015-03-18 12:40:03.749925432 +0100 -@@ -13,6 +13,7 @@ - */ - - const char *get_canonical_hostname(int); -+void set_remote_ipaddr(void); - const char *get_remote_ipaddr(void); - const char *get_remote_name_or_ip(u_int, int); - -diff -up openssh-6.8p1/sshconnect.c.set_remote_ipaddr openssh-6.8p1/sshconnect.c ---- openssh-6.8p1/sshconnect.c.set_remote_ipaddr 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sshconnect.c 2015-03-18 12:40:58.096788804 +0100 -@@ -65,6 +65,7 @@ - #include "authfile.h" - #include "ssherr.h" - #include "authfd.h" -+#include "canohost.h" - - char *client_version_string = NULL; - char *server_version_string = NULL; -@@ -174,6 +175,7 @@ ssh_proxy_fdpass_connect(const char *hos - - /* Set the connection file descriptors. */ - packet_set_connection(sock, sock); -+ set_remote_ipaddr(); - - return 0; - } -@@ -496,6 +498,7 @@ ssh_connect_direct(const char *host, str - - /* Set the connection. */ - packet_set_connection(sock, sock); -+ set_remote_ipaddr(); - - return 0; - } diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 73fe662..143ebad 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,20 +1,3 @@ -diff -up openssh-6.8p1/auth-pam.c.coverity openssh-6.8p1/auth-pam.c ---- openssh-6.8p1/auth-pam.c.coverity 2015-03-18 17:21:51.792265051 +0100 -+++ openssh-6.8p1/auth-pam.c 2015-03-18 17:21:51.895264835 +0100 -@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * - if (sshpam_thread_status != -1) - return (sshpam_thread_status); - signal(SIGCHLD, sshpam_oldsig); -- waitpid(thread, &status, 0); -+ while (waitpid(thread, &status, 0) < 0) { -+ if (errno == EINTR) -+ continue; -+ fatal("%s: waitpid: %s", __func__, -+ strerror(errno)); -+ } - return (status); - } - #endif diff -up openssh-6.8p1/channels.c.coverity openssh-6.8p1/channels.c --- openssh-6.8p1/channels.c.coverity 2015-03-18 17:21:51.815265002 +0100 +++ openssh-6.8p1/channels.c 2015-03-18 17:21:51.896264833 +0100 @@ -60,27 +43,6 @@ diff -up openssh-6.8p1/monitor.c.coverity openssh-6.8p1/monitor.c ; close(pmonitor->m_sendfd); -@@ -1303,6 +1303,10 @@ mm_answer_keyallowed(int sock, Buffer *m - break; - } - } -+ -+ debug3("%s: key %p is %s", -+ __func__, key, allowed ? "allowed" : "not allowed"); -+ - if (key != NULL) - key_free(key); - -@@ -1324,9 +1328,6 @@ mm_answer_keyallowed(int sock, Buffer *m - free(chost); - } - -- debug3("%s: key %p is %s", -- __func__, key, allowed ? "allowed" : "not allowed"); -- - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); diff -up openssh-6.8p1/monitor_wrap.c.coverity openssh-6.8p1/monitor_wrap.c --- openssh-6.8p1/monitor_wrap.c.coverity 2015-03-18 17:21:51.888264849 +0100 +++ openssh-6.8p1/monitor_wrap.c 2015-03-18 17:21:51.897264831 +0100 @@ -270,96 +232,6 @@ diff -up openssh-6.8p1/sftp.c.coverity openssh-6.8p1/sftp.c } _exit(1); -@@ -335,7 +335,7 @@ local_do_ls(const char *args) - - /* Strip one path (usually the pwd) from the start of another */ - static char * --path_strip(char *path, char *strip) -+path_strip(const char *path, const char *strip) - { - size_t len; - -@@ -353,7 +353,7 @@ path_strip(char *path, char *strip) - } - - static char * --make_absolute(char *p, char *pwd) -+make_absolute(char *p, const char *pwd) - { - char *abs_str; - -@@ -551,7 +551,7 @@ parse_no_flags(const char *cmd, char **a - } - - static int --is_dir(char *path) -+is_dir(const char *path) - { - struct stat sb; - -@@ -563,7 +563,7 @@ is_dir(char *path) - } - - static int --remote_is_dir(struct sftp_conn *conn, char *path) -+remote_is_dir(struct sftp_conn *conn, const char *path) - { - Attrib *a; - -@@ -577,7 +577,7 @@ remote_is_dir(struct sftp_conn *conn, ch - - /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ - static int --pathname_is_dir(char *pathname) -+pathname_is_dir(const char *pathname) - { - size_t l = strlen(pathname); - -@@ -585,7 +585,7 @@ pathname_is_dir(char *pathname) - } - - static int --process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag, int resume, int fflag) - { - char *abs_src = NULL; -@@ -669,7 +669,7 @@ out: - } - - static int --process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag, int resume, int fflag) - { - char *tmp_dst = NULL; -@@ -779,7 +779,7 @@ sdirent_comp(const void *aa, const void - - /* sftp ls.1 replacement for directories */ - static int --do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) -+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) - { - int n; - u_int c = 1, colspace = 0, columns = 1; -@@ -864,7 +864,7 @@ do_ls_dir(struct sftp_conn *conn, char * - - /* sftp ls.1 replacement which handles path globs */ - static int --do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, -+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, - int lflag) - { - char *fname, *lname; -@@ -949,7 +949,7 @@ do_globbed_ls(struct sftp_conn *conn, ch - } - - static int --do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) -+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) - { - struct sftp_statvfs st; - char s_used[FMT_SCALED_STRSIZE]; diff -up openssh-6.8p1/ssh-agent.c.coverity openssh-6.8p1/ssh-agent.c --- openssh-6.8p1/ssh-agent.c.coverity 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/ssh-agent.c 2015-03-18 17:21:58.284251454 +0100 @@ -372,8 +244,8 @@ diff -up openssh-6.8p1/ssh-agent.c.coverity openssh-6.8p1/ssh-agent.c + (void) setegid(getgid()); + (void) setgid(getgid()); - #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) - /* Disable ptrace on Linux without sgid bit */ + platform_disable_tracing(0); /* strict=no */ + diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c --- openssh-6.8p1/sshd.c.coverity 2015-03-18 17:21:51.893264839 +0100 +++ openssh-6.8p1/sshd.c 2015-03-18 17:21:58.284251454 +0100 @@ -398,4 +270,4 @@ diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c + free(fdset); } - + /* diff --git a/openssh-6.9p1-scp-progressmeter.patch b/openssh-6.9p1-scp-progressmeter.patch deleted file mode 100644 index c929708..0000000 --- a/openssh-6.9p1-scp-progressmeter.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/progressmeter.c b/progressmeter.c -index 319b747..b54738c 100644 ---- a/progressmeter.c -+++ b/progressmeter.c -@@ -66,7 +66,8 @@ static void update_progress_meter(int); - - static time_t start; /* start progress */ - static time_t last_update; /* last progress update */ --static const char *file; /* name of the file being transferred */ -+static char *file; /* name of the file being transferred */ -+static size_t file_len = 0; /* allocated length of file */ - static off_t start_pos; /* initial position of transfer */ - static off_t end_pos; /* ending position of transfer */ - static off_t cur_pos; /* transfer position as of last refresh */ -@@ -250,7 +251,11 @@ update_progress_meter(int ignore) - start_progress_meter(const char *f, off_t filesize, off_t *ctr) - { - start = last_update = monotime(); -- file = f; -+ if (strlen(f) > file_len) { -+ file_len = strlen(f); -+ file = realloc(file, file_len * 4 + 1); -+ } -+ sanitize_utf8(file, f, file_len); - start_pos = *ctr; - end_pos = filesize; - cur_pos = 0; -diff --git a/Makefile.in b/Makefile.in -index ac45b05..6978081 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -173,8 +173,8 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - --scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o -- $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o -+ $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o - $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/openssh-6.9p1-seccomp-secondary.patch b/openssh-6.9p1-seccomp-secondary.patch deleted file mode 100644 index dce205d..0000000 --- a/openssh-6.9p1-seccomp-secondary.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 24378a7..0bed910 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -811,6 +811,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - aarch64*-*) - seccomp_audit_arch=AUDIT_ARCH_AARCH64 - ;; -+ s390x-*) -+ seccomp_audit_arch=AUDIT_ARCH_S390X -+ ;; -+ s390-*) -+ seccomp_audit_arch=AUDIT_ARCH_S390 -+ ;; -+ powerpc64-*) -+ seccomp_audit_arch=AUDIT_ARCH_PPC64 -+ ;; -+ powerpc64le-*) -+ seccomp_audit_arch=AUDIT_ARCH_PPC64LE -+ ;; -+ mips-*) -+ seccomp_audit_arch=AUDIT_ARCH_MIPS -+ ;; -+ mipsel-*) -+ seccomp_audit_arch=AUDIT_ARCH_MIPSEL -+ ;; -+ mips64-*) -+ seccomp_audit_arch=AUDIT_ARCH_MIPS64 -+ ;; -+ mips64el-*) -+ seccomp_audit_arch=AUDIT_ARCH_MIPSEL64 -+ ;; - esac - if test "x$seccomp_audit_arch" != "x" ; then - AC_MSG_RESULT(["$seccomp_audit_arch"]) - diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index 52c7d73..2666842 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -127,8 +127,8 @@ index 1d03bdf..6af4c62 100644 { u_int i; @@ -2259,7 +2274,6 @@ dump_client_config(Options *o, const char *host) - dump_cfg_fmtint(oControlMaster, o->control_master); dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); + dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); - dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(oForwardAgent, o->forward_agent); diff --git a/openssh-7.1p1-iutf8.patch b/openssh-7.1p1-iutf8.patch deleted file mode 100644 index 89de5c7..0000000 --- a/openssh-7.1p1-iutf8.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/PROTOCOL b/PROTOCOL -index 131adfe..c828087 100644 ---- a/PROTOCOL -+++ b/PROTOCOL -@@ -328,6 +328,11 @@ a server may offer multiple keys of the same type for a period (to - give clients an opportunity to learn them using this extension) before - removing the deprecated key from those offered. - -+2.6. connection: add IUTF8 terminal mode flag -+ -+OpenSSH supports the IUTF8 terminal mode flag and encodes it in "pty-req" -+messages as opcode value 42. -+ - 3. SFTP protocol changes - - 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK -diff --git a/ttymodes.h b/ttymodes.h -index 4d848fe..396ae88 100644 ---- a/ttymodes.h -+++ b/ttymodes.h -@@ -127,6 +127,9 @@ TTYMODE(IXOFF, c_iflag, 40) - #ifdef IMAXBEL - TTYMODE(IMAXBEL,c_iflag, 41) - #endif /* IMAXBEL */ -+#ifdef IUTF8 -+TTYMODE(IUTF8, c_iflag, 42) -+#endif /* IUTF8 */ - - TTYMODE(ISIG, c_lflag, 50) - TTYMODE(ICANON, c_lflag, 51) - diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index 35bed50..081671d 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.2p1/audit-bsm.c.audit openssh-7.2p1/audit-bsm.c ---- openssh-7.2p1/audit-bsm.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/audit-bsm.c 2016-02-12 18:24:34.212825181 +0100 +diff -up openssh-7.3p1/audit-bsm.c.audit openssh-7.3p1/audit-bsm.c +--- openssh-7.3p1/audit-bsm.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/audit-bsm.c 2016-08-02 09:28:22.692299001 +0200 @@ -375,10 +375,23 @@ audit_connection_from(const char *host, #endif } @@ -80,9 +80,9 @@ diff -up openssh-7.2p1/audit-bsm.c.audit openssh-7.2p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-7.2p1/audit.c.audit openssh-7.2p1/audit.c ---- openssh-7.2p1/audit.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/audit.c 2016-02-12 18:24:34.216825179 +0100 +diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c +--- openssh-7.3p1/audit.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/audit.c 2016-08-02 09:28:22.692299001 +0200 @@ -28,6 +28,7 @@ #include @@ -280,9 +280,9 @@ diff -up openssh-7.2p1/audit.c.audit openssh-7.2p1/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.2p1/audit.h.audit openssh-7.2p1/audit.h ---- openssh-7.2p1/audit.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/audit.h 2016-02-12 18:24:34.216825179 +0100 +diff -up openssh-7.3p1/audit.h.audit openssh-7.3p1/audit.h +--- openssh-7.3p1/audit.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/audit.h 2016-08-02 09:28:22.692299001 +0200 @@ -28,6 +28,7 @@ # define _SSH_AUDIT_H @@ -326,10 +326,10 @@ diff -up openssh-7.2p1/audit.h.audit openssh-7.2p1/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c ---- openssh-7.2p1/audit-linux.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/audit-linux.c 2016-02-12 18:24:34.219825178 +0100 -@@ -35,13 +35,25 @@ +diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c +--- openssh-7.3p1/audit-linux.c.audit 2016-08-02 09:28:22.693299000 +0200 ++++ openssh-7.3p1/audit-linux.c 2016-08-02 09:37:19.652010336 +0200 +@@ -35,25 +35,38 @@ #include "log.h" #include "audit.h" @@ -339,27 +339,29 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c +#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" #include "canohost.h" -+#include "packet.h" + #include "packet.h" +- +#include "cipher.h" - ++#include "channels.h" ++#include "session.h" ++ +#define AUDIT_LOG_SIZE 256 + +extern ServerOptions options; +extern Authctxt *the_authctxt; +extern u_int utmp_len; - const char* audit_username(void); + const char *audit_username(void); -int --linux_audit_record_event(int uid, const char *username, -- const char *hostname, const char *ip, const char *ttyn, int success) +-linux_audit_record_event(int uid, const char *username, const char *hostname, +- const char *ip, const char *ttyn, int success) +static void -+linux_audit_user_logxxx(int uid, const char *username, -+ const char *hostname, const char *ip, const char *ttyn, int success, int event) ++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; -@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const - if (audit_fd < 0) { + if ((audit_fd = audit_open()) < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) - return 1; /* No audit support in kernel */ @@ -373,17 +375,17 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -65,35 +77,150 @@ linux_audit_record_event(int uid, const - if ((rc == -EPERM) && (geteuid() != 0)) +@@ -67,9 +80,97 @@ linux_audit_record_event(int uid, const rc = 0; errno = saved_errno; -- return (rc >= 0); + +- return rc >= 0; + if (rc < 0) { +fatal_report: + fatal("linux_audit_write_entry failed: %s", strerror(errno)); + } - } - ++} ++ +static void +linux_audit_user_auth(int uid, const char *username, + const char *hostname, const char *ip, const char *ttyn, int success, int event) @@ -450,33 +452,31 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + else + return 0; /* Must prevent login */ + } -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port()); ++ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", ssh_remote_port(active_state)); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; + snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", -+ type, bits, fp, get_remote_port()); ++ type, bits, fp, ssh_remote_port(active_state)); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), NULL, rv); +out: + saved_errno = errno; + audit_close(audit_fd); + errno = saved_errno; + /* do not report error if the error is EPERM and sshd is run as non root user */ + return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0)); -+} -+ + } + +static int user_login_count = 0; + /* Below is the sshd audit API code */ void - audit_connection_from(const char *host, int port) - { --} +@@ -78,24 +179,51 @@ audit_connection_from(const char *host, /* not implemented */ -+} + } -void +int @@ -484,9 +484,9 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c { - /* not implemented */ + if (!user_login_count++) -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_LOGIN); -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_START); + return 0; +} @@ -494,10 +494,10 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c +void +audit_end_command(int handle, const char *command) +{ -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_END); + if (user_login_count && !--user_login_count) -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_LOGOUT); +} + @@ -510,8 +510,8 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c void audit_session_open(struct logininfo *li) { -- if (linux_audit_record_event(li->uid, NULL, li->hostname, -- NULL, li->line, 1) == 0) +- if (linux_audit_record_event(li->uid, NULL, li->hostname, NULL, +- li->line, 1) == 0) - fatal("linux_audit_write_entry failed: %s", strerror(errno)); + if (!user_login_count++) + linux_audit_user_logxxx(li->uid, NULL, li->hostname, @@ -532,24 +532,23 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c } void -@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) - { +@@ -105,24 +233,180 @@ audit_event(ssh_audit_event_t event) + switch(event) { case SSH_AUTH_SUCCESS: - case SSH_CONNECTION_CLOSE: + linux_audit_user_auth(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 1, event); ++ ssh_remote_ipaddr(ssh), "ssh", 1, event); + break; + case SSH_NOLOGIN: - case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_LOGIN_ROOT_DENIED: + linux_audit_user_auth(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, event); ++ ssh_remote_ipaddr(ssh), "ssh", 0, event); + linux_audit_user_logxxx(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); ++ ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; - + case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_AUTH_FAIL_NONE: case SSH_AUTH_FAIL_PASSWD: @@ -558,15 +557,17 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c case SSH_AUTH_FAIL_HOSTBASED: case SSH_AUTH_FAIL_GSSAPI: + linux_audit_user_auth(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, event); ++ ssh_remote_ipaddr(ssh), "ssh", 0, event); + break; + + case SSH_CONNECTION_CLOSE: + if (user_login_count) { + while (user_login_count--) -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_END); -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), + NULL, "ssh", 1, AUDIT_USER_LOGOUT); + } + break; @@ -574,16 +575,16 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + case SSH_CONNECTION_ABANDON: case SSH_INVALID_USER: - linux_audit_record_event(-1, audit_username(), NULL, -- get_remote_ipaddr(), "sshd", 0); +- ssh_remote_ipaddr(ssh), "sshd", 0); + linux_audit_user_logxxx(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); ++ ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; - default: -@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) + debug("%s: unhandled event %d", __func__, event); + break; } } - ++ +void +audit_unsupported_body(int what) +{ @@ -594,15 +595,15 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + int audit_fd; + + snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ", -+ name[what], get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), -+ get_local_port()); ++ name[what], ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ++ ssh_local_port(active_state)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) + /* no problem, the next instruction will be fatal() */ + return; + audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, get_remote_ipaddr(), NULL, 0); ++ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 0); + audit_close(audit_fd); +#endif +} @@ -622,7 +623,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", + direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, + (intmax_t)pid, (intmax_t)uid, -+ get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); ++ ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ssh_local_port(active_state)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) { @@ -633,7 +634,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + fatal("cannot open audit"); /* Must prevent login */ + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, get_remote_ipaddr(), NULL, 1); ++ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ + if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) @@ -650,9 +651,9 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + + snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", + direction[ctos], (intmax_t)pid, (intmax_t)uid, -+ get_remote_port(), ++ ssh_remote_port(active_state), + (s = get_local_ipaddr(packet_get_connection_in())), -+ get_local_port()); ++ ssh_local_port(active_state)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) { @@ -662,7 +663,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + return; + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, get_remote_ipaddr(), NULL, 1); ++ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ + if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) @@ -686,7 +687,7 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, + buf, NULL, -+ listening_for_clients() ? NULL : get_remote_ipaddr(), ++ listening_for_clients() ? NULL : ssh_remote_ipaddr(active_state), + NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ @@ -716,9 +717,9 @@ diff -up openssh-7.2p1/audit-linux.c.audit openssh-7.2p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-7.2p1/auditstub.c.audit openssh-7.2p1/auditstub.c ---- openssh-7.2p1/auditstub.c.audit 2016-02-12 18:24:34.219825178 +0100 -+++ openssh-7.2p1/auditstub.c 2016-02-12 18:24:34.219825178 +0100 +diff -up openssh-7.3p1/auditstub.c.audit openssh-7.3p1/auditstub.c +--- openssh-7.3p1/auditstub.c.audit 2016-08-02 09:28:22.693299000 +0200 ++++ openssh-7.3p1/auditstub.c 2016-08-02 09:28:22.693299000 +0200 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -770,9 +771,9 @@ diff -up openssh-7.2p1/auditstub.c.audit openssh-7.2p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-7.2p1/auth2.c.audit openssh-7.2p1/auth2.c ---- openssh-7.2p1/auth2.c.audit 2016-02-12 18:24:34.148825205 +0100 -+++ openssh-7.2p1/auth2.c 2016-02-12 18:24:34.219825178 +0100 +diff -up openssh-7.3p1/auth2.c.audit openssh-7.3p1/auth2.c +--- openssh-7.3p1/auth2.c.audit 2016-08-02 09:28:22.685299005 +0200 ++++ openssh-7.3p1/auth2.c 2016-08-02 09:28:22.693299000 +0200 @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { logit("input_userauth_request: invalid user %s", user); @@ -783,10 +784,10 @@ diff -up openssh-7.2p1/auth2.c.audit openssh-7.2p1/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c ---- openssh-7.2p1/auth2-hostbased.c.audit 2016-02-12 18:24:34.109825220 +0100 -+++ openssh-7.2p1/auth2-hostbased.c 2016-02-12 18:24:34.220825178 +0100 -@@ -146,7 +146,7 @@ userauth_hostbased(Authctxt *authctxt) +diff -up openssh-7.3p1/auth2-hostbased.c.audit openssh-7.3p1/auth2-hostbased.c +--- openssh-7.3p1/auth2-hostbased.c.audit 2016-08-02 09:28:22.686299004 +0200 ++++ openssh-7.3p1/auth2-hostbased.c 2016-08-02 09:28:22.693299000 +0200 +@@ -148,7 +148,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && @@ -795,7 +796,7 @@ diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c buffer_len(&b))) == 1) { authenticated = 1; authctxt->last_details = pubkey; -@@ -163,6 +163,18 @@ done: +@@ -169,6 +169,18 @@ done: return authenticated; } @@ -814,10 +815,10 @@ diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c ---- openssh-7.2p1/auth2-pubkey.c.audit 2016-02-12 18:24:34.122825215 +0100 -+++ openssh-7.2p1/auth2-pubkey.c 2016-02-12 18:24:34.220825178 +0100 -@@ -178,7 +178,7 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-7.3p1/auth2-pubkey.c.audit openssh-7.3p1/auth2-pubkey.c +--- openssh-7.3p1/auth2-pubkey.c.audit 2016-08-02 09:28:22.686299004 +0200 ++++ openssh-7.3p1/auth2-pubkey.c 2016-08-02 09:28:22.694299000 +0200 +@@ -179,7 +179,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && @@ -826,7 +827,7 @@ diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c buffer_len(&b))) == 1) { authenticated = 1; authctxt->last_details = pubkey; -@@ -258,6 +258,18 @@ pubkey_auth_info(Authctxt *authctxt, con +@@ -248,6 +248,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } @@ -845,12 +846,12 @@ diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh-7.2p1/auth.c.audit openssh-7.2p1/auth.c ---- openssh-7.2p1/auth.c.audit 2016-02-12 18:24:34.148825205 +0100 -+++ openssh-7.2p1/auth.c 2016-02-12 18:24:34.220825178 +0100 -@@ -646,9 +646,6 @@ getpwnamallow(const char *user) +diff -up openssh-7.3p1/auth.c.audit openssh-7.3p1/auth.c +--- openssh-7.3p1/auth.c.audit 2016-08-02 09:28:22.635299033 +0200 ++++ openssh-7.3p1/auth.c 2016-08-02 09:28:22.694299000 +0200 +@@ -657,9 +657,6 @@ getpwnamallow(const char *user) record_failed_login(user, - get_canonical_hostname(options.use_dns), "ssh"); + auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif -#ifdef SSH_AUDIT_EVENTS - audit_event(SSH_INVALID_USER); @@ -858,10 +859,10 @@ diff -up openssh-7.2p1/auth.c.audit openssh-7.2p1/auth.c return (NULL); } if (!allowed_user(pw)) -diff -up openssh-7.2p1/auth.h.audit openssh-7.2p1/auth.h ---- openssh-7.2p1/auth.h.audit 2016-02-12 18:24:34.108825221 +0100 -+++ openssh-7.2p1/auth.h 2016-02-12 18:32:46.085636046 +0100 -@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt +diff -up openssh-7.3p1/auth.h.audit openssh-7.3p1/auth.h +--- openssh-7.3p1/auth.h.audit 2016-08-02 09:28:22.686299004 +0200 ++++ openssh-7.3p1/auth.h 2016-08-02 09:28:22.694299000 +0200 +@@ -199,6 +199,7 @@ void abandon_challenge_response(Authctxt char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -869,7 +870,7 @@ diff -up openssh-7.2p1/auth.h.audit openssh-7.2p1/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc +@@ -219,6 +220,7 @@ int get_hostkey_index(Key *, int, struc int ssh1_session_key(BIGNUM *); int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); @@ -877,9 +878,9 @@ diff -up openssh-7.2p1/auth.h.audit openssh-7.2p1/auth.h /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-7.2p1/auth-rsa.c.audit openssh-7.2p1/auth-rsa.c ---- openssh-7.2p1/auth-rsa.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/auth-rsa.c 2016-02-12 18:24:34.221825177 +0100 +diff -up openssh-7.3p1/auth-rsa.c.audit openssh-7.3p1/auth-rsa.c +--- openssh-7.3p1/auth-rsa.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/auth-rsa.c 2016-08-02 09:28:22.694299000 +0200 @@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNU { u_char buf[32], mdbuf[16]; @@ -916,9 +917,9 @@ diff -up openssh-7.2p1/auth-rsa.c.audit openssh-7.2p1/auth-rsa.c } /* -diff -up openssh-7.2p1/cipher.c.audit openssh-7.2p1/cipher.c ---- openssh-7.2p1/cipher.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/cipher.c 2016-02-12 18:24:34.221825177 +0100 +diff -up openssh-7.3p1/cipher.c.audit openssh-7.3p1/cipher.c +--- openssh-7.3p1/cipher.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/cipher.c 2016-08-02 09:28:22.694299000 +0200 @@ -57,26 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #endif @@ -946,9 +947,9 @@ diff -up openssh-7.2p1/cipher.c.audit openssh-7.2p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-7.2p1/cipher.h.audit openssh-7.2p1/cipher.h ---- openssh-7.2p1/cipher.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/cipher.h 2016-02-12 18:24:34.221825177 +0100 +diff -up openssh-7.3p1/cipher.h.audit openssh-7.3p1/cipher.h +--- openssh-7.3p1/cipher.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/cipher.h 2016-08-02 09:28:22.694299000 +0200 @@ -62,7 +62,26 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -977,10 +978,10 @@ diff -up openssh-7.2p1/cipher.h.audit openssh-7.2p1/cipher.h struct sshcipher_ctx { int plaintext; int encrypt; -diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c ---- openssh-7.2p1/kex.c.audit 2016-02-12 18:24:34.201825185 +0100 -+++ openssh-7.2p1/kex.c 2016-02-12 18:24:34.221825177 +0100 -@@ -54,6 +54,7 @@ +diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c +--- openssh-7.3p1/kex.c.audit 2016-08-02 09:28:22.676299010 +0200 ++++ openssh-7.3p1/kex.c 2016-08-02 09:28:22.695298999 +0200 +@@ -55,6 +55,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -988,7 +989,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -669,8 +670,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -673,8 +674,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -1002,7 +1003,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -688,8 +693,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -692,8 +697,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1016,7 +1017,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -706,8 +715,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -710,8 +719,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1030,7 +1031,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -878,6 +891,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -882,6 +895,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); @@ -1041,7 +1042,7 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1052,3 +1069,33 @@ dump_digest(char *msg, u_char *digest, i +@@ -1056,3 +1073,33 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1075,21 +1076,21 @@ diff -up openssh-7.2p1/kex.c.audit openssh-7.2p1/kex.c + mac_destroy(&newkeys->mac); + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} -diff -up openssh-7.2p1/kex.h.audit openssh-7.2p1/kex.h ---- openssh-7.2p1/kex.h.audit 2016-03-04 14:25:52.627329892 +0100 -+++ openssh-7.2p1/kex.h 2016-03-04 14:25:52.639329883 +0100 -@@ -206,6 +206,8 @@ int kexgss_client(struct ssh *); +diff -up openssh-7.3p1/kex.h.audit openssh-7.3p1/kex.h +--- openssh-7.3p1/kex.h.audit 2016-08-02 09:28:22.676299010 +0200 ++++ openssh-7.3p1/kex.h 2016-08-02 09:28:22.695298999 +0200 +@@ -212,6 +212,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif +void newkeys_destroy(struct newkeys *newkeys); + - int kex_dh_hash(const char *, const char *, + int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.2p1/key.h.audit openssh-7.2p1/key.h ---- openssh-7.2p1/key.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/key.h 2016-02-12 18:24:34.222825177 +0100 +diff -up openssh-7.3p1/key.h.audit openssh-7.3p1/key.h +--- openssh-7.3p1/key.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/key.h 2016-08-02 09:28:22.695298999 +0200 @@ -50,6 +50,7 @@ typedef struct sshkey Key; #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid @@ -1098,10 +1099,10 @@ diff -up openssh-7.2p1/key.h.audit openssh-7.2p1/key.h #define key_type_plain sshkey_type_plain #define key_curve_name_to_nid sshkey_curve_name_to_nid #define key_curve_nid_to_bits sshkey_curve_nid_to_bits -diff -up openssh-7.2p1/mac.c.audit openssh-7.2p1/mac.c ---- openssh-7.2p1/mac.c.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/mac.c 2016-02-12 18:24:34.222825177 +0100 -@@ -226,6 +226,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh-7.3p1/mac.c.audit openssh-7.3p1/mac.c +--- openssh-7.3p1/mac.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/mac.c 2016-08-02 09:28:22.695298999 +0200 +@@ -245,6 +245,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1122,32 +1123,32 @@ diff -up openssh-7.2p1/mac.c.audit openssh-7.2p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-7.2p1/mac.h.audit openssh-7.2p1/mac.h ---- openssh-7.2p1/mac.h.audit 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/mac.h 2016-02-12 18:24:34.222825177 +0100 -@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); - int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, - u_char *, size_t); +diff -up openssh-7.3p1/mac.h.audit openssh-7.3p1/mac.h +--- openssh-7.3p1/mac.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/mac.h 2016-08-02 09:28:22.695298999 +0200 +@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 + int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, + const u_char *, size_t); void mac_clear(struct sshmac *); +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-7.2p1/Makefile.in.audit openssh-7.2p1/Makefile.in ---- openssh-7.2p1/Makefile.in.audit 2016-02-12 18:24:34.222825177 +0100 -+++ openssh-7.2p1/Makefile.in 2016-02-12 18:33:38.858629492 +0100 +diff -up openssh-7.3p1/Makefile.in.audit openssh-7.3p1/Makefile.in +--- openssh-7.3p1/Makefile.in.audit 2016-08-02 09:28:22.638299031 +0200 ++++ openssh-7.3p1/Makefile.in 2016-08-02 09:28:22.695298999 +0200 @@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ -- platform-pledge.o -+ platform-pledge.o auditstub.o +- platform-pledge.o platform-tracing.o ++ platform-pledge.o platform-tracing.o auditstub.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c ---- openssh-7.2p1/monitor.c.audit 2016-02-12 18:24:34.176825195 +0100 -+++ openssh-7.2p1/monitor.c 2016-02-12 18:34:05.184629882 +0100 -@@ -101,6 +101,7 @@ +diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c +--- openssh-7.3p1/monitor.c.audit 2016-08-02 09:28:22.687299004 +0200 ++++ openssh-7.3p1/monitor.c 2016-08-02 09:28:22.696298999 +0200 +@@ -103,6 +103,7 @@ #include "compat.h" #include "ssh2.h" #include "authfd.h" @@ -1155,7 +1156,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #include "match.h" #include "ssherr.h" -@@ -116,6 +117,8 @@ extern Buffer auth_debug; +@@ -118,6 +119,8 @@ extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; @@ -1164,7 +1165,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c /* State exported from the child */ static struct sshbuf *child_state; -@@ -166,6 +169,11 @@ int mm_answer_gss_updatecreds(int, Buffe +@@ -168,6 +171,11 @@ int mm_answer_gss_updatecreds(int, Buffe #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); @@ -1176,7 +1177,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #endif static int monitor_read_log(struct monitor *); -@@ -225,6 +233,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -227,6 +235,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1187,7 +1188,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -263,6 +275,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -265,6 +277,11 @@ struct mon_table mon_dispatch_postauth20 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1199,7 +1200,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #endif {0, 0, NULL} }; -@@ -295,6 +312,10 @@ struct mon_table mon_dispatch_proto15[] +@@ -297,6 +314,10 @@ struct mon_table mon_dispatch_proto15[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1210,7 +1211,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #endif #endif /* WITH_SSH1 */ {0, 0, NULL} -@@ -308,6 +329,11 @@ struct mon_table mon_dispatch_postauth15 +@@ -310,6 +331,11 @@ struct mon_table mon_dispatch_postauth15 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, @@ -1222,7 +1223,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c #endif #endif /* WITH_SSH1 */ {0, 0, NULL} -@@ -1464,9 +1490,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1488,9 +1514,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1234,7 +1235,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1474,6 +1502,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1498,6 +1526,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1243,7 +1244,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1494,7 +1524,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1518,7 +1548,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1262,7 +1263,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1555,6 +1595,12 @@ mm_session_close(Session *s) +@@ -1584,6 +1624,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1275,7 +1276,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c session_unused(s->self); } -@@ -1837,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1866,6 +1912,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1284,7 +1285,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1879,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff +@@ -1908,11 +1956,43 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1329,7 +1330,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c free(cmd); return (0); } -@@ -1940,6 +2020,7 @@ monitor_apply_keystate(struct monitor *p +@@ -1972,6 +2052,7 @@ monitor_apply_keystate(struct monitor *p void mm_get_keystate(struct monitor *pmonitor) { @@ -1337,7 +1338,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1947,6 +2028,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1979,6 +2060,21 @@ mm_get_keystate(struct monitor *pmonitor mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); @@ -1359,7 +1360,7 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c } -@@ -2213,3 +2309,86 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -2248,3 +2344,86 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1446,9 +1447,9 @@ diff -up openssh-7.2p1/monitor.c.audit openssh-7.2p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.2p1/monitor.h.audit openssh-7.2p1/monitor.h ---- openssh-7.2p1/monitor.h.audit 2016-02-12 18:24:34.177825194 +0100 -+++ openssh-7.2p1/monitor.h 2016-02-12 18:24:34.224825176 +0100 +diff -up openssh-7.3p1/monitor.h.audit openssh-7.3p1/monitor.h +--- openssh-7.3p1/monitor.h.audit 2016-08-02 09:28:22.660299019 +0200 ++++ openssh-7.3p1/monitor.h 2016-08-02 09:28:22.696298999 +0200 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1464,10 +1465,10 @@ diff -up openssh-7.2p1/monitor.h.audit openssh-7.2p1/monitor.h }; -diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c ---- openssh-7.2p1/monitor_wrap.c.audit 2016-02-12 18:24:34.151825204 +0100 -+++ openssh-7.2p1/monitor_wrap.c 2016-02-12 18:24:34.224825176 +0100 -@@ -462,7 +462,7 @@ mm_key_allowed(enum mm_keytype type, cha +diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c +--- openssh-7.3p1/monitor_wrap.c.audit 2016-08-02 09:28:22.639299030 +0200 ++++ openssh-7.3p1/monitor_wrap.c 2016-08-02 09:28:22.696298999 +0200 +@@ -466,7 +466,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1476,7 +1477,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c { Buffer m; u_char *blob; -@@ -476,6 +476,7 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -480,6 +480,7 @@ mm_key_verify(Key *key, u_char *sig, u_i return (0); buffer_init(&m); @@ -1484,7 +1485,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -493,6 +494,18 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -497,6 +498,18 @@ mm_key_verify(Key *key, u_char *sig, u_i return (verified); } @@ -1503,7 +1504,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c void mm_send_keystate(struct monitor *monitor) { -@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -1010,10 +1023,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1516,7 +1517,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command +@@ -1021,6 +1035,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1543,7 +1544,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1151,3 +1185,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1156,3 +1190,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1614,20 +1615,20 @@ diff -up openssh-7.2p1/monitor_wrap.c.audit openssh-7.2p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.2p1/monitor_wrap.h.audit openssh-7.2p1/monitor_wrap.h ---- openssh-7.2p1/monitor_wrap.h.audit 2016-02-12 18:24:34.152825204 +0100 -+++ openssh-7.2p1/monitor_wrap.h 2016-02-12 18:24:34.224825176 +0100 -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char - int mm_user_key_allowed(struct passwd *, Key *, int); - int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); - int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); +diff -up openssh-7.3p1/monitor_wrap.h.audit openssh-7.3p1/monitor_wrap.h +--- openssh-7.3p1/monitor_wrap.h.audit 2016-08-02 09:28:22.639299030 +0200 ++++ openssh-7.3p1/monitor_wrap.h 2016-08-02 09:28:22.696298999 +0200 +@@ -54,7 +54,8 @@ int mm_hostbased_key_allowed(struct pass + const char *, Key *); + int mm_auth_rhosts_rsa_key_allowed(struct passwd *, const char *, + const char *, Key *); -int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); +int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); +int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); BIGNUM *mm_auth_rsa_generate_challenge(Key *); -@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); +@@ -81,7 +82,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); @@ -1641,10 +1642,10 @@ diff -up openssh-7.2p1/monitor_wrap.h.audit openssh-7.2p1/monitor_wrap.h #endif struct Session; -diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c ---- openssh-7.2p1/packet.c.audit 2016-02-12 18:24:34.095825226 +0100 -+++ openssh-7.2p1/packet.c 2016-02-12 18:43:47.268638489 +0100 -@@ -67,6 +67,7 @@ +diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c +--- openssh-7.3p1/packet.c.audit 2016-08-02 09:28:22.582299062 +0200 ++++ openssh-7.3p1/packet.c 2016-08-02 09:28:22.697298998 +0200 +@@ -68,6 +68,7 @@ #include "key.h" /* typedefs XXX */ #include "xmalloc.h" @@ -1652,7 +1653,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c #include "crc32.h" #include "deattack.h" #include "compat.h" -@@ -456,6 +457,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -468,6 +469,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1666,7 +1667,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -500,13 +508,6 @@ ssh_packet_close(struct ssh *ssh) +@@ -537,13 +545,6 @@ ssh_packet_close(struct ssh *ssh) if (!state->initialized) return; state->initialized = 0; @@ -1680,7 +1681,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); -@@ -538,12 +539,22 @@ ssh_packet_close(struct ssh *ssh) +@@ -575,12 +576,22 @@ ssh_packet_close(struct ssh *ssh) inflateEnd(stream); } } @@ -1707,7 +1708,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c free(ssh->state); ssh->state = NULL; } -@@ -968,6 +979,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod +@@ -1005,6 +1016,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod (unsigned long long)state->p_read.blocks, (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); @@ -1715,7 +1716,7 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; -@@ -2408,6 +2420,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2450,6 +2462,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1788,19 +1789,19 @@ diff -up openssh-7.2p1/packet.c.audit openssh-7.2p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-7.2p1/packet.h.audit openssh-7.2p1/packet.h ---- openssh-7.2p1/packet.h.audit 2016-02-26 04:40:04.000000000 +0100 -+++ openssh-7.2p1/packet.h 2016-03-04 14:25:52.640329883 +0100 -@@ -200,4 +200,5 @@ extern struct ssh *active_state; +diff -up openssh-7.3p1/packet.h.audit openssh-7.3p1/packet.h +--- openssh-7.3p1/packet.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/packet.h 2016-08-02 09:28:22.697298998 +0200 +@@ -204,4 +204,5 @@ extern struct ssh *active_state; # undef EC_POINT #endif +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-7.2p1/sandbox-seccomp-filter.c.audit openssh-7.2p1/sandbox-seccomp-filter.c ---- openssh-7.2p1/sandbox-seccomp-filter.c.audit 2016-02-12 18:24:34.193825188 +0100 -+++ openssh-7.2p1/sandbox-seccomp-filter.c 2016-02-12 18:24:34.226825175 +0100 -@@ -153,6 +153,12 @@ static const struct sock_filter preauth_ +diff -up openssh-7.3p1/sandbox-seccomp-filter.c.audit openssh-7.3p1/sandbox-seccomp-filter.c +--- openssh-7.3p1/sandbox-seccomp-filter.c.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/sandbox-seccomp-filter.c 2016-08-02 09:28:22.697298998 +0200 +@@ -159,6 +159,12 @@ static const struct sock_filter preauth_ #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), #endif @@ -1813,10 +1814,10 @@ diff -up openssh-7.2p1/sandbox-seccomp-filter.c.audit openssh-7.2p1/sandbox-secc #ifdef __NR_madvise SC_ALLOW(madvise), #endif -diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c ---- openssh-7.2p1/session.c.audit 2016-02-12 18:24:34.177825194 +0100 -+++ openssh-7.2p1/session.c 2016-02-12 18:24:34.226825175 +0100 -@@ -139,7 +139,7 @@ extern int log_stderr; +diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c +--- openssh-7.3p1/session.c.audit 2016-08-02 09:28:22.691299001 +0200 ++++ openssh-7.3p1/session.c 2016-08-02 09:28:22.698298997 +0200 +@@ -144,7 +144,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1825,7 +1826,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c extern Buffer loginmsg; /* original command from peer. */ -@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm +@@ -757,6 +757,14 @@ do_exec_pty(Session *s, const char *comm /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1840,7 +1841,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) +@@ -882,15 +890,19 @@ do_exec(Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1862,7 +1863,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1695,7 +1707,10 @@ do_child(Session *s, const char *command +@@ -1756,7 +1768,10 @@ do_child(Session *s, const char *command int r = 0; /* remove hostkey from the child's memory */ @@ -1874,7 +1875,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1925,6 +1940,7 @@ session_unused(int id) +@@ -1986,6 +2001,7 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1882,7 +1883,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2007,6 +2023,19 @@ session_open(Authctxt *authctxt, int cha +@@ -2068,6 +2084,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1902,7 +1903,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c session_by_tty(char *tty) { int i; -@@ -2523,6 +2552,32 @@ session_exit_message(Session *s, int sta +@@ -2590,6 +2619,32 @@ session_exit_message(Session *s, int sta chan_write_failed(c); } @@ -1935,7 +1936,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c void session_close(Session *s) { -@@ -2531,6 +2586,10 @@ session_close(Session *s) +@@ -2604,6 +2659,10 @@ session_close(Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1946,7 +1947,7 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2745,6 +2804,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2818,6 +2877,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -1962,16 +1963,18 @@ diff -up openssh-7.2p1/session.c.audit openssh-7.2p1/session.c void do_cleanup(Authctxt *authctxt) { -@@ -2793,5 +2861,5 @@ do_cleanup(Authctxt *authctxt) +@@ -2869,7 +2937,7 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) - session_destroy_all(session_pty_cleanup2); + session_destroy_all(do_cleanup_one_session); } -diff -up openssh-7.2p1/session.h.audit openssh-7.2p1/session.h ---- openssh-7.2p1/session.h.audit 2016-02-26 04:40:04.000000000 +0100 -+++ openssh-7.2p1/session.h 2016-03-04 14:25:52.641329882 +0100 + + /* Return a name for the remote host that fits inside utmp_size */ +diff -up openssh-7.3p1/session.h.audit openssh-7.3p1/session.h +--- openssh-7.3p1/session.h.audit 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/session.h 2016-08-02 09:28:22.698298997 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -1996,9 +1999,9 @@ diff -up openssh-7.2p1/session.h.audit openssh-7.2p1/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c ---- openssh-7.2p1/sshd.c.audit 2016-02-12 18:24:34.189825190 +0100 -+++ openssh-7.2p1/sshd.c 2016-02-12 18:44:44.650639338 +0100 +diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c +--- openssh-7.3p1/sshd.c.audit 2016-08-02 09:28:22.667299015 +0200 ++++ openssh-7.3p1/sshd.c 2016-08-02 09:28:22.698298997 +0200 @@ -121,6 +121,7 @@ #include "ssh-gss.h" #endif @@ -2026,13 +2029,13 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c + */ +int listening_for_clients(void) +{ -+ return num_listen_socks > 0; ++ return num_listen_socks >= 0; +} + static void close_startup_pipes(void) { -@@ -560,22 +570,49 @@ sshd_exchange_identification(int sock_in +@@ -566,22 +576,49 @@ sshd_exchange_identification(struct ssh } } @@ -2085,7 +2088,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -590,7 +627,13 @@ demote_sensitive_data(void) +@@ -596,7 +633,13 @@ demote_sensitive_data(void) { Key *tmp; int i; @@ -2099,7 +2102,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c if (sensitive_data.server_key) { tmp = key_demote(sensitive_data.server_key); key_free(sensitive_data.server_key); -@@ -599,11 +642,23 @@ demote_sensitive_data(void) +@@ -605,11 +648,23 @@ demote_sensitive_data(void) for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { @@ -2123,7 +2126,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c } /* Certs do not need demotion */ } -@@ -675,7 +722,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -681,7 +736,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2132,7 +2135,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -760,6 +807,12 @@ privsep_postauth(Authctxt *authctxt) +@@ -766,6 +821,12 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); @@ -2145,7 +2148,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1293,6 +1346,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1310,6 +1371,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2153,7 +2156,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2256,6 +2310,7 @@ main(int ac, char **av) +@@ -2335,6 +2397,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2161,7 +2164,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c exit(0); } -@@ -2301,7 +2356,7 @@ main(int ac, char **av) +@@ -2380,7 +2443,7 @@ main(int ac, char **av) privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) @@ -2170,7 +2173,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c } packet_set_timeout(options.client_alive_interval, -@@ -2315,6 +2370,9 @@ main(int ac, char **av) +@@ -2394,6 +2457,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2180,7 +2183,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2475,6 +2533,10 @@ do_ssh1_kex(void) +@@ -2556,6 +2622,10 @@ do_ssh1_kex(void) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); @@ -2191,7 +2194,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ -@@ -2534,7 +2596,7 @@ do_ssh1_kex(void) +@@ -2616,7 +2686,7 @@ do_ssh1_kex(void) } /* Destroy the private and public keys. No longer. */ @@ -2200,7 +2203,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c if (use_privsep) mm_ssh1_session_id(session_id); -@@ -2708,6 +2770,16 @@ do_ssh2_kex(void) +@@ -2794,6 +2864,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2217,7 +2220,7 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2719,9 +2791,14 @@ cleanup_exit(int i) +@@ -2805,9 +2885,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2233,10 +2236,10 @@ diff -up openssh-7.2p1/sshd.c.audit openssh-7.2p1/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-7.2p1/sshkey.c.audit openssh-7.2p1/sshkey.c ---- openssh-7.2p1/sshkey.c.audit 2016-02-12 18:24:34.157825202 +0100 -+++ openssh-7.2p1/sshkey.c 2016-02-12 18:24:34.228825175 +0100 -@@ -303,6 +303,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-7.3p1/sshkey.c.audit openssh-7.3p1/sshkey.c +--- openssh-7.3p1/sshkey.c.audit 2016-08-02 09:28:22.689299002 +0200 ++++ openssh-7.3p1/sshkey.c 2016-08-02 09:28:22.699298997 +0200 +@@ -304,6 +304,33 @@ sshkey_type_is_valid_ca(int type) } int @@ -2270,10 +2273,10 @@ diff -up openssh-7.2p1/sshkey.c.audit openssh-7.2p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-7.2p1/sshkey.h.audit openssh-7.2p1/sshkey.h ---- openssh-7.2p1/sshkey.h.audit 2016-02-12 18:24:34.157825202 +0100 -+++ openssh-7.2p1/sshkey.h 2016-02-12 18:24:34.228825175 +0100 -@@ -133,6 +133,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-7.3p1/sshkey.h.audit openssh-7.3p1/sshkey.h +--- openssh-7.3p1/sshkey.h.audit 2016-08-02 09:28:22.689299002 +0200 ++++ openssh-7.3p1/sshkey.h 2016-08-02 09:28:22.699298997 +0200 +@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index f9fc406..c405be7 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -114,9 +114,9 @@ diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c --- openssh-7.2p1/kex.c.fips 2016-02-12 18:53:56.084665234 +0100 +++ openssh-7.2p1/kex.c 2016-02-12 18:53:56.091665235 +0100 @@ -35,6 +35,7 @@ - #ifdef WITH_OPENSSL #include + #include +#include #endif @@ -281,8 +281,8 @@ diff -up openssh-7.2p1/Makefile.in.fips openssh-7.2p1/Makefile.in - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o - $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -320,7 +320,7 @@ diff -up openssh-7.2p1/myproposal.h.fips openssh-7.2p1/myproposal.h +#define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ -+ KEX_SHA256_METHODS \ ++ KEX_SHA2_METHODS \ + "diffie-hellman-group-exchange-sha1," \ + "diffie-hellman-group14-sha1" +#define KEX_FIPS_ENCRYPT \ @@ -433,7 +433,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ @@ -608,6 +618,9 @@ main(int ac, char **av) - "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { + "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': + if (FIPS_mode()) { @@ -495,7 +495,7 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c - orig = options.kex_algorithms; - - if (options.gss_trust_dns) -- gss_host = (char *)get_canonical_hostname(1); +- gss_host = (char *)get_canonical_hostname(active_state, 1); - else - gss_host = host; - @@ -514,7 +514,7 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c + orig = options.kex_algorithms; + + if (options.gss_trust_dns) -+ gss_host = (char *)get_canonical_hostname(1); ++ gss_host = (char *)get_canonical_hostname(active_state, 1); + else + gss_host = host; + @@ -683,10 +683,10 @@ index 7efe312..bcf2ae1 100644 #define KEX_DEFAULT_KEX_FIPS \ KEX_ECDH_METHODS \ -- KEX_SHA256_METHODS \ +- KEX_SHA2_METHODS \ - "diffie-hellman-group-exchange-sha1," \ - "diffie-hellman-group14-sha1" -+ KEX_SHA256_METHODS ++ KEX_SHA2_METHODS #define KEX_FIPS_ENCRYPT \ "aes128-ctr,aes192-ctr,aes256-ctr," \ "aes128-cbc,3des-cbc," \ diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 4544c54..cc4aa20 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -179,7 +179,7 @@ diff -up openssh-7.2p1/configure.ac.gsskex openssh-7.2p1/configure.ac + [AC_MSG_RESULT(no)] + ) m4_pattern_allow([AU_IPv]) - AC_CHECK_DECL([AU_IPv4], [], + AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c --- openssh-7.2p1/gss-genr.c.gsskex 2016-02-12 11:47:25.000000000 +0100 @@ -1251,7 +1251,7 @@ diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: -+ kex_dh_hash( ssh->kex->client_version_string, ++ kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, + ssh->kex->server_version_string, + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), @@ -1320,7 +1320,7 @@ diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c --- openssh-7.2p1/kexgsss.c.gsskex 2016-02-19 10:01:04.868969323 +0100 +++ openssh-7.2p1/kexgsss.c 2016-02-19 10:01:04.868969323 +0100 -@@ -0,0 +1,295 @@ +@@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1392,6 +1392,7 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c + u_char *kbuf; + DH *dh; + int min = -1, max = -1, nbits = -1; ++ int cmin = -1, cmax = -1; /* client proposal */ + BIGNUM *shared_secret = NULL; + BIGNUM *dh_client_pub = NULL; + int type = 0; @@ -1430,11 +1431,12 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange"); + packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); -+ min = packet_get_int(); ++ /* store client proposal to provide valid signature */ ++ cmin = packet_get_int(); + nbits = packet_get_int(); -+ max = packet_get_int(); -+ min = MAX(DH_GRP_MIN, min); -+ max = MIN(DH_GRP_MAX, max); ++ cmax = packet_get_int(); ++ min = MAX(DH_GRP_MIN, cmin); ++ max = MIN(DH_GRP_MAX, cmax); + packet_check_eom(); + if (max < min || nbits < min || max < nbits) + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", @@ -1541,7 +1543,7 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: -+ kex_dh_hash( ++ kex_dh_hash(ssh->kex->hash_alg, + ssh->kex->client_version_string, ssh->kex->server_version_string, + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), @@ -1557,7 +1559,7 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, -+ min, nbits, max, ++ cmin, nbits, cmax, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, @@ -1653,14 +1655,14 @@ diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h +int kexgss_server(struct ssh *); +#endif - int kex_dh_hash(const char *, const char *, + int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh-7.2p1/Makefile.in.gsskex openssh-7.2p1/Makefile.in ---- openssh-7.2p1/Makefile.in.gsskex 2016-02-19 10:01:04.864969325 +0100 -+++ openssh-7.2p1/Makefile.in 2016-02-19 10:01:04.868969323 +0100 +diff -up openssh/Makefile.in.gsskex openssh/Makefile.in +--- openssh/Makefile.in.gsskex 2016-07-25 14:11:42.978324182 +0200 ++++ openssh/Makefile.in 2016-07-25 14:14:15.560289050 +0200 @@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ - atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ + atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ @@ -2064,21 +2066,21 @@ diff -up openssh-7.2p1/readconf.h.gsskex openssh-7.2p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-7.2p1/regress/cert-hostkey.sh.gsskex openssh-7.2p1/regress/cert-hostkey.sh ---- openssh-7.2p1/regress/cert-hostkey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/regress/cert-hostkey.sh 2016-02-19 10:01:04.870969322 +0100 -@@ -46,7 +46,7 @@ touch $OBJ/host_revoked_plain +diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh +--- openssh/regress/cert-hostkey.sh.gsskex 2016-07-25 14:11:42.986324181 +0200 ++++ openssh/regress/cert-hostkey.sh 2016-07-25 14:15:17.784274722 +0200 +@@ -59,7 +59,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert - cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca + cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` - # Prepare certificate, plain key and CA KRLs - ${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" -diff -up openssh-7.2p1/regress/cert-userkey.sh.gsskex openssh-7.2p1/regress/cert-userkey.sh ---- openssh-7.2p1/regress/cert-userkey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/regress/cert-userkey.sh 2016-02-19 10:01:04.870969322 +0100 + if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then + PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" +diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh +--- openssh/regress/cert-userkey.sh.gsskex 2016-07-25 14:11:42.986324181 +0200 ++++ openssh/regress/cert-userkey.sh 2016-07-25 14:15:36.769270354 +0200 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2086,11 +2088,11 @@ diff -up openssh-7.2p1/regress/cert-userkey.sh.gsskex openssh-7.2p1/regress/cert -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` - kname() { - n=`echo "$1" | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/'` -diff -up openssh-7.2p1/regress/kextype.sh.gsskex openssh-7.2p1/regress/kextype.sh ---- openssh-7.2p1/regress/kextype.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/regress/kextype.sh 2016-02-19 10:01:04.870969322 +0100 + if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then + PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" +diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh +--- openssh/regress/kextype.sh.gsskex 2016-07-24 13:50:13.000000000 +0200 ++++ openssh/regress/kextype.sh 2016-07-25 14:11:42.987324180 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2304,7 +2306,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c + orig = options.kex_algorithms; + + if (options.gss_trust_dns) -+ gss_host = (char *)get_canonical_hostname(1); ++ gss_host = (char *)get_canonical_hostname(active_state, 1); + else + gss_host = host; + @@ -2399,7 +2401,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c + if (options.gss_server_identity) + gss_host = options.gss_server_identity; + else if (options.gss_trust_dns) -+ gss_host = get_canonical_hostname(1); ++ gss_host = get_canonical_hostname(active_state, 1); + else + gss_host = authctxt->host; @@ -2739,41 +2741,264 @@ diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h KEY_UNSPEC }; -diff --git a/kexgsss.c b/kexgsss.c -index b2f9658..2d33ff7 100644 ---- a/kexgsss.c -+++ b/kexgsss.c -@@ -69,6 +69,7 @@ kexgss_server(struct ssh *ssh) - u_char *kbuf; - DH *dh; - int min = -1, max = -1, nbits = -1; -+ int cmin = -1, cmax = -1; /* client proposal */ - BIGNUM *shared_secret = NULL; - BIGNUM *dh_client_pub = NULL; - int type = 0; -@@ -107,11 +108,12 @@ kexgss_server(struct ssh *ssh) - case KEX_GSS_GEX_SHA1: - debug("Doing group exchange"); - packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); -- min = packet_get_int(); -+ /* store client proposal to provide valid signature */ -+ cmin = packet_get_int(); - nbits = packet_get_int(); -- max = packet_get_int(); -- min = MAX(DH_GRP_MIN, min); -- max = MIN(DH_GRP_MAX, max); -+ cmax = packet_get_int(); -+ min = MAX(DH_GRP_MIN, cmin); -+ max = MIN(DH_GRP_MAX, cmax); - packet_check_eom(); - if (max < min || nbits < min || max < nbits) - fatal("GSS_GEX, bad parameters: %d !< %d !< %d", -@@ -234,7 +236,7 @@ kexgss_server(struct ssh *ssh) - buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), - buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), - NULL, 0, -- min, nbits, max, -+ cmin, nbits, cmax, - dh->p, dh->g, - dh_client_pub, - dh->pub_key, +diff --git a/auth.c b/auth.c +index e0f7639..a5a346e 100644 +--- a/auth.c ++++ b/auth.c +@@ -784,99 +784,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 legacy rhosts-style authentication. +- * XXX is RhostsRSAAuthentication vulnerable to these? +- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) +- */ +- +-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) < 0) { +- debug("getpeername failed: %.100s", strerror(errno)); +- return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); +- } +- return strdup(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/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 80729b3..93a1b04 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -32,6 +32,8 @@ + #include "log.h" + #include "xmalloc.h" + #include "port-linux.h" ++#include "canohost.h" ++#include "misc.h" + + #ifdef WITH_SELINUX + #include +@@ -286,4 +288,121 @@ oom_adjust_restore(void) + return; + } + #endif /* LINUX_OOM_ADJUST */ ++ ++/**************** XXX moved from auth.c ****************/ ++ ++/* ++ * 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 legacy rhosts-style authentication. ++ * XXX is RhostsRSAAuthentication vulnerable to these? ++ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) ++ */ ++ ++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) < 0) { ++ debug("getpeername failed: %.100s", strerror(errno)); ++ return strdup(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 strdup(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 strdup(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 - POSSIBLE BREAK-IN ATTEMPT!", name, ntop); ++ return strdup(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 - POSSIBLE BREAK-IN ATTEMPT!", ++ ntop, name); ++ return strdup(ntop); ++ } ++ return strdup(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. ++ */ ++ ++const char * ++get_canonical_hostname(struct ssh *ssh, int use_dns) ++{ ++ static char *dnsname; ++ ++ if (!use_dns) ++ return ssh_remote_ipaddr(ssh); ++ else if (dnsname != NULL) ++ return dnsname; ++ else { ++ dnsname = remote_hostname(ssh); ++ return dnsname; ++ } ++} + #endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ +diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h +index e2ca8a1..6c5ac3f 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -18,6 +18,7 @@ + + #ifndef _PORT_LINUX_H + #define _PORT_LINUX_H ++#include "packet.h" + + #ifdef WITH_SELINUX + int ssh_selinux_enabled(void); +@@ -39,4 +40,8 @@ void oom_adjust_setup(void); + + void linux_seed(void); + ++const char *get_canonical_hostname(struct ssh *, int); ++char *remote_hostname(struct ssh *); ++ ++ + #endif /* ! _PORT_LINUX_H */ + diff --git a/openssh-7.2p2-CVE-2015-8325.patch b/openssh-7.2p2-CVE-2015-8325.patch deleted file mode 100644 index 4224051..0000000 --- a/openssh-7.2p2-CVE-2015-8325.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 85bdcd7c92fe7ff133bbc4e10a65c91810f88755 Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Wed, 13 Apr 2016 10:39:57 +1000 -Subject: ignore PAM environment vars when UseLogin=yes - -If PAM is configured to read user-specified environment variables -and UseLogin=yes in sshd_config, then a hostile local user may -attack /bin/login via LD_PRELOAD or similar environment variables -set via PAM. - -CVE-2015-8325, found by Shayan Sadigh, via Colin Watson ---- - session.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/session.c b/session.c -index 4859245..4653b09 100644 ---- a/session.c -+++ b/session.c -@@ -1322,7 +1322,7 @@ do_setup_env(Session *s, const char *shell) - * Pull in any environment variables that may have - * been set by PAM. - */ -- if (options.use_pam) { -+ if (options.use_pam && !options.use_login) { - char **p; - - p = fetch_pam_child_environment(); --- -cgit v0.11.2 - - diff --git a/openssh-7.2p2-certificats-regress.patch b/openssh-7.2p2-certificats-regress.patch deleted file mode 100644 index 8b08319..0000000 --- a/openssh-7.2p2-certificats-regress.patch +++ /dev/null @@ -1,38 +0,0 @@ -commit c38905ba391434834da86abfc988a2b8b9b62477 -Author: djm@openbsd.org -Date: Mon Mar 14 16:20:54 2016 +0000 - - upstream commit - - unbreak authentication using lone certificate keys in - ssh-agent: when attempting pubkey auth with a certificate, if no separate - private key is found among the keys then try with the certificate key itself. - - bz#2550 reported by Peter Moody - - Upstream-ID: f939cd76d68e6a9a3d1711b5a943d6ed1e623966 - -diff --git a/sshconnect2.c b/sshconnect2.c -index f79c96b..1cf48a2 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect2.c,v 1.239 2016/02/23 01:34:14 djm Exp $ */ -+/* $OpenBSD: sshconnect2.c,v 1.240 2016/03/14 16:20:54 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2008 Damien Miller. All rights reserved. -@@ -1112,12 +1112,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) - "certificate", __func__, id->filename, - id->agent_fd != -1 ? " from agent" : ""); - } else { -- /* XXX maybe verbose/error? */ -- debug("%s: no private key for certificate " -+ debug("%s: no separate private key for certificate " - "\"%s\"", __func__, id->filename); -- free(blob); -- buffer_free(&b); -- return 0; - } - } - diff --git a/openssh-7.2p2-chroot-capabilities.patch b/openssh-7.2p2-chroot-capabilities.patch new file mode 100644 index 0000000..69a5342 --- /dev/null +++ b/openssh-7.2p2-chroot-capabilities.patch @@ -0,0 +1,102 @@ +diff --git a/configure.ac b/configure.ac +index aeef42a..d01e67e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -4998,6 +4998,37 @@ if test -n "$conf_lastlog_location"; then + [Define if you want to specify the path to your lastlog file]) + fi + ++AC_ARG_WITH(libcap-ng, ++ [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],, ++ with_libcap_ng=auto) ++ ++dnl libcap-ng detection ++if test x$with_libcap_ng = xno ; then ++ have_libcap_ng=no; ++else ++ # Start by checking for header file ++ AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no) ++ ++ # See if we have libcap-ng library ++ AC_CHECK_LIB(cap-ng, capng_clear, CAPNG_LDADD=-lcap-ng,) ++ ++ # Check results are usable ++ if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then ++ AC_MSG_ERROR(libcap-ng support was requested and the library was not found) ++ fi ++ if test x$CAPNG_LDADD != x -a $capng_headers = no ; then ++ AC_MSG_ERROR(libcap-ng libraries found but headers are missing) ++ fi ++fi ++AC_MSG_CHECKING(whether to use libcap-ng) ++if test x$CAPNG_LDADD != x ; then ++ AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support]) ++ SSHDLIBS="$SSHDLIBS -lcap-ng" ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) ++fi ++ + dnl utmp detection + AC_MSG_CHECKING([if your system defines UTMP_FILE]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +diff --git a/session.c b/session.c +index 6cfcba4..80d2806 100644 +--- a/session.c ++++ b/session.c +@@ -96,6 +96,10 @@ + #include "monitor_wrap.h" + #include "sftp.h" + ++#ifdef HAVE_LIBCAP_NG ++#include ++#endif ++ + #if defined(KRB5) && defined(USE_AFS) + #include + #endif +@@ -1586,6 +1590,7 @@ void + do_setusercontext(struct passwd *pw) + { + char *chroot_path, *tmp; ++ int dropped_suid = -1; + + platform_setusercontext(pw); + +@@ -1619,10 +1624,24 @@ do_setusercontext(struct passwd *pw) + pw->pw_uid); + chroot_path = percent_expand(tmp, "h", pw->pw_dir, + "u", pw->pw_name, (char *)NULL); ++#ifdef HAVE_LIBCAP_NG ++ /* drop suid soon, retain SYS_CHROOT capability */ ++ capng_clear(CAPNG_SELECT_BOTH); ++ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SYS_CHROOT); ++ if ((dropped_suid = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) != 0) ++ logit("capng_change_id() = %d (failure): Try to drop UID later", dropped_suid); ++#endif + #ifdef WITH_SELINUX + sshd_selinux_copy_context(); + #endif + safely_chroot(chroot_path, pw->pw_uid); ++#ifdef HAVE_LIBCAP_NG ++ /* Drop chroot capability. Already used */ ++ if (dropped_suid == 0) { ++ capng_clear(CAPNG_SELECT_BOTH); ++ capng_apply(CAPNG_SELECT_BOTH); ++ } ++#endif + free(tmp); + free(chroot_path); + /* Make sure we don't attempt to chroot again */ +@@ -1654,8 +1673,9 @@ do_setusercontext(struct passwd *pw) + if (!in_chroot && set_id(pw->pw_name) != 0) + fatal("set_id(%s) Failed", pw->pw_name); + # endif /* USE_LIBIAF */ +- /* Permanently switch to the desired uid. */ +- permanently_set_uid(pw); ++ /* Permanently switch to the desired uid if not yet done. */ ++ if (dropped_suid != 0) ++ permanently_set_uid(pw); + #endif + + #ifdef WITH_SELINUX diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch index 49f6436..a2dfdd3 100644 --- a/openssh-7.2p2-expose-pam.patch +++ b/openssh-7.2p2-expose-pam.patch @@ -331,8 +331,8 @@ diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c M_CP_INTOPT(rekey_interval); + M_CP_INTOPT(expose_auth_methods); - /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ - #define M_CP_STROPT(n) do {\ + /* + * The bind_mask is a mode_t that may be unsigned, so we can't use @@ -2181,6 +2198,8 @@ fmt_intarg(ServerOpCodes code, int val) return fmt_multistate_int(val, multistate_tcpfwd); case sFingerprintHash: diff --git a/openssh-7.2p2-user-enumeration.patch b/openssh-7.2p2-user-enumeration.patch deleted file mode 100644 index 91ccccf..0000000 --- a/openssh-7.2p2-user-enumeration.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 9286875a73b2de7736b5e50692739d314cd8d9dc Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Fri, 15 Jul 2016 13:32:45 +1000 -Subject: [PATCH] Determine appropriate salt for invalid users. - -When sshd is processing a non-PAM login for a non-existent user it uses -the string from the fakepw structure as the salt for crypt(3)ing the -password supplied by the client. That string has a Blowfish prefix, so on -systems that don't understand that crypt will fail fast due to an invalid -salt, and even on those that do it may have significantly different timing -from the hash methods used for real accounts (eg sha512). This allows -user enumeration by, eg, sending large password strings. This was noted -by EddieEzra.Harari at verint.com (CVE-2016-6210). - -To mitigate, use the same hash algorithm that root uses for hashing -passwords for users that do not exist on the system. ok djm@ ---- - auth-passwd.c | 12 ++++++++---- - openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+), 4 deletions(-) - -diff --git a/auth-passwd.c b/auth-passwd.c -index 63ccf3c..530b5d4 100644 ---- a/auth-passwd.c -+++ b/auth-passwd.c -@@ -193,7 +193,7 @@ int - sys_auth_passwd(Authctxt *authctxt, const char *password) - { - struct passwd *pw = authctxt->pw; -- char *encrypted_password; -+ char *encrypted_password, *salt = NULL; - - /* Just use the supplied fake password if authctxt is invalid */ - char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; -@@ -202,9 +202,13 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) - if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) - return (1); - -- /* Encrypt the candidate password using the proper salt. */ -- encrypted_password = xcrypt(password, -- (pw_password[0] && pw_password[1]) ? pw_password : "xx"); -+ /* -+ * Encrypt the candidate password using the proper salt, or pass a -+ * NULL and let xcrypt pick one. -+ */ -+ if (authctxt->valid && pw_password[0] && pw_password[1]) -+ salt = pw_password; -+ encrypted_password = xcrypt(password, salt); - - /* - * Authentication is accepted if the encrypted passwords -diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c -index 8577cbd..8913bb8 100644 ---- a/openbsd-compat/xcrypt.c -+++ b/openbsd-compat/xcrypt.c -@@ -25,6 +25,7 @@ - #include "includes.h" - - #include -+#include - #include - #include - -@@ -62,11 +63,44 @@ - # define crypt DES_crypt - # endif - -+/* -+ * Pick an appropriate password encryption type and salt for the running -+ * system. -+ */ -+static const char * -+pick_salt(void) -+{ -+ struct passwd *pw; -+ char *passwd, *p; -+ size_t typelen; -+ static char salt[32]; -+ -+ if (salt[0] != '\0') -+ return salt; -+ strlcpy(salt, "xx", sizeof(salt)); -+ if ((pw = getpwuid(0)) == NULL) -+ return salt; -+ passwd = shadow_pw(pw); -+ if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL) -+ return salt; /* no $, DES */ -+ typelen = p - passwd + 1; -+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); -+ explicit_bzero(passwd, strlen(passwd)); -+ return salt; -+} -+ - char * - xcrypt(const char *password, const char *salt) - { - char *crypted; - -+ /* -+ * If we don't have a salt we are encrypting a fake password for -+ * for timing purposes. Pick an appropriate salt. -+ */ -+ if (salt == NULL) -+ salt = pick_salt(); -+ - # ifdef HAVE_MD5_PASSWORDS - if (is_md5_salt(salt)) - crypted = md5_crypt(password, salt); - -From 283b97ff33ea2c641161950849931bd578de6946 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Fri, 15 Jul 2016 13:49:44 +1000 -Subject: [PATCH] Mitigate timing of disallowed users PAM logins. - -When sshd decides to not allow a login (eg PermitRootLogin=no) and -it's using PAM, it sends a fake password to PAM so that the timing for -the failure is not noticeably different whether or not the password -is correct. This behaviour can be detected by sending a very long -password string which is slower to hash than the fake password. - -Mitigate by constructing an invalid password that is the same length -as the one from the client and thus takes the same time to hash. -Diff from djm@ ---- - auth-pam.c | 35 +++++++++++++++++++++++++++++++---- - 1 file changed, 31 insertions(+), 4 deletions(-) - -diff --git a/auth-pam.c b/auth-pam.c -index 451de78..465b5a7 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -232,7 +232,6 @@ static int sshpam_account_status = -1; - static char **sshpam_env = NULL; - static Authctxt *sshpam_authctxt = NULL; - static const char *sshpam_password = NULL; --static char badpw[] = "\b\n\r\177INCORRECT"; - - /* Some PAM implementations don't implement this */ - #ifndef HAVE_PAM_GETENVLIST -@@ -795,12 +794,35 @@ sshpam_query(void *ctx, char **name, char **info, - return (-1); - } - -+/* -+ * Returns a junk password of identical length to that the user supplied. -+ * Used to mitigate timing attacks against crypt(3)/PAM stacks that -+ * vary processing time in proportion to password length. -+ */ -+static char * -+fake_password(const char *wire_password) -+{ -+ const char junk[] = "\b\n\r\177INCORRECT"; -+ char *ret = NULL; -+ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; -+ -+ if (l >= INT_MAX) -+ fatal("%s: password length too long: %zu", __func__, l); -+ -+ ret = malloc(l + 1); -+ for (i = 0; i < l; i++) -+ ret[i] = junk[i % (sizeof(junk) - 1)]; -+ ret[i] = '\0'; -+ return ret; -+} -+ - /* XXX - see also comment in auth-chall.c:verify_response */ - static int - sshpam_respond(void *ctx, u_int num, char **resp) - { - Buffer buffer; - struct pam_ctxt *ctxt = ctx; -+ char *fake; - - debug2("PAM: %s entering, %u responses", __func__, num); - switch (ctxt->pam_done) { -@@ -821,8 +843,11 @@ sshpam_respond(void *ctx, u_int num, char **resp) - (sshpam_authctxt->pw->pw_uid != 0 || - options.permit_root_login == PERMIT_YES)) - buffer_put_cstring(&buffer, *resp); -- else -- buffer_put_cstring(&buffer, badpw); -+ else { -+ fake = fake_password(*resp); -+ buffer_put_cstring(&buffer, fake); -+ free(fake); -+ } - if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { - buffer_free(&buffer); - return (-1); -@@ -1166,6 +1191,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) - { - int flags = (options.permit_empty_passwd == 0 ? - PAM_DISALLOW_NULL_AUTHTOK : 0); -+ char *fake = NULL; - - if (!options.use_pam || sshpam_handle == NULL) - fatal("PAM: %s called when PAM disabled or failed to " -@@ -1181,7 +1207,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) - */ - if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && - options.permit_root_login != PERMIT_YES)) -- sshpam_password = badpw; -+ sshpam_password = fake = fake_password(password); - - sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, - (const void *)&passwd_conv); -@@ -1191,6 +1217,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) - - sshpam_err = pam_authenticate(sshpam_handle, flags); - sshpam_password = NULL; -+ free(fake); - if (sshpam_err == PAM_SUCCESS && authctxt->valid) { - debug("PAM: password authentication accepted for %.100s", - authctxt->user); - diff --git a/openssh-7.2p2-gsissh.patch b/openssh-7.3p1-gsissh.patch similarity index 89% rename from openssh-7.2p2-gsissh.patch rename to openssh-7.3p1-gsissh.patch index 771ec18..90b0e20 100644 --- a/openssh-7.2p2-gsissh.patch +++ b/openssh-7.3p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-7.2p1.orig/auth2.c openssh-7.2p1/auth2.c ---- openssh-7.2p1.orig/auth2.c 2016-03-02 19:04:36.376960285 +0100 -+++ openssh-7.2p1/auth2.c 2016-03-02 19:05:41.290212928 +0100 +diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c +--- openssh-7.3p1.orig/auth2.c 2016-08-15 15:32:58.794404264 +0200 ++++ openssh-7.3p1/auth2.c 2016-08-15 15:33:35.802990200 +0200 @@ -50,6 +50,7 @@ #include "dispatch.h" #include "pathnames.h" @@ -18,7 +18,7 @@ diff -Nur openssh-7.2p1.orig/auth2.c openssh-7.2p1/auth2.c Authmethod *authmethods[] = { &method_none, &method_pubkey, -@@ -228,7 +231,33 @@ +@@ -228,7 +231,32 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -45,8 +45,7 @@ diff -Nur openssh-7.2p1.orig/auth2.c openssh-7.2p1/auth2.c + debug("userauth-request for user %s service %s method %s", + user[0] ? user : "", service, method); + if (!log_flag) { -+ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", -+ get_remote_ipaddr(), get_remote_port(), ++ logit("SSH: Server;Ltype: Authname;Name: %s", + user[0] ? user : ""); + log_flag = 1; + } @@ -120,9 +119,9 @@ diff -Nur openssh-7.2p1.orig/auth2.c openssh-7.2p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c ---- openssh-7.2p1.orig/auth2-gss.c 2016-03-02 19:04:36.311961033 +0100 -+++ openssh-7.2p1/auth2-gss.c 2016-03-02 19:05:41.290212928 +0100 +diff -Nur openssh-7.3p1.orig/auth2-gss.c openssh-7.3p1/auth2-gss.c +--- openssh-7.3p1.orig/auth2-gss.c 2016-08-15 15:32:58.782404398 +0200 ++++ openssh-7.3p1/auth2-gss.c 2016-08-15 15:33:35.802990200 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -260,7 +259,7 @@ diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c if (authenticated) authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -316,9 +368,16 @@ +@@ -319,9 +371,16 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -279,7 +278,7 @@ diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -336,6 +395,23 @@ +@@ -342,6 +401,23 @@ return 0; } @@ -303,10 +302,10 @@ diff -Nur openssh-7.2p1.orig/auth2-gss.c openssh-7.2p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.2p1.orig/auth.c openssh-7.2p1/auth.c ---- openssh-7.2p1.orig/auth.c 2016-03-02 19:04:36.376960285 +0100 -+++ openssh-7.2p1/auth.c 2016-03-02 19:05:41.291212916 +0100 -@@ -75,6 +75,9 @@ +diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c +--- openssh-7.3p1.orig/auth.c 2016-08-15 15:32:58.795404252 +0200 ++++ openssh-7.3p1/auth.c 2016-08-15 15:38:11.546905093 +0200 +@@ -77,6 +77,9 @@ #include "ssherr.h" #include "compat.h" @@ -316,17 +315,17 @@ diff -Nur openssh-7.2p1.orig/auth.c openssh-7.2p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -299,7 +302,8 @@ +@@ -303,7 +306,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", - authctxt->user, + (authctxt->user && authctxt->user[0]) ? + authctxt->user : "unknown", - get_remote_ipaddr(), - get_remote_port(), + ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh), compat20 ? "ssh2" : "ssh1", -@@ -325,6 +329,23 @@ +@@ -330,6 +334,23 @@ if (authenticated == 0 && !authctxt->postponed) audit_event(audit_classify_auth(method)); #endif @@ -338,19 +337,19 @@ diff -Nur openssh-7.2p1.orig/auth.c openssh-7.2p1/auth.c +#endif + debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)", + SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), -+ method, mech_name?mech_name:"NULL", get_remote_ipaddr(), ++ method, mech_name?mech_name:"NULL", ssh_remote_ipaddr(ssh), + (authctxt->user && authctxt->user[0])? + authctxt->user : "unknown", + userdn?userdn:"NULL"); + ssh_globus_send_usage_metrics(SSH_RELEASE, + SSLeay_version(SSLEAY_VERSION), -+ method, mech_name, get_remote_ipaddr(), ++ method, mech_name, ssh_remote_ipaddr(ssh), + authctxt->user, userdn); + } } -@@ -622,6 +643,10 @@ +@@ -633,6 +654,10 @@ #endif pw = getpwnam(user); @@ -361,19 +360,19 @@ diff -Nur openssh-7.2p1.orig/auth.c openssh-7.2p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -641,7 +666,8 @@ +@@ -652,7 +677,8 @@ #endif if (pw == NULL) { - logit("Invalid user %.100s from %.100s", -- user, get_remote_ipaddr()); -+ (user && user[0]) ? user : "unknown", -+ get_remote_ipaddr()); + logit("Invalid user %.100s from %.100s port %d", +- user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); ++ (user && user[0]) ? user : "unknown", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, - get_canonical_hostname(options.use_dns), "ssh"); -diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c ---- openssh-7.2p1.orig/auth-pam.c 2016-03-02 19:04:36.394960078 +0100 -+++ openssh-7.2p1/auth-pam.c 2016-03-02 19:05:41.292212905 +0100 + auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); +diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c +--- openssh-7.3p1.orig/auth-pam.c 2016-08-15 15:32:58.783404387 +0200 ++++ openssh-7.3p1/auth-pam.c 2016-08-15 15:33:35.804990178 +0200 @@ -123,6 +123,10 @@ */ typedef pthread_t sp_pthread_t; @@ -385,7 +384,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c typedef pid_t sp_pthread_t; #endif -@@ -278,6 +282,56 @@ +@@ -280,6 +284,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -442,7 +441,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -300,7 +354,7 @@ +@@ -302,7 +356,7 @@ static void import_environments(Buffer *b) { @@ -451,7 +450,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c u_int i, num_env; int err; -@@ -310,6 +364,17 @@ +@@ -312,6 +366,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -469,7 +468,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -476,6 +541,13 @@ +@@ -463,6 +528,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -483,7 +482,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -496,6 +568,11 @@ +@@ -483,6 +555,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -495,7 +494,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -913,6 +990,18 @@ +@@ -939,6 +1016,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -514,7 +513,7 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1210,6 +1299,9 @@ +@@ -1237,6 +1326,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -523,20 +522,20 @@ diff -Nur openssh-7.2p1.orig/auth-pam.c openssh-7.2p1/auth-pam.c + } sshpam_password = NULL; free(fake); - if (sshpam_err == PAM_SUCCESS && authctxt->valid) { -diff -Nur openssh-7.2p1.orig/auth-pam.h openssh-7.2p1/auth-pam.h ---- openssh-7.2p1.orig/auth-pam.h 2016-03-02 19:04:36.265961563 +0100 -+++ openssh-7.2p1/auth-pam.h 2016-03-02 19:05:41.292212905 +0100 -@@ -46,5 +46,6 @@ - void sshpam_cleanup(void); - int sshpam_auth_passwd(Authctxt *, const char *); + if (sshpam_err == PAM_MAXTRIES) +diff -Nur openssh-7.3p1.orig/auth-pam.h openssh-7.3p1/auth-pam.h +--- openssh-7.3p1.orig/auth-pam.h 2016-08-15 15:32:58.669405662 +0200 ++++ openssh-7.3p1/auth-pam.h 2016-08-15 15:33:35.805990167 +0200 +@@ -48,5 +48,6 @@ + int sshpam_get_maxtries_reached(void); + void sshpam_set_maxtries_reached(int); int is_pam_session_open(void); +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.2p1.orig/canohost.c openssh-7.2p1/canohost.c ---- openssh-7.2p1.orig/canohost.c 2016-03-02 19:04:36.333960780 +0100 -+++ openssh-7.2p1/canohost.c 2016-03-02 19:05:41.292212905 +0100 +diff -Nur openssh-7.3p1.orig/canohost.c openssh-7.3p1/canohost.c +--- openssh-7.3p1.orig/canohost.c 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/canohost.c 2016-08-15 15:33:35.806990155 +0200 @@ -17,6 +17,7 @@ #include #include @@ -545,9 +544,9 @@ diff -Nur openssh-7.2p1.orig/canohost.c openssh-7.2p1/canohost.c #include #include -@@ -468,3 +469,33 @@ +@@ -202,3 +203,33 @@ { - return get_port(1); + return get_sock_port(sock, 1); } + +void @@ -579,20 +578,20 @@ diff -Nur openssh-7.2p1.orig/canohost.c openssh-7.2p1/canohost.c + } + } +} -diff -Nur openssh-7.2p1.orig/canohost.h openssh-7.2p1/canohost.h ---- openssh-7.2p1.orig/canohost.h 2016-03-02 19:04:36.334960769 +0100 -+++ openssh-7.2p1/canohost.h 2016-03-02 19:05:41.292212905 +0100 -@@ -27,4 +27,6 @@ - int get_sock_port(int, int); - void clear_cached_addr(void); +diff -Nur openssh-7.3p1.orig/canohost.h openssh-7.3p1/canohost.h +--- openssh-7.3p1.orig/canohost.h 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/canohost.h 2016-08-15 15:33:35.806990155 +0200 +@@ -23,4 +23,6 @@ + + #endif /* _CANOHOST_H */ +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.2p1.orig/configure.ac openssh-7.2p1/configure.ac ---- openssh-7.2p1.orig/configure.ac 2016-03-02 19:04:36.356960515 +0100 -+++ openssh-7.2p1/configure.ac 2016-03-02 19:05:41.293212893 +0100 -@@ -4330,6 +4330,14 @@ +diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac +--- openssh-7.3p1.orig/configure.ac 2016-08-15 15:32:58.791404297 +0200 ++++ openssh-7.3p1/configure.ac 2016-08-15 15:33:35.807990144 +0200 +@@ -4383,6 +4383,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -607,7 +606,7 @@ diff -Nur openssh-7.2p1.orig/configure.ac openssh-7.2p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4369,6 +4377,50 @@ +@@ -4422,6 +4430,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -658,9 +657,9 @@ diff -Nur openssh-7.2p1.orig/configure.ac openssh-7.2p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-7.2p1.orig/gss-genr.c openssh-7.2p1/gss-genr.c ---- openssh-7.2p1.orig/gss-genr.c 2016-03-02 19:04:36.363960435 +0100 -+++ openssh-7.2p1/gss-genr.c 2016-03-02 19:05:41.294212882 +0100 +diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c +--- openssh-7.3p1.orig/gss-genr.c 2016-08-15 15:32:58.771404521 +0200 ++++ openssh-7.3p1/gss-genr.c 2016-08-15 15:33:35.808990133 +0200 @@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -697,9 +696,9 @@ diff -Nur openssh-7.2p1.orig/gss-genr.c openssh-7.2p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c ---- openssh-7.2p1.orig/gss-serv.c 2016-03-02 19:04:36.363960435 +0100 -+++ openssh-7.2p1/gss-serv.c 2016-03-02 19:05:41.294212882 +0100 +diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c +--- openssh-7.3p1.orig/gss-serv.c 2016-08-15 15:32:58.784404375 +0200 ++++ openssh-7.3p1/gss-serv.c 2016-08-15 15:33:35.808990133 +0200 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -848,7 +847,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -441,8 +493,9 @@ +@@ -451,8 +503,9 @@ } /* Privileged */ @@ -859,7 +858,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c { OM_uint32 lmin; -@@ -451,6 +504,12 @@ +@@ -461,6 +514,12 @@ debug("No suitable client data"); return 0; } @@ -872,7 +871,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -470,6 +529,24 @@ +@@ -480,6 +539,24 @@ return (0); } @@ -897,7 +896,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -496,6 +573,7 @@ +@@ -506,6 +583,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -905,7 +904,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -525,6 +603,18 @@ +@@ -535,6 +613,18 @@ if (ret) return; @@ -924,7 +923,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -556,4 +646,13 @@ +@@ -566,4 +656,13 @@ return ok; } @@ -938,9 +937,9 @@ diff -Nur openssh-7.2p1.orig/gss-serv.c openssh-7.2p1/gss-serv.c +} + #endif -diff -Nur openssh-7.2p1.orig/gss-serv-gsi.c openssh-7.2p1/gss-serv-gsi.c ---- openssh-7.2p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.2p1/gss-serv-gsi.c 2016-03-02 19:05:41.294212882 +0100 +diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c +--- openssh-7.3p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.3p1/gss-serv-gsi.c 2016-08-15 15:33:35.809990122 +0200 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1181,10 +1180,10 @@ diff -Nur openssh-7.2p1.orig/gss-serv-gsi.c openssh-7.2p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.2p1.orig/gss-serv-krb5.c openssh-7.2p1/gss-serv-krb5.c ---- openssh-7.2p1.orig/gss-serv-krb5.c 2016-03-02 19:04:36.348960607 +0100 -+++ openssh-7.2p1/gss-serv-krb5.c 2016-03-02 19:05:41.295212870 +0100 -@@ -359,6 +359,34 @@ +diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c +--- openssh-7.3p1.orig/gss-serv-krb5.c 2016-08-15 15:32:58.757404678 +0200 ++++ openssh-7.3p1/gss-serv-krb5.c 2016-08-15 15:33:35.809990122 +0200 +@@ -378,6 +378,34 @@ return found_principal; } @@ -1219,7 +1218,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv-krb5.c openssh-7.2p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -463,7 +491,7 @@ +@@ -482,7 +510,7 @@ return; } @@ -1228,7 +1227,7 @@ diff -Nur openssh-7.2p1.orig/gss-serv-krb5.c openssh-7.2p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -534,7 +562,7 @@ +@@ -553,7 +581,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1237,9 +1236,9 @@ diff -Nur openssh-7.2p1.orig/gss-serv-krb5.c openssh-7.2p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c ---- openssh-7.2p1.orig/kexgsss.c 2016-03-02 19:04:36.314960999 +0100 -+++ openssh-7.2p1/kexgsss.c 2016-03-02 19:05:41.295212870 +0100 +diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c +--- openssh-7.3p1.orig/kexgsss.c 2016-08-15 15:32:58.722405069 +0200 ++++ openssh-7.3p1/kexgsss.c 2016-08-15 15:33:35.809990122 +0200 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1248,7 +1247,7 @@ diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c extern ServerOptions options; int -@@ -94,8 +95,10 @@ +@@ -95,8 +96,10 @@ debug2("%s: Acquiring credentials", __func__); @@ -1260,7 +1259,7 @@ diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -181,12 +184,13 @@ +@@ -183,12 +186,13 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1275,7 +1274,7 @@ diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -292,4 +296,23 @@ +@@ -294,4 +298,23 @@ ssh_gssapi_rekey_creds(); return 0; } @@ -1299,9 +1298,9 @@ diff -Nur openssh-7.2p1.orig/kexgsss.c openssh-7.2p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.2p1.orig/LICENSE.globus_usage openssh-7.2p1/LICENSE.globus_usage ---- openssh-7.2p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.2p1/LICENSE.globus_usage 2016-03-02 19:05:41.295212870 +0100 +diff -Nur openssh-7.3p1.orig/LICENSE.globus_usage openssh-7.3p1/LICENSE.globus_usage +--- openssh-7.3p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.3p1/LICENSE.globus_usage 2016-08-15 15:33:35.810990111 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1321,10 +1320,10 @@ diff -Nur openssh-7.2p1.orig/LICENSE.globus_usage openssh-7.2p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.2p1.orig/Makefile.in openssh-7.2p1/Makefile.in ---- openssh-7.2p1.orig/Makefile.in 2016-03-02 19:04:36.389960135 +0100 -+++ openssh-7.2p1/Makefile.in 2016-03-02 19:09:08.722825330 +0100 -@@ -113,8 +113,10 @@ +diff -Nur openssh-7.3p1.orig/Makefile.in openssh-7.3p1/Makefile.in +--- openssh-7.3p1.orig/Makefile.in 2016-08-15 15:32:58.808404107 +0200 ++++ openssh-7.3p1/Makefile.in 2016-08-15 15:33:35.810990111 +0200 +@@ -114,8 +114,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1335,9 +1334,9 @@ diff -Nur openssh-7.2p1.orig/Makefile.in openssh-7.2p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o -diff -Nur openssh-7.2p1.orig/misc.c openssh-7.2p1/misc.c ---- openssh-7.2p1.orig/misc.c 2016-03-02 19:04:36.347960619 +0100 -+++ openssh-7.2p1/misc.c 2016-03-02 19:05:41.296212859 +0100 +diff -Nur openssh-7.3p1.orig/misc.c openssh-7.3p1/misc.c +--- openssh-7.3p1.orig/misc.c 2016-08-15 15:32:58.756404689 +0200 ++++ openssh-7.3p1/misc.c 2016-08-15 15:33:35.810990111 +0200 @@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1397,10 +1396,10 @@ diff -Nur openssh-7.2p1.orig/misc.c openssh-7.2p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.2p1.orig/misc.h openssh-7.2p1/misc.h ---- openssh-7.2p1.orig/misc.h 2016-03-02 19:04:36.335960757 +0100 -+++ openssh-7.2p1/misc.h 2016-03-02 19:05:41.296212859 +0100 -@@ -61,6 +61,7 @@ +diff -Nur openssh-7.3p1.orig/misc.h openssh-7.3p1/misc.h +--- openssh-7.3p1.orig/misc.h 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/misc.h 2016-08-15 15:33:35.811990100 +0200 +@@ -65,6 +65,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1408,10 +1407,10 @@ diff -Nur openssh-7.2p1.orig/misc.h openssh-7.2p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c ---- openssh-7.2p1.orig/monitor.c 2016-03-02 19:04:36.396960055 +0100 -+++ openssh-7.2p1/monitor.c 2016-03-02 19:05:41.297212847 +0100 -@@ -163,6 +163,9 @@ +diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c +--- openssh-7.3p1.orig/monitor.c 2016-08-15 15:32:58.816404017 +0200 ++++ openssh-7.3p1/monitor.c 2016-08-15 15:33:35.811990100 +0200 +@@ -165,6 +165,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1421,7 +1420,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -216,7 +219,7 @@ +@@ -218,7 +221,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1430,7 +1429,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -224,7 +227,7 @@ +@@ -226,7 +229,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1439,7 +1438,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -254,6 +257,9 @@ +@@ -256,6 +259,9 @@ {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, @@ -1449,7 +1448,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c #endif {0, 0, NULL} }; -@@ -263,6 +269,8 @@ +@@ -265,6 +271,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1458,7 +1457,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -303,7 +311,7 @@ +@@ -305,7 +313,7 @@ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM @@ -1467,7 +1466,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -398,6 +406,8 @@ +@@ -401,6 +409,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1476,7 +1475,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_proto15; -@@ -512,6 +522,8 @@ +@@ -527,6 +537,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1485,7 +1484,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -840,14 +852,17 @@ +@@ -858,14 +870,17 @@ debug3("%s", __func__); @@ -1506,7 +1505,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2222,12 +2237,15 @@ +@@ -2253,12 +2268,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1523,7 +1522,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2235,15 +2253,80 @@ +@@ -2266,7 +2284,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1535,8 +1534,7 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c if (authenticated) authctxt->last_details = ssh_gssapi_get_displayname(); - - /* Monitor loop will terminate if authenticated */ +@@ -2275,6 +2296,68 @@ return (authenticated); } @@ -1605,9 +1603,9 @@ diff -Nur openssh-7.2p1.orig/monitor.c openssh-7.2p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.2p1.orig/monitor.h openssh-7.2p1/monitor.h ---- openssh-7.2p1.orig/monitor.h 2016-03-02 19:04:36.379960251 +0100 -+++ openssh-7.2p1/monitor.h 2016-03-02 19:05:41.298212836 +0100 +diff -Nur openssh-7.3p1.orig/monitor.h openssh-7.3p1/monitor.h +--- openssh-7.3p1.orig/monitor.h 2016-08-15 15:32:58.798404219 +0200 ++++ openssh-7.3p1/monitor.h 2016-08-15 15:33:35.812990088 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1621,10 +1619,10 @@ diff -Nur openssh-7.2p1.orig/monitor.h openssh-7.2p1/monitor.h }; struct mm_master; -diff -Nur openssh-7.2p1.orig/monitor_wrap.c openssh-7.2p1/monitor_wrap.c ---- openssh-7.2p1.orig/monitor_wrap.c 2016-03-02 19:04:36.396960055 +0100 -+++ openssh-7.2p1/monitor_wrap.c 2016-03-02 19:05:41.298212836 +0100 -@@ -1121,12 +1121,13 @@ +diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c +--- openssh-7.3p1.orig/monitor_wrap.c 2016-08-15 15:32:58.816404017 +0200 ++++ openssh-7.3p1/monitor_wrap.c 2016-08-15 15:33:35.812990088 +0200 +@@ -1126,12 +1126,13 @@ } int @@ -1639,7 +1637,7 @@ diff -Nur openssh-7.2p1.orig/monitor_wrap.c openssh-7.2p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1139,6 +1140,83 @@ +@@ -1144,6 +1145,83 @@ return (authenticated); } @@ -1723,10 +1721,10 @@ diff -Nur openssh-7.2p1.orig/monitor_wrap.c openssh-7.2p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.2p1.orig/monitor_wrap.h openssh-7.2p1/monitor_wrap.h ---- openssh-7.2p1.orig/monitor_wrap.h 2016-03-02 19:04:36.385960182 +0100 -+++ openssh-7.2p1/monitor_wrap.h 2016-03-02 19:05:41.298212836 +0100 -@@ -62,9 +62,13 @@ +diff -Nur openssh-7.3p1.orig/monitor_wrap.h openssh-7.3p1/monitor_wrap.h +--- openssh-7.3p1.orig/monitor_wrap.h 2016-08-15 15:32:58.804404152 +0200 ++++ openssh-7.3p1/monitor_wrap.h 2016-08-15 15:33:35.813990077 +0200 +@@ -64,9 +64,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1741,10 +1739,10 @@ diff -Nur openssh-7.2p1.orig/monitor_wrap.h openssh-7.2p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.2p1.orig/readconf.c openssh-7.2p1/readconf.c ---- openssh-7.2p1.orig/readconf.c 2016-03-02 19:04:36.390960124 +0100 -+++ openssh-7.2p1/readconf.c 2016-03-02 19:05:41.299212824 +0100 -@@ -1830,13 +1830,13 @@ +diff -Nur openssh-7.3p1.orig/readconf.c openssh-7.3p1/readconf.c +--- openssh-7.3p1.orig/readconf.c 2016-08-15 15:32:58.809404096 +0200 ++++ openssh-7.3p1/readconf.c 2016-08-15 15:33:35.813990077 +0200 +@@ -1974,13 +1974,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1762,9 +1760,9 @@ diff -Nur openssh-7.2p1.orig/readconf.c openssh-7.2p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.2p1.orig/readconf.h openssh-7.2p1/readconf.h ---- openssh-7.2p1.orig/readconf.h 2016-03-02 19:04:36.370960354 +0100 -+++ openssh-7.2p1/readconf.h 2016-03-02 19:05:41.299212824 +0100 +diff -Nur openssh-7.3p1.orig/readconf.h openssh-7.3p1/readconf.h +--- openssh-7.3p1.orig/readconf.h 2016-08-15 15:32:58.778404443 +0200 ++++ openssh-7.3p1/readconf.h 2016-08-15 15:33:35.814990066 +0200 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1774,9 +1772,9 @@ diff -Nur openssh-7.2p1.orig/readconf.h openssh-7.2p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c ---- openssh-7.2p1.orig/servconf.c 2016-03-02 19:04:36.397960043 +0100 -+++ openssh-7.2p1/servconf.c 2016-03-02 19:05:41.300212813 +0100 +diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c +--- openssh-7.3p1.orig/servconf.c 2016-08-15 15:32:58.818403995 +0200 ++++ openssh-7.3p1/servconf.c 2016-08-15 15:33:35.815990055 +0200 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1806,7 +1804,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -210,6 +215,8 @@ +@@ -211,6 +216,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1815,7 +1813,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -296,13 +303,17 @@ +@@ -297,13 +304,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1836,7 +1834,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -420,7 +431,7 @@ +@@ -431,7 +442,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1845,7 +1843,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -442,10 +453,14 @@ +@@ -453,10 +464,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1860,7 +1858,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -470,8 +485,10 @@ +@@ -482,8 +497,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1871,7 +1869,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -517,7 +534,14 @@ +@@ -529,7 +546,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1886,7 +1884,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -525,7 +549,10 @@ +@@ -537,7 +561,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1897,7 +1895,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -593,6 +620,8 @@ +@@ -605,6 +632,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1906,7 +1904,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1048,6 +1077,10 @@ +@@ -1068,6 +1097,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1917,7 +1915,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1279,6 +1312,10 @@ +@@ -1299,6 +1332,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1928,7 +1926,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1287,6 +1324,10 @@ +@@ -1307,6 +1344,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1939,7 +1937,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1307,6 +1348,12 @@ +@@ -1327,6 +1368,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1952,7 +1950,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1777,6 +1824,35 @@ +@@ -1797,6 +1844,35 @@ *charptr = xstrdup(arg); break; @@ -1988,7 +1986,7 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2053,6 +2129,7 @@ +@@ -2096,6 +2172,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1996,10 +1994,10 @@ diff -Nur openssh-7.2p1.orig/servconf.c openssh-7.2p1/servconf.c M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-7.2p1.orig/servconf.h openssh-7.2p1/servconf.h ---- openssh-7.2p1.orig/servconf.h 2016-03-02 19:04:36.366960400 +0100 -+++ openssh-7.2p1/servconf.h 2016-03-02 19:05:41.300212813 +0100 -@@ -117,9 +117,12 @@ +diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h +--- openssh-7.3p1.orig/servconf.h 2016-08-15 15:32:58.786404353 +0200 ++++ openssh-7.3p1/servconf.h 2016-08-15 15:33:35.815990055 +0200 +@@ -122,9 +122,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -2012,7 +2010,7 @@ diff -Nur openssh-7.2p1.orig/servconf.h openssh-7.2p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -176,6 +179,7 @@ +@@ -181,6 +184,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2020,7 +2018,7 @@ diff -Nur openssh-7.2p1.orig/servconf.h openssh-7.2p1/servconf.h int permit_tun; -@@ -184,6 +188,10 @@ +@@ -189,6 +193,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2031,10 +2029,10 @@ diff -Nur openssh-7.2p1.orig/servconf.h openssh-7.2p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.2p1.orig/ssh.1 openssh-7.2p1/ssh.1 ---- openssh-7.2p1.orig/ssh.1 2016-03-02 19:04:36.366960400 +0100 -+++ openssh-7.2p1/ssh.1 2016-03-02 19:05:41.301212801 +0100 -@@ -1407,6 +1407,18 @@ +diff -Nur openssh-7.3p1.orig/ssh.1 openssh-7.3p1/ssh.1 +--- openssh-7.3p1.orig/ssh.1 2016-08-15 15:32:58.788404331 +0200 ++++ openssh-7.3p1/ssh.1 2016-08-15 15:33:35.816990044 +0200 +@@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2053,9 +2051,9 @@ diff -Nur openssh-7.2p1.orig/ssh.1 openssh-7.2p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.2p1.orig/ssh.c openssh-7.2p1/ssh.c ---- openssh-7.2p1.orig/ssh.c 2016-03-02 19:04:36.391960112 +0100 -+++ openssh-7.2p1/ssh.c 2016-03-02 19:05:41.301212801 +0100 +diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c +--- openssh-7.3p1.orig/ssh.c 2016-08-15 15:32:58.810404085 +0200 ++++ openssh-7.3p1/ssh.c 2016-08-15 15:33:35.816990044 +0200 @@ -475,6 +475,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2089,7 +2087,7 @@ diff -Nur openssh-7.2p1.orig/ssh.c openssh-7.2p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1143,8 +1169,12 @@ +@@ -1191,8 +1217,12 @@ logit("FIPS mode initialized"); } @@ -2103,9 +2101,9 @@ diff -Nur openssh-7.2p1.orig/ssh.c openssh-7.2p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.2p1.orig/ssh_config openssh-7.2p1/ssh_config ---- openssh-7.2p1.orig/ssh_config 2016-03-02 19:04:36.318960953 +0100 -+++ openssh-7.2p1/ssh_config 2016-03-02 19:05:41.302212790 +0100 +diff -Nur openssh-7.3p1.orig/ssh_config openssh-7.3p1/ssh_config +--- openssh-7.3p1.orig/ssh_config 2016-08-15 15:32:58.727405013 +0200 ++++ openssh-7.3p1/ssh_config 2016-08-15 15:33:35.817990032 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2121,9 +2119,9 @@ diff -Nur openssh-7.2p1.orig/ssh_config openssh-7.2p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.2p1.orig/ssh_config.5 openssh-7.2p1/ssh_config.5 ---- openssh-7.2p1.orig/ssh_config.5 2016-03-02 19:04:36.370960354 +0100 -+++ openssh-7.2p1/ssh_config.5 2016-03-02 19:05:41.302212790 +0100 +diff -Nur openssh-7.3p1.orig/ssh_config.5 openssh-7.3p1/ssh_config.5 +--- openssh-7.3p1.orig/ssh_config.5 2016-08-15 15:32:58.778404443 +0200 ++++ openssh-7.3p1/ssh_config.5 2016-08-15 15:33:35.817990032 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2137,10 +2135,10 @@ diff -Nur openssh-7.2p1.orig/ssh_config.5 openssh-7.2p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c ---- openssh-7.2p1.orig/sshconnect2.c 2016-03-02 19:04:36.391960112 +0100 -+++ openssh-7.2p1/sshconnect2.c 2016-03-02 19:05:41.303212778 +0100 -@@ -728,6 +728,11 @@ +diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c +--- openssh-7.3p1.orig/sshconnect2.c 2016-08-15 15:32:58.810404085 +0200 ++++ openssh-7.3p1/sshconnect2.c 2016-08-15 15:33:35.818990021 +0200 +@@ -722,6 +722,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2152,7 +2150,7 @@ diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -965,6 +970,15 @@ +@@ -959,6 +964,15 @@ return 0; } @@ -2168,7 +2166,7 @@ diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -982,8 +996,16 @@ +@@ -976,8 +990,16 @@ return (0); } @@ -2185,7 +2183,7 @@ diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -994,7 +1016,15 @@ +@@ -988,7 +1010,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2201,9 +2199,9 @@ diff -Nur openssh-7.2p1.orig/sshconnect2.c openssh-7.2p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.2p1.orig/sshd.8 openssh-7.2p1/sshd.8 ---- openssh-7.2p1.orig/sshd.8 2016-03-02 19:04:36.352960561 +0100 -+++ openssh-7.2p1/sshd.8 2016-03-02 19:05:41.303212778 +0100 +diff -Nur openssh-7.3p1.orig/sshd.8 openssh-7.3p1/sshd.8 +--- openssh-7.3p1.orig/sshd.8 2016-08-15 15:32:58.761404633 +0200 ++++ openssh-7.3p1/sshd.8 2016-08-15 15:33:35.818990021 +0200 @@ -795,6 +795,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2249,9 +2247,9 @@ diff -Nur openssh-7.2p1.orig/sshd.8 openssh-7.2p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.2p1.orig/sshd.c openssh-7.2p1/sshd.c ---- openssh-7.2p1.orig/sshd.c 2016-03-02 19:04:36.399960020 +0100 -+++ openssh-7.2p1/sshd.c 2016-03-02 19:05:41.304212767 +0100 +diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c +--- openssh-7.3p1.orig/sshd.c 2016-08-15 15:32:58.820403973 +0200 ++++ openssh-7.3p1/sshd.c 2016-08-15 15:33:35.819990010 +0200 @@ -128,6 +128,7 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2260,7 +2258,7 @@ diff -Nur openssh-7.2p1.orig/sshd.c openssh-7.2p1/sshd.c #ifdef LIBWRAP #include -@@ -1797,6 +1798,13 @@ +@@ -1885,6 +1886,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2274,7 +2272,7 @@ diff -Nur openssh-7.2p1.orig/sshd.c openssh-7.2p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2362,7 +2370,7 @@ +@@ -2447,7 +2455,7 @@ #endif #ifdef GSSAPI @@ -2283,10 +2281,10 @@ diff -Nur openssh-7.2p1.orig/sshd.c openssh-7.2p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.2p1.orig/sshd_config openssh-7.2p1/sshd_config ---- openssh-7.2p1.orig/sshd_config 2016-03-02 19:04:36.361960458 +0100 -+++ openssh-7.2p1/sshd_config 2016-03-02 19:05:41.304212767 +0100 -@@ -90,10 +90,11 @@ +diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config +--- openssh-7.3p1.orig/sshd_config 2016-08-15 15:32:58.769404543 +0200 ++++ openssh-7.3p1/sshd_config 2016-08-15 15:33:35.819990010 +0200 +@@ -89,10 +89,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2300,7 +2298,7 @@ diff -Nur openssh-7.2p1.orig/sshd_config openssh-7.2p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -109,6 +110,10 @@ +@@ -108,6 +109,10 @@ # problems. UsePAM yes @@ -2311,17 +2309,17 @@ diff -Nur openssh-7.2p1.orig/sshd_config openssh-7.2p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -151,3 +156,6 @@ +@@ -152,3 +157,6 @@ # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 -diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 ---- openssh-7.2p1.orig/sshd_config.5 2016-03-02 19:04:36.367960389 +0100 -+++ openssh-7.2p1/sshd_config.5 2016-03-02 19:07:15.338130138 +0100 -@@ -570,6 +570,15 @@ +diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 +--- openssh-7.3p1.orig/sshd_config.5 2016-08-15 15:32:58.788404331 +0200 ++++ openssh-7.3p1/sshd_config.5 2016-08-15 15:33:35.820989999 +0200 +@@ -594,6 +594,15 @@ (Expose them to PAM and keep them in the shell environment). The default is .Dq never . @@ -2337,7 +2335,7 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: -@@ -623,6 +632,10 @@ +@@ -647,6 +656,10 @@ Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . @@ -2348,7 +2346,7 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 .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. -@@ -639,6 +652,22 @@ +@@ -663,6 +676,22 @@ .Xr ksu 1 . The default is .Dq no . @@ -2371,7 +2369,7 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1552,6 +1581,103 @@ +@@ -1579,6 +1608,103 @@ .Pp To disable TCP keepalive messages, the value should be set to .Dq no . @@ -2475,7 +2473,7 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -1628,6 +1754,12 @@ +@@ -1655,6 +1781,12 @@ as a non-root user. The default is .Dq no . @@ -2488,9 +2486,9 @@ diff -Nur openssh-7.2p1.orig/sshd_config.5 openssh-7.2p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-7.2p1.orig/ssh-globus-usage.c openssh-7.2p1/ssh-globus-usage.c ---- openssh-7.2p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.2p1/ssh-globus-usage.c 2016-03-02 19:05:41.306212744 +0100 +diff -Nur openssh-7.3p1.orig/ssh-globus-usage.c openssh-7.3p1/ssh-globus-usage.c +--- openssh-7.3p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.3p1/ssh-globus-usage.c 2016-08-15 15:33:35.821989988 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2888,9 +2886,9 @@ diff -Nur openssh-7.2p1.orig/ssh-globus-usage.c openssh-7.2p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.2p1.orig/ssh-globus-usage.h openssh-7.2p1/ssh-globus-usage.h ---- openssh-7.2p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.2p1/ssh-globus-usage.h 2016-03-02 19:05:41.306212744 +0100 +diff -Nur openssh-7.3p1.orig/ssh-globus-usage.h openssh-7.3p1/ssh-globus-usage.h +--- openssh-7.3p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.3p1/ssh-globus-usage.h 2016-08-15 15:33:35.821989988 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2940,9 +2938,9 @@ diff -Nur openssh-7.2p1.orig/ssh-globus-usage.h openssh-7.2p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.2p1.orig/ssh-gss.h openssh-7.2p1/ssh-gss.h ---- openssh-7.2p1.orig/ssh-gss.h 2016-03-02 19:04:36.367960389 +0100 -+++ openssh-7.2p1/ssh-gss.h 2016-03-02 19:05:41.306212744 +0100 +diff -Nur openssh-7.3p1.orig/ssh-gss.h openssh-7.3p1/ssh-gss.h +--- openssh-7.3p1.orig/ssh-gss.h 2016-08-15 15:32:58.788404331 +0200 ++++ openssh-7.3p1/ssh-gss.h 2016-08-15 15:33:35.821989988 +0200 @@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2979,7 +2977,7 @@ diff -Nur openssh-7.2p1.orig/ssh-gss.h openssh-7.2p1/ssh-gss.h char* ssh_gssapi_get_displayname(void); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); -@@ -170,6 +174,7 @@ +@@ -171,6 +175,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -2987,11 +2985,11 @@ diff -Nur openssh-7.2p1.orig/ssh-gss.h openssh-7.2p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.2p1.orig/version.h openssh-7.2p1/version.h ---- openssh-7.2p1.orig/version.h 2016-02-26 04:40:04.000000000 +0100 -+++ openssh-7.2p1/version.h 2016-03-02 19:10:52.953628948 +0100 +diff -Nur openssh-7.3p1.orig/version.h openssh-7.3p1/version.h +--- openssh-7.3p1.orig/version.h 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/version.h 2016-08-15 15:39:50.075808639 +0200 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.76 2016/02/23 09:14:34 djm Exp $ */ + /* $OpenBSD: version.h,v 1.77 2016/07/24 11:45:36 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3007,9 +3005,9 @@ diff -Nur openssh-7.2p1.orig/version.h openssh-7.2p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20150812" + - #define SSH_VERSION "OpenSSH_7.2" + #define SSH_VERSION "OpenSSH_7.3" - #define SSH_PORTABLE "p2" + #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE \ + NCSA_VERSION GSI_VERSION KRB5_VERSION diff --git a/sources b/sources index 7c814f0..11a8bcb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -13009a9156510d8f27e752659075cced openssh-7.2p2.tar.gz +dfadd9f035d38ce5d58a3bf130b86d08 openssh-7.3p1.tar.gz From da02042fe2a42ffcd418d4bcf6d2cc4f995a97ab Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 20 Oct 2016 14:15:31 +0200 Subject: [PATCH 032/146] Based on openssh-7.3p1-4.fc25 --- gsi-openssh.spec | 10 ++++--- openssh-6.6p1-redhat.patch | 11 ++++---- openssh-6.6p1-role-mls.patch | 6 ++++- openssh-7.2p1-audit.patch | 8 ++++-- openssh-7.3p1-null-deref.patch | 48 ++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 openssh-7.3p1-null-deref.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 32b9d2f..d568881 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.3p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -163,6 +163,8 @@ Patch939: openssh-7.2p2-s390-closefrom.patch Patch940: openssh-7.2p2-expose-pam.patch # Rework SELinux context handling with chroot (#1357860) Patch942: openssh-7.2p2-chroot-capabilities.patch +# Null dereference in newkeys code (#1380297) +Patch943: openssh-7.3p1-null-deref.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -268,10 +270,8 @@ This version of OpenSSH has been modified to support GSI authentication. # investigate %patch102 -p1 -b .getaddrinfo %patch103 -p1 -b .packet -%if %{WITH_SELINUX} %patch400 -p1 -b .role-mls %patch404 -p1 -b .privsep-selinux -%endif %if %{ldap} %patch501 -p1 -b .ldap @@ -319,6 +319,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch939 -p1 -b .s390-dev %patch940 -p1 -b .expose-pam %patch942 -p1 -b .chroot-cap +%patch943 -p1 -b .deref %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -534,6 +535,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Oct 20 2016 Mattias Ellert - 7.3p1-2 +- Based on openssh-7.3p1-4.fc25 + * Mon Aug 15 2016 Mattias Ellert - 7.3p1-1 - Based on openssh-7.3p1-3.fc25 diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index 10b0b9e..de6216d 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -7,15 +7,16 @@ index 49a4f6c..3f83c40 100644 # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h +# -+# To modify the system-wide ssh configuration, create a file under -+# /etc/ssh/ssh_config.d/ which will get automatically included below ++# To modify the system-wide ssh configuration, create a *.conf file under ++# /etc/ssh/ssh_config.d/ which will be automatically included below +Include /etc/ssh/ssh_config.d/*.conf diff --git a/ssh_config_redhat b/ssh_config_redhat -new file mode 100644 -index 0000000..9082a13 --- /dev/null +++ b/ssh_config_redhat -@@ -0,0 +1,17 @@ +@@ -0,0 +1,20 @@ ++# Follow system-wide Crypto Poliicy, if defined: ++Include /etc/crypto-policies/back-ends/openssh.txt ++ +# Uncomment this if you want to use .local domain +# Host *.local +# CheckHostIP no diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index 8c9485e..76e6721 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -131,7 +131,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c --- openssh/auth2-pubkey.c.role-mls 2016-07-24 13:50:13.000000000 +0200 +++ openssh/auth2-pubkey.c 2016-07-26 12:37:48.794593332 +0200 -@@ -151,9 +151,11 @@ userauth_pubkey(Authctxt *authctxt) +@@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -140,8 +140,12 @@ diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c authctxt->style ? ":" : "", - authctxt->style ? authctxt->style : ""); + authctxt->style ? authctxt->style : "", ++#ifdef WITH_SELINUX + authctxt->role ? "/" : "", + authctxt->role ? authctxt->role : ""); ++#else ++ "", ""); ++#endif buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index 081671d..8654e95 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -1285,7 +1285,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1908,11 +1956,43 @@ mm_answer_audit_command(int socket, Buff +@@ -1908,11 +1956,45 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1300,7 +1300,9 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c + if (s == NULL) + fatal("%s: error allocating a session", __func__); + s->command = cmd; ++#ifdef SSH_AUDIT_EVENTS + s->command_handle = audit_run_command(cmd); ++#endif + + buffer_clear(m); + buffer_put_int(m, s->self); @@ -1875,11 +1877,13 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1986,6 +2001,7 @@ session_unused(int id) +@@ -1986,6 +2001,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; ++#ifdef SSH_AUDIT_EVENTS + sessions[id].command_handle = -1; ++#endif sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } diff --git a/openssh-7.3p1-null-deref.patch b/openssh-7.3p1-null-deref.patch new file mode 100644 index 0000000..041ae78 --- /dev/null +++ b/openssh-7.3p1-null-deref.patch @@ -0,0 +1,48 @@ +From 28652bca29046f62c7045e933e6b931de1d16737 Mon Sep 17 00:00:00 2001 +From: "markus@openbsd.org" +Date: Mon, 19 Sep 2016 19:02:19 +0000 +Subject: upstream commit + +move inbound NEWKEYS handling to kex layer; otherwise +early NEWKEYS causes NULL deref; found by Robert Swiecki/honggfuzz; fixed +with & ok djm@ + +Upstream-ID: 9a68b882892e9f51dc7bfa9f5a423858af358b2f +--- + kex.c | 4 +++- + packet.c | 6 ++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/kex.c b/kex.c +index f4c130f..8800d40 100644 +--- a/kex.c ++++ b/kex.c +@@ -425,6 +425,8 @@ kex_input_newkeys(int type, u_int32_t seq, void *ctxt) + ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); + if ((r = sshpkt_get_end(ssh)) != 0) + return r; ++ if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) ++ return r; + kex->done = 1; + sshbuf_reset(kex->peer); + /* sshbuf_reset(kex->my); */ +diff --git a/packet.c b/packet.c +index 711091d..fb316ac 100644 +--- a/packet.c ++++ b/packet.c +@@ -1907,9 +1907,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } +- if (*typep == SSH2_MSG_NEWKEYS) +- r = ssh_set_newkeys(ssh, MODE_IN); +- else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) ++ if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) + r = ssh_packet_enable_delayed_compress(ssh); + else + r = 0; +-- +cgit v0.12 + +0 + From 8c517cb8d1df431e78fa52b9e3b263875bd7a790 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 2 Nov 2016 16:44:54 +0100 Subject: [PATCH 033/146] Based on openssh-7.3p1-5.fc26 --- gsi-openssh.spec | 9 +- openssh-7.2p2-chroot-capabilities.patch | 5 +- openssh-7.3p1-gsissh.patch | 11 - openssh-7.3p1-openssl-1.1.0.patch | 4100 +++++++++++++++++++++++ 4 files changed, 4111 insertions(+), 14 deletions(-) create mode 100644 openssh-7.3p1-openssl-1.1.0.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d568881..1fef480 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.3p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -59,6 +59,8 @@ Patch100: openssh-6.7p1-coverity.patch #Patch102: openssh-5.8p1-getaddrinfo.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1889 Patch103: openssh-5.8p1-packet.patch +# OpenSSL 1.1.0 compatibility +Patch104: openssh-7.3p1-openssl-1.1.0.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 @@ -219,6 +221,7 @@ Obsoletes: gsissh-clients < 5.8p2-2 Group: Applications/Internet Requires: %{name} = %{version}-%{release} Requires: fipscheck-lib%{_isa} >= 1.3.0 +Recommends: crypto-policies %package server Summary: SSH server daemon with GSI authentication @@ -326,6 +329,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch700 -p1 -b .fips %patch100 -p1 -b .coverity +%patch104 -p1 -b .openssl %patch98 -p1 -b .gsi @@ -535,6 +539,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Nov 02 2016 Mattias Ellert - 7.3p1-3 +- Based on openssh-7.3p1-5.fc26 + * Thu Oct 20 2016 Mattias Ellert - 7.3p1-2 - Based on openssh-7.3p1-4.fc25 diff --git a/openssh-7.2p2-chroot-capabilities.patch b/openssh-7.2p2-chroot-capabilities.patch index 69a5342..ea71cb9 100644 --- a/openssh-7.2p2-chroot-capabilities.patch +++ b/openssh-7.2p2-chroot-capabilities.patch @@ -63,7 +63,7 @@ index 6cfcba4..80d2806 100644 platform_setusercontext(pw); -@@ -1619,10 +1624,24 @@ do_setusercontext(struct passwd *pw) +@@ -1619,10 +1624,25 @@ do_setusercontext(struct passwd *pw) pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); @@ -71,7 +71,8 @@ index 6cfcba4..80d2806 100644 + /* drop suid soon, retain SYS_CHROOT capability */ + capng_clear(CAPNG_SELECT_BOTH); + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SYS_CHROOT); -+ if ((dropped_suid = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) != 0) ++ if (pw->pw_uid != 0 && ++ (dropped_suid = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_INIT_SUPP_GRP)) != 0) + logit("capng_change_id() = %d (failure): Try to drop UID later", dropped_suid); +#endif #ifdef WITH_SELINUX diff --git a/openssh-7.3p1-gsissh.patch b/openssh-7.3p1-gsissh.patch index 90b0e20..8a5548d 100644 --- a/openssh-7.3p1-gsissh.patch +++ b/openssh-7.3p1-gsissh.patch @@ -373,17 +373,6 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c --- openssh-7.3p1.orig/auth-pam.c 2016-08-15 15:32:58.783404387 +0200 +++ openssh-7.3p1/auth-pam.c 2016-08-15 15:33:35.804990178 +0200 -@@ -123,6 +123,10 @@ - */ - typedef pthread_t sp_pthread_t; - #else -+#define pthread_create openssh_pthread_create -+#define pthread_exit openssh_pthread_exit -+#define pthread_cancel openssh_pthread_cancel -+#define pthread_join openssh_pthread_join - typedef pid_t sp_pthread_t; - #endif - @@ -280,6 +284,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch new file mode 100644 index 0000000..17508d2 --- /dev/null +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -0,0 +1,4100 @@ +diff -up openssh-7.3p1/auth1.c.openssl openssh-7.3p1/auth1.c +--- openssh-7.3p1/auth1.c.openssl 2016-10-27 14:28:16.459815636 +0200 ++++ openssh-7.3p1/auth1.c 2016-10-27 14:28:16.614815267 +0200 +@@ -164,6 +164,7 @@ auth1_process_rhosts_rsa(Authctxt *authc + u_int bits; + Key *client_host_key; + u_int ulen; ++ BIGNUM *n = NULL, *e = NULL; + + /* + * Get client user name. Note that we just have to +@@ -175,14 +176,17 @@ auth1_process_rhosts_rsa(Authctxt *authc + /* Get the client host key. */ + client_host_key = key_new(KEY_RSA1); + bits = packet_get_int(); +- packet_get_bignum(client_host_key->rsa->e); +- packet_get_bignum(client_host_key->rsa->n); ++ if( (n = BN_new()) == NULL || (e = BN_new()) == NULL) ++ return 0; ++ packet_get_bignum(e); ++ packet_get_bignum(n); ++ RSA_set0_key(client_host_key->rsa, n, e, NULL); + +- keybits = BN_num_bits(client_host_key->rsa->n); ++ keybits = BN_num_bits(n); + if (keybits < 0 || bits != (u_int)keybits) { + verbose("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", +- BN_num_bits(client_host_key->rsa->n), bits); ++ BN_num_bits(n), bits); + } + packet_check_eom(); + +diff -up openssh-7.3p1/authfd.c.openssl openssh-7.3p1/authfd.c +--- openssh-7.3p1/authfd.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/authfd.c 2016-10-27 14:28:16.614815267 +0200 +@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids + int r, keybits; + u_int32_t bits; + char *comment = NULL; ++ BIGNUM *e = NULL, *n = NULL; + + if ((key = sshkey_new(KEY_RSA1)) == NULL) + return SSH_ERR_ALLOC_FAIL; +- if ((r = sshbuf_get_u32(ids, &bits)) != 0 || +- (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || +- (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || +- (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) ++ if ((e = BN_new()) == NULL || ++ (n = BN_new()) == NULL || ++ (r = sshbuf_get_u32(ids, &bits)) != 0 || ++ (r = sshbuf_get_bignum1(ids, e)) != 0 || ++ (r = sshbuf_get_bignum1(ids, n)) != 0 || ++ (RSA_set0_key(key->rsa, n, e, NULL) == 0) || ++ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) { ++ BN_free(n); ++ BN_free(e); + goto out; +- keybits = BN_num_bits(key->rsa->n); ++ } ++ keybits = BN_num_bits(n); + /* XXX previously we just warned here. I think we should be strict */ + if (keybits < 0 || bits != (u_int)keybits) { + r = SSH_ERR_KEY_BITS_MISMATCH; +@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct s + struct sshbuf *msg; + int r; + u_char type; ++ const BIGNUM *e, *n; + + if (key->type != KEY_RSA1) + return SSH_ERR_INVALID_ARGUMENT; + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; ++ RSA_get0_key(key->rsa, &n, &e, NULL); + if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || +- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || +- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || +- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || ++ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || ++ (r = sshbuf_put_bignum1(msg, e)) != 0 || ++ (r = sshbuf_put_bignum1(msg, n)) != 0 || + (r = sshbuf_put_bignum1(msg, challenge)) != 0 || + (r = sshbuf_put(msg, session_id, 16)) != 0 || + (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ +@@ -499,15 +508,19 @@ static int + ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) + { + int r; ++ const BIGNUM *n, *e, *d, *q, *p, *iqmp; + ++ RSA_get0_key(key, &n, &e, &d); ++ RSA_get0_factors(key, &p, &q); ++ RSA_get0_crt_params(key, NULL, NULL, &iqmp); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ +- if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 || +- (r = sshbuf_put_bignum1(b, key->n)) != 0 || +- (r = sshbuf_put_bignum1(b, key->e)) != 0 || +- (r = sshbuf_put_bignum1(b, key->d)) != 0 || +- (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || +- (r = sshbuf_put_bignum1(b, key->q)) != 0 || +- (r = sshbuf_put_bignum1(b, key->p)) != 0 || ++ if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 || ++ (r = sshbuf_put_bignum1(b, n)) != 0 || ++ (r = sshbuf_put_bignum1(b, e)) != 0 || ++ (r = sshbuf_put_bignum1(b, d)) != 0 || ++ (r = sshbuf_put_bignum1(b, iqmp)) != 0 || ++ (r = sshbuf_put_bignum1(b, q)) != 0 || ++ (r = sshbuf_put_bignum1(b, p)) != 0 || + (r = sshbuf_put_cstring(b, comment)) != 0) + return r; + return 0; +@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct ssh + + #ifdef WITH_SSH1 + if (key->type == KEY_RSA1) { ++ const BIGNUM *e, *n; ++ RSA_get0_key(key->rsa, &n, &e, NULL); + if ((r = sshbuf_put_u8(msg, + SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || +- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || +- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || +- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) ++ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || ++ (r = sshbuf_put_bignum1(msg, e)) != 0 || ++ (r = sshbuf_put_bignum1(msg, n)) != 0) + goto out; + } else + #endif +diff -up openssh-7.3p1/auth-pam.c.openssl openssh-7.3p1/auth-pam.c +--- openssh-7.3p1/auth-pam.c.openssl 2016-10-27 14:28:16.577815355 +0200 ++++ openssh-7.3p1/auth-pam.c 2016-10-27 14:28:16.615815264 +0200 +@@ -124,6 +124,10 @@ extern u_int utmp_len; + typedef pthread_t sp_pthread_t; + #else + typedef pid_t sp_pthread_t; ++# define pthread_create(a, b, c, d) _ssh_compat_pthread_create(a, b, c, d) ++# define pthread_exit(a) _ssh_compat_pthread_exit(a) ++# define pthread_cancel(a) _ssh_compat_pthread_cancel(a) ++# define pthread_join(a, b) _ssh_compat_pthread_join(a, b) + #endif + + struct pam_ctxt { +diff -up openssh-7.3p1/auth-rsa.c.openssl openssh-7.3p1/auth-rsa.c +--- openssh-7.3p1/auth-rsa.c.openssl 2016-10-27 14:28:16.592815319 +0200 ++++ openssh-7.3p1/auth-rsa.c 2016-10-27 14:28:16.615815264 +0200 +@@ -75,6 +75,7 @@ auth_rsa_generate_challenge(Key *key) + { + BIGNUM *challenge; + BN_CTX *ctx; ++ const BIGNUM *n; + + if ((challenge = BN_new()) == NULL) + fatal("auth_rsa_generate_challenge: BN_new() failed"); +@@ -83,7 +84,8 @@ auth_rsa_generate_challenge(Key *key) + fatal("auth_rsa_generate_challenge: BN_rand failed"); + if ((ctx = BN_CTX_new()) == NULL) + fatal("auth_rsa_generate_challenge: BN_CTX_new failed"); +- if (BN_mod(challenge, challenge, key->rsa->n, ctx) == 0) ++ RSA_get0_key(key->rsa, &n, NULL, NULL); ++ if (BN_mod(challenge, challenge, n, ctx) == 0) + fatal("auth_rsa_generate_challenge: BN_mod failed"); + BN_CTX_free(ctx); + +@@ -99,12 +101,14 @@ auth_rsa_verify_response(Key *key, BIGNU + #ifdef SSH_AUDIT_EVENTS + char *fp; + #endif ++ const BIGNUM *n; + + /* don't allow short keys */ +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { ++ RSA_get0_key(key->rsa, &n, NULL, NULL); ++ if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error("%s: RSA modulus too small: %d < minimum %d bits", + __func__, +- BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); ++ BN_num_bits(n), SSH_RSA_MINIMUM_MODULUS_SIZE); + return (0); + } + +@@ -200,6 +204,7 @@ rsa_key_allowed_in_file(struct passwd *p + char *cp; + char *key_options; + int keybits; ++ const BIGNUM *n; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) +@@ -237,15 +242,16 @@ rsa_key_allowed_in_file(struct passwd *p + * Check if the we have found the desired key (identified + * by its modulus). + */ +- if (BN_cmp(key->rsa->n, client_n) != 0) ++ RSA_get0_key(key->rsa, &n, NULL, NULL); ++ if (BN_cmp(n, client_n) != 0) + continue; + + /* check the real bits */ +- keybits = BN_num_bits(key->rsa->n); ++ keybits = BN_num_bits(n); + if (keybits < 0 || bits != keybits) + logit("Warning: %s, line %lu: keysize mismatch: " + "actual %d vs. announced %d.", +- file, linenum, BN_num_bits(key->rsa->n), bits); ++ file, linenum, BN_num_bits(n), bits); + + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) +diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c +--- openssh-7.3p1/cipher-3des1.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/cipher-3des1.c 2016-10-27 14:28:16.615815264 +0200 +@@ -42,7 +42,7 @@ + */ + struct ssh1_3des_ctx + { +- EVP_CIPHER_CTX k1, k2, k3; ++ EVP_CIPHER_CTX *k1, *k2, *k3; + }; + + const EVP_CIPHER * evp_ssh1_3des(void); +@@ -63,7 +63,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons + if (key == NULL) + return 1; + if (enc == -1) +- enc = ctx->encrypt; ++ enc = EVP_CIPHER_CTX_encrypting(ctx); + k1 = k2 = k3 = (u_char *) key; + k2 += 8; + if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { +@@ -72,12 +72,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons + else + k1 += 16; + } +- EVP_CIPHER_CTX_init(&c->k1); +- EVP_CIPHER_CTX_init(&c->k2); +- EVP_CIPHER_CTX_init(&c->k3); +- if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || +- EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || +- EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { ++ c->k1 = EVP_CIPHER_CTX_new(); ++ c->k2 = EVP_CIPHER_CTX_new(); ++ c->k3 = EVP_CIPHER_CTX_new(); ++ if (c->k1 == NULL || c->k2 == NULL || c->k3 == NULL) { ++ EVP_CIPHER_CTX_free(c->k1); ++ EVP_CIPHER_CTX_free(c->k2); ++ EVP_CIPHER_CTX_free(c->k3); ++ free(c); ++ return 0; ++ } ++ if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || ++ EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || ++ EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { + explicit_bzero(c, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); +@@ -93,9 +100,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) + return 0; +- if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || +- EVP_Cipher(&c->k2, dest, dest, len) == 0 || +- EVP_Cipher(&c->k3, dest, dest, len) == 0) ++ if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || ++ EVP_Cipher(c->k2, dest, dest, len) == 0 || ++ EVP_Cipher(c->k3, dest, dest, len) == 0) + return 0; + return 1; + } +@@ -106,9 +113,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) + struct ssh1_3des_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { +- EVP_CIPHER_CTX_cleanup(&c->k1); +- EVP_CIPHER_CTX_cleanup(&c->k2); +- EVP_CIPHER_CTX_cleanup(&c->k3); ++ EVP_CIPHER_CTX_free(c->k1); ++ EVP_CIPHER_CTX_free(c->k2); ++ EVP_CIPHER_CTX_free(c->k3); + explicit_bzero(c, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); +@@ -126,13 +133,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (doset) { +- memcpy(c->k1.iv, iv, 8); +- memcpy(c->k2.iv, iv + 8, 8); +- memcpy(c->k3.iv, iv + 16, 8); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); + } else { +- memcpy(iv, c->k1.iv, 8); +- memcpy(iv + 8, c->k2.iv, 8); +- memcpy(iv + 16, c->k3.iv, 8); ++ memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); ++ memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); ++ memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); + } + return 0; + } +@@ -140,16 +147,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do + const EVP_CIPHER * + evp_ssh1_3des(void) + { +- static EVP_CIPHER ssh1_3des; ++ EVP_CIPHER *ssh1_3des; + +- memset(&ssh1_3des, 0, sizeof(ssh1_3des)); +- ssh1_3des.nid = NID_undef; +- ssh1_3des.block_size = 8; +- ssh1_3des.iv_len = 0; +- ssh1_3des.key_len = 16; +- ssh1_3des.init = ssh1_3des_init; +- ssh1_3des.cleanup = ssh1_3des_cleanup; +- ssh1_3des.do_cipher = ssh1_3des_cbc; +- ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; +- return &ssh1_3des; ++ ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16); ++ EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0); ++ EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init); ++ EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup); ++ EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc); ++ EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); ++ return ssh1_3des; + } +diff -up openssh-7.3p1/cipher-bf1.c.openssl openssh-7.3p1/cipher-bf1.c +--- openssh-7.3p1/cipher-bf1.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/cipher-bf1.c 2016-10-27 14:28:16.615815264 +0200 +@@ -88,16 +88,27 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_ch + const EVP_CIPHER * + evp_ssh1_bf(void) + { +- static EVP_CIPHER ssh1_bf; ++ EVP_CIPHER *ssh1_bf; + +- memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); +- orig_bf = ssh1_bf.do_cipher; +- ssh1_bf.nid = NID_undef; ++ orig_bf = EVP_CIPHER_meth_get_do_cipher(EVP_bf_cbc()); ++ /* block_size, length, flags from openssl/crypto/engine/eng_cryptodev.c:638 */ ++ ssh1_bf = EVP_CIPHER_meth_new(NID_undef, 8, 32); ++ EVP_CIPHER_meth_set_iv_length(ssh1_bf, 8); ++ EVP_CIPHER_meth_set_flags(ssh1_bf, EVP_CIPH_CBC_MODE); + #ifdef SSH_OLD_EVP +- ssh1_bf.init = bf_ssh1_init; ++ EVP_CIPHER_meth_set_init(ssh1_bf, ssh1_bf_init); ++#else ++ EVP_CIPHER_meth_set_init(ssh1_bf, ++ EVP_CIPHER_meth_get_init(EVP_bf_cbc())); + #endif +- ssh1_bf.do_cipher = bf_ssh1_cipher; +- ssh1_bf.key_len = 32; +- return (&ssh1_bf); ++ /* copy methods and parameters from old EVP_BF_cbc() ++ * meth_dup does not allow to change type and key_len */ ++ EVP_CIPHER_meth_set_cleanup(ssh1_bf, ++ EVP_CIPHER_meth_get_cleanup(EVP_bf_cbc())); ++ EVP_CIPHER_meth_set_ctrl(ssh1_bf, ++ EVP_CIPHER_meth_get_ctrl(EVP_bf_cbc())); ++ /* ASN1 params??? */ ++ EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_cipher); ++ return ssh1_bf; + } + #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */ +diff -up openssh-7.3p1/cipher.c.openssl openssh-7.3p1/cipher.c +--- openssh-7.3p1/cipher.c.openssl 2016-10-27 14:28:16.607815283 +0200 ++++ openssh-7.3p1/cipher.c 2016-10-27 14:28:16.615815264 +0200 +@@ -330,29 +330,28 @@ cipher_init(struct sshcipher_ctx *cc, co + return SSH_ERR_INVALID_ARGUMENT; + #else + type = (*cipher->evptype)(); +- EVP_CIPHER_CTX_init(&cc->evp); +- if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, ++ if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto bad; ++ } ++ if (EVP_CipherInit(cc->evp, type, (u_char *)key, (u_char *)iv, + (do_encrypt == CIPHER_ENCRYPT)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto bad; + } + if (cipher_authlen(cipher) && +- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, ++ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, + -1, (u_char *)iv)) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto bad; + } +- klen = EVP_CIPHER_CTX_key_length(&cc->evp); ++ klen = EVP_CIPHER_CTX_key_length(cc->evp); + if (klen > 0 && keylen != (u_int)klen) { +- if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { ++ if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto bad; + } + } +- if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { +- ret = SSH_ERR_LIBCRYPTO_ERROR; +- goto bad; +- } + + if (cipher->discard_len > 0) { + if ((junk = malloc(cipher->discard_len)) == NULL || +@@ -361,14 +360,14 @@ cipher_init(struct sshcipher_ctx *cc, co + ret = SSH_ERR_ALLOC_FAIL; + goto bad; + } +- ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); ++ ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); + explicit_bzero(discard, cipher->discard_len); + free(junk); + free(discard); + if (ret != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + bad: +- EVP_CIPHER_CTX_cleanup(&cc->evp); ++ EVP_CIPHER_CTX_free(cc->evp); + return ret; + } + } +@@ -414,33 +413,33 @@ cipher_crypt(struct sshcipher_ctx *cc, u + if (authlen != cipher_authlen(cc->cipher)) + return SSH_ERR_INVALID_ARGUMENT; + /* increment IV */ +- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, ++ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, + 1, lastiv)) + return SSH_ERR_LIBCRYPTO_ERROR; + /* set tag on decyption */ + if (!cc->encrypt && +- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, ++ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, + authlen, (u_char *)src + aadlen + len)) + return SSH_ERR_LIBCRYPTO_ERROR; + } + if (aadlen) { + if (authlen && +- EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) ++ EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0) + return SSH_ERR_LIBCRYPTO_ERROR; + memcpy(dest, src, aadlen); + } + if (len % cc->cipher->block_size) + return SSH_ERR_INVALID_ARGUMENT; +- if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, ++ if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen, + len) < 0) + return SSH_ERR_LIBCRYPTO_ERROR; + if (authlen) { + /* compute tag (on encrypt) or verify tag (on decrypt) */ +- if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) ++ if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) + return cc->encrypt ? + SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; + if (cc->encrypt && +- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, ++ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, + authlen, dest + aadlen + len)) + return SSH_ERR_LIBCRYPTO_ERROR; + } +@@ -472,8 +471,8 @@ cipher_cleanup(struct sshcipher_ctx *cc) + else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) + explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); + #ifdef WITH_OPENSSL +- else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) +- return SSH_ERR_LIBCRYPTO_ERROR; ++ EVP_CIPHER_CTX_free(cc->evp); ++ cc->evp = NULL; + #endif + return 0; + } +@@ -519,7 +518,7 @@ cipher_get_keyiv_len(const struct sshcip + ivlen = sizeof(cc->ac_ctx.ctr); + #ifdef WITH_OPENSSL + else +- ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); ++ ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); + #endif /* WITH_OPENSSL */ + return (ivlen); + } +@@ -551,7 +550,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: +- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); ++ evplen = EVP_CIPHER_CTX_iv_length(cc->evp); + if (evplen == 0) + return 0; + else if (evplen < 0) +@@ -560,20 +559,20 @@ cipher_get_keyiv(struct sshcipher_ctx *c + return SSH_ERR_INVALID_ARGUMENT; + #ifndef OPENSSL_HAVE_EVPCTR + if (c->evptype == evp_aes_128_ctr) +- ssh_aes_ctr_iv(&cc->evp, 0, iv, len); ++ ssh_aes_ctr_iv(cc->evp, 0, iv, len); + else + #endif + if (cipher_authlen(c)) { +- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, ++ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, + len, iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(iv, cc->evp.iv, len); ++ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); + break; + #endif + #ifdef WITH_SSH1 + case SSH_CIPHER_3DES: +- return ssh1_3des_iv(&cc->evp, 0, iv, 24); ++ return ssh1_3des_iv(cc->evp, 0, iv, 24); + #endif + default: + return SSH_ERR_INVALID_ARGUMENT; +@@ -599,21 +598,21 @@ cipher_set_keyiv(struct sshcipher_ctx *c + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: +- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); ++ evplen = EVP_CIPHER_CTX_iv_length(cc->evp); + if (evplen <= 0) + return SSH_ERR_LIBCRYPTO_ERROR; + if (cipher_authlen(c)) { + /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ +- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, ++ if (!EVP_CIPHER_CTX_ctrl(cc->evp, + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(cc->evp.iv, iv, evplen); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); + break; + #endif + #ifdef WITH_SSH1 + case SSH_CIPHER_3DES: +- return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); ++ return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); + #endif + default: + return SSH_ERR_INVALID_ARGUMENT; +@@ -622,8 +621,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c + } + + #ifdef WITH_OPENSSL +-#define EVP_X_STATE(evp) (evp).cipher_data +-#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size ++#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp) ++#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp)) + #endif + + int +diff -up openssh-7.3p1/cipher.h.openssl openssh-7.3p1/cipher.h +--- openssh-7.3p1/cipher.h.openssl 2016-10-27 14:28:16.593815317 +0200 ++++ openssh-7.3p1/cipher.h 2016-10-27 14:28:16.616815262 +0200 +@@ -85,7 +85,7 @@ struct sshcipher { + struct sshcipher_ctx { + int plaintext; + int encrypt; +- EVP_CIPHER_CTX evp; ++ EVP_CIPHER_CTX *evp; + struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ + struct aesctr_ctx ac_ctx; /* XXX union with evp? */ + const struct sshcipher *cipher; +diff -up openssh-7.3p1/ctr-cavstest.c.openssl openssh-7.3p1/ctr-cavstest.c +--- openssh-7.3p1/ctr-cavstest.c.openssl 2016-10-27 14:28:16.506815524 +0200 ++++ openssh-7.3p1/ctr-cavstest.c 2016-10-27 14:28:16.616815262 +0200 +@@ -144,7 +144,7 @@ int main (int argc, char *argv[]) + usage(); + } + +- SSLeay_add_all_algorithms(); ++ OpenSSL_add_all_algorithms(); + + c = cipher_by_name(algo); + if (c == NULL) { +diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c +--- openssh-7.3p1/dh.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/dh.c 2016-10-27 14:28:16.616815262 +0200 +@@ -213,14 +213,15 @@ choose_dh(int min, int wantbits, int max + /* diffie-hellman-groupN-sha1 */ + + int +-dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) ++dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) + { + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + BIGNUM *tmp; ++ const BIGNUM *p; + +- if (dh_pub->neg) { ++ if (BN_is_negative(dh_pub)) { + logit("invalid public DH value: negative"); + return 0; + } +@@ -233,7 +234,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) + error("%s: BN_new failed", __func__); + return 0; + } +- if (!BN_sub(tmp, dh->p, BN_value_one()) || ++ DH_get0_pqg(dh, &p, NULL, NULL); ++ if (!BN_sub(tmp, p, BN_value_one()) || + BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ + BN_clear_free(tmp); + logit("invalid public DH value: >= p-1"); +@@ -244,14 +246,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; +- debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); ++ debug2("bits set: %d/%d", bits_set, BN_num_bits(p)); + + /* + * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial + */ + if (bits_set < 4) { + logit("invalid public DH value (%d/%d)", +- bits_set, BN_num_bits(dh->p)); ++ bits_set, BN_num_bits(p)); + return 0; + } + return 1; +@@ -261,9 +263,11 @@ int + dh_gen_key(DH *dh, int need) + { + int pbits; ++ const BIGNUM *p, *pub_key; + +- if (need < 0 || dh->p == NULL || +- (pbits = BN_num_bits(dh->p)) <= 0 || ++ DH_get0_pqg(dh, &p, NULL, NULL); ++ if (need < 0 || p == NULL || ++ (pbits = BN_num_bits(p)) <= 0 || + need > INT_MAX / 2 || 2 * need > pbits) + return SSH_ERR_INVALID_ARGUMENT; + if (need < 256) +@@ -272,12 +276,12 @@ dh_gen_key(DH *dh, int need) + * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), + * so double requested need here. + */ +- dh->length = MIN(need * 2, pbits - 1); +- if (DH_generate_key(dh) == 0 || +- !dh_pub_is_valid(dh, dh->pub_key)) { +- BN_clear_free(dh->priv_key); ++ DH_set_length(dh, MINIMUM(need * 2, pbits - 1)); ++ 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_LIBCRYPTO_ERROR; +- } + return 0; + } + +@@ -285,15 +289,22 @@ DH * + dh_new_group_asc(const char *gen, const char *modulus) + { + DH *dh; ++ BIGNUM *p, *g; + +- if ((dh = DH_new()) == NULL) +- return NULL; +- if (BN_hex2bn(&dh->p, modulus) == 0 || +- BN_hex2bn(&dh->g, gen) == 0) { +- DH_free(dh); +- return NULL; +- } ++ if ((dh = DH_new()) == NULL || ++ (p = BN_new()) == NULL || ++ (g = BN_new()) == NULL) ++ goto err; ++ if (BN_hex2bn(&p, modulus) == 0 || ++ BN_hex2bn(&g, gen) == 0 || ++ DH_set0_pqg(dh, p, NULL, g) == 0) ++ goto err; + return (dh); ++err: ++ DH_free(dh); ++ BN_free(p); ++ BN_free(g); ++ return NULL; + } + + /* +@@ -308,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu + + if ((dh = DH_new()) == NULL) + return NULL; +- dh->p = modulus; +- dh->g = gen; ++ DH_set0_pqg(dh, modulus, NULL, gen); + + return (dh); + } +diff -up openssh-7.3p1/dh.h.openssl openssh-7.3p1/dh.h +--- openssh-7.3p1/dh.h.openssl 2016-10-27 14:28:16.602815295 +0200 ++++ openssh-7.3p1/dh.h 2016-10-27 14:28:16.616815262 +0200 +@@ -42,7 +42,7 @@ DH *dh_new_group18(void); + DH *dh_new_group_fallback(int); + + int dh_gen_key(DH *, int); +-int dh_pub_is_valid(DH *, BIGNUM *); ++int dh_pub_is_valid(const DH *, const BIGNUM *); + + u_int dh_estimate(int); + +diff -up openssh-7.3p1/digest-openssl.c.openssl openssh-7.3p1/digest-openssl.c +--- openssh-7.3p1/digest-openssl.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/digest-openssl.c 2016-10-27 14:28:16.616815262 +0200 +@@ -43,7 +43,7 @@ + + struct ssh_digest_ctx { + int alg; +- EVP_MD_CTX mdctx; ++ EVP_MD_CTX *mdctx; + }; + + struct ssh_digest { +@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg) + size_t + ssh_digest_blocksize(struct ssh_digest_ctx *ctx) + { +- return EVP_MD_CTX_block_size(&ctx->mdctx); ++ return EVP_MD_CTX_block_size(ctx->mdctx); + } + + struct ssh_digest_ctx * +@@ -119,8 +119,9 @@ ssh_digest_start(int alg) + if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) + return NULL; + ret->alg = alg; +- EVP_MD_CTX_init(&ret->mdctx); +- if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { ++ ret->mdctx = EVP_MD_CTX_new(); ++ if (ret->mdctx == NULL || ++ EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) { + free(ret); + return NULL; + } +@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ + if (from->alg != to->alg) + return SSH_ERR_INVALID_ARGUMENT; + /* we have bcopy-style order while openssl has memcpy-style */ +- if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) ++ if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx)) + return SSH_ERR_LIBCRYPTO_ERROR; + return 0; + } +@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ + int + ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) + { +- if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) ++ if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1) + return SSH_ERR_LIBCRYPTO_ERROR; + return 0; + } +@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx * + return SSH_ERR_INVALID_ARGUMENT; + if (dlen < digest->digest_len) /* No truncation allowed */ + return SSH_ERR_INVALID_ARGUMENT; +- if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) ++ if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1) + return SSH_ERR_LIBCRYPTO_ERROR; + if (l != digest->digest_len) /* sanity */ + return SSH_ERR_INTERNAL_ERROR; +@@ -173,7 +174,7 @@ void + ssh_digest_free(struct ssh_digest_ctx *ctx) + { + if (ctx != NULL) { +- EVP_MD_CTX_cleanup(&ctx->mdctx); ++ EVP_MD_CTX_free(ctx->mdctx); + explicit_bzero(ctx, sizeof(*ctx)); + free(ctx); + } +diff -up openssh-7.3p1/entropy.c.openssl openssh-7.3p1/entropy.c +--- openssh-7.3p1/entropy.c.openssl 2016-10-27 14:28:16.603815293 +0200 ++++ openssh-7.3p1/entropy.c 2016-10-27 14:28:16.616815262 +0200 +@@ -218,7 +218,9 @@ seed_rng(void) + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + + /* clean the PRNG status when exiting the program */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + atexit(RAND_cleanup); ++#endif + + #ifndef OPENSSL_PRNG_ONLY + if (RAND_status() == 1) { +diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c +--- openssh-7.3p1/gss-genr.c.openssl 2016-10-27 14:28:16.558815400 +0200 ++++ openssh-7.3p1/gss-genr.c 2016-10-27 14:28:16.617815259 +0200 +@@ -100,7 +100,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + u_char digest[EVP_MAX_MD_SIZE]; + char deroid[2]; + const EVP_MD *evp_md = EVP_md5(); +- EVP_MD_CTX md; ++ EVP_MD_CTX *md; + char *s, *cp, *p; + + if (gss_enc2oid != NULL) { +@@ -114,6 +114,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + + buffer_init(&buf); + ++ md = EVP_MD_CTX_new(); + oidpos = 0; + s = cp = xstrdup(kex); + for (i = 0; i < gss_supported->count; i++) { +@@ -123,12 +124,13 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + deroid[0] = SSH_GSS_OIDTYPE; + deroid[1] = gss_supported->elements[i].length; + +- EVP_DigestInit(&md, evp_md); +- EVP_DigestUpdate(&md, deroid, 2); +- EVP_DigestUpdate(&md, ++ EVP_MD_CTX_reset(md); ++ EVP_DigestInit(md, evp_md); ++ EVP_DigestUpdate(md, deroid, 2); ++ EVP_DigestUpdate(md, + gss_supported->elements[i].elements, + gss_supported->elements[i].length); +- EVP_DigestFinal(&md, digest, NULL); ++ EVP_DigestFinal(md, digest, NULL); + + encoded = xmalloc(EVP_MD_size(evp_md) * 2); + enclen = __b64_ntop(digest, EVP_MD_size(evp_md), +@@ -150,6 +152,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + } + } + free(s); ++ EVP_MD_CTX_free(md); + gss_enc2oid[oidpos].oid = NULL; + gss_enc2oid[oidpos].encoded = NULL; + +diff -up openssh-7.3p1/includes.h.openssl openssh-7.3p1/includes.h +--- openssh-7.3p1/includes.h.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/includes.h 2016-10-27 14:28:16.617815259 +0200 +@@ -163,6 +163,7 @@ + + #ifdef WITH_OPENSSL + #include /* For OPENSSL_VERSION_NUMBER */ ++#include "libcrypto-compat.h" + #endif + + #include "defines.h" +diff -up openssh-7.3p1/kexdhc.c.openssl openssh-7.3p1/kexdhc.c +--- openssh-7.3p1/kexdhc.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/kexdhc.c 2016-10-27 14:28:16.617815259 +0200 +@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) + { + struct kex *kex = ssh->kex; + int r; ++ const BIGNUM *pub_key; + + /* generate and send 'e', client DH public key */ + switch (kex->kex_type) { +@@ -81,21 +82,27 @@ kexdh_client(struct ssh *ssh) + goto out; + } + debug("sending SSH2_MSG_KEXDH_INIT"); +- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || +- (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) ++ goto out; ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + #ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, kex->dh); + fprintf(stderr, "pub= "); +- BN_print_fp(stderr, kex->dh->pub_key); ++ BN_print_fp(stderr, pub_key); + fprintf(stderr, "\n"); + #endif + debug("expecting SSH2_MSG_KEXDH_REPLY"); + ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); + r = 0; + out: ++ if (r != 0) { ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ } + return r; + } + +@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, vo + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t klen = 0, slen, sbloblen, hashlen; + int kout, r; ++ const BIGNUM *pub_key; + + if (kex->verify_host_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; +@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, vo + #endif + + /* calc and verify H */ ++ DH_get0_key(kex->dh, &pub_key, NULL); + hashlen = sizeof(hash); + if ((r = kex_dh_hash( + kex->hash_alg, +@@ -177,7 +186,7 @@ input_kex_dh(int type, u_int32_t seq, vo + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + server_host_key_blob, sbloblen, +- kex->dh->pub_key, ++ pub_key, + dh_server_pub, + shared_secret, + hash, &hashlen)) != 0) +diff -up openssh-7.3p1/kexdhs.c.openssl openssh-7.3p1/kexdhs.c +--- openssh-7.3p1/kexdhs.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/kexdhs.c 2016-10-27 14:28:16.617815259 +0200 +@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) + ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); + r = 0; + out: ++ if (r != 0) { ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ } + return r; + } + +@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t se + size_t sbloblen, slen; + size_t klen = 0, hashlen; + int kout, r; ++ const BIGNUM *pub_key; + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) { +@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t se + goto out; + /* calc H */ + hashlen = sizeof(hash); ++ DH_get0_key(kex->dh, &pub_key, NULL); + if ((r = kex_dh_hash( + kex->hash_alg, + kex->client_version_string, +@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t se + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + server_host_key_blob, sbloblen, + dh_client_pub, +- kex->dh->pub_key, ++ pub_key, + shared_secret, + hash, &hashlen)) != 0) + goto out; +@@ -198,7 +204,7 @@ input_kex_dh_init(int type, u_int32_t se + /* send server hostkey, DH pubkey 'f' and singed H */ + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; +diff -up openssh-7.3p1/kexgexc.c.openssl openssh-7.3p1/kexgexc.c +--- openssh-7.3p1/kexgexc.c.openssl 2016-10-27 14:28:16.603815293 +0200 ++++ openssh-7.3p1/kexgexc.c 2016-10-27 14:28:16.617815259 +0200 +@@ -96,6 +96,7 @@ input_kex_dh_gex_group(int type, u_int32 + struct kex *kex = ssh->kex; + BIGNUM *p = NULL, *g = NULL; + int r, bits; ++ const BIGNUM *pub_key; + + debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); + +@@ -120,26 +121,30 @@ input_kex_dh_gex_group(int type, u_int32 + p = g = NULL; /* belong to kex->dh now */ + + /* generate and send 'e', client DH public key */ +- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || +- (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) ++ goto out; ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); + #ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, kex->dh); + fprintf(stderr, "pub= "); +- BN_print_fp(stderr, kex->dh->pub_key); ++ BN_print_fp(stderr, pub_key); + fprintf(stderr, "\n"); + #endif + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); + r = 0; + out: +- if (p) +- BN_clear_free(p); +- if (g) +- BN_clear_free(g); ++ BN_clear_free(p); ++ BN_clear_free(g); ++ if (r != 0) { ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ } + return r; + } + +@@ -154,6 +159,7 @@ input_kex_dh_gex_reply(int type, u_int32 + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t klen = 0, slen, sbloblen, hashlen; + int kout, r; ++ const BIGNUM *p, *g, *pub_key; + + debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); + if (kex->verify_host_key == NULL) { +@@ -220,6 +226,8 @@ input_kex_dh_gex_reply(int type, u_int32 + kex->min = kex->max = -1; + + /* calc and verify H */ ++ DH_get0_pqg(kex->dh, &p, NULL, &g); ++ DH_get0_key(kex->dh, &pub_key, NULL); + hashlen = sizeof(hash); + if ((r = kexgex_hash( + kex->hash_alg, +@@ -229,8 +237,8 @@ input_kex_dh_gex_reply(int type, u_int32 + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + server_host_key_blob, sbloblen, + kex->min, kex->nbits, kex->max, +- kex->dh->p, kex->dh->g, +- kex->dh->pub_key, ++ p, g, ++ pub_key, + dh_server_pub, + shared_secret, + hash, &hashlen)) != 0) +diff -up openssh-7.3p1/kexgexs.c.openssl openssh-7.3p1/kexgexs.c +--- openssh-7.3p1/kexgexs.c.openssl 2016-10-27 14:28:16.603815293 +0200 ++++ openssh-7.3p1/kexgexs.c 2016-10-27 14:28:16.618815257 +0200 +@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int + struct kex *kex = ssh->kex; + int r; + u_int min = 0, max = 0, nbits = 0; ++ const BIGNUM *p, *g; + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); + if ((r = sshpkt_get_u32(ssh, &min)) != 0 || +@@ -102,9 +103,10 @@ input_kex_dh_gex_request(int type, u_int + goto out; + } + debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); ++ DH_get0_pqg(kex->dh, &p, NULL, &g); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, p)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, g)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + +@@ -116,6 +118,10 @@ input_kex_dh_gex_request(int type, u_int + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); + r = 0; + out: ++ if (r != 0) { ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ } + return r; + } + +@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_ + size_t sbloblen, slen; + size_t klen = 0, hashlen; + int kout, r; ++ const BIGNUM *p, *g, *pub_key; + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) { +@@ -193,6 +200,8 @@ input_kex_dh_gex_init(int type, u_int32_ + goto out; + /* calc H */ + hashlen = sizeof(hash); ++ DH_get0_pqg(kex->dh, &p, NULL, &g); ++ DH_get0_key(kex->dh, &pub_key, NULL); + if ((r = kexgex_hash( + kex->hash_alg, + kex->client_version_string, +@@ -201,9 +210,9 @@ input_kex_dh_gex_init(int type, u_int32_ + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + server_host_key_blob, sbloblen, + kex->min, kex->nbits, kex->max, +- kex->dh->p, kex->dh->g, ++ p, g, + dh_client_pub, +- kex->dh->pub_key, ++ pub_key, + shared_secret, + hash, &hashlen)) != 0) + goto out; +@@ -229,7 +238,7 @@ input_kex_dh_gex_init(int type, u_int32_ + /* send server hostkey, DH pubkey 'f' and singed H */ + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || +- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; +diff -up openssh-7.3p1/kexgssc.c.openssl openssh-7.3p1/kexgssc.c +--- openssh-7.3p1/kexgssc.c.openssl 2016-10-27 14:28:16.512815510 +0200 ++++ openssh-7.3p1/kexgssc.c 2016-10-27 14:28:16.618815257 +0200 +@@ -58,6 +58,7 @@ kexgss_client(struct ssh *ssh) { + BIGNUM *shared_secret = NULL; + BIGNUM *p = NULL; + BIGNUM *g = NULL; ++ const BIGNUM *pub_key, *p1, *g1; + u_char *kbuf; + u_char *serverhostkey = NULL; + u_char *empty = ""; +@@ -121,6 +122,7 @@ kexgss_client(struct ssh *ssh) { + + /* Step 1 - e is dh->pub_key */ + dh_gen_key(dh, ssh->kex->we_need * 8); ++ DH_get0_key(dh, &pub_key, NULL); + + /* This is f, we initialise it now to make life easier */ + dh_server_pub = BN_new(); +@@ -168,7 +170,7 @@ kexgss_client(struct ssh *ssh) { + packet_start(SSH2_MSG_KEXGSS_INIT); + packet_put_string(send_tok.value, + send_tok.length); +- packet_put_bignum2(dh->pub_key); ++ packet_put_bignum2((BIGNUM *)pub_key); + first = 0; + } else { + packet_start(SSH2_MSG_KEXGSS_CONTINUE); +@@ -275,13 +277,14 @@ kexgss_client(struct ssh *ssh) { + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, +- dh->pub_key, /* e */ ++ pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ + hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: ++ DH_get0_pqg(dh, &p1, NULL, &g1); + kexgex_hash( + ssh->kex->hash_alg, + ssh->kex->client_version_string, +@@ -290,8 +293,8 @@ kexgss_client(struct ssh *ssh) { + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + min, nbits, max, +- dh->p, dh->g, +- dh->pub_key, ++ p1, g1, ++ pub_key, + dh_server_pub, + shared_secret, + hash, &hashlen +diff -up openssh-7.3p1/kexgsss.c.openssl openssh-7.3p1/kexgsss.c +--- openssh-7.3p1/kexgsss.c.openssl 2016-10-27 14:28:16.512815510 +0200 ++++ openssh-7.3p1/kexgsss.c 2016-10-27 14:28:16.618815257 +0200 +@@ -77,6 +77,7 @@ kexgss_server(struct ssh *ssh) + char *mechs; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t hashlen; ++ const BIGNUM *p, *g, *pub_key; + + /* Initialise GSSAPI */ + +@@ -122,9 +123,10 @@ kexgss_server(struct ssh *ssh) + if (dh == NULL) + packet_disconnect("Protocol error: no matching group found"); + ++ DH_get0_pqg(dh, &p, NULL, &g); + packet_start(SSH2_MSG_KEXGSS_GROUP); +- packet_put_bignum2(dh->p); +- packet_put_bignum2(dh->g); ++ packet_put_bignum2((BIGNUM *)p); ++ packet_put_bignum2((BIGNUM *)g); + packet_send(); + + packet_write_wait(); +@@ -216,6 +218,7 @@ kexgss_server(struct ssh *ssh) + memset(kbuf, 0, klen); + free(kbuf); + ++ DH_get0_key(dh, &pub_key, NULL); + hashlen = sizeof(hash); + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: +@@ -225,7 +228,7 @@ kexgss_server(struct ssh *ssh) + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, /* Change this if we start sending host keys */ +- dh_client_pub, dh->pub_key, shared_secret, ++ dh_client_pub, pub_key, shared_secret, + hash, &hashlen + ); + break; +@@ -237,9 +240,9 @@ kexgss_server(struct ssh *ssh) + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + NULL, 0, + cmin, nbits, cmax, +- dh->p, dh->g, ++ p, g, + dh_client_pub, +- dh->pub_key, ++ pub_key, + shared_secret, + hash, &hashlen + ); +@@ -263,7 +266,7 @@ kexgss_server(struct ssh *ssh) + fatal("Couldn't get MIC"); + + packet_start(SSH2_MSG_KEXGSS_COMPLETE); +- packet_put_bignum2(dh->pub_key); ++ packet_put_bignum2((BIGNUM *)pub_key); + packet_put_string(msg_tok.value,msg_tok.length); + + if (send_tok.length != 0) { +diff -up openssh-7.3p1/libcrypto-compat.c.openssl openssh-7.3p1/libcrypto-compat.c +--- openssh-7.3p1/libcrypto-compat.c.openssl 2016-10-27 14:28:16.618815257 +0200 ++++ openssh-7.3p1/libcrypto-compat.c 2016-10-27 14:28:16.618815257 +0200 +@@ -0,0 +1,546 @@ ++/* ++ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#include "includes.h" ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++#include ++#include ++ ++static void *OPENSSL_zalloc(size_t num) ++{ ++ void *ret = OPENSSL_malloc(num); ++ ++ if (ret != NULL) ++ memset(ret, 0, num); ++ return ret; ++} ++ ++int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ /* If the fields n and e in r are NULL, the corresponding input ++ * parameters MUST be non-NULL for n and e. d may be ++ * left NULL (in case only the public key is used). ++ */ ++ if ((r->n == NULL && n == NULL) ++ || (r->e == NULL && e == NULL)) ++ return 0; ++ ++ if (n != NULL) { ++ BN_free(r->n); ++ r->n = n; ++ } ++ if (e != NULL) { ++ BN_free(r->e); ++ r->e = e; ++ } ++ if (d != NULL) { ++ BN_free(r->d); ++ r->d = d; ++ } ++ ++ return 1; ++} ++ ++int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) ++{ ++ /* If the fields p and q in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->p == NULL && p == NULL) ++ || (r->q == NULL && q == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ BN_free(r->p); ++ r->p = p; ++ } ++ if (q != NULL) { ++ BN_free(r->q); ++ r->q = q; ++ } ++ ++ return 1; ++} ++ ++int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) ++{ ++ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->dmp1 == NULL && dmp1 == NULL) ++ || (r->dmq1 == NULL && dmq1 == NULL) ++ || (r->iqmp == NULL && iqmp == NULL)) ++ return 0; ++ ++ if (dmp1 != NULL) { ++ BN_free(r->dmp1); ++ r->dmp1 = dmp1; ++ } ++ if (dmq1 != NULL) { ++ BN_free(r->dmq1); ++ r->dmq1 = dmq1; ++ } ++ if (iqmp != NULL) { ++ BN_free(r->iqmp); ++ r->iqmp = iqmp; ++ } ++ ++ return 1; ++} ++ ++void RSA_get0_key(const RSA *r, ++ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) ++{ ++ if (n != NULL) ++ *n = r->n; ++ if (e != NULL) ++ *e = r->e; ++ if (d != NULL) ++ *d = r->d; ++} ++ ++void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) ++{ ++ if (p != NULL) ++ *p = r->p; ++ if (q != NULL) ++ *q = r->q; ++} ++ ++void RSA_get0_crt_params(const RSA *r, ++ const BIGNUM **dmp1, const BIGNUM **dmq1, ++ const BIGNUM **iqmp) ++{ ++ if (dmp1 != NULL) ++ *dmp1 = r->dmp1; ++ if (dmq1 != NULL) ++ *dmq1 = r->dmq1; ++ if (iqmp != NULL) ++ *iqmp = r->iqmp; ++} ++ ++void DSA_get0_pqg(const DSA *d, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p != NULL) ++ *p = d->p; ++ if (q != NULL) ++ *q = d->q; ++ if (g != NULL) ++ *g = d->g; ++} ++ ++int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ /* If the fields p, q and g in d are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((d->p == NULL && p == NULL) ++ || (d->q == NULL && q == NULL) ++ || (d->g == NULL && g == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ BN_free(d->p); ++ d->p = p; ++ } ++ if (q != NULL) { ++ BN_free(d->q); ++ d->q = q; ++ } ++ if (g != NULL) { ++ BN_free(d->g); ++ d->g = g; ++ } ++ ++ return 1; ++} ++ ++void DSA_get0_key(const DSA *d, ++ const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key != NULL) ++ *pub_key = d->pub_key; ++ if (priv_key != NULL) ++ *priv_key = d->priv_key; ++} ++ ++int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ /* If the field pub_key in d is NULL, the corresponding input ++ * parameters MUST be non-NULL. The priv_key field may ++ * be left NULL. ++ */ ++ if (d->pub_key == NULL && pub_key == NULL) ++ return 0; ++ ++ if (pub_key != NULL) { ++ BN_free(d->pub_key); ++ d->pub_key = pub_key; ++ } ++ if (priv_key != NULL) { ++ BN_free(d->priv_key); ++ d->priv_key = priv_key; ++ } ++ ++ return 1; ++} ++ ++void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) ++{ ++ if (pr != NULL) ++ *pr = sig->r; ++ if (ps != NULL) ++ *ps = sig->s; ++} ++ ++int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) ++{ ++ if (r == NULL || s == NULL) ++ return 0; ++ BN_clear_free(sig->r); ++ BN_clear_free(sig->s); ++ sig->r = r; ++ sig->s = s; ++ return 1; ++} ++ ++void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) ++{ ++ if (pr != NULL) ++ *pr = sig->r; ++ if (ps != NULL) ++ *ps = sig->s; ++} ++ ++int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) ++{ ++ if (r == NULL || s == NULL) ++ return 0; ++ BN_clear_free(sig->r); ++ BN_clear_free(sig->s); ++ sig->r = r; ++ sig->s = s; ++ return 1; ++} ++ ++void DH_get0_pqg(const DH *dh, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p != NULL) ++ *p = dh->p; ++ if (q != NULL) ++ *q = dh->q; ++ if (g != NULL) ++ *g = dh->g; ++} ++ ++int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ /* If the fields p and g in d are NULL, the corresponding input ++ * parameters MUST be non-NULL. q may remain NULL. ++ */ ++ if ((dh->p == NULL && p == NULL) ++ || (dh->g == NULL && g == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ BN_free(dh->p); ++ dh->p = p; ++ } ++ if (q != NULL) { ++ BN_free(dh->q); ++ dh->q = q; ++ } ++ if (g != NULL) { ++ BN_free(dh->g); ++ dh->g = g; ++ } ++ ++ if (q != NULL) { ++ dh->length = BN_num_bits(q); ++ } ++ ++ return 1; ++} ++ ++void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key != NULL) ++ *pub_key = dh->pub_key; ++ if (priv_key != NULL) ++ *priv_key = dh->priv_key; ++} ++ ++int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ /* If the field pub_key in dh is NULL, the corresponding input ++ * parameters MUST be non-NULL. The priv_key field may ++ * be left NULL. ++ */ ++ if (dh->pub_key == NULL && pub_key == NULL) ++ return 0; ++ ++ if (pub_key != NULL) { ++ BN_free(dh->pub_key); ++ dh->pub_key = pub_key; ++ } ++ if (priv_key != NULL) { ++ BN_free(dh->priv_key); ++ dh->priv_key = priv_key; ++ } ++ ++ return 1; ++} ++ ++int DH_set_length(DH *dh, long length) ++{ ++ dh->length = length; ++ return 1; ++} ++ ++const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) ++{ ++ return ctx->iv; ++} ++ ++unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) ++{ ++ return ctx->iv; ++} ++ ++EVP_MD_CTX *EVP_MD_CTX_new(void) ++{ ++ return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); ++} ++ ++static void OPENSSL_clear_free(void *str, size_t num) ++{ ++ if (str == NULL) ++ return; ++ if (num) ++ OPENSSL_cleanse(str, num); ++ OPENSSL_free(str); ++} ++ ++/* This call frees resources associated with the context */ ++int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) ++{ ++ if (ctx == NULL) ++ return 1; ++ ++ /* ++ * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because ++ * sometimes only copies of the context are ever finalised. ++ */ ++ if (ctx->digest && ctx->digest->cleanup ++ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) ++ ctx->digest->cleanup(ctx); ++ if (ctx->digest && ctx->digest->ctx_size && ctx->md_data ++ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { ++ OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); ++ } ++ EVP_PKEY_CTX_free(ctx->pctx); ++#ifndef OPENSSL_NO_ENGINE ++ ENGINE_finish(ctx->engine); ++#endif ++ OPENSSL_cleanse(ctx, sizeof(*ctx)); ++ ++ return 1; ++} ++ ++void EVP_MD_CTX_free(EVP_MD_CTX *ctx) ++{ ++ EVP_MD_CTX_reset(ctx); ++ OPENSSL_free(ctx); ++} ++ ++RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) ++{ ++ RSA_METHOD *ret; ++ ++ ret = OPENSSL_malloc(sizeof(RSA_METHOD)); ++ ++ if (ret != NULL) { ++ memcpy(ret, meth, sizeof(*meth)); ++ ret->name = OPENSSL_strdup(meth->name); ++ if (ret->name == NULL) { ++ OPENSSL_free(ret); ++ return NULL; ++ } ++ } ++ ++ return ret; ++} ++ ++int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) ++{ ++ char *tmpname; ++ ++ tmpname = OPENSSL_strdup(name); ++ if (tmpname == NULL) { ++ return 0; ++ } ++ ++ OPENSSL_free((char *)meth->name); ++ meth->name = tmpname; ++ ++ return 1; ++} ++ ++int RSA_meth_set_priv_enc(RSA_METHOD *meth, ++ int (*priv_enc) (int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, ++ int padding)) ++{ ++ meth->rsa_priv_enc = priv_enc; ++ return 1; ++} ++ ++int RSA_meth_set_priv_dec(RSA_METHOD *meth, ++ int (*priv_dec) (int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, ++ int padding)) ++{ ++ meth->rsa_priv_dec = priv_dec; ++ return 1; ++} ++ ++int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) ++{ ++ meth->finish = finish; ++ return 1; ++} ++ ++void RSA_meth_free(RSA_METHOD *meth) ++{ ++ if (meth != NULL) { ++ OPENSSL_free((char *)meth->name); ++ OPENSSL_free(meth); ++ } ++} ++ ++int RSA_bits(const RSA *r) ++{ ++ return (BN_num_bits(r->n)); ++} ++ ++int DSA_bits(const DSA *dsa) ++{ ++ return BN_num_bits(dsa->p); ++} ++ ++RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) ++{ ++ if (pkey->type != EVP_PKEY_RSA) { ++ return NULL; ++ } ++ return pkey->pkey.rsa; ++} ++ ++EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) ++{ ++ EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); ++ ++ if (cipher != NULL) { ++ cipher->nid = cipher_type; ++ cipher->block_size = block_size; ++ cipher->key_len = key_len; ++ } ++ return cipher; ++} ++ ++void EVP_CIPHER_meth_free(EVP_CIPHER *cipher) ++{ ++ OPENSSL_free(cipher); ++} ++ ++int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) ++{ ++ cipher->iv_len = iv_len; ++ return 1; ++} ++ ++int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) ++{ ++ cipher->flags = flags; ++ return 1; ++} ++ ++int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, ++ int (*init) (EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, ++ int enc)) ++{ ++ cipher->init = init; ++ return 1; ++} ++ ++int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, ++ int (*do_cipher) (EVP_CIPHER_CTX *ctx, ++ unsigned char *out, ++ const unsigned char *in, ++ size_t inl)) ++{ ++ cipher->do_cipher = do_cipher; ++ return 1; ++} ++ ++int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, ++ int (*cleanup) (EVP_CIPHER_CTX *)) ++{ ++ cipher->cleanup = cleanup; ++ return 1; ++} ++ ++int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, ++ int (*ctrl) (EVP_CIPHER_CTX *, int type, ++ int arg, void *ptr)) ++{ ++ cipher->ctrl = ctrl; ++ return 1; ++} ++ ++int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, ++ int enc) ++{ ++ return cipher->init; ++} ++ ++int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, ++ unsigned char *out, ++ const unsigned char *in, ++ size_t inl) ++{ ++ return cipher->do_cipher; ++} ++ ++int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *) ++{ ++ return cipher->cleanup; ++} ++ ++int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, ++ int type, int arg, ++ void *ptr) ++{ ++ return cipher->ctrl; ++} ++ ++int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) ++{ ++ return ctx->encrypt; ++} ++ ++#endif /* OPENSSL_VERSION_NUMBER */ +diff -up openssh-7.3p1/libcrypto-compat.h.openssl openssh-7.3p1/libcrypto-compat.h +--- openssh-7.3p1/libcrypto-compat.h.openssl 2016-10-27 14:28:16.618815257 +0200 ++++ openssh-7.3p1/libcrypto-compat.h 2016-10-27 14:28:16.618815257 +0200 +@@ -0,0 +1,98 @@ ++#ifndef LIBCRYPTO_COMPAT_H ++#define LIBCRYPTO_COMPAT_H ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++#include ++#include ++#include ++#include ++#include ++ ++int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); ++int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); ++int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); ++void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); ++void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); ++void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); ++ ++void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key); ++int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); ++ ++void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); ++int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); ++ ++void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); ++int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); ++ ++void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); ++int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); ++int DH_set_length(DH *dh, long length); ++ ++const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); ++unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); ++int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); ++EVP_MD_CTX *EVP_MD_CTX_new(void); ++void EVP_MD_CTX_free(EVP_MD_CTX *ctx); ++#define EVP_CIPHER_impl_ctx_size(e) e->ctx_size ++#define EVP_CIPHER_CTX_get_cipher_data(ctx) ctx->cipher_data ++ ++RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); ++int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); ++#define RSA_meth_get_finish(meth) meth->finish ++int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); ++int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); ++int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)); ++void RSA_meth_free(RSA_METHOD *meth); ++ ++int RSA_bits(const RSA *r); ++int DSA_bits(const DSA *d); ++ ++RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); ++ ++EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); ++void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); ++ ++int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); ++int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); ++int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, ++ int (*init) (EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, ++ int enc)); ++int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, ++ int (*do_cipher) (EVP_CIPHER_CTX *ctx, ++ unsigned char *out, ++ const unsigned char *in, ++ size_t inl)); ++int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, ++ int (*cleanup) (EVP_CIPHER_CTX *)); ++int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, ++ int (*ctrl) (EVP_CIPHER_CTX *, int type, ++ int arg, void *ptr)); ++ ++int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, ++ int enc); ++int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, ++ unsigned char *out, ++ const unsigned char *in, ++ size_t inl); ++int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); ++int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, ++ int type, int arg, ++ void *ptr); ++ ++#define EVP_CIPHER_CTX_reset(c) EVP_CIPHER_CTX_init(c) ++ ++int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); ++ ++#endif /* OPENSSL_VERSION_NUMBER */ ++ ++#endif /* LIBCRYPTO_COMPAT_H */ ++ +diff -up openssh-7.3p1/Makefile.in.openssl openssh-7.3p1/Makefile.in +--- openssh-7.3p1/Makefile.in.openssl 2016-10-27 14:28:16.604815290 +0200 ++++ openssh-7.3p1/Makefile.in 2016-10-27 14:28:16.619815255 +0200 +@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ + kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ +- platform-pledge.o platform-tracing.o auditstub.o ++ platform-pledge.o platform-tracing.o auditstub.o libcrypto-compat.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect1.o sshconnect2.o mux.o +diff -up openssh-7.3p1/misc.h.openssl openssh-7.3p1/misc.h +--- openssh-7.3p1/misc.h.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/misc.h 2016-10-27 14:28:16.619815255 +0200 +@@ -139,4 +139,8 @@ char *read_passphrase(const char *, int) + int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); + int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); + ++#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) ++#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) ++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) ++ + #endif /* _MISC_H */ +diff -up openssh-7.3p1/monitor.c.openssl openssh-7.3p1/monitor.c +--- openssh-7.3p1/monitor.c.openssl 2016-10-27 14:28:16.610815276 +0200 ++++ openssh-7.3p1/monitor.c 2016-10-27 14:28:16.619815255 +0200 +@@ -735,9 +735,12 @@ mm_answer_moduli(int sock, Buffer *m) + return (0); + } else { + /* Send first bignum */ ++ const BIGNUM *p, *g; ++ ++ DH_get0_pqg(dh, &p, NULL, &g); + buffer_put_char(m, 1); +- buffer_put_bignum2(m, dh->p); +- buffer_put_bignum2(m, dh->g); ++ buffer_put_bignum2(m, p); ++ buffer_put_bignum2(m, g); + + DH_free(dh); + } +diff -up openssh-7.3p1/openbsd-compat/openssl-compat.c.openssl openssh-7.3p1/openbsd-compat/openssl-compat.c +--- openssh-7.3p1/openbsd-compat/openssl-compat.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/openbsd-compat/openssl-compat.c 2016-10-27 14:28:16.619815255 +0200 +@@ -72,12 +72,19 @@ ssh_compatible_openssl(long headerver, l + void + ssh_OpenSSL_add_all_algorithms(void) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + OpenSSL_add_all_algorithms(); + + /* Enable use of crypto hardware */ + ENGINE_load_builtin_engines(); ++#if OPENSSL_VERSION_NUMBER < 0x10001000L + ENGINE_register_all_complete(); ++#endif + OPENSSL_config(NULL); ++#else ++ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS | ++ OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); ++#endif + } + #endif + +diff -up openssh-7.3p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.3p1/regress/unittests/sshkey/test_file.c +--- openssh-7.3p1/regress/unittests/sshkey/test_file.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/regress/unittests/sshkey/test_file.c 2016-10-27 14:28:16.620815252 +0200 +@@ -46,6 +46,7 @@ sshkey_file_tests(void) + struct sshbuf *buf, *pw; + BIGNUM *a, *b, *c; + char *cp; ++ const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key; + + TEST_START("load passphrase"); + pw = load_text_file("pw"); +@@ -58,7 +59,8 @@ sshkey_file_tests(void) + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("rsa1_1.param.n"); +- ASSERT_BIGNUM_EQ(k1->rsa->n, a); ++ RSA_get0_key(k1->rsa, &n, NULL, NULL); ++ ASSERT_BIGNUM_EQ(n, a); + BN_free(a); + TEST_DONE(); + +@@ -109,9 +111,11 @@ sshkey_file_tests(void) + a = load_bignum("rsa_1.param.n"); + b = load_bignum("rsa_1.param.p"); + c = load_bignum("rsa_1.param.q"); +- ASSERT_BIGNUM_EQ(k1->rsa->n, a); +- ASSERT_BIGNUM_EQ(k1->rsa->p, b); +- ASSERT_BIGNUM_EQ(k1->rsa->q, c); ++ RSA_get0_key(k1->rsa, &n, NULL, NULL); ++ RSA_get0_factors(k1->rsa, &p, &q); ++ ASSERT_BIGNUM_EQ(n, a); ++ ASSERT_BIGNUM_EQ(p, b); ++ ASSERT_BIGNUM_EQ(q, c); + BN_free(a); + BN_free(b); + BN_free(c); +@@ -200,9 +204,11 @@ sshkey_file_tests(void) + a = load_bignum("dsa_1.param.g"); + b = load_bignum("dsa_1.param.priv"); + c = load_bignum("dsa_1.param.pub"); +- ASSERT_BIGNUM_EQ(k1->dsa->g, a); +- ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); +- ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); ++ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); ++ DSA_get0_key(k1->dsa, &pub_key, &priv_key); ++ ASSERT_BIGNUM_EQ(g, a); ++ ASSERT_BIGNUM_EQ(priv_key, b); ++ ASSERT_BIGNUM_EQ(pub_key, c); + BN_free(a); + BN_free(b); + BN_free(c); +diff -up openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c +--- openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c 2016-10-27 14:28:16.620815252 +0200 +@@ -197,9 +197,6 @@ sshkey_tests(void) + k1 = sshkey_new(KEY_RSA1); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); +- ASSERT_PTR_NE(k1->rsa->n, NULL); +- ASSERT_PTR_NE(k1->rsa->e, NULL); +- ASSERT_PTR_EQ(k1->rsa->p, NULL); + sshkey_free(k1); + TEST_DONE(); + +@@ -207,9 +204,6 @@ sshkey_tests(void) + k1 = sshkey_new(KEY_RSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); +- ASSERT_PTR_NE(k1->rsa->n, NULL); +- ASSERT_PTR_NE(k1->rsa->e, NULL); +- ASSERT_PTR_EQ(k1->rsa->p, NULL); + sshkey_free(k1); + TEST_DONE(); + +@@ -217,8 +211,6 @@ sshkey_tests(void) + k1 = sshkey_new(KEY_DSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->dsa, NULL); +- ASSERT_PTR_NE(k1->dsa->g, NULL); +- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); + sshkey_free(k1); + TEST_DONE(); + +@@ -244,9 +236,6 @@ sshkey_tests(void) + k1 = sshkey_new_private(KEY_RSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->rsa, NULL); +- ASSERT_PTR_NE(k1->rsa->n, NULL); +- ASSERT_PTR_NE(k1->rsa->e, NULL); +- ASSERT_PTR_NE(k1->rsa->p, NULL); + ASSERT_INT_EQ(sshkey_add_private(k1), 0); + sshkey_free(k1); + TEST_DONE(); +@@ -255,8 +244,6 @@ sshkey_tests(void) + k1 = sshkey_new_private(KEY_DSA); + ASSERT_PTR_NE(k1, NULL); + ASSERT_PTR_NE(k1->dsa, NULL); +- ASSERT_PTR_NE(k1->dsa->g, NULL); +- ASSERT_PTR_NE(k1->dsa->priv_key, NULL); + ASSERT_INT_EQ(sshkey_add_private(k1), 0); + sshkey_free(k1); + TEST_DONE(); +@@ -295,18 +282,13 @@ sshkey_tests(void) + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); + ASSERT_PTR_NE(kr, NULL); + ASSERT_PTR_NE(kr->rsa, NULL); +- ASSERT_PTR_NE(kr->rsa->n, NULL); +- ASSERT_PTR_NE(kr->rsa->e, NULL); +- ASSERT_PTR_NE(kr->rsa->p, NULL); +- ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); ++ ASSERT_INT_EQ(RSA_bits(kr->rsa), 1024); + TEST_DONE(); + + TEST_START("generate KEY_DSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); + ASSERT_PTR_NE(kd, NULL); + ASSERT_PTR_NE(kd->dsa, NULL); +- ASSERT_PTR_NE(kd->dsa->g, NULL); +- ASSERT_PTR_NE(kd->dsa->priv_key, NULL); + TEST_DONE(); + + #ifdef OPENSSL_HAS_ECC +@@ -333,9 +315,6 @@ sshkey_tests(void) + ASSERT_PTR_NE(kr, k1); + ASSERT_INT_EQ(k1->type, KEY_RSA); + ASSERT_PTR_NE(k1->rsa, NULL); +- ASSERT_PTR_NE(k1->rsa->n, NULL); +- ASSERT_PTR_NE(k1->rsa->e, NULL); +- ASSERT_PTR_EQ(k1->rsa->p, NULL); + TEST_DONE(); + + TEST_START("equal KEY_RSA/demoted KEY_RSA"); +@@ -349,8 +328,6 @@ sshkey_tests(void) + ASSERT_PTR_NE(kd, k1); + ASSERT_INT_EQ(k1->type, KEY_DSA); + ASSERT_PTR_NE(k1->dsa, NULL); +- ASSERT_PTR_NE(k1->dsa->g, NULL); +- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); + TEST_DONE(); + + TEST_START("equal KEY_DSA/demoted KEY_DSA"); +diff -up openssh-7.3p1/rsa.c.openssl openssh-7.3p1/rsa.c +--- openssh-7.3p1/rsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/rsa.c 2016-10-27 14:28:16.620815252 +0200 +@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM * + { + u_char *inbuf = NULL, *outbuf = NULL; + int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; ++ const BIGNUM *e, *n; + +- if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) ++ RSA_get0_key(key, &n, &e, NULL); ++ ++ if (BN_num_bits(e) < 2 || !BN_is_odd(e)) + return SSH_ERR_INVALID_ARGUMENT; + +- olen = BN_num_bytes(key->n); ++ olen = BN_num_bytes(n); + if ((outbuf = malloc(olen)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; +@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM + { + u_char *inbuf = NULL, *outbuf = NULL; + int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; ++ const BIGNUM *n; ++ ++ RSA_get0_key(key, &n, NULL, NULL); + +- olen = BN_num_bytes(key->n); ++ olen = BN_num_bytes(n); + if ((outbuf = malloc(olen)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; +@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM + return r; + } + +-/* calculate p-1 and q-1 */ ++/* calculate d mod p-1 and d mod q-1 */ + int +-rsa_generate_additional_parameters(RSA *rsa) ++rsa_generate_additional_parameters(RSA *rsa, BIGNUM *iqmp) + { + BIGNUM *aux = NULL; + BN_CTX *ctx = NULL; + int r; ++ const BIGNUM *p, *q, *d; ++ BIGNUM *dmp1 = NULL, *dmq1 = NULL; ++ ++ RSA_get0_factors(rsa, &p, &q); ++ RSA_get0_key(rsa, NULL, NULL, &d); + +- if ((ctx = BN_CTX_new()) == NULL) +- return SSH_ERR_ALLOC_FAIL; +- if ((aux = BN_new()) == NULL) { ++ if ((ctx = BN_CTX_new()) == NULL || ++ (aux = BN_new()) == NULL || ++ (dmp1 = BN_new()) == NULL || ++ (dmq1 = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + +- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || +- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || +- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || +- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { ++ if ((BN_sub(aux, q, BN_value_one()) == 0) || ++ (BN_mod(dmq1, d, aux, ctx) == 0) || ++ (BN_sub(aux, p, BN_value_one()) == 0) || ++ (BN_mod(dmp1, d, aux, ctx) == 0) || ++ (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ++ dmp1 = NULL; ++ dmq1 = NULL; + r = 0; + out: + BN_clear_free(aux); ++ BN_clear_free(dmp1); ++ BN_clear_free(dmq1); + BN_CTX_free(ctx); + return r; + } +diff -up openssh-7.3p1/rsa.h.openssl openssh-7.3p1/rsa.h +--- openssh-7.3p1/rsa.h.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/rsa.h 2016-10-27 14:28:16.620815252 +0200 +@@ -21,6 +21,6 @@ + + int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); + int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); +-int rsa_generate_additional_parameters(RSA *); ++int rsa_generate_additional_parameters(RSA *, BIGNUM *); + + #endif /* RSA_H */ +diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c +--- openssh-7.3p1/ssh-agent.c.openssl 2016-10-27 14:28:16.612815271 +0200 ++++ openssh-7.3p1/ssh-agent.c 2016-10-27 14:28:16.621815250 +0200 +@@ -251,12 +251,12 @@ process_request_identities(SocketEntry * + TAILQ_FOREACH(id, &tab->idlist, next) { + if (id->key->type == KEY_RSA1) { + #ifdef WITH_SSH1 ++ const BIGNUM *r_n, *r_e; ++ RSA_get0_key(id->key->rsa, &r_n, &r_e, NULL); + if ((r = sshbuf_put_u32(msg, +- BN_num_bits(id->key->rsa->n))) != 0 || +- (r = sshbuf_put_bignum1(msg, +- id->key->rsa->e)) != 0 || +- (r = sshbuf_put_bignum1(msg, +- id->key->rsa->n)) != 0) ++ BN_num_bits(r_n))) != 0 || ++ (r = sshbuf_put_bignum1(msg, r_e)) != 0 || ++ (r = sshbuf_put_bignum1(msg, r_n)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + #endif +@@ -295,6 +295,7 @@ process_authentication_challenge1(Socket + struct sshbuf *msg; + struct ssh_digest_ctx *md; + struct sshkey *key; ++ BIGNUM *r_n = NULL, *r_e = NULL; + + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); +@@ -303,11 +304,16 @@ process_authentication_challenge1(Socket + if ((challenge = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + +- if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ +- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || +- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || +- (r = sshbuf_get_bignum1(e->request, challenge))) ++ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || ++ (r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ ++ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || ++ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || ++ (r = sshbuf_get_bignum1(e->request, challenge)) || ++ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { ++ BN_free(r_n); ++ BN_free(r_e); + fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ } + + /* Only protocol 1.1 is supported */ + if (sshbuf_len(e->request) == 0) +@@ -443,6 +449,7 @@ process_remove_identity(SocketEntry *e, + u_char *blob; + #ifdef WITH_SSH1 + u_int bits; ++ BIGNUM *r_n = NULL, *r_e = NULL; + #endif /* WITH_SSH1 */ + + switch (version) { +@@ -452,10 +459,15 @@ process_remove_identity(SocketEntry *e, + error("%s: sshkey_new failed", __func__); + return; + } +- if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || +- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || +- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) ++ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || ++ (r = sshbuf_get_u32(e->request, &bits)) != 0 || ++ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || ++ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || ++ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { ++ BN_free(r_n); ++ BN_free(r_e); + fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ } + + if (bits != sshkey_size(key)) + logit("Warning: identity keysize mismatch: " +@@ -558,23 +570,38 @@ agent_decode_rsa1(struct sshbuf *m, stru + { + struct sshkey *k = NULL; + int r = SSH_ERR_INTERNAL_ERROR; ++ BIGNUM *n = NULL, *e = NULL, *d = NULL, ++ *iqmp = NULL, *q = NULL, *p = NULL; + + *kp = NULL; + if ((k = sshkey_new_private(KEY_RSA1)) == NULL) + return SSH_ERR_ALLOC_FAIL; + +- if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ +- (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || +- (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || +- (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || +- (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || ++ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || ++ (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL || ++ (q = BN_new()) == NULL || (p = BN_new()) == NULL || ++ (r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ ++ (r = sshbuf_get_bignum1(m, n)) != 0 || ++ (r = sshbuf_get_bignum1(m, e)) != 0 || ++ (r = sshbuf_get_bignum1(m, d)) != 0 || ++ (r = sshbuf_get_bignum1(m, iqmp)) != 0 || + /* SSH1 and SSL have p and q swapped */ +- (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ +- (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ ++ (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */ ++ (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */ ++ RSA_set0_key(k->rsa, n, e, d) == 0 || ++ RSA_set0_factors(k->rsa, p, q) == 0 || ++ RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) { ++ BN_free(n); ++ BN_free(e); ++ BN_free(d); ++ BN_free(p); ++ BN_free(q); ++ BN_free(iqmp); + goto out; ++ } + + /* Generate additional parameters */ +- if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) ++ if ((r = rsa_generate_additional_parameters(k->rsa, NULL)) != 0) + goto out; + /* enable blinding */ + if (RSA_blinding_on(k->rsa, NULL) != 1) { +diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c +--- openssh-7.3p1/sshconnect1.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/sshconnect1.c 2016-10-27 16:20:55.388110063 +0200 +@@ -70,6 +70,7 @@ try_agent_authentication(void) + u_char response[16]; + size_t i; + BIGNUM *challenge; ++ const BIGNUM *n; + struct ssh_identitylist *idlist = NULL; + + /* Get connection to the agent. */ +@@ -96,8 +97,9 @@ try_agent_authentication(void) + idlist->comments[i]); + + /* Tell the server that we are willing to authenticate using this key. */ ++ RSA_get0_key(idlist->keys[i]->rsa, &n, NULL, NULL); + packet_start(SSH_CMSG_AUTH_RSA); +- packet_put_bignum(idlist->keys[i]->rsa->n); ++ packet_put_bignum((BIGNUM *)n); + packet_send(); + packet_write_wait(); + +@@ -220,6 +222,7 @@ static int + try_rsa_authentication(int idx) + { + BIGNUM *challenge; ++ const BIGNUM *n; + Key *public, *private; + char buf[300], *passphrase = NULL, *comment, *authfile; + int i, perm_ok = 1, type, quit; +@@ -231,8 +234,9 @@ try_rsa_authentication(int idx) + debug("Trying RSA authentication with key '%.100s'", comment); + + /* Tell the server that we are willing to authenticate using this key. */ ++ RSA_get0_key(public->rsa, &n, NULL, NULL); + packet_start(SSH_CMSG_AUTH_RSA); +- packet_put_bignum(public->rsa->n); ++ packet_put_bignum((BIGNUM *)n); + packet_send(); + packet_write_wait(); + +@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char + { + int type; + BIGNUM *challenge; ++ const BIGNUM *n, *e; + + debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); + + /* Tell the server that we are willing to authenticate using this key. */ ++ RSA_get0_key(host_key->rsa, &n, &e, NULL); + packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); + packet_put_cstring(local_user); +- packet_put_int(BN_num_bits(host_key->rsa->n)); +- packet_put_bignum(host_key->rsa->e); +- packet_put_bignum(host_key->rsa->n); ++ packet_put_int(BN_num_bits(n)); ++ packet_put_bignum((BIGNUM *)e); ++ packet_put_bignum((BIGNUM *)n); + packet_send(); + packet_write_wait(); + +@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hos + { + int i; + BIGNUM *key; ++ BIGNUM *server_n = NULL, *server_e = NULL, ++ *host_n = NULL, *host_e = NULL; + Key *host_key, *server_key; + int bits, rbits; + int ssh_cipher_default = SSH_CIPHER_3DES; +@@ -523,10 +531,14 @@ ssh_kex(char *host, struct sockaddr *hos + /* Get the public key. */ + server_key = key_new(KEY_RSA1); + bits = packet_get_int(); +- packet_get_bignum(server_key->rsa->e); +- packet_get_bignum(server_key->rsa->n); ++ if ((server_e = BN_new()) == NULL || ++ (server_n = BN_new()) == NULL) ++ fatal("BN_new() failed"); ++ packet_get_bignum(server_e); ++ packet_get_bignum(server_n); ++ RSA_set0_key(server_key->rsa, server_n, server_e, NULL); + +- rbits = BN_num_bits(server_key->rsa->n); ++ rbits = BN_num_bits(server_n); + if (bits != rbits) { + logit("Warning: Server lies about size of server public key: " + "actual size is %d bits vs. announced %d.", rbits, bits); +@@ -535,10 +547,14 @@ ssh_kex(char *host, struct sockaddr *hos + /* Get the host key. */ + host_key = key_new(KEY_RSA1); + bits = packet_get_int(); +- packet_get_bignum(host_key->rsa->e); +- packet_get_bignum(host_key->rsa->n); ++ if ((host_e = BN_new()) == NULL || ++ (host_n = BN_new()) == NULL) ++ fatal("BN_new() failed"); ++ packet_get_bignum(host_e); ++ packet_get_bignum(host_n); ++ RSA_set0_key(host_key->rsa, host_n, host_e, NULL); + +- rbits = BN_num_bits(host_key->rsa->n); ++ rbits = BN_num_bits(host_n); + if (bits != rbits) { + logit("Warning: Server lies about size of server host key: " + "actual size is %d bits vs. announced %d.", rbits, bits); +@@ -554,14 +570,14 @@ ssh_kex(char *host, struct sockaddr *hos + packet_check_eom(); + + debug("Received server public key (%d bits) and host key (%d bits).", +- BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); ++ BN_num_bits(server_n), BN_num_bits(host_n)); + + if (verify_host_key(host, hostaddr, host_key) == -1) + fatal("Host key verification failed."); + + client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; + +- derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); ++ derive_ssh1_session_id(host_n, server_n, cookie, session_id); + + /* + * Generate an encryption key for the session. The key is a 256 bit +@@ -601,14 +617,14 @@ ssh_kex(char *host, struct sockaddr *hos + * Encrypt the integer using the public key and host key of the + * server (key with smaller modulus first). + */ +- if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { ++ if (BN_cmp(server_n, host_n) < 0) { + /* Public key has smaller modulus. */ +- if (BN_num_bits(host_key->rsa->n) < +- BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { ++ if (BN_num_bits(host_n) < ++ BN_num_bits(server_n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " + "SSH_KEY_BITS_RESERVED %d", +- BN_num_bits(host_key->rsa->n), +- BN_num_bits(server_key->rsa->n), ++ BN_num_bits(host_n), ++ BN_num_bits(server_n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || +@@ -616,12 +632,12 @@ ssh_kex(char *host, struct sockaddr *hos + fatal("%s: rsa_public_encrypt failed", __func__); + } else { + /* Host key has smaller modulus (or they are equal). */ +- if (BN_num_bits(server_key->rsa->n) < +- BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { ++ if (BN_num_bits(server_n) < ++ BN_num_bits(host_n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " + "SSH_KEY_BITS_RESERVED %d", +- BN_num_bits(server_key->rsa->n), +- BN_num_bits(host_key->rsa->n), ++ BN_num_bits(server_n), ++ BN_num_bits(host_n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || +diff -up openssh-7.3p1/sshconnect2.c.openssl openssh-7.3p1/sshconnect2.c +--- openssh-7.3p1/sshconnect2.c.openssl 2016-10-27 14:28:16.606815286 +0200 ++++ openssh-7.3p1/sshconnect2.c 2016-10-27 14:28:16.621815250 +0200 +@@ -299,6 +299,7 @@ ssh_kex2(char *host, struct sockaddr *ho + packet_send(); + packet_write_wait(); + #endif ++ /* XXX free myproposal ?? */ + } + + /* +diff -up openssh-7.3p1/sshconnect.c.openssl openssh-7.3p1/sshconnect.c +--- openssh-7.3p1/sshconnect.c.openssl 2016-10-27 14:28:16.571815369 +0200 ++++ openssh-7.3p1/sshconnect.c 2016-10-27 14:28:16.622815247 +0200 +@@ -1370,6 +1370,7 @@ ssh_login(Sensitive *sensitive, const ch + char *server_user, *local_user; + + local_user = xstrdup(pw->pw_name); ++ free(pw); + server_user = options.user ? options.user : local_user; + + /* Convert the user-supplied hostname into all lowercase. */ +diff -up openssh-7.3p1/ssh.c.openssl openssh-7.3p1/ssh.c +--- openssh-7.3p1/ssh.c.openssl 2016-10-27 14:28:16.606815286 +0200 ++++ openssh-7.3p1/ssh.c 2016-10-27 14:28:16.622815247 +0200 +@@ -535,7 +535,9 @@ main(int ac, char **av) + sanitise_stdfd(); + + __progname = ssh_get_progname(av[0]); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSLeay_add_all_algorithms(); ++#endif + if (access("/etc/system-fips", F_OK) == 0) + if (! FIPSCHECK_verify(NULL, NULL)){ + if (FIPS_mode()) +@@ -1247,6 +1249,7 @@ main(int ac, char **av) + free(cp); + } + free(conn_hash_hex); ++ free(host_arg); + + if (config_test) { + dump_client_config(&options, host); +diff -up openssh-7.3p1/sshd.c.openssl openssh-7.3p1/sshd.c +--- openssh-7.3p1/sshd.c.openssl 2016-10-27 14:28:16.613815269 +0200 ++++ openssh-7.3p1/sshd.c 2016-10-27 14:51:24.038759046 +0200 +@@ -1141,19 +1141,17 @@ send_rexec_state(int fd, struct sshbuf * + #ifdef WITH_SSH1 + if (sensitive_data.server_key != NULL && + sensitive_data.server_key->type == KEY_RSA1) { ++ const BIGNUM *e, *n, *d, *iqmp, *p, *q; ++ RSA_get0_key(sensitive_data.server_key->rsa, &n, &e, &d); ++ RSA_get0_factors(sensitive_data.server_key->rsa, &p, &q); ++ RSA_get0_crt_params(sensitive_data.server_key->rsa, NULL, NULL, &iqmp); + if ((r = sshbuf_put_u32(m, 1)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->e)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->n)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->d)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->iqmp)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->p)) != 0 || +- (r = sshbuf_put_bignum1(m, +- sensitive_data.server_key->rsa->q)) != 0) ++ (r = sshbuf_put_bignum1(m, e)) != 0 || ++ (r = sshbuf_put_bignum1(m, n)) != 0 || ++ (r = sshbuf_put_bignum1(m, d)) != 0 || ++ (r = sshbuf_put_bignum1(m, iqmp)) != 0 || ++ (r = sshbuf_put_bignum1(m, p)) != 0 || ++ (r = sshbuf_put_bignum1(m, q)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + } else + #endif +@@ -1195,17 +1193,25 @@ recv_rexec_state(int fd, Buffer *conf) + + if (buffer_get_int(&m)) { + #ifdef WITH_SSH1 ++ BIGNUM *e = NULL, *n = NULL, *d = NULL, *iqmp = NULL, ++ *p = NULL, *q = NULL; + if (sensitive_data.server_key != NULL) + key_free(sensitive_data.server_key); ++ if ((e = BN_new()) == NULL || (n = BN_new()) == NULL || ++ (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL || ++ (p = BN_new()) == NULL || (q = BN_new()) == NULL) ++ fatal("BN_new() failed"); + sensitive_data.server_key = key_new_private(KEY_RSA1); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); +- buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); ++ buffer_get_bignum(&m, e); ++ buffer_get_bignum(&m, n); ++ buffer_get_bignum(&m, d); ++ buffer_get_bignum(&m, iqmp); ++ buffer_get_bignum(&m, p); ++ buffer_get_bignum(&m, q); ++ RSA_set0_key(sensitive_data.server_key->rsa, n, e, d); ++ RSA_set0_factors(sensitive_data.server_key->rsa, p, q); + if (rsa_generate_additional_parameters( +- sensitive_data.server_key->rsa) != 0) ++ sensitive_data.server_key->rsa, iqmp) != 0) + fatal("%s: rsa_generate_additional_parameters " + "error", __func__); + #endif +@@ -1576,8 +1584,9 @@ check_ip_options(struct ssh *ssh) + #ifdef IP_OPTIONS + int sock_in = ssh_packet_get_connection_in(ssh); + struct sockaddr_storage from; +- socklen_t option_size, i, fromlen = sizeof(from); ++ socklen_t i, fromlen = sizeof(from); + u_char opts[200]; ++ socklen_t option_size = sizeof(opts); + char text[sizeof(opts) * 3 + 1]; + + memset(&from, 0, sizeof(from)); +@@ -1649,7 +1658,7 @@ main(int ac, char **av) + #endif + __progname = ssh_get_progname(av[0]); + +- SSLeay_add_all_algorithms(); ++ OpenSSL_add_all_algorithms(); + if (access("/etc/system-fips", F_OK) == 0) + if (! FIPSCHECK_verify(NULL, NULL)) { + openlog(__progname, LOG_PID, LOG_AUTHPRIV); +@@ -2082,6 +2091,7 @@ main(int ac, char **av) + #ifdef WITH_SSH1 + /* Check certain values for sanity. */ + if (options.protocol & SSH_PROTO_1) { ++ const BIGNUM *n; + if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || + options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { + fprintf(stderr, "Bad server key size.\n"); +@@ -2092,13 +2102,13 @@ main(int ac, char **av) + * is necessary to make double encryption work with rsaref. Oh, I + * hate software patents. I dont know if this can go? Niels + */ ++ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &n, NULL, NULL); + if (options.server_key_bits > +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - +- SSH_KEY_BITS_RESERVED && options.server_key_bits < +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + +- SSH_KEY_BITS_RESERVED) { ++ BN_num_bits(n) - SSH_KEY_BITS_RESERVED && ++ options.server_key_bits < ++ BN_num_bits(n) + SSH_KEY_BITS_RESERVED) { + options.server_key_bits = +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + ++ BN_num_bits(n) + + SSH_KEY_BITS_RESERVED; + debug("Forcing server key to %d bits to make it differ from host key.", + options.server_key_bits); +@@ -2521,18 +2531,18 @@ ssh1_session_key(BIGNUM *session_key_int + { + struct ssh *ssh = active_state; /* XXX */ + int rsafail = 0; ++ const BIGNUM *s_n, *h_n; + +- if (BN_cmp(sensitive_data.server_key->rsa->n, +- sensitive_data.ssh1_host_key->rsa->n) > 0) { ++ RSA_get0_key(sensitive_data.server_key->rsa, &s_n, NULL, NULL); ++ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &h_n, NULL, NULL); ++ if (BN_cmp(s_n, h_n) > 0) { + /* Server key has bigger modulus. */ +- if (BN_num_bits(sensitive_data.server_key->rsa->n) < +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + +- SSH_KEY_BITS_RESERVED) { ++ if (BN_num_bits(s_n) < ++ BN_num_bits(h_n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s port %d: " + "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), +- BN_num_bits(sensitive_data.server_key->rsa->n), +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), ++ BN_num_bits(s_n), BN_num_bits(h_n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_private_decrypt(session_key_int, session_key_int, +@@ -2543,14 +2553,14 @@ ssh1_session_key(BIGNUM *session_key_int + rsafail++; + } else { + /* Host key has bigger modulus (or they are equal). */ +- if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < +- BN_num_bits(sensitive_data.server_key->rsa->n) + ++ if (BN_num_bits(h_n) < ++ BN_num_bits(s_n) + + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s port %d: " + "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), +- BN_num_bits(sensitive_data.server_key->rsa->n), ++ BN_num_bits(h_n), ++ BN_num_bits(s_n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_private_decrypt(session_key_int, session_key_int, +@@ -2578,6 +2588,7 @@ do_ssh1_kex(void) + size_t fake_key_len; + u_char cookie[8]; + u_int cipher_type, auth_mask, protocol_flags; ++ const BIGNUM *n, *e; + + /* + * Generate check bytes that the client must send back in the user +@@ -2600,14 +2611,16 @@ do_ssh1_kex(void) + packet_put_char(cookie[i]); + + /* Store our public server RSA key. */ +- packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); +- packet_put_bignum(sensitive_data.server_key->rsa->e); +- packet_put_bignum(sensitive_data.server_key->rsa->n); ++ RSA_get0_key(sensitive_data.server_key->rsa, &n, &e, NULL); ++ packet_put_int(BN_num_bits(n)); ++ packet_put_bignum((BIGNUM *)e); ++ packet_put_bignum((BIGNUM *)n); + + /* Store our public host RSA key. */ +- packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); +- packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); +- packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); ++ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &n, &e, NULL); ++ packet_put_int(BN_num_bits(n)); ++ packet_put_bignum((BIGNUM *)e); ++ packet_put_bignum((BIGNUM *)n); + + /* Put protocol flags. */ + packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); +@@ -2632,8 +2645,8 @@ do_ssh1_kex(void) + packet_write_wait(); + + debug("Sent %d bit server key and %d bit host key.", +- BN_num_bits(sensitive_data.server_key->rsa->n), +- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); ++ RSA_bits(sensitive_data.server_key->rsa), ++ RSA_bits(sensitive_data.ssh1_host_key->rsa)); + + /* Read clients reply (cipher type and session key). */ + packet_read_expect(SSH_CMSG_SESSION_KEY); +@@ -2697,14 +2710,14 @@ do_ssh1_kex(void) + len, (u_long)sizeof(session_key)); + rsafail++; + } else { ++ const BIGNUM *h_n, *s_n; + explicit_bzero(session_key, sizeof(session_key)); + BN_bn2bin(session_key_int, + session_key + sizeof(session_key) - len); + +- derive_ssh1_session_id( +- sensitive_data.ssh1_host_key->rsa->n, +- sensitive_data.server_key->rsa->n, +- cookie, session_id); ++ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &h_n, NULL, NULL); ++ RSA_get0_key(sensitive_data.server_key->rsa, &s_n, NULL, NULL); ++ derive_ssh1_session_id((BIGNUM *)h_n, (BIGNUM *)s_n, cookie, session_id); + /* + * Xor the first 16 bytes of the session key with the + * session id. +diff -up openssh-7.3p1/ssh-dss.c.openssl openssh-7.3p1/ssh-dss.c +--- openssh-7.3p1/ssh-dss.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-dss.c 2016-10-27 14:28:16.623815245 +0200 +@@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u + size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); + struct sshbuf *b = NULL; + int ret = SSH_ERR_INVALID_ARGUMENT; ++ const BIGNUM *r, *s; + + if (lenp != NULL) + *lenp = 0; +@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u + goto out; + } + +- rlen = BN_num_bytes(sig->r); +- slen = BN_num_bytes(sig->s); ++ DSA_SIG_get0(sig, &r, &s); ++ rlen = BN_num_bytes(r); ++ slen = BN_num_bytes(s); + if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { + ret = SSH_ERR_INTERNAL_ERROR; + goto out; + } + explicit_bzero(sigblob, SIGBLOB_LEN); +- BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); +- BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); ++ BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); ++ BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen); + + if (compat & SSH_BUG_SIGBLOB) { + if (sigp != NULL) { +@@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key, + int ret = SSH_ERR_INTERNAL_ERROR; + struct sshbuf *b = NULL; + char *ktype = NULL; ++ BIGNUM *r = NULL, *s = NULL; + + if (key == NULL || key->dsa == NULL || + sshkey_type_plain(key->type) != KEY_DSA || +@@ -177,16 +180,19 @@ ssh_dss_verify(const struct sshkey *key, + + /* parse signature */ + if ((sig = DSA_SIG_new()) == NULL || +- (sig->r = BN_new()) == NULL || +- (sig->s = BN_new()) == NULL) { ++ (r = BN_new()) == NULL || ++ (s = BN_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || +- (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { ++ if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) || ++ (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL) || ++ (DSA_SIG_set0(sig, r, s) == 0)) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ++ r = NULL; ++ s = NULL; + + /* sha1 the data */ + if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, +@@ -207,8 +213,9 @@ ssh_dss_verify(const struct sshkey *key, + + out: + explicit_bzero(digest, sizeof(digest)); +- if (sig != NULL) +- DSA_SIG_free(sig); ++ BN_free(r); ++ BN_free(s); ++ DSA_SIG_free(sig); + sshbuf_free(b); + free(ktype); + if (sigblob != NULL) { +diff -up openssh-7.3p1/ssh-ecdsa.c.openssl openssh-7.3p1/ssh-ecdsa.c +--- openssh-7.3p1/ssh-ecdsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-ecdsa.c 2016-10-27 14:28:16.623815245 +0200 +@@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, + size_t len, dlen; + struct sshbuf *b = NULL, *bb = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; ++ const BIGNUM *r, *s; + + if (lenp != NULL) + *lenp = 0; +@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || +- (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) ++ ECDSA_SIG_get0(sig, &r, &s); ++ if ((ret = sshbuf_put_bignum2(bb, r)) != 0 || ++ (ret = sshbuf_put_bignum2(bb, s)) != 0) + goto out; + if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || + (ret = sshbuf_put_stringb(b, bb)) != 0) +@@ -119,6 +121,7 @@ ssh_ecdsa_verify(const struct sshkey *ke + int ret = SSH_ERR_INTERNAL_ERROR; + struct sshbuf *b = NULL, *sigbuf = NULL; + char *ktype = NULL; ++ BIGNUM *r = NULL, *s = NULL; + + if (key == NULL || key->ecdsa == NULL || + sshkey_type_plain(key->type) != KEY_ECDSA || +@@ -147,15 +150,23 @@ ssh_ecdsa_verify(const struct sshkey *ke + } + + /* parse signature */ +- if ((sig = ECDSA_SIG_new()) == NULL) { ++ if ((sig = ECDSA_SIG_new()) == NULL || ++ (r = BN_new()) == NULL || ++ (s = BN_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || +- sshbuf_get_bignum2(sigbuf, sig->s) != 0) { ++ if (sshbuf_get_bignum2(sigbuf, r) != 0 || ++ sshbuf_get_bignum2(sigbuf, s) != 0) { + ret = SSH_ERR_INVALID_FORMAT; + goto out; + } ++ if (ECDSA_SIG_set0(sig, r, s) == 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ r = NULL; ++ s = NULL; + if (sshbuf_len(sigbuf) != 0) { + ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; + goto out; +@@ -180,8 +191,9 @@ ssh_ecdsa_verify(const struct sshkey *ke + explicit_bzero(digest, sizeof(digest)); + sshbuf_free(sigbuf); + sshbuf_free(b); +- if (sig != NULL) +- ECDSA_SIG_free(sig); ++ BN_free(r); ++ BN_free(s); ++ ECDSA_SIG_free(sig); + free(ktype); + return ret; + } +diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c +--- openssh-7.3p1/sshkey.c.openssl 2016-10-27 14:28:16.607815283 +0200 ++++ openssh-7.3p1/sshkey.c 2016-10-27 14:28:16.624815243 +0200 +@@ -276,10 +276,10 @@ sshkey_size(const struct sshkey *k) + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT: +- return BN_num_bits(k->rsa->n); ++ return RSA_bits(k->rsa); + case KEY_DSA: + case KEY_DSA_CERT: +- return BN_num_bits(k->dsa->p); ++ return DSA_bits(k->dsa); + case KEY_ECDSA: + case KEY_ECDSA_CERT: + return sshkey_curve_nid_to_bits(k->ecdsa_nid); +@@ -312,11 +312,17 @@ sshkey_is_private(const struct sshkey *k + #ifdef WITH_OPENSSL + case KEY_RSA_CERT: + case KEY_RSA1: +- case KEY_RSA: +- return k->rsa->d != NULL; ++ case KEY_RSA: { ++ const BIGNUM *d; ++ RSA_get0_key(k->rsa, NULL, NULL, &d); ++ return d != NULL; ++ } + case KEY_DSA_CERT: +- case KEY_DSA: +- return k->dsa->priv_key != NULL; ++ case KEY_DSA: { ++ const BIGNUM *priv_key; ++ DSA_get0_key(k->dsa, NULL, &priv_key); ++ return priv_key != NULL; ++ } + #ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: +@@ -506,11 +512,7 @@ sshkey_new(int type) + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT: +- if ((rsa = RSA_new()) == NULL || +- (rsa->n = BN_new()) == NULL || +- (rsa->e = BN_new()) == NULL) { +- if (rsa != NULL) +- RSA_free(rsa); ++ if ((rsa = RSA_new()) == NULL) { + free(k); + return NULL; + } +@@ -518,13 +520,7 @@ sshkey_new(int type) + break; + case KEY_DSA: + case KEY_DSA_CERT: +- if ((dsa = DSA_new()) == NULL || +- (dsa->p = BN_new()) == NULL || +- (dsa->q = BN_new()) == NULL || +- (dsa->g = BN_new()) == NULL || +- (dsa->pub_key = BN_new()) == NULL) { +- if (dsa != NULL) +- DSA_free(dsa); ++ if ((dsa = DSA_new()) == NULL) { + free(k); + return NULL; + } +@@ -565,21 +561,10 @@ sshkey_add_private(struct sshkey *k) + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT: +-#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) +- if (bn_maybe_alloc_failed(k->rsa->d) || +- bn_maybe_alloc_failed(k->rsa->iqmp) || +- bn_maybe_alloc_failed(k->rsa->q) || +- bn_maybe_alloc_failed(k->rsa->p) || +- bn_maybe_alloc_failed(k->rsa->dmq1) || +- bn_maybe_alloc_failed(k->rsa->dmp1)) +- return SSH_ERR_ALLOC_FAIL; + break; + case KEY_DSA: + case KEY_DSA_CERT: +- if (bn_maybe_alloc_failed(k->dsa->priv_key)) +- return SSH_ERR_ALLOC_FAIL; + break; +-#undef bn_maybe_alloc_failed + case KEY_ECDSA: + case KEY_ECDSA_CERT: + /* Cannot do anything until we know the group */ +@@ -698,17 +683,31 @@ sshkey_equal_public(const struct sshkey + #ifdef WITH_OPENSSL + case KEY_RSA1: + case KEY_RSA_CERT: +- case KEY_RSA: +- return a->rsa != NULL && b->rsa != NULL && +- BN_cmp(a->rsa->e, b->rsa->e) == 0 && +- BN_cmp(a->rsa->n, b->rsa->n) == 0; ++ case KEY_RSA: { ++ const BIGNUM *a_e, *a_n, *b_e, *b_n; ++ ++ if (a->rsa == NULL || b->rsa == NULL) ++ return 0; ++ RSA_get0_key(a->rsa, &a_n, &a_e, NULL); ++ RSA_get0_key(b->rsa, &b_n, &b_e, NULL); ++ return BN_cmp(a_e, b_e) == 0 && BN_cmp(a_n, b_n) == 0; ++ } + case KEY_DSA_CERT: +- case KEY_DSA: +- return a->dsa != NULL && b->dsa != NULL && +- BN_cmp(a->dsa->p, b->dsa->p) == 0 && +- BN_cmp(a->dsa->q, b->dsa->q) == 0 && +- BN_cmp(a->dsa->g, b->dsa->g) == 0 && +- BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; ++ case KEY_DSA: { ++ const BIGNUM *a_p, *a_q, *a_g, *a_pub_key; ++ const BIGNUM *b_p, *b_q, *b_g, *b_pub_key; ++ ++ if (a->dsa == NULL || b->dsa == NULL) ++ return 0; ++ DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g); ++ DSA_get0_key(a->dsa, &a_pub_key, NULL); ++ DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g); ++ DSA_get0_key(b->dsa, &b_pub_key, NULL); ++ return BN_cmp(a_p, b_p) == 0 && ++ BN_cmp(a_q, b_q) == 0 && ++ BN_cmp(a_g, b_g) == 0 && ++ BN_cmp(a_pub_key, b_pub_key) == 0; ++ } + # ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: +@@ -783,15 +782,21 @@ to_blob_buf(const struct sshkey *key, st + return ret; + break; + #ifdef WITH_OPENSSL +- case KEY_DSA: +- if (key->dsa == NULL) +- return SSH_ERR_INVALID_ARGUMENT; +- if ((ret = sshbuf_put_cstring(b, typename)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) +- return ret; ++ case KEY_DSA: { ++ const BIGNUM *p, *q, *g, *pub_key; ++ ++ if (key->dsa == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ ++ DSA_get0_pqg(key->dsa, &p, &q, &g); ++ DSA_get0_key(key->dsa, &pub_key, NULL); ++ if ((ret = sshbuf_put_cstring(b, typename)) != 0 || ++ (ret = sshbuf_put_bignum2(b, p)) != 0 || ++ (ret = sshbuf_put_bignum2(b, q)) != 0 || ++ (ret = sshbuf_put_bignum2(b, g)) != 0 || ++ (ret = sshbuf_put_bignum2(b, pub_key)) != 0) ++ return ret; ++ } + break; + # ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: +@@ -804,13 +809,18 @@ to_blob_buf(const struct sshkey *key, st + return ret; + break; + # endif +- case KEY_RSA: +- if (key->rsa == NULL) +- return SSH_ERR_INVALID_ARGUMENT; +- if ((ret = sshbuf_put_cstring(b, typename)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || +- (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) +- return ret; ++ case KEY_RSA: { ++ const BIGNUM *e, *n; ++ ++ if (key->rsa == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ ++ RSA_get0_key(key->rsa, &n, &e, NULL); ++ if ((ret = sshbuf_put_cstring(b, typename)) != 0 || ++ (ret = sshbuf_put_bignum2(b, e)) != 0 || ++ (ret = sshbuf_put_bignum2(b, n)) != 0) ++ return ret; ++ } + break; + #endif /* WITH_OPENSSL */ + case KEY_ED25519: +@@ -916,8 +926,13 @@ sshkey_fingerprint_raw(const struct sshk + + if (k->type == KEY_RSA1) { + #ifdef WITH_OPENSSL +- int nlen = BN_num_bytes(k->rsa->n); +- int elen = BN_num_bytes(k->rsa->e); ++ const BIGNUM *n, *e; ++ int nlen, elen; ++ ++ RSA_get0_key(k->rsa, &n, &e, NULL); ++ ++ nlen = BN_num_bytes(n); ++ elen = BN_num_bytes(e); + + blob_len = nlen + elen; + if (nlen >= INT_MAX - elen || +@@ -925,8 +940,8 @@ sshkey_fingerprint_raw(const struct sshk + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- BN_bn2bin(k->rsa->n, blob); +- BN_bn2bin(k->rsa->e, blob + nlen); ++ BN_bn2bin(n, blob); ++ BN_bn2bin(e, blob + nlen); + #endif /* WITH_OPENSSL */ + } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) + goto out; +@@ -1289,6 +1304,7 @@ sshkey_read(struct sshkey *ret, char **c + struct sshbuf *blob; + #ifdef WITH_SSH1 + u_long bits; ++ BIGNUM *e = NULL, *n = NULL; + #endif /* WITH_SSH1 */ + + cp = *cpp; +@@ -1302,12 +1318,21 @@ sshkey_read(struct sshkey *ret, char **c + bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) + return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ + /* Get public exponent, public modulus. */ +- if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) ++ if ((e = BN_new()) == NULL || (n = BN_new()) == NULL) { ++ BN_free(e); ++ return SSH_ERR_ALLOC_FAIL; ++ } ++ if ((r = read_decimal_bignum(&ep, e)) < 0) + return r; +- if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) ++ if ((r = read_decimal_bignum(&ep, n)) < 0) + return r; ++ if (RSA_set0_key(ret->rsa, n, e, NULL) == 0) { ++ BN_free(e); ++ BN_free(n); ++ return -1; ++ } + /* validate the claimed number of bits */ +- if (BN_num_bits(ret->rsa->n) != (int)bits) ++ if (BN_num_bits(n) != (int)bits) + return SSH_ERR_KEY_BITS_MISMATCH; + *cpp = ep; + retval = 0; +@@ -1472,19 +1497,20 @@ sshkey_format_rsa1(const struct sshkey * + #ifdef WITH_SSH1 + u_int bits = 0; + char *dec_e = NULL, *dec_n = NULL; ++ const BIGNUM *e, *n; + +- if (key->rsa == NULL || key->rsa->e == NULL || +- key->rsa->n == NULL) { ++ RSA_get0_key(key->rsa, &n, &e, NULL); ++ if (key->rsa == NULL || e == NULL || n == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +- if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || +- (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { ++ if ((dec_e = BN_bn2dec(e)) == NULL || ++ (dec_n = BN_bn2dec(n)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* size of modulus 'n' */ +- if ((bits = BN_num_bits(key->rsa->n)) <= 0) { ++ if ((bits = BN_num_bits(n)) <= 0) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +@@ -1818,15 +1844,32 @@ sshkey_from_private(const struct sshkey + switch (k->type) { + #ifdef WITH_OPENSSL + case KEY_DSA: +- case KEY_DSA_CERT: +- if ((n = sshkey_new(k->type)) == NULL) +- return SSH_ERR_ALLOC_FAIL; +- if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || +- (BN_copy(n->dsa->q, k->dsa->q) == NULL) || +- (BN_copy(n->dsa->g, k->dsa->g) == NULL) || +- (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { +- sshkey_free(n); +- return SSH_ERR_ALLOC_FAIL; ++ case KEY_DSA_CERT: { ++ const BIGNUM *k_p, *k_q, *k_g, *k_pub_key; ++ BIGNUM *n_p = NULL, *n_q = NULL, *n_g = NULL, *n_pub_key = NULL; ++ ++ if ((n = sshkey_new(k->type)) == NULL) ++ return SSH_ERR_ALLOC_FAIL; ++ ++ DSA_get0_pqg(k->dsa, &k_p, &k_q, &k_g); ++ DSA_get0_key(k->dsa, &k_pub_key, NULL); ++ ++ if (((n_p = BN_dup(k_p)) == NULL) || ++ ((n_q = BN_dup(k_q)) == NULL) || ++ ((n_g = BN_dup(k_g)) == NULL) || ++ (DSA_set0_pqg(n->dsa, n_p, n_q, n_g) == 0)) { ++ sshkey_free(n); ++ BN_free(n_p); ++ BN_free(n_q); ++ BN_free(n_g); ++ return SSH_ERR_ALLOC_FAIL; ++ } ++ if (((n_pub_key = BN_dup(k_pub_key)) == NULL) || ++ (DSA_set0_key(n->dsa, n_pub_key, NULL) == 0)) { ++ sshkey_free(n); ++ BN_free(n_pub_key); ++ return SSH_ERR_ALLOC_FAIL; ++ } + } + break; + # ifdef OPENSSL_HAS_ECC +@@ -1849,13 +1892,22 @@ sshkey_from_private(const struct sshkey + # endif /* OPENSSL_HAS_ECC */ + case KEY_RSA: + case KEY_RSA1: +- case KEY_RSA_CERT: +- if ((n = sshkey_new(k->type)) == NULL) +- return SSH_ERR_ALLOC_FAIL; +- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || +- (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { +- sshkey_free(n); +- return SSH_ERR_ALLOC_FAIL; ++ case KEY_RSA_CERT: { ++ const BIGNUM *k_n, *k_e; ++ BIGNUM *n_n = NULL, *n_e = NULL; ++ ++ if ((n = sshkey_new(k->type)) == NULL) ++ return SSH_ERR_ALLOC_FAIL; ++ ++ RSA_get0_key(k->rsa, &k_n, &k_e, NULL); ++ if (((n_n = BN_dup(k_n)) == NULL) || ++ ((n_e = BN_dup(k_e)) == NULL) || ++ RSA_set0_key(n->rsa, n_n, n_e, NULL) == 0) { ++ sshkey_free(n); ++ BN_free(n_n); ++ BN_free(n_e); ++ return SSH_ERR_ALLOC_FAIL; ++ } + } + break; + #endif /* WITH_OPENSSL */ +@@ -2053,10 +2105,20 @@ sshkey_from_blob_internal(struct sshbuf + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || +- sshbuf_get_bignum2(b, key->rsa->n) != 0) { +- ret = SSH_ERR_INVALID_FORMAT; +- goto out; ++ { ++ BIGNUM *e, *n; ++ ++ e = BN_new(); ++ n = BN_new(); ++ if (e == NULL || n == NULL || ++ sshbuf_get_bignum2(b, e) != 0 || ++ sshbuf_get_bignum2(b, n) != 0 || ++ RSA_set0_key(key->rsa, n, e, NULL) == 0) { ++ BN_free(e); ++ BN_free(n); ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + } + #ifdef DEBUG_PK + RSA_print_fp(stderr, key->rsa, 8); +@@ -2074,12 +2136,34 @@ sshkey_from_blob_internal(struct sshbuf + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || +- sshbuf_get_bignum2(b, key->dsa->q) != 0 || +- sshbuf_get_bignum2(b, key->dsa->g) != 0 || +- sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { +- ret = SSH_ERR_INVALID_FORMAT; +- goto out; ++ { ++ BIGNUM *p, *q, *g, *pub_key; ++ ++ p = BN_new(); ++ q = BN_new(); ++ g = BN_new(); ++ pub_key = BN_new(); ++ ++ if (p == NULL || q == NULL || g == NULL || ++ pub_key == NULL || ++ sshbuf_get_bignum2(b, p) != 0 || ++ sshbuf_get_bignum2(b, q) != 0 || ++ sshbuf_get_bignum2(b, g) != 0 || ++ sshbuf_get_bignum2(b, pub_key) != 0 || ++ DSA_set0_pqg(key->dsa, p, q, g) == 0) { ++ BN_free(p); ++ BN_free(q); ++ BN_free(g); ++ BN_free(pub_key); ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) { ++ BN_free(pub_key); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + } + #ifdef DEBUG_PK + DSA_print_fp(stderr, key->dsa, 8); +@@ -2319,26 +2403,53 @@ sshkey_demote(const struct sshkey *k, st + goto fail; + /* FALLTHROUGH */ + case KEY_RSA1: +- case KEY_RSA: +- if ((pk->rsa = RSA_new()) == NULL || +- (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || +- (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { +- ret = SSH_ERR_ALLOC_FAIL; +- goto fail; ++ case KEY_RSA: { ++ const BIGNUM *k_e, *k_n; ++ BIGNUM *pk_e = NULL, *pk_n = NULL; ++ ++ RSA_get0_key(k->rsa, &k_n, &k_e, NULL); ++ if ((pk->rsa = RSA_new()) == NULL || ++ (pk_e = BN_dup(k_e)) == NULL || ++ (pk_n = BN_dup(k_n)) == NULL || ++ RSA_set0_key(pk->rsa, pk_n, pk_e, NULL) == 0) { ++ BN_free(pk_e); ++ BN_free(pk_n); ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto fail; + } ++ } + break; + case KEY_DSA_CERT: + if ((ret = sshkey_cert_copy(k, pk)) != 0) + goto fail; + /* FALLTHROUGH */ +- case KEY_DSA: +- if ((pk->dsa = DSA_new()) == NULL || +- (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || +- (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || +- (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || +- (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { +- ret = SSH_ERR_ALLOC_FAIL; +- goto fail; ++ case KEY_DSA: { ++ const BIGNUM *k_p, *k_q, *k_g, *k_pub_key; ++ BIGNUM *pk_p = NULL, *pk_q = NULL, *pk_g = NULL; ++ BIGNUM *pk_pub_key = NULL; ++ ++ DSA_get0_pqg(k->dsa, &k_p, &k_q, &k_g); ++ DSA_get0_key(k->dsa, &k_pub_key, NULL); ++ ++ if ((pk->dsa = DSA_new()) == NULL || ++ (pk_p = BN_dup(k_p)) == NULL || ++ (pk_q = BN_dup(k_q)) == NULL || ++ (pk_g = BN_dup(k_g)) == NULL || ++ (pk_pub_key = BN_dup(k_pub_key)) == NULL || ++ DSA_set0_pqg(pk->dsa, pk_p, pk_q, pk_g) == 0) { ++ BN_free(pk_p); ++ BN_free(pk_q); ++ BN_free(pk_g); ++ BN_free(pk_pub_key); ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto fail; ++ } ++ ++ if (DSA_set0_key(pk->dsa, pk_pub_key, NULL) == 0) { ++ BN_free(pk_pub_key); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto fail; ++ } + } + break; + case KEY_ECDSA_CERT: +@@ -2459,12 +2570,17 @@ sshkey_certify(struct sshkey *k, struct + /* XXX this substantially duplicates to_blob(); refactor */ + switch (k->type) { + #ifdef WITH_OPENSSL +- case KEY_DSA_CERT: +- if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || +- (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || +- (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || +- (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) +- goto out; ++ case KEY_DSA_CERT: { ++ const BIGNUM *p, *q, *g, *pub_key; ++ ++ DSA_get0_pqg(k->dsa, &p, &q, &g); ++ DSA_get0_key(k->dsa, &pub_key, NULL); ++ if ((ret = sshbuf_put_bignum2(cert, p)) != 0 || ++ (ret = sshbuf_put_bignum2(cert, q)) != 0 || ++ (ret = sshbuf_put_bignum2(cert, g)) != 0 || ++ (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) ++ goto out; ++ } + break; + # ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: +@@ -2476,10 +2592,15 @@ sshkey_certify(struct sshkey *k, struct + goto out; + break; + # endif /* OPENSSL_HAS_ECC */ +- case KEY_RSA_CERT: +- if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || +- (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) +- goto out; ++ case KEY_RSA_CERT: { ++ const BIGNUM *e, *n; ++ ++ RSA_get0_key(k->rsa, &n, &e, NULL); ++ if (e == NULL || n == NULL || ++ (ret = sshbuf_put_bignum2(cert, e)) != 0 || ++ (ret = sshbuf_put_bignum2(cert, n)) != 0) ++ goto out; ++ } + break; + #endif /* WITH_OPENSSL */ + case KEY_ED25519_CERT: +@@ -2636,43 +2757,65 @@ sshkey_private_serialize(const struct ss + goto out; + switch (key->type) { + #ifdef WITH_OPENSSL +- case KEY_RSA: +- if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) +- goto out; ++ case KEY_RSA: { ++ const BIGNUM *n, *e, *d, *iqmp, *p, *q; ++ RSA_get0_key(key->rsa, &n, &e, &d); ++ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); ++ RSA_get0_factors(key->rsa, &p, &q); ++ if ((r = sshbuf_put_bignum2(b, n)) != 0 || ++ (r = sshbuf_put_bignum2(b, e)) != 0 || ++ (r = sshbuf_put_bignum2(b, d)) != 0 || ++ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || ++ (r = sshbuf_put_bignum2(b, p)) != 0 || ++ (r = sshbuf_put_bignum2(b, q)) != 0) ++ goto out; ++ } + break; + case KEY_RSA_CERT: + if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || +- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) +- goto out; ++ { ++ const BIGNUM *d, *iqmp, *p, *q; ++ ++ RSA_get0_key(key->rsa, NULL, NULL, &d); ++ RSA_get0_factors(key->rsa, &p, &q); ++ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); ++ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || ++ (r = sshbuf_put_bignum2(b, d)) != 0 || ++ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || ++ (r = sshbuf_put_bignum2(b, p)) != 0 || ++ (r = sshbuf_put_bignum2(b, q)) != 0) ++ goto out; ++ } + break; +- case KEY_DSA: +- if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || +- (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || +- (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || +- (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || +- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) +- goto out; ++ case KEY_DSA: { ++ const BIGNUM *p, *q, *g, *pub_key, *priv_key; ++ ++ DSA_get0_pqg(key->dsa, &p, &q, &g); ++ DSA_get0_key(key->dsa, &pub_key, &priv_key); ++ if ((r = sshbuf_put_bignum2(b, p)) != 0 || ++ (r = sshbuf_put_bignum2(b, q)) != 0 || ++ (r = sshbuf_put_bignum2(b, g)) != 0 || ++ (r = sshbuf_put_bignum2(b, pub_key)) != 0 || ++ (r = sshbuf_put_bignum2(b, priv_key)) != 0) ++ goto out; ++ } + break; + case KEY_DSA_CERT: + if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || +- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) +- goto out; ++ { ++ const BIGNUM *priv_key; ++ ++ DSA_get0_key(key->dsa, NULL, &priv_key); ++ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || ++ (r = sshbuf_put_bignum2(b, priv_key)) != 0) ++ goto out; ++ } + break; + # ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: +@@ -2748,18 +2891,51 @@ sshkey_private_deserialize(struct sshbuf + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) +- goto out; ++ { ++ BIGNUM *p, *q, *g, *pub_key, *priv_key; ++ ++ p = BN_new(); ++ q = BN_new(); ++ g = BN_new(); ++ pub_key = BN_new(); ++ priv_key = BN_new(); ++ if (p == NULL || q == NULL || g == NULL || ++ pub_key == NULL || priv_key == NULL || ++ (r = sshbuf_get_bignum2(buf, p)) != 0 || ++ (r = sshbuf_get_bignum2(buf, q)) != 0 || ++ (r = sshbuf_get_bignum2(buf, g)) != 0 || ++ (r = sshbuf_get_bignum2(buf, pub_key)) != 0 || ++ (r = sshbuf_get_bignum2(buf, priv_key)) != 0 || ++ (r = ((DSA_set0_pqg(k->dsa, p, q, g) == 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { ++ BN_free(p); ++ BN_free(q); ++ BN_free(g); ++ BN_free(pub_key); ++ BN_free(priv_key); ++ goto out; ++ } ++ if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ BN_free(pub_key); ++ BN_free(priv_key); ++ goto out; ++ } ++ } + break; +- case KEY_DSA_CERT: +- if ((r = sshkey_froms(buf, &k)) != 0 || +- (r = sshkey_add_private(k)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) +- goto out; ++ case KEY_DSA_CERT: { ++ BIGNUM *priv_key = BN_new(); ++ ++ if (priv_key == NULL || ++ (r = sshkey_froms(buf, &k)) != 0 || ++ (r = sshkey_add_private(k)) != 0 || ++ (r = sshbuf_get_bignum2(buf, priv_key)) != 0 || ++ (r = ((DSA_set0_key(k->dsa, NULL, priv_key) == 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { ++ BN_free(priv_key); ++ goto out; ++ } ++ } + break; + # ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: +@@ -2818,24 +2994,73 @@ sshkey_private_deserialize(struct sshbuf + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || +- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- goto out; ++ { ++ BIGNUM *n, *e, *d, *iqmp, *p, *q; ++ ++ n = BN_new(); ++ e = BN_new(); ++ d = BN_new(); ++ iqmp = BN_new(); ++ p = BN_new(); ++ q = BN_new(); ++ ++ if (n == NULL || e == NULL || d == NULL || ++ iqmp == NULL || p == NULL || q == NULL || ++ (r = sshbuf_get_bignum2(buf, n)) != 0 || ++ (r = sshbuf_get_bignum2(buf, e)) != 0 || ++ (r = sshbuf_get_bignum2(buf, d)) != 0 || ++ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || ++ (r = sshbuf_get_bignum2(buf, p)) != 0 || ++ (r = sshbuf_get_bignum2(buf, q)) != 0 || ++ (r = ((RSA_set0_key(k->rsa, n, e, d) == 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { ++ BN_free(n); ++ BN_free(e); ++ BN_free(d); ++ BN_free(iqmp); ++ BN_free(p); ++ BN_free(q); ++ goto out; ++ } ++ if (RSA_set0_factors(k->rsa, p, q) == 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ BN_free(iqmp); ++ BN_free(p); ++ BN_free(q); ++ goto out; ++ } ++ if ((r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) { ++ BN_free(iqmp); ++ goto out; ++ } ++ } + break; +- case KEY_RSA_CERT: +- if ((r = sshkey_froms(buf, &k)) != 0 || +- (r = sshkey_add_private(k)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || +- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || +- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- goto out; ++ case KEY_RSA_CERT: { ++ BIGNUM *n, *e, *d, *iqmp, *p, *q; ++ ++ /* XXX leave N, E as zero */ ++ n = BN_new(); ++ e = BN_new(); ++ d = BN_new(); ++ iqmp = BN_new(); ++ p = BN_new(); ++ q = BN_new(); ++ ++ if (n == NULL || e == NULL || d == NULL || ++ iqmp == NULL || p == NULL || q == NULL || ++ (r = sshkey_froms(buf, &k)) != 0 || ++ (r = sshkey_add_private(k)) != 0 || ++ (r = sshbuf_get_bignum2(buf, d)) != 0 || ++ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || ++ (r = sshbuf_get_bignum2(buf, p)) != 0 || ++ (r = sshbuf_get_bignum2(buf, q)) != 0 || ++ (r = ((RSA_set0_key(k->rsa, n, e, d) == 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || ++ (r = ((RSA_set0_factors(k->rsa, p, q) == 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || ++ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) ++ goto out; ++ } + break; + #endif /* WITH_OPENSSL */ + case KEY_ED25519: +@@ -3465,6 +3690,7 @@ sshkey_private_rsa1_to_blob(struct sshke + struct sshcipher_ctx ciphercontext; + const struct sshcipher *cipher; + u_char *cp; ++ const BIGNUM *n, *e, *d, *q, *p, *iqmp; + + /* + * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting +@@ -3491,10 +3717,13 @@ sshkey_private_rsa1_to_blob(struct sshke + * format would just give known plaintext). + * Note: q and p are stored in reverse order to SSL. + */ +- if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || +- (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || +- (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || +- (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) ++ RSA_get0_key(key->rsa, &n, &e, &d); ++ RSA_get0_factors(key->rsa, &p, &q); ++ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); ++ if ((r = sshbuf_put_bignum1(buffer, d)) != 0 || ++ (r = sshbuf_put_bignum1(buffer, iqmp)) != 0 || ++ (r = sshbuf_put_bignum1(buffer, q)) != 0 || ++ (r = sshbuf_put_bignum1(buffer, p)) != 0) + goto out; + + /* Pad the part to be encrypted to a size that is a multiple of 8. */ +@@ -3519,9 +3748,9 @@ sshkey_private_rsa1_to_blob(struct sshke + goto out; + + /* Store public key. This will be in plain text. */ +- if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || +- (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || +- (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || ++ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(n))) != 0 || ++ (r = sshbuf_put_bignum1(encrypted, n)) != 0 || ++ (r = sshbuf_put_bignum1(encrypted, e)) != 0 || + (r = sshbuf_put_cstring(encrypted, comment)) != 0) + goto out; + +@@ -3650,6 +3879,7 @@ sshkey_parse_public_rsa1_fileblob(struct + int r; + struct sshkey *pub = NULL; + struct sshbuf *copy = NULL; ++ BIGNUM *n = NULL, *e = NULL; + + if (keyp != NULL) + *keyp = NULL; +@@ -3679,10 +3909,16 @@ sshkey_parse_public_rsa1_fileblob(struct + goto out; + + /* Read the public key from the buffer. */ +- if ((pub = sshkey_new(KEY_RSA1)) == NULL || +- (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || +- (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) ++ if ((n = BN_new()) == NULL || ++ (e = BN_new()) == NULL || ++ (pub = sshkey_new(KEY_RSA1)) == NULL || ++ (r = sshbuf_get_bignum1(copy, n)) != 0 || ++ (r = sshbuf_get_bignum1(copy, e)) != 0 || ++ RSA_set0_key(pub->rsa, n, e, NULL) == 0) { ++ BN_free(n); ++ BN_free(e); + goto out; ++ } + + /* Finally, the comment */ + if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) +@@ -3714,6 +3950,8 @@ sshkey_parse_private_rsa1(struct sshbuf + struct sshcipher_ctx ciphercontext; + const struct sshcipher *cipher; + struct sshkey *prv = NULL; ++ BIGNUM *n = NULL, *e = NULL, *d = NULL, *q = NULL, *p = NULL, ++ *iqmp = NULL; + + if (keyp != NULL) + *keyp = NULL; +@@ -3749,11 +3987,17 @@ sshkey_parse_private_rsa1(struct sshbuf + goto out; + + /* Read the public key and comment from the buffer. */ +- if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ +- (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || +- (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || +- (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) ++ if ((n = BN_new()) == NULL || ++ (e = BN_new()) == NULL || ++ (r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ ++ (r = sshbuf_get_bignum1(copy, n)) != 0 || ++ (r = sshbuf_get_bignum1(copy, e)) != 0 || ++ (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0 || ++ RSA_set0_key(prv->rsa, n, e, NULL) == 0) { ++ BN_free(n); ++ BN_free(e); + goto out; ++ } + + /* Check that it is a supported cipher. */ + cipher = cipher_by_number(cipher_type); +@@ -3786,14 +4030,25 @@ sshkey_parse_private_rsa1(struct sshbuf + } + + /* Read the rest of the private key. */ +- if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || +- (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || +- (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || +- (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) ++ if ((d = BN_new()) == NULL || ++ (p = BN_new()) == NULL || ++ (q = BN_new()) == NULL || ++ (iqmp = BN_new()) == NULL || ++ (r = sshbuf_get_bignum1(decrypted, d)) != 0 || ++ (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 || ++ (r = sshbuf_get_bignum1(decrypted, q)) != 0 || ++ (r = sshbuf_get_bignum1(decrypted, p)) != 0 || ++ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0) || ++ (RSA_set0_factors(prv->rsa, p, q) == 0)) { ++ BN_free(d); ++ BN_free(p); ++ BN_free(q); ++ BN_free(iqmp); + goto out; ++ } + + /* calculate p-1 and q-1 */ +- if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) ++ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) + goto out; + + /* enable blinding */ +@@ -3846,7 +4101,7 @@ sshkey_parse_private_pem_fileblob(struct + r = SSH_ERR_KEY_WRONG_PASSPHRASE; + goto out; + } +- if (pk->type == EVP_PKEY_RSA && ++ if (EVP_PKEY_id(pk) == EVP_PKEY_RSA && + (type == KEY_UNSPEC || type == KEY_RSA)) { + if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; +@@ -3861,7 +4116,7 @@ sshkey_parse_private_pem_fileblob(struct + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- } else if (pk->type == EVP_PKEY_DSA && ++ } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA && + (type == KEY_UNSPEC || type == KEY_DSA)) { + if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; +@@ -3873,7 +4128,7 @@ sshkey_parse_private_pem_fileblob(struct + DSA_print_fp(stderr, prv->dsa, 8); + #endif + #ifdef OPENSSL_HAS_ECC +- } else if (pk->type == EVP_PKEY_EC && ++ } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC && + (type == KEY_UNSPEC || type == KEY_ECDSA)) { + if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; +diff -up openssh-7.3p1/ssh-keygen.c.openssl openssh-7.3p1/ssh-keygen.c +--- openssh-7.3p1/ssh-keygen.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-keygen.c 2016-10-27 14:28:16.625815240 +0200 +@@ -480,40 +480,67 @@ do_convert_private_ssh2_from_blob(u_char + free(type); + + switch (key->type) { +- case KEY_DSA: +- buffer_get_bignum_bits(b, key->dsa->p); +- buffer_get_bignum_bits(b, key->dsa->g); +- buffer_get_bignum_bits(b, key->dsa->q); +- buffer_get_bignum_bits(b, key->dsa->pub_key); +- buffer_get_bignum_bits(b, key->dsa->priv_key); ++ case KEY_DSA: { ++ BIGNUM *p = NULL, *g = NULL, *q = NULL, *pub_key = NULL, *priv_key = NULL; ++ ++ if ((p = BN_new()) == NULL || ++ (g = BN_new()) == NULL || ++ (q = BN_new()) == NULL || ++ (pub_key = BN_new()) == NULL || ++ (priv_key = BN_new()) == NULL) ++ fatal("BN_new() failed"); ++ buffer_get_bignum_bits(b, p); ++ buffer_get_bignum_bits(b, g); ++ buffer_get_bignum_bits(b, q); ++ buffer_get_bignum_bits(b, pub_key); ++ buffer_get_bignum_bits(b, priv_key); ++ if (DSA_set0_pqg(key->dsa, p, q, g) == 0 || ++ DSA_set0_key(key->dsa, pub_key, priv_key) == 0) { ++ fatal("failed to set DSA key"); ++ } ++ } + break; +- case KEY_RSA: +- if ((r = sshbuf_get_u8(b, &e1)) != 0 || +- (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || +- (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) +- fatal("%s: buffer error: %s", __func__, ssh_err(r)); +- e = e1; +- debug("e %lx", e); +- if (e < 30) { +- e <<= 8; +- e += e2; +- debug("e %lx", e); +- e <<= 8; +- e += e3; ++ case KEY_RSA: { ++ BIGNUM *bn_e = NULL, *bn_d = NULL, *bn_n = NULL, *bn_iqmp = NULL, *bn_p = NULL, *bn_q = NULL; ++ ++ if ((bn_e = BN_new()) == NULL || ++ (bn_d = BN_new()) == NULL || ++ (bn_n = BN_new()) == NULL || ++ (bn_iqmp = BN_new()) == NULL || ++ (bn_p = BN_new()) == NULL || ++ (bn_q = BN_new()) == NULL) ++ fatal("BN_new() failed"); ++ ++ if ((r = sshbuf_get_u8(b, &e1)) != 0 || ++ (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || ++ (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ e = e1; + debug("e %lx", e); ++ if (e < 30) { ++ e <<= 8; ++ e += e2; ++ debug("e %lx", e); ++ e <<= 8; ++ e += e3; ++ debug("e %lx", e); ++ } ++ if (!BN_set_word(bn_e, e)) { ++ sshbuf_free(b); ++ sshkey_free(key); ++ return NULL; ++ } ++ buffer_get_bignum_bits(b, bn_d); ++ buffer_get_bignum_bits(b, bn_n); ++ buffer_get_bignum_bits(b, bn_iqmp); ++ buffer_get_bignum_bits(b, bn_q); ++ buffer_get_bignum_bits(b, bn_p); ++ if (RSA_set0_key(key->rsa, bn_n, bn_e, bn_d) == 0 || ++ RSA_set0_factors(key->rsa, bn_p, bn_q) == 0) ++ fatal("Failed to set RSA parameters"); ++ if ((r = rsa_generate_additional_parameters(key->rsa, bn_iqmp)) != 0) ++ fatal("generate RSA parameters failed: %s", ssh_err(r)); + } +- if (!BN_set_word(key->rsa->e, e)) { +- sshbuf_free(b); +- sshkey_free(key); +- return NULL; +- } +- buffer_get_bignum_bits(b, key->rsa->d); +- buffer_get_bignum_bits(b, key->rsa->n); +- buffer_get_bignum_bits(b, key->rsa->iqmp); +- buffer_get_bignum_bits(b, key->rsa->q); +- buffer_get_bignum_bits(b, key->rsa->p); +- if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) +- fatal("generate RSA parameters failed: %s", ssh_err(r)); + break; + } + rlen = sshbuf_len(b); +@@ -621,7 +648,7 @@ do_convert_from_pkcs8(struct sshkey **k, + identity_file); + } + fclose(fp); +- switch (EVP_PKEY_type(pubkey->type)) { ++ switch (EVP_PKEY_base_id(pubkey)) { + case EVP_PKEY_RSA: + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); +@@ -645,7 +672,7 @@ do_convert_from_pkcs8(struct sshkey **k, + #endif + default: + fatal("%s: unsupported pubkey type %d", __func__, +- EVP_PKEY_type(pubkey->type)); ++ EVP_PKEY_base_id(pubkey)); + } + EVP_PKEY_free(pubkey); + return; +@@ -1683,6 +1710,7 @@ do_ca_sign(struct passwd *pw, int argc, + #ifdef ENABLE_PKCS11 + pkcs11_terminate(); + #endif ++ free(ca); + exit(0); + } + +diff -up openssh-7.3p1/ssh-keyscan.c.openssl openssh-7.3p1/ssh-keyscan.c +--- openssh-7.3p1/ssh-keyscan.c.openssl 2016-10-27 14:28:16.486815572 +0200 ++++ openssh-7.3p1/ssh-keyscan.c 2016-10-27 14:28:16.625815240 +0200 +@@ -195,6 +195,7 @@ keygrab_ssh1(con *c) + static struct sshbuf *msg; + int r; + u_char type; ++ BIGNUM *n = NULL, *e = NULL; + + if (rsa == NULL) { + if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { +@@ -213,16 +214,20 @@ keygrab_ssh1(con *c) + sshbuf_reset(msg); + return NULL; + } +- if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ ++ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || ++ (r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ + /* server key */ + (r = sshbuf_get_u32(msg, NULL)) != 0 || + (r = sshbuf_get_bignum1(msg, NULL)) != 0 || + (r = sshbuf_get_bignum1(msg, NULL)) != 0 || + /* host key */ + (r = sshbuf_get_u32(msg, NULL)) != 0 || +- (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || +- (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { ++ (r = sshbuf_get_bignum1(msg, e)) != 0 || ++ (r = sshbuf_get_bignum1(msg, n)) != 0 || ++ RSA_set0_key(rsa->rsa, n, e, NULL) == 0) { + buf_err: ++ BN_free(n); ++ BN_free(e); + error("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_reset(msg); + return NULL; +diff -up openssh-7.3p1/ssh-pkcs11-client.c.openssl openssh-7.3p1/ssh-pkcs11-client.c +--- openssh-7.3p1/ssh-pkcs11-client.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-pkcs11-client.c 2016-10-27 14:28:16.625815240 +0200 +@@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, con + static int + wrap_key(RSA *rsa) + { +- static RSA_METHOD helper_rsa; ++ static RSA_METHOD *helper_rsa; + +- memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); +- helper_rsa.name = "ssh-pkcs11-helper"; +- helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; +- RSA_set_method(rsa, &helper_rsa); ++ if (helper_rsa == NULL) { ++ helper_rsa = RSA_meth_dup(RSA_get_default_method()); ++ RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper"); ++ RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt); ++ } ++ RSA_set_method(rsa, helper_rsa); + return (0); + } + +diff -up openssh-7.3p1/ssh-pkcs11.c.openssl openssh-7.3p1/ssh-pkcs11.c +--- openssh-7.3p1/ssh-pkcs11.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-pkcs11.c 2016-10-27 14:28:16.625815240 +0200 +@@ -67,7 +67,7 @@ struct pkcs11_key { + struct pkcs11_provider *provider; + CK_ULONG slotidx; + int (*orig_finish)(RSA *rsa); +- RSA_METHOD rsa_method; ++ RSA_METHOD *rsa_method; + char *keyid; + int keyid_len; + }; +@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } +- k11->orig_finish = def->finish; +- memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); +- k11->rsa_method.name = "pkcs11"; +- k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; +- k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; +- k11->rsa_method.finish = pkcs11_rsa_finish; +- RSA_set_method(rsa, &k11->rsa_method); ++ k11->orig_finish = RSA_meth_get_finish(def); ++ if ((k11->rsa_method = RSA_meth_dup(def)) == NULL || ++ RSA_meth_set1_name(k11->rsa_method, "pkcs11") == 0 || ++ RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt) == 0 || ++ RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt) == 0 || ++ RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish) == 0) { ++ RSA_meth_free(k11->rsa_method); ++ k11->rsa_method = NULL; ++ pkcs11_provider_unref(k11->provider); ++ free(k11->keyid); ++ free(k11); ++ return (-1); ++ } ++ ++ RSA_set_method(rsa, k11->rsa_method); + RSA_set_app_data(rsa, k11); + return (0); + } +@@ -460,6 +468,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + CK_ULONG nfound; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f; ++ const BIGNUM *n, *e; + + f = p->function_list; + session = p->slotinfo[slotidx].session; +@@ -512,10 +521,14 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + if ((rsa = RSA_new()) == NULL) { + error("RSA_new failed"); + } else { +- rsa->n = BN_bin2bn(attribs[1].pValue, ++ BIGNUM *rsa_n, *rsa_e; ++ ++ rsa_n = BN_bin2bn(attribs[1].pValue, + attribs[1].ulValueLen, NULL); +- rsa->e = BN_bin2bn(attribs[2].pValue, ++ rsa_e = BN_bin2bn(attribs[2].pValue, + attribs[2].ulValueLen, NULL); ++ if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0) ++ error("RSA_set0_key failed"); + } + } else { + cp = attribs[2].pValue; +@@ -525,17 +538,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + == NULL) { + error("d2i_X509 failed"); + } else if ((evp = X509_get_pubkey(x509)) == NULL || +- evp->type != EVP_PKEY_RSA || +- evp->pkey.rsa == NULL) { ++ EVP_PKEY_id(evp) != EVP_PKEY_RSA || ++ EVP_PKEY_get0_RSA(evp) == NULL) { + debug("X509_get_pubkey failed or no rsa"); +- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) ++ } else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) + == NULL) { + error("RSAPublicKey_dup"); + } + if (x509) + X509_free(x509); + } +- if (rsa && rsa->n && rsa->e && ++ RSA_get0_key(rsa, &n, &e, NULL); ++ if (rsa && n && e && + pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { + key = sshkey_new(KEY_UNSPEC); + key->rsa = rsa; +diff -up openssh-7.3p1/ssh-rsa.c.openssl openssh-7.3p1/ssh-rsa.c +--- openssh-7.3p1/ssh-rsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 ++++ openssh-7.3p1/ssh-rsa.c 2016-10-27 14:28:16.626815238 +0200 +@@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u + hash_alg = rsa_hash_alg_from_ident(alg_ident); + if (key == NULL || key->rsa == NULL || hash_alg == -1 || + sshkey_type_plain(key->type) != KEY_RSA || +- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) ++ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_INVALID_ARGUMENT; + slen = RSA_size(key->rsa); + if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) +@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key, + + if (key == NULL || key->rsa == NULL || + sshkey_type_plain(key->type) != KEY_RSA || +- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE || ++ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE || + sig == NULL || siglen == 0) + return SSH_ERR_INVALID_ARGUMENT; + From 25f492eb241c0c1a502b112de2fe6bc8e0e8a1f1 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 9 Dec 2016 15:38:57 +0100 Subject: [PATCH 034/146] Based on openssh-7.3p1-7.fc25 --- gsi-openssh.spec | 8 +- openssh-7.2p1-gsskex.patch | 14 ++ openssh-7.3p1-openssl-1.1.0.patch | 14 +- openssh-7.3p1-x11-max-displays.patch | 214 +++++++++++++++++++++++++++ 4 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 openssh-7.3p1-x11-max-displays.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 1fef480..80d4b05 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.3p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -167,6 +167,8 @@ Patch940: openssh-7.2p2-expose-pam.patch Patch942: openssh-7.2p2-chroot-capabilities.patch # Null dereference in newkeys code (#1380297) Patch943: openssh-7.3p1-null-deref.patch +# Move MAX_DISPLAYS to a configuration option (#1341302) +Patch944: openssh-7.3p1-x11-max-displays.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -323,6 +325,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch940 -p1 -b .expose-pam %patch942 -p1 -b .chroot-cap %patch943 -p1 -b .deref +%patch944 -p1 -b .x11max %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -539,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Dec 09 2016 Mattias Ellert - 7.3p1-4 +- Based on openssh-7.3p1-7.fc25 + * Wed Nov 02 2016 Mattias Ellert - 7.3p1-3 - Based on openssh-7.3p1-5.fc26 diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index cc4aa20..deb6637 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -3002,3 +3002,17 @@ index e2ca8a1..6c5ac3f 100644 + #endif /* ! _PORT_LINUX_H */ +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 3e6f982..4c2653f 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -213,6 +213,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_write + SC_ALLOW(write), + #endif ++#ifdef __NR_futex ++ SC_ALLOW(futex), /* for GSSAPI Kex */ ++#endif + #ifdef __NR_socketcall + SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), + #endif diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 17508d2..5208c95 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -3555,7 +3555,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2818,24 +2994,73 @@ sshkey_private_deserialize(struct sshbuf +@@ -2818,24 +2994,81 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3620,28 +3620,36 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c + case KEY_RSA_CERT: { + BIGNUM *n, *e, *d, *iqmp, *p, *q; + -+ /* XXX leave N, E as zero */ ++ /* N can't be zero because it breaks blinding (seed). Count it now */ ++ /* E is zero because it is not in the protocol, but needed for RSA structure */ + n = BN_new(); + e = BN_new(); + d = BN_new(); + iqmp = BN_new(); + p = BN_new(); + q = BN_new(); ++ BN_CTX *ctx = BN_CTX_new(); + + if (n == NULL || e == NULL || d == NULL || + iqmp == NULL || p == NULL || q == NULL || ++ ctx == NULL || + (r = sshkey_froms(buf, &k)) != 0 || + (r = sshkey_add_private(k)) != 0 || + (r = sshbuf_get_bignum2(buf, d)) != 0 || + (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || + (r = sshbuf_get_bignum2(buf, p)) != 0 || + (r = sshbuf_get_bignum2(buf, q)) != 0 || ++ (r = ((BN_mul(n, p, q, ctx) == 0) /* N = P * Q */ ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || + (r = ((RSA_set0_key(k->rsa, n, e, d) == 0) + ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || + (r = ((RSA_set0_factors(k->rsa, p, q) == 0) + ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || -+ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) ++ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) { ++ BN_CTX_free(ctx); + goto out; ++ } ++ BN_CTX_free(ctx); + } break; #endif /* WITH_OPENSSL */ diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch new file mode 100644 index 0000000..26553fa --- /dev/null +++ b/openssh-7.3p1-x11-max-displays.patch @@ -0,0 +1,214 @@ +diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c +--- openssh-6.6p1/channels.c.x11max 2016-06-27 16:28:49.803631684 +0200 ++++ openssh-6.6p1/channels.c 2016-06-27 16:28:49.814631678 +0200 +@@ -138,8 +138,8 @@ static int all_opens_permitted = 0; + + /* -- 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 + + /* Saved X11 local (client) display. */ + static char *x11_saved_display = NULL; +@@ -3445,7 +3445,8 @@ channel_send_window_changes(void) + */ + int + x11_create_display_inet(int x11_display_offset, int x11_use_localhost, +- int single_connection, u_int *display_numberp, int **chanids) ++ int x11_max_displays, int single_connection, u_int *display_numberp, ++ int **chanids) + { + Channel *nc = NULL; + int display_number, sock; +@@ -3457,10 +3458,15 @@ x11_create_display_inet(int x11_display_ + if (chanids == NULL) + return -1; + ++ /* Try to bind ports starting at 6000+X11DisplayOffset */ ++ x11_max_displays = x11_max_displays + x11_display_offset; ++ + for (display_number = x11_display_offset; +- display_number < MAX_DISPLAYS; ++ display_number < x11_max_displays; + display_number++) { +- port = 6000 + display_number; ++ port = X11_PORT_MIN + display_number; ++ if (port < X11_PORT_MIN) /* overflow */ ++ break; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; +@@ -3512,7 +3518,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_PORT_MIN ) { + error("Failed to allocate internet-domain X11 display socket."); + return -1; + } +@@ -3658,7 +3664,7 @@ x11_connect_display(void) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = 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)); +@@ -3674,7 +3680,7 @@ x11_connect_display(void) + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug2("connect %.100s port %u: %.100s", buf, +- 6000 + display_number, strerror(errno)); ++ X11_PORT_MIN + display_number, strerror(errno)); + close(sock); + continue; + } +@@ -3683,8 +3689,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-6.6p1/channels.h.x11max openssh-6.6p1/channels.h +--- openssh-6.6p1/channels.h.x11max 2016-06-27 16:28:49.814631678 +0200 ++++ openssh-6.6p1/channels.h 2016-06-27 16:31:18.925557840 +0200 +@@ -281,7 +281,7 @@ int permitopen_port(const char *); + + void channel_set_x11_refuse_time(u_int); + int x11_connect_display(void); +-int x11_create_display_inet(int, int, int, u_int *, int **); ++int x11_create_display_inet(int, int, int, int, u_int *, int **); + int x11_input_open(int, u_int32_t, void *); + void x11_request_forwarding_with_spoofing(int, const char *, const char *, + const char *, int); +diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c +--- openssh-6.6p1/servconf.c.x11max 2016-06-27 16:28:49.808631681 +0200 ++++ openssh-6.6p1/servconf.c 2016-06-27 16:30:46.941573678 +0200 +@@ -92,6 +92,7 @@ initialize_server_options(ServerOptions + options->print_lastlog = -1; + options->x11_forwarding = -1; + options->x11_display_offset = -1; ++ options->x11_max_displays = -1; + options->x11_use_localhost = -1; + options->permit_tty = -1; + options->permit_user_rc = -1; +@@ -219,6 +220,8 @@ fill_default_server_options(ServerOption + options->x11_forwarding = 0; + if (options->x11_display_offset == -1) + options->x11_display_offset = 10; ++ if (options->x11_max_displays == -1) ++ options->x11_max_displays = DEFAULT_MAX_DISPLAYS; + if (options->x11_use_localhost == -1) + options->x11_use_localhost = 1; + if (options->xauth_location == NULL) +@@ -364,7 +367,7 @@ typedef enum { + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, +- sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, ++ sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, + sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, +@@ -476,6 +479,7 @@ static struct { + { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, + { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, + { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, ++ { "x11maxdisplays", sX11MaxDisplays, SSHCFG_ALL }, + { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, + { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, + { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, +@@ -1202,6 +1206,10 @@ process_server_config_line(ServerOptions + intptr = &options->x11_display_offset; + goto parse_int; + ++ case sX11MaxDisplays: ++ intptr = &options->x11_max_displays; ++ goto parse_int; ++ + case sX11UseLocalhost: + intptr = &options->x11_use_localhost; + goto parse_flag; +@@ -1889,6 +1897,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); ++ M_CP_INTOPT(x11_max_displays); + M_CP_INTOPT(x11_use_localhost); + M_CP_INTOPT(permit_tty); + M_CP_INTOPT(permit_user_rc); +@@ -2106,6 +2115,7 @@ dump_config(ServerOptions *o) + dump_cfg_int(sLoginGraceTime, o->login_grace_time); + dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); + dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); ++ dump_cfg_int(sX11MaxDisplays, o->x11_max_displays); + dump_cfg_int(sMaxAuthTries, o->max_authtries); + dump_cfg_int(sMaxSessions, o->max_sessions); + dump_cfg_int(sClientAliveInterval, o->client_alive_interval); +diff -up openssh-6.6p1/servconf.h.x11max openssh-6.6p1/servconf.h +--- openssh-6.6p1/servconf.h.x11max 2016-06-27 16:28:49.809631681 +0200 ++++ openssh-6.6p1/servconf.h 2016-06-27 16:28:49.815631678 +0200 +@@ -55,6 +55,7 @@ + + #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ + #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ ++#define DEFAULT_MAX_DISPLAYS 1000 /* Maximum number of fake X11 displays to try. */ + + /* Magic name for internal sftp-server */ + #define INTERNAL_SFTP_NAME "internal-sftp" +@@ -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 */ ++ int x11_max_displays; /* Number of displays to search */ + int x11_use_localhost; /* If true, use localhost for fake X11 server. */ + char *xauth_location; /* Location of xauth program */ + int permit_tty; /* If false, deny pty allocation */ +diff -up openssh-6.6p1/session.c.x11max openssh-6.6p1/session.c +--- openssh-6.6p1/session.c.x11max 2016-06-27 16:28:49.809631681 +0200 ++++ openssh-6.6p1/session.c 2016-06-27 16:28:49.815631678 +0200 +@@ -2741,8 +2741,9 @@ session_setup_x11fwd(Session *s) + return 0; + } + if (x11_create_display_inet(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, ++ s->single_connection, &s->display_number, ++ &s->x11_chanids) == -1) { + debug("x11_create_display_inet failed."); + return 0; + } +diff -up openssh-6.6p1/sshd_config.5.x11max openssh-6.6p1/sshd_config.5 +--- openssh-6.6p1/sshd_config.5.x11max 2016-06-27 16:28:49.809631681 +0200 ++++ openssh-6.6p1/sshd_config.5 2016-06-27 16:32:01.253536879 +0200 +@@ -930,6 +930,7 @@ Available keywords are + .Cm StreamLocalBindUnlink , + .Cm TrustedUserCAKeys , + .Cm X11DisplayOffset , ++.Cm X11MaxDisplays , + .Cm X11Forwarding + and + .Cm X11UseLocalHost . +@@ -1339,6 +1340,12 @@ Specifies the first display number avail + X11 forwarding. + This prevents sshd from interfering with real X11 servers. + The default is 10. ++.It Cm X11MaxDisplays ++Specifies the maximum number of displays available for ++.Xr sshd 8 Ns 's ++X11 forwarding. ++This prevents sshd from exhausting local ports. ++The default is 1000. + .It Cm X11Forwarding + Specifies whether X11 forwarding is permitted. + The argument must be From 1f8a82b0c7e151c308bfbd10fe39db6ffb94ce27 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 13 Dec 2016 22:01:38 +0100 Subject: [PATCH 035/146] Adding mechanism OID negotiation with the introduction of micv2 OID --- gsi-openssh.spec | 7 +- openssh-7.3p1-gsissh.patch | 595 ++++++++++++++++++++++--------------- 2 files changed, 362 insertions(+), 240 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 80d4b05..f923eca 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.3p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -198,7 +198,7 @@ BuildRequires: krb5-devel %if %{gsi} BuildRequires: globus-gss-assist-devel >= 8 -BuildRequires: globus-gssapi-gsi-devel >= 10 +BuildRequires: globus-gssapi-gsi-devel >= 12.12 BuildRequires: globus-common-devel >= 14 BuildRequires: globus-usage-devel >= 3 %endif @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Dec 13 2016 Mattias Ellert - 7.3p1-5 +- Adding mechanism OID negotiation with the introduction of micv2 OID + * Fri Dec 09 2016 Mattias Ellert - 7.3p1-4 - Based on openssh-7.3p1-7.fc25 diff --git a/openssh-7.3p1-gsissh.patch b/openssh-7.3p1-gsissh.patch index 8a5548d..89d11dc 100644 --- a/openssh-7.3p1-gsissh.patch +++ b/openssh-7.3p1-gsissh.patch @@ -1,24 +1,7 @@ diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c ---- openssh-7.3p1.orig/auth2.c 2016-08-15 15:32:58.794404264 +0200 -+++ openssh-7.3p1/auth2.c 2016-08-15 15:33:35.802990200 +0200 -@@ -50,6 +50,7 @@ - #include "dispatch.h" - #include "pathnames.h" - #include "buffer.h" -+#include "canohost.h" - - #ifdef GSSAPI - #include "ssh-gss.h" -@@ -74,6 +75,8 @@ - extern Authmethod method_gssapi; - #endif - -+static int log_flag = 0; -+ - Authmethod *authmethods[] = { - &method_none, - &method_pubkey, -@@ -228,7 +231,32 @@ +--- openssh-7.3p1.orig/auth2.c 2016-12-13 11:17:13.434232603 +0100 ++++ openssh-7.3p1/auth2.c 2016-12-13 19:16:47.109836990 +0100 +@@ -228,7 +228,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -44,15 +27,10 @@ diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c + + debug("userauth-request for user %s service %s method %s", + user[0] ? user : "", service, method); -+ if (!log_flag) { -+ logit("SSH: Server;Ltype: Authname;Name: %s", -+ user[0] ? user : ""); -+ log_flag = 1; -+ } debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -239,23 +268,48 @@ +@@ -239,23 +259,48 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -105,7 +83,7 @@ diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -270,9 +324,10 @@ +@@ -270,9 +315,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -120,8 +98,8 @@ diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-7.3p1.orig/auth2-gss.c openssh-7.3p1/auth2-gss.c ---- openssh-7.3p1.orig/auth2-gss.c 2016-08-15 15:32:58.782404398 +0200 -+++ openssh-7.3p1/auth2-gss.c 2016-08-15 15:33:35.802990200 +0200 +--- openssh-7.3p1.orig/auth2-gss.c 2016-12-13 11:17:13.419232772 +0100 ++++ openssh-7.3p1/auth2-gss.c 2016-12-13 15:57:03.191160419 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -303,8 +281,8 @@ diff -Nur openssh-7.3p1.orig/auth2-gss.c openssh-7.3p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c ---- openssh-7.3p1.orig/auth.c 2016-08-15 15:32:58.795404252 +0200 -+++ openssh-7.3p1/auth.c 2016-08-15 15:38:11.546905093 +0200 +--- openssh-7.3p1.orig/auth.c 2016-12-13 11:17:13.435232591 +0100 ++++ openssh-7.3p1/auth.c 2016-12-15 13:50:04.489124248 +0100 @@ -77,6 +77,9 @@ #include "ssherr.h" #include "compat.h" @@ -336,15 +314,15 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c + ssh_gssapi_get_client_info(&userdn, &mech_name); +#endif + debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)", -+ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), -+ method, mech_name?mech_name:"NULL", ssh_remote_ipaddr(ssh), -+ (authctxt->user && authctxt->user[0])? -+ authctxt->user : "unknown", -+ userdn?userdn:"NULL"); ++ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), ++ method, mech_name?mech_name:"NULL", ssh_remote_ipaddr(ssh), ++ (authctxt->user && authctxt->user[0])? ++ authctxt->user : "unknown", ++ userdn?userdn:"NULL"); + ssh_globus_send_usage_metrics(SSH_RELEASE, -+ SSLeay_version(SSLEAY_VERSION), -+ method, mech_name, ssh_remote_ipaddr(ssh), -+ authctxt->user, userdn); ++ SSLeay_version(SSLEAY_VERSION), ++ method, mech_name, ssh_remote_ipaddr(ssh), ++ authctxt->user, userdn); + } } @@ -371,9 +349,9 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c ---- openssh-7.3p1.orig/auth-pam.c 2016-08-15 15:32:58.783404387 +0200 -+++ openssh-7.3p1/auth-pam.c 2016-08-15 15:33:35.804990178 +0200 -@@ -280,6 +284,56 @@ +--- openssh-7.3p1.orig/auth-pam.c 2016-12-13 11:17:13.458232332 +0100 ++++ openssh-7.3p1/auth-pam.c 2016-12-13 15:57:03.192160408 +0100 +@@ -284,6 +284,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -430,7 +408,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -302,7 +356,7 @@ +@@ -306,7 +356,7 @@ static void import_environments(Buffer *b) { @@ -439,7 +417,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c u_int i, num_env; int err; -@@ -312,6 +366,17 @@ +@@ -316,6 +366,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -457,7 +435,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -463,6 +528,13 @@ +@@ -467,6 +528,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -471,7 +449,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -483,6 +555,11 @@ +@@ -487,6 +555,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -483,7 +461,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -939,6 +1016,18 @@ +@@ -943,6 +1016,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -502,7 +480,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1237,6 +1326,9 @@ +@@ -1241,6 +1326,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -513,8 +491,8 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-7.3p1.orig/auth-pam.h openssh-7.3p1/auth-pam.h ---- openssh-7.3p1.orig/auth-pam.h 2016-08-15 15:32:58.669405662 +0200 -+++ openssh-7.3p1/auth-pam.h 2016-08-15 15:33:35.805990167 +0200 +--- openssh-7.3p1.orig/auth-pam.h 2016-12-13 11:17:13.274234405 +0100 ++++ openssh-7.3p1/auth-pam.h 2016-12-13 15:57:03.192160408 +0100 @@ -48,5 +48,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -524,7 +502,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.h openssh-7.3p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-7.3p1.orig/canohost.c openssh-7.3p1/canohost.c --- openssh-7.3p1.orig/canohost.c 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/canohost.c 2016-08-15 15:33:35.806990155 +0200 ++++ openssh-7.3p1/canohost.c 2016-12-13 15:57:03.192160408 +0100 @@ -17,6 +17,7 @@ #include #include @@ -569,7 +547,7 @@ diff -Nur openssh-7.3p1.orig/canohost.c openssh-7.3p1/canohost.c +} diff -Nur openssh-7.3p1.orig/canohost.h openssh-7.3p1/canohost.h --- openssh-7.3p1.orig/canohost.h 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/canohost.h 2016-08-15 15:33:35.806990155 +0200 ++++ openssh-7.3p1/canohost.h 2016-12-13 15:57:03.193160397 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -578,8 +556,8 @@ diff -Nur openssh-7.3p1.orig/canohost.h openssh-7.3p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac ---- openssh-7.3p1.orig/configure.ac 2016-08-15 15:32:58.791404297 +0200 -+++ openssh-7.3p1/configure.ac 2016-08-15 15:33:35.807990144 +0200 +--- openssh-7.3p1.orig/configure.ac 2016-12-13 11:17:13.425232704 +0100 ++++ openssh-7.3p1/configure.ac 2016-12-13 15:57:03.193160397 +0100 @@ -4383,6 +4383,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -647,8 +625,8 @@ diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac PRIVSEP_PATH=/var/empty diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c ---- openssh-7.3p1.orig/gss-genr.c 2016-08-15 15:32:58.771404521 +0200 -+++ openssh-7.3p1/gss-genr.c 2016-08-15 15:33:35.808990133 +0200 +--- openssh-7.3p1.orig/gss-genr.c 2016-12-13 11:17:13.460232310 +0100 ++++ openssh-7.3p1/gss-genr.c 2016-12-13 15:57:03.233159954 +0100 @@ -40,6 +40,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -657,7 +635,7 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -368,9 +369,18 @@ +@@ -371,9 +372,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -677,7 +655,7 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -378,6 +388,7 @@ +@@ -381,6 +391,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -686,8 +664,8 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c return (ctx->major); } diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c ---- openssh-7.3p1.orig/gss-serv.c 2016-08-15 15:32:58.784404375 +0200 -+++ openssh-7.3p1/gss-serv.c 2016-08-15 15:33:35.808990133 +0200 +--- openssh-7.3p1.orig/gss-serv.c 2016-12-13 11:17:13.420232760 +0100 ++++ openssh-7.3p1/gss-serv.c 2016-12-13 23:14:33.804004555 +0100 @@ -47,14 +47,17 @@ #include "servconf.h" #include "uidswap.h" @@ -707,12 +685,13 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -62,14 +65,24 @@ +@@ -62,14 +65,26 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif +#ifdef GSI +extern ssh_gssapi_mech gssapi_gsi_mech; ++extern ssh_gssapi_mech gssapi_gsi_mech_micv2; +#endif ssh_gssapi_mech* supported_mechs[]= { @@ -721,6 +700,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c #endif +#ifdef GSI + &gssapi_gsi_mech, ++ &gssapi_gsi_mech_micv2, +#endif &gssapi_null_mech, }; @@ -732,7 +712,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -230,6 +243,10 @@ +@@ -230,6 +245,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -743,14 +723,17 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c } return (status); -@@ -249,6 +266,17 @@ +@@ -249,6 +268,20 @@ tok = ename->value; +#ifdef GSI /* GSI gss_export_name() is broken. */ -+ if ((ctx->oid->length == gssapi_gsi_mech.oid.length) && -+ (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements, -+ gssapi_gsi_mech.oid.length) == 0)) { ++ if (((ctx->oid->length == gssapi_gsi_mech.oid.length) && ++ (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements, ++ gssapi_gsi_mech.oid.length) == 0)) || ++ ((ctx->oid->length == gssapi_gsi_mech_micv2.oid.length) && ++ (memcmp(ctx->oid->elements, gssapi_gsi_mech_micv2.oid.elements, ++ gssapi_gsi_mech_micv2.oid.length) == 0))) { + name->length = ename->length; + name->value = xmalloc(ename->length+1); + memcpy(name->value, ename->value, ename->length); @@ -761,7 +744,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -316,8 +344,11 @@ +@@ -316,8 +349,11 @@ return GSS_S_COMPLETE; } @@ -775,7 +758,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); -@@ -360,9 +391,12 @@ +@@ -360,9 +396,12 @@ if (client->mech == NULL) return GSS_S_FAILURE; @@ -790,7 +773,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -389,6 +423,10 @@ +@@ -389,6 +428,10 @@ /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -801,7 +784,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c return (ctx->major); } -@@ -396,6 +434,7 @@ +@@ -396,6 +439,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -809,7 +792,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -411,6 +450,14 @@ +@@ -411,6 +455,14 @@ gssapi_client.store.data = NULL; } } @@ -824,7 +807,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c } /* As user */ -@@ -418,6 +465,11 @@ +@@ -418,6 +470,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -836,7 +819,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -451,8 +503,9 @@ +@@ -451,8 +508,9 @@ } /* Privileged */ @@ -847,7 +830,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c { OM_uint32 lmin; -@@ -461,6 +514,12 @@ +@@ -461,6 +519,12 @@ debug("No suitable client data"); return 0; } @@ -860,7 +843,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -480,6 +539,24 @@ +@@ -480,6 +544,24 @@ return (0); } @@ -885,7 +868,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -506,6 +583,7 @@ +@@ -506,6 +588,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -893,7 +876,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -535,6 +613,18 @@ +@@ -535,6 +618,18 @@ if (ret) return; @@ -912,7 +895,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -566,4 +656,13 @@ +@@ -566,4 +661,13 @@ return ok; } @@ -928,8 +911,8 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c #endif diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c --- openssh-7.3p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/gss-serv-gsi.c 2016-08-15 15:33:35.809990122 +0200 -@@ -0,0 +1,239 @@ ++++ openssh-7.3p1/gss-serv-gsi.c 2016-12-15 13:37:48.136468294 +0100 +@@ -0,0 +1,329 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * @@ -982,8 +965,11 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c +static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name); +static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user); +static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client); ++static void ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client); +static int ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client); ++static int ssh_gssapi_gsi_updatecreds_micv2(ssh_gssapi_ccache *store, ++ ssh_gssapi_client *client); + +ssh_gssapi_mech gssapi_gsi_mech = { + "dZuIebMjgUqaxvbF7hDbAw==", @@ -996,6 +982,17 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + &ssh_gssapi_gsi_updatecreds +}; + ++ssh_gssapi_mech gssapi_gsi_mech_micv2 = { ++ "vz8J1E9PzLr8b1K+0remTg==", ++ "GSI", ++ {10, "\x2b\x06\x01\x04\x01\x9b\x50\x01\x01\x01"}, ++ NULL, ++ &ssh_gssapi_gsi_userok, ++ &ssh_gssapi_gsi_localname, ++ &ssh_gssapi_gsi_storecreds_micv2, ++ &ssh_gssapi_gsi_updatecreds_micv2 ++}; ++ +/* + * Check if this user is OK to login under GSI. User has been authenticated + * as identity in global 'client_name.value' and is trying to log in as passed @@ -1011,10 +1008,10 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE + char lname[256] = ""; +#endif -+ ++ +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE + if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) { -+ return 0; ++ return 0; + } +#endif + @@ -1040,10 +1037,10 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + authorized = 1; + } +#endif -+ ++ + logit("GSI user %s is%s authorized as target user %s", -+ (char *) client->displayname.value, (authorized ? "" : " not"), name); -+ ++ (char *) client->displayname.value, (authorized ? "" : " not"), name); ++ + return authorized; +} + @@ -1060,7 +1057,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE + if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) { -+ return 0; ++ return 0; + } +#endif + @@ -1086,7 +1083,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c +#endif + + logit("GSI user %s mapped to target user %s", -+ (char *) client->displayname.value, *user); ++ (char *) client->displayname.value, *user); + + return 1; +} @@ -1101,9 +1098,9 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + OM_uint32 minor_status; + gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER; + char * p; -+ ++ + if (!client || !client->creds) { -+ return; ++ return; + } + + major_status = gss_export_cred(&minor_status, @@ -1112,47 +1109,113 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + 1, + &export_cred); + if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) { -+ Gssctxt *ctx; -+ ssh_gssapi_build_ctx(&ctx); -+ ctx->major = major_status; -+ ctx->minor = minor_status; -+ ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid); -+ ssh_gssapi_error(ctx); -+ ssh_gssapi_delete_ctx(&ctx); -+ return; ++ Gssctxt *ctx; ++ ssh_gssapi_build_ctx(&ctx); ++ ctx->major = major_status; ++ ctx->minor = minor_status; ++ ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid); ++ ssh_gssapi_error(ctx); ++ ssh_gssapi_delete_ctx(&ctx); ++ return; + } -+ ++ + p = strchr((char *) export_cred.value, '='); + if (p == NULL) { -+ logit("Failed to parse exported credentials string '%.100s'", -+ (char *)export_cred.value); -+ gss_release_buffer(&minor_status, &export_cred); -+ return; ++ logit("Failed to parse exported credentials string '%.100s'", ++ (char *)export_cred.value); ++ gss_release_buffer(&minor_status, &export_cred); ++ return; + } + *p++ = '\0'; + if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { -+ client->store.envvar = strdup("X509_USER_PROXY"); ++ client->store.envvar = strdup("X509_USER_PROXY"); + } else { -+ client->store.envvar = strdup((char *)export_cred.value); ++ client->store.envvar = strdup((char *)export_cred.value); + } + if (access(p, R_OK) == 0) { -+ if (client->store.filename) { -+ if (rename(p, client->store.filename) < 0) { -+ logit("Failed to rename %s to %s: %s", p, -+ client->store.filename, strerror(errno)); -+ free(client->store.filename); -+ client->store.filename = strdup(p); -+ } else { -+ p = client->store.filename; -+ } -+ } else { -+ client->store.filename = strdup(p); -+ } ++ if (client->store.filename) { ++ if (rename(p, client->store.filename) < 0) { ++ logit("Failed to rename %s to %s: %s", p, ++ client->store.filename, strerror(errno)); ++ free(client->store.filename); ++ client->store.filename = strdup(p); ++ } else { ++ p = client->store.filename; ++ } ++ } else { ++ client->store.filename = strdup(p); ++ } + } + client->store.envval = strdup(p); +#ifdef USE_PAM + if (options.use_pam) -+ do_pam_putenv(client->store.envvar, client->store.envval); ++ do_pam_putenv(client->store.envvar, client->store.envval); ++#endif ++ gss_release_buffer(&minor_status, &export_cred); ++} ++ ++/* ++ * Export GSI credentials to disk. ++ */ ++static void ++ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client) ++{ ++ OM_uint32 major_status; ++ OM_uint32 minor_status; ++ gss_buffer_desc export_cred = GSS_C_EMPTY_BUFFER; ++ char * p; ++ ++ if (!client || !client->creds) { ++ return; ++ } ++ ++ major_status = gss_export_cred(&minor_status, ++ client->creds, ++ GSS_C_NO_OID, ++ 1, ++ &export_cred); ++ if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) { ++ Gssctxt *ctx; ++ ssh_gssapi_build_ctx(&ctx); ++ ctx->major = major_status; ++ ctx->minor = minor_status; ++ ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech_micv2.oid); ++ ssh_gssapi_error(ctx); ++ ssh_gssapi_delete_ctx(&ctx); ++ return; ++ } ++ ++ p = strchr((char *) export_cred.value, '='); ++ if (p == NULL) { ++ logit("Failed to parse exported credentials string '%.100s'", ++ (char *)export_cred.value); ++ gss_release_buffer(&minor_status, &export_cred); ++ return; ++ } ++ *p++ = '\0'; ++ if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { ++ client->store.envvar = strdup("X509_USER_PROXY"); ++ } else { ++ client->store.envvar = strdup((char *)export_cred.value); ++ } ++ if (access(p, R_OK) == 0) { ++ if (client->store.filename) { ++ if (rename(p, client->store.filename) < 0) { ++ logit("Failed to rename %s to %s: %s", p, ++ client->store.filename, strerror(errno)); ++ free(client->store.filename); ++ client->store.filename = strdup(p); ++ } else { ++ p = client->store.filename; ++ } ++ } else { ++ client->store.filename = strdup(p); ++ } ++ } ++ client->store.envval = strdup(p); ++#ifdef USE_PAM ++ if (options.use_pam) ++ do_pam_putenv(client->store.envvar, client->store.envval); +#endif + gss_release_buffer(&minor_status, &export_cred); +} @@ -1167,11 +1230,21 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + return 1; +} + ++/* ++ * Export updated GSI credentials to disk. ++ */ ++static int ++ssh_gssapi_gsi_updatecreds_micv2(ssh_gssapi_ccache *store,ssh_gssapi_client *client) ++{ ++ ssh_gssapi_gsi_storecreds_micv2(client); ++ return 1; ++} ++ +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c ---- openssh-7.3p1.orig/gss-serv-krb5.c 2016-08-15 15:32:58.757404678 +0200 -+++ openssh-7.3p1/gss-serv-krb5.c 2016-08-15 15:33:35.809990122 +0200 +--- openssh-7.3p1.orig/gss-serv-krb5.c 2016-12-13 11:17:13.392233076 +0100 ++++ openssh-7.3p1/gss-serv-krb5.c 2016-12-15 13:38:23.114071274 +0100 @@ -378,6 +378,34 @@ return found_principal; } @@ -1190,7 +1263,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c + if ((retval=krb5_parse_name(krb_context, client->displayname.value, + &princ))) { + logit("krb5_parse_name(): %.100s", -+ krb5_get_err_text(krb_context,retval)); ++ krb5_get_err_text(krb_context,retval)); + return 0; + } + @@ -1226,8 +1299,8 @@ diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c ---- openssh-7.3p1.orig/kexgsss.c 2016-08-15 15:32:58.722405069 +0200 -+++ openssh-7.3p1/kexgsss.c 2016-08-15 15:33:35.809990122 +0200 +--- openssh-7.3p1.orig/kexgsss.c 2016-12-13 11:17:13.462232287 +0100 ++++ openssh-7.3p1/kexgsss.c 2016-12-13 15:57:03.234159943 +0100 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1236,7 +1309,7 @@ diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c extern ServerOptions options; int -@@ -95,8 +96,10 @@ +@@ -96,8 +97,10 @@ debug2("%s: Acquiring credentials", __func__); @@ -1248,7 +1321,7 @@ diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -183,12 +186,13 @@ +@@ -185,12 +188,13 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1263,7 +1336,7 @@ diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -294,4 +298,23 @@ +@@ -297,4 +301,23 @@ ssh_gssapi_rekey_creds(); return 0; } @@ -1289,7 +1362,7 @@ diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c #endif /* GSSAPI */ diff -Nur openssh-7.3p1.orig/LICENSE.globus_usage openssh-7.3p1/LICENSE.globus_usage --- openssh-7.3p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/LICENSE.globus_usage 2016-08-15 15:33:35.810990111 +0200 ++++ openssh-7.3p1/LICENSE.globus_usage 2016-12-13 15:57:03.240159876 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1310,8 +1383,8 @@ diff -Nur openssh-7.3p1.orig/LICENSE.globus_usage openssh-7.3p1/LICENSE.globus_u + * limitations under the License. + */ diff -Nur openssh-7.3p1.orig/Makefile.in openssh-7.3p1/Makefile.in ---- openssh-7.3p1.orig/Makefile.in 2016-08-15 15:32:58.808404107 +0200 -+++ openssh-7.3p1/Makefile.in 2016-08-15 15:33:35.810990111 +0200 +--- openssh-7.3p1.orig/Makefile.in 2016-12-13 11:17:13.462232287 +0100 ++++ openssh-7.3p1/Makefile.in 2016-12-13 15:57:03.241159865 +0100 @@ -114,8 +114,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ @@ -1324,8 +1397,8 @@ diff -Nur openssh-7.3p1.orig/Makefile.in openssh-7.3p1/Makefile.in sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o diff -Nur openssh-7.3p1.orig/misc.c openssh-7.3p1/misc.c ---- openssh-7.3p1.orig/misc.c 2016-08-15 15:32:58.756404689 +0200 -+++ openssh-7.3p1/misc.c 2016-08-15 15:33:35.810990111 +0200 +--- openssh-7.3p1.orig/misc.c 2016-12-13 11:17:13.390233098 +0100 ++++ openssh-7.3p1/misc.c 2016-12-13 15:57:03.241159865 +0100 @@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1386,8 +1459,8 @@ diff -Nur openssh-7.3p1.orig/misc.c openssh-7.3p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-7.3p1.orig/misc.h openssh-7.3p1/misc.h ---- openssh-7.3p1.orig/misc.h 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/misc.h 2016-08-15 15:33:35.811990100 +0200 +--- openssh-7.3p1.orig/misc.h 2016-12-13 11:17:13.463232276 +0100 ++++ openssh-7.3p1/misc.h 2016-12-13 15:57:03.241159865 +0100 @@ -65,6 +65,7 @@ void sock_set_v6only(int); @@ -1397,8 +1470,8 @@ diff -Nur openssh-7.3p1.orig/misc.h openssh-7.3p1/misc.h typedef struct arglist arglist; diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c ---- openssh-7.3p1.orig/monitor.c 2016-08-15 15:32:58.816404017 +0200 -+++ openssh-7.3p1/monitor.c 2016-08-15 15:33:35.811990100 +0200 +--- openssh-7.3p1.orig/monitor.c 2016-12-13 11:17:13.463232276 +0100 ++++ openssh-7.3p1/monitor.c 2016-12-13 15:57:03.242159854 +0100 @@ -165,6 +165,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1473,7 +1546,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c #endif } else { mon_dispatch = mon_dispatch_postauth15; -@@ -858,14 +870,17 @@ +@@ -861,14 +873,17 @@ debug3("%s", __func__); @@ -1494,7 +1567,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2253,12 +2268,15 @@ +@@ -2258,12 +2273,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1511,7 +1584,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2266,7 +2284,10 @@ +@@ -2271,7 +2289,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1523,7 +1596,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c if (authenticated) authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -2275,6 +2296,68 @@ +@@ -2280,6 +2301,68 @@ return (authenticated); } @@ -1593,8 +1666,8 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c mm_answer_gss_sign(int socket, Buffer *m) { diff -Nur openssh-7.3p1.orig/monitor.h openssh-7.3p1/monitor.h ---- openssh-7.3p1.orig/monitor.h 2016-08-15 15:32:58.798404219 +0200 -+++ openssh-7.3p1/monitor.h 2016-08-15 15:33:35.812990088 +0200 +--- openssh-7.3p1.orig/monitor.h 2016-12-13 11:17:13.437232569 +0100 ++++ openssh-7.3p1/monitor.h 2016-12-13 15:57:03.242159854 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1609,8 +1682,8 @@ diff -Nur openssh-7.3p1.orig/monitor.h openssh-7.3p1/monitor.h struct mm_master; diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c ---- openssh-7.3p1.orig/monitor_wrap.c 2016-08-15 15:32:58.816404017 +0200 -+++ openssh-7.3p1/monitor_wrap.c 2016-08-15 15:33:35.812990088 +0200 +--- openssh-7.3p1.orig/monitor_wrap.c 2016-12-13 11:17:13.453232389 +0100 ++++ openssh-7.3p1/monitor_wrap.c 2016-12-13 15:57:03.243159843 +0100 @@ -1126,12 +1126,13 @@ } @@ -1711,8 +1784,8 @@ diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-7.3p1.orig/monitor_wrap.h openssh-7.3p1/monitor_wrap.h ---- openssh-7.3p1.orig/monitor_wrap.h 2016-08-15 15:32:58.804404152 +0200 -+++ openssh-7.3p1/monitor_wrap.h 2016-08-15 15:33:35.813990077 +0200 +--- openssh-7.3p1.orig/monitor_wrap.h 2016-12-13 11:17:13.443232501 +0100 ++++ openssh-7.3p1/monitor_wrap.h 2016-12-13 15:57:03.243159843 +0100 @@ -64,9 +64,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1729,8 +1802,8 @@ diff -Nur openssh-7.3p1.orig/monitor_wrap.h openssh-7.3p1/monitor_wrap.h #endif diff -Nur openssh-7.3p1.orig/readconf.c openssh-7.3p1/readconf.c ---- openssh-7.3p1.orig/readconf.c 2016-08-15 15:32:58.809404096 +0200 -+++ openssh-7.3p1/readconf.c 2016-08-15 15:33:35.813990077 +0200 +--- openssh-7.3p1.orig/readconf.c 2016-12-13 11:17:13.447232456 +0100 ++++ openssh-7.3p1/readconf.c 2016-12-13 15:57:03.243159843 +0100 @@ -1974,13 +1974,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1750,8 +1823,8 @@ diff -Nur openssh-7.3p1.orig/readconf.c openssh-7.3p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-7.3p1.orig/readconf.h openssh-7.3p1/readconf.h ---- openssh-7.3p1.orig/readconf.h 2016-08-15 15:32:58.778404443 +0200 -+++ openssh-7.3p1/readconf.h 2016-08-15 15:33:35.814990066 +0200 +--- openssh-7.3p1.orig/readconf.h 2016-12-13 11:17:13.410232873 +0100 ++++ openssh-7.3p1/readconf.h 2016-12-13 15:57:03.243159843 +0100 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1762,8 +1835,8 @@ diff -Nur openssh-7.3p1.orig/readconf.h openssh-7.3p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c ---- openssh-7.3p1.orig/servconf.c 2016-08-15 15:32:58.818403995 +0200 -+++ openssh-7.3p1/servconf.c 2016-08-15 15:33:35.815990055 +0200 +--- openssh-7.3p1.orig/servconf.c 2016-12-13 11:17:13.454232377 +0100 ++++ openssh-7.3p1/servconf.c 2016-12-13 17:11:03.047678663 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1772,7 +1845,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -118,9 +119,11 @@ +@@ -119,9 +120,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1784,16 +1857,16 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->password_authentication = -1; -@@ -165,6 +168,8 @@ +@@ -166,6 +169,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; -+ options->disable_usage_stats = 0; ++ options->disable_usage_stats = 1; + options->usage_stats_targets = NULL; options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -211,6 +216,8 @@ +@@ -212,6 +217,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1802,7 +1875,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -297,13 +304,17 @@ +@@ -300,13 +307,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1823,7 +1896,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -431,7 +442,7 @@ +@@ -434,7 +445,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1832,7 +1905,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -453,10 +464,14 @@ +@@ -456,10 +467,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1847,7 +1920,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -482,8 +497,10 @@ +@@ -485,8 +500,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1858,7 +1931,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -529,7 +546,14 @@ +@@ -532,7 +549,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1873,7 +1946,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -537,7 +561,10 @@ +@@ -540,7 +564,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1884,7 +1957,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -605,6 +632,8 @@ +@@ -609,6 +636,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1893,7 +1966,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1068,6 +1097,10 @@ +@@ -1072,6 +1101,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1904,7 +1977,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1299,6 +1332,10 @@ +@@ -1303,6 +1336,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1915,7 +1988,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1307,6 +1344,10 @@ +@@ -1311,6 +1348,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1926,7 +1999,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1327,6 +1368,12 @@ +@@ -1331,6 +1372,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1939,7 +2012,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1797,6 +1844,35 @@ +@@ -1805,6 +1852,35 @@ *charptr = xstrdup(arg); break; @@ -1975,7 +2048,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2096,6 +2172,7 @@ +@@ -2104,6 +2180,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1984,9 +2057,9 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h ---- openssh-7.3p1.orig/servconf.h 2016-08-15 15:32:58.786404353 +0200 -+++ openssh-7.3p1/servconf.h 2016-08-15 15:33:35.815990055 +0200 -@@ -122,9 +122,12 @@ +--- openssh-7.3p1.orig/servconf.h 2016-12-13 11:17:13.431232636 +0100 ++++ openssh-7.3p1/servconf.h 2016-12-13 15:57:03.245159821 +0100 +@@ -124,9 +124,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -1999,7 +2072,7 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -181,6 +184,7 @@ +@@ -183,6 +186,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2007,7 +2080,7 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h int permit_tun; -@@ -189,6 +193,10 @@ +@@ -191,6 +195,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2019,8 +2092,8 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h char *trusted_user_ca_keys; char *authorized_keys_command; diff -Nur openssh-7.3p1.orig/ssh.1 openssh-7.3p1/ssh.1 ---- openssh-7.3p1.orig/ssh.1 2016-08-15 15:32:58.788404331 +0200 -+++ openssh-7.3p1/ssh.1 2016-08-15 15:33:35.816990044 +0200 +--- openssh-7.3p1.orig/ssh.1 2016-12-13 11:17:13.422232738 +0100 ++++ openssh-7.3p1/ssh.1 2016-12-13 15:57:03.245159821 +0100 @@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER @@ -2041,8 +2114,8 @@ diff -Nur openssh-7.3p1.orig/ssh.1 openssh-7.3p1/ssh.1 .Pp Additionally, diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c ---- openssh-7.3p1.orig/ssh.c 2016-08-15 15:32:58.810404085 +0200 -+++ openssh-7.3p1/ssh.c 2016-08-15 15:33:35.816990044 +0200 +--- openssh-7.3p1.orig/ssh.c 2016-12-13 11:17:13.466232242 +0100 ++++ openssh-7.3p1/ssh.c 2016-12-13 15:57:03.246159810 +0100 @@ -475,6 +475,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2076,7 +2149,7 @@ diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1191,8 +1217,12 @@ +@@ -1193,8 +1219,12 @@ logit("FIPS mode initialized"); } @@ -2091,8 +2164,8 @@ diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); diff -Nur openssh-7.3p1.orig/ssh_config openssh-7.3p1/ssh_config ---- openssh-7.3p1.orig/ssh_config 2016-08-15 15:32:58.727405013 +0200 -+++ openssh-7.3p1/ssh_config 2016-08-15 15:33:35.817990032 +0200 +--- openssh-7.3p1.orig/ssh_config 2016-12-13 11:17:13.362233414 +0100 ++++ openssh-7.3p1/ssh_config 2016-12-13 15:57:03.246159810 +0100 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2109,25 +2182,58 @@ diff -Nur openssh-7.3p1.orig/ssh_config openssh-7.3p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-7.3p1.orig/ssh_config.5 openssh-7.3p1/ssh_config.5 ---- openssh-7.3p1.orig/ssh_config.5 2016-08-15 15:32:58.778404443 +0200 -+++ openssh-7.3p1/ssh_config.5 2016-08-15 15:33:35.817990032 +0200 +--- openssh-7.3p1.orig/ssh_config.5 2016-12-13 11:17:13.410232873 +0100 ++++ openssh-7.3p1/ssh_config.5 2016-12-15 09:40:44.531257428 +0100 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config .It +GSSAPI configuration file -+.Pq Pa $HOME/.ssh/config.gssapi ++.Pq Pa ~/.ssh/config.gssapi +.It +Kerberos configuration file -+.Pq Pa $HOME/.ssh/config.krb ++.Pq Pa ~/.ssh/config.krb +.It system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El +@@ -825,12 +831,12 @@ + .It Cm GSSAPIAuthentication + Specifies whether user authentication based on GSSAPI is allowed. + The default is +-.Dq no . ++.Dq yes . + .It Cm GSSAPIKeyExchange + Specifies whether key exchange based on GSSAPI may be used. When using + GSSAPI key exchange the server need not have a host key. + The default is +-.Dq no . ++.Dq yes . + .It Cm GSSAPIClientIdentity + If set, specifies the GSSAPI client identity that ssh should use when + connecting to the server. The default is unset, which means that the default +@@ -843,7 +849,7 @@ + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is +-.Dq no . ++.Dq yes . + .It Cm GSSAPIRenewalForcesRekey + If set to + .Dq yes +@@ -870,7 +876,7 @@ + the hostname entered on the + command line will be passed untouched to the GSSAPI library. + The default is +-.Dq no . ++.Dq yes . + .It Cm GSSAPIKexAlgorithms + The list of key exchange algorithms that are offered for GSSAPI + key exchange. Possible values are diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c ---- openssh-7.3p1.orig/sshconnect2.c 2016-08-15 15:32:58.810404085 +0200 -+++ openssh-7.3p1/sshconnect2.c 2016-08-15 15:33:35.818990021 +0200 -@@ -722,6 +722,11 @@ +--- openssh-7.3p1.orig/sshconnect2.c 2016-12-13 11:17:13.465232253 +0100 ++++ openssh-7.3p1/sshconnect2.c 2016-12-13 23:17:35.567954069 +0100 +@@ -723,6 +723,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2139,23 +2245,27 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -959,6 +964,15 @@ +@@ -960,6 +965,19 @@ return 0; } +#ifdef GSI +extern +const gss_OID_desc * const gss_mech_globus_gssapi_openssl; ++const gss_OID_desc * const gss_mech_globus_gssapi_openssl_micv2; +#define is_gsi_oid(oid) \ -+ (oid->length == gss_mech_globus_gssapi_openssl->length && \ -+ (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \ -+ oid->length) == 0)) ++ ((oid->length == gss_mech_globus_gssapi_openssl->length && \ ++ (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \ ++ oid->length) == 0)) || \ ++ (oid->length == gss_mech_globus_gssapi_openssl_micv2->length && \ ++ (memcmp(oid->elements, gss_mech_globus_gssapi_openssl_micv2->elements, \ ++ oid->length) == 0))) +#endif + int userauth_gsskeyex(Authctxt *authctxt) { -@@ -976,8 +990,16 @@ +@@ -977,8 +995,16 @@ return (0); } @@ -2172,7 +2282,7 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -988,7 +1010,15 @@ +@@ -989,7 +1015,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2189,8 +2299,8 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-7.3p1.orig/sshd.8 openssh-7.3p1/sshd.8 ---- openssh-7.3p1.orig/sshd.8 2016-08-15 15:32:58.761404633 +0200 -+++ openssh-7.3p1/sshd.8 2016-08-15 15:33:35.818990021 +0200 +--- openssh-7.3p1.orig/sshd.8 2016-12-13 11:17:13.395233042 +0100 ++++ openssh-7.3p1/sshd.8 2016-12-13 15:57:03.248159788 +0100 @@ -795,6 +795,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2237,8 +2347,8 @@ diff -Nur openssh-7.3p1.orig/sshd.8 openssh-7.3p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c ---- openssh-7.3p1.orig/sshd.c 2016-08-15 15:32:58.820403973 +0200 -+++ openssh-7.3p1/sshd.c 2016-08-15 15:33:35.819990010 +0200 +--- openssh-7.3p1.orig/sshd.c 2016-12-13 11:17:13.466232242 +0100 ++++ openssh-7.3p1/sshd.c 2016-12-13 15:57:03.248159788 +0100 @@ -128,6 +128,7 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2247,7 +2357,7 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c #ifdef LIBWRAP #include -@@ -1885,6 +1886,13 @@ +@@ -1892,6 +1893,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2261,7 +2371,7 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2447,7 +2455,7 @@ +@@ -2455,7 +2463,7 @@ #endif #ifdef GSSAPI @@ -2271,8 +2381,8 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config ---- openssh-7.3p1.orig/sshd_config 2016-08-15 15:32:58.769404543 +0200 -+++ openssh-7.3p1/sshd_config 2016-08-15 15:33:35.819990010 +0200 +--- openssh-7.3p1.orig/sshd_config 2016-12-13 11:17:13.402232963 +0100 ++++ openssh-7.3p1/sshd_config 2016-12-15 10:55:00.889596292 +0100 @@ -89,10 +89,11 @@ #KerberosUseKuserok yes @@ -2298,20 +2408,24 @@ diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -152,3 +157,6 @@ - # AllowTcpForwarding no - # PermitTTY no - # ForceCommand cvs server -+ +@@ -146,6 +151,10 @@ + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + +# Usage Metrics +#UsageStatsTargets usage-stats.example.edu:4810 ++#DisableUsageStats yes ++ + # Example of overriding settings on a per-user basis + #Match User anoncvs + # X11Forwarding no diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 ---- openssh-7.3p1.orig/sshd_config.5 2016-08-15 15:32:58.788404331 +0200 -+++ openssh-7.3p1/sshd_config.5 2016-08-15 15:33:35.820989999 +0200 -@@ -594,6 +594,15 @@ - (Expose them to PAM and keep them in the shell environment). - The default is - .Dq never . +--- openssh-7.3p1.orig/sshd_config.5 2016-12-13 11:17:13.432232625 +0100 ++++ openssh-7.3p1/sshd_config.5 2016-12-15 09:52:24.308294018 +0100 +@@ -579,6 +579,15 @@ + See PATTERNS in + .Xr ssh_config 5 + for more information on patterns. +.It Cm DisableUsageStats +This keyword can be followed by one of the keywords "true", "enabled", "yes", +"on" or "1" to disable reporting of usage metrics. Or it can be set to "false", @@ -2321,13 +2435,15 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 +Disabling reporting of usage metrics will cause the +.Cm UsageStatsTargets +setting to be ignored. - .It Cm FingerprintHash - Specifies the hash algorithm used when logging key fingerprints. - Valid options are: -@@ -647,6 +656,10 @@ + .It Cm ExposeAuthenticationMethods + When using SSH2, this option controls the exposure of the list of + successful authentication methods to PAM during the authentication +@@ -646,17 +655,36 @@ + .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is - .Dq no . +-.Dq no . ++.Dq yes . +.It Cm GSSAPIDelegateCredentials +Specifies whether delegated credentials are stored in the user's environment. +The default is @@ -2335,10 +2451,14 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 .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. -@@ -663,6 +676,22 @@ - .Xr ksu 1 . The default is - .Dq no . +-.Dq no . ++.Dq yes . + .It Cm GSSAPICleanupCredentials + Specifies whether to automatically destroy the user's credentials cache + on logout. + The default is + .Dq yes . +.It Cm GSSAPICredentialsPath +If specified, the delegated GSSAPI credential is stored in the +given path, overwriting any existing credentials. @@ -2351,17 +2471,16 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 +the same user. +Currently only implemented for the GSI mechanism. +.It Cm GSIAllowLimitedProxy -+Specifies whether to accept limited proxy credentials for -+authentication. ++Specifies whether to accept limited proxy credentials for authentication. +The default is +.Dq no . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. -@@ -1579,6 +1608,103 @@ - .Pp - To disable TCP keepalive messages, the value should be set to - .Dq no . + .It Cm GSSAPIEnablek5users + Specifies whether to look at .k5users file for GSSAPI authentication + access control. Further details are described in +@@ -1596,6 +1624,103 @@ + .Cm TrustedUserCAKeys . + For more details on certificates, see the CERTIFICATES section in + .Xr ssh-keygen 1 . +.It Cm UsageStatsTargets +This option can be used to specify the target collector hosts to which usage +metrics should be reported. This setting will be ignored if @@ -2459,10 +2578,10 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 +.Cm UsageStatsTargets +is specified. +.Pp - .It Cm TrustedUserCAKeys - Specifies a file containing public keys of certificate authorities that are - trusted to sign user certificates for authentication, or -@@ -1655,6 +1781,12 @@ + .It Cm UseDNS + Specifies whether + .Xr sshd 8 +@@ -1656,6 +1781,12 @@ as a non-root user. The default is .Dq no . @@ -2477,7 +2596,7 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 .Xr sshd 8 diff -Nur openssh-7.3p1.orig/ssh-globus-usage.c openssh-7.3p1/ssh-globus-usage.c --- openssh-7.3p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/ssh-globus-usage.c 2016-08-15 15:33:35.821989988 +0200 ++++ openssh-7.3p1/ssh-globus-usage.c 2016-12-13 15:57:03.250159766 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2877,7 +2996,7 @@ diff -Nur openssh-7.3p1.orig/ssh-globus-usage.c openssh-7.3p1/ssh-globus-usage.c +} diff -Nur openssh-7.3p1.orig/ssh-globus-usage.h openssh-7.3p1/ssh-globus-usage.h --- openssh-7.3p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/ssh-globus-usage.h 2016-08-15 15:33:35.821989988 +0200 ++++ openssh-7.3p1/ssh-globus-usage.h 2016-12-13 15:57:03.250159766 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2928,8 +3047,8 @@ diff -Nur openssh-7.3p1.orig/ssh-globus-usage.h openssh-7.3p1/ssh-globus-usage.h + +#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-7.3p1.orig/ssh-gss.h openssh-7.3p1/ssh-gss.h ---- openssh-7.3p1.orig/ssh-gss.h 2016-08-15 15:32:58.788404331 +0200 -+++ openssh-7.3p1/ssh-gss.h 2016-08-15 15:33:35.821989988 +0200 +--- openssh-7.3p1.orig/ssh-gss.h 2016-12-13 11:17:13.423232726 +0100 ++++ openssh-7.3p1/ssh-gss.h 2016-12-13 15:57:03.250159766 +0100 @@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -2976,7 +3095,7 @@ diff -Nur openssh-7.3p1.orig/ssh-gss.h openssh-7.3p1/ssh-gss.h #endif /* _SSH_GSS_H */ diff -Nur openssh-7.3p1.orig/version.h openssh-7.3p1/version.h --- openssh-7.3p1.orig/version.h 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/version.h 2016-08-15 15:39:50.075808639 +0200 ++++ openssh-7.3p1/version.h 2016-12-13 17:08:57.017089717 +0100 @@ -1,6 +1,21 @@ /* $OpenBSD: version.h,v 1.77 2016/07/24 11:45:36 djm Exp $ */ @@ -2992,7 +3111,7 @@ diff -Nur openssh-7.3p1.orig/version.h openssh-7.3p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20150812" ++#define NCSA_VERSION " GSI_GSSAPI_20161122" + #define SSH_VERSION "OpenSSH_7.3" From 6995654e64f6d1a7c5a155608c34493618933499 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 24 Jan 2017 16:42:47 +0100 Subject: [PATCH 036/146] Based on openssh-7.4p1-1 --- gsi-openssh.spec | 18 +- openssh-4.3p2-askpass-grab-info.patch | 13 +- openssh-5.1p1-askpass-progress.patch | 24 +- openssh-6.2p1-vendor.patch | 91 +- openssh-6.6.1p1-log-in-chroot.patch | 130 +-- openssh-6.6p1-GSSAPIEnablek5users.patch | 76 +- openssh-6.6p1-ctr-cavstest.patch | 6 +- openssh-6.6p1-entropy.patch | 253 +++-- openssh-6.6p1-kuserok.patch | 78 +- openssh-6.6p1-privsep-selinux.patch | 82 +- openssh-6.6p1-redhat.patch | 101 +- openssh-6.6p1-role-mls.patch | 500 +++++----- openssh-6.7p1-coverity.patch | 174 +--- ...sh-6.7p1-debian-restore-tcp-wrappers.patch | 36 +- openssh-6.8p1-memory-problems.patch | 13 +- openssh-7.0p1-gssKexAlgorithms.patch | 13 +- openssh-7.0p1-show-more-fingerprints.patch | 200 ++-- openssh-7.1p1-gssapi-documentation.patch | 21 +- openssh-7.1p2-audit-race-condition.patch | 98 +- openssh-7.2p1-audit.patch | 516 ++++------ openssh-7.2p1-fips.patch | 272 ++---- openssh-7.2p1-gsskex.patch | 526 +++++----- openssh-7.2p2-UsePAM-UseLogin-warning.patch | 15 +- openssh-7.2p2-expose-pam.patch | 184 ++-- openssh-7.3p1-null-deref.patch | 48 - openssh-7.3p1-openssl-1.1.0.patch | 905 +++++------------- openssh-7.3p1-x11-max-displays.patch | 80 +- openssh-7.4p1-daemon.patch | 12 + ...gsissh.patch => openssh-7.4p1-gsissh.patch | 544 ++++++----- openssh-7.4p1-pkcs11-whitelist.patch | 24 + sources | 2 +- 31 files changed, 2118 insertions(+), 2937 deletions(-) delete mode 100644 openssh-7.3p1-null-deref.patch create mode 100644 openssh-7.4p1-daemon.patch rename openssh-7.3p1-gsissh.patch => openssh-7.4p1-gsissh.patch (88%) create mode 100644 openssh-7.4p1-pkcs11-whitelist.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f923eca..022714e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.3p1 -%global openssh_rel 5 +%global openssh_ver 7.4p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -165,14 +165,16 @@ Patch939: openssh-7.2p2-s390-closefrom.patch Patch940: openssh-7.2p2-expose-pam.patch # Rework SELinux context handling with chroot (#1357860) Patch942: openssh-7.2p2-chroot-capabilities.patch -# Null dereference in newkeys code (#1380297) -Patch943: openssh-7.3p1-null-deref.patch # Move MAX_DISPLAYS to a configuration option (#1341302) Patch944: openssh-7.3p1-x11-max-displays.patch +# Temporary workaround for upstream (#2641) +Patch945: openssh-7.4p1-daemon.patch +# Whitelist /usr/lib*/ as planed upstream to prevent breakage +Patch946: openssh-7.4p1-pkcs11-whitelist.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch -Patch98: openssh-7.3p1-gsissh.patch +Patch98: openssh-7.4p1-gsissh.patch License: BSD Group: Applications/Internet @@ -324,8 +326,9 @@ This version of OpenSSH has been modified to support GSI authentication. %patch939 -p1 -b .s390-dev %patch940 -p1 -b .expose-pam %patch942 -p1 -b .chroot-cap -%patch943 -p1 -b .deref %patch944 -p1 -b .x11max +%patch945 -p1 -b .daemon +%patch946 -p1 -b .pkcs11-whitelist %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -542,6 +545,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Jan 24 2017 Mattias Ellert - 7.4p1-1 +- Based on openssh-7.4p1-1 + * Tue Dec 13 2016 Mattias Ellert - 7.3p1-5 - Adding mechanism OID negotiation with the introduction of micv2 OID diff --git a/openssh-4.3p2-askpass-grab-info.patch b/openssh-4.3p2-askpass-grab-info.patch index e9dc835..e9a0b0d 100644 --- a/openssh-4.3p2-askpass-grab-info.patch +++ b/openssh-4.3p2-askpass-grab-info.patch @@ -1,7 +1,8 @@ ---- openssh-4.3p2/contrib/gnome-ssh-askpass2.c.grab-info 2006-07-17 15:10:11.000000000 +0200 -+++ openssh-4.3p2/contrib/gnome-ssh-askpass2.c 2006-07-17 15:25:04.000000000 +0200 -@@ -65,9 +65,12 @@ - err = gtk_message_dialog_new(NULL, 0, +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. " @@ -14,5 +15,5 @@ + "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_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), - TRUE); + + gtk_dialog_run(GTK_DIALOG(err)); diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index ec93b87..6601fbf 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -1,6 +1,6 @@ -diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contrib/gnome-ssh-askpass2.c ---- openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress 2008-07-23 19:05:26.000000000 +0200 -+++ openssh-5.1p1/contrib/gnome-ssh-askpass2.c 2008-07-23 19:05:26.000000000 +0200 +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 #include @@ -9,7 +9,7 @@ diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contr #include #include -@@ -83,13 +84,24 @@ ok_dialog(GtkWidget *entry, gpointer dia +@@ -81,13 +82,24 @@ ok_dialog(GtkWidget *entry, gpointer dia gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); } @@ -30,12 +30,12 @@ diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contr const char *failed; char *passphrase, *local; int result, grab_tries, grab_server, grab_pointer; -- GtkWidget *dialog, *entry; -+ GtkWidget *dialog, *entry, *progress, *hbox; +- GtkWidget *parent_window, *dialog, *entry; ++ GtkWidget *parent_window, *dialog, *entry, *progress, *hbox; GdkGrabStatus status; grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); -@@ -102,13 +114,31 @@ passphrase_dialog(char *message) +@@ -104,14 +116,32 @@ passphrase_dialog(char *message) "%s", message); @@ -45,9 +45,11 @@ diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contr + gtk_widget_show(hbox); + entry = gtk_entry_new(); -- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, -+ gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, - FALSE, 0); + 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); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); @@ -68,7 +70,7 @@ diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contr gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); -@@ -119,6 +149,8 @@ passphrase_dialog(char *message) +@@ -120,6 +150,8 @@ passphrase_dialog(char *message) gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(ok_dialog), dialog); diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index 55353c2..2d946eb 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.0p1/configure.ac.vendor openssh-7.0p1/configure.ac ---- openssh-7.0p1/configure.ac.vendor 2015-08-12 11:14:54.102628399 +0200 -+++ openssh-7.0p1/configure.ac 2015-08-12 11:14:54.129628356 +0200 -@@ -4776,6 +4776,12 @@ AC_ARG_WITH([lastlog], +diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.vendor 2016-12-23 13:34:51.681253844 +0100 ++++ openssh-7.4p1/configure.ac 2016-12-23 13:34:51.694253847 +0100 +@@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog], fi ] ) @@ -14,7 +14,7 @@ diff -up openssh-7.0p1/configure.ac.vendor openssh-7.0p1/configure.ac dnl lastlog, [uw]tmpx? detection dnl NOTE: set the paths in the platform section to avoid the -@@ -5038,6 +5044,7 @@ echo " Translate v4 in v6 hack +@@ -5194,6 +5200,7 @@ echo " Translate v4 in v6 hack echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -22,10 +22,10 @@ diff -up openssh-7.0p1/configure.ac.vendor openssh-7.0p1/configure.ac echo "" -diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.vendor 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 11:15:33.201565712 +0200 -@@ -149,6 +149,7 @@ initialize_server_options(ServerOptions +diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.vendor 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 13:36:07.555268628 +0100 +@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; @@ -33,7 +33,7 @@ diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; -@@ -335,6 +336,8 @@ fill_default_server_options(ServerOption +@@ -325,6 +326,8 @@ fill_default_server_options(ServerOption options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); @@ -42,8 +42,8 @@ diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) -@@ -407,7 +410,7 @@ typedef enum { - sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, +@@ -402,7 +405,7 @@ typedef enum { + sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, - sBanner, sUseDNS, sHostbasedAuthentication, @@ -51,7 +51,7 @@ diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, -@@ -529,6 +532,7 @@ static struct { +@@ -528,6 +531,7 @@ static struct { { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, @@ -59,7 +59,7 @@ diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1389,6 +1393,10 @@ process_server_config_line(ServerOptions +@@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions multistate_ptr = multistate_privsep; goto parse_multistate; @@ -70,18 +70,18 @@ diff -up openssh-7.0p1/servconf.c.vendor openssh-7.0p1/servconf.c case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -2266,6 +2274,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseLogin, o->use_login); +@@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); + dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); -diff -up openssh-7.0p1/servconf.h.vendor openssh-7.0p1/servconf.h ---- openssh-7.0p1/servconf.h.vendor 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-12 11:14:54.130628355 +0200 -@@ -155,6 +155,7 @@ typedef struct { +diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.vendor 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/servconf.h 2016-12-23 13:34:51.694253847 +0100 +@@ -149,6 +149,7 @@ typedef struct { int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ @@ -89,12 +89,12 @@ diff -up openssh-7.0p1/servconf.h.vendor openssh-7.0p1/servconf.h int use_dns; int client_alive_interval; /* * poke the client this often to -diff -up openssh-7.0p1/sshd_config.0.vendor openssh-7.0p1/sshd_config.0 ---- openssh-7.0p1/sshd_config.0.vendor 2015-08-12 11:14:54.125628363 +0200 -+++ openssh-7.0p1/sshd_config.0 2015-08-12 11:14:54.130628355 +0200 -@@ -841,6 +841,11 @@ DESCRIPTION - Defines the number of bits in the ephemeral protocol version 1 - server key. The default and minimum value is 1024. +diff -up openssh-7.4p1/sshd_config.0.vendor openssh-7.4p1/sshd_config.0 +--- openssh-7.4p1/sshd_config.0.vendor 2016-12-23 13:34:51.695253847 +0100 ++++ openssh-7.4p1/sshd_config.0 2016-12-23 13:36:53.146277511 +0100 +@@ -792,6 +792,11 @@ DESCRIPTION + ssh-keygen(1). For more information on KRLs, see the KEY + REVOCATION LISTS section in ssh-keygen(1). + ShowPatchLevel + Specifies whether sshd will display the specific patch level of @@ -104,13 +104,13 @@ diff -up openssh-7.0p1/sshd_config.0.vendor openssh-7.0p1/sshd_config.0 StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. -diff -up openssh-7.0p1/sshd_config.5.vendor openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1/sshd_config.5.vendor 2015-08-12 11:14:54.125628363 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-12 11:14:54.131628353 +0200 -@@ -1411,6 +1411,13 @@ This option applies to protocol version - .It Cm ServerKeyBits - Defines the number of bits in the ephemeral protocol version 1 server key. - The default and minimum value is 1024. +diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100 +@@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as + .Xr ssh-keygen 1 . + For more information on KRLs, see the KEY REVOCATION LISTS section in + .Xr ssh-keygen 1 . +.It Cm ShowPatchLevel +Specifies whether +.Nm sshd @@ -121,10 +121,10 @@ diff -up openssh-7.0p1/sshd_config.5.vendor openssh-7.0p1/sshd_config.5 .It Cm StreamLocalBindMask Sets the octal file creation mode mask .Pq umask -diff -up openssh-7.0p1/sshd_config.vendor openssh-7.0p1/sshd_config ---- openssh-7.0p1/sshd_config.vendor 2015-08-12 11:14:54.125628363 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-12 11:14:54.131628353 +0200 -@@ -119,6 +119,7 @@ UsePrivilegeSeparation sandbox # Defaul +diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.vendor 2016-12-23 13:34:51.690253846 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 13:34:51.695253847 +0100 +@@ -105,6 +105,7 @@ X11Forwarding yes #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 @@ -132,19 +132,20 @@ diff -up openssh-7.0p1/sshd_config.vendor openssh-7.0p1/sshd_config #UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 -diff -up openssh-7.0p1/sshd.c.vendor openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.vendor 2015-08-12 11:14:54.100628403 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-12 11:14:54.131628353 +0200 -@@ -432,7 +432,7 @@ sshd_exchange_identification(int sock_in - } +diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.vendor 2016-12-23 13:34:51.682253844 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 13:38:32.434296856 +0100 +@@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh + char remote_version[256]; /* Must be at least as big as buf. */ xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", -- major, minor, SSH_VERSION, -+ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, +- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, ++ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, *options.version_addendum == '\0' ? "" : " ", options.version_addendum, newline); -@@ -1749,7 +1749,8 @@ main(int ac, char **av) +@@ -1650,7 +1651,8 @@ main(int ac, char **av) exit(1); } diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 46d8382..f36d83f 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.8p1/log.c.log-in-chroot openssh-6.8p1/log.c ---- openssh-6.8p1/log.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/log.c 2015-03-18 12:59:29.694022313 +0100 -@@ -241,6 +241,11 @@ debug3(const char *fmt,...) +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) { @@ -13,7 +13,7 @@ diff -up openssh-6.8p1/log.c.log-in-chroot openssh-6.8p1/log.c #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif -@@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, Sysl +@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl exit(1); } @@ -26,9 +26,9 @@ diff -up openssh-6.8p1/log.c.log-in-chroot openssh-6.8p1/log.c log_on_stderr = on_stderr; if (on_stderr) -diff -up openssh-6.8p1/log.h.log-in-chroot openssh-6.8p1/log.h ---- openssh-6.8p1/log.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/log.h 2015-03-18 12:59:29.694022313 +0100 +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 *); @@ -37,10 +37,10 @@ diff -up openssh-6.8p1/log.h.log-in-chroot openssh-6.8p1/log.h void log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); -diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c ---- openssh-6.8p1/monitor.c.log-in-chroot 2015-03-18 12:59:29.669022374 +0100 -+++ openssh-6.8p1/monitor.c 2015-03-18 13:01:52.894671198 +0100 -@@ -357,6 +357,8 @@ monitor_child_preauth(Authctxt *_authctx +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; @@ -49,7 +49,7 @@ diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); -@@ -465,6 +467,8 @@ monitor_child_postauth(struct monitor *p +@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; @@ -58,7 +58,7 @@ diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c monitor_set_child_handler(pmonitor->m_pid); signal(SIGHUP, &monitor_child_handler); signal(SIGTERM, &monitor_child_handler); -@@ -566,7 +570,7 @@ monitor_read_log(struct monitor *pmonito +@@ -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); @@ -67,9 +67,9 @@ diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c buffer_free(&logmsg); free(msg); -@@ -1998,13 +2002,28 @@ monitor_init(void) - (ssh_packet_comp_free_func *)mm_zfree); - } +@@ -1719,13 +1723,28 @@ monitor_init(void) + mon = xcalloc(1, sizeof(*mon)); + monitor_openfds(mon, 1); + mon->m_state = ""; + @@ -98,11 +98,11 @@ diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c } #ifdef GSSAPI -diff -up openssh-6.8p1/monitor.h.log-in-chroot openssh-6.8p1/monitor.h ---- openssh-6.8p1/monitor.h.log-in-chroot 2015-03-18 12:59:29.695022310 +0100 -+++ openssh-6.8p1/monitor.h 2015-03-18 13:02:56.926514197 +0100 +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 { - struct mm_master *m_zlib; + int m_log_sendfd; struct kex **m_pkex; pid_t m_pid; + char *m_state; @@ -111,13 +111,13 @@ diff -up openssh-6.8p1/monitor.h.log-in-chroot openssh-6.8p1/monitor.h struct monitor *monitor_init(void); -void monitor_reinit(struct monitor *); +void monitor_reinit(struct monitor *, const char *); - void monitor_sync(struct monitor *); struct Authctxt; -diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c ---- openssh-6.8p1/session.c.log-in-chroot 2015-03-18 12:59:29.675022359 +0100 -+++ openssh-6.8p1/session.c 2015-03-18 12:59:29.696022308 +0100 -@@ -161,6 +161,7 @@ login_cap_t *lc; + void monitor_child_preauth(struct Authctxt *, 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; @@ -125,7 +125,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; -@@ -506,8 +508,8 @@ do_exec_no_pty(Session *s, const char *c +@@ -365,8 +366,8 @@ do_exec_no_pty(Session *s, const char *c is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ @@ -136,7 +136,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c /* * Create a new session and process group since the 4.4BSD -@@ -675,8 +677,8 @@ do_exec_pty(Session *s, const char *comm +@@ -523,8 +524,8 @@ do_exec_pty(Session *s, const char *comm close(ptymaster); /* Child. Reinitialize the log because the pid has changed. */ @@ -147,7 +147,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c /* Close the master side of the pseudo tty. */ close(ptyfd); -@@ -780,6 +782,7 @@ do_exec(Session *s, const char *command) +@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -155,7 +155,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c if (options.adm_forced_command) { original_command = command; -@@ -837,6 +840,10 @@ do_exec(Session *s, const char *command) +@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) tty += 5; } @@ -166,7 +166,7 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1678,14 +1685,6 @@ child_close_fds(void) +@@ -1486,14 +1492,6 @@ child_close_fds(void) * descriptors left by system functions. They will be closed later. */ endpwent(); @@ -181,16 +181,16 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c } /* -@@ -1831,8 +1830,6 @@ do_child(Session *s, const char *command +@@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command exit(1); } - closefrom(STDERR_FILENO + 1); - - if (!options.use_login) - do_rc_files(s, shell); + do_rc_files(s, shell); -@@ -1856,9 +1853,17 @@ do_child(Session *s, const char *command + /* restore SIGPIPE for child */ +@@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -208,21 +208,21 @@ diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c + fflush(NULL); - if (options.use_login) { -diff -up openssh-6.8p1/sftp-server-main.c.log-in-chroot openssh-6.8p1/sftp-server-main.c ---- openssh-6.8p1/sftp-server-main.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sftp-server-main.c 2015-03-18 12:59:29.696022308 +0100 -@@ -47,5 +47,5 @@ main(int argc, char **argv) - return 1; - } + /* 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 @@ -- return (sftp_server_main(argc, argv, user_pw)); -+ return (sftp_server_main(argc, argv, user_pw, 0)); - } -diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c ---- openssh-6.8p1/sftp-server.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sftp-server.c 2015-03-18 13:03:52.510377911 +0100 -@@ -1502,7 +1502,7 @@ sftp_server_usage(void) + struct passwd; + +-int sftp_server_main(int, char **, struct passwd *); ++int sftp_server_main(int, char **, struct passwd *, int); + void sftp_server_cleanup_exit(int) __attribute__((noreturn)); +diff -up openssh-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 @@ -231,7 +231,7 @@ diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c { fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; -@@ -1515,7 +1515,7 @@ sftp_server_main(int argc, char **argv, +@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); @@ -240,7 +240,7 @@ diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c pw = pwcopy(user_pw); -@@ -1586,7 +1586,7 @@ sftp_server_main(int argc, char **argv, +@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, } } @@ -249,20 +249,20 @@ diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c /* * On platforms where we can, avoid making /proc/self/{mem,maps} -diff -up openssh-6.8p1/sftp.h.log-in-chroot openssh-6.8p1/sftp.h ---- openssh-6.8p1/sftp.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sftp.h 2015-03-18 12:59:29.696022308 +0100 -@@ -97,5 +97,5 @@ +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; + } - 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-6.8p1/sshd.c.log-in-chroot openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.log-in-chroot 2015-03-18 12:59:29.691022320 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 12:59:29.697022305 +0100 -@@ -744,7 +744,7 @@ privsep_postauth(Authctxt *authctxt) +- 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 */ @@ -271,7 +271,7 @@ diff -up openssh-6.8p1/sshd.c.log-in-chroot openssh-6.8p1/sshd.c pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -762,6 +762,11 @@ privsep_postauth(Authctxt *authctxt) +@@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 16333c3..069b36d 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.0p1/gss-serv-krb5.c ---- openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users 2015-08-12 11:27:44.022407951 +0200 -+++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:27:44.047407912 +0200 -@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +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[BUFSIZ] = ""; @@ -9,7 +9,7 @@ diff -up openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.0p1/gss-ser struct stat st; struct passwd *pw = the_authctxt->pw; int found_principal = 0; -@@ -269,7 +268,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +@@ -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. */ @@ -18,27 +18,27 @@ diff -up openssh-7.0p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.0p1/gss-ser return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.GSSAPIEnablek5users 2015-08-12 11:27:44.036407930 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 11:28:49.087306430 +0200 -@@ -173,6 +173,7 @@ initialize_server_options(ServerOptions - options->version_addendum = NULL; +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->fingerprint_hash = -1; + options->disable_forwarding = -1; options->use_kuserok = -1; + options->enable_k5users = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -351,6 +352,8 @@ fill_default_server_options(ServerOption - options->fwd_opts.streamlocal_bind_unlink = 0; - if (options->fingerprint_hash == -1) - options->fingerprint_hash = SSH_FP_HASH_DEFAULT; -+ if (options->enable_k5users == -1) -+ options->enable_k5users = 0; +@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption + options->disable_forwarding = 0; if (options->use_kuserok == -1) options->use_kuserok = 1; ++ if (options->enable_k5users == -1) ++ options->enable_k5users = 0; -@@ -423,7 +426,7 @@ typedef enum { + assemble_algorithms(options); + +@@ -418,7 +421,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -47,7 +47,7 @@ diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -502,12 +505,14 @@ static struct { +@@ -497,12 +500,14 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, @@ -62,7 +62,7 @@ diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1680,6 +1685,10 @@ process_server_config_line(ServerOptions +@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions intptr = &options->use_kuserok; goto parse_flag; @@ -73,7 +73,7 @@ diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -2035,6 +2044,7 @@ copy_set_server_options(ServerOptions *d +@@ -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); @@ -81,7 +81,7 @@ diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2317,6 +2327,7 @@ dump_config(ServerOptions *o) +@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -89,10 +89,10 @@ diff -up openssh-7.0p1/servconf.c.GSSAPIEnablek5users openssh-7.0p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-7.0p1/servconf.h.GSSAPIEnablek5users openssh-7.0p1/servconf.h ---- openssh-7.0p1/servconf.h.GSSAPIEnablek5users 2015-08-12 11:27:44.022407951 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-12 11:27:44.048407911 +0200 -@@ -180,7 +180,8 @@ typedef struct { +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,7 +174,8 @@ typedef struct { int num_permitted_opens; @@ -102,26 +102,26 @@ diff -up openssh-7.0p1/servconf.h.GSSAPIEnablek5users openssh-7.0p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1/sshd_config.5.GSSAPIEnablek5users 2015-08-12 11:27:44.023407950 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-12 11:27:44.048407911 +0200 -@@ -633,6 +633,12 @@ on logout. +diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100 +@@ -628,6 +628,12 @@ Specifies whether to automatically destr on logout. The default is - .Dq yes . + .Cm yes . +.It Cm GSSAPIEnablek5users +Specifies whether to look at .k5users file for GSSAPI authentication +access control. Further details are described in +.Xr ksu 1 . +The default is -+.Dq no . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. -diff -up openssh-7.0p1/sshd_config.GSSAPIEnablek5users openssh-7.0p1/sshd_config ---- openssh-7.0p1/sshd_config.GSSAPIEnablek5users 2015-08-12 11:27:44.023407950 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-12 11:27:44.048407911 +0200 -@@ -94,6 +94,7 @@ GSSAPIAuthentication yes ++.Cm no . + .It Cm GSSAPIKeyExchange + Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange + doesn't rely on ssh keys to verify host identity. +diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 15:18:40.631216103 +0100 +@@ -80,6 +80,7 @@ GSSAPIAuthentication yes GSSAPICleanupCredentials no #GSSAPIStrictAcceptorCheck yes #GSSAPIKeyExchange no diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 9383a98..eb43c79 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -142,7 +142,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c +{ + + const struct sshcipher *c; -+ struct sshcipher_ctx cc; ++ struct sshcipher_ctx *cc; + char *algo = "aes128-ctr"; + char *hexkey = NULL; + char *hexiv = "00000000000000000000000000000000"; @@ -232,11 +232,11 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + return 2; + } + -+ cipher_crypt(&cc, 0, outdata, data, datalen, 0, 0); ++ cipher_crypt(cc, 0, outdata, data, datalen, 0, 0); + + free(data); + -+ cipher_cleanup(&cc); ++ cipher_free(cc); + + for (p = outdata; datalen > 0; ++p, --datalen) { + printf("%02X", (unsigned char)*p); diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index b023ddc..db8ce54 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -1,8 +1,7 @@ -diff --git a/entropy.c b/entropy.c -index 1e9d52a..d24e724 100644 ---- a/entropy.c -+++ b/entropy.c -@@ -227,6 +227,9 @@ seed_rng(void) +diff -up openssh-7.4p1/entropy.c.entropy openssh-7.4p1/entropy.c +--- openssh-7.4p1/entropy.c.entropy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/entropy.c 2016-12-23 18:34:27.769753570 +0100 +@@ -229,6 +229,9 @@ seed_rng(void) memset(buf, '\0', sizeof(buf)); #endif /* OPENSSL_PRNG_ONLY */ @@ -12,24 +11,31 @@ index 1e9d52a..d24e724 100644 if (RAND_status() != 1) fatal("PRNG is not seeded"); } -diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in -index 843225d..041bbab 100644 ---- a/openbsd-compat/Makefile.in -+++ b/openbsd-compat/Makefile.in -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di +diff -up openssh-7.4p1/openbsd-compat/Makefile.in.entropy openssh-7.4p1/openbsd-compat/Makefile.in +--- openssh-7.4p1/openbsd-compat/Makefile.in.entropy 2016-12-23 18:34:53.715762155 +0100 ++++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 18:35:15.890769493 +0100 +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff --git a/openbsd-compat/port-linux-prng.c b/openbsd-compat/port-linux-prng.c -new file mode 100644 -index 0000000..da84bf2 ---- /dev/null -+++ b/openbsd-compat/port-linux-prng.c +diff -up openssh-7.4p1/openbsd-compat/port-linux.h.entropy openssh-7.4p1/openbsd-compat/port-linux.h +--- openssh-7.4p1/openbsd-compat/port-linux.h.entropy 2016-12-23 18:34:27.747753563 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 18:34:27.769753570 +0100 +@@ -34,4 +34,6 @@ void oom_adjust_restore(void); + void oom_adjust_setup(void); + #endif + ++void linux_seed(void); ++ + #endif /* ! _PORT_LINUX_H */ +diff -up openssh-7.4p1/openbsd-compat/port-linux-prng.c.entropy openssh-7.4p1/openbsd-compat/port-linux-prng.c +--- openssh-7.4p1/openbsd-compat/port-linux-prng.c.entropy 2016-12-23 18:34:27.769753570 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux-prng.c 2016-12-23 18:34:27.769753570 +0100 @@ -0,0 +1,59 @@ +/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ + @@ -90,11 +96,37 @@ index 0000000..da84bf2 + fatal ("EOF reading %s", random); + } +} -diff --git a/ssh-add.0 b/ssh-add.0 -index f16165a..17d22cf 100644 ---- a/ssh-add.0 -+++ b/ssh-add.0 -@@ -82,6 +82,16 @@ ENVIRONMENT +diff -up openssh-7.4p1/ssh.1.entropy openssh-7.4p1/ssh.1 +--- openssh-7.4p1/ssh.1.entropy 2016-12-23 18:34:27.754753565 +0100 ++++ openssh-7.4p1/ssh.1 2016-12-23 18:34:27.770753571 +0100 +@@ -1441,6 +1441,23 @@ For more information, see the + .Cm PermitUserEnvironment + option in + .Xr sshd_config 5 . ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.It Ev SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 14 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh FILES + .Bl -tag -width Ds -compact + .It Pa ~/.rhosts +diff -up openssh-7.4p1/ssh-add.0.entropy openssh-7.4p1/ssh-add.0 +--- openssh-7.4p1/ssh-add.0.entropy 2016-12-19 06:21:21.000000000 +0100 ++++ openssh-7.4p1/ssh-add.0 2016-12-23 18:34:27.770753571 +0100 +@@ -88,6 +88,16 @@ ENVIRONMENT Identifies the path of a UNIX-domain socket used to communicate with the agent. @@ -111,11 +143,10 @@ index f16165a..17d22cf 100644 FILES ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of -diff --git a/ssh-add.1 b/ssh-add.1 -index 04d1840..db883a4 100644 ---- a/ssh-add.1 -+++ b/ssh-add.1 -@@ -170,6 +170,20 @@ to make this work.) +diff -up openssh-7.4p1/ssh-add.1.entropy openssh-7.4p1/ssh-add.1 +--- openssh-7.4p1/ssh-add.1.entropy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-add.1 2016-12-23 18:34:27.770753571 +0100 +@@ -171,6 +171,20 @@ to make this work.) Identifies the path of a .Ux Ns -domain socket used to communicate with the agent. @@ -136,11 +167,10 @@ index 04d1840..db883a4 100644 .El .Sh FILES .Bl -tag -width Ds -diff --git a/ssh-agent.1 b/ssh-agent.1 -index d7e791b..7332f0d 100644 ---- a/ssh-agent.1 -+++ b/ssh-agent.1 -@@ -189,6 +189,24 @@ sockets used to contain the connection to the authentication agent. +diff -up openssh-7.4p1/ssh-agent.1.entropy openssh-7.4p1/ssh-agent.1 +--- openssh-7.4p1/ssh-agent.1.entropy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-agent.1 2016-12-23 18:34:27.770753571 +0100 +@@ -214,6 +214,24 @@ sockets used to contain the connection t These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El @@ -165,97 +195,10 @@ index d7e791b..7332f0d 100644 .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , -diff --git a/ssh-keygen.1 b/ssh-keygen.1 -index 276dacc..a09d9b1 100644 ---- a/ssh-keygen.1 -+++ b/ssh-keygen.1 -@@ -841,6 +841,24 @@ Contains Diffie-Hellman groups used for DH-GEX. - The file format is described in - .Xr moduli 5 . - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff --git a/ssh-keysign.8 b/ssh-keysign.8 -index 69d0829..02d79f8 100644 ---- a/ssh-keysign.8 -+++ b/ssh-keysign.8 -@@ -80,6 +80,24 @@ must be set-uid root if host-based authentication is used. - If these files exist they are assumed to contain public certificate - information corresponding with the private keys above. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-keygen 1 , -diff --git a/ssh.1 b/ssh.1 -index 4a476c2..410a04a 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -1299,6 +1299,23 @@ For more information, see the - .Cm PermitUserEnvironment - option in - .Xr sshd_config 5 . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh FILES - .Bl -tag -width Ds -compact - .It Pa ~/.rhosts -diff --git a/sshd.8 b/sshd.8 -index cb866b5..adcaaf9 100644 ---- a/sshd.8 -+++ b/sshd.8 -@@ -945,6 +945,24 @@ concurrently for different ports, this contains the process ID of the one +diff -up openssh-7.4p1/sshd.8.entropy openssh-7.4p1/sshd.8 +--- openssh-7.4p1/sshd.8.entropy 2016-12-23 18:34:27.755753566 +0100 ++++ openssh-7.4p1/sshd.8 2016-12-23 18:34:27.770753571 +0100 +@@ -920,6 +920,24 @@ concurrently for different ports, this c started last). The content of this file is not sensitive; it can be world-readable. .El @@ -280,13 +223,59 @@ index cb866b5..adcaaf9 100644 .Sh IPV6 IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. .Sh SEE ALSO -diff -up openssh-6.8p1/openbsd-compat/port-linux.h.coverity openssh-6.8p1/openbsd-compat/port-linux.h ---- openssh-6.8p1/openbsd-compat/port-linux.h.coverity 2015-03-18 17:21:51.861264906 +0100 -+++ openssh-6.8p1/openbsd-compat/port-linux.h 2015-03-18 17:21:51.897264831 +0100 -@@ -37,4 +37,6 @@ void oom_adjust_restore(void); - void oom_adjust_setup(void); - #endif - -+void linux_seed(void); -+ - #endif /* ! _PORT_LINUX_H */ +diff -up openssh-7.4p1/ssh-keygen.1.entropy openssh-7.4p1/ssh-keygen.1 +--- openssh-7.4p1/ssh-keygen.1.entropy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-keygen.1 2016-12-23 18:34:27.770753571 +0100 +@@ -848,6 +848,24 @@ Contains Diffie-Hellman groups used for + The file format is described in + .Xr moduli 5 . + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 14 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh SEE ALSO + .Xr ssh 1 , + .Xr ssh-add 1 , +diff -up openssh-7.4p1/ssh-keysign.8.entropy openssh-7.4p1/ssh-keysign.8 +--- openssh-7.4p1/ssh-keysign.8.entropy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-keysign.8 2016-12-23 18:34:27.770753571 +0100 +@@ -80,6 +80,24 @@ must be set-uid root if host-based authe + If these files exist they are assumed to contain public certificate + information corresponding with the private keys above. + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 14 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh SEE ALSO + .Xr ssh 1 , + .Xr ssh-keygen 1 , diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 192b9c3..1af0fa4 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.0p1/auth-krb5.c.kuserok openssh-7.0p1/auth-krb5.c ---- openssh-7.0p1/auth-krb5.c.kuserok 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/auth-krb5.c 2015-08-12 11:26:21.874536127 +0200 -@@ -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; @@ -23,7 +23,7 @@ diff -up openssh-7.0p1/auth-krb5.c.kuserok openssh-7.0p1/auth-krb5.c static int krb5_init(void *context) { -@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c if (problem) goto out; @@ -35,9 +35,9 @@ diff -up openssh-7.0p1/auth-krb5.c.kuserok openssh-7.0p1/auth-krb5.c problem = -1; goto out; } -diff -up openssh-7.0p1/gss-serv-krb5.c.kuserok openssh-7.0p1/gss-serv-krb5.c ---- openssh-7.0p1/gss-serv-krb5.c.kuserok 2015-08-12 11:26:21.868536137 +0200 -+++ openssh-7.0p1/gss-serv-krb5.c 2015-08-12 11:26:21.875536126 +0200 +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); @@ -160,7 +160,7 @@ diff -up openssh-7.0p1/gss-serv-krb5.c.kuserok openssh-7.0p1/gss-serv-krb5.c retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); -@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +@@ -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)) { @@ -172,28 +172,28 @@ diff -up openssh-7.0p1/gss-serv-krb5.c.kuserok openssh-7.0p1/gss-serv-krb5.c } if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; -diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.kuserok 2015-08-12 11:26:21.865536141 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 11:27:14.126454598 +0200 -@@ -172,6 +172,7 @@ initialize_server_options(ServerOptions - options->ip_qos_bulk = -1; +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 +@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions options->version_addendum = NULL; options->fingerprint_hash = -1; + options->disable_forwarding = -1; + options->use_kuserok = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -350,6 +351,8 @@ fill_default_server_options(ServerOption - options->fwd_opts.streamlocal_bind_unlink = 0; - if (options->fingerprint_hash == -1) +@@ -342,6 +343,8 @@ fill_default_server_options(ServerOption options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->disable_forwarding == -1) + options->disable_forwarding = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; assemble_algorithms(options); -@@ -404,7 +407,7 @@ typedef enum { - sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, +@@ -399,7 +402,7 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, @@ -201,7 +201,7 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, -@@ -483,11 +486,13 @@ static struct { +@@ -478,11 +481,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -215,7 +215,7 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1671,6 +1676,10 @@ process_server_config_line(ServerOptions +@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions *activep = value; break; @@ -226,15 +226,15 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') -@@ -2023,6 +2032,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); +@@ -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); + M_CP_INTOPT(use_kuserok); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); -@@ -2304,6 +2314,7 @@ dump_config(ServerOptions *o) +@@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); @@ -242,10 +242,10 @@ diff -up openssh-7.0p1/servconf.c.kuserok openssh-7.0p1/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-7.0p1/servconf.h.kuserok openssh-7.0p1/servconf.h ---- openssh-7.0p1/servconf.h.kuserok 2015-08-12 11:26:21.865536141 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-12 11:26:21.876536124 +0200 -@@ -180,6 +180,7 @@ typedef struct { +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 +@@ -174,6 +174,7 @@ typedef struct { int num_permitted_opens; @@ -253,21 +253,21 @@ diff -up openssh-7.0p1/servconf.h.kuserok openssh-7.0p1/servconf.h char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; -diff -up openssh-7.0p1/sshd_config.5.kuserok openssh-7.0p1/sshd_config.5 ---- openssh-7.0p1/sshd_config.5.kuserok 2015-08-12 11:26:21.867536138 +0200 -+++ openssh-7.0p1/sshd_config.5 2015-08-12 11:26:21.877536123 +0200 -@@ -872,6 +872,10 @@ Specifies whether to automatically destr +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 file on logout. The default is - .Dq yes . + .Cm yes . +.It Cm KerberosUseKuserok +Specifies whether to look at .k5login file for user's aliases. +The default is -+.Dq yes . ++.Cm yes . .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. -@@ -1116,6 +1120,7 @@ Available keywords are +@@ -1078,6 +1082,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -275,10 +275,10 @@ diff -up openssh-7.0p1/sshd_config.5.kuserok openssh-7.0p1/sshd_config.5 .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , -diff -up openssh-7.0p1/sshd_config.kuserok openssh-7.0p1/sshd_config ---- openssh-7.0p1/sshd_config.kuserok 2015-08-12 11:26:21.867536138 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-12 11:26:21.876536124 +0200 -@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no +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 diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 3433fd6..6933b39 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -1,8 +1,18 @@ -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index c18524e..d04f4ed 100644 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c -@@ -409,6 +409,28 @@ sshd_selinux_setup_exec_context(char *pwname) +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__); } @@ -31,23 +41,19 @@ index c18524e..d04f4ed 100644 #endif #endif -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 8ef6cc4..b18893c 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -25,6 +25,7 @@ void ssh_selinux_setup_pty(char *, const char *); - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); +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) -+void sshd_selinux_copy_context(void); - void sshd_selinux_setup_exec_context(char *); - #endif + platform_setusercontext(pw); -diff --git a/session.c b/session.c -index 2bcf818..b5dc144 100644 ---- a/session.c -+++ b/session.c -@@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *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) pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); @@ -57,7 +63,7 @@ index 2bcf818..b5dc144 100644 safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); -@@ -1565,6 +1568,11 @@ do_setusercontext(struct passwd *pw) +@@ -1396,6 +1399,11 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -69,7 +75,7 @@ index 2bcf818..b5dc144 100644 } else if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { fatal("server lacks privileges to chroot to ChrootDirectory"); -@@ -1588,9 +1588,6 @@ do_pwchange(Session *s) +@@ -1413,9 +1421,6 @@ do_pwchange(Session *s) if (s->ttyfd != -1) { fprintf(stderr, "You must change your password now and login again!\n"); @@ -79,7 +85,7 @@ index 2bcf818..b5dc144 100644 #ifdef PASSWD_NEEDS_USERNAME execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name, (char *)NULL); -@@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command) +@@ -1625,9 +1630,6 @@ do_child(Session *s, const char *command argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -89,11 +95,10 @@ index 2bcf818..b5dc144 100644 exit(sftp_server_main(i, argv, s->pw)); } -diff --git a/sshd.c b/sshd.c -index 07f9926..a97f8b7 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -632,6 +632,10 @@ privsep_preauth_child(void) +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(); @@ -104,26 +109,13 @@ index 07f9926..a97f8b7 100644 /* Demote the child */ if (getuid() == 0 || geteuid() == 0) { /* Change our root directory */ -@@ -755,6 +755,9 @@ privsep_postauth(Authctxt *authctxt) - +@@ -633,6 +637,9 @@ privsep_postauth(Authctxt *authctxt) + { #ifdef DISABLE_FD_PASSING if (1) { +#elif defined(WITH_SELINUX) -+ if (options.use_login) { ++ if (0) { + /* even root user can be confined by SELinux */ #else - if (authctxt->pw->pw_uid == 0 || options.use_login) { + if (authctxt->pw->pw_uid == 0) { #endif -diff --git a/session.c b/session.c -index 684f867..09048bc 100644 ---- a/session.c -+++ b/session.c -@@ -1538,7 +1538,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) { diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index de6216d..b23f47e 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -1,8 +1,7 @@ -diff --git a/ssh_config b/ssh_config -index 49a4f6c..3f83c40 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -46,3 +46,7 @@ +diff -up openssh-7.4p1/ssh_config.redhat openssh-7.4p1/ssh_config +--- openssh-7.4p1/ssh_config.redhat 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh_config 2016-12-23 13:32:00.045220402 +0100 +@@ -48,3 +48,7 @@ # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h @@ -10,9 +9,9 @@ index 49a4f6c..3f83c40 100644 +# To modify the system-wide ssh configuration, create a *.conf file under +# /etc/ssh/ssh_config.d/ which will be automatically included below +Include /etc/ssh/ssh_config.d/*.conf -diff --git a/ssh_config_redhat b/ssh_config_redhat ---- /dev/null -+++ b/ssh_config_redhat +diff -up openssh-7.4p1/ssh_config_redhat.redhat openssh-7.4p1/ssh_config_redhat +--- openssh-7.4p1/ssh_config_redhat.redhat 2016-12-23 13:32:00.045220402 +0100 ++++ openssh-7.4p1/ssh_config_redhat 2016-12-23 13:32:00.045220402 +0100 @@ -0,0 +1,20 @@ +# Follow system-wide Crypto Poliicy, if defined: +Include /etc/crypto-policies/back-ends/openssh.txt @@ -34,11 +33,38 @@ diff --git a/ssh_config_redhat b/ssh_config_redhat + SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT + SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE + SendEnv XMODIFIERS -diff --git a/sshd_config b/sshd_config -index c735429..e68ddee 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -10,6 +10,10 @@ +diff -up openssh-7.4p1/sshd_config.0.redhat openssh-7.4p1/sshd_config.0 +--- openssh-7.4p1/sshd_config.0.redhat 2016-12-19 06:21:22.000000000 +0100 ++++ openssh-7.4p1/sshd_config.0 2016-12-23 13:32:00.045220402 +0100 +@@ -837,9 +837,9 @@ DESCRIPTION + + SyslogFacility + Gives the facility code that is used when logging messages from +- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, +- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The +- default is AUTH. ++ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, ++ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. ++ The default is AUTH. + + TCPKeepAlive + Specifies whether the system should send TCP keepalive messages +diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.redhat 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 13:32:00.046220403 +0100 +@@ -1393,7 +1393,7 @@ By default no subsystems are defined. + .It Cm SyslogFacility + Gives the facility code that is used when logging messages from + .Xr sshd 8 . +-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, ++The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, + LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. + The default is AUTH. + .It Cm TCPKeepAlive +diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.redhat 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 13:33:05.386233133 +0100 +@@ -10,21 +10,26 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -49,10 +75,8 @@ index c735429..e68ddee 100644 #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -21,10 +25,10 @@ - # HostKey for protocol version 1 - #HostKey /etc/ssh/ssh_host_key - # HostKeys for protocol version 2 + #ListenAddress :: + -#HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key @@ -61,9 +85,8 @@ index c735429..e68ddee 100644 +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key - # Lifetime and size of ephemeral version 1 server key - #KeyRegenerationInterval 1h -@@ -36,6 +40,7 @@ + # Ciphers and keying + #RekeyLimit default none # Logging #SyslogFacility AUTH @@ -71,7 +94,7 @@ index c735429..e68ddee 100644 #LogLevel INFO # Authentication: -@@ -71,9 +76,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -57,9 +62,11 @@ AuthorizedKeysFile .ssh/authorized_keys # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no @@ -83,7 +106,7 @@ index c735429..e68ddee 100644 # Kerberos options #KerberosAuthentication no -@@ -82,8 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -68,8 +75,8 @@ AuthorizedKeysFile .ssh/authorized_keys #KerberosGetAFSToken no # GSSAPI options @@ -94,7 +117,7 @@ index c735429..e68ddee 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will -@@ -94,12 +101,12 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -80,12 +87,12 @@ 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 ChallengeResponseAuthentication to 'no'. @@ -109,7 +132,7 @@ index c735429..e68ddee 100644 #X11DisplayOffset 10 #X11UseLocalhost yes #PermitTTY yes -@@ -122,6 +129,12 @@ UsePrivilegeSeparation sandbox # Default for new installations. +@@ -108,6 +115,12 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none @@ -122,33 +145,3 @@ index c735429..e68ddee 100644 # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server -diff --git a/sshd_config.0 b/sshd_config.0 -index 413c260..87e7ee7 100644 ---- a/sshd_config.0 -+++ b/sshd_config.0 -@@ -675,9 +675,9 @@ DESCRIPTION - - SyslogFacility - Gives the facility code that is used when logging messages from -- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, -- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The -- default is AUTH. -+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, -+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. -+ The default is AUTH. - - TCPKeepAlive - Specifies whether the system should send TCP keepalive messages -diff --git a/sshd_config.5 b/sshd_config.5 -index ce71efe..12465c2 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1131,7 +1131,7 @@ Note that this option applies to protocol version 2 only. - .It Cm SyslogFacility - Gives the facility code that is used when logging messages from - .Xr sshd 8 . --The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, -+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, - LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. - The default is AUTH. - .It Cm TCPKeepAlive diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index 76e6721..f2bfa5a 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -1,157 +1,6 @@ -diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c ---- openssh/auth-pam.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth-pam.c 2016-07-26 12:37:48.793593333 +0200 -@@ -1095,7 +1095,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; - #ifdef HAVE_PAM_PUTENV -diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h ---- openssh/auth-pam.h.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth-pam.h 2016-07-26 12:37:48.793593333 +0200 -@@ -38,7 +38,7 @@ void do_pam_session(void); - void do_pam_set_tty(const char *); - 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/auth.h.role-mls openssh/auth.h ---- openssh/auth.h.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth.h 2016-07-26 12:37:48.793593333 +0200 -@@ -62,6 +62,9 @@ struct Authctxt { - char *service; - struct passwd *pw; /* set if 'valid' */ - char *style; -+#ifdef WITH_SELINUX -+ char *role; -+#endif - void *kbdintctxt; - char *info; /* Extra info for next auth_log */ - #ifdef BSD_AUTH -diff -up openssh/auth1.c.role-mls openssh/auth1.c ---- openssh/auth1.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth1.c 2016-07-26 12:37:48.793593333 +0200 -@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) - { - u_int ulen; - char *user, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role=NULL; -+#endif - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(SSH_CMSG_USER); -@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) - user = packet_get_cstring(&ulen); - packet_check_eom(); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = '\0'; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = '\0'; -+#ifdef WITH_SELINUX -+ else -+ if (role && (style = strchr(role, ':')) != NULL) -+ *style++ = '\0'; -+#endif - - authctxt->user = user; - authctxt->style = style; -+#ifdef WITH_SELINUX -+ authctxt->role = role; -+#endif - - /* Verify that the user is a valid user. */ - if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c ---- openssh/auth2-gss.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth2-gss.c 2016-07-26 12:37:48.794593332 +0200 -@@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - int authenticated = 0; -+ char *micuser; - Buffer b; - gss_buffer_desc mic, gssbuf; - u_int len; -@@ -267,7 +268,13 @@ input_gssapi_mic(int type, u_int32_t ple - mic.value = packet_get_string(&len); - mic.length = len; - -- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, -+#ifdef WITH_SELINUX -+ if (authctxt->role && (strlen(authctxt->role) > 0)) -+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); -+ else -+#endif -+ micuser = authctxt->user; -+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, - "gssapi-with-mic"); - - gssbuf.value = buffer_ptr(&b); -@@ -279,6 +286,8 @@ input_gssapi_mic(int type, u_int32_t ple - logit("GSSAPI MIC check failed"); - - buffer_free(&b); -+ if (micuser != authctxt->user) -+ free(micuser); - free(mic.value); - - authctxt->postponed = 0; -diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth2-hostbased.c 2016-07-26 12:37:48.794593332 +0200 -@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); -diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth2-pubkey.c 2016-07-26 12:37:48.794593332 +0200 -@@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) - } - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- xasprintf(&userstyle, "%s%s%s", authctxt->user, -+ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, - authctxt->style ? ":" : "", -- authctxt->style ? authctxt->style : ""); -+ authctxt->style ? authctxt->style : "", -+#ifdef WITH_SELINUX -+ authctxt->role ? "/" : "", -+ authctxt->role ? authctxt->role : ""); -+#else -+ "", ""); -+#endif - buffer_put_cstring(&b, userstyle); - free(userstyle); - buffer_put_cstring(&b, -diff -up openssh/auth2.c.role-mls openssh/auth2.c ---- openssh/auth2.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/auth2.c 2016-07-26 12:37:48.794593332 +0200 +diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c +--- openssh-7.4p1/auth2.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth2.c 2016-12-23 12:19:58.587459379 +0100 @@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ctxt; Authmethod *m = NULL; @@ -191,9 +40,122 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); -diff -up openssh/misc.c.role-mls openssh/misc.c ---- openssh/misc.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/misc.c 2016-07-26 12:37:48.794593332 +0200 +diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c +--- openssh-7.4p1/auth2-gss.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth2-gss.c 2016-12-23 12:19:58.586459382 +0100 +@@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated = 0; ++ char *micuser; + Buffer b; + gss_buffer_desc mic, gssbuf; + u_int len; +@@ -267,7 +268,13 @@ input_gssapi_mic(int type, u_int32_t ple + mic.value = packet_get_string(&len); + mic.length = len; + +- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, ++#ifdef WITH_SELINUX ++ if (authctxt->role && (strlen(authctxt->role) > 0)) ++ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); ++ else ++#endif ++ micuser = authctxt->user; ++ ssh_gssapi_buildmic(&b, micuser, authctxt->service, + "gssapi-with-mic"); + + gssbuf.value = buffer_ptr(&b); +@@ -279,6 +286,8 @@ input_gssapi_mic(int type, u_int32_t ple + logit("GSSAPI MIC check failed"); + + buffer_free(&b); ++ if (micuser != authctxt->user) ++ free(micuser); + free(mic.value); + + authctxt->postponed = 0; +diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased.c +--- openssh-7.4p1/auth2-hostbased.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 12:19:58.586459382 +0100 +@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) + buffer_put_string(&b, session_id2, session_id2_len); + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- buffer_put_cstring(&b, authctxt->user); ++#ifdef WITH_SELINUX ++ if (authctxt->role) { ++ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); ++ buffer_append(&b, authctxt->user, strlen(authctxt->user)); ++ buffer_put_char(&b, '/'); ++ buffer_append(&b, authctxt->role, strlen(authctxt->role)); ++ } else ++#endif ++ buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "hostbased"); + buffer_put_string(&b, pkalg, alen); +diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c +--- openssh-7.4p1/auth2-pubkey.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 12:19:58.587459379 +0100 +@@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- xasprintf(&userstyle, "%s%s%s", authctxt->user, ++ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, + authctxt->style ? ":" : "", +- authctxt->style ? authctxt->style : ""); ++ authctxt->style ? authctxt->style : "", ++#ifdef WITH_SELINUX ++ authctxt->role ? "/" : "", ++ authctxt->role ? authctxt->role : ""); ++#else ++ "", ""); ++#endif + buffer_put_cstring(&b, userstyle); + free(userstyle); + buffer_put_cstring(&b, +diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h +--- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth.h 2016-12-23 12:19:43.478510375 +0100 +@@ -62,6 +62,9 @@ struct Authctxt { + char *service; + struct passwd *pw; /* set if 'valid' */ + char *style; ++#ifdef WITH_SELINUX ++ char *role; ++#endif + void *kbdintctxt; + char *info; /* Extra info for next auth_log */ + #ifdef BSD_AUTH +diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c +--- openssh-7.4p1/auth-pam.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth-pam.c 2016-12-23 12:19:43.477510378 +0100 +@@ -1087,7 +1087,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; + #ifdef HAVE_PAM_PUTENV +diff -up openssh-7.4p1/auth-pam.h.role-mls openssh-7.4p1/auth-pam.h +--- openssh-7.4p1/auth-pam.h.role-mls 2016-12-23 12:19:43.478510375 +0100 ++++ openssh-7.4p1/auth-pam.h 2016-12-23 12:21:44.698101234 +0100 +@@ -31,7 +31,7 @@ u_int do_pam_account(void); + void do_pam_session(void); + 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-7.4p1/misc.c.role-mls openssh-7.4p1/misc.c +--- openssh-7.4p1/misc.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/misc.c 2016-12-23 12:19:58.587459379 +0100 @@ -432,6 +432,7 @@ char * colon(char *cp) { @@ -216,10 +178,10 @@ diff -up openssh/misc.c.role-mls openssh/misc.c } return NULL; } -diff -up openssh/monitor.c.role-mls openssh/monitor.c ---- openssh/monitor.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/monitor.c 2016-07-26 12:44:19.363379490 +0200 -@@ -128,6 +128,9 @@ int mm_answer_sign(int, Buffer *); +diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/monitor.c 2016-12-23 12:23:03.503835248 +0100 +@@ -127,6 +127,9 @@ int mm_answer_sign(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); @@ -229,7 +191,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(int, Buffer *); int mm_answer_bsdauthquery(int, Buffer *); int mm_answer_bsdauthrespond(int, Buffer *); -@@ -207,6 +210,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -202,6 +205,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}, @@ -239,17 +201,17 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -863,6 +869,9 @@ mm_answer_pwnamallow(int sock, Buffer *m - else { - /* Allow service/style information on the auth context */ - monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); +@@ -769,6 +775,9 @@ mm_answer_pwnamallow(int sock, Buffer *m + + /* Allow service/style information on the auth context */ + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); +#ifdef WITH_SELINUX -+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); +#endif - monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); - } + monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); + #ifdef USE_PAM -@@ -904,6 +913,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -810,6 +819,25 @@ mm_answer_authserv(int sock, Buffer *m) return (0); } @@ -275,7 +237,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(int sock, Buffer *m) { -@@ -1300,7 +1328,7 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1208,7 +1236,7 @@ monitor_valid_userblob(u_char *data, u_i { Buffer b; u_char *p; @@ -284,16 +246,16 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c u_int len; int fail = 0; -@@ -1326,6 +1354,8 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1234,6 +1262,8 @@ monitor_valid_userblob(u_char *data, u_i if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; cp = buffer_get_cstring(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) ++ if ((r = strchr(cp, '/')) != NULL) + *r = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1361,7 +1391,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1269,7 +1299,7 @@ monitor_valid_hostbasedblob(u_char *data char *chost) { Buffer b; @@ -302,7 +264,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c u_int len; int fail = 0; -@@ -1378,6 +1408,8 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1286,6 +1316,8 @@ monitor_valid_hostbasedblob(u_char *data if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); @@ -311,9 +273,9 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh/monitor.h.role-mls openssh/monitor.h ---- openssh/monitor.h.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/monitor.h 2016-07-26 12:37:48.795593331 +0200 +diff -up openssh-7.4p1/monitor.h.role-mls openssh-7.4p1/monitor.h +--- openssh-7.4p1/monitor.h.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/monitor.h 2016-12-23 12:19:58.588459376 +0100 @@ -57,6 +57,10 @@ enum monitor_reqtype { MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, @@ -325,10 +287,10 @@ diff -up openssh/monitor.h.role-mls openssh/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/monitor_wrap.c 2016-07-26 12:37:48.795593331 +0200 -@@ -346,6 +346,25 @@ mm_inform_authserv(char *service, char * +diff -up openssh-7.4p1/monitor_wrap.c.role-mls openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2016-12-23 12:19:58.588459376 +0100 +@@ -345,6 +345,25 @@ mm_inform_authserv(char *service, char * buffer_free(&m); } @@ -354,9 +316,9 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c /* Do the password authentication */ int mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/monitor_wrap.h 2016-07-26 12:37:48.795593331 +0200 +diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 @@ -42,6 +42,9 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); @@ -367,21 +329,90 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct Authctxt *, char *); -diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in ---- openssh/openbsd-compat/Makefile.in.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/openbsd-compat/Makefile.in 2016-07-26 12:37:48.795593331 +0200 +diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd-compat/Makefile.in +--- openssh-7.4p1/openbsd-compat/Makefile.in.role-mls 2016-12-23 12:19:58.588459376 +0100 ++++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 12:24:06.042643938 +0100 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -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 2016-07-26 12:37:48.796593331 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2016-07-26 12:37:48.796593331 +0200 +diff -up openssh-7.4p1/openbsd-compat/port-linux.c.role-mls openssh-7.4p1/openbsd-compat/port-linux.c +--- openssh-7.4p1/openbsd-compat/port-linux.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.c 2016-12-23 12:19:58.590459369 +0100 +@@ -101,37 +101,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-7.4p1/openbsd-compat/port-linux.h.role-mls openssh-7.4p1/openbsd-compat/port-linux.h +--- openssh-7.4p1/openbsd-compat/port-linux.h.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 12:19:58.591459365 +0100 +@@ -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-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-7.4p1/openbsd-compat/port-linux-sshd.c +--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls 2016-12-23 12:19:58.590459369 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2016-12-23 12:19:58.590459369 +0100 @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2005 Daniel Walsh @@ -807,79 +838,10 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa +#endif +#endif + -diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c ---- openssh/openbsd-compat/port-linux.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.c 2016-07-26 12:37:48.796593331 +0200 -@@ -103,37 +103,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) -@@ -147,7 +116,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 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.h 2016-07-26 12:37:48.796593331 +0200 -@@ -22,9 +22,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/platform.c.role-mls openssh/platform.c ---- openssh/platform.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/platform.c 2016-07-26 12:37:48.796593331 +0200 -@@ -186,7 +186,7 @@ platform_setusercontext_post_groups(stru +diff -up openssh-7.4p1/platform.c.role-mls openssh-7.4p1/platform.c +--- openssh-7.4p1/platform.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/platform.c 2016-12-23 12:19:58.591459365 +0100 +@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -888,10 +850,10 @@ diff -up openssh/platform.c.role-mls openssh/platform.c #endif } -diff -up openssh/sshd.c.role-mls openssh/sshd.c ---- openssh/sshd.c.role-mls 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/sshd.c 2016-07-26 12:37:48.796593331 +0200 -@@ -2295,6 +2295,9 @@ main(int ac, char **av) +diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.role-mls 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 12:19:58.591459365 +0100 +@@ -2053,6 +2053,9 @@ main(int ac, char **av) restore_uid(); } #endif diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 143ebad..5b12ddd 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,22 +1,7 @@ -diff -up openssh-6.8p1/channels.c.coverity openssh-6.8p1/channels.c ---- openssh-6.8p1/channels.c.coverity 2015-03-18 17:21:51.815265002 +0100 -+++ openssh-6.8p1/channels.c 2015-03-18 17:21:51.896264833 +0100 -@@ -243,11 +243,11 @@ channel_register_fds(Channel *c, int rfd - channel_max_fd = MAX(channel_max_fd, wfd); - channel_max_fd = MAX(channel_max_fd, efd); - -- if (rfd != -1) -+ if (rfd >= 0) - fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -+ if (wfd >= 0 && wfd != rfd) - fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -+ if (efd >= 0 && efd != rfd && efd != wfd) - fcntl(efd, F_SETFD, FD_CLOEXEC); - - c->rfd = rfd; -@@ -265,11 +265,11 @@ channel_register_fds(Channel *c, int rfd +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) { @@ -31,10 +16,10 @@ diff -up openssh-6.8p1/channels.c.coverity openssh-6.8p1/channels.c set_nonblock(efd); } } -diff -up openssh-6.8p1/monitor.c.coverity openssh-6.8p1/monitor.c ---- openssh-6.8p1/monitor.c.coverity 2015-03-18 17:21:51.887264852 +0100 -+++ openssh-6.8p1/monitor.c 2015-03-18 17:21:51.897264831 +0100 -@@ -444,7 +444,7 @@ monitor_child_preauth(Authctxt *_authctx +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(pmonitor); /* Drain any buffered messages from the child */ @@ -43,10 +28,10 @@ diff -up openssh-6.8p1/monitor.c.coverity openssh-6.8p1/monitor.c ; close(pmonitor->m_sendfd); -diff -up openssh-6.8p1/monitor_wrap.c.coverity openssh-6.8p1/monitor_wrap.c ---- openssh-6.8p1/monitor_wrap.c.coverity 2015-03-18 17:21:51.888264849 +0100 -+++ openssh-6.8p1/monitor_wrap.c 2015-03-18 17:21:51.897264831 +0100 -@@ -533,10 +533,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, +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__); @@ -60,9 +45,9 @@ diff -up openssh-6.8p1/monitor_wrap.c.coverity openssh-6.8p1/monitor_wrap.c return 0; } close(tmp1); -diff -up openssh-6.8p1/openbsd-compat/bindresvport.c.coverity openssh-6.8p1/openbsd-compat/bindresvport.c ---- openssh-6.8p1/openbsd-compat/bindresvport.c.coverity 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/openbsd-compat/bindresvport.c 2015-03-18 17:21:51.897264831 +0100 +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; @@ -72,10 +57,10 @@ diff -up openssh-6.8p1/openbsd-compat/bindresvport.c.coverity openssh-6.8p1/open int i; if (sa == NULL) { -diff -up openssh-6.8p1/scp.c.coverity openssh-6.8p1/scp.c ---- openssh-6.8p1/scp.c.coverity 2015-03-18 17:21:51.868264891 +0100 -+++ openssh-6.8p1/scp.c 2015-03-18 17:21:58.281251460 +0100 -@@ -156,7 +156,7 @@ killchild(int signo) +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); @@ -84,10 +69,10 @@ diff -up openssh-6.8p1/scp.c.coverity openssh-6.8p1/scp.c } if (signo) -diff -up openssh-6.8p1/servconf.c.coverity openssh-6.8p1/servconf.c ---- openssh-6.8p1/servconf.c.coverity 2015-03-18 17:21:51.893264839 +0100 -+++ openssh-6.8p1/servconf.c 2015-03-18 17:21:58.281251460 +0100 -@@ -1475,7 +1475,7 @@ process_server_config_line(ServerOptions +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) { @@ -96,7 +81,7 @@ diff -up openssh-6.8p1/servconf.c.coverity openssh-6.8p1/servconf.c break; } for (i = 0; i < options->num_subsystems; i++) -@@ -1566,8 +1566,9 @@ process_server_config_line(ServerOptions +@@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ @@ -108,10 +93,10 @@ diff -up openssh-6.8p1/servconf.c.coverity openssh-6.8p1/servconf.c } break; -diff -up openssh-6.8p1/serverloop.c.coverity openssh-6.8p1/serverloop.c ---- openssh-6.8p1/serverloop.c.coverity 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/serverloop.c 2015-03-18 17:28:45.616436080 +0100 -@@ -147,13 +147,13 @@ notify_setup(void) +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) { @@ -127,7 +112,7 @@ diff -up openssh-6.8p1/serverloop.c.coverity openssh-6.8p1/serverloop.c FD_SET(notify_pipe[0], readset); } static void -@@ -161,8 +161,8 @@ notify_done(fd_set *readset) +@@ -139,8 +139,8 @@ notify_done(fd_set *readset) { char c; @@ -138,80 +123,7 @@ diff -up openssh-6.8p1/serverloop.c.coverity openssh-6.8p1/serverloop.c debug2("notify_done: reading"); } -@@ -337,7 +337,7 @@ wait_until_can_do_something(fd_set **rea - * If we have buffered data, try to write some of that data - * to the program. - */ -- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) -+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, *writesetp); - } - notify_prepare(*readsetp); -@@ -477,7 +477,7 @@ process_output(fd_set *writeset) - int len; - - /* Write buffered data to program stdin. */ -- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { -+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { - data = buffer_ptr(&stdin_buffer); - dlen = buffer_len(&stdin_buffer); - len = write(fdin, data, dlen); -@@ -590,7 +590,7 @@ server_loop(pid_t pid, int fdin_arg, int - set_nonblock(fdin); - set_nonblock(fdout); - /* we don't have stderr for interactive terminal sessions, see below */ -- if (fderr != -1) -+ if (fderr >= 0) - set_nonblock(fderr); - - if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) -@@ -614,7 +614,7 @@ server_loop(pid_t pid, int fdin_arg, int - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); -- if (fderr != -1) -+ if (fderr >= 0) - max_fd = MAX(max_fd, fderr); - #endif - -@@ -644,7 +644,7 @@ server_loop(pid_t pid, int fdin_arg, int - * If we have received eof, and there is no more pending - * input data, cause a real eof by closing fdin. - */ -- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { -+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { - if (fdin != fdout) - close(fdin); - else -@@ -740,15 +740,15 @@ server_loop(pid_t pid, int fdin_arg, int - buffer_free(&stderr_buffer); - - /* Close the file descriptors. */ -- if (fdout != -1) -+ if (fdout >= 0) - close(fdout); - fdout = -1; - fdout_eof = 1; -- if (fderr != -1) -+ if (fderr >= 0) - close(fderr); - fderr = -1; - fderr_eof = 1; -- if (fdin != -1) -+ if (fdin >= 0) - close(fdin); - fdin = -1; - -@@ -950,7 +950,7 @@ server_input_window_size(int type, u_int - - debug("Window change received."); - packet_check_eom(); -- if (fdin != -1) -+ if (fdin >= 0) - pty_change_window_size(fdin, row, col, xpixel, ypixel); - return 0; - } -@@ -1043,7 +1043,7 @@ server_request_tun(void) +@@ -518,7 +518,7 @@ server_request_tun(void) } tun = packet_get_int(); @@ -220,10 +132,10 @@ diff -up openssh-6.8p1/serverloop.c.coverity openssh-6.8p1/serverloop.c if (tun != SSH_TUNID_ANY && forced_tun_device != tun) goto done; tun = forced_tun_device; -diff -up openssh-6.8p1/sftp.c.coverity openssh-6.8p1/sftp.c ---- openssh-6.8p1/sftp.c.coverity 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/sftp.c 2015-03-18 17:21:58.283251456 +0100 -@@ -223,7 +223,7 @@ killchild(int signo) +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) { if (sshpid > 1) { kill(sshpid, SIGTERM); @@ -232,10 +144,10 @@ diff -up openssh-6.8p1/sftp.c.coverity openssh-6.8p1/sftp.c } _exit(1); -diff -up openssh-6.8p1/ssh-agent.c.coverity openssh-6.8p1/ssh-agent.c ---- openssh-6.8p1/ssh-agent.c.coverity 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/ssh-agent.c 2015-03-18 17:21:58.284251454 +0100 -@@ -1166,8 +1166,8 @@ main(int ac, char **av) +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 */ @@ -246,10 +158,10 @@ diff -up openssh-6.8p1/ssh-agent.c.coverity openssh-6.8p1/ssh-agent.c platform_disable_tracing(0); /* strict=no */ -diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c ---- openssh-6.8p1/sshd.c.coverity 2015-03-18 17:21:51.893264839 +0100 -+++ openssh-6.8p1/sshd.c 2015-03-18 17:21:58.284251454 +0100 -@@ -778,8 +778,10 @@ privsep_preauth(Authctxt *authctxt) +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(); setproctitle("%s", "[net]"); @@ -261,7 +173,7 @@ diff -up openssh-6.8p1/sshd.c.coverity openssh-6.8p1/sshd.c return 0; } -@@ -1518,6 +1520,9 @@ server_accept_loop(int *sock_in, int *so +@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so if (num_listen_socks < 0) break; } diff --git a/openssh-6.7p1-debian-restore-tcp-wrappers.patch b/openssh-6.7p1-debian-restore-tcp-wrappers.patch index a41cf34..5fcc451 100644 --- a/openssh-6.7p1-debian-restore-tcp-wrappers.patch +++ b/openssh-6.7p1-debian-restore-tcp-wrappers.patch @@ -1,7 +1,7 @@ -diff -up openssh/configure.ac.tcp_wrappers openssh/configure.ac ---- openssh/configure.ac.tcp_wrappers 2015-06-24 11:41:04.519293694 +0200 -+++ openssh/configure.ac 2015-06-24 11:41:04.556293600 +0200 -@@ -1448,6 +1448,62 @@ AC_ARG_WITH([skey], +diff -up openssh-7.4p1/configure.ac.tcp_wrappers openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.tcp_wrappers 2016-12-23 15:36:38.745411192 +0100 ++++ openssh-7.4p1/configure.ac 2016-12-23 15:36:38.777411197 +0100 +@@ -1491,6 +1491,62 @@ AC_ARG_WITH([skey], ] ) @@ -64,7 +64,7 @@ diff -up openssh/configure.ac.tcp_wrappers openssh/configure.ac # Check whether user wants to use ldns LDNS_MSG="no" AC_ARG_WITH(ldns, -@@ -5034,6 +5090,7 @@ echo " KerberosV support +@@ -5214,6 +5270,7 @@ echo " KerberosV support echo " SELinux support: $SELINUX_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" @@ -72,10 +72,10 @@ diff -up openssh/configure.ac.tcp_wrappers openssh/configure.ac echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" -diff -up openssh/sshd.8.tcp_wrappers openssh/sshd.8 ---- openssh/sshd.8.tcp_wrappers 2015-06-24 11:41:04.527293674 +0200 -+++ openssh/sshd.8 2015-06-24 11:41:04.556293600 +0200 -@@ -860,6 +860,12 @@ the user's home directory becomes access +diff -up openssh-7.4p1/sshd.8.tcp_wrappers openssh-7.4p1/sshd.8 +--- openssh-7.4p1/sshd.8.tcp_wrappers 2016-12-23 15:36:38.759411194 +0100 ++++ openssh-7.4p1/sshd.8 2016-12-23 15:36:38.778411197 +0100 +@@ -836,6 +836,12 @@ the user's home directory becomes access This file should be writable only by the user, and need not be readable by anyone else. .Pp @@ -88,7 +88,7 @@ diff -up openssh/sshd.8.tcp_wrappers openssh/sshd.8 .It Pa /etc/hosts.equiv This file is for host-based authentication (see .Xr ssh 1 ) . -@@ -983,6 +989,7 @@ IPv6 address can be used everywhere wher +@@ -960,6 +966,7 @@ IPv6 address can be used everywhere wher .Xr ssh-keygen 1 , .Xr ssh-keyscan 1 , .Xr chroot 2 , @@ -96,10 +96,10 @@ diff -up openssh/sshd.8.tcp_wrappers openssh/sshd.8 .Xr login.conf 5 , .Xr moduli 5 , .Xr sshd_config 5 , -diff -up openssh/sshd.c.tcp_wrappers openssh/sshd.c ---- openssh/sshd.c.tcp_wrappers 2015-06-24 11:41:04.549293618 +0200 -+++ openssh/sshd.c 2015-06-24 11:41:53.331169536 +0200 -@@ -125,6 +125,13 @@ +diff -up openssh-7.4p1/sshd.c.tcp_wrappers openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.tcp_wrappers 2016-12-23 15:36:38.772411196 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 15:37:15.032417028 +0100 +@@ -123,6 +123,13 @@ #include "version.h" #include "ssherr.h" @@ -110,10 +110,10 @@ diff -up openssh/sshd.c.tcp_wrappers openssh/sshd.c +int deny_severity; +#endif /* LIBWRAP */ + - #ifndef O_NOCTTY - #define O_NOCTTY 0 - #endif -@@ -2158,6 +2165,24 @@ main(int ac, char **av) + /* Re-exec fds */ + #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) + #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) +@@ -2012,6 +2019,24 @@ main(int ac, char **av) #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif diff --git a/openssh-6.8p1-memory-problems.patch b/openssh-6.8p1-memory-problems.patch index db21660..e112033 100644 --- a/openssh-6.8p1-memory-problems.patch +++ b/openssh-6.8p1-memory-problems.patch @@ -1,8 +1,7 @@ -diff --git a/servconf.c b/servconf.c -index ad5869b..0255ed3 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -1910,6 +1910,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +diff -up openssh-7.4p1/servconf.c.memory openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.memory 2016-12-23 15:37:48.181422360 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 15:38:30.189429116 +0100 +@@ -2006,6 +2006,8 @@ copy_set_server_options(ServerOptions *d dst->n = src->n; \ } while (0) @@ -10,8 +9,8 @@ index ad5869b..0255ed3 100644 + M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); - M_CP_INTOPT(rsa_authentication); -@@ -1947,8 +1949,10 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + M_CP_INTOPT(pubkey_authentication); +@@ -2058,8 +2060,10 @@ copy_set_server_options(ServerOptions *d } while(0) #define M_CP_STRARRAYOPT(n, num_n) do {\ if (src->num_n != 0) { \ diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 6988f2f..4e989dc 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -82,12 +82,13 @@ diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c --- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 +++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200 -@@ -150,7 +150,7 @@ ssh_gssapi_server_mechanisms() { - - ssh_gssapi_supported_oids(&supported); - return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, -- NULL, NULL)); -+ NULL, NULL, options.gss_kex_algorithms)); +@@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() { + if (supported_oids == NULL) + ssh_gssapi_prepare_supported_oids(); + return (ssh_gssapi_kex_mechs(supported_oids, +- &ssh_gssapi_server_check_mech, NULL, NULL)); ++ &ssh_gssapi_server_check_mech, NULL, NULL, ++ options.gss_kex_algorithms)); } /* Unprivileged */ diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index 2666842..d4637f5 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -1,23 +1,7 @@ -From e1d58c44bd911e5ee4dddb6205e16eb9a03cc736 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 7 Aug 2015 10:18:54 +0200 -Subject: [PATCH] Possibility tu specify more fingerprint algorithms on client - side for smother transition - ---- - clientloop.c | 8 ++++---- - readconf.c | 43 +++++++++++++++++++++++++++++-------------- - readconf.h | 4 +++- - ssh_config.5 | 4 ++-- - sshconnect.c | 48 +++++++++++++++++++++++++++--------------------- - sshconnect2.c | 6 +++--- - 6 files changed, 68 insertions(+), 45 deletions(-) - -diff --git a/clientloop.c b/clientloop.c -index 87ceb3d..4553114 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -2194,7 +2194,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) +diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c +--- openssh-7.4p1/clientloop.c.fingerprint 2016-12-23 15:38:50.520432387 +0100 ++++ openssh-7.4p1/clientloop.c 2016-12-23 15:38:50.564432394 +0100 +@@ -2279,7 +2279,7 @@ update_known_hosts(struct hostkeys_updat if (ctx->keys_seen[i] != 2) continue; if ((fp = sshkey_fingerprint(ctx->keys[i], @@ -26,7 +10,7 @@ index 87ceb3d..4553114 100644 fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Learned new hostkey: %s %s", sshkey_type(ctx->keys[i]), fp); -@@ -2202,7 +2202,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) +@@ -2287,7 +2287,7 @@ update_known_hosts(struct hostkeys_updat } for (i = 0; i < ctx->nold; i++) { if ((fp = sshkey_fingerprint(ctx->old_keys[i], @@ -35,7 +19,7 @@ index 87ceb3d..4553114 100644 fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", sshkey_type(ctx->old_keys[i]), fp); -@@ -2245,7 +2245,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) +@@ -2330,7 +2330,7 @@ update_known_hosts(struct hostkeys_updat (r = hostfile_replace_entries(options.user_hostfiles[0], ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, options.hash_known_hosts, 0, @@ -44,7 +28,7 @@ index 87ceb3d..4553114 100644 error("%s: hostfile_replace_entries failed: %s", __func__, ssh_err(r)); } -@@ -2358,7 +2358,7 @@ client_input_hostkeys(void) +@@ -2443,7 +2443,7 @@ client_input_hostkeys(void) error("%s: parse key: %s", __func__, ssh_err(r)); goto out; } @@ -53,11 +37,10 @@ index 87ceb3d..4553114 100644 SSH_FP_DEFAULT); debug3("%s: received %s key %s", __func__, sshkey_type(key), fp); -diff --git a/readconf.c b/readconf.c -index 1d03bdf..6af4c62 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -1471,16 +1471,18 @@ parse_keytypes: +diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c +--- openssh-7.4p1/readconf.c.fingerprint 2016-12-23 15:38:50.559432393 +0100 ++++ openssh-7.4p1/readconf.c 2016-12-23 15:38:50.565432394 +0100 +@@ -1668,16 +1668,18 @@ parse_keytypes: goto parse_string; case oFingerprintHash: @@ -86,7 +69,7 @@ index 1d03bdf..6af4c62 100644 break; case oUpdateHostkeys: -@@ -1673,7 +1675,7 @@ initialize_options(Options * options) +@@ -1905,7 +1907,7 @@ initialize_options(Options * options) options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; @@ -95,7 +78,7 @@ index 1d03bdf..6af4c62 100644 options->update_hostkeys = -1; options->hostbased_key_types = NULL; options->pubkey_key_types = NULL; -@@ -1851,8 +1853,10 @@ fill_default_options(Options * options) +@@ -2102,8 +2104,10 @@ fill_default_options(Options * options) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; @@ -108,7 +91,7 @@ index 1d03bdf..6af4c62 100644 if (options->update_hostkeys == -1) options->update_hostkeys = 0; if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || -@@ -2189,6 +2193,17 @@ dump_cfg_strarray(OpCodes code, u_int count, char **vals) +@@ -2489,6 +2493,17 @@ dump_cfg_strarray(OpCodes code, u_int co } static void @@ -126,7 +109,7 @@ index 1d03bdf..6af4c62 100644 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) { u_int i; -@@ -2259,7 +2274,6 @@ dump_client_config(Options *o, const char *host) +@@ -2564,7 +2579,6 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); @@ -134,7 +117,7 @@ index 1d03bdf..6af4c62 100644 dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); -@@ -2328,6 +2342,7 @@ dump_client_config(Options *o, const char *host) +@@ -2634,6 +2648,7 @@ dump_client_config(Options *o, const cha dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); @@ -142,10 +125,9 @@ index 1d03bdf..6af4c62 100644 /* Special cases */ -diff --git a/readconf.h b/readconf.h -index bb2d552..d817f92 100644 ---- a/readconf.h -+++ b/readconf.h +diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h +--- openssh-7.4p1/readconf.h.fingerprint 2016-12-23 15:38:50.559432393 +0100 ++++ openssh-7.4p1/readconf.h 2016-12-23 15:38:50.565432394 +0100 @@ -21,6 +21,7 @@ #define MAX_SEND_ENV 256 #define SSH_MAX_HOSTS_FILES 32 @@ -154,7 +136,7 @@ index bb2d552..d817f92 100644 #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { -@@ -146,7 +147,8 @@ typedef struct { +@@ -162,7 +163,8 @@ typedef struct { char *revoked_host_keys; @@ -164,31 +146,60 @@ index bb2d552..d817f92 100644 int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ -diff --git a/ssh_config.5 b/ssh_config.5 -index 5b0975f..e8e6458 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -647,13 +647,13 @@ or - The default is - .Dq no . +diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1/ssh_config.5.fingerprint 2016-12-23 15:38:50.565432394 +0100 ++++ openssh-7.4p1/ssh_config.5 2016-12-23 15:40:03.754444166 +0100 +@@ -652,12 +652,13 @@ or + .Cm no + (the default). .It Cm FingerprintHash -Specifies the hash algorithm used when displaying key fingerprints. +Specifies the hash algorithms used when displaying key fingerprints. Valid options are: - .Dq md5 + .Cm md5 and - .Dq sha256 . - The default is --.Dq sha256 . -+.Dq "sha256 md5". +-.Cm sha256 +-(the default). ++.Cm sha256 . ++The default is ++.Cm "sha256 md5". .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. -diff --git a/sshconnect.c b/sshconnect.c -index f41960c..e12932f 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -920,9 +920,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, +diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.fingerprint 2016-12-23 15:38:50.561432394 +0100 ++++ openssh-7.4p1/sshconnect2.c 2016-12-23 15:38:50.566432394 +0100 +@@ -677,7 +677,7 @@ input_userauth_pk_ok(int type, u_int32_t + key->type, pktype); + goto done; + } +- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + goto done; + debug2("input_userauth_pk_ok: fp %s", fp); +@@ -1172,7 +1172,7 @@ sign_and_send_pubkey(Authctxt *authctxt, + int matched, ret = -1, have_sig = 1; + char *fp; + +- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + return 0; + debug3("%s: %s %s", __func__, key_type(id->key), fp); +@@ -1864,7 +1864,7 @@ userauth_hostbased(Authctxt *authctxt) + goto out; + } + +- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; +diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c +--- openssh-7.4p1/sshconnect.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshconnect.c 2016-12-23 15:38:50.566432394 +0100 +@@ -922,9 +922,9 @@ check_host_key(char *hostname, struct so "of known hosts.", type, ip); } else if (options.visual_host_key) { fp = sshkey_fingerprint(host_key, @@ -200,7 +211,7 @@ index f41960c..e12932f 100644 if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("Host key fingerprint is %s\n%s", fp, ra); -@@ -964,12 +964,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, +@@ -966,12 +966,6 @@ check_host_key(char *hostname, struct so else snprintf(msg1, sizeof(msg1), "."); /* The default */ @@ -213,14 +224,14 @@ index f41960c..e12932f 100644 msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) -@@ -983,16 +977,28 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, +@@ -985,16 +979,28 @@ check_host_key(char *hostname, struct so } snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " - "established%s\n" - "%s key fingerprint is %s.%s%s\n%s" + "established%s\n", host, ip, msg1); -+ for (i = 0; i < options.num_fingerprint_hash; i++) { ++ for (i = 0; i < (u_int) options.num_fingerprint_hash; i++) { + fp = sshkey_fingerprint(host_key, + options.fingerprint_hash[i], SSH_FP_DEFAULT); + ra = sshkey_fingerprint(host_key, @@ -251,7 +262,7 @@ index f41960c..e12932f 100644 if (!confirm(msg)) goto fail; hostkey_trusted = 1; /* user explicitly confirmed */ -@@ -1241,7 +1247,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) +@@ -1244,7 +1250,7 @@ verify_host_key(char *host, struct socka struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, @@ -260,7 +271,16 @@ index f41960c..e12932f 100644 error("%s: fingerprint host key: %s", __func__, ssh_err(r)); r = -1; goto out; -@@ -1405,9 +1411,9 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) +@@ -1252,7 +1258,7 @@ verify_host_key(char *host, struct socka + + if (sshkey_is_cert(host_key)) { + if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { + error("%s: fingerprint CA key: %s", + __func__, ssh_err(r)); + r = -1; +@@ -1432,9 +1438,9 @@ show_other_keys(struct hostkeys *hostkey if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; fp = sshkey_fingerprint(found->key, @@ -272,7 +292,7 @@ index f41960c..e12932f 100644 if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" -@@ -1430,7 +1436,7 @@ warn_changed_key(Key *host_key) +@@ -1457,7 +1463,7 @@ warn_changed_key(Key *host_key) { char *fp; @@ -281,42 +301,10 @@ index f41960c..e12932f 100644 SSH_FP_DEFAULT); if (fp == NULL) fatal("%s: sshkey_fingerprint fail", __func__); -diff --git a/sshconnect2.c b/sshconnect2.c -index 7751031..82ed92e 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -589,7 +589,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) - key->type, pktype); - goto done; - } -- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) - goto done; - debug2("input_userauth_pk_ok: fp %s", fp); -@@ -1009,7 +1009,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) - int matched, ret = -1, have_sig = 1; - char *fp; - -- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) - return 0; - debug3("%s: %s %s", __func__, key_type(id->key), fp); -@@ -1635,7 +1635,7 @@ userauth_hostbased(Authctxt *authctxt) - goto out; - } - -- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) { - error("%s: sshkey_fingerprint failed", __func__); - goto out; -diff --git a/ssh-keysign.c b/ssh-keysign.c -index 1dca3e2..23bff7d 100644 ---- a/ssh-keysign.c -+++ b/ssh-keysign.c -@@ -275,7 +275,7 @@ main(int argc, char **argv) +diff -up openssh-7.4p1/ssh-keysign.c.fingerprint openssh-7.4p1/ssh-keysign.c +--- openssh-7.4p1/ssh-keysign.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-keysign.c 2016-12-23 15:38:50.566432394 +0100 +@@ -285,7 +285,7 @@ main(int argc, char **argv) } } if (!found) { @@ -325,21 +313,3 @@ index 1dca3e2..23bff7d 100644 SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint failed", __progname); fatal("no matching hostkey found for key %s %s", - --- -2.1.0 - - -diff --git a/sshconnect.c b/sshconnect.c -index de7ace6..f16e606 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -1262,7 +1262,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) - - if (sshkey_is_cert(host_key)) { - if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, -- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { -+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { - error("%s: fingerprint CA key: %s", - __func__, ssh_err(r)); - r = -1; diff --git a/openssh-7.1p1-gssapi-documentation.patch b/openssh-7.1p1-gssapi-documentation.patch index 4887cc0..a97cbc4 100644 --- a/openssh-7.1p1-gssapi-documentation.patch +++ b/openssh-7.1p1-gssapi-documentation.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.1p1/ssh_config.5.gss-docs openssh-7.1p1/ssh_config.5 ---- openssh-7.1p1/ssh_config.5.gss-docs 2015-12-10 15:28:47.451966457 +0100 -+++ openssh-7.1p1/ssh_config.5 2015-12-10 15:30:28.070738047 +0100 -@@ -773,15 +773,26 @@ Note that this option applies to protoco +diff -up openssh-7.4p1/ssh_config.5.gss-docs openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1/ssh_config.5.gss-docs 2016-12-23 14:28:34.051714486 +0100 ++++ openssh-7.4p1/ssh_config.5 2016-12-23 14:34:24.568522417 +0100 +@@ -765,10 +765,19 @@ The default is If set to .Dq yes then renewal of the client's GSSAPI credentials will force the rekeying of the @@ -19,6 +19,11 @@ diff -up openssh-7.1p1/ssh_config.5.gss-docs openssh-7.1p1/ssh_config.5 +For this to work +.Cm GSSAPIKeyExchange +needs to be enabled in the server and also used by the client. + .It Cm GSSAPIServerIdentity + If set, specifies the GSSAPI server identity that ssh should expect when + connecting to the server. The default is unset, which means that the +@@ -776,9 +785,11 @@ expected GSSAPI server identity will be + hostname. .It Cm GSSAPITrustDns Set to -.Dq yes to indicate that the DNS is trusted to securely canonicalize @@ -31,10 +36,10 @@ diff -up openssh-7.1p1/ssh_config.5.gss-docs openssh-7.1p1/ssh_config.5 command line will be passed untouched to the GSSAPI library. The default is .Dq no . -diff -up openssh-7.1p1/sshd_config.5.gss-docs openssh-7.1p1/sshd_config.5 ---- openssh-7.1p1/sshd_config.5.gss-docs 2015-12-10 15:28:47.453966452 +0100 -+++ openssh-7.1p1/sshd_config.5 2015-12-10 15:28:47.461966434 +0100 -@@ -653,6 +653,10 @@ Controls whether the user's GSSAPI crede +diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.gss-docs 2016-12-23 14:28:34.043714490 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 14:28:34.051714486 +0100 +@@ -652,6 +652,10 @@ Controls whether the user's GSSAPI crede successful connection rekeying. This option can be used to accepted renewed or updated credentials from a compatible client. The default is .Dq no . diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 0a58fb4..035f0ac 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -1,8 +1,7 @@ -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 89a1762..fe98e08 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -1251,4 +1251,48 @@ mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t 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,48 @@ mm_audit_destroy_sensitive_data(const ch mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); buffer_free(&m); } @@ -32,13 +31,13 @@ index 89a1762..fe98e08 100644 + buffer_clear(&m); + buffer_append_space(&m, msg_len); + if (atomicio(read, fdin, buffer_ptr(&m), msg_len) != msg_len) { -+ error("%s: Failed to read the the buffer conent from the child", __func__); ++ 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, buffer_ptr(&m), msg_len) != msg_len) { -+ error("%s: Failed to write the messag to the monitor", __func__); ++ error("%s: Failed to write the message to the monitor", __func__); + ret = -1; + break; + } @@ -51,11 +50,10 @@ index 89a1762..fe98e08 100644 + pmonitor->m_recvfd = fd; +} #endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index e73134e..fbfe395 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -86,6 +86,8 @@ void mm_audit_unsupported_body(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(int, char *, char *, char *, char *, pid_t, uid_t); void mm_audit_session_key_free_body(int, pid_t, uid_t); void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); @@ -64,11 +62,10 @@ index e73134e..fbfe395 100644 #endif struct Session; -diff --git a/session.c b/session.c -index 8949fd1..9afb764 100644 ---- a/session.c -+++ b/session.c -@@ -159,6 +159,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 @@ -79,7 +76,35 @@ index 8949fd1..9afb764 100644 static int is_child = 0; static int in_chroot = 0; static int have_dev_log = 1; -@@ -875,6 +879,8 @@ do_exec(Session *s, const char *command) +@@ -289,6 +293,8 @@ xauth_valid_string(const char *s) + return 1; + } + ++void child_destory_sensitive_data(); ++ + #define USE_PIPES 1 + /* + * This is called to fork and execute a command when we have no tty. This +@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c + cray_init_job(s->pw); /* set up cray jid and tmpdir */ + #endif + ++ child_destory_sensitive_data(); ++ + /* Do processing for the child (exec command etc). */ + do_child(s, command); + /* NOTREACHED */ +@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm + /* Close the extra descriptor for the pseudo tty. */ + close(ttyfd); + ++ /* Do this early, so we will not block large MOTDs */ ++ child_destory_sensitive_data(); ++ + /* record login, etc. similar to login(1) */ + #ifdef _UNICOS + cray_init_job(s->pw); /* set up cray jid and tmpdir */ +@@ -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(s->command)); @@ -88,7 +113,7 @@ index 8949fd1..9afb764 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -890,6 +896,20 @@ do_exec(Session *s, const char *command) +@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) */ buffer_clear(&loginmsg); @@ -109,10 +134,13 @@ index 8949fd1..9afb764 100644 return ret; } -@@ -1707,12 +1727,28 @@ do_child(Session *s, const char *command) - struct passwd *pw = s->pw; - int r = 0; +@@ -1538,6 +1565,33 @@ child_close_fds(void) + endpwent(); + } ++void ++child_destory_sensitive_data() ++{ +#ifdef SSH_AUDIT_EVENTS + int pparent = paudit[1]; + close(paudit[0]); @@ -121,23 +149,35 @@ index 8949fd1..9afb764 100644 + mm_set_monitor_pipe(pparent); +#endif + - /* remove hostkey from the child's memory */ -- destroy_sensitive_data(1); -- /* Don't audit this - both us and the parent would be talking to the -- monitor over a single socket, with no synchronization. */ ++ /* remove hostkey from the child's memory */ + destroy_sensitive_data(use_privsep); + /* -+ * We can audit this, because wer hacked the pipe to direct the ++ * We can audit this, because we hacked the pipe to direct the + * messages over postauth child. But this message requires answer + * which we can't do using one-way pipe. + */ - packet_destroy_all(0, 1); - ++ packet_destroy_all(0, 1); ++ +#ifdef SSH_AUDIT_EVENTS + /* Notify parent that we are done */ + close(pparent); +#endif + ++} ++ + /* + * Performs common processing for the child, such as setting up the + * environment, closing extra file descriptors, setting the user and group +@@ -1554,12 +1608,6 @@ do_child(Session *s, const char *command + struct passwd *pw = s->pw; + int r = 0; + +- /* remove hostkey from the child's memory */ +- destroy_sensitive_data(1); +- /* Don't audit this - both us and the parent would be talking to the +- monitor over a single socket, with no synchronization. */ +- packet_destroy_all(0, 1); +- /* Force a password change */ if (s->authctxt->force_pwchange) { do_setusercontext(pw); diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index 8654e95..c8a4df3 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.3p1/audit-bsm.c.audit openssh-7.3p1/audit-bsm.c ---- openssh-7.3p1/audit-bsm.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/audit-bsm.c 2016-08-02 09:28:22.692299001 +0200 -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, +diff -up openssh-7.4p1/audit-bsm.c.audit openssh-7.4p1/audit-bsm.c +--- openssh-7.4p1/audit-bsm.c.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/audit-bsm.c 2016-12-23 18:54:54.433080419 +0100 +@@ -373,10 +373,23 @@ audit_connection_from(const char *host, #endif } @@ -26,7 +26,7 @@ diff -up openssh-7.3p1/audit-bsm.c.audit openssh-7.3p1/audit-bsm.c } void -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -39,7 +39,7 @@ diff -up openssh-7.3p1/audit-bsm.c.audit openssh-7.3p1/audit-bsm.c void audit_event(ssh_audit_event_t event) { -@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event) +@@ -452,4 +471,40 @@ audit_event(ssh_audit_event_t event) debug("%s: unhandled event %d", __func__, event); } } @@ -80,10 +80,10 @@ diff -up openssh-7.3p1/audit-bsm.c.audit openssh-7.3p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c ---- openssh-7.3p1/audit.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/audit.c 2016-08-02 09:28:22.692299001 +0200 -@@ -28,6 +28,7 @@ +diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c +--- openssh-7.4p1/audit.c.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/audit.c 2016-12-23 18:54:54.433080419 +0100 +@@ -26,6 +26,7 @@ #include #include @@ -91,7 +91,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c #ifdef SSH_AUDIT_EVENTS -@@ -36,6 +37,11 @@ +@@ -34,6 +35,11 @@ #include "key.h" #include "hostfile.h" #include "auth.h" @@ -103,7 +103,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c /* * Care must be taken when using this since it WILL NOT be initialized when -@@ -43,6 +49,7 @@ +@@ -41,6 +47,7 @@ * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. */ extern Authctxt *the_authctxt; @@ -111,7 +111,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c /* Maybe add the audit class to struct Authmethod? */ ssh_audit_event_t -@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) +@@ -69,13 +76,10 @@ audit_classify_auth(const char *method) const char * audit_username(void) { @@ -127,7 +127,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c return (the_authctxt->user); } -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -109,6 +113,40 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -168,7 +168,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c # ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) +@@ -138,6 +176,17 @@ audit_event(ssh_audit_event_t event) } /* @@ -186,7 +186,7 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li +@@ -172,13 +221,91 @@ audit_session_close(struct logininfo *li /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -280,10 +280,10 @@ diff -up openssh-7.3p1/audit.c.audit openssh-7.3p1/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.3p1/audit.h.audit openssh-7.3p1/audit.h ---- openssh-7.3p1/audit.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/audit.h 2016-08-02 09:28:22.692299001 +0200 -@@ -28,6 +28,7 @@ +diff -up openssh-7.4p1/audit.h.audit openssh-7.4p1/audit.h +--- openssh-7.4p1/audit.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/audit.h 2016-12-23 18:54:54.433080419 +0100 +@@ -26,6 +26,7 @@ # define _SSH_AUDIT_H #include "loginrec.h" @@ -291,7 +291,7 @@ diff -up openssh-7.3p1/audit.h.audit openssh-7.3p1/audit.h enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, -@@ -45,13 +46,33 @@ enum ssh_audit_event_type { +@@ -43,13 +44,33 @@ enum ssh_audit_event_type { SSH_CONNECTION_ABANDON, /* closed without completing auth */ SSH_AUDIT_UNKNOWN }; @@ -326,10 +326,10 @@ diff -up openssh-7.3p1/audit.h.audit openssh-7.3p1/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c ---- openssh-7.3p1/audit-linux.c.audit 2016-08-02 09:28:22.693299000 +0200 -+++ openssh-7.3p1/audit-linux.c 2016-08-02 09:37:19.652010336 +0200 -@@ -35,25 +35,38 @@ +diff -up openssh-7.4p1/audit-linux.c.audit openssh-7.4p1/audit-linux.c +--- openssh-7.4p1/audit-linux.c.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/audit-linux.c 2016-12-23 18:54:54.434080419 +0100 +@@ -33,25 +33,38 @@ #include "log.h" #include "audit.h" @@ -375,7 +375,7 @@ diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; -@@ -67,9 +80,97 @@ linux_audit_record_event(int uid, const +@@ -65,9 +78,97 @@ linux_audit_record_event(int uid, const rc = 0; errno = saved_errno; @@ -474,7 +474,7 @@ diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c /* Below is the sshd audit API code */ void -@@ -78,24 +179,51 @@ audit_connection_from(const char *host, +@@ -76,24 +177,51 @@ audit_connection_from(const char *host, /* not implemented */ } @@ -532,7 +532,7 @@ diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c } void -@@ -105,24 +233,180 @@ audit_event(ssh_audit_event_t event) +@@ -103,24 +231,180 @@ audit_event(ssh_audit_event_t event) switch(event) { case SSH_AUTH_SUCCESS: @@ -717,9 +717,9 @@ diff -up openssh-7.3p1/audit-linux.c.audit openssh-7.3p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-7.3p1/auditstub.c.audit openssh-7.3p1/auditstub.c ---- openssh-7.3p1/auditstub.c.audit 2016-08-02 09:28:22.693299000 +0200 -+++ openssh-7.3p1/auditstub.c 2016-08-02 09:28:22.693299000 +0200 +diff -up openssh-7.4p1/auditstub.c.audit openssh-7.4p1/auditstub.c +--- openssh-7.4p1/auditstub.c.audit 2016-12-23 18:54:54.434080419 +0100 ++++ openssh-7.4p1/auditstub.c 2016-12-23 18:54:54.434080419 +0100 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -771,9 +771,9 @@ diff -up openssh-7.3p1/auditstub.c.audit openssh-7.3p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-7.3p1/auth2.c.audit openssh-7.3p1/auth2.c ---- openssh-7.3p1/auth2.c.audit 2016-08-02 09:28:22.685299005 +0200 -+++ openssh-7.3p1/auth2.c 2016-08-02 09:28:22.693299000 +0200 +diff -up openssh-7.4p1/auth2.c.audit openssh-7.4p1/auth2.c +--- openssh-7.4p1/auth2.c.audit 2016-12-23 18:54:54.422080416 +0100 ++++ openssh-7.4p1/auth2.c 2016-12-23 18:54:54.434080419 +0100 @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { logit("input_userauth_request: invalid user %s", user); @@ -784,9 +784,9 @@ diff -up openssh-7.3p1/auth2.c.audit openssh-7.3p1/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-7.3p1/auth2-hostbased.c.audit openssh-7.3p1/auth2-hostbased.c ---- openssh-7.3p1/auth2-hostbased.c.audit 2016-08-02 09:28:22.686299004 +0200 -+++ openssh-7.3p1/auth2-hostbased.c 2016-08-02 09:28:22.693299000 +0200 +diff -up openssh-7.4p1/auth2-hostbased.c.audit openssh-7.4p1/auth2-hostbased.c +--- openssh-7.4p1/auth2-hostbased.c.audit 2016-12-23 18:54:54.422080416 +0100 ++++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 18:54:54.434080419 +0100 @@ -148,7 +148,7 @@ userauth_hostbased(Authctxt *authctxt) /* test for allowed key and correct signature */ authenticated = 0; @@ -815,10 +815,10 @@ diff -up openssh-7.3p1/auth2-hostbased.c.audit openssh-7.3p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-7.3p1/auth2-pubkey.c.audit openssh-7.3p1/auth2-pubkey.c ---- openssh-7.3p1/auth2-pubkey.c.audit 2016-08-02 09:28:22.686299004 +0200 -+++ openssh-7.3p1/auth2-pubkey.c 2016-08-02 09:28:22.694299000 +0200 -@@ -179,7 +179,7 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-7.4p1/auth2-pubkey.c.audit openssh-7.4p1/auth2-pubkey.c +--- openssh-7.4p1/auth2-pubkey.c.audit 2016-12-23 18:54:54.423080416 +0100 ++++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 18:54:54.435080419 +0100 +@@ -183,7 +183,7 @@ userauth_pubkey(Authctxt *authctxt) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && @@ -827,7 +827,7 @@ diff -up openssh-7.3p1/auth2-pubkey.c.audit openssh-7.3p1/auth2-pubkey.c buffer_len(&b))) == 1) { authenticated = 1; authctxt->last_details = pubkey; -@@ -248,6 +248,18 @@ pubkey_auth_info(Authctxt *authctxt, con +@@ -252,6 +252,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } @@ -846,10 +846,10 @@ diff -up openssh-7.3p1/auth2-pubkey.c.audit openssh-7.3p1/auth2-pubkey.c /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh-7.3p1/auth.c.audit openssh-7.3p1/auth.c ---- openssh-7.3p1/auth.c.audit 2016-08-02 09:28:22.635299033 +0200 -+++ openssh-7.3p1/auth.c 2016-08-02 09:28:22.694299000 +0200 -@@ -657,9 +657,6 @@ getpwnamallow(const char *user) +diff -up openssh-7.4p1/auth.c.audit openssh-7.4p1/auth.c +--- openssh-7.4p1/auth.c.audit 2016-12-23 18:54:54.373080404 +0100 ++++ openssh-7.4p1/auth.c 2016-12-23 18:54:54.435080419 +0100 +@@ -666,9 +666,6 @@ getpwnamallow(const char *user) record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -859,10 +859,10 @@ diff -up openssh-7.3p1/auth.c.audit openssh-7.3p1/auth.c return (NULL); } if (!allowed_user(pw)) -diff -up openssh-7.3p1/auth.h.audit openssh-7.3p1/auth.h ---- openssh-7.3p1/auth.h.audit 2016-08-02 09:28:22.686299004 +0200 -+++ openssh-7.3p1/auth.h 2016-08-02 09:28:22.694299000 +0200 -@@ -199,6 +199,7 @@ void abandon_challenge_response(Authctxt +diff -up openssh-7.4p1/auth.h.audit openssh-7.4p1/auth.h +--- openssh-7.4p1/auth.h.audit 2016-12-23 18:54:54.423080416 +0100 ++++ openssh-7.4p1/auth.h 2016-12-23 18:54:54.435080419 +0100 +@@ -185,6 +185,7 @@ struct passwd * getpwnamallow(const char char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -870,59 +870,20 @@ diff -up openssh-7.3p1/auth.h.audit openssh-7.3p1/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -219,6 +220,7 @@ int get_hostkey_index(Key *, int, struc - int ssh1_session_key(BIGNUM *); +@@ -204,6 +205,7 @@ Key *get_hostkey_private_by_type(int, in + int get_hostkey_index(Key *, int, struct ssh *); int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); +int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-7.3p1/auth-rsa.c.audit openssh-7.3p1/auth-rsa.c ---- openssh-7.3p1/auth-rsa.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/auth-rsa.c 2016-08-02 09:28:22.694299000 +0200 -@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNU - { - u_char buf[32], mdbuf[16]; - struct ssh_digest_ctx *md; -- int len; -+ int len, rv; -+#ifdef SSH_AUDIT_EVENTS -+ char *fp; -+#endif - - /* don't allow short keys */ - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNU - ssh_digest_free(md); - - /* Verify that the response is the original challenge. */ -- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { -- /* Wrong answer. */ -- return (0); -+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; -+ -+#ifdef SSH_AUDIT_EVENTS -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) { -+ debug("unsuccessful audit"); -+ rv = 0; - } -- /* Correct answer. */ -- return (1); -+ free(fp); -+#endif -+ -+ return rv; - } - - /* -diff -up openssh-7.3p1/cipher.c.audit openssh-7.3p1/cipher.c ---- openssh-7.3p1/cipher.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/cipher.c 2016-08-02 09:28:22.694299000 +0200 -@@ -57,26 +57,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v - extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); - #endif +diff -up openssh-7.4p1/cipher.c.audit openssh-7.4p1/cipher.c +--- openssh-7.4p1/cipher.c.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/cipher.c 2016-12-23 18:54:54.435080419 +0100 +@@ -66,26 +66,6 @@ struct sshcipher_ctx { + const struct sshcipher *cipher; + }; -struct sshcipher { - char *name; @@ -947,15 +908,15 @@ diff -up openssh-7.3p1/cipher.c.audit openssh-7.3p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-7.3p1/cipher.h.audit openssh-7.3p1/cipher.h ---- openssh-7.3p1/cipher.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/cipher.h 2016-08-02 09:28:22.694299000 +0200 -@@ -62,7 +62,26 @@ +diff -up openssh-7.4p1/cipher.h.audit openssh-7.4p1/cipher.h +--- openssh-7.4p1/cipher.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/cipher.h 2016-12-23 18:54:54.436080419 +0100 +@@ -62,7 +62,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 -struct sshcipher; -+struct sshcipher { ++struct sshcipher { /* from cipher.c */ + char *name; + int number; /* for ssh1 only */ + u_int block_size; @@ -974,14 +935,13 @@ diff -up openssh-7.3p1/cipher.h.audit openssh-7.3p1/cipher.h + void *ignored; +#endif +}; -+ - struct sshcipher_ctx { - int plaintext; - int encrypt; -diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c ---- openssh-7.3p1/kex.c.audit 2016-08-02 09:28:22.676299010 +0200 -+++ openssh-7.3p1/kex.c 2016-08-02 09:28:22.695298999 +0200 -@@ -55,6 +55,7 @@ + struct sshcipher_ctx; + + u_int cipher_mask_ssh1(int); +diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.audit 2016-12-23 18:54:54.410080413 +0100 ++++ openssh-7.4p1/kex.c 2016-12-23 18:54:54.436080419 +0100 +@@ -54,6 +54,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -989,7 +949,7 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -673,8 +674,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -683,8 +684,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -1003,7 +963,7 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; -@@ -692,8 +697,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -702,8 +707,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1017,7 +977,7 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ -@@ -710,8 +719,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -720,8 +729,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1031,10 +991,10 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -882,6 +895,10 @@ kex_choose_conf(struct ssh *ssh) - dh_need = MAX(dh_need, newkeys->enc.block_size); - dh_need = MAX(dh_need, newkeys->enc.iv_len); - dh_need = MAX(dh_need, newkeys->mac.key_len); +@@ -890,6 +903,10 @@ kex_choose_conf(struct ssh *ssh) + dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); + dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); + dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); + debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); +#ifdef SSH_AUDIT_EVENTS + audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); @@ -1042,7 +1002,7 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1056,3 +1073,33 @@ dump_digest(char *msg, u_char *digest, i +@@ -1064,3 +1081,33 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1076,10 +1036,10 @@ diff -up openssh-7.3p1/kex.c.audit openssh-7.3p1/kex.c + mac_destroy(&newkeys->mac); + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} -diff -up openssh-7.3p1/kex.h.audit openssh-7.3p1/kex.h ---- openssh-7.3p1/kex.h.audit 2016-08-02 09:28:22.676299010 +0200 -+++ openssh-7.3p1/kex.h 2016-08-02 09:28:22.695298999 +0200 -@@ -212,6 +212,8 @@ int kexgss_client(struct ssh *); +diff -up openssh-7.4p1/kex.h.audit openssh-7.4p1/kex.h +--- openssh-7.4p1/kex.h.audit 2016-12-23 18:54:54.410080413 +0100 ++++ openssh-7.4p1/kex.h 2016-12-23 18:54:54.436080419 +0100 +@@ -213,6 +213,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1088,9 +1048,9 @@ diff -up openssh-7.3p1/kex.h.audit openssh-7.3p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.3p1/key.h.audit openssh-7.3p1/key.h ---- openssh-7.3p1/key.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/key.h 2016-08-02 09:28:22.695298999 +0200 +diff -up openssh-7.4p1/key.h.audit openssh-7.4p1/key.h +--- openssh-7.4p1/key.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/key.h 2016-12-23 18:54:54.436080419 +0100 @@ -50,6 +50,7 @@ typedef struct sshkey Key; #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid @@ -1099,10 +1059,10 @@ diff -up openssh-7.3p1/key.h.audit openssh-7.3p1/key.h #define key_type_plain sshkey_type_plain #define key_curve_name_to_nid sshkey_curve_name_to_nid #define key_curve_nid_to_bits sshkey_curve_nid_to_bits -diff -up openssh-7.3p1/mac.c.audit openssh-7.3p1/mac.c ---- openssh-7.3p1/mac.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/mac.c 2016-08-02 09:28:22.695298999 +0200 -@@ -245,6 +245,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh-7.4p1/mac.c.audit openssh-7.4p1/mac.c +--- openssh-7.4p1/mac.c.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/mac.c 2016-12-23 18:54:54.436080419 +0100 +@@ -249,6 +249,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1123,9 +1083,9 @@ diff -up openssh-7.3p1/mac.c.audit openssh-7.3p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-7.3p1/mac.h.audit openssh-7.3p1/mac.h ---- openssh-7.3p1/mac.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/mac.h 2016-08-02 09:28:22.695298999 +0200 +diff -up openssh-7.4p1/mac.h.audit openssh-7.4p1/mac.h +--- openssh-7.4p1/mac.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/mac.h 2016-12-23 18:54:54.436080419 +0100 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1133,10 +1093,10 @@ diff -up openssh-7.3p1/mac.h.audit openssh-7.3p1/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-7.3p1/Makefile.in.audit openssh-7.3p1/Makefile.in ---- openssh-7.3p1/Makefile.in.audit 2016-08-02 09:28:22.638299031 +0200 -+++ openssh-7.3p1/Makefile.in 2016-08-02 09:28:22.695298999 +0200 -@@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-7.4p1/Makefile.in.audit openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.audit 2016-12-23 18:54:54.375080404 +0100 ++++ openssh-7.4p1/Makefile.in 2016-12-23 18:54:54.436080419 +0100 +@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ @@ -1145,10 +1105,10 @@ diff -up openssh-7.3p1/Makefile.in.audit openssh-7.3p1/Makefile.in SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c ---- openssh-7.3p1/monitor.c.audit 2016-08-02 09:28:22.687299004 +0200 -+++ openssh-7.3p1/monitor.c 2016-08-02 09:28:22.696298999 +0200 -@@ -103,6 +103,7 @@ +diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.audit 2016-12-23 18:54:54.423080416 +0100 ++++ openssh-7.4p1/monitor.c 2016-12-23 18:54:54.437080420 +0100 +@@ -102,6 +102,7 @@ #include "compat.h" #include "ssh2.h" #include "authfd.h" @@ -1156,7 +1116,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c #include "match.h" #include "ssherr.h" -@@ -118,6 +119,8 @@ extern Buffer auth_debug; +@@ -117,6 +118,8 @@ extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; @@ -1165,7 +1125,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c /* State exported from the child */ static struct sshbuf *child_state; -@@ -168,6 +171,11 @@ int mm_answer_gss_updatecreds(int, Buffe +@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); @@ -1177,7 +1137,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c #endif static int monitor_read_log(struct monitor *); -@@ -227,6 +235,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -222,6 +230,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1188,7 +1148,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -265,6 +277,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -260,6 +272,11 @@ struct mon_table mon_dispatch_postauth20 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1200,30 +1160,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -297,6 +314,10 @@ struct mon_table mon_dispatch_proto15[] - #endif - #ifdef SSH_AUDIT_EVENTS - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, - #endif - #endif /* WITH_SSH1 */ - {0, 0, NULL} -@@ -310,6 +331,11 @@ struct mon_table mon_dispatch_postauth15 - #ifdef SSH_AUDIT_EVENTS - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, - #endif - #endif /* WITH_SSH1 */ - {0, 0, NULL} -@@ -1488,9 +1514,11 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1396,9 +1413,11 @@ mm_answer_keyverify(int sock, Buffer *m) Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; @@ -1235,7 +1172,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); -@@ -1498,6 +1526,8 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1406,6 +1425,8 @@ mm_answer_keyverify(int sock, Buffer *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1244,7 +1181,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c key = key_from_blob(blob, bloblen); if (key == NULL) -@@ -1518,7 +1548,17 @@ mm_answer_keyverify(int sock, Buffer *m) +@@ -1426,7 +1447,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1263,7 +1200,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); -@@ -1584,6 +1624,12 @@ mm_session_close(Session *s) +@@ -1489,6 +1520,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1276,7 +1213,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c session_unused(s->self); } -@@ -1866,6 +1912,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1591,6 +1628,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1285,7 +1222,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1908,11 +1956,45 @@ mm_answer_audit_command(int socket, Buff +@@ -1633,11 +1672,45 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1332,7 +1269,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c free(cmd); return (0); } -@@ -1972,6 +2052,7 @@ monitor_apply_keystate(struct monitor *p +@@ -1690,6 +1763,7 @@ monitor_apply_keystate(struct monitor *p void mm_get_keystate(struct monitor *pmonitor) { @@ -1340,7 +1277,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1979,6 +2060,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1697,6 +1771,21 @@ mm_get_keystate(struct monitor *pmonitor mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); @@ -1362,7 +1299,7 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c } -@@ -2248,3 +2344,86 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -1953,3 +2042,86 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1449,9 +1386,9 @@ diff -up openssh-7.3p1/monitor.c.audit openssh-7.3p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.3p1/monitor.h.audit openssh-7.3p1/monitor.h ---- openssh-7.3p1/monitor.h.audit 2016-08-02 09:28:22.660299019 +0200 -+++ openssh-7.3p1/monitor.h 2016-08-02 09:28:22.696298999 +0200 +diff -up openssh-7.4p1/monitor.h.audit openssh-7.4p1/monitor.h +--- openssh-7.4p1/monitor.h.audit 2016-12-23 18:54:54.393080409 +0100 ++++ openssh-7.4p1/monitor.h 2016-12-23 18:54:54.437080420 +0100 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1467,10 +1404,10 @@ diff -up openssh-7.3p1/monitor.h.audit openssh-7.3p1/monitor.h }; -diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c ---- openssh-7.3p1/monitor_wrap.c.audit 2016-08-02 09:28:22.639299030 +0200 -+++ openssh-7.3p1/monitor_wrap.c 2016-08-02 09:28:22.696298999 +0200 -@@ -466,7 +466,7 @@ mm_key_allowed(enum mm_keytype type, con +diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.audit 2016-12-23 18:54:54.376080405 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2016-12-23 18:54:54.437080420 +0100 +@@ -453,7 +453,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1479,7 +1416,7 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c { Buffer m; u_char *blob; -@@ -480,6 +480,7 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -467,6 +467,7 @@ mm_key_verify(Key *key, u_char *sig, u_i return (0); buffer_init(&m); @@ -1487,7 +1424,7 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -497,6 +498,18 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -484,6 +485,18 @@ mm_key_verify(Key *key, u_char *sig, u_i return (verified); } @@ -1506,7 +1443,7 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c void mm_send_keystate(struct monitor *monitor) { -@@ -1010,10 +1023,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -861,10 +874,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1519,7 +1456,7 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -1021,6 +1035,26 @@ mm_audit_run_command(const char *command +@@ -872,6 +886,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1546,7 +1483,7 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1156,3 +1190,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1007,3 +1041,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1617,20 +1554,20 @@ diff -up openssh-7.3p1/monitor_wrap.c.audit openssh-7.3p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.3p1/monitor_wrap.h.audit openssh-7.3p1/monitor_wrap.h ---- openssh-7.3p1/monitor_wrap.h.audit 2016-08-02 09:28:22.639299030 +0200 -+++ openssh-7.3p1/monitor_wrap.h 2016-08-02 09:28:22.696298999 +0200 -@@ -54,7 +54,8 @@ int mm_hostbased_key_allowed(struct pass - const char *, Key *); - int mm_auth_rhosts_rsa_key_allowed(struct passwd *, const char *, +diff -up openssh-7.4p1/monitor_wrap.h.audit openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1/monitor_wrap.h.audit 2016-12-23 18:54:54.376080405 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2016-12-23 18:54:54.437080420 +0100 +@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, cons + int mm_user_key_allowed(struct passwd *, Key *, int); + int mm_hostbased_key_allowed(struct passwd *, const char *, const char *, Key *); -int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); +int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); +int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); - int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); - int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); - BIGNUM *mm_auth_rsa_generate_challenge(Key *); -@@ -81,7 +82,12 @@ void mm_sshpam_free_ctx(void *); + + #ifdef GSSAPI + OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +@@ -76,7 +77,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); @@ -1644,10 +1581,10 @@ diff -up openssh-7.3p1/monitor_wrap.h.audit openssh-7.3p1/monitor_wrap.h #endif struct Session; -diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c ---- openssh-7.3p1/packet.c.audit 2016-08-02 09:28:22.582299062 +0200 -+++ openssh-7.3p1/packet.c 2016-08-02 09:28:22.697298998 +0200 -@@ -68,6 +68,7 @@ +diff -up openssh-7.4p1/packet.c.audit openssh-7.4p1/packet.c +--- openssh-7.4p1/packet.c.audit 2016-12-23 18:54:54.318080390 +0100 ++++ openssh-7.4p1/packet.c 2016-12-23 18:54:54.438080420 +0100 +@@ -67,6 +67,7 @@ #include "key.h" /* typedefs XXX */ #include "xmalloc.h" @@ -1655,7 +1592,7 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c #include "crc32.h" #include "deattack.h" #include "compat.h" -@@ -468,6 +469,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -494,6 +495,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1669,7 +1606,7 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -537,13 +545,6 @@ ssh_packet_close(struct ssh *ssh) +@@ -562,13 +570,6 @@ ssh_packet_close(struct ssh *ssh) if (!state->initialized) return; state->initialized = 0; @@ -1683,21 +1620,18 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); -@@ -575,12 +576,22 @@ ssh_packet_close(struct ssh *ssh) +@@ -600,11 +601,21 @@ ssh_packet_close(struct ssh *ssh) inflateEnd(stream); } } -- if ((r = cipher_cleanup(&state->send_context)) != 0) -- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); -- if ((r = cipher_cleanup(&state->receive_context)) != 0) -- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); +- cipher_free(state->send_context); +- cipher_free(state->receive_context); + if (packet_state_has_keys(state)) { -+ if ((r = cipher_cleanup(&state->send_context)) != 0) -+ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); -+ if ((r = cipher_cleanup(&state->receive_context)) != 0) -+ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ cipher_free(state->send_context); ++ cipher_free(state->receive_context); + audit_session_key_free(MODE_MAX); + } + state->send_context = state->receive_context = NULL; free(ssh->remote_ipaddr); ssh->remote_ipaddr = NULL; + if (state->connection_in == state->connection_out) { @@ -1710,15 +1644,15 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c free(ssh->state); ssh->state = NULL; } -@@ -1005,6 +1016,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - (unsigned long long)state->p_read.blocks, - (unsigned long long)state->p_send.bytes, - (unsigned long long)state->p_send.blocks); +@@ -950,6 +961,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + " (%llu bytes total)", __func__, + (unsigned long long)ps->blocks, dir, + (unsigned long long)ps->bytes); + audit_session_key_free(mode); - if ((r = cipher_cleanup(cc)) != 0) - return r; + cipher_free(*ccp); + *ccp = NULL; enc = &state->newkeys[mode]->enc; -@@ -2450,6 +2462,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2440,6 +2452,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1747,8 +1681,8 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c + if (state == NULL) + return; + -+ cipher_cleanup(&state->receive_context); -+ cipher_cleanup(&state->send_context); ++ cipher_free(state->receive_context); ++ cipher_free(state->send_context); + + buffer_free(state->input); + state->input = NULL; @@ -1791,18 +1725,18 @@ diff -up openssh-7.3p1/packet.c.audit openssh-7.3p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-7.3p1/packet.h.audit openssh-7.3p1/packet.h ---- openssh-7.3p1/packet.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/packet.h 2016-08-02 09:28:22.697298998 +0200 -@@ -204,4 +204,5 @@ extern struct ssh *active_state; +diff -up openssh-7.4p1/packet.h.audit openssh-7.4p1/packet.h +--- openssh-7.4p1/packet.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/packet.h 2016-12-23 18:54:54.438080420 +0100 +@@ -208,4 +208,5 @@ extern struct ssh *active_state; # undef EC_POINT #endif +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-7.3p1/sandbox-seccomp-filter.c.audit openssh-7.3p1/sandbox-seccomp-filter.c ---- openssh-7.3p1/sandbox-seccomp-filter.c.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/sandbox-seccomp-filter.c 2016-08-02 09:28:22.697298998 +0200 +diff -up openssh-7.4p1/sandbox-seccomp-filter.c.audit openssh-7.4p1/sandbox-seccomp-filter.c +--- openssh-7.4p1/sandbox-seccomp-filter.c.audit 2016-12-23 18:54:54.377080405 +0100 ++++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 18:54:54.438080420 +0100 @@ -159,6 +159,12 @@ static const struct sock_filter preauth_ #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), @@ -1816,10 +1750,10 @@ diff -up openssh-7.3p1/sandbox-seccomp-filter.c.audit openssh-7.3p1/sandbox-secc #ifdef __NR_madvise SC_ALLOW(madvise), #endif -diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c ---- openssh-7.3p1/session.c.audit 2016-08-02 09:28:22.691299001 +0200 -+++ openssh-7.3p1/session.c 2016-08-02 09:28:22.698298997 +0200 -@@ -144,7 +144,7 @@ extern int log_stderr; +diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.audit 2016-12-23 18:54:54.430080418 +0100 ++++ openssh-7.4p1/session.c 2016-12-23 18:57:45.068115466 +0100 +@@ -142,7 +142,7 @@ extern int log_stderr; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1828,7 +1762,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c extern Buffer loginmsg; /* original command from peer. */ -@@ -757,6 +757,14 @@ do_exec_pty(Session *s, const char *comm +@@ -576,6 +576,14 @@ do_exec_pty(Session *s, const char *comm /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1836,14 +1770,14 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c + /* do_login in the child did not affect state in this process, + compensate. From an architectural standpoint, this is extremely + ugly. */ -+ if (!(options.use_login && command == NULL)) ++ if (command != NULL) + audit_count_session_open(); +#endif + /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -882,15 +890,19 @@ do_exec(Session *s, const char *command) +@@ -696,15 +704,19 @@ do_exec(Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1865,7 +1799,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); -@@ -1756,7 +1768,10 @@ do_child(Session *s, const char *command +@@ -1543,7 +1555,10 @@ do_child(Session *s, const char *command int r = 0; /* remove hostkey from the child's memory */ @@ -1877,7 +1811,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1986,6 +2001,9 @@ session_unused(int id) +@@ -1757,6 +1772,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1887,7 +1821,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -2068,6 +2084,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1839,6 +1857,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1907,7 +1841,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c session_by_tty(char *tty) { int i; -@@ -2590,6 +2619,32 @@ session_exit_message(Session *s, int sta +@@ -2351,6 +2382,32 @@ session_exit_message(Session *s, int sta chan_write_failed(c); } @@ -1940,7 +1874,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c void session_close(Session *s) { -@@ -2604,6 +2659,10 @@ session_close(Session *s) +@@ -2365,6 +2422,10 @@ session_close(Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1951,7 +1885,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2818,6 +2877,15 @@ do_authenticated2(Authctxt *authctxt) +@@ -2575,6 +2636,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -1967,7 +1901,7 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c void do_cleanup(Authctxt *authctxt) { -@@ -2869,7 +2937,7 @@ do_cleanup(Authctxt *authctxt) +@@ -2626,7 +2696,7 @@ do_cleanup(Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -1976,10 +1910,10 @@ diff -up openssh-7.3p1/session.c.audit openssh-7.3p1/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-7.3p1/session.h.audit openssh-7.3p1/session.h ---- openssh-7.3p1/session.h.audit 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/session.h 2016-08-02 09:28:22.698298997 +0200 -@@ -61,6 +61,12 @@ struct Session { +diff -up openssh-7.4p1/session.h.audit openssh-7.4p1/session.h +--- openssh-7.4p1/session.h.audit 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/session.h 2016-12-23 18:54:54.438080420 +0100 +@@ -60,6 +60,12 @@ struct Session { char *name; char *val; } *env; @@ -1992,7 +1926,7 @@ diff -up openssh-7.3p1/session.h.audit openssh-7.3p1/session.h }; void do_authenticated(Authctxt *); -@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); +@@ -72,8 +78,10 @@ void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); void session_destroy_all(void (*)(Session *)); void session_pty_cleanup2(Session *); @@ -2003,10 +1937,10 @@ diff -up openssh-7.3p1/session.h.audit openssh-7.3p1/session.h Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); -diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c ---- openssh-7.3p1/sshd.c.audit 2016-08-02 09:28:22.667299015 +0200 -+++ openssh-7.3p1/sshd.c 2016-08-02 09:28:22.698298997 +0200 -@@ -121,6 +121,7 @@ +diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.audit 2016-12-23 18:54:54.403080411 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 18:56:18.992101105 +0100 +@@ -119,6 +119,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" @@ -2014,16 +1948,16 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" -@@ -260,7 +261,7 @@ Buffer loginmsg; +@@ -244,7 +245,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); +void destroy_sensitive_data(int); void demote_sensitive_data(void); + static void do_ssh2_kex(void); - #ifdef WITH_SSH1 -@@ -281,6 +282,15 @@ close_listen_socks(void) +@@ -261,6 +262,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2039,7 +1973,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c static void close_startup_pipes(void) { -@@ -566,22 +576,49 @@ sshd_exchange_identification(struct ssh +@@ -473,18 +483,45 @@ sshd_exchange_identification(struct ssh } } @@ -2060,10 +1994,6 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c + pid = getpid(); + uid = getuid(); +#endif - if (sensitive_data.server_key) { - key_free(sensitive_data.server_key); - sensitive_data.server_key = NULL; - } for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + char *fp; @@ -2092,7 +2022,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -596,7 +633,13 @@ demote_sensitive_data(void) +@@ -497,12 +534,30 @@ demote_sensitive_data(void) { Key *tmp; int i; @@ -2103,11 +2033,6 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c + pid = getpid(); + uid = getuid(); +#endif - if (sensitive_data.server_key) { - tmp = key_demote(sensitive_data.server_key); - key_free(sensitive_data.server_key); -@@ -605,11 +648,23 @@ demote_sensitive_data(void) - for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + char *fp; @@ -2119,8 +2044,6 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c tmp = key_demote(sensitive_data.host_keys[i]); key_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; - if (tmp->type == KEY_RSA1) - sensitive_data.ssh1_host_key = tmp; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS + audit_destroy_sensitive_data(fp, pid, uid); @@ -2130,7 +2053,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c } /* Certs do not need demotion */ } -@@ -681,7 +736,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -585,7 +640,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2139,7 +2062,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -766,6 +821,12 @@ privsep_postauth(Authctxt *authctxt) +@@ -665,6 +720,12 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); @@ -2152,7 +2075,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c monitor_child_postauth(pmonitor); /* NEVERREACHED */ -@@ -1310,6 +1371,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1154,6 +1215,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2160,7 +2083,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2335,6 +2397,7 @@ main(int ac, char **av) +@@ -2092,6 +2150,7 @@ main(int ac, char **av) */ if (use_privsep) { mm_send_keystate(pmonitor); @@ -2168,16 +2091,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c exit(0); } -@@ -2380,7 +2443,7 @@ main(int ac, char **av) - privsep_postauth(authctxt); - /* the monitor process [priv] will not return */ - if (!compat20) -- destroy_sensitive_data(); -+ destroy_sensitive_data(0); - } - - packet_set_timeout(options.client_alive_interval, -@@ -2394,6 +2457,9 @@ main(int ac, char **av) +@@ -2148,6 +2207,9 @@ main(int ac, char **av) do_authenticated(authctxt); /* The connection has been terminated. */ @@ -2187,27 +2101,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2556,6 +2622,10 @@ do_ssh1_kex(void) - if (cookie[i] != packet_get_char()) - packet_disconnect("IP Spoofing check bytes do not match."); - -+#ifdef SSH_AUDIT_EVENTS -+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); -+#endif -+ - debug("Encryption type: %.200s", cipher_name(cipher_type)); - - /* Get the encrypted integer. */ -@@ -2616,7 +2686,7 @@ do_ssh1_kex(void) - } - - /* Destroy the private and public keys. No longer. */ -- destroy_sensitive_data(); -+ destroy_sensitive_data(1); - - if (use_privsep) - mm_ssh1_session_id(session_id); -@@ -2794,6 +2864,16 @@ do_ssh2_kex(void) +@@ -2321,6 +2383,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2224,7 +2118,7 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2805,9 +2885,14 @@ cleanup_exit(int i) +@@ -2332,9 +2404,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2240,10 +2134,10 @@ diff -up openssh-7.3p1/sshd.c.audit openssh-7.3p1/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-7.3p1/sshkey.c.audit openssh-7.3p1/sshkey.c ---- openssh-7.3p1/sshkey.c.audit 2016-08-02 09:28:22.689299002 +0200 -+++ openssh-7.3p1/sshkey.c 2016-08-02 09:28:22.699298997 +0200 -@@ -304,6 +304,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-7.4p1/sshkey.c.audit openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.audit 2016-12-23 18:54:54.425080417 +0100 ++++ openssh-7.4p1/sshkey.c 2016-12-23 18:54:54.439080420 +0100 +@@ -303,6 +303,33 @@ sshkey_type_is_valid_ca(int type) } int @@ -2277,9 +2171,9 @@ diff -up openssh-7.3p1/sshkey.c.audit openssh-7.3p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-7.3p1/sshkey.h.audit openssh-7.3p1/sshkey.h ---- openssh-7.3p1/sshkey.h.audit 2016-08-02 09:28:22.689299002 +0200 -+++ openssh-7.3p1/sshkey.h 2016-08-02 09:28:22.699298997 +0200 +diff -up openssh-7.4p1/sshkey.h.audit openssh-7.4p1/sshkey.h +--- openssh-7.4p1/sshkey.h.audit 2016-12-23 18:54:54.425080417 +0100 ++++ openssh-7.4p1/sshkey.h 2016-12-23 18:54:54.439080420 +0100 @@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index c405be7..37dcc91 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c ---- openssh-7.2p1/cipher.c.fips 2016-02-12 18:53:56.083665235 +0100 -+++ openssh-7.2p1/cipher.c 2016-02-12 18:53:56.090665235 +0100 +diff -up openssh-7.4p1/cipher.c.fips openssh-7.4p1/cipher.c +--- openssh-7.4p1/cipher.c.fips 2016-12-23 16:37:49.290741582 +0100 ++++ openssh-7.4p1/cipher.c 2016-12-23 16:37:49.300741586 +0100 @@ -39,6 +39,8 @@ #include @@ -10,7 +10,7 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c #include #include #include -@@ -99,6 +101,26 @@ static const struct sshcipher ciphers[] +@@ -116,6 +118,20 @@ static const struct sshcipher ciphers[] { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; @@ -25,19 +25,13 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, -+#ifdef OPENSSL_HAVE_EVPGCM -+ { "aes128-gcm@openssh.com", -+ SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, -+ { "aes256-gcm@openssh.com", -+ SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, -+#endif + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } +}; + /*--*/ /* Returns a comma-separated list of supported ciphers. */ -@@ -109,7 +131,7 @@ cipher_alg_list(char sep, int auth_only) +@@ -126,7 +142,7 @@ cipher_alg_list(char sep, int auth_only) size_t nlen, rlen = 0; const struct sshcipher *c; @@ -46,7 +40,7 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c if (c->number != SSH_CIPHER_SSH2) continue; if (auth_only && c->auth_len == 0) -@@ -193,7 +215,7 @@ const struct sshcipher * +@@ -222,7 +238,7 @@ const struct sshcipher * cipher_by_name(const char *name) { const struct sshcipher *c; @@ -55,7 +49,7 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c if (strcmp(c->name, name) == 0) return c; return NULL; -@@ -203,7 +225,7 @@ const struct sshcipher * +@@ -232,7 +248,7 @@ const struct sshcipher * cipher_by_number(int id) { const struct sshcipher *c; @@ -64,7 +58,7 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c if (c->number == id) return c; return NULL; -@@ -244,7 +266,7 @@ cipher_number(const char *name) +@@ -273,7 +289,7 @@ cipher_number(const char *name) const struct sshcipher *c; if (name == NULL) return -1; @@ -73,9 +67,9 @@ diff -up openssh-7.2p1/cipher.c.fips openssh-7.2p1/cipher.c if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff -up openssh-7.2p1/cipher-ctr.c.fips openssh-7.2p1/cipher-ctr.c ---- openssh-7.2p1/cipher-ctr.c.fips 2016-02-12 18:53:56.013665228 +0100 -+++ openssh-7.2p1/cipher-ctr.c 2016-02-12 18:53:56.090665235 +0100 +diff -up openssh-7.4p1/cipher-ctr.c.fips openssh-7.4p1/cipher-ctr.c +--- openssh-7.4p1/cipher-ctr.c.fips 2016-12-23 16:37:49.225741551 +0100 ++++ openssh-7.4p1/cipher-ctr.c 2016-12-23 16:37:49.297741585 +0100 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -86,10 +80,10 @@ diff -up openssh-7.2p1/cipher-ctr.c.fips openssh-7.2p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.2p1/dh.h.fips openssh-7.2p1/dh.h ---- openssh-7.2p1/dh.h.fips 2016-02-12 18:53:56.090665235 +0100 -+++ openssh-7.2p1/dh.h 2016-02-12 18:54:48.425670204 +0100 -@@ -49,6 +49,7 @@ u_int dh_estimate(int); +diff -up openssh-7.4p1/dh.h.fips openssh-7.4p1/dh.h +--- openssh-7.4p1/dh.h.fips 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/dh.h 2016-12-23 16:37:49.297741585 +0100 +@@ -51,6 +51,7 @@ u_int dh_estimate(int); * Miniumum increased in light of DH precomputation attacks. */ #define DH_GRP_MIN 2048 @@ -97,9 +91,9 @@ diff -up openssh-7.2p1/dh.h.fips openssh-7.2p1/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh-7.2p1/entropy.c.fips openssh-7.2p1/entropy.c ---- openssh-7.2p1/entropy.c.fips 2016-02-12 18:53:56.005665227 +0100 -+++ openssh-7.2p1/entropy.c 2016-02-12 18:53:56.091665235 +0100 +diff -up openssh-7.4p1/entropy.c.fips openssh-7.4p1/entropy.c +--- openssh-7.4p1/entropy.c.fips 2016-12-23 16:37:49.219741548 +0100 ++++ openssh-7.4p1/entropy.c 2016-12-23 16:37:49.297741585 +0100 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -110,9 +104,9 @@ diff -up openssh-7.2p1/entropy.c.fips openssh-7.2p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c ---- openssh-7.2p1/kex.c.fips 2016-02-12 18:53:56.084665234 +0100 -+++ openssh-7.2p1/kex.c 2016-02-12 18:53:56.091665235 +0100 +diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.fips 2016-12-23 16:37:49.290741582 +0100 ++++ openssh-7.4p1/kex.c 2016-12-23 16:37:49.300741586 +0100 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL #include @@ -121,13 +115,11 @@ diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c #endif #include "ssh2.h" -@@ -121,6 +122,25 @@ static const struct kexalg kexalgs[] = { +@@ -125,6 +126,23 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; +static const struct kexalg kexalgs_fips[] = { -+ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, +#ifdef HAVE_EVP_SHA256 + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif @@ -147,7 +139,7 @@ diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c char * kex_alg_list(char sep) { -@@ -148,7 +168,7 @@ kex_alg_by_name(const char *name) +@@ -152,7 +170,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -156,7 +148,7 @@ diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -174,7 +194,10 @@ kex_names_valid(const char *names) +@@ -178,7 +196,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -168,17 +160,17 @@ diff -up openssh-7.2p1/kex.c.fips openssh-7.2p1/kex.c free(s); return 0; } -diff -up openssh-7.2p1/kexgexc.c.fips openssh-7.2p1/kexgexc.c ---- openssh-7.2p1/kexgexc.c.fips 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/kexgexc.c 2016-02-12 18:53:56.091665235 +0100 +diff -up openssh-7.4p1/kexgexc.c.fips openssh-7.4p1/kexgexc.c +--- openssh-7.4p1/kexgexc.c.fips 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kexgexc.c 2016-12-23 16:38:38.727763540 +0100 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL +#include - #include #include + #include @@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh) nbits = dh_estimate(kex->dh_need * 8); @@ -188,24 +180,24 @@ diff -up openssh-7.2p1/kexgexc.c.fips openssh-7.2p1/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh-7.2p1/kexgexs.c.fips openssh-7.2p1/kexgexs.c ---- openssh-7.2p1/kexgexs.c.fips 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/kexgexs.c 2016-02-12 18:53:56.091665235 +0100 +diff -up openssh-7.4p1/kexgexs.c.fips openssh-7.4p1/kexgexs.c +--- openssh-7.4p1/kexgexs.c.fips 2016-12-23 16:37:49.297741585 +0100 ++++ openssh-7.4p1/kexgexs.c 2016-12-23 16:39:35.009776626 +0100 @@ -83,9 +83,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; kex->min = min; kex->max = max; -- min = MAX(DH_GRP_MIN, min); -+ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); -- nbits = MAX(DH_GRP_MIN, nbits); -+ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); - nbits = MIN(DH_GRP_MAX, nbits); +- min = MAXIMUM(DH_GRP_MIN, min); ++ min = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); + max = MINIMUM(DH_GRP_MAX, max); +- nbits = MAXIMUM(DH_GRP_MIN, nbits); ++ nbits = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); + nbits = MINIMUM(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c ---- openssh-7.2p1/mac.c.fips 2016-02-12 18:53:56.084665234 +0100 -+++ openssh-7.2p1/mac.c 2016-02-12 18:53:56.091665235 +0100 +diff -up openssh-7.4p1/mac.c.fips openssh-7.4p1/mac.c +--- openssh-7.4p1/mac.c.fips 2016-12-23 16:37:49.291741582 +0100 ++++ openssh-7.4p1/mac.c 2016-12-23 16:37:49.298741585 +0100 @@ -27,6 +27,8 @@ #include @@ -224,7 +216,7 @@ diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, -@@ -85,6 +87,24 @@ static const struct macalg macs[] = { +@@ -89,6 +91,24 @@ static const struct macalg macs[] = { { NULL, 0, 0, 0, 0, 0, 0 } }; @@ -249,7 +241,7 @@ diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c /* Returns a list of supported MACs separated by the specified char. */ char * mac_alg_list(char sep) -@@ -93,7 +113,7 @@ mac_alg_list(char sep) +@@ -97,7 +117,7 @@ mac_alg_list(char sep) size_t nlen, rlen = 0; const struct macalg *m; @@ -258,7 +250,7 @@ diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c if (ret != NULL) ret[rlen++] = sep; nlen = strlen(m->name); -@@ -132,7 +152,7 @@ mac_setup(struct sshmac *mac, char *name +@@ -136,7 +156,7 @@ mac_setup(struct sshmac *mac, char *name { const struct macalg *m; @@ -267,10 +259,10 @@ diff -up openssh-7.2p1/mac.c.fips openssh-7.2p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-7.2p1/Makefile.in.fips openssh-7.2p1/Makefile.in ---- openssh-7.2p1/Makefile.in.fips 2016-02-12 18:53:56.085665235 +0100 -+++ openssh-7.2p1/Makefile.in 2016-02-12 18:53:56.092665235 +0100 -@@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) +diff -up openssh-7.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.fips 2016-12-23 16:37:49.291741582 +0100 ++++ openssh-7.4p1/Makefile.in 2016-12-23 16:37:49.298741585 +0100 +@@ -169,25 +169,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) @@ -302,7 +294,7 @@ diff -up openssh-7.2p1/Makefile.in.fips openssh-7.2p1/Makefile.in ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -204,7 +204,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a +@@ -205,7 +205,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o @@ -311,18 +303,16 @@ diff -up openssh-7.2p1/Makefile.in.fips openssh-7.2p1/Makefile.in sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.2p1/myproposal.h.fips openssh-7.2p1/myproposal.h ---- openssh-7.2p1/myproposal.h.fips 2016-02-12 18:53:56.092665235 +0100 -+++ openssh-7.2p1/myproposal.h 2016-02-12 18:55:42.137675304 +0100 -@@ -129,6 +129,28 @@ +diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h +--- openssh-7.4p1/myproposal.h.fips 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/myproposal.h 2016-12-23 16:37:49.300741586 +0100 +@@ -138,6 +138,26 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC +#define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ -+ KEX_SHA2_METHODS \ -+ "diffie-hellman-group-exchange-sha1," \ -+ "diffie-hellman-group14-sha1" ++ KEX_SHA2_METHODS +#define KEX_FIPS_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-cbc,3des-cbc," \ @@ -343,10 +333,10 @@ diff -up openssh-7.2p1/myproposal.h.fips openssh-7.2p1/myproposal.h #else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ -diff -up openssh-7.2p1/readconf.c.fips openssh-7.2p1/readconf.c ---- openssh-7.2p1/readconf.c.fips 2016-02-12 18:53:56.073665234 +0100 -+++ openssh-7.2p1/readconf.c 2016-02-12 18:53:56.092665235 +0100 -@@ -1969,9 +1969,12 @@ fill_default_options(Options * options) +diff -up openssh-7.4p1/readconf.c.fips openssh-7.4p1/readconf.c +--- openssh-7.4p1/readconf.c.fips 2016-12-23 16:37:49.274741574 +0100 ++++ openssh-7.4p1/readconf.c 2016-12-23 16:37:49.298741585 +0100 +@@ -2110,9 +2110,12 @@ fill_default_options(Options * options) } if (options->update_hostkeys == -1) options->update_hostkeys = 0; @@ -362,10 +352,23 @@ diff -up openssh-7.2p1/readconf.c.fips openssh-7.2p1/readconf.c kex_assemble_names(KEX_DEFAULT_PK_ALG, &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -diff -up openssh-7.2p1/servconf.c.fips openssh-7.2p1/servconf.c ---- openssh-7.2p1/servconf.c.fips 2016-02-12 18:53:56.068665233 +0100 -+++ openssh-7.2p1/servconf.c 2016-02-12 18:56:52.185681954 +0100 -@@ -188,9 +188,12 @@ option_clear_or_none(const char *o) +diff -up openssh-7.4p1/sandbox-seccomp-filter.c.fips openssh-7.4p1/sandbox-seccomp-filter.c +--- openssh-7.4p1/sandbox-seccomp-filter.c.fips 2016-12-23 16:37:49.292741583 +0100 ++++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 16:37:49.300741586 +0100 +@@ -118,6 +118,9 @@ static const struct sock_filter preauth_ + #ifdef __NR_open + SC_DENY(open, EACCES), + #endif ++#ifdef __NR_socket ++ SC_DENY(socket, EACCES), ++#endif + #ifdef __NR_openat + SC_DENY(openat, EACCES), + #endif +diff -up openssh-7.4p1/servconf.c.fips openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.fips 2016-12-23 16:37:49.285741579 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 16:37:49.299741586 +0100 +@@ -185,9 +185,12 @@ option_clear_or_none(const char *o) static void assemble_algorithms(ServerOptions *o) { @@ -381,7 +384,7 @@ diff -up openssh-7.2p1/servconf.c.fips openssh-7.2p1/servconf.c kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -@@ -2376,8 +2379,10 @@ dump_config(ServerOptions *o) +@@ -2390,8 +2393,10 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); @@ -394,7 +397,7 @@ diff -up openssh-7.2p1/servconf.c.fips openssh-7.2p1/servconf.c 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); -@@ -2392,8 +2397,8 @@ dump_config(ServerOptions *o) +@@ -2406,8 +2411,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); @@ -405,10 +408,10 @@ diff -up openssh-7.2p1/servconf.c.fips openssh-7.2p1/servconf.c dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? o->hostbased_key_types : KEX_DEFAULT_PK_ALG); dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? -diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c ---- openssh-7.2p1/ssh.c.fips 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/ssh.c 2016-02-12 18:53:56.093665236 +0100 -@@ -75,6 +75,8 @@ +diff -up openssh-7.4p1/ssh.c.fips openssh-7.4p1/ssh.c +--- openssh-7.4p1/ssh.c.fips 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh.c 2016-12-23 16:37:49.299741586 +0100 +@@ -76,6 +76,8 @@ #include #include #endif @@ -417,7 +420,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -531,6 +533,14 @@ main(int ac, char **av) +@@ -530,6 +532,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -432,7 +435,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -608,6 +618,9 @@ main(int ac, char **av) +@@ -609,6 +619,9 @@ main(int ac, char **av) "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -442,7 +445,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c options.protocol = SSH_PROTO_1; break; case '2': -@@ -952,7 +965,6 @@ main(int ac, char **av) +@@ -964,7 +977,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -450,7 +453,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c ERR_load_crypto_strings(); #endif -@@ -1126,6 +1138,10 @@ main(int ac, char **av) +@@ -1175,6 +1187,10 @@ main(int ac, char **av) seed_rng(); @@ -461,7 +464,7 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1206,6 +1222,12 @@ main(int ac, char **av) +@@ -1263,6 +1279,12 @@ main(int ac, char **av) timeout_ms = options.connection_timeout * 1000; @@ -474,9 +477,9 @@ diff -up openssh-7.2p1/ssh.c.fips openssh-7.2p1/ssh.c /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c ---- openssh-7.2p1/sshconnect2.c.fips 2016-02-12 18:53:56.074665234 +0100 -+++ openssh-7.2p1/sshconnect2.c 2016-02-12 18:53:56.094665236 +0100 +diff -up openssh-7.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.fips 2016-12-23 16:37:49.275741574 +0100 ++++ openssh-7.4p1/sshconnect2.c 2016-12-23 16:37:49.299741586 +0100 @@ -44,6 +44,8 @@ #include #endif @@ -486,7 +489,7 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -171,21 +173,26 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -172,21 +174,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -528,9 +531,9 @@ diff -up openssh-7.2p1/sshconnect2.c.fips openssh-7.2p1/sshconnect2.c } } #endif -diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c ---- openssh-7.2p1/sshd.c.fips 2016-02-12 18:53:56.088665235 +0100 -+++ openssh-7.2p1/sshd.c 2016-02-12 18:53:56.094665236 +0100 +diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.fips 2016-12-23 16:37:49.293741583 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 16:37:49.299741586 +0100 @@ -66,6 +66,7 @@ #include #include @@ -548,7 +551,7 @@ diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1555,6 +1558,18 @@ main(int ac, char **av) +@@ -1475,6 +1478,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -567,7 +570,7 @@ diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1707,7 +1722,7 @@ main(int ac, char **av) +@@ -1623,7 +1638,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -576,18 +579,7 @@ diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1906,6 +1921,10 @@ main(int ac, char **av) - sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); - free(fp); - } -+ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { -+ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); -+ options.protocol &= ~SSH_PROTO_1; -+ } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; -@@ -2074,6 +2093,10 @@ main(int ac, char **av) +@@ -1937,6 +1952,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); @@ -598,7 +590,7 @@ diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2695,10 +2718,14 @@ do_ssh2_kex(void) +@@ -2309,10 +2328,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -617,10 +609,10 @@ diff -up openssh-7.2p1/sshd.c.fips openssh-7.2p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c ---- openssh-7.2p1/sshkey.c.fips 2016-02-12 18:53:56.089665235 +0100 -+++ openssh-7.2p1/sshkey.c 2016-02-12 18:53:56.095665236 +0100 -@@ -35,6 +35,7 @@ +diff -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.fips 2016-12-23 16:37:49.293741583 +0100 ++++ openssh-7.4p1/sshkey.c 2016-12-23 16:37:49.300741586 +0100 +@@ -34,6 +34,7 @@ #include #include #include @@ -628,7 +620,7 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c #endif #include "crypto_api.h" -@@ -58,6 +58,7 @@ +@@ -56,6 +57,7 @@ #include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" @@ -636,7 +628,7 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c #include "match.h" #include "xmalloc.h" -@@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1580,6 +1582,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -645,63 +637,3 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff --git a/cipher.c b/cipher.c -index f282907..51bbffb 100644 ---- a/cipher.c -+++ b/cipher.c -@@ -112,12 +112,6 @@ static const struct sshcipher fips_ciphers[] = { - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, --#ifdef OPENSSL_HAVE_EVPGCM -- { "aes128-gcm@openssh.com", -- SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, -- { "aes256-gcm@openssh.com", -- SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, --#endif - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } - }; - -diff --git a/kex.c b/kex.c -index f07a636..4ce5843 100644 ---- a/kex.c -+++ b/kex.c -@@ -123,8 +123,6 @@ static const struct kexalg kexalgs[] = { - }; - - static const struct kexalg kexalgs_fips[] = { -- { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -- { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, - #ifdef HAVE_EVP_SHA256 - { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, - #endif -diff --git a/myproposal.h b/myproposal.h -index 7efe312..bcf2ae1 100644 ---- a/myproposal.h -+++ b/myproposal.h -@@ -131,9 +131,7 @@ - - #define KEX_DEFAULT_KEX_FIPS \ - KEX_ECDH_METHODS \ -- KEX_SHA2_METHODS \ -- "diffie-hellman-group-exchange-sha1," \ -- "diffie-hellman-group14-sha1" -+ KEX_SHA2_METHODS - #define KEX_FIPS_ENCRYPT \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ - "aes128-cbc,3des-cbc," \ -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index a3975eb..5224084 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -112,6 +112,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_open - SC_DENY(open, EACCES), - #endif -+#ifdef __NR_socket -+ SC_DENY(socket, EACCES), -+#endif - #ifdef __NR_openat - SC_DENY(openat, EACCES), - #endif - diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index deb6637..0ab2e04 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.2p1/auth2.c.gsskex openssh-7.2p1/auth2.c ---- openssh-7.2p1/auth2.c.gsskex 2016-02-19 10:01:04.829969345 +0100 -+++ openssh-7.2p1/auth2.c 2016-02-19 10:01:04.865969325 +0100 +diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c +--- openssh-7.4p1/auth2.c.gsskex 2016-12-23 13:38:53.685300997 +0100 ++++ openssh-7.4p1/auth2.c 2016-12-23 13:38:53.725301005 +0100 @@ -70,6 +70,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; @@ -17,9 +17,9 @@ diff -up openssh-7.2p1/auth2.c.gsskex openssh-7.2p1/auth2.c &method_gssapi, #endif &method_passwd, -diff -up openssh-7.2p1/auth2-gss.c.gsskex openssh-7.2p1/auth2-gss.c ---- openssh-7.2p1/auth2-gss.c.gsskex 2016-02-19 10:01:04.829969345 +0100 -+++ openssh-7.2p1/auth2-gss.c 2016-02-19 10:01:04.865969325 +0100 +diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c +--- openssh-7.4p1/auth2-gss.c.gsskex 2016-12-23 13:38:53.685300997 +0100 ++++ openssh-7.4p1/auth2-gss.c 2016-12-23 13:38:53.725301005 +0100 @@ -31,6 +31,7 @@ #include @@ -102,21 +102,10 @@ diff -up openssh-7.2p1/auth2-gss.c.gsskex openssh-7.2p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-7.2p1/auth.c.gsskex openssh-7.2p1/auth.c ---- openssh-7.2p1/auth.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/auth.c 2016-02-19 10:01:04.866969324 +0100 -@@ -354,6 +354,7 @@ auth_root_allowed(const char *method) - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -+ strcmp(method, "gssapi-keyex") == 0 || - strcmp(method, "gssapi-with-mic") == 0) - return 1; - break; -diff -up openssh-7.2p1/clientloop.c.gsskex openssh-7.2p1/clientloop.c ---- openssh-7.2p1/clientloop.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/clientloop.c 2016-02-19 10:01:04.866969324 +0100 -@@ -114,6 +114,10 @@ +diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c +--- openssh-7.4p1/clientloop.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/clientloop.c 2016-12-23 13:38:53.725301005 +0100 +@@ -113,6 +113,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -127,7 +116,7 @@ diff -up openssh-7.2p1/clientloop.c.gsskex openssh-7.2p1/clientloop.c /* import options */ extern Options options; -@@ -1662,9 +1666,18 @@ client_loop(int have_pty, int escape_cha +@@ -1664,9 +1668,18 @@ client_loop(int have_pty, int escape_cha break; /* Do channel operations unless rekeying in progress. */ @@ -137,7 +126,7 @@ diff -up openssh-7.2p1/clientloop.c.gsskex openssh-7.2p1/clientloop.c +#ifdef GSSAPI + if (options.gss_renewal_rekey && -+ ssh_gssapi_credentials_updated(GSS_C_NO_CONTEXT)) { ++ ssh_gssapi_credentials_updated(NULL)) { + debug("credentials updated - forcing rekey"); + need_rekeying = 1; + } @@ -147,10 +136,10 @@ diff -up openssh-7.2p1/clientloop.c.gsskex openssh-7.2p1/clientloop.c /* Buffer input from the connection. */ client_process_net_input(readset); -diff -up openssh-7.2p1/configure.ac.gsskex openssh-7.2p1/configure.ac ---- openssh-7.2p1/configure.ac.gsskex 2016-02-19 10:01:04.857969329 +0100 -+++ openssh-7.2p1/configure.ac 2016-02-19 10:01:04.867969323 +0100 -@@ -632,6 +632,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +diff -up openssh-7.4p1/configure.ac.gsskex openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.gsskex 2016-12-23 13:38:53.716301003 +0100 ++++ openssh-7.4p1/configure.ac 2016-12-23 13:38:53.726301005 +0100 +@@ -623,6 +623,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -181,10 +170,10 @@ diff -up openssh-7.2p1/configure.ac.gsskex openssh-7.2p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c ---- openssh-7.2p1/gss-genr.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/gss-genr.c 2016-02-19 10:01:04.867969323 +0100 -@@ -41,12 +41,167 @@ +diff -up openssh-7.4p1/gss-genr.c.gsskex openssh-7.4p1/gss-genr.c +--- openssh-7.4p1/gss-genr.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/gss-genr.c 2016-12-23 13:38:53.726301005 +0100 +@@ -40,12 +40,167 @@ #include "buffer.h" #include "log.h" #include "ssh2.h" @@ -352,7 +341,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -199,7 +354,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de +@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -361,7 +350,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -229,8 +384,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -228,8 +383,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -404,7 +393,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -238,6 +427,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -424,7 +413,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) -@@ -251,11 +453,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha +@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha } int @@ -442,7 +431,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -265,6 +472,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -264,6 +471,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -453,7 +442,7 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -274,10 +485,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -521,9 +510,9 @@ diff -up openssh-7.2p1/gss-genr.c.gsskex openssh-7.2p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-7.2p1/gss-serv.c.gsskex openssh-7.2p1/gss-serv.c ---- openssh-7.2p1/gss-serv.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/gss-serv.c 2016-02-19 10:01:04.867969323 +0100 +diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c +--- openssh-7.4p1/gss-serv.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/gss-serv.c 2016-12-23 13:38:53.727301005 +0100 @@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" @@ -536,9 +525,10 @@ diff -up openssh-7.2p1/gss-serv.c.gsskex openssh-7.2p1/gss-serv.c extern ServerOptions options; static ssh_gssapi_client gssapi_client = - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, +- { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; -+ GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, {NULL, NULL, NULL}, 0, 0}; ++ { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, ++ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; ssh_gssapi_mech gssapi_null_mech = - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; @@ -546,17 +536,16 @@ diff -up openssh-7.2p1/gss-serv.c.gsskex openssh-7.2p1/gss-serv.c #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -142,6 +144,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss +@@ -142,6 +144,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss } /* Unprivileged */ +char * +ssh_gssapi_server_mechanisms() { -+ gss_OID_set supported; -+ -+ ssh_gssapi_supported_oids(&supported); -+ return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, -+ NULL, NULL)); ++ if (supported_oids == NULL) ++ ssh_gssapi_prepare_supported_oids(); ++ return (ssh_gssapi_kex_mechs(supported_oids, ++ &ssh_gssapi_server_check_mech, NULL, NULL)); +} + +/* Unprivileged */ @@ -806,9 +795,9 @@ diff -up openssh-7.2p1/gss-serv.c.gsskex openssh-7.2p1/gss-serv.c } #endif -diff -up openssh-7.2p1/gss-serv-krb5.c.gsskex openssh-7.2p1/gss-serv-krb5.c ---- openssh-7.2p1/gss-serv-krb5.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/gss-serv-krb5.c 2016-02-19 10:01:04.867969323 +0100 +diff -up openssh-7.4p1/gss-serv-krb5.c.gsskex openssh-7.4p1/gss-serv-krb5.c +--- openssh-7.4p1/gss-serv-krb5.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 13:38:53.727301005 +0100 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -936,9 +925,9 @@ diff -up openssh-7.2p1/gss-serv-krb5.c.gsskex openssh-7.2p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-7.2p1/kex.c.gsskex openssh-7.2p1/kex.c ---- openssh-7.2p1/kex.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/kex.c 2016-02-19 10:01:04.868969323 +0100 +diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kex.c 2016-12-23 13:39:56.064313151 +0100 @@ -54,6 +54,10 @@ #include "sshbuf.h" #include "digest.h" @@ -950,9 +939,9 @@ diff -up openssh-7.2p1/kex.c.gsskex openssh-7.2p1/kex.c #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 -@@ -107,6 +111,11 @@ static const struct kexalg kexalgs[] = { - #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) +@@ -111,6 +115,11 @@ static const struct kexalg kexalgs[] = { { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ +#ifdef GSSAPI + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, @@ -962,7 +951,7 @@ diff -up openssh-7.2p1/kex.c.gsskex openssh-7.2p1/kex.c { NULL, -1, -1, -1}, }; -@@ -140,6 +149,12 @@ kex_alg_by_name(const char *name) +@@ -144,6 +153,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -975,9 +964,9 @@ diff -up openssh-7.2p1/kex.c.gsskex openssh-7.2p1/kex.c } return NULL; } -diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c ---- openssh-7.2p1/kexgssc.c.gsskex 2016-02-19 10:01:04.868969323 +0100 -+++ openssh-7.2p1/kexgssc.c 2016-02-19 10:01:04.868969323 +0100 +diff -up openssh-7.4p1/kexgssc.c.gsskex openssh-7.4p1/kexgssc.c +--- openssh-7.4p1/kexgssc.c.gsskex 2016-12-23 13:38:53.727301005 +0100 ++++ openssh-7.4p1/kexgssc.c 2016-12-23 13:38:53.727301005 +0100 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1317,9 +1306,9 @@ diff -up openssh-7.2p1/kexgssc.c.gsskex openssh-7.2p1/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c ---- openssh-7.2p1/kexgsss.c.gsskex 2016-02-19 10:01:04.868969323 +0100 -+++ openssh-7.2p1/kexgsss.c 2016-02-19 10:01:04.868969323 +0100 +diff -up openssh-7.4p1/kexgsss.c.gsskex openssh-7.4p1/kexgsss.c +--- openssh-7.4p1/kexgsss.c.gsskex 2016-12-23 13:38:53.728301005 +0100 ++++ openssh-7.4p1/kexgsss.c 2016-12-23 13:38:53.728301005 +0100 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1618,10 +1607,10 @@ diff -up openssh-7.2p1/kexgsss.c.gsskex openssh-7.2p1/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h ---- openssh-7.2p1/kex.h.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/kex.h 2016-02-19 10:01:04.868969323 +0100 -@@ -92,6 +92,11 @@ enum kex_exchange { +diff -up openssh-7.4p1/kex.h.gsskex openssh-7.4p1/kex.h +--- openssh-7.4p1/kex.h.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kex.h 2016-12-23 13:38:53.728301005 +0100 +@@ -99,6 +99,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, @@ -1633,7 +1622,7 @@ diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h KEX_MAX }; -@@ -140,6 +145,12 @@ struct kex { +@@ -147,6 +152,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1646,7 +1635,7 @@ diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h char *client_version_string; char *server_version_string; char *failed_choice; -@@ -189,6 +200,10 @@ int kexecdh_client(struct ssh *); +@@ -196,6 +207,10 @@ int kexecdh_client(struct ssh *); int kexecdh_server(struct ssh *); int kexc25519_client(struct ssh *); int kexc25519_server(struct ssh *); @@ -1657,10 +1646,10 @@ diff -up openssh-7.2p1/kex.h.gsskex openssh-7.2p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh/Makefile.in.gsskex openssh/Makefile.in ---- openssh/Makefile.in.gsskex 2016-07-25 14:11:42.978324182 +0200 -+++ openssh/Makefile.in 2016-07-25 14:14:15.560289050 +0200 -@@ -90,6 +90,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-7.4p1/Makefile.in.gsskex openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.gsskex 2016-12-23 13:38:53.723301004 +0100 ++++ openssh-7.4p1/Makefile.in 2016-12-23 13:40:32.226320197 +0100 +@@ -91,6 +91,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ @@ -1668,19 +1657,19 @@ diff -up openssh/Makefile.in.gsskex openssh/Makefile.in msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o \ -@@ -111,7 +112,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw +@@ -112,7 +113,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.o monitor.o monitor_wrap.o auth-krb5.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 \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c ---- openssh-7.2p1/monitor.c.gsskex 2016-02-19 10:01:04.830969345 +0100 -+++ openssh-7.2p1/monitor.c 2016-02-19 10:01:04.869969322 +0100 -@@ -159,6 +159,8 @@ int mm_answer_gss_setup_ctx(int, Buffer +diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.gsskex 2016-12-23 13:38:53.687300997 +0100 ++++ openssh-7.4p1/monitor.c 2016-12-23 13:45:49.347381091 +0100 +@@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1689,10 +1678,10 @@ diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c #endif #ifdef SSH_AUDIT_EVENTS -@@ -239,11 +241,18 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, - {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, +@@ -236,11 +238,18 @@ struct mon_table mon_dispatch_proto20[] + {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, + {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, + {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, #endif {0, 0, NULL} @@ -1708,29 +1697,29 @@ diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -358,6 +367,10 @@ monitor_child_preauth(Authctxt *_authctx - /* Permit requests for moduli and signatures */ - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +@@ -307,6 +316,10 @@ monitor_child_preauth(Authctxt *_authctx + /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +#ifdef GSSAPI -+ /* and for the GSSAPI key exchange */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++ /* and for the GSSAPI key exchange */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); +#endif - } else { - mon_dispatch = mon_dispatch_proto15; -@@ -466,6 +479,10 @@ monitor_child_postauth(struct monitor *p - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); + /* The first few requests do not require asynchronous access */ + while (!authenticated) { +@@ -406,6 +419,10 @@ monitor_child_postauth(struct monitor *p + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); +#ifdef GSSAPI -+ /* and for the GSSAPI key exchange */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++ /* and for the GSSAPI key exchange */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); +#endif - } else { - mon_dispatch = mon_dispatch_postauth15; - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1893,6 +1910,13 @@ monitor_apply_keystate(struct monitor *p + + if (!no_pty_flag) { + monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); +@@ -1633,6 +1650,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1744,27 +1733,25 @@ diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1992,6 +2016,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -1712,7 +1736,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; +- if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("In GSSAPI monitor when GSSAPI is disabled"); -+ - goid.elements = buffer_get_string(m, &len); - goid.length = len; + fatal("%s: GSSAPI authentication not enabled", __func__); -@@ -2019,6 +2046,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe + goid.elements = buffer_get_string(m, &len); +@@ -1742,7 +1766,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; +- if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("In GSSAPI monitor when GSSAPI is disabled"); -+ + fatal("%s: GSSAPI authentication not enabled", __func__); + in.value = buffer_get_string(m, &len); - in.length = len; - major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2036,6 +2066,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -1762,6 +1786,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1772,30 +1759,30 @@ diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c } return (0); } -@@ -2047,6 +2078,9 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -1773,7 +1798,7 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; +- if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("In GSSAPI monitor when GSSAPI is disabled"); -+ + fatal("%s: GSSAPI authentication not enabled", __func__); + gssbuf.value = buffer_get_string(m, &len); - gssbuf.length = len; - mic.value = buffer_get_string(m, &len); -@@ -2073,7 +2107,11 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1802,10 +1827,11 @@ mm_answer_gss_userok(int sock, Buffer *m { int authenticated; -- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); +- if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("In GSSAPI monitor when GSSAPI is disabled"); -+ -+ authenticated = authctxt->valid && + fatal("%s: GSSAPI authentication not enabled", __func__); + +- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); ++ authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw); buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2086,5 +2124,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1818,5 +1844,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1869,9 +1856,9 @@ diff -up openssh-7.2p1/monitor.c.gsskex openssh-7.2p1/monitor.c + #endif /* GSSAPI */ -diff -up openssh-7.2p1/monitor.h.gsskex openssh-7.2p1/monitor.h ---- openssh-7.2p1/monitor.h.gsskex 2016-02-19 10:01:04.830969345 +0100 -+++ openssh-7.2p1/monitor.h 2016-02-19 10:01:04.869969322 +0100 +diff -up openssh-7.4p1/monitor.h.gsskex openssh-7.4p1/monitor.h +--- openssh-7.4p1/monitor.h.gsskex 2016-12-23 13:38:53.687300997 +0100 ++++ openssh-7.4p1/monitor.h 2016-12-23 13:38:53.729301005 +0100 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1881,10 +1868,10 @@ diff -up openssh-7.2p1/monitor.h.gsskex openssh-7.2p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-7.2p1/monitor_wrap.c.gsskex openssh-7.2p1/monitor_wrap.c ---- openssh-7.2p1/monitor_wrap.c.gsskex 2016-02-19 10:01:04.830969345 +0100 -+++ openssh-7.2p1/monitor_wrap.c 2016-02-19 10:01:04.869969322 +0100 -@@ -1087,7 +1087,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.gsskex 2016-12-23 13:38:53.687300997 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2016-12-23 13:38:53.729301005 +0100 +@@ -943,7 +943,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1893,7 +1880,7 @@ diff -up openssh-7.2p1/monitor_wrap.c.gsskex openssh-7.2p1/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -1104,5 +1104,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -960,5 +960,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1944,10 +1931,10 @@ diff -up openssh-7.2p1/monitor_wrap.c.gsskex openssh-7.2p1/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh-7.2p1/monitor_wrap.h.gsskex openssh-7.2p1/monitor_wrap.h ---- openssh-7.2p1/monitor_wrap.h.gsskex 2016-02-19 10:01:04.830969345 +0100 -+++ openssh-7.2p1/monitor_wrap.h 2016-02-19 10:01:04.869969322 +0100 -@@ -61,8 +61,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K +diff -up openssh-7.4p1/monitor_wrap.h.gsskex openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1/monitor_wrap.h.gsskex 2016-12-23 13:38:53.687300997 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2016-12-23 13:38:53.729301005 +0100 +@@ -58,8 +58,10 @@ int mm_key_verify(Key *, u_char *, u_int OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1959,10 +1946,10 @@ diff -up openssh-7.2p1/monitor_wrap.h.gsskex openssh-7.2p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c ---- openssh-7.2p1/readconf.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/readconf.c 2016-02-19 10:01:04.870969322 +0100 -@@ -148,6 +148,8 @@ typedef enum { +diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c +--- openssh-7.4p1/readconf.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/readconf.c 2016-12-23 13:38:53.730301005 +0100 +@@ -160,6 +160,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -1971,7 +1958,7 @@ diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -193,10 +195,19 @@ static struct { +@@ -205,10 +207,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1991,7 +1978,7 @@ diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, -@@ -926,10 +937,30 @@ parse_time: +@@ -961,10 +972,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2022,7 +2009,7 @@ diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1648,7 +1679,12 @@ initialize_options(Options * options) +@@ -1776,7 +1807,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2035,7 +2022,7 @@ diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1777,8 +1813,14 @@ fill_default_options(Options * options) +@@ -1920,8 +1956,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2050,9 +2037,9 @@ diff -up openssh-7.2p1/readconf.c.gsskex openssh-7.2p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-7.2p1/readconf.h.gsskex openssh-7.2p1/readconf.h ---- openssh-7.2p1/readconf.h.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/readconf.h 2016-02-19 10:01:04.870969322 +0100 +diff -up openssh-7.4p1/readconf.h.gsskex openssh-7.4p1/readconf.h +--- openssh-7.4p1/readconf.h.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/readconf.h 2016-12-23 13:38:53.730301005 +0100 @@ -45,7 +45,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2066,9 +2053,9 @@ diff -up openssh-7.2p1/readconf.h.gsskex openssh-7.2p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh ---- openssh/regress/cert-hostkey.sh.gsskex 2016-07-25 14:11:42.986324181 +0200 -+++ openssh/regress/cert-hostkey.sh 2016-07-25 14:15:17.784274722 +0200 +diff -up openssh-7.4p1/regress/cert-hostkey.sh.gsskex openssh-7.4p1/regress/cert-hostkey.sh +--- openssh-7.4p1/regress/cert-hostkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/cert-hostkey.sh 2016-12-23 13:38:53.731301006 +0100 @@ -59,7 +59,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca @@ -2078,9 +2065,9 @@ diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh ---- openssh/regress/cert-userkey.sh.gsskex 2016-07-25 14:11:42.986324181 +0200 -+++ openssh/regress/cert-userkey.sh 2016-07-25 14:15:36.769270354 +0200 +diff -up openssh-7.4p1/regress/cert-userkey.sh.gsskex openssh-7.4p1/regress/cert-userkey.sh +--- openssh-7.4p1/regress/cert-userkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/cert-userkey.sh 2016-12-23 13:38:53.731301006 +0100 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2090,9 +2077,9 @@ diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh ---- openssh/regress/kextype.sh.gsskex 2016-07-24 13:50:13.000000000 +0200 -+++ openssh/regress/kextype.sh 2016-07-25 14:11:42.987324180 +0200 +diff -up openssh-7.4p1/regress/kextype.sh.gsskex openssh-7.4p1/regress/kextype.sh +--- openssh-7.4p1/regress/kextype.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/kextype.sh 2016-12-23 13:38:53.731301006 +0100 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2103,9 +2090,9 @@ diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh-7.2p1/regress/rekey.sh.gsskex openssh-7.2p1/regress/rekey.sh ---- openssh-7.2p1/regress/rekey.sh.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/regress/rekey.sh 2016-02-19 10:01:04.870969322 +0100 +diff -up openssh-7.4p1/regress/rekey.sh.gsskex openssh-7.4p1/regress/rekey.sh +--- openssh-7.4p1/regress/rekey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/rekey.sh 2016-12-23 13:38:53.731301006 +0100 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2126,10 +2113,10 @@ diff -up openssh-7.2p1/regress/rekey.sh.gsskex openssh-7.2p1/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c ---- openssh-7.2p1/servconf.c.gsskex 2016-02-19 10:01:04.857969329 +0100 -+++ openssh-7.2p1/servconf.c 2016-02-19 10:01:04.870969322 +0100 -@@ -117,8 +117,10 @@ initialize_server_options(ServerOptions +diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.gsskex 2016-12-23 13:38:53.717301003 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 13:38:53.732301006 +0100 +@@ -113,8 +113,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -2140,7 +2127,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -288,10 +290,14 @@ fill_default_server_options(ServerOption +@@ -268,10 +270,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2155,7 +2142,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -422,7 +428,7 @@ typedef enum { +@@ -410,7 +416,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -2164,7 +2151,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -496,11 +502,17 @@ static struct { +@@ -484,11 +490,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2182,7 +2169,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1246,6 +1258,10 @@ process_server_config_line(ServerOptions +@@ -1211,6 +1223,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2193,7 +2180,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1254,6 +1270,10 @@ process_server_config_line(ServerOptions +@@ -1219,6 +1235,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2204,7 +2191,7 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2274,6 +2294,9 @@ dump_config(ServerOptions *o) +@@ -2257,6 +2277,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2214,10 +2201,10 @@ diff -up openssh-7.2p1/servconf.c.gsskex openssh-7.2p1/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-7.2p1/servconf.h.gsskex openssh-7.2p1/servconf.h ---- openssh-7.2p1/servconf.h.gsskex 2016-02-19 10:01:04.857969329 +0100 -+++ openssh-7.2p1/servconf.h 2016-02-19 10:01:04.871969321 +0100 -@@ -118,8 +118,10 @@ typedef struct { +diff -up openssh-7.4p1/servconf.h.gsskex openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.gsskex 2016-12-23 13:38:53.717301003 +0100 ++++ openssh-7.4p1/servconf.h 2016-12-23 13:38:53.732301006 +0100 +@@ -112,8 +112,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2228,31 +2215,26 @@ diff -up openssh-7.2p1/servconf.h.gsskex openssh-7.2p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-7.2p1/ssh_config.5.gsskex openssh-7.2p1/ssh_config.5 ---- openssh-7.2p1/ssh_config.5.gsskex 2016-02-19 10:01:04.871969321 +0100 -+++ openssh-7.2p1/ssh_config.5 2016-02-19 10:05:58.630146245 +0100 -@@ -824,10 +824,40 @@ The default is +diff -up openssh-7.4p1/ssh_config.5.gsskex openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1/ssh_config.5.gsskex 2016-12-23 13:38:53.732301006 +0100 ++++ openssh-7.4p1/ssh_config.5 2016-12-23 13:48:00.502331870 +0100 +@@ -748,10 +748,40 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is - .Dq no . + .Cm no . ++.It Cm GSSAPIClientIdentity ++If set, specifies the GSSAPI client identity that ssh should use when ++connecting to the server. The default is unset, which means that the default ++identity will be used. + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is + .Cm no . +.It Cm GSSAPIKeyExchange +Specifies whether key exchange based on GSSAPI may be used. When using +GSSAPI key exchange the server need not have a host key. +The default is +.Dq no . -+.It Cm GSSAPIClientIdentity -+If set, specifies the GSSAPI client identity that ssh should use when -+connecting to the server. The default is unset, which means that the default -+identity will be used. -+.It Cm GSSAPIServerIdentity -+If set, specifies the GSSAPI server identity that ssh should expect when -+connecting to the server. The default is unset, which means that the -+expected GSSAPI server identity will be determined from the target -+hostname. - .It Cm GSSAPIDelegateCredentials - Forward (delegate) credentials to the server. - The default is - .Dq no . +.It Cm GSSAPIRenewalForcesRekey +If set to +.Dq yes @@ -2261,6 +2243,11 @@ diff -up openssh-7.2p1/ssh_config.5.gsskex openssh-7.2p1/ssh_config.5 +credentials to a session on the server. +The default is +.Dq no . ++.It Cm GSSAPIServerIdentity ++If set, specifies the GSSAPI server identity that ssh should expect when ++connecting to the server. The default is unset, which means that the ++expected GSSAPI server identity will be determined from the target ++hostname. +.It Cm GSSAPITrustDns +Set to +.Dq yes to indicate that the DNS is trusted to securely canonicalize @@ -2272,9 +2259,9 @@ diff -up openssh-7.2p1/ssh_config.5.gsskex openssh-7.2p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-7.2p1/ssh_config.gsskex openssh-7.2p1/ssh_config ---- openssh-7.2p1/ssh_config.gsskex 2016-02-19 10:01:04.852969332 +0100 -+++ openssh-7.2p1/ssh_config 2016-02-19 10:01:04.871969321 +0100 +diff -up openssh-7.4p1/ssh_config.gsskex openssh-7.4p1/ssh_config +--- openssh-7.4p1/ssh_config.gsskex 2016-12-23 13:38:53.708301001 +0100 ++++ openssh-7.4p1/ssh_config 2016-12-23 13:38:53.733301006 +0100 @@ -26,6 +26,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -2284,10 +2271,10 @@ diff -up openssh-7.2p1/ssh_config.gsskex openssh-7.2p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c ---- openssh-7.2p1/sshconnect2.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/sshconnect2.c 2016-02-19 10:01:04.872969321 +0100 -@@ -161,9 +161,34 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshconnect2.c 2016-12-23 13:38:53.733301006 +0100 +@@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2322,7 +2309,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -195,6 +220,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -192,6 +217,17 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2380,7 +2367,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c #endif void userauth(Authctxt *, char *); -@@ -326,6 +383,11 @@ static char *authmethods_get(void); +@@ -327,6 +384,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2392,7 +2379,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -656,19 +718,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -652,19 +714,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2426,7 +2413,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -765,8 +839,8 @@ input_gssapi_response(int type, u_int32_ +@@ -761,8 +835,8 @@ input_gssapi_response(int type, u_int32_ { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; @@ -2437,7 +2424,7 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -879,6 +953,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -875,6 +949,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); return 0; } @@ -2489,6 +2476,15 @@ diff -up openssh-7.2p1/sshconnect2.c.gsskex openssh-7.2p1/sshconnect2.c diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c --- openssh-7.2p1/sshd.c.gsskex 2016-02-19 10:01:04.860969328 +0100 +++ openssh-7.2p1/sshd.c 2016-02-19 10:01:04.872969321 +0100 +@@ -547,7 +547,7 @@ privsep_preauth_child(void) + + #ifdef GSSAPI + /* Cache supported mechanism OIDs for later use */ +- if (options.gss_authentication) ++ if (options.gss_authentication || options.gss_keyex) + ssh_gssapi_prepare_supported_oids(); + #endif + @@ -974,8 +974,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %d hostkeys", __func__, nkeys); @@ -2501,21 +2497,17 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c sshbuf_free(buf); } -@@ -1845,10 +1846,13 @@ main(int ac, char **av) - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; +@@ -1739,7 +1740,8 @@ main(int ac, char **av) + key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); + free(fp); } -+#ifndef GSSAPI +- if (!sensitive_data.have_ssh2_key) { + /* The GSSAPI key exchange can run without a host key */ - if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { - logit("Disabling protocol version 2. Could not load host key"); - options.protocol &= ~SSH_PROTO_2; - } -+#endif - if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { ++ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2586,6 +2590,48 @@ do_ssh2_kex(void) + } +@@ -2196,6 +2198,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2564,7 +2556,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2600,6 +2646,13 @@ do_ssh2_kex(void) +@@ -2213,6 +2257,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2578,25 +2570,25 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-7.2p1/sshd_config.5.gsskex openssh-7.2p1/sshd_config.5 ---- openssh-7.2p1/sshd_config.5.gsskex 2016-02-19 10:01:04.858969329 +0100 -+++ openssh-7.2p1/sshd_config.5 2016-02-19 10:06:26.651172355 +0100 -@@ -623,6 +623,11 @@ The default is - Specifies whether user authentication based on GSSAPI is allowed. +diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.gsskex 2016-12-23 13:38:53.734301006 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 13:48:57.825310358 +0100 +@@ -628,6 +628,11 @@ Specifies whether to automatically destr + on logout. The default is - .Dq no . + .Cm yes . +.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. +The default is +.Dq no . - .It Cm GSSAPICleanupCredentials - Specifies whether to automatically destroy the user's credentials cache - on logout. -@@ -643,6 +648,11 @@ machine's default store. + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -642,6 +647,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is - .Dq yes . + .Cm yes . +.It Cm GSSAPIStoreCredentialsOnRekey +Controls whether the user's GSSAPI credentials should be updated following a +successful connection rekeying. This option can be used to accepted renewed @@ -2605,10 +2597,10 @@ diff -up openssh-7.2p1/sshd_config.5.gsskex openssh-7.2p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -diff -up openssh-7.2p1/sshd_config.gsskex openssh-7.2p1/sshd_config ---- openssh-7.2p1/sshd_config.gsskex 2016-02-19 10:01:04.860969328 +0100 -+++ openssh-7.2p1/sshd_config 2016-02-19 10:01:04.873969320 +0100 -@@ -91,6 +91,8 @@ ChallengeResponseAuthentication no +diff -up openssh-7.4p1/sshd_config.gsskex openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.gsskex 2016-12-23 13:38:53.719301003 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 13:38:53.734301006 +0100 +@@ -77,6 +77,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes GSSAPICleanupCredentials no @@ -2617,9 +2609,9 @@ diff -up openssh-7.2p1/sshd_config.gsskex openssh-7.2p1/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-7.2p1/ssh-gss.h.gsskex openssh-7.2p1/ssh-gss.h ---- openssh-7.2p1/ssh-gss.h.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/ssh-gss.h 2016-02-19 10:01:04.873969320 +0100 +diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h +--- openssh-7.4p1/ssh-gss.h.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-gss.h 2016-12-23 13:38:53.734301006 +0100 @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* @@ -2719,10 +2711,10 @@ diff -up openssh-7.2p1/ssh-gss.h.gsskex openssh-7.2p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -up openssh-7.2p1/sshkey.c.gsskex openssh-7.2p1/sshkey.c ---- openssh-7.2p1/sshkey.c.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/sshkey.c 2016-02-19 10:01:04.874969320 +0100 -@@ -115,6 +115,7 @@ static const struct keytype keytypes[] = +diff -up openssh-7.4p1/sshkey.c.gsskex openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshkey.c 2016-12-23 13:38:53.735301006 +0100 +@@ -114,6 +114,7 @@ static const struct keytype keytypes[] = # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2730,9 +2722,9 @@ diff -up openssh-7.2p1/sshkey.c.gsskex openssh-7.2p1/sshkey.c { NULL, NULL, -1, -1, 0, 0 } }; -diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h ---- openssh-7.2p1/sshkey.h.gsskex 2016-02-12 11:47:25.000000000 +0100 -+++ openssh-7.2p1/sshkey.h 2016-02-19 10:01:04.874969320 +0100 +diff -up openssh-7.4p1/sshkey.h.gsskex openssh-7.4p1/sshkey.h +--- openssh-7.4p1/sshkey.h.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshkey.h 2016-12-23 13:38:53.735301006 +0100 @@ -62,6 +62,7 @@ enum sshkey_types { KEY_DSA_CERT, KEY_ECDSA_CERT, @@ -2741,11 +2733,18 @@ diff -up openssh-7.2p1/sshkey.h.gsskex openssh-7.2p1/sshkey.h KEY_UNSPEC }; -diff --git a/auth.c b/auth.c -index e0f7639..a5a346e 100644 ---- a/auth.c -+++ b/auth.c -@@ -784,99 +784,6 @@ fakepw(void) +diff -up openssh-7.4p1/auth.c.gsskex openssh-7.4p1/auth.c +--- openssh-7.4p1/auth.c.gsskex 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth.c 2016-12-23 13:38:53.735301006 +0100 +@@ -372,6 +372,7 @@ auth_root_allowed(const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || ++ strcmp(method, "gssapi-keyex") == 0 || + strcmp(method, "gssapi-with-mic") == 0) + return 1; + break; +@@ -795,99 +796,6 @@ fakepw(void) } /* @@ -2845,11 +2844,10 @@ index e0f7639..a5a346e 100644 * 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/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 80729b3..93a1b04 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -32,6 +32,8 @@ +diff -up openssh-7.4p1/openbsd-compat/port-linux.c.gsskex openssh-7.4p1/openbsd-compat/port-linux.c +--- openssh-7.4p1/openbsd-compat/port-linux.c.gsskex 2016-12-23 13:38:53.688300997 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.c 2016-12-23 13:38:53.735301006 +0100 +@@ -30,6 +30,8 @@ #include "log.h" #include "xmalloc.h" #include "port-linux.h" @@ -2858,7 +2856,7 @@ index 80729b3..93a1b04 100644 #ifdef WITH_SELINUX #include -@@ -286,4 +288,121 @@ oom_adjust_restore(void) +@@ -279,4 +281,121 @@ oom_adjust_restore(void) return; } #endif /* LINUX_OOM_ADJUST */ @@ -2980,11 +2978,10 @@ index 80729b3..93a1b04 100644 + } +} #endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index e2ca8a1..6c5ac3f 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -18,6 +18,7 @@ +diff -up openssh-7.4p1/openbsd-compat/port-linux.h.gsskex openssh-7.4p1/openbsd-compat/port-linux.h +--- openssh-7.4p1/openbsd-compat/port-linux.h.gsskex 2016-12-23 13:38:53.712301002 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 13:38:53.735301006 +0100 +@@ -16,6 +16,7 @@ #ifndef _PORT_LINUX_H #define _PORT_LINUX_H @@ -2992,7 +2989,7 @@ index e2ca8a1..6c5ac3f 100644 #ifdef WITH_SELINUX int ssh_selinux_enabled(void); -@@ -39,4 +40,8 @@ void oom_adjust_setup(void); +@@ -36,4 +37,8 @@ void oom_adjust_setup(void); void linux_seed(void); @@ -3001,18 +2998,3 @@ index e2ca8a1..6c5ac3f 100644 + + #endif /* ! _PORT_LINUX_H */ - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 3e6f982..4c2653f 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -213,6 +213,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_write - SC_ALLOW(write), - #endif -+#ifdef __NR_futex -+ SC_ALLOW(futex), /* for GSSAPI Kex */ -+#endif - #ifdef __NR_socketcall - SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), - #endif diff --git a/openssh-7.2p2-UsePAM-UseLogin-warning.patch b/openssh-7.2p2-UsePAM-UseLogin-warning.patch index 9d01df9..b3038ea 100644 --- a/openssh-7.2p2-UsePAM-UseLogin-warning.patch +++ b/openssh-7.2p2-UsePAM-UseLogin-warning.patch @@ -1,14 +1,10 @@ diff --git a/sshd.c b/sshd.c --- a/sshd.c +++ b/sshd.c -@@ -1701,6 +1701,14 @@ main(int ac, char **av) +@@ -1701,6 +1701,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, &cfg, NULL); -+ /* 'UseLogin yes' is not supported in Fedora */ -+ if (options.use_login == 1) -+ logit("WARNING: 'UseLogin yes' is not supported in Fedora and may cause several problems."); -+ + /* '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."); @@ -28,12 +24,3 @@ diff --git a/sshd_config b/sshd_config UsePAM yes #AllowAgentForwarding yes -@@ -113,6 +115,8 @@ X11Forwarding yes - #PrintMotd yes - #PrintLastLog yes - #TCPKeepAlive yes -+# WARNING: 'UseLogin yes' is not supported in Fedora and may cause several -+# problems. - #UseLogin no - #UsePrivilegeSeparation sandbox - #PermitUserEnvironment no diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch index a2dfdd3..c593f68 100644 --- a/openssh-7.2p2-expose-pam.patch +++ b/openssh-7.2p2-expose-pam.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.2p2/auth2.c.expose-pam openssh-7.2p2/auth2.c ---- openssh-7.2p2/auth2.c.expose-pam 2016-07-18 12:30:12.064783302 +0200 -+++ openssh-7.2p2/auth2.c 2016-07-18 12:30:12.124783255 +0200 +diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c +--- openssh-7.4p1/auth2.c.expose-pam 2016-12-23 15:40:26.768447868 +0100 ++++ openssh-7.4p1/auth2.c 2016-12-23 15:40:26.818447876 +0100 @@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int const char *submethod) { @@ -28,9 +28,9 @@ diff -up openssh-7.2p2/auth2.c.expose-pam openssh-7.2p2/auth2.c #ifdef USE_PAM if (options.use_pam && authenticated) { if (!PRIVSEP(do_pam_account())) { -diff -up openssh-7.2p2/auth2-gss.c.expose-pam openssh-7.2p2/auth2-gss.c ---- openssh-7.2p2/auth2-gss.c.expose-pam 2016-07-18 12:30:12.123783256 +0200 -+++ openssh-7.2p2/auth2-gss.c 2016-07-18 12:32:08.034692086 +0200 +diff -up openssh-7.4p1/auth2-gss.c.expose-pam openssh-7.4p1/auth2-gss.c +--- openssh-7.4p1/auth2-gss.c.expose-pam 2016-12-23 15:40:26.769447868 +0100 ++++ openssh-7.4p1/auth2-gss.c 2016-12-23 15:40:26.818447876 +0100 @@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); @@ -51,9 +51,9 @@ diff -up openssh-7.2p2/auth2-gss.c.expose-pam openssh-7.2p2/auth2-gss.c buffer_free(&b); if (micuser != authctxt->user) free(micuser); -diff -up openssh-7.2p2/auth2-hostbased.c.expose-pam openssh-7.2p2/auth2-hostbased.c ---- openssh-7.2p2/auth2-hostbased.c.expose-pam 2016-07-18 12:30:12.027783331 +0200 -+++ openssh-7.2p2/auth2-hostbased.c 2016-07-18 12:30:12.124783255 +0200 +diff -up openssh-7.4p1/auth2-hostbased.c.expose-pam openssh-7.4p1/auth2-hostbased.c +--- openssh-7.4p1/auth2-hostbased.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 ++++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 15:40:26.818447876 +0100 @@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) { Buffer b; @@ -88,9 +88,9 @@ diff -up openssh-7.2p2/auth2-hostbased.c.expose-pam openssh-7.2p2/auth2-hostbase buffer_free(&b); done: -diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c ---- openssh-7.2p2/auth2-pubkey.c.expose-pam 2016-07-18 12:30:12.039783322 +0200 -+++ openssh-7.2p2/auth2-pubkey.c 2016-07-18 12:30:12.124783255 +0200 +diff -up openssh-7.4p1/auth2-pubkey.c.expose-pam openssh-7.4p1/auth2-pubkey.c +--- openssh-7.4p1/auth2-pubkey.c.expose-pam 2016-12-23 15:40:26.746447864 +0100 ++++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 15:40:26.819447876 +0100 @@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) { Buffer b; @@ -100,7 +100,7 @@ diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; -@@ -173,7 +173,8 @@ userauth_pubkey(Authctxt *authctxt) +@@ -177,7 +177,8 @@ userauth_pubkey(Authctxt *authctxt) #ifdef DEBUG_PK buffer_dump(&b); #endif @@ -110,7 +110,7 @@ diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c /* test for correct signature */ authenticated = 0; -@@ -181,9 +182,12 @@ userauth_pubkey(Authctxt *authctxt) +@@ -185,9 +186,12 @@ userauth_pubkey(Authctxt *authctxt) PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; @@ -123,7 +123,7 @@ diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c } buffer_free(&b); free(sig); -@@ -224,7 +228,7 @@ done: +@@ -228,7 +232,7 @@ done: void pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) { @@ -132,7 +132,7 @@ diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c va_list ap; int i; -@@ -234,27 +238,13 @@ pubkey_auth_info(Authctxt *authctxt, con +@@ -238,27 +242,13 @@ pubkey_auth_info(Authctxt *authctxt, con i = vasprintf(&extra, fmt, ap); va_end(ap); if (i < 0 || extra == NULL) @@ -165,9 +165,9 @@ diff -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c free(extra); } -diff -up openssh-7.2p2/auth.h.expose-pam openssh-7.2p2/auth.h ---- openssh-7.2p2/auth.h.expose-pam 2016-07-18 12:30:12.077783292 +0200 -+++ openssh-7.2p2/auth.h 2016-07-18 12:30:12.123783256 +0200 +diff -up openssh-7.4p1/auth.h.expose-pam openssh-7.4p1/auth.h +--- openssh-7.4p1/auth.h.expose-pam 2016-12-23 15:40:26.782447870 +0100 ++++ openssh-7.4p1/auth.h 2016-12-23 15:40:26.819447876 +0100 @@ -84,6 +84,9 @@ struct Authctxt { struct sshkey **prev_userkeys; @@ -178,10 +178,10 @@ diff -up openssh-7.2p2/auth.h.expose-pam openssh-7.2p2/auth.h }; /* * Every authentication method has to handle authentication requests for -diff -up openssh-7.2p2/auth-pam.c.expose-pam openssh-7.2p2/auth-pam.c ---- openssh-7.2p2/auth-pam.c.expose-pam 2016-07-18 12:30:12.026783332 +0200 -+++ openssh-7.2p2/auth-pam.c 2016-07-18 12:30:12.123783256 +0200 -@@ -689,6 +689,11 @@ sshpam_init_ctx(Authctxt *authctxt) +diff -up openssh-7.4p1/auth-pam.c.expose-pam openssh-7.4p1/auth-pam.c +--- openssh-7.4p1/auth-pam.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 ++++ openssh-7.4p1/auth-pam.c 2016-12-23 15:40:26.819447876 +0100 +@@ -688,6 +688,11 @@ sshpam_init_ctx(Authctxt *authctxt) return (NULL); } @@ -193,9 +193,9 @@ diff -up openssh-7.2p2/auth-pam.c.expose-pam openssh-7.2p2/auth-pam.c ctxt = xcalloc(1, sizeof *ctxt); /* Start the authentication thread */ -diff -up openssh-7.2p2/gss-serv.c.expose-pam openssh-7.2p2/gss-serv.c ---- openssh-7.2p2/gss-serv.c.expose-pam 2016-07-18 12:30:12.124783255 +0200 -+++ openssh-7.2p2/gss-serv.c 2016-07-18 12:33:08.835644264 +0200 +diff -up openssh-7.4p1/gss-serv.c.expose-pam openssh-7.4p1/gss-serv.c +--- openssh-7.4p1/gss-serv.c.expose-pam 2016-12-23 15:40:26.808447874 +0100 ++++ openssh-7.4p1/gss-serv.c 2016-12-23 15:40:26.819447876 +0100 @@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int } @@ -213,10 +213,10 @@ diff -up openssh-7.2p2/gss-serv.c.expose-pam openssh-7.2p2/gss-serv.c int ssh_gssapi_userok(char *user, struct passwd *pw) { -diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c ---- openssh-7.2p2/monitor.c.expose-pam 2016-07-18 12:30:12.093783279 +0200 -+++ openssh-7.2p2/monitor.c 2016-07-18 12:30:12.124783255 +0200 -@@ -349,6 +349,7 @@ monitor_child_preauth(Authctxt *_authctx +diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 ++++ openssh-7.4p1/monitor.c 2016-12-23 15:41:16.473455863 +0100 +@@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx { struct mon_table *ent; int authenticated = 0, partial = 0; @@ -224,7 +224,7 @@ diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c debug3("preauth child monitor started"); -@@ -386,6 +387,18 @@ monitor_child_preauth(Authctxt *_authctx +@@ -330,6 +331,18 @@ monitor_child_preauth(Authctxt *_authctx auth_submethod = NULL; authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); @@ -242,8 +242,8 @@ diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c + /* Special handling for multiple required authentications */ if (options.num_auth_methods != 0) { - if (!compat20) -@@ -1498,6 +1511,10 @@ mm_answer_keyverify(int sock, Buffer *m) + if (authenticated && +@@ -1417,6 +1430,10 @@ mm_answer_keyverify(int sock, Buffer *m) debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); @@ -254,7 +254,7 @@ diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c /* If auth was successful then record key to ensure it isn't reused */ if (verified == 1 && key_blobtype == MM_USERKEY) auth2_record_userkey(authctxt, key); -@@ -2140,6 +2157,9 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1860,6 +1877,9 @@ mm_answer_gss_userok(int sock, Buffer *m auth_method = "gssapi-with-mic"; @@ -264,43 +264,43 @@ diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c /* Monitor loop will terminate if authenticated */ return (authenticated); } -diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c ---- openssh-7.2p2/servconf.c.expose-pam 2016-07-18 12:30:12.112783264 +0200 -+++ openssh-7.2p2/servconf.c 2016-07-18 12:34:38.170574004 +0200 -@@ -176,6 +176,7 @@ initialize_server_options(ServerOptions - options->fingerprint_hash = -1; +diff -up openssh-7.4p1/servconf.c.expose-pam openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.expose-pam 2016-12-23 15:40:26.810447875 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 15:44:04.691482920 +0100 +@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions + options->disable_forwarding = -1; options->use_kuserok = -1; options->enable_k5users = -1; + options->expose_auth_methods = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -374,6 +375,8 @@ fill_default_server_options(ServerOption - options->enable_k5users = 0; - if (options->use_kuserok == -1) +@@ -354,6 +355,8 @@ fill_default_server_options(ServerOption options->use_kuserok = 1; + if (options->enable_k5users == -1) + options->enable_k5users = 0; + if (options->expose_auth_methods == -1) + options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; assemble_algorithms(options); -@@ -451,6 +454,7 @@ typedef enum { +@@ -439,6 +442,7 @@ typedef enum { sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, sFingerprintHash, + sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, + sExposeAuthenticationMethods, - sDeprecated, sUnsupported + sDeprecated, sIgnore, sUnsupported } ServerOpCodes; -@@ -606,6 +610,7 @@ static struct { - { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, +@@ -595,6 +599,7 @@ static struct { { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, + { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, + { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; -@@ -994,6 +999,12 @@ static const struct multistate multistat +@@ -984,6 +989,12 @@ static const struct multistate multistat { "local", FORWARD_LOCAL }, { NULL, -1 } }; @@ -313,7 +313,7 @@ diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c int process_server_config_line(ServerOptions *options, char *line, -@@ -1918,6 +1929,11 @@ process_server_config_line(ServerOptions +@@ -1902,6 +1913,11 @@ process_server_config_line(ServerOptions options->fingerprint_hash = value; break; @@ -323,9 +323,9 @@ diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c + goto parse_multistate; + case sDeprecated: - logit("%s line %d: Deprecated option %s", - filename, linenum, arg); -@@ -2076,6 +2092,7 @@ copy_set_server_options(ServerOptions *d + case sIgnore: + case sUnsupported: +@@ -2060,6 +2076,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(enable_k5users); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); @@ -333,16 +333,16 @@ diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c /* * The bind_mask is a mode_t that may be unsigned, so we can't use -@@ -2181,6 +2198,8 @@ fmt_intarg(ServerOpCodes code, int val) +@@ -2176,6 +2193,8 @@ fmt_intarg(ServerOpCodes code, int val) return fmt_multistate_int(val, multistate_tcpfwd); case sFingerprintHash: return ssh_digest_alg_name(val); + case sExposeAuthenticationMethods: + return fmt_multistate_int(val, multistate_exposeauthmeth); - case sProtocol: + default: switch (val) { - case SSH_PROTO_1: -@@ -2374,6 +2393,7 @@ dump_config(ServerOptions *o) + case 0: +@@ -2356,6 +2375,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); @@ -350,9 +350,9 @@ diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-7.2p2/servconf.h.expose-pam openssh-7.2p2/servconf.h ---- openssh-7.2p2/servconf.h.expose-pam 2016-07-18 12:30:12.112783264 +0200 -+++ openssh-7.2p2/servconf.h 2016-07-18 12:30:12.125783254 +0200 +diff -up openssh-7.4p1/servconf.h.expose-pam openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.expose-pam 2016-12-23 15:40:26.810447875 +0100 ++++ openssh-7.4p1/servconf.h 2016-12-23 15:40:26.821447876 +0100 @@ -48,6 +48,11 @@ #define FORWARD_LOCAL (1<<1) #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) @@ -365,7 +365,7 @@ diff -up openssh-7.2p2/servconf.h.expose-pam openssh-7.2p2/servconf.h #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ -@@ -201,6 +206,8 @@ typedef struct { +@@ -195,6 +200,8 @@ typedef struct { char *auth_methods[MAX_AUTH_METHODS]; int fingerprint_hash; @@ -374,10 +374,10 @@ diff -up openssh-7.2p2/servconf.h.expose-pam openssh-7.2p2/servconf.h } ServerOptions; /* Information about the incoming connection as used by Match */ -diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c ---- openssh-7.2p2/session.c.expose-pam 2016-07-18 12:30:12.120783258 +0200 -+++ openssh-7.2p2/session.c 2016-07-18 12:30:12.125783254 +0200 -@@ -1180,6 +1180,12 @@ copy_environment(char **source, char *** +diff -up openssh-7.4p1/session.c.expose-pam openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 ++++ openssh-7.4p1/session.c 2016-12-23 15:40:26.821447876 +0100 +@@ -997,6 +997,12 @@ copy_environment(char **source, char *** } *var_val++ = '\0'; @@ -390,7 +390,7 @@ diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c debug3("Copy environment: %s=%s", var_name, var_val); child_set_env(env, envsize, var_name, var_val); -@@ -1359,6 +1365,11 @@ do_setup_env(Session *s, const char *she +@@ -1173,6 +1179,11 @@ do_setup_env(Session *s, const char *she } #endif /* USE_PAM */ @@ -402,7 +402,7 @@ diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c if (auth_sock_name != NULL) child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, auth_sock_name); -@@ -2798,6 +2809,9 @@ do_cleanup(Authctxt *authctxt) +@@ -2561,6 +2572,9 @@ do_cleanup(Authctxt *authctxt) if (authctxt == NULL) return; @@ -412,10 +412,10 @@ diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c #ifdef USE_PAM if (options.use_pam) { sshpam_cleanup(); -diff -up openssh-7.2p2/ssh.1.expose-pam openssh-7.2p2/ssh.1 ---- openssh-7.2p2/ssh.1.expose-pam 2016-07-18 12:30:12.112783264 +0200 -+++ openssh-7.2p2/ssh.1 2016-07-18 12:30:12.126783253 +0200 -@@ -1396,6 +1396,10 @@ server IP address, and server port numbe +diff -up openssh-7.4p1/ssh.1.expose-pam openssh-7.4p1/ssh.1 +--- openssh-7.4p1/ssh.1.expose-pam 2016-12-23 15:40:26.810447875 +0100 ++++ openssh-7.4p1/ssh.1 2016-12-23 15:40:26.822447877 +0100 +@@ -1421,6 +1421,10 @@ server IP address, and server port numbe This variable contains the original command line if a forced command is executed. It can be used to extract the original arguments. @@ -426,13 +426,13 @@ diff -up openssh-7.2p2/ssh.1.expose-pam openssh-7.2p2/ssh.1 .It Ev SSH_TTY This is set to the name of the tty (path to the device) associated with the current shell or command. -diff -up openssh-7.2p2/sshd_config.5.expose-pam openssh-7.2p2/sshd_config.5 ---- openssh-7.2p2/sshd_config.5.expose-pam 2016-07-18 12:30:12.113783263 +0200 -+++ openssh-7.2p2/sshd_config.5 2016-07-18 12:30:12.126783253 +0200 -@@ -570,6 +570,21 @@ and finally - See PATTERNS in - .Xr ssh_config 5 - for more information on patterns. +diff -up openssh-7.4p1/sshd_config.5.expose-pam openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.expose-pam 2016-12-23 15:40:26.822447877 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 15:45:22.411495421 +0100 +@@ -570,6 +570,21 @@ Disables all forwarding features, includ + TCP and StreamLocal. + This option overrides all other forwarding-related options and may + simplify restricted configurations. +.It Cm ExposeAuthenticationMethods +When using SSH2, this option controls the exposure of the list of +successful authentication methods to PAM during the authentication @@ -440,20 +440,20 @@ diff -up openssh-7.2p2/sshd_config.5.expose-pam openssh-7.2p2/sshd_config.5 +.Cm SSH_USER_AUTH +variable. See the description of this variable for more details. +Valid options are: -+.Dq never ++.Cm never +(Do not expose successful authentication methods), -+.Dq pam-only ++.Cm pam-only +(Only expose them to PAM during authentication, not afterwards), -+.Dq pam-and-env ++.Cm pam-and-env +(Expose them to PAM and keep them in the shell environment). +The default is -+.Dq never . ++.Cm never . .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: -diff -up openssh-7.2p2/ssh-gss.h.expose-pam openssh-7.2p2/ssh-gss.h ---- openssh-7.2p2/ssh-gss.h.expose-pam 2016-07-18 12:30:12.125783254 +0200 -+++ openssh-7.2p2/ssh-gss.h 2016-07-18 12:35:01.906555328 +0200 +diff -up openssh-7.4p1/ssh-gss.h.expose-pam openssh-7.4p1/ssh-gss.h +--- openssh-7.4p1/ssh-gss.h.expose-pam 2016-12-23 15:40:26.811447875 +0100 ++++ openssh-7.4p1/ssh-gss.h 2016-12-23 15:40:26.823447877 +0100 @@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -462,10 +462,10 @@ diff -up openssh-7.2p2/ssh-gss.h.expose-pam openssh-7.2p2/ssh-gss.h 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); -diff -up openssh-7.2p2/sshkey.c.expose-pam openssh-7.2p2/sshkey.c ---- openssh-7.2p2/sshkey.c.expose-pam 2016-07-18 12:30:12.071783296 +0200 -+++ openssh-7.2p2/sshkey.c 2016-07-18 12:30:12.126783253 +0200 -@@ -58,6 +58,7 @@ +diff -up openssh-7.4p1/sshkey.c.expose-pam openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.expose-pam 2016-12-23 15:40:26.777447869 +0100 ++++ openssh-7.4p1/sshkey.c 2016-12-23 15:40:26.823447877 +0100 +@@ -57,6 +57,7 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" @@ -473,7 +473,7 @@ diff -up openssh-7.2p2/sshkey.c.expose-pam openssh-7.2p2/sshkey.c /* openssh private key file format */ #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" -@@ -1190,6 +1191,30 @@ sshkey_fingerprint(const struct sshkey * +@@ -1191,6 +1192,30 @@ sshkey_fingerprint(const struct sshkey * return retval; } @@ -504,9 +504,9 @@ diff -up openssh-7.2p2/sshkey.c.expose-pam openssh-7.2p2/sshkey.c #ifdef WITH_SSH1 /* * Reads a multiple-precision integer in decimal from the buffer, and advances -diff -up openssh-7.2p2/sshkey.h.expose-pam openssh-7.2p2/sshkey.h ---- openssh-7.2p2/sshkey.h.expose-pam 2016-07-18 12:30:12.071783296 +0200 -+++ openssh-7.2p2/sshkey.h 2016-07-18 12:30:12.127783252 +0200 +diff -up openssh-7.4p1/sshkey.h.expose-pam openssh-7.4p1/sshkey.h +--- openssh-7.4p1/sshkey.h.expose-pam 2016-12-23 15:40:26.777447869 +0100 ++++ openssh-7.4p1/sshkey.h 2016-12-23 15:40:26.823447877 +0100 @@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s int, enum sshkey_fp_rep); int sshkey_fingerprint_raw(const struct sshkey *k, diff --git a/openssh-7.3p1-null-deref.patch b/openssh-7.3p1-null-deref.patch deleted file mode 100644 index 041ae78..0000000 --- a/openssh-7.3p1-null-deref.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 28652bca29046f62c7045e933e6b931de1d16737 Mon Sep 17 00:00:00 2001 -From: "markus@openbsd.org" -Date: Mon, 19 Sep 2016 19:02:19 +0000 -Subject: upstream commit - -move inbound NEWKEYS handling to kex layer; otherwise -early NEWKEYS causes NULL deref; found by Robert Swiecki/honggfuzz; fixed -with & ok djm@ - -Upstream-ID: 9a68b882892e9f51dc7bfa9f5a423858af358b2f ---- - kex.c | 4 +++- - packet.c | 6 ++---- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/kex.c b/kex.c -index f4c130f..8800d40 100644 ---- a/kex.c -+++ b/kex.c -@@ -425,6 +425,8 @@ kex_input_newkeys(int type, u_int32_t seq, void *ctxt) - ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); - if ((r = sshpkt_get_end(ssh)) != 0) - return r; -+ if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) -+ return r; - kex->done = 1; - sshbuf_reset(kex->peer); - /* sshbuf_reset(kex->my); */ -diff --git a/packet.c b/packet.c -index 711091d..fb316ac 100644 ---- a/packet.c -+++ b/packet.c -@@ -1907,9 +1907,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - return r; - return SSH_ERR_PROTOCOL_ERROR; - } -- if (*typep == SSH2_MSG_NEWKEYS) -- r = ssh_set_newkeys(ssh, MODE_IN); -- else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) -+ if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) - r = ssh_packet_enable_delayed_compress(ssh); - else - r = 0; --- -cgit v0.12 - -0 - diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 5208c95..452f99d 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -1,39 +1,6 @@ -diff -up openssh-7.3p1/auth1.c.openssl openssh-7.3p1/auth1.c ---- openssh-7.3p1/auth1.c.openssl 2016-10-27 14:28:16.459815636 +0200 -+++ openssh-7.3p1/auth1.c 2016-10-27 14:28:16.614815267 +0200 -@@ -164,6 +164,7 @@ auth1_process_rhosts_rsa(Authctxt *authc - u_int bits; - Key *client_host_key; - u_int ulen; -+ BIGNUM *n = NULL, *e = NULL; - - /* - * Get client user name. Note that we just have to -@@ -175,14 +176,17 @@ auth1_process_rhosts_rsa(Authctxt *authc - /* Get the client host key. */ - client_host_key = key_new(KEY_RSA1); - bits = packet_get_int(); -- packet_get_bignum(client_host_key->rsa->e); -- packet_get_bignum(client_host_key->rsa->n); -+ if( (n = BN_new()) == NULL || (e = BN_new()) == NULL) -+ return 0; -+ packet_get_bignum(e); -+ packet_get_bignum(n); -+ RSA_set0_key(client_host_key->rsa, n, e, NULL); - -- keybits = BN_num_bits(client_host_key->rsa->n); -+ keybits = BN_num_bits(n); - if (keybits < 0 || bits != (u_int)keybits) { - verbose("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", -- BN_num_bits(client_host_key->rsa->n), bits); -+ BN_num_bits(n), bits); - } - packet_check_eom(); - -diff -up openssh-7.3p1/authfd.c.openssl openssh-7.3p1/authfd.c ---- openssh-7.3p1/authfd.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/authfd.c 2016-10-27 14:28:16.614815267 +0200 +diff -up openssh-7.4p1/authfd.c.openssl openssh-7.4p1/authfd.c +--- openssh-7.4p1/authfd.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/authfd.c 2016-12-23 17:47:36.429817751 +0100 @@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids int r, keybits; u_int32_t bits; @@ -127,10 +94,10 @@ diff -up openssh-7.3p1/authfd.c.openssl openssh-7.3p1/authfd.c goto out; } else #endif -diff -up openssh-7.3p1/auth-pam.c.openssl openssh-7.3p1/auth-pam.c ---- openssh-7.3p1/auth-pam.c.openssl 2016-10-27 14:28:16.577815355 +0200 -+++ openssh-7.3p1/auth-pam.c 2016-10-27 14:28:16.615815264 +0200 -@@ -124,6 +124,10 @@ extern u_int utmp_len; +diff -up openssh-7.4p1/auth-pam.c.openssl openssh-7.4p1/auth-pam.c +--- openssh-7.4p1/auth-pam.c.openssl 2016-12-23 17:47:36.400817739 +0100 ++++ openssh-7.4p1/auth-pam.c 2016-12-23 17:47:36.430817752 +0100 +@@ -129,6 +129,10 @@ extern u_int utmp_len; typedef pthread_t sp_pthread_t; #else typedef pid_t sp_pthread_t; @@ -141,76 +108,10 @@ diff -up openssh-7.3p1/auth-pam.c.openssl openssh-7.3p1/auth-pam.c #endif struct pam_ctxt { -diff -up openssh-7.3p1/auth-rsa.c.openssl openssh-7.3p1/auth-rsa.c ---- openssh-7.3p1/auth-rsa.c.openssl 2016-10-27 14:28:16.592815319 +0200 -+++ openssh-7.3p1/auth-rsa.c 2016-10-27 14:28:16.615815264 +0200 -@@ -75,6 +75,7 @@ auth_rsa_generate_challenge(Key *key) - { - BIGNUM *challenge; - BN_CTX *ctx; -+ const BIGNUM *n; - - if ((challenge = BN_new()) == NULL) - fatal("auth_rsa_generate_challenge: BN_new() failed"); -@@ -83,7 +84,8 @@ auth_rsa_generate_challenge(Key *key) - fatal("auth_rsa_generate_challenge: BN_rand failed"); - if ((ctx = BN_CTX_new()) == NULL) - fatal("auth_rsa_generate_challenge: BN_CTX_new failed"); -- if (BN_mod(challenge, challenge, key->rsa->n, ctx) == 0) -+ RSA_get0_key(key->rsa, &n, NULL, NULL); -+ if (BN_mod(challenge, challenge, n, ctx) == 0) - fatal("auth_rsa_generate_challenge: BN_mod failed"); - BN_CTX_free(ctx); - -@@ -99,12 +101,14 @@ auth_rsa_verify_response(Key *key, BIGNU - #ifdef SSH_AUDIT_EVENTS - char *fp; - #endif -+ const BIGNUM *n; - - /* don't allow short keys */ -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ RSA_get0_key(key->rsa, &n, NULL, NULL); -+ if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - error("%s: RSA modulus too small: %d < minimum %d bits", - __func__, -- BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); -+ BN_num_bits(n), SSH_RSA_MINIMUM_MODULUS_SIZE); - return (0); - } - -@@ -200,6 +204,7 @@ rsa_key_allowed_in_file(struct passwd *p - char *cp; - char *key_options; - int keybits; -+ const BIGNUM *n; - - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) -@@ -237,15 +242,16 @@ rsa_key_allowed_in_file(struct passwd *p - * Check if the we have found the desired key (identified - * by its modulus). - */ -- if (BN_cmp(key->rsa->n, client_n) != 0) -+ RSA_get0_key(key->rsa, &n, NULL, NULL); -+ if (BN_cmp(n, client_n) != 0) - continue; - - /* check the real bits */ -- keybits = BN_num_bits(key->rsa->n); -+ keybits = BN_num_bits(n); - if (keybits < 0 || bits != keybits) - logit("Warning: %s, line %lu: keysize mismatch: " - "actual %d vs. announced %d.", -- file, linenum, BN_num_bits(key->rsa->n), bits); -+ file, linenum, BN_num_bits(n), bits); - - if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, - SSH_FP_DEFAULT)) == NULL) -diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c ---- openssh-7.3p1/cipher-3des1.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/cipher-3des1.c 2016-10-27 14:28:16.615815264 +0200 -@@ -42,7 +42,7 @@ +diff -up openssh-7.4p1/cipher-3des1.c.openssl openssh-7.4p1/cipher-3des1.c +--- openssh-7.4p1/cipher-3des1.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/cipher-3des1.c 2016-12-23 17:47:36.430817752 +0100 +@@ -44,7 +44,7 @@ */ struct ssh1_3des_ctx { @@ -219,7 +120,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c }; const EVP_CIPHER * evp_ssh1_3des(void); -@@ -63,7 +63,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons +@@ -65,7 +65,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons if (key == NULL) return 1; if (enc == -1) @@ -228,7 +129,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c k1 = k2 = k3 = (u_char *) key; k2 += 8; if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { -@@ -72,12 +72,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons +@@ -74,12 +74,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons else k1 += 16; } @@ -254,7 +155,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c explicit_bzero(c, sizeof(*c)); free(c); EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -93,9 +100,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha +@@ -95,9 +102,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) return 0; @@ -267,7 +168,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c return 0; return 1; } -@@ -106,9 +113,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) +@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) struct ssh1_3des_ctx *c; if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { @@ -280,7 +181,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c explicit_bzero(c, sizeof(*c)); free(c); EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -126,13 +133,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do +@@ -128,13 +135,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) return SSH_ERR_INTERNAL_ERROR; if (doset) { @@ -300,7 +201,7 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c } return 0; } -@@ -140,16 +147,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do +@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do const EVP_CIPHER * evp_ssh1_3des(void) { @@ -325,10 +226,11 @@ diff -up openssh-7.3p1/cipher-3des1.c.openssl openssh-7.3p1/cipher-3des1.c + EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); + return ssh1_3des; } -diff -up openssh-7.3p1/cipher-bf1.c.openssl openssh-7.3p1/cipher-bf1.c ---- openssh-7.3p1/cipher-bf1.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/cipher-bf1.c 2016-10-27 14:28:16.615815264 +0200 -@@ -88,16 +88,27 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_ch + #endif /* WITH_SSH1 */ +diff -up openssh-7.4p1/cipher-bf1.c.openssl openssh-7.4p1/cipher-bf1.c +--- openssh-7.4p1/cipher-bf1.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/cipher-bf1.c 2016-12-23 17:47:36.430817752 +0100 +@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_ch const EVP_CIPHER * evp_ssh1_bf(void) { @@ -364,210 +266,62 @@ diff -up openssh-7.3p1/cipher-bf1.c.openssl openssh-7.3p1/cipher-bf1.c + return ssh1_bf; } #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */ -diff -up openssh-7.3p1/cipher.c.openssl openssh-7.3p1/cipher.c ---- openssh-7.3p1/cipher.c.openssl 2016-10-27 14:28:16.607815283 +0200 -+++ openssh-7.3p1/cipher.c 2016-10-27 14:28:16.615815264 +0200 -@@ -330,29 +330,28 @@ cipher_init(struct sshcipher_ctx *cc, co - return SSH_ERR_INVALID_ARGUMENT; - #else - type = (*cipher->evptype)(); -- EVP_CIPHER_CTX_init(&cc->evp); -- if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, -+ if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto bad; -+ } + +diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c +--- openssh-7.4p1/cipher.c.openssl 2016-12-23 17:47:36.418817747 +0100 ++++ openssh-7.4p1/cipher.c 2016-12-23 17:47:36.430817752 +0100 +@@ -368,7 +368,7 @@ cipher_init(struct sshcipher_ctx **ccp, + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, + if (EVP_CipherInit(cc->evp, type, (u_char *)key, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; - goto bad; - } - if (cipher_authlen(cipher) && -- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, - -1, (u_char *)iv)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto bad; - } -- klen = EVP_CIPHER_CTX_key_length(&cc->evp); -+ klen = EVP_CIPHER_CTX_key_length(cc->evp); - if (klen > 0 && keylen != (u_int)klen) { -- if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { -+ if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto bad; + goto out; +@@ -386,10 +386,6 @@ cipher_init(struct sshcipher_ctx **ccp, + goto out; } } -- if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { +- if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; -- goto bad; +- goto out; - } if (cipher->discard_len > 0) { if ((junk = malloc(cipher->discard_len)) == NULL || -@@ -361,14 +360,14 @@ cipher_init(struct sshcipher_ctx *cc, co - ret = SSH_ERR_ALLOC_FAIL; - goto bad; - } -- ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); -+ ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); - explicit_bzero(discard, cipher->discard_len); - free(junk); - free(discard); - if (ret != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - bad: -- EVP_CIPHER_CTX_cleanup(&cc->evp); -+ EVP_CIPHER_CTX_free(cc->evp); - return ret; - } - } -@@ -414,33 +413,33 @@ cipher_crypt(struct sshcipher_ctx *cc, u - if (authlen != cipher_authlen(cc->cipher)) - return SSH_ERR_INVALID_ARGUMENT; - /* increment IV */ -- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, -+ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - 1, lastiv)) - return SSH_ERR_LIBCRYPTO_ERROR; - /* set tag on decyption */ - if (!cc->encrypt && -- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, -+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, - authlen, (u_char *)src + aadlen + len)) - return SSH_ERR_LIBCRYPTO_ERROR; - } - if (aadlen) { - if (authlen && -- EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) -+ EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0) - return SSH_ERR_LIBCRYPTO_ERROR; - memcpy(dest, src, aadlen); - } - if (len % cc->cipher->block_size) - return SSH_ERR_INVALID_ARGUMENT; -- if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, -+ if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen, - len) < 0) - return SSH_ERR_LIBCRYPTO_ERROR; - if (authlen) { - /* compute tag (on encrypt) or verify tag (on decrypt) */ -- if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) -+ if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) - return cc->encrypt ? - SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; - if (cc->encrypt && -- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, -+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, - authlen, dest + aadlen + len)) - return SSH_ERR_LIBCRYPTO_ERROR; - } -@@ -472,8 +471,8 @@ cipher_cleanup(struct sshcipher_ctx *cc) - else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) - explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); - #ifdef WITH_OPENSSL -- else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) -- return SSH_ERR_LIBCRYPTO_ERROR; -+ EVP_CIPHER_CTX_free(cc->evp); -+ cc->evp = NULL; - #endif - return 0; - } -@@ -519,7 +518,7 @@ cipher_get_keyiv_len(const struct sshcip - ivlen = sizeof(cc->ac_ctx.ctr); - #ifdef WITH_OPENSSL - else -- ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); -+ ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); - #endif /* WITH_OPENSSL */ - return (ivlen); - } -@@ -551,7 +550,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c - case SSH_CIPHER_SSH2: - case SSH_CIPHER_DES: - case SSH_CIPHER_BLOWFISH: -- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); -+ evplen = EVP_CIPHER_CTX_iv_length(cc->evp); - if (evplen == 0) - return 0; - else if (evplen < 0) -@@ -560,20 +559,20 @@ cipher_get_keyiv(struct sshcipher_ctx *c - return SSH_ERR_INVALID_ARGUMENT; - #ifndef OPENSSL_HAVE_EVPCTR - if (c->evptype == evp_aes_128_ctr) -- ssh_aes_ctr_iv(&cc->evp, 0, iv, len); -+ ssh_aes_ctr_iv(cc->evp, 0, iv, len); - else - #endif - if (cipher_authlen(c)) { -- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, -+ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, +@@ -621,7 +617,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c len, iv)) return SSH_ERR_LIBCRYPTO_ERROR; } else -- memcpy(iv, cc->evp.iv, len); +- memcpy(iv, cc->evp->iv, len); + memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); break; #endif #ifdef WITH_SSH1 - case SSH_CIPHER_3DES: -- return ssh1_3des_iv(&cc->evp, 0, iv, 24); -+ return ssh1_3des_iv(cc->evp, 0, iv, 24); - #endif - default: - return SSH_ERR_INVALID_ARGUMENT; -@@ -599,21 +598,21 @@ cipher_set_keyiv(struct sshcipher_ctx *c - case SSH_CIPHER_SSH2: - case SSH_CIPHER_DES: - case SSH_CIPHER_BLOWFISH: -- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); -+ evplen = EVP_CIPHER_CTX_iv_length(cc->evp); - if (evplen <= 0) - return SSH_ERR_LIBCRYPTO_ERROR; - if (cipher_authlen(c)) { - /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ -- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, -+ if (!EVP_CIPHER_CTX_ctrl(cc->evp, +@@ -667,7 +663,7 @@ cipher_set_keyiv(struct sshcipher_ctx *c EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) return SSH_ERR_LIBCRYPTO_ERROR; } else -- memcpy(cc->evp.iv, iv, evplen); +- memcpy(cc->evp->iv, iv, evplen); + memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); break; #endif #ifdef WITH_SSH1 - case SSH_CIPHER_3DES: -- return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); -+ return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); - #endif - default: - return SSH_ERR_INVALID_ARGUMENT; -@@ -622,8 +621,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c +@@ -681,8 +677,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c } #ifdef WITH_OPENSSL --#define EVP_X_STATE(evp) (evp).cipher_data --#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size +-#define EVP_X_STATE(evp) (evp)->cipher_data +-#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size +#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp) +#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp)) #endif int -diff -up openssh-7.3p1/cipher.h.openssl openssh-7.3p1/cipher.h ---- openssh-7.3p1/cipher.h.openssl 2016-10-27 14:28:16.593815317 +0200 -+++ openssh-7.3p1/cipher.h 2016-10-27 14:28:16.616815262 +0200 -@@ -85,7 +85,7 @@ struct sshcipher { - struct sshcipher_ctx { - int plaintext; - int encrypt; -- EVP_CIPHER_CTX evp; -+ EVP_CIPHER_CTX *evp; - struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ - struct aesctr_ctx ac_ctx; /* XXX union with evp? */ - const struct sshcipher *cipher; -diff -up openssh-7.3p1/ctr-cavstest.c.openssl openssh-7.3p1/ctr-cavstest.c ---- openssh-7.3p1/ctr-cavstest.c.openssl 2016-10-27 14:28:16.506815524 +0200 -+++ openssh-7.3p1/ctr-cavstest.c 2016-10-27 14:28:16.616815262 +0200 +diff -up openssh-7.4p1/ctr-cavstest.c.openssl openssh-7.4p1/ctr-cavstest.c +--- openssh-7.4p1/ctr-cavstest.c.openssl 2016-12-23 17:47:36.344817716 +0100 ++++ openssh-7.4p1/ctr-cavstest.c 2016-12-23 17:47:36.430817752 +0100 @@ -144,7 +144,7 @@ int main (int argc, char *argv[]) usage(); } @@ -577,10 +331,10 @@ diff -up openssh-7.3p1/ctr-cavstest.c.openssl openssh-7.3p1/ctr-cavstest.c c = cipher_by_name(algo); if (c == NULL) { -diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c ---- openssh-7.3p1/dh.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/dh.c 2016-10-27 14:28:16.616815262 +0200 -@@ -213,14 +213,15 @@ choose_dh(int min, int wantbits, int max +diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c +--- openssh-7.4p1/dh.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/dh.c 2016-12-23 17:47:36.430817752 +0100 +@@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max /* diffie-hellman-groupN-sha1 */ int @@ -598,7 +352,7 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c logit("invalid public DH value: negative"); return 0; } -@@ -233,7 +234,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +@@ -232,7 +233,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) error("%s: BN_new failed", __func__); return 0; } @@ -608,7 +362,7 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ BN_clear_free(tmp); logit("invalid public DH value: >= p-1"); -@@ -244,14 +246,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +@@ -243,14 +245,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) for (i = 0; i <= n; i++) if (BN_is_bit_set(dh_pub, i)) bits_set++; @@ -625,7 +379,7 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c return 0; } return 1; -@@ -261,9 +263,11 @@ int +@@ -260,9 +262,11 @@ int dh_gen_key(DH *dh, int need) { int pbits; @@ -639,11 +393,11 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c need > INT_MAX / 2 || 2 * need > pbits) return SSH_ERR_INVALID_ARGUMENT; if (need < 256) -@@ -272,12 +276,12 @@ dh_gen_key(DH *dh, int need) +@@ -271,10 +275,11 @@ dh_gen_key(DH *dh, int need) * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), * so double requested need here. */ -- dh->length = MIN(need * 2, pbits - 1); +- dh->length = MINIMUM(need * 2, pbits - 1); - if (DH_generate_key(dh) == 0 || - !dh_pub_is_valid(dh, dh->pub_key)) { - BN_clear_free(dh->priv_key); @@ -651,13 +405,11 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c + 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)) ++ if (!dh_pub_is_valid(dh, pub_key)) { return SSH_ERR_LIBCRYPTO_ERROR; -- } + } return 0; - } - -@@ -285,15 +289,22 @@ DH * +@@ -284,15 +290,22 @@ DH * dh_new_group_asc(const char *gen, const char *modulus) { DH *dh; @@ -687,7 +439,7 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c } /* -@@ -308,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu +@@ -307,8 +320,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu if ((dh = DH_new()) == NULL) return NULL; @@ -697,9 +449,9 @@ diff -up openssh-7.3p1/dh.c.openssl openssh-7.3p1/dh.c return (dh); } -diff -up openssh-7.3p1/dh.h.openssl openssh-7.3p1/dh.h ---- openssh-7.3p1/dh.h.openssl 2016-10-27 14:28:16.602815295 +0200 -+++ openssh-7.3p1/dh.h 2016-10-27 14:28:16.616815262 +0200 +diff -up openssh-7.4p1/dh.h.openssl openssh-7.4p1/dh.h +--- openssh-7.4p1/dh.h.openssl 2016-12-23 17:47:36.418817747 +0100 ++++ openssh-7.4p1/dh.h 2016-12-23 17:47:36.431817752 +0100 @@ -42,7 +42,7 @@ DH *dh_new_group18(void); DH *dh_new_group_fallback(int); @@ -709,9 +461,9 @@ diff -up openssh-7.3p1/dh.h.openssl openssh-7.3p1/dh.h u_int dh_estimate(int); -diff -up openssh-7.3p1/digest-openssl.c.openssl openssh-7.3p1/digest-openssl.c ---- openssh-7.3p1/digest-openssl.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/digest-openssl.c 2016-10-27 14:28:16.616815262 +0200 +diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c +--- openssh-7.4p1/digest-openssl.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/digest-openssl.c 2016-12-23 17:47:36.431817752 +0100 @@ -43,7 +43,7 @@ struct ssh_digest_ctx { @@ -778,9 +530,9 @@ diff -up openssh-7.3p1/digest-openssl.c.openssl openssh-7.3p1/digest-openssl.c explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } -diff -up openssh-7.3p1/entropy.c.openssl openssh-7.3p1/entropy.c ---- openssh-7.3p1/entropy.c.openssl 2016-10-27 14:28:16.603815293 +0200 -+++ openssh-7.3p1/entropy.c 2016-10-27 14:28:16.616815262 +0200 +diff -up openssh-7.4p1/entropy.c.openssl openssh-7.4p1/entropy.c +--- openssh-7.4p1/entropy.c.openssl 2016-12-23 17:47:36.419817747 +0100 ++++ openssh-7.4p1/entropy.c 2016-12-23 17:47:36.431817752 +0100 @@ -218,7 +218,9 @@ seed_rng(void) "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -791,10 +543,10 @@ diff -up openssh-7.3p1/entropy.c.openssl openssh-7.3p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { -diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c ---- openssh-7.3p1/gss-genr.c.openssl 2016-10-27 14:28:16.558815400 +0200 -+++ openssh-7.3p1/gss-genr.c 2016-10-27 14:28:16.617815259 +0200 -@@ -100,7 +100,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup +diff -up openssh-7.4p1/gss-genr.c.openssl openssh-7.4p1/gss-genr.c +--- openssh-7.4p1/gss-genr.c.openssl 2016-12-23 17:47:36.392817736 +0100 ++++ openssh-7.4p1/gss-genr.c 2016-12-23 17:47:36.431817752 +0100 +@@ -99,7 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup u_char digest[EVP_MAX_MD_SIZE]; char deroid[2]; const EVP_MD *evp_md = EVP_md5(); @@ -803,7 +555,7 @@ diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c char *s, *cp, *p; if (gss_enc2oid != NULL) { -@@ -114,6 +114,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup +@@ -113,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup buffer_init(&buf); @@ -811,7 +563,7 @@ diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c oidpos = 0; s = cp = xstrdup(kex); for (i = 0; i < gss_supported->count; i++) { -@@ -123,12 +124,13 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup +@@ -122,12 +123,13 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup deroid[0] = SSH_GSS_OIDTYPE; deroid[1] = gss_supported->elements[i].length; @@ -829,7 +581,7 @@ diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c encoded = xmalloc(EVP_MD_size(evp_md) * 2); enclen = __b64_ntop(digest, EVP_MD_size(evp_md), -@@ -150,6 +152,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup +@@ -149,6 +151,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup } } free(s); @@ -837,9 +589,9 @@ diff -up openssh-7.3p1/gss-genr.c.openssl openssh-7.3p1/gss-genr.c gss_enc2oid[oidpos].oid = NULL; gss_enc2oid[oidpos].encoded = NULL; -diff -up openssh-7.3p1/includes.h.openssl openssh-7.3p1/includes.h ---- openssh-7.3p1/includes.h.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/includes.h 2016-10-27 14:28:16.617815259 +0200 +diff -up openssh-7.4p1/includes.h.openssl openssh-7.4p1/includes.h +--- openssh-7.4p1/includes.h.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/includes.h 2016-12-23 17:47:36.431817752 +0100 @@ -163,6 +163,7 @@ #ifdef WITH_OPENSSL @@ -848,9 +600,9 @@ diff -up openssh-7.3p1/includes.h.openssl openssh-7.3p1/includes.h #endif #include "defines.h" -diff -up openssh-7.3p1/kexdhc.c.openssl openssh-7.3p1/kexdhc.c ---- openssh-7.3p1/kexdhc.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/kexdhc.c 2016-10-27 14:28:16.617815259 +0200 +diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c +--- openssh-7.4p1/kexdhc.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kexdhc.c 2016-12-23 17:47:36.431817752 +0100 @@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) { struct kex *kex = ssh->kex; @@ -916,9 +668,9 @@ diff -up openssh-7.3p1/kexdhc.c.openssl openssh-7.3p1/kexdhc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.3p1/kexdhs.c.openssl openssh-7.3p1/kexdhs.c ---- openssh-7.3p1/kexdhs.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/kexdhs.c 2016-10-27 14:28:16.617815259 +0200 +diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c +--- openssh-7.4p1/kexdhs.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kexdhs.c 2016-12-23 17:47:36.431817752 +0100 @@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); r = 0; @@ -964,9 +716,9 @@ diff -up openssh-7.3p1/kexdhs.c.openssl openssh-7.3p1/kexdhs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.3p1/kexgexc.c.openssl openssh-7.3p1/kexgexc.c ---- openssh-7.3p1/kexgexc.c.openssl 2016-10-27 14:28:16.603815293 +0200 -+++ openssh-7.3p1/kexgexc.c 2016-10-27 14:28:16.617815259 +0200 +diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c +--- openssh-7.4p1/kexgexc.c.openssl 2016-12-23 17:47:36.419817747 +0100 ++++ openssh-7.4p1/kexgexc.c 2016-12-23 17:47:36.431817752 +0100 @@ -96,6 +96,7 @@ input_kex_dh_gex_group(int type, u_int32 struct kex *kex = ssh->kex; BIGNUM *p = NULL, *g = NULL; @@ -1042,9 +794,9 @@ diff -up openssh-7.3p1/kexgexc.c.openssl openssh-7.3p1/kexgexc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.3p1/kexgexs.c.openssl openssh-7.3p1/kexgexs.c ---- openssh-7.3p1/kexgexs.c.openssl 2016-10-27 14:28:16.603815293 +0200 -+++ openssh-7.3p1/kexgexs.c 2016-10-27 14:28:16.618815257 +0200 +diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c +--- openssh-7.4p1/kexgexs.c.openssl 2016-12-23 17:47:36.419817747 +0100 ++++ openssh-7.4p1/kexgexs.c 2016-12-23 17:47:36.432817753 +0100 @@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int struct kex *kex = ssh->kex; int r; @@ -1115,9 +867,9 @@ diff -up openssh-7.3p1/kexgexs.c.openssl openssh-7.3p1/kexgexs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.3p1/kexgssc.c.openssl openssh-7.3p1/kexgssc.c ---- openssh-7.3p1/kexgssc.c.openssl 2016-10-27 14:28:16.512815510 +0200 -+++ openssh-7.3p1/kexgssc.c 2016-10-27 14:28:16.618815257 +0200 +diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c +--- openssh-7.4p1/kexgssc.c.openssl 2016-12-23 17:47:36.349817718 +0100 ++++ openssh-7.4p1/kexgssc.c 2016-12-23 17:47:36.432817753 +0100 @@ -58,6 +58,7 @@ kexgss_client(struct ssh *ssh) { BIGNUM *shared_secret = NULL; BIGNUM *p = NULL; @@ -1170,9 +922,9 @@ diff -up openssh-7.3p1/kexgssc.c.openssl openssh-7.3p1/kexgssc.c dh_server_pub, shared_secret, hash, &hashlen -diff -up openssh-7.3p1/kexgsss.c.openssl openssh-7.3p1/kexgsss.c ---- openssh-7.3p1/kexgsss.c.openssl 2016-10-27 14:28:16.512815510 +0200 -+++ openssh-7.3p1/kexgsss.c 2016-10-27 14:28:16.618815257 +0200 +diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c +--- openssh-7.4p1/kexgsss.c.openssl 2016-12-23 17:47:36.349817718 +0100 ++++ openssh-7.4p1/kexgsss.c 2016-12-23 17:47:36.432817753 +0100 @@ -77,6 +77,7 @@ kexgss_server(struct ssh *ssh) char *mechs; u_char hash[SSH_DIGEST_MAX_LENGTH]; @@ -1232,9 +984,9 @@ diff -up openssh-7.3p1/kexgsss.c.openssl openssh-7.3p1/kexgsss.c packet_put_string(msg_tok.value,msg_tok.length); if (send_tok.length != 0) { -diff -up openssh-7.3p1/libcrypto-compat.c.openssl openssh-7.3p1/libcrypto-compat.c ---- openssh-7.3p1/libcrypto-compat.c.openssl 2016-10-27 14:28:16.618815257 +0200 -+++ openssh-7.3p1/libcrypto-compat.c 2016-10-27 14:28:16.618815257 +0200 +diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat.c +--- openssh-7.4p1/libcrypto-compat.c.openssl 2016-12-23 17:47:36.432817753 +0100 ++++ openssh-7.4p1/libcrypto-compat.c 2016-12-23 17:47:36.432817753 +0100 @@ -0,0 +1,546 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. @@ -1782,9 +1534,9 @@ diff -up openssh-7.3p1/libcrypto-compat.c.openssl openssh-7.3p1/libcrypto-compat +} + +#endif /* OPENSSL_VERSION_NUMBER */ -diff -up openssh-7.3p1/libcrypto-compat.h.openssl openssh-7.3p1/libcrypto-compat.h ---- openssh-7.3p1/libcrypto-compat.h.openssl 2016-10-27 14:28:16.618815257 +0200 -+++ openssh-7.3p1/libcrypto-compat.h 2016-10-27 14:28:16.618815257 +0200 +diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat.h +--- openssh-7.4p1/libcrypto-compat.h.openssl 2016-12-23 17:47:36.432817753 +0100 ++++ openssh-7.4p1/libcrypto-compat.h 2016-12-23 17:47:36.432817753 +0100 @@ -0,0 +1,98 @@ +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H @@ -1884,9 +1636,9 @@ diff -up openssh-7.3p1/libcrypto-compat.h.openssl openssh-7.3p1/libcrypto-compat + +#endif /* LIBCRYPTO_COMPAT_H */ + -diff -up openssh-7.3p1/Makefile.in.openssl openssh-7.3p1/Makefile.in ---- openssh-7.3p1/Makefile.in.openssl 2016-10-27 14:28:16.604815290 +0200 -+++ openssh-7.3p1/Makefile.in 2016-10-27 14:28:16.619815255 +0200 +diff -up openssh-7.4p1/Makefile.in.openssl openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.openssl 2016-12-23 17:47:36.420817748 +0100 ++++ openssh-7.4p1/Makefile.in 2016-12-23 17:47:36.432817753 +0100 @@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ @@ -1896,22 +1648,10 @@ diff -up openssh-7.3p1/Makefile.in.openssl openssh-7.3p1/Makefile.in SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.3p1/misc.h.openssl openssh-7.3p1/misc.h ---- openssh-7.3p1/misc.h.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/misc.h 2016-10-27 14:28:16.619815255 +0200 -@@ -139,4 +139,8 @@ char *read_passphrase(const char *, int) - int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); - int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); - -+#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) -+#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) -+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -+ - #endif /* _MISC_H */ -diff -up openssh-7.3p1/monitor.c.openssl openssh-7.3p1/monitor.c ---- openssh-7.3p1/monitor.c.openssl 2016-10-27 14:28:16.610815276 +0200 -+++ openssh-7.3p1/monitor.c 2016-10-27 14:28:16.619815255 +0200 -@@ -735,9 +735,12 @@ mm_answer_moduli(int sock, Buffer *m) +diff -up openssh-7.4p1/monitor.c.openssl openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.openssl 2016-12-23 17:47:36.426817750 +0100 ++++ openssh-7.4p1/monitor.c 2016-12-23 17:47:36.433817753 +0100 +@@ -636,9 +636,12 @@ mm_answer_moduli(int sock, Buffer *m) return (0); } else { /* Send first bignum */ @@ -1926,10 +1666,10 @@ diff -up openssh-7.3p1/monitor.c.openssl openssh-7.3p1/monitor.c DH_free(dh); } -diff -up openssh-7.3p1/openbsd-compat/openssl-compat.c.openssl openssh-7.3p1/openbsd-compat/openssl-compat.c ---- openssh-7.3p1/openbsd-compat/openssl-compat.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/openbsd-compat/openssl-compat.c 2016-10-27 14:28:16.619815255 +0200 -@@ -72,12 +72,19 @@ ssh_compatible_openssl(long headerver, l +diff -up openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl openssh-7.4p1/openbsd-compat/openssl-compat.c +--- openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/openbsd-compat/openssl-compat.c 2016-12-23 17:47:36.433817753 +0100 +@@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, l void ssh_OpenSSL_add_all_algorithms(void) { @@ -1949,9 +1689,9 @@ diff -up openssh-7.3p1/openbsd-compat/openssl-compat.c.openssl openssh-7.3p1/ope } #endif -diff -up openssh-7.3p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.3p1/regress/unittests/sshkey/test_file.c ---- openssh-7.3p1/regress/unittests/sshkey/test_file.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/regress/unittests/sshkey/test_file.c 2016-10-27 14:28:16.620815252 +0200 +diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_file.c +--- openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/unittests/sshkey/test_file.c 2016-12-23 17:47:36.433817753 +0100 @@ -46,6 +46,7 @@ sshkey_file_tests(void) struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; @@ -2000,9 +1740,9 @@ diff -up openssh-7.3p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.3p BN_free(a); BN_free(b); BN_free(c); -diff -up openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c ---- openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c 2016-10-27 14:28:16.620815252 +0200 +diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c +--- openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c 2016-12-23 17:47:36.433817753 +0100 @@ -197,9 +197,6 @@ sshkey_tests(void) k1 = sshkey_new(KEY_RSA1); ASSERT_PTR_NE(k1, NULL); @@ -2090,9 +1830,9 @@ diff -up openssh-7.3p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -up openssh-7.3p1/rsa.c.openssl openssh-7.3p1/rsa.c ---- openssh-7.3p1/rsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/rsa.c 2016-10-27 14:28:16.620815252 +0200 +diff -up openssh-7.4p1/rsa.c.openssl openssh-7.4p1/rsa.c +--- openssh-7.4p1/rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/rsa.c 2016-12-23 17:47:36.434817754 +0100 @@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM * { u_char *inbuf = NULL, *outbuf = NULL; @@ -2175,9 +1915,9 @@ diff -up openssh-7.3p1/rsa.c.openssl openssh-7.3p1/rsa.c BN_CTX_free(ctx); return r; } -diff -up openssh-7.3p1/rsa.h.openssl openssh-7.3p1/rsa.h ---- openssh-7.3p1/rsa.h.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/rsa.h 2016-10-27 14:28:16.620815252 +0200 +diff -up openssh-7.4p1/rsa.h.openssl openssh-7.4p1/rsa.h +--- openssh-7.4p1/rsa.h.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/rsa.h 2016-12-23 17:47:36.434817754 +0100 @@ -21,6 +21,6 @@ int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); @@ -2186,10 +1926,10 @@ diff -up openssh-7.3p1/rsa.h.openssl openssh-7.3p1/rsa.h +int rsa_generate_additional_parameters(RSA *, BIGNUM *); #endif /* RSA_H */ -diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c ---- openssh-7.3p1/ssh-agent.c.openssl 2016-10-27 14:28:16.612815271 +0200 -+++ openssh-7.3p1/ssh-agent.c 2016-10-27 14:28:16.621815250 +0200 -@@ -251,12 +251,12 @@ process_request_identities(SocketEntry * +diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c +--- openssh-7.4p1/ssh-agent.c.openssl 2016-12-23 17:47:36.428817751 +0100 ++++ openssh-7.4p1/ssh-agent.c 2016-12-23 17:47:36.434817754 +0100 +@@ -258,12 +258,12 @@ process_request_identities(SocketEntry * TAILQ_FOREACH(id, &tab->idlist, next) { if (id->key->type == KEY_RSA1) { #ifdef WITH_SSH1 @@ -2207,7 +1947,7 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c fatal("%s: buffer error: %s", __func__, ssh_err(r)); #endif -@@ -295,6 +295,7 @@ process_authentication_challenge1(Socket +@@ -302,6 +302,7 @@ process_authentication_challenge1(Socket struct sshbuf *msg; struct ssh_digest_ctx *md; struct sshkey *key; @@ -2215,7 +1955,7 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); -@@ -303,11 +304,16 @@ process_authentication_challenge1(Socket +@@ -310,11 +311,16 @@ process_authentication_challenge1(Socket if ((challenge = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); @@ -2236,7 +1976,7 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c /* Only protocol 1.1 is supported */ if (sshbuf_len(e->request) == 0) -@@ -443,6 +449,7 @@ process_remove_identity(SocketEntry *e, +@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, u_char *blob; #ifdef WITH_SSH1 u_int bits; @@ -2244,7 +1984,7 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c #endif /* WITH_SSH1 */ switch (version) { -@@ -452,10 +459,15 @@ process_remove_identity(SocketEntry *e, +@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, error("%s: sshkey_new failed", __func__); return; } @@ -2263,7 +2003,7 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c if (bits != sshkey_size(key)) logit("Warning: identity keysize mismatch: " -@@ -558,23 +570,38 @@ agent_decode_rsa1(struct sshbuf *m, stru +@@ -565,23 +577,38 @@ agent_decode_rsa1(struct sshbuf *m, stru { struct sshkey *k = NULL; int r = SSH_ERR_INTERNAL_ERROR; @@ -2310,9 +2050,9 @@ diff -up openssh-7.3p1/ssh-agent.c.openssl openssh-7.3p1/ssh-agent.c goto out; /* enable blinding */ if (RSA_blinding_on(k->rsa, NULL) != 1) { -diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c ---- openssh-7.3p1/sshconnect1.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/sshconnect1.c 2016-10-27 16:20:55.388110063 +0200 +diff -up openssh-7.4p1/sshconnect1.c.openssl openssh-7.4p1/sshconnect1.c +--- openssh-7.4p1/sshconnect1.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshconnect1.c 2016-12-23 17:47:36.434817754 +0100 @@ -70,6 +70,7 @@ try_agent_authentication(void) u_char response[16]; size_t i; @@ -2381,7 +2121,7 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c Key *host_key, *server_key; int bits, rbits; int ssh_cipher_default = SSH_CIPHER_3DES; -@@ -523,10 +531,14 @@ ssh_kex(char *host, struct sockaddr *hos +@@ -522,10 +530,14 @@ ssh_kex(char *host, struct sockaddr *hos /* Get the public key. */ server_key = key_new(KEY_RSA1); bits = packet_get_int(); @@ -2399,7 +2139,7 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c if (bits != rbits) { logit("Warning: Server lies about size of server public key: " "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -535,10 +547,14 @@ ssh_kex(char *host, struct sockaddr *hos +@@ -534,10 +546,14 @@ ssh_kex(char *host, struct sockaddr *hos /* Get the host key. */ host_key = key_new(KEY_RSA1); bits = packet_get_int(); @@ -2417,7 +2157,7 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c if (bits != rbits) { logit("Warning: Server lies about size of server host key: " "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -554,14 +570,14 @@ ssh_kex(char *host, struct sockaddr *hos +@@ -553,14 +569,14 @@ ssh_kex(char *host, struct sockaddr *hos packet_check_eom(); debug("Received server public key (%d bits) and host key (%d bits).", @@ -2434,7 +2174,7 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c /* * Generate an encryption key for the session. The key is a 256 bit -@@ -601,14 +617,14 @@ ssh_kex(char *host, struct sockaddr *hos +@@ -595,14 +611,14 @@ ssh_kex(char *host, struct sockaddr *hos * Encrypt the integer using the public key and host key of the * server (key with smaller modulus first). */ @@ -2454,7 +2194,7 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c SSH_KEY_BITS_RESERVED); } if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || -@@ -616,12 +632,12 @@ ssh_kex(char *host, struct sockaddr *hos +@@ -610,12 +626,12 @@ ssh_kex(char *host, struct sockaddr *hos fatal("%s: rsa_public_encrypt failed", __func__); } else { /* Host key has smaller modulus (or they are equal). */ @@ -2471,9 +2211,9 @@ diff -up openssh-7.3p1/sshconnect1.c.openssl openssh-7.3p1/sshconnect1.c SSH_KEY_BITS_RESERVED); } if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || -diff -up openssh-7.3p1/sshconnect2.c.openssl openssh-7.3p1/sshconnect2.c ---- openssh-7.3p1/sshconnect2.c.openssl 2016-10-27 14:28:16.606815286 +0200 -+++ openssh-7.3p1/sshconnect2.c 2016-10-27 14:28:16.621815250 +0200 +diff -up openssh-7.4p1/sshconnect2.c.openssl openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.openssl 2016-12-23 17:47:36.423817749 +0100 ++++ openssh-7.4p1/sshconnect2.c 2016-12-23 17:47:36.434817754 +0100 @@ -299,6 +299,7 @@ ssh_kex2(char *host, struct sockaddr *ho packet_send(); packet_write_wait(); @@ -2482,10 +2222,10 @@ diff -up openssh-7.3p1/sshconnect2.c.openssl openssh-7.3p1/sshconnect2.c } /* -diff -up openssh-7.3p1/sshconnect.c.openssl openssh-7.3p1/sshconnect.c ---- openssh-7.3p1/sshconnect.c.openssl 2016-10-27 14:28:16.571815369 +0200 -+++ openssh-7.3p1/sshconnect.c 2016-10-27 14:28:16.622815247 +0200 -@@ -1370,6 +1370,7 @@ ssh_login(Sensitive *sensitive, const ch +diff -up openssh-7.4p1/sshconnect.c.openssl openssh-7.4p1/sshconnect.c +--- openssh-7.4p1/sshconnect.c.openssl 2016-12-23 17:47:36.397817738 +0100 ++++ openssh-7.4p1/sshconnect.c 2016-12-23 17:47:36.435817754 +0100 +@@ -1369,6 +1369,7 @@ ssh_login(Sensitive *sensitive, const ch char *server_user, *local_user; local_user = xstrdup(pw->pw_name); @@ -2493,10 +2233,10 @@ diff -up openssh-7.3p1/sshconnect.c.openssl openssh-7.3p1/sshconnect.c server_user = options.user ? options.user : local_user; /* Convert the user-supplied hostname into all lowercase. */ -diff -up openssh-7.3p1/ssh.c.openssl openssh-7.3p1/ssh.c ---- openssh-7.3p1/ssh.c.openssl 2016-10-27 14:28:16.606815286 +0200 -+++ openssh-7.3p1/ssh.c 2016-10-27 14:28:16.622815247 +0200 -@@ -535,7 +535,9 @@ main(int ac, char **av) +diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c +--- openssh-7.4p1/ssh.c.openssl 2016-12-23 17:47:36.422817748 +0100 ++++ openssh-7.4p1/ssh.c 2016-12-23 17:47:36.435817754 +0100 +@@ -532,7 +532,9 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -2514,84 +2254,10 @@ diff -up openssh-7.3p1/ssh.c.openssl openssh-7.3p1/ssh.c if (config_test) { dump_client_config(&options, host); -diff -up openssh-7.3p1/sshd.c.openssl openssh-7.3p1/sshd.c ---- openssh-7.3p1/sshd.c.openssl 2016-10-27 14:28:16.613815269 +0200 -+++ openssh-7.3p1/sshd.c 2016-10-27 14:51:24.038759046 +0200 -@@ -1141,19 +1141,17 @@ send_rexec_state(int fd, struct sshbuf * - #ifdef WITH_SSH1 - if (sensitive_data.server_key != NULL && - sensitive_data.server_key->type == KEY_RSA1) { -+ const BIGNUM *e, *n, *d, *iqmp, *p, *q; -+ RSA_get0_key(sensitive_data.server_key->rsa, &n, &e, &d); -+ RSA_get0_factors(sensitive_data.server_key->rsa, &p, &q); -+ RSA_get0_crt_params(sensitive_data.server_key->rsa, NULL, NULL, &iqmp); - if ((r = sshbuf_put_u32(m, 1)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->n)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->p)) != 0 || -- (r = sshbuf_put_bignum1(m, -- sensitive_data.server_key->rsa->q)) != 0) -+ (r = sshbuf_put_bignum1(m, e)) != 0 || -+ (r = sshbuf_put_bignum1(m, n)) != 0 || -+ (r = sshbuf_put_bignum1(m, d)) != 0 || -+ (r = sshbuf_put_bignum1(m, iqmp)) != 0 || -+ (r = sshbuf_put_bignum1(m, p)) != 0 || -+ (r = sshbuf_put_bignum1(m, q)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - } else - #endif -@@ -1195,17 +1193,25 @@ recv_rexec_state(int fd, Buffer *conf) - - if (buffer_get_int(&m)) { - #ifdef WITH_SSH1 -+ BIGNUM *e = NULL, *n = NULL, *d = NULL, *iqmp = NULL, -+ *p = NULL, *q = NULL; - if (sensitive_data.server_key != NULL) - key_free(sensitive_data.server_key); -+ if ((e = BN_new()) == NULL || (n = BN_new()) == NULL || -+ (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL || -+ (p = BN_new()) == NULL || (q = BN_new()) == NULL) -+ fatal("BN_new() failed"); - sensitive_data.server_key = key_new_private(KEY_RSA1); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); -- buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); -+ buffer_get_bignum(&m, e); -+ buffer_get_bignum(&m, n); -+ buffer_get_bignum(&m, d); -+ buffer_get_bignum(&m, iqmp); -+ buffer_get_bignum(&m, p); -+ buffer_get_bignum(&m, q); -+ RSA_set0_key(sensitive_data.server_key->rsa, n, e, d); -+ RSA_set0_factors(sensitive_data.server_key->rsa, p, q); - if (rsa_generate_additional_parameters( -- sensitive_data.server_key->rsa) != 0) -+ sensitive_data.server_key->rsa, iqmp) != 0) - fatal("%s: rsa_generate_additional_parameters " - "error", __func__); - #endif -@@ -1576,8 +1584,9 @@ check_ip_options(struct ssh *ssh) - #ifdef IP_OPTIONS - int sock_in = ssh_packet_get_connection_in(ssh); - struct sockaddr_storage from; -- socklen_t option_size, i, fromlen = sizeof(from); -+ socklen_t i, fromlen = sizeof(from); - u_char opts[200]; -+ socklen_t option_size = sizeof(opts); - char text[sizeof(opts) * 3 + 1]; - - memset(&from, 0, sizeof(from)); -@@ -1649,7 +1658,7 @@ main(int ac, char **av) +diff -up openssh-7.4p1/sshd.c.openssl openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.openssl 2016-12-23 17:47:36.428817751 +0100 ++++ openssh-7.4p1/sshd.c 2016-12-23 17:47:36.435817754 +0100 +@@ -1483,7 +1483,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -2600,142 +2266,9 @@ diff -up openssh-7.3p1/sshd.c.openssl openssh-7.3p1/sshd.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)) { openlog(__progname, LOG_PID, LOG_AUTHPRIV); -@@ -2082,6 +2091,7 @@ main(int ac, char **av) - #ifdef WITH_SSH1 - /* Check certain values for sanity. */ - if (options.protocol & SSH_PROTO_1) { -+ const BIGNUM *n; - if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || - options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { - fprintf(stderr, "Bad server key size.\n"); -@@ -2092,13 +2102,13 @@ main(int ac, char **av) - * is necessary to make double encryption work with rsaref. Oh, I - * hate software patents. I dont know if this can go? Niels - */ -+ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &n, NULL, NULL); - if (options.server_key_bits > -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - -- SSH_KEY_BITS_RESERVED && options.server_key_bits < -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + -- SSH_KEY_BITS_RESERVED) { -+ BN_num_bits(n) - SSH_KEY_BITS_RESERVED && -+ options.server_key_bits < -+ BN_num_bits(n) + SSH_KEY_BITS_RESERVED) { - options.server_key_bits = -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + -+ BN_num_bits(n) + - SSH_KEY_BITS_RESERVED; - debug("Forcing server key to %d bits to make it differ from host key.", - options.server_key_bits); -@@ -2521,18 +2531,18 @@ ssh1_session_key(BIGNUM *session_key_int - { - struct ssh *ssh = active_state; /* XXX */ - int rsafail = 0; -+ const BIGNUM *s_n, *h_n; - -- if (BN_cmp(sensitive_data.server_key->rsa->n, -- sensitive_data.ssh1_host_key->rsa->n) > 0) { -+ RSA_get0_key(sensitive_data.server_key->rsa, &s_n, NULL, NULL); -+ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &h_n, NULL, NULL); -+ if (BN_cmp(s_n, h_n) > 0) { - /* Server key has bigger modulus. */ -- if (BN_num_bits(sensitive_data.server_key->rsa->n) < -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + -- SSH_KEY_BITS_RESERVED) { -+ if (BN_num_bits(s_n) < -+ BN_num_bits(h_n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s port %d: " - "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -- BN_num_bits(sensitive_data.server_key->rsa->n), -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), -+ BN_num_bits(s_n), BN_num_bits(h_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, -@@ -2543,14 +2553,14 @@ ssh1_session_key(BIGNUM *session_key_int - rsafail++; - } else { - /* Host key has bigger modulus (or they are equal). */ -- if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < -- BN_num_bits(sensitive_data.server_key->rsa->n) + -+ if (BN_num_bits(h_n) < -+ BN_num_bits(s_n) + - SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s port %d: " - "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), -- BN_num_bits(sensitive_data.server_key->rsa->n), -+ BN_num_bits(h_n), -+ BN_num_bits(s_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, -@@ -2578,6 +2588,7 @@ do_ssh1_kex(void) - size_t fake_key_len; - u_char cookie[8]; - u_int cipher_type, auth_mask, protocol_flags; -+ const BIGNUM *n, *e; - - /* - * Generate check bytes that the client must send back in the user -@@ -2600,14 +2611,16 @@ do_ssh1_kex(void) - packet_put_char(cookie[i]); - - /* Store our public server RSA key. */ -- packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); -- packet_put_bignum(sensitive_data.server_key->rsa->e); -- packet_put_bignum(sensitive_data.server_key->rsa->n); -+ RSA_get0_key(sensitive_data.server_key->rsa, &n, &e, NULL); -+ packet_put_int(BN_num_bits(n)); -+ packet_put_bignum((BIGNUM *)e); -+ packet_put_bignum((BIGNUM *)n); - - /* Store our public host RSA key. */ -- packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); -- packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); -- packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); -+ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &n, &e, NULL); -+ packet_put_int(BN_num_bits(n)); -+ packet_put_bignum((BIGNUM *)e); -+ packet_put_bignum((BIGNUM *)n); - - /* Put protocol flags. */ - packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); -@@ -2632,8 +2645,8 @@ do_ssh1_kex(void) - packet_write_wait(); - - debug("Sent %d bit server key and %d bit host key.", -- BN_num_bits(sensitive_data.server_key->rsa->n), -- BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); -+ RSA_bits(sensitive_data.server_key->rsa), -+ RSA_bits(sensitive_data.ssh1_host_key->rsa)); - - /* Read clients reply (cipher type and session key). */ - packet_read_expect(SSH_CMSG_SESSION_KEY); -@@ -2697,14 +2710,14 @@ do_ssh1_kex(void) - len, (u_long)sizeof(session_key)); - rsafail++; - } else { -+ const BIGNUM *h_n, *s_n; - explicit_bzero(session_key, sizeof(session_key)); - BN_bn2bin(session_key_int, - session_key + sizeof(session_key) - len); - -- derive_ssh1_session_id( -- sensitive_data.ssh1_host_key->rsa->n, -- sensitive_data.server_key->rsa->n, -- cookie, session_id); -+ RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &h_n, NULL, NULL); -+ RSA_get0_key(sensitive_data.server_key->rsa, &s_n, NULL, NULL); -+ derive_ssh1_session_id((BIGNUM *)h_n, (BIGNUM *)s_n, cookie, session_id); - /* - * Xor the first 16 bytes of the session key with the - * session id. -diff -up openssh-7.3p1/ssh-dss.c.openssl openssh-7.3p1/ssh-dss.c ---- openssh-7.3p1/ssh-dss.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-dss.c 2016-10-27 14:28:16.623815245 +0200 +diff -up openssh-7.4p1/ssh-dss.c.openssl openssh-7.4p1/ssh-dss.c +--- openssh-7.4p1/ssh-dss.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-dss.c 2016-12-23 17:47:36.435817754 +0100 @@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; @@ -2809,9 +2342,9 @@ diff -up openssh-7.3p1/ssh-dss.c.openssl openssh-7.3p1/ssh-dss.c sshbuf_free(b); free(ktype); if (sigblob != NULL) { -diff -up openssh-7.3p1/ssh-ecdsa.c.openssl openssh-7.3p1/ssh-ecdsa.c ---- openssh-7.3p1/ssh-ecdsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-ecdsa.c 2016-10-27 14:28:16.623815245 +0200 +diff -up openssh-7.4p1/ssh-ecdsa.c.openssl openssh-7.4p1/ssh-ecdsa.c +--- openssh-7.4p1/ssh-ecdsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-ecdsa.c 2016-12-23 17:47:36.436817754 +0100 @@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, size_t len, dlen; struct sshbuf *b = NULL, *bb = NULL; @@ -2879,10 +2412,10 @@ diff -up openssh-7.3p1/ssh-ecdsa.c.openssl openssh-7.3p1/ssh-ecdsa.c free(ktype); return ret; } -diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c ---- openssh-7.3p1/sshkey.c.openssl 2016-10-27 14:28:16.607815283 +0200 -+++ openssh-7.3p1/sshkey.c 2016-10-27 14:28:16.624815243 +0200 -@@ -276,10 +276,10 @@ sshkey_size(const struct sshkey *k) +diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.openssl 2016-12-23 17:47:36.424817749 +0100 ++++ openssh-7.4p1/sshkey.c 2016-12-23 17:47:56.652826110 +0100 +@@ -275,10 +275,10 @@ sshkey_size(const struct sshkey *k) case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: @@ -2895,7 +2428,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: return sshkey_curve_nid_to_bits(k->ecdsa_nid); -@@ -312,11 +312,17 @@ sshkey_is_private(const struct sshkey *k +@@ -311,11 +311,17 @@ sshkey_is_private(const struct sshkey *k #ifdef WITH_OPENSSL case KEY_RSA_CERT: case KEY_RSA1: @@ -2917,7 +2450,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -506,11 +512,7 @@ sshkey_new(int type) +@@ -505,11 +511,7 @@ sshkey_new(int type) case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: @@ -2930,7 +2463,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c free(k); return NULL; } -@@ -518,13 +520,7 @@ sshkey_new(int type) +@@ -517,13 +519,7 @@ sshkey_new(int type) break; case KEY_DSA: case KEY_DSA_CERT: @@ -2945,7 +2478,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c free(k); return NULL; } -@@ -565,21 +561,10 @@ sshkey_add_private(struct sshkey *k) +@@ -563,21 +559,10 @@ sshkey_add_private(struct sshkey *k) case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: @@ -2967,7 +2500,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ -@@ -698,17 +683,31 @@ sshkey_equal_public(const struct sshkey +@@ -696,17 +681,31 @@ sshkey_equal_public(const struct sshkey #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA_CERT: @@ -3009,7 +2542,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -783,15 +782,21 @@ to_blob_buf(const struct sshkey *key, st +@@ -781,15 +780,21 @@ to_blob_buf(const struct sshkey *key, st return ret; break; #ifdef WITH_OPENSSL @@ -3040,7 +2573,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -804,13 +809,18 @@ to_blob_buf(const struct sshkey *key, st +@@ -802,13 +807,18 @@ to_blob_buf(const struct sshkey *key, st return ret; break; # endif @@ -3066,7 +2599,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519: -@@ -916,8 +926,13 @@ sshkey_fingerprint_raw(const struct sshk +@@ -914,8 +924,13 @@ sshkey_fingerprint_raw(const struct sshk if (k->type == KEY_RSA1) { #ifdef WITH_OPENSSL @@ -3080,9 +2613,9 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c + nlen = BN_num_bytes(n); + elen = BN_num_bytes(e); - blob_len = nlen + elen; - if (nlen >= INT_MAX - elen || -@@ -925,8 +940,8 @@ sshkey_fingerprint_raw(const struct sshk + if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) { + r = SSH_ERR_INVALID_FORMAT; +@@ -926,8 +941,8 @@ sshkey_fingerprint_raw(const struct sshk r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3093,7 +2626,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c #endif /* WITH_OPENSSL */ } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) goto out; -@@ -1289,6 +1304,7 @@ sshkey_read(struct sshkey *ret, char **c +@@ -1290,6 +1305,7 @@ sshkey_read(struct sshkey *ret, char **c struct sshbuf *blob; #ifdef WITH_SSH1 u_long bits; @@ -3101,7 +2634,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c #endif /* WITH_SSH1 */ cp = *cpp; -@@ -1302,12 +1318,21 @@ sshkey_read(struct sshkey *ret, char **c +@@ -1303,12 +1319,21 @@ sshkey_read(struct sshkey *ret, char **c bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ /* Get public exponent, public modulus. */ @@ -3126,7 +2659,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c return SSH_ERR_KEY_BITS_MISMATCH; *cpp = ep; retval = 0; -@@ -1472,19 +1497,20 @@ sshkey_format_rsa1(const struct sshkey * +@@ -1473,19 +1498,20 @@ sshkey_format_rsa1(const struct sshkey * #ifdef WITH_SSH1 u_int bits = 0; char *dec_e = NULL, *dec_n = NULL; @@ -3152,7 +2685,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c r = SSH_ERR_INVALID_ARGUMENT; goto out; } -@@ -1818,15 +1844,32 @@ sshkey_from_private(const struct sshkey +@@ -1819,15 +1845,32 @@ sshkey_from_private(const struct sshkey switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA: @@ -3194,7 +2727,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c } break; # ifdef OPENSSL_HAS_ECC -@@ -1849,13 +1892,22 @@ sshkey_from_private(const struct sshkey +@@ -1850,13 +1893,22 @@ sshkey_from_private(const struct sshkey # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: case KEY_RSA1: @@ -3224,7 +2757,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c } break; #endif /* WITH_OPENSSL */ -@@ -2053,10 +2105,20 @@ sshkey_from_blob_internal(struct sshbuf +@@ -2054,10 +2106,20 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3249,7 +2782,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c } #ifdef DEBUG_PK RSA_print_fp(stderr, key->rsa, 8); -@@ -2074,12 +2136,34 @@ sshkey_from_blob_internal(struct sshbuf +@@ -2075,12 +2137,34 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3290,7 +2823,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c } #ifdef DEBUG_PK DSA_print_fp(stderr, key->dsa, 8); -@@ -2319,26 +2403,53 @@ sshkey_demote(const struct sshkey *k, st +@@ -2320,26 +2404,53 @@ sshkey_demote(const struct sshkey *k, st goto fail; /* FALLTHROUGH */ case KEY_RSA1: @@ -3358,7 +2891,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c } break; case KEY_ECDSA_CERT: -@@ -2459,12 +2570,17 @@ sshkey_certify(struct sshkey *k, struct +@@ -2460,12 +2571,17 @@ sshkey_certify(struct sshkey *k, struct /* XXX this substantially duplicates to_blob(); refactor */ switch (k->type) { #ifdef WITH_OPENSSL @@ -3382,7 +2915,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: -@@ -2476,10 +2592,15 @@ sshkey_certify(struct sshkey *k, struct +@@ -2477,10 +2593,15 @@ sshkey_certify(struct sshkey *k, struct goto out; break; # endif /* OPENSSL_HAS_ECC */ @@ -3402,7 +2935,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: -@@ -2636,43 +2757,65 @@ sshkey_private_serialize(const struct ss +@@ -2637,43 +2758,65 @@ sshkey_private_serialize(const struct ss goto out; switch (key->type) { #ifdef WITH_OPENSSL @@ -3492,7 +3025,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2748,18 +2891,51 @@ sshkey_private_deserialize(struct sshbuf +@@ -2749,18 +2892,51 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3555,7 +3088,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2818,24 +2994,81 @@ sshkey_private_deserialize(struct sshbuf +@@ -2819,24 +2995,81 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3654,15 +3187,15 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519: -@@ -3465,6 +3690,7 @@ sshkey_private_rsa1_to_blob(struct sshke - struct sshcipher_ctx ciphercontext; +@@ -3471,6 +3704,7 @@ sshkey_private_rsa1_to_blob(struct sshke + struct sshcipher_ctx *ciphercontext = NULL; const struct sshcipher *cipher; u_char *cp; + const BIGNUM *n, *e, *d, *q, *p, *iqmp; /* * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting -@@ -3491,10 +3717,13 @@ sshkey_private_rsa1_to_blob(struct sshke +@@ -3497,10 +3731,13 @@ sshkey_private_rsa1_to_blob(struct sshke * format would just give known plaintext). * Note: q and p are stored in reverse order to SSL. */ @@ -3680,7 +3213,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c goto out; /* Pad the part to be encrypted to a size that is a multiple of 8. */ -@@ -3519,9 +3748,9 @@ sshkey_private_rsa1_to_blob(struct sshke +@@ -3525,9 +3762,9 @@ sshkey_private_rsa1_to_blob(struct sshke goto out; /* Store public key. This will be in plain text. */ @@ -3693,7 +3226,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; -@@ -3650,6 +3879,7 @@ sshkey_parse_public_rsa1_fileblob(struct +@@ -3654,6 +3891,7 @@ sshkey_parse_public_rsa1_fileblob(struct int r; struct sshkey *pub = NULL; struct sshbuf *copy = NULL; @@ -3701,7 +3234,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c if (keyp != NULL) *keyp = NULL; -@@ -3679,10 +3909,16 @@ sshkey_parse_public_rsa1_fileblob(struct +@@ -3683,10 +3921,16 @@ sshkey_parse_public_rsa1_fileblob(struct goto out; /* Read the public key from the buffer. */ @@ -3721,8 +3254,8 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c /* Finally, the comment */ if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) -@@ -3714,6 +3950,8 @@ sshkey_parse_private_rsa1(struct sshbuf - struct sshcipher_ctx ciphercontext; +@@ -3718,6 +3962,8 @@ sshkey_parse_private_rsa1(struct sshbuf + struct sshcipher_ctx *ciphercontext = NULL; const struct sshcipher *cipher; struct sshkey *prv = NULL; + BIGNUM *n = NULL, *e = NULL, *d = NULL, *q = NULL, *p = NULL, @@ -3730,7 +3263,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c if (keyp != NULL) *keyp = NULL; -@@ -3749,11 +3987,17 @@ sshkey_parse_private_rsa1(struct sshbuf +@@ -3753,11 +3999,17 @@ sshkey_parse_private_rsa1(struct sshbuf goto out; /* Read the public key and comment from the buffer. */ @@ -3752,7 +3285,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); -@@ -3786,14 +4030,25 @@ sshkey_parse_private_rsa1(struct sshbuf +@@ -3786,14 +4038,25 @@ sshkey_parse_private_rsa1(struct sshbuf } /* Read the rest of the private key. */ @@ -3783,7 +3316,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c goto out; /* enable blinding */ -@@ -3846,7 +4101,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3846,7 +4109,7 @@ sshkey_parse_private_pem_fileblob(struct r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } @@ -3792,7 +3325,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3861,7 +4116,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3861,7 +4124,7 @@ sshkey_parse_private_pem_fileblob(struct r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -3801,7 +3334,7 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3873,7 +4128,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3873,7 +4136,7 @@ sshkey_parse_private_pem_fileblob(struct DSA_print_fp(stderr, prv->dsa, 8); #endif #ifdef OPENSSL_HAS_ECC @@ -3810,9 +3343,9 @@ diff -up openssh-7.3p1/sshkey.c.openssl openssh-7.3p1/sshkey.c (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -diff -up openssh-7.3p1/ssh-keygen.c.openssl openssh-7.3p1/ssh-keygen.c ---- openssh-7.3p1/ssh-keygen.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-keygen.c 2016-10-27 14:28:16.625815240 +0200 +diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c +--- openssh-7.4p1/ssh-keygen.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-keygen.c 2016-12-23 17:47:36.437817755 +0100 @@ -480,40 +480,67 @@ do_convert_private_ssh2_from_blob(u_char free(type); @@ -3938,9 +3471,9 @@ diff -up openssh-7.3p1/ssh-keygen.c.openssl openssh-7.3p1/ssh-keygen.c exit(0); } -diff -up openssh-7.3p1/ssh-keyscan.c.openssl openssh-7.3p1/ssh-keyscan.c ---- openssh-7.3p1/ssh-keyscan.c.openssl 2016-10-27 14:28:16.486815572 +0200 -+++ openssh-7.3p1/ssh-keyscan.c 2016-10-27 14:28:16.625815240 +0200 +diff -up openssh-7.4p1/ssh-keyscan.c.openssl openssh-7.4p1/ssh-keyscan.c +--- openssh-7.4p1/ssh-keyscan.c.openssl 2016-12-23 17:47:36.325817708 +0100 ++++ openssh-7.4p1/ssh-keyscan.c 2016-12-23 17:47:36.437817755 +0100 @@ -195,6 +195,7 @@ keygrab_ssh1(con *c) static struct sshbuf *msg; int r; @@ -3973,9 +3506,9 @@ diff -up openssh-7.3p1/ssh-keyscan.c.openssl openssh-7.3p1/ssh-keyscan.c error("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_reset(msg); return NULL; -diff -up openssh-7.3p1/ssh-pkcs11-client.c.openssl openssh-7.3p1/ssh-pkcs11-client.c ---- openssh-7.3p1/ssh-pkcs11-client.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-pkcs11-client.c 2016-10-27 14:28:16.625815240 +0200 +diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-client.c +--- openssh-7.4p1/ssh-pkcs11-client.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-pkcs11-client.c 2016-12-23 17:47:36.437817755 +0100 @@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, con static int wrap_key(RSA *rsa) @@ -3996,9 +3529,9 @@ diff -up openssh-7.3p1/ssh-pkcs11-client.c.openssl openssh-7.3p1/ssh-pkcs11-clie return (0); } -diff -up openssh-7.3p1/ssh-pkcs11.c.openssl openssh-7.3p1/ssh-pkcs11.c ---- openssh-7.3p1/ssh-pkcs11.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-pkcs11.c 2016-10-27 14:28:16.625815240 +0200 +diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c +--- openssh-7.4p1/ssh-pkcs11.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-pkcs11.c 2016-12-23 17:47:36.437817755 +0100 @@ -67,7 +67,7 @@ struct pkcs11_key { struct pkcs11_provider *provider; CK_ULONG slotidx; @@ -4085,9 +3618,9 @@ diff -up openssh-7.3p1/ssh-pkcs11.c.openssl openssh-7.3p1/ssh-pkcs11.c pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { key = sshkey_new(KEY_UNSPEC); key->rsa = rsa; -diff -up openssh-7.3p1/ssh-rsa.c.openssl openssh-7.3p1/ssh-rsa.c ---- openssh-7.3p1/ssh-rsa.c.openssl 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/ssh-rsa.c 2016-10-27 14:28:16.626815238 +0200 +diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c +--- openssh-7.4p1/ssh-rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/ssh-rsa.c 2016-12-23 17:47:36.437817755 +0100 @@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u hash_alg = rsa_hash_alg_from_ident(alg_ident); if (key == NULL || key->rsa == NULL || hash_alg == -1 || diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 26553fa..f973010 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -1,7 +1,7 @@ -diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c ---- openssh-6.6p1/channels.c.x11max 2016-06-27 16:28:49.803631684 +0200 -+++ openssh-6.6p1/channels.c 2016-06-27 16:28:49.814631678 +0200 -@@ -138,8 +138,8 @@ static int all_opens_permitted = 0; +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; /* -- X11 forwarding */ @@ -12,7 +12,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c /* Saved X11 local (client) display. */ static char *x11_saved_display = NULL; -@@ -3445,7 +3445,8 @@ channel_send_window_changes(void) +@@ -4228,7 +4228,8 @@ channel_send_window_changes(void) */ int x11_create_display_inet(int x11_display_offset, int x11_use_localhost, @@ -22,7 +22,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c { Channel *nc = NULL; int display_number, sock; -@@ -3457,10 +3458,15 @@ x11_create_display_inet(int x11_display_ +@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ if (chanids == NULL) return -1; @@ -40,7 +40,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; -@@ -3512,7 +3518,7 @@ x11_create_display_inet(int x11_display_ +@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ if (num_socks > 0) break; } @@ -49,7 +49,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c error("Failed to allocate internet-domain X11 display socket."); return -1; } -@@ -3658,7 +3664,7 @@ x11_connect_display(void) +@@ -4441,7 +4447,7 @@ x11_connect_display(void) memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; @@ -58,7 +58,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); -@@ -3674,7 +3680,7 @@ x11_connect_display(void) +@@ -4457,7 +4463,7 @@ x11_connect_display(void) /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("connect %.100s port %u: %.100s", buf, @@ -67,7 +67,7 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c close(sock); continue; } -@@ -3683,8 +3689,8 @@ x11_connect_display(void) +@@ -4466,8 +4472,8 @@ x11_connect_display(void) } freeaddrinfo(aitop); if (!ai) { @@ -78,10 +78,10 @@ diff -up openssh-6.6p1/channels.c.x11max openssh-6.6p1/channels.c return -1; } set_nodelay(sock); -diff -up openssh-6.6p1/channels.h.x11max openssh-6.6p1/channels.h ---- openssh-6.6p1/channels.h.x11max 2016-06-27 16:28:49.814631678 +0200 -+++ openssh-6.6p1/channels.h 2016-06-27 16:31:18.925557840 +0200 -@@ -281,7 +281,7 @@ int permitopen_port(const char *); +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(u_int); int x11_connect_display(void); @@ -90,10 +90,10 @@ diff -up openssh-6.6p1/channels.h.x11max openssh-6.6p1/channels.h int x11_input_open(int, u_int32_t, void *); void x11_request_forwarding_with_spoofing(int, const char *, const char *, const char *, int); -diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c ---- openssh-6.6p1/servconf.c.x11max 2016-06-27 16:28:49.808631681 +0200 -+++ openssh-6.6p1/servconf.c 2016-06-27 16:30:46.941573678 +0200 -@@ -92,6 +92,7 @@ initialize_server_options(ServerOptions +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; @@ -101,7 +101,7 @@ diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; -@@ -219,6 +220,8 @@ fill_default_server_options(ServerOption +@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; @@ -110,16 +110,16 @@ diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) -@@ -364,7 +367,7 @@ typedef enum { +@@ -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, sUseLogin, sAllowTcpForwarding, sCompression, + sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -476,6 +479,7 @@ static struct { +@@ -540,6 +543,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -127,9 +127,9 @@ diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, -@@ -1202,6 +1206,10 @@ process_server_config_line(ServerOptions - intptr = &options->x11_display_offset; - goto parse_int; +@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions + *intptr = value; + break; + case sX11MaxDisplays: + intptr = &options->x11_max_displays; @@ -138,7 +138,7 @@ diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; -@@ -1889,6 +1897,7 @@ copy_set_server_options(ServerOptions *d +@@ -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); @@ -146,17 +146,17 @@ diff -up openssh-6.6p1/servconf.c.x11max openssh-6.6p1/servconf.c M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); -@@ -2106,6 +2115,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(sKeyRegenerationTime, o->key_regeneration_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); + dump_cfg_int(sX11MaxDisplays, o->x11_max_displays); dump_cfg_int(sMaxAuthTries, o->max_authtries); dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); -diff -up openssh-6.6p1/servconf.h.x11max openssh-6.6p1/servconf.h ---- openssh-6.6p1/servconf.h.x11max 2016-06-27 16:28:49.809631681 +0200 -+++ openssh-6.6p1/servconf.h 2016-06-27 16:28:49.815631678 +0200 +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 */ @@ -173,10 +173,10 @@ diff -up openssh-6.6p1/servconf.h.x11max openssh-6.6p1/servconf.h int x11_use_localhost; /* If true, use localhost for fake X11 server. */ char *xauth_location; /* Location of xauth program */ int permit_tty; /* If false, deny pty allocation */ -diff -up openssh-6.6p1/session.c.x11max openssh-6.6p1/session.c ---- openssh-6.6p1/session.c.x11max 2016-06-27 16:28:49.809631681 +0200 -+++ openssh-6.6p1/session.c 2016-06-27 16:28:49.815631678 +0200 -@@ -2741,8 +2741,9 @@ session_setup_x11fwd(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(options.x11_display_offset, @@ -188,10 +188,10 @@ diff -up openssh-6.6p1/session.c.x11max openssh-6.6p1/session.c debug("x11_create_display_inet failed."); return 0; } -diff -up openssh-6.6p1/sshd_config.5.x11max openssh-6.6p1/sshd_config.5 ---- openssh-6.6p1/sshd_config.5.x11max 2016-06-27 16:28:49.809631681 +0200 -+++ openssh-6.6p1/sshd_config.5 2016-06-27 16:32:01.253536879 +0200 -@@ -930,6 +930,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 X11DisplayOffset , @@ -199,7 +199,7 @@ diff -up openssh-6.6p1/sshd_config.5.x11max openssh-6.6p1/sshd_config.5 .Cm X11Forwarding and .Cm X11UseLocalHost . -@@ -1339,6 +1340,12 @@ Specifies the first display number avail +@@ -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. diff --git a/openssh-7.4p1-daemon.patch b/openssh-7.4p1-daemon.patch new file mode 100644 index 0000000..3515398 --- /dev/null +++ b/openssh-7.4p1-daemon.patch @@ -0,0 +1,12 @@ +diff -up openssh-7.4p1/sshd.c.daemon openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.daemon 2017-01-02 15:32:56.618447579 +0100 ++++ openssh-7.4p1/sshd.c 2017-01-02 15:33:07.606442751 +0100 +@@ -1943,7 +1943,7 @@ main(int ac, char **av) + * terminal, and fork. The original process exits. + */ + already_daemon = daemonized(); +- if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) { ++ if (!(debug_flag || inetd_flag || no_daemon_flag /*|| already_daemon*/)) { + + if (daemon(0, 0) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); diff --git a/openssh-7.3p1-gsissh.patch b/openssh-7.4p1-gsissh.patch similarity index 88% rename from openssh-7.3p1-gsissh.patch rename to openssh-7.4p1-gsissh.patch index 89d11dc..cd2cb1a 100644 --- a/openssh-7.3p1-gsissh.patch +++ b/openssh-7.4p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c ---- openssh-7.3p1.orig/auth2.c 2016-12-13 11:17:13.434232603 +0100 -+++ openssh-7.3p1/auth2.c 2016-12-13 19:16:47.109836990 +0100 +diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c +--- openssh-7.4p1.orig/auth2.c 2017-01-24 13:03:15.289941715 +0100 ++++ openssh-7.4p1/auth2.c 2017-01-24 13:04:06.432370524 +0100 @@ -228,7 +228,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -97,9 +97,9 @@ diff -Nur openssh-7.3p1.orig/auth2.c openssh-7.3p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.3p1.orig/auth2-gss.c openssh-7.3p1/auth2-gss.c ---- openssh-7.3p1.orig/auth2-gss.c 2016-12-13 11:17:13.419232772 +0100 -+++ openssh-7.3p1/auth2-gss.c 2016-12-13 15:57:03.191160419 +0100 +diff -Nur openssh-7.4p1.orig/auth2-gss.c openssh-7.4p1/auth2-gss.c +--- openssh-7.4p1.orig/auth2-gss.c 2017-01-24 13:03:15.270941928 +0100 ++++ openssh-7.4p1/auth2-gss.c 2017-01-24 13:04:06.432370524 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -280,9 +280,9 @@ diff -Nur openssh-7.3p1.orig/auth2-gss.c openssh-7.3p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c ---- openssh-7.3p1.orig/auth.c 2016-12-13 11:17:13.435232591 +0100 -+++ openssh-7.3p1/auth.c 2016-12-15 13:50:04.489124248 +0100 +diff -Nur openssh-7.4p1.orig/auth.c openssh-7.4p1/auth.c +--- openssh-7.4p1.orig/auth.c 2017-01-24 13:03:15.290941704 +0100 ++++ openssh-7.4p1/auth.c 2017-01-24 13:04:06.433370512 +0100 @@ -77,6 +77,9 @@ #include "ssherr.h" #include "compat.h" @@ -293,7 +293,7 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -303,7 +306,8 @@ +@@ -314,7 +317,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -302,8 +302,8 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c + authctxt->user : "unknown", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), - compat20 ? "ssh2" : "ssh1", -@@ -330,6 +334,23 @@ + authctxt->info != NULL ? ": " : "", +@@ -340,6 +344,23 @@ if (authenticated == 0 && !authctxt->postponed) audit_event(audit_classify_auth(method)); #endif @@ -327,7 +327,7 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c } -@@ -633,6 +654,10 @@ +@@ -642,6 +663,10 @@ #endif pw = getpwnam(user); @@ -338,7 +338,7 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -652,7 +677,8 @@ +@@ -661,7 +686,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -348,10 +348,10 @@ diff -Nur openssh-7.3p1.orig/auth.c openssh-7.3p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c ---- openssh-7.3p1.orig/auth-pam.c 2016-12-13 11:17:13.458232332 +0100 -+++ openssh-7.3p1/auth-pam.c 2016-12-13 15:57:03.192160408 +0100 -@@ -284,6 +284,56 @@ +diff -Nur openssh-7.4p1.orig/auth-pam.c openssh-7.4p1/auth-pam.c +--- openssh-7.4p1.orig/auth-pam.c 2017-01-24 13:03:15.310941481 +0100 ++++ openssh-7.4p1/auth-pam.c 2017-01-24 13:04:06.434370501 +0100 +@@ -289,6 +289,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -408,7 +408,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -306,7 +356,7 @@ +@@ -311,7 +361,7 @@ static void import_environments(Buffer *b) { @@ -417,7 +417,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c u_int i, num_env; int err; -@@ -316,6 +366,17 @@ +@@ -321,6 +371,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -435,7 +435,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -467,6 +528,13 @@ +@@ -472,6 +533,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -449,7 +449,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; -@@ -487,6 +555,11 @@ +@@ -492,6 +560,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -461,7 +461,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -943,6 +1016,18 @@ +@@ -947,6 +1020,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -480,7 +480,7 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1241,6 +1326,9 @@ +@@ -1233,6 +1318,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -490,19 +490,19 @@ diff -Nur openssh-7.3p1.orig/auth-pam.c openssh-7.3p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.3p1.orig/auth-pam.h openssh-7.3p1/auth-pam.h ---- openssh-7.3p1.orig/auth-pam.h 2016-12-13 11:17:13.274234405 +0100 -+++ openssh-7.3p1/auth-pam.h 2016-12-13 15:57:03.192160408 +0100 -@@ -48,5 +48,6 @@ +diff -Nur openssh-7.4p1.orig/auth-pam.h openssh-7.4p1/auth-pam.h +--- openssh-7.4p1.orig/auth-pam.h 2017-01-24 13:03:15.169943056 +0100 ++++ openssh-7.4p1/auth-pam.h 2017-01-24 13:04:06.435370490 +0100 +@@ -41,5 +41,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); int is_pam_session_open(void); +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.3p1.orig/canohost.c openssh-7.3p1/canohost.c ---- openssh-7.3p1.orig/canohost.c 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/canohost.c 2016-12-13 15:57:03.192160408 +0100 +diff -Nur openssh-7.4p1.orig/canohost.c openssh-7.4p1/canohost.c +--- openssh-7.4p1.orig/canohost.c 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/canohost.c 2017-01-24 13:04:06.435370490 +0100 @@ -17,6 +17,7 @@ #include #include @@ -545,9 +545,9 @@ diff -Nur openssh-7.3p1.orig/canohost.c openssh-7.3p1/canohost.c + } + } +} -diff -Nur openssh-7.3p1.orig/canohost.h openssh-7.3p1/canohost.h ---- openssh-7.3p1.orig/canohost.h 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/canohost.h 2016-12-13 15:57:03.193160397 +0100 +diff -Nur openssh-7.4p1.orig/canohost.h openssh-7.4p1/canohost.h +--- openssh-7.4p1.orig/canohost.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/canohost.h 2017-01-24 13:04:06.435370490 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -555,10 +555,10 @@ diff -Nur openssh-7.3p1.orig/canohost.h openssh-7.3p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac ---- openssh-7.3p1.orig/configure.ac 2016-12-13 11:17:13.425232704 +0100 -+++ openssh-7.3p1/configure.ac 2016-12-13 15:57:03.193160397 +0100 -@@ -4383,6 +4383,14 @@ +diff -Nur openssh-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac +--- openssh-7.4p1.orig/configure.ac 2017-01-24 13:03:15.276941860 +0100 ++++ openssh-7.4p1/configure.ac 2017-01-24 13:04:06.436370479 +0100 +@@ -4428,6 +4428,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -573,7 +573,7 @@ diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4422,6 +4430,50 @@ +@@ -4467,6 +4475,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -624,10 +624,10 @@ diff -Nur openssh-7.3p1.orig/configure.ac openssh-7.3p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c ---- openssh-7.3p1.orig/gss-genr.c 2016-12-13 11:17:13.460232310 +0100 -+++ openssh-7.3p1/gss-genr.c 2016-12-13 15:57:03.233159954 +0100 -@@ -40,6 +40,7 @@ +diff -Nur openssh-7.4p1.orig/gss-genr.c openssh-7.4p1/gss-genr.c +--- openssh-7.4p1.orig/gss-genr.c 2017-01-24 13:03:15.312941458 +0100 ++++ openssh-7.4p1/gss-genr.c 2017-01-24 13:04:06.437370468 +0100 +@@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" #include "log.h" @@ -635,7 +635,7 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -371,9 +372,18 @@ +@@ -370,9 +371,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -655,7 +655,7 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -381,6 +391,7 @@ +@@ -380,6 +390,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -663,29 +663,24 @@ diff -Nur openssh-7.3p1.orig/gss-genr.c openssh-7.3p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c ---- openssh-7.3p1.orig/gss-serv.c 2016-12-13 11:17:13.420232760 +0100 -+++ openssh-7.3p1/gss-serv.c 2016-12-13 23:14:33.804004555 +0100 -@@ -47,14 +47,17 @@ - #include "servconf.h" - #include "uidswap.h" - -+#include "xmalloc.h" - #include "ssh-gss.h" +diff -Nur openssh-7.4p1.orig/gss-serv.c openssh-7.4p1/gss-serv.c +--- openssh-7.4p1.orig/gss-serv.c 2017-01-24 13:03:15.271941916 +0100 ++++ openssh-7.4p1/gss-serv.c 2017-01-24 16:22:25.069522257 +0100 +@@ -51,10 +51,12 @@ #include "monitor_wrap.h" extern ServerOptions options; +extern Authctxt *the_authctxt; 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}, 0, 0}; -+ GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, + { 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}, + GSS_C_NO_CONTEXT, 0, 0}; ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -62,14 +65,26 @@ +@@ -62,14 +64,26 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -712,7 +707,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -230,6 +245,10 @@ +@@ -230,6 +244,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -723,7 +718,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c } return (status); -@@ -249,6 +268,20 @@ +@@ -249,6 +267,20 @@ tok = ename->value; @@ -744,7 +739,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -316,8 +349,11 @@ +@@ -316,8 +348,11 @@ return GSS_S_COMPLETE; } @@ -758,7 +753,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); -@@ -360,9 +396,12 @@ +@@ -360,9 +395,12 @@ if (client->mech == NULL) return GSS_S_FAILURE; @@ -773,7 +768,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -389,6 +428,10 @@ +@@ -389,6 +427,10 @@ /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -784,7 +779,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c return (ctx->major); } -@@ -396,6 +439,7 @@ +@@ -396,6 +438,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -792,7 +787,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -411,6 +455,14 @@ +@@ -411,6 +454,14 @@ gssapi_client.store.data = NULL; } } @@ -807,7 +802,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c } /* As user */ -@@ -418,6 +470,11 @@ +@@ -418,6 +469,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -819,7 +814,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -451,8 +508,9 @@ +@@ -451,8 +507,9 @@ } /* Privileged */ @@ -830,7 +825,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c { OM_uint32 lmin; -@@ -461,6 +519,12 @@ +@@ -461,6 +518,12 @@ debug("No suitable client data"); return 0; } @@ -843,7 +838,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -480,6 +544,24 @@ +@@ -480,6 +543,24 @@ return (0); } @@ -868,7 +863,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -506,6 +588,7 @@ +@@ -506,6 +587,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -876,7 +871,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -535,6 +618,18 @@ +@@ -535,6 +617,18 @@ if (ret) return; @@ -895,7 +890,7 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -566,4 +661,13 @@ +@@ -566,4 +660,13 @@ return ok; } @@ -909,9 +904,9 @@ diff -Nur openssh-7.3p1.orig/gss-serv.c openssh-7.3p1/gss-serv.c +} + #endif -diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c ---- openssh-7.3p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/gss-serv-gsi.c 2016-12-15 13:37:48.136468294 +0100 +diff -Nur openssh-7.4p1.orig/gss-serv-gsi.c openssh-7.4p1/gss-serv-gsi.c +--- openssh-7.4p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/gss-serv-gsi.c 2017-01-24 13:04:06.438370457 +0100 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1242,9 +1237,9 @@ diff -Nur openssh-7.3p1.orig/gss-serv-gsi.c openssh-7.3p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c ---- openssh-7.3p1.orig/gss-serv-krb5.c 2016-12-13 11:17:13.392233076 +0100 -+++ openssh-7.3p1/gss-serv-krb5.c 2016-12-15 13:38:23.114071274 +0100 +diff -Nur openssh-7.4p1.orig/gss-serv-krb5.c openssh-7.4p1/gss-serv-krb5.c +--- openssh-7.4p1.orig/gss-serv-krb5.c 2017-01-24 13:03:15.245942207 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2017-01-24 13:04:06.438370457 +0100 @@ -378,6 +378,34 @@ return found_principal; } @@ -1298,9 +1293,9 @@ diff -Nur openssh-7.3p1.orig/gss-serv-krb5.c openssh-7.3p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c ---- openssh-7.3p1.orig/kexgsss.c 2016-12-13 11:17:13.462232287 +0100 -+++ openssh-7.3p1/kexgsss.c 2016-12-13 15:57:03.234159943 +0100 +diff -Nur openssh-7.4p1.orig/kexgsss.c openssh-7.4p1/kexgsss.c +--- openssh-7.4p1.orig/kexgsss.c 2017-01-24 13:03:15.313941447 +0100 ++++ openssh-7.4p1/kexgsss.c 2017-01-24 13:04:06.438370457 +0100 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1360,9 +1355,9 @@ diff -Nur openssh-7.3p1.orig/kexgsss.c openssh-7.3p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.3p1.orig/LICENSE.globus_usage openssh-7.3p1/LICENSE.globus_usage ---- openssh-7.3p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/LICENSE.globus_usage 2016-12-13 15:57:03.240159876 +0100 +diff -Nur openssh-7.4p1.orig/LICENSE.globus_usage openssh-7.4p1/LICENSE.globus_usage +--- openssh-7.4p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/LICENSE.globus_usage 2017-01-24 13:04:06.439370445 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1382,13 +1377,13 @@ diff -Nur openssh-7.3p1.orig/LICENSE.globus_usage openssh-7.3p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.3p1.orig/Makefile.in openssh-7.3p1/Makefile.in ---- openssh-7.3p1.orig/Makefile.in 2016-12-13 11:17:13.462232287 +0100 -+++ openssh-7.3p1/Makefile.in 2016-12-13 15:57:03.241159865 +0100 +diff -Nur openssh-7.4p1.orig/Makefile.in openssh-7.4p1/Makefile.in +--- openssh-7.4p1.orig/Makefile.in 2017-01-24 13:03:15.314941436 +0100 ++++ openssh-7.4p1/Makefile.in 2017-01-24 13:12:49.715525415 +0100 @@ -114,8 +114,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + monitor.o monitor_wrap.o auth-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ @@ -1396,9 +1391,9 @@ diff -Nur openssh-7.3p1.orig/Makefile.in openssh-7.3p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o -diff -Nur openssh-7.3p1.orig/misc.c openssh-7.3p1/misc.c ---- openssh-7.3p1.orig/misc.c 2016-12-13 11:17:13.390233098 +0100 -+++ openssh-7.3p1/misc.c 2016-12-13 15:57:03.241159865 +0100 +diff -Nur openssh-7.4p1.orig/misc.c openssh-7.4p1/misc.c +--- openssh-7.4p1.orig/misc.c 2017-01-24 13:03:15.244942218 +0100 ++++ openssh-7.4p1/misc.c 2017-01-24 13:04:06.440370434 +0100 @@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1458,10 +1453,10 @@ diff -Nur openssh-7.3p1.orig/misc.c openssh-7.3p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.3p1.orig/misc.h openssh-7.3p1/misc.h ---- openssh-7.3p1.orig/misc.h 2016-12-13 11:17:13.463232276 +0100 -+++ openssh-7.3p1/misc.h 2016-12-13 15:57:03.241159865 +0100 -@@ -65,6 +65,7 @@ +diff -Nur openssh-7.4p1.orig/misc.h openssh-7.4p1/misc.h +--- openssh-7.4p1.orig/misc.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/misc.h 2017-01-24 13:04:06.440370434 +0100 +@@ -69,6 +69,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1469,10 +1464,10 @@ diff -Nur openssh-7.3p1.orig/misc.h openssh-7.3p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c ---- openssh-7.3p1.orig/monitor.c 2016-12-13 11:17:13.463232276 +0100 -+++ openssh-7.3p1/monitor.c 2016-12-13 15:57:03.242159854 +0100 -@@ -165,6 +165,9 @@ +diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c +--- openssh-7.4p1.orig/monitor.c 2017-01-24 13:03:15.314941436 +0100 ++++ openssh-7.4p1/monitor.c 2017-01-24 13:17:19.347511114 +0100 +@@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1482,7 +1477,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -218,7 +221,7 @@ +@@ -213,7 +216,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1491,18 +1486,18 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -226,7 +229,7 @@ +@@ -221,7 +224,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM - {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start}, {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, - {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, - {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -256,6 +259,9 @@ - {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, +@@ -251,6 +254,9 @@ + {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, + {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, + {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, @@ -1510,7 +1505,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -265,6 +271,8 @@ +@@ -260,6 +266,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1519,34 +1514,25 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -305,7 +313,7 @@ - {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, - #endif - #ifdef USE_PAM -- {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, -+ {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start}, - {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, - {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, - {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, -@@ -401,6 +409,8 @@ +@@ -339,6 +347,8 @@ #ifdef GSSAPI - /* and for the GSSAPI key exchange */ - monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1); -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); + /* and for the GSSAPI key exchange */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); #endif - } else { - mon_dispatch = mon_dispatch_proto15; -@@ -527,6 +537,8 @@ + + /* The first few requests do not require asynchronous access */ +@@ -456,6 +466,8 @@ #ifdef GSSAPI - /* and for the GSSAPI key exchange */ - monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1); -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); + /* and for the GSSAPI key exchange */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); #endif - } else { - mon_dispatch = mon_dispatch_postauth15; -@@ -861,14 +873,17 @@ + + if (!no_pty_flag) { +@@ -762,14 +774,17 @@ debug3("%s", __func__); @@ -1567,24 +1553,24 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2258,12 +2273,15 @@ +@@ -1954,12 +1969,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; + int gssapi_keyex; if (!options.gss_authentication && !options.gss_keyex) - fatal("In GSSAPI monitor when GSSAPI is disabled"); + fatal("%s: GSSAPI authentication not enabled", __func__); + gssapi_keyex = buffer_get_int(m); + - authenticated = authctxt->valid && + authenticated = authctxt->valid && - ssh_gssapi_userok(authctxt->user, authctxt->pw); + ssh_gssapi_userok(authctxt->user, authctxt->pw, gssapi_keyex); buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2271,7 +2289,10 @@ +@@ -1967,7 +1985,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1596,7 +1582,7 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c if (authenticated) authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -2280,6 +2301,68 @@ +@@ -1976,6 +1997,68 @@ return (authenticated); } @@ -1665,9 +1651,9 @@ diff -Nur openssh-7.3p1.orig/monitor.c openssh-7.3p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.3p1.orig/monitor.h openssh-7.3p1/monitor.h ---- openssh-7.3p1.orig/monitor.h 2016-12-13 11:17:13.437232569 +0100 -+++ openssh-7.3p1/monitor.h 2016-12-13 15:57:03.242159854 +0100 +diff -Nur openssh-7.4p1.orig/monitor.h openssh-7.4p1/monitor.h +--- openssh-7.4p1.orig/monitor.h 2017-01-24 13:03:15.292941682 +0100 ++++ openssh-7.4p1/monitor.h 2017-01-24 13:04:06.442370412 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1680,11 +1666,11 @@ diff -Nur openssh-7.3p1.orig/monitor.h openssh-7.3p1/monitor.h + MONITOR_REQ_GSSERR = 204, MONITOR_ANS_GSSERR = 205 }; - struct mm_master; -diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c ---- openssh-7.3p1.orig/monitor_wrap.c 2016-12-13 11:17:13.453232389 +0100 -+++ openssh-7.3p1/monitor_wrap.c 2016-12-13 15:57:03.243159843 +0100 -@@ -1126,12 +1126,13 @@ + struct monitor { +diff -Nur openssh-7.4p1.orig/monitor_wrap.c openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1.orig/monitor_wrap.c 2017-01-24 13:03:15.306941525 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2017-01-24 13:04:06.442370412 +0100 +@@ -977,12 +977,13 @@ } int @@ -1699,7 +1685,7 @@ diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1144,6 +1145,83 @@ +@@ -995,6 +996,83 @@ return (authenticated); } @@ -1783,10 +1769,10 @@ diff -Nur openssh-7.3p1.orig/monitor_wrap.c openssh-7.3p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.3p1.orig/monitor_wrap.h openssh-7.3p1/monitor_wrap.h ---- openssh-7.3p1.orig/monitor_wrap.h 2016-12-13 11:17:13.443232501 +0100 -+++ openssh-7.3p1/monitor_wrap.h 2016-12-13 15:57:03.243159843 +0100 -@@ -64,9 +64,13 @@ +diff -Nur openssh-7.4p1.orig/monitor_wrap.h openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1.orig/monitor_wrap.h 2017-01-24 13:03:15.297941626 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2017-01-24 13:04:06.443370401 +0100 +@@ -59,9 +59,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1801,10 +1787,10 @@ diff -Nur openssh-7.3p1.orig/monitor_wrap.h openssh-7.3p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.3p1.orig/readconf.c openssh-7.3p1/readconf.c ---- openssh-7.3p1.orig/readconf.c 2016-12-13 11:17:13.447232456 +0100 -+++ openssh-7.3p1/readconf.c 2016-12-13 15:57:03.243159843 +0100 -@@ -1974,13 +1974,13 @@ +diff -Nur openssh-7.4p1.orig/readconf.c openssh-7.4p1/readconf.c +--- openssh-7.4p1.orig/readconf.c 2017-01-24 13:03:15.301941581 +0100 ++++ openssh-7.4p1/readconf.c 2017-01-24 13:04:06.444370390 +0100 +@@ -1973,13 +1973,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1822,9 +1808,9 @@ diff -Nur openssh-7.3p1.orig/readconf.c openssh-7.3p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.3p1.orig/readconf.h openssh-7.3p1/readconf.h ---- openssh-7.3p1.orig/readconf.h 2016-12-13 11:17:13.410232873 +0100 -+++ openssh-7.3p1/readconf.h 2016-12-13 15:57:03.243159843 +0100 +diff -Nur openssh-7.4p1.orig/readconf.h openssh-7.4p1/readconf.h +--- openssh-7.4p1.orig/readconf.h 2017-01-24 13:03:15.266941972 +0100 ++++ openssh-7.4p1/readconf.h 2017-01-24 13:04:06.444370390 +0100 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1834,9 +1820,9 @@ diff -Nur openssh-7.3p1.orig/readconf.h openssh-7.3p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c ---- openssh-7.3p1.orig/servconf.c 2016-12-13 11:17:13.454232377 +0100 -+++ openssh-7.3p1/servconf.c 2016-12-13 17:11:03.047678663 +0100 +diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c +--- openssh-7.4p1.orig/servconf.c 2017-01-24 13:03:15.307941514 +0100 ++++ openssh-7.4p1/servconf.c 2017-01-24 13:25:28.276034742 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1845,7 +1831,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -119,9 +120,11 @@ +@@ -115,9 +116,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1857,7 +1843,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->password_authentication = -1; -@@ -166,6 +169,8 @@ +@@ -160,6 +163,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1866,7 +1852,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -212,6 +217,8 @@ +@@ -207,6 +212,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1874,8 +1860,8 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c + options->permit_pam_user_change = 0; /* Standard Options */ - if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -300,13 +307,17 @@ + if (options->num_host_key_files == 0) { +@@ -280,13 +287,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1896,16 +1882,16 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -434,7 +445,7 @@ +@@ -414,7 +425,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sUsePAM, + sUsePAM, sPermitPAMUserChange, /* Standard Options */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, - sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -456,10 +467,14 @@ + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, +@@ -436,10 +447,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1920,7 +1906,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -485,8 +500,10 @@ +@@ -465,8 +480,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1931,7 +1917,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -532,7 +549,14 @@ +@@ -512,7 +529,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1946,7 +1932,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -540,7 +564,10 @@ +@@ -520,7 +544,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1957,7 +1943,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -609,6 +636,8 @@ +@@ -589,6 +616,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1966,7 +1952,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1072,6 +1101,10 @@ +@@ -1053,6 +1082,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1977,7 +1963,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1303,6 +1336,10 @@ +@@ -1259,6 +1292,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1988,7 +1974,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1311,6 +1348,10 @@ +@@ -1267,6 +1304,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1999,7 +1985,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1331,6 +1372,12 @@ +@@ -1287,6 +1328,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2012,7 +1998,7 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1805,6 +1852,35 @@ +@@ -1762,6 +1809,35 @@ *charptr = xstrdup(arg); break; @@ -2048,18 +2034,18 @@ diff -Nur openssh-7.3p1.orig/servconf.c openssh-7.3p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2104,6 +2180,7 @@ +@@ -2058,6 +2134,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); + M_CP_INTOPT(gss_deleg_creds); - M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h ---- openssh-7.3p1.orig/servconf.h 2016-12-13 11:17:13.431232636 +0100 -+++ openssh-7.3p1/servconf.h 2016-12-13 15:57:03.245159821 +0100 -@@ -124,9 +124,12 @@ + M_CP_INTOPT(hostbased_authentication); +diff -Nur openssh-7.4p1.orig/servconf.h openssh-7.4p1/servconf.h +--- openssh-7.4p1.orig/servconf.h 2017-01-24 13:03:15.279941827 +0100 ++++ openssh-7.4p1/servconf.h 2017-01-24 13:04:06.445370378 +0100 +@@ -118,9 +118,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -2072,7 +2058,7 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -183,6 +186,7 @@ +@@ -177,6 +180,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2080,7 +2066,7 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h int permit_tun; -@@ -191,6 +195,10 @@ +@@ -185,6 +189,10 @@ int use_kuserok; int enable_k5users; char *chroot_directory; @@ -2091,9 +2077,9 @@ diff -Nur openssh-7.3p1.orig/servconf.h openssh-7.3p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.3p1.orig/ssh.1 openssh-7.3p1/ssh.1 ---- openssh-7.3p1.orig/ssh.1 2016-12-13 11:17:13.422232738 +0100 -+++ openssh-7.3p1/ssh.1 2016-12-13 15:57:03.245159821 +0100 +diff -Nur openssh-7.4p1.orig/ssh.1 openssh-7.4p1/ssh.1 +--- openssh-7.4p1.orig/ssh.1 2017-01-24 13:03:15.273941894 +0100 ++++ openssh-7.4p1/ssh.1 2017-01-24 13:04:06.446370367 +0100 @@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER @@ -2113,10 +2099,10 @@ diff -Nur openssh-7.3p1.orig/ssh.1 openssh-7.3p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c ---- openssh-7.3p1.orig/ssh.c 2016-12-13 11:17:13.466232242 +0100 -+++ openssh-7.3p1/ssh.c 2016-12-13 15:57:03.246159810 +0100 -@@ -475,6 +475,32 @@ +diff -Nur openssh-7.4p1.orig/ssh.c openssh-7.4p1/ssh.c +--- openssh-7.4p1.orig/ssh.c 2017-01-24 13:03:15.317941403 +0100 ++++ openssh-7.4p1/ssh.c 2017-01-24 13:04:06.447370356 +0100 +@@ -472,6 +472,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2163,9 +2149,9 @@ diff -Nur openssh-7.3p1.orig/ssh.c openssh-7.3p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.3p1.orig/ssh_config openssh-7.3p1/ssh_config ---- openssh-7.3p1.orig/ssh_config 2016-12-13 11:17:13.362233414 +0100 -+++ openssh-7.3p1/ssh_config 2016-12-13 15:57:03.246159810 +0100 +diff -Nur openssh-7.4p1.orig/ssh_config openssh-7.4p1/ssh_config +--- openssh-7.4p1.orig/ssh_config 2017-01-24 13:03:15.219942497 +0100 ++++ openssh-7.4p1/ssh_config 2017-01-24 13:04:06.447370356 +0100 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2181,9 +2167,9 @@ diff -Nur openssh-7.3p1.orig/ssh_config openssh-7.3p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.3p1.orig/ssh_config.5 openssh-7.3p1/ssh_config.5 ---- openssh-7.3p1.orig/ssh_config.5 2016-12-13 11:17:13.410232873 +0100 -+++ openssh-7.3p1/ssh_config.5 2016-12-15 09:40:44.531257428 +0100 +diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1.orig/ssh_config.5 2017-01-24 13:03:15.267941961 +0100 ++++ openssh-7.4p1/ssh_config.5 2017-01-24 13:39:41.675460732 +0100 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2197,31 +2183,31 @@ diff -Nur openssh-7.3p1.orig/ssh_config.5 openssh-7.3p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -825,12 +831,12 @@ +@@ -748,7 +754,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is --.Dq no . -+.Dq yes . +-.Cm no . ++.Cm yes . + .It Cm GSSAPIClientIdentity + If set, specifies the GSSAPI client identity that ssh should use when + connecting to the server. The default is unset, which means that the default +@@ -756,12 +762,12 @@ + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is +-.Cm no . ++.Cm yes . .It Cm GSSAPIKeyExchange Specifies whether key exchange based on GSSAPI may be used. When using GSSAPI key exchange the server need not have a host key. The default is -.Dq no . -+.Dq yes . - .It Cm GSSAPIClientIdentity - If set, specifies the GSSAPI client identity that ssh should use when - connecting to the server. The default is unset, which means that the default -@@ -843,7 +849,7 @@ - .It Cm GSSAPIDelegateCredentials - Forward (delegate) credentials to the server. - The default is --.Dq no . +.Dq yes . .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -870,7 +876,7 @@ +@@ -793,7 +799,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2230,10 +2216,10 @@ diff -Nur openssh-7.3p1.orig/ssh_config.5 openssh-7.3p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c ---- openssh-7.3p1.orig/sshconnect2.c 2016-12-13 11:17:13.465232253 +0100 -+++ openssh-7.3p1/sshconnect2.c 2016-12-13 23:17:35.567954069 +0100 -@@ -723,6 +723,11 @@ +diff -Nur openssh-7.4p1.orig/sshconnect2.c openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1.orig/sshconnect2.c 2017-01-24 13:03:15.316941414 +0100 ++++ openssh-7.4p1/sshconnect2.c 2017-01-24 13:04:06.448370345 +0100 +@@ -725,6 +725,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2245,7 +2231,7 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -960,6 +965,19 @@ +@@ -962,6 +967,19 @@ return 0; } @@ -2265,7 +2251,7 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -977,8 +995,16 @@ +@@ -979,8 +997,16 @@ return (0); } @@ -2282,7 +2268,7 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -989,7 +1015,15 @@ +@@ -991,7 +1017,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2298,10 +2284,10 @@ diff -Nur openssh-7.3p1.orig/sshconnect2.c openssh-7.3p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.3p1.orig/sshd.8 openssh-7.3p1/sshd.8 ---- openssh-7.3p1.orig/sshd.8 2016-12-13 11:17:13.395233042 +0100 -+++ openssh-7.3p1/sshd.8 2016-12-13 15:57:03.248159788 +0100 -@@ -795,6 +795,44 @@ +diff -Nur openssh-7.4p1.orig/sshd.8 openssh-7.4p1/sshd.8 +--- openssh-7.4p1.orig/sshd.8 2017-01-24 13:03:15.248942173 +0100 ++++ openssh-7.4p1/sshd.8 2017-01-24 13:04:06.449370334 +0100 +@@ -740,6 +740,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2346,10 +2332,10 @@ diff -Nur openssh-7.3p1.orig/sshd.8 openssh-7.3p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c ---- openssh-7.3p1.orig/sshd.c 2016-12-13 11:17:13.466232242 +0100 -+++ openssh-7.3p1/sshd.c 2016-12-13 15:57:03.248159788 +0100 -@@ -128,6 +128,7 @@ +diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c +--- openssh-7.4p1.orig/sshd.c 2017-01-24 13:03:15.318941391 +0100 ++++ openssh-7.4p1/sshd.c 2017-01-24 13:04:06.450370322 +0100 +@@ -126,6 +126,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -2357,7 +2343,7 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c #ifdef LIBWRAP #include -@@ -1892,6 +1893,13 @@ +@@ -1708,6 +1709,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2371,7 +2357,7 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2455,7 +2463,7 @@ +@@ -2196,7 +2204,7 @@ #endif #ifdef GSSAPI @@ -2380,10 +2366,10 @@ diff -Nur openssh-7.3p1.orig/sshd.c openssh-7.3p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config ---- openssh-7.3p1.orig/sshd_config 2016-12-13 11:17:13.402232963 +0100 -+++ openssh-7.3p1/sshd_config 2016-12-15 10:55:00.889596292 +0100 -@@ -89,10 +89,11 @@ +diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config +--- openssh-7.4p1.orig/sshd_config 2017-01-24 13:03:15.259942050 +0100 ++++ openssh-7.4p1/sshd_config 2017-01-24 13:04:06.450370322 +0100 +@@ -76,10 +76,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2397,7 +2383,7 @@ diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -108,6 +109,10 @@ +@@ -95,6 +96,10 @@ # problems. UsePAM yes @@ -2408,7 +2394,7 @@ diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -146,6 +151,10 @@ +@@ -131,6 +136,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2419,13 +2405,13 @@ diff -Nur openssh-7.3p1.orig/sshd_config openssh-7.3p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 ---- openssh-7.3p1.orig/sshd_config.5 2016-12-13 11:17:13.432232625 +0100 -+++ openssh-7.3p1/sshd_config.5 2016-12-15 09:52:24.308294018 +0100 -@@ -579,6 +579,15 @@ - See PATTERNS in - .Xr ssh_config 5 - for more information on patterns. +diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1.orig/sshd_config.5 2017-01-24 13:03:15.280941816 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-01-24 13:11:48.226212823 +0100 +@@ -570,6 +570,15 @@ + TCP and StreamLocal. + This option overrides all other forwarding-related options and may + simplify restricted configurations. +.It Cm DisableUsageStats +This keyword can be followed by one of the keywords "true", "enabled", "yes", +"on" or "1" to disable reporting of usage metrics. Or it can be set to "false", @@ -2438,27 +2424,24 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 .It Cm ExposeAuthenticationMethods When using SSH2, this option controls the exposure of the list of successful authentication methods to PAM during the authentication -@@ -646,17 +655,36 @@ +@@ -634,15 +643,34 @@ + to allow the client to select the address to which the forwarding is bound. + The default is + .Cm no . ++.It Cm GSIAllowLimitedProxy ++Specifies whether to accept limited proxy credentials for authentication. ++The default is ++.Dq no . .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is --.Dq no . -+.Dq yes . -+.It Cm GSSAPIDelegateCredentials -+Specifies whether delegated credentials are stored in the user's environment. -+The default is -+.Dq yes . - .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. - The default is --.Dq no . -+.Dq yes . +-.Cm no . ++.Cm yes . .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is - .Dq yes . + .Cm yes . +.It Cm GSSAPICredentialsPath +If specified, the delegated GSSAPI credential is stored in the +given path, overwriting any existing credentials. @@ -2470,14 +2453,23 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 +doesn't remove the credentials in use by another session of +the same user. +Currently only implemented for the GSI mechanism. -+.It Cm GSIAllowLimitedProxy -+Specifies whether to accept limited proxy credentials for authentication. ++.It Cm GSSAPIDelegateCredentials ++Specifies whether delegated credentials are stored in the user's environment. +The default is -+.Dq no . ++.Dq yes . .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -1596,6 +1624,103 @@ +@@ -653,7 +681,7 @@ + Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange + doesn't rely on ssh keys to verify host identity. + The default is +-.Dq no . ++.Dq yes . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -1493,6 +1521,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2581,10 +2573,10 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1656,6 +1781,12 @@ +@@ -1534,6 +1659,12 @@ as a non-root user. The default is - .Dq no . + .Cm no . +.It Cm PermitPAMUserChange +If set to +.Dq yes @@ -2594,9 +2586,9 @@ diff -Nur openssh-7.3p1.orig/sshd_config.5 openssh-7.3p1/sshd_config.5 .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -diff -Nur openssh-7.3p1.orig/ssh-globus-usage.c openssh-7.3p1/ssh-globus-usage.c ---- openssh-7.3p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/ssh-globus-usage.c 2016-12-13 15:57:03.250159766 +0100 +diff -Nur openssh-7.4p1.orig/ssh-globus-usage.c openssh-7.4p1/ssh-globus-usage.c +--- openssh-7.4p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/ssh-globus-usage.c 2017-01-24 13:04:06.452370300 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2994,9 +2986,9 @@ diff -Nur openssh-7.3p1.orig/ssh-globus-usage.c openssh-7.3p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.3p1.orig/ssh-globus-usage.h openssh-7.3p1/ssh-globus-usage.h ---- openssh-7.3p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.3p1/ssh-globus-usage.h 2016-12-13 15:57:03.250159766 +0100 +diff -Nur openssh-7.4p1.orig/ssh-globus-usage.h openssh-7.4p1/ssh-globus-usage.h +--- openssh-7.4p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/ssh-globus-usage.h 2017-01-24 13:04:06.452370300 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3046,9 +3038,9 @@ diff -Nur openssh-7.3p1.orig/ssh-globus-usage.h openssh-7.3p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.3p1.orig/ssh-gss.h openssh-7.3p1/ssh-gss.h ---- openssh-7.3p1.orig/ssh-gss.h 2016-12-13 11:17:13.423232726 +0100 -+++ openssh-7.3p1/ssh-gss.h 2016-12-13 15:57:03.250159766 +0100 +diff -Nur openssh-7.4p1.orig/ssh-gss.h openssh-7.4p1/ssh-gss.h +--- openssh-7.4p1.orig/ssh-gss.h 2017-01-24 13:03:15.274941883 +0100 ++++ openssh-7.4p1/ssh-gss.h 2017-01-24 13:04:06.452370300 +0100 @@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -3093,11 +3085,11 @@ diff -Nur openssh-7.3p1.orig/ssh-gss.h openssh-7.3p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.3p1.orig/version.h openssh-7.3p1/version.h ---- openssh-7.3p1.orig/version.h 2016-07-28 00:54:27.000000000 +0200 -+++ openssh-7.3p1/version.h 2016-12-13 17:08:57.017089717 +0100 +diff -Nur openssh-7.4p1.orig/version.h openssh-7.4p1/version.h +--- openssh-7.4p1.orig/version.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/version.h 2017-01-24 13:24:26.115731721 +0100 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.77 2016/07/24 11:45:36 djm Exp $ */ + /* $OpenBSD: version.h,v 1.78 2016/12/19 04:55:51 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3113,7 +3105,7 @@ diff -Nur openssh-7.3p1.orig/version.h openssh-7.3p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20161122" + - #define SSH_VERSION "OpenSSH_7.3" + #define SSH_VERSION "OpenSSH_7.4" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-7.4p1-pkcs11-whitelist.patch b/openssh-7.4p1-pkcs11-whitelist.patch new file mode 100644 index 0000000..36b4232 --- /dev/null +++ b/openssh-7.4p1-pkcs11-whitelist.patch @@ -0,0 +1,24 @@ +diff -up openssh-7.4p1/ssh-agent.1.pkcs11-whitelist openssh-7.4p1/ssh-agent.1 +--- openssh-7.4p1/ssh-agent.1.pkcs11-whitelist 2017-01-03 10:41:01.916331710 +0100 ++++ openssh-7.4p1/ssh-agent.1 2017-01-03 10:40:06.549366029 +0100 +@@ -129,7 +129,7 @@ that may be added using the + option to + .Xr ssh-add 1 . + The default is to allow loading PKCS#11 libraries from +-.Dq /usr/lib/*,/usr/local/lib/* . ++.Dq /usr/lib*/*,/usr/local/lib*/* . + PKCS#11 libraries that do not match the whitelist will be refused. + See PATTERNS in + .Xr ssh_config 5 +diff -up openssh-7.4p1/ssh-agent.c.pkcs11-whitelist openssh-7.4p1/ssh-agent.c +--- openssh-7.4p1/ssh-agent.c.pkcs11-whitelist 2017-01-03 10:41:09.324327118 +0100 ++++ openssh-7.4p1/ssh-agent.c 2017-01-03 10:40:21.212356939 +0100 +@@ -89,7 +89,7 @@ + #endif + + #ifndef DEFAULT_PKCS11_WHITELIST +-# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" ++# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" + #endif + + typedef enum { diff --git a/sources b/sources index 11a8bcb..01c94ef 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -dfadd9f035d38ce5d58a3bf130b86d08 openssh-7.3p1.tar.gz +SHA512 (openssh-7.4p1.tar.gz) = 4f3256f461f01366c5d5e0e45285eec65016e2643b3284b407f48f53d81087bf2c1caf7d5f7530d307a15c91c64de91446e1cba948e8fc68f82098290fe3b292 From a3ffcc1efad11443c79939f2309594e0b33ff926 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 7 Feb 2017 11:27:13 +0100 Subject: [PATCH 037/146] Based on openssh-7.4p1-2.fc25 --- gsi-openssh.spec | 7 +++++-- openssh-6.6p1-redhat.patch | 2 +- openssh-7.3p1-openssl-1.1.0.patch | 24 +++++++----------------- openssh-7.4p1-daemon.patch | 30 +++++++++++++++++++++--------- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 022714e..b9116eb 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.4p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -545,8 +545,11 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Feb 07 2017 Mattias Ellert - 7.4p1-2 +- Based on openssh-7.4p1-2.fc25 + * Tue Jan 24 2017 Mattias Ellert - 7.4p1-1 -- Based on openssh-7.4p1-1 +- Based on openssh-7.4p1-1.fc25 * Tue Dec 13 2016 Mattias Ellert - 7.3p1-5 - Adding mechanism OID negotiation with the introduction of micv2 OID diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index b23f47e..ba2f2ae 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -14,7 +14,7 @@ diff -up openssh-7.4p1/ssh_config_redhat.redhat openssh-7.4p1/ssh_config_redhat +++ openssh-7.4p1/ssh_config_redhat 2016-12-23 13:32:00.045220402 +0100 @@ -0,0 +1,20 @@ +# Follow system-wide Crypto Poliicy, if defined: -+Include /etc/crypto-policies/back-ends/openssh.txt ++Include /etc/crypto-policies/back-ends/openssh.config + +# Uncomment this if you want to use .local domain +# Host *.local diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 452f99d..1117205 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -3088,7 +3088,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2819,24 +2995,81 @@ sshkey_private_deserialize(struct sshbuf +@@ -2819,24 +2995,71 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3151,38 +3151,28 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c - (r = rsa_generate_additional_parameters(k->rsa)) != 0) - goto out; + case KEY_RSA_CERT: { -+ BIGNUM *n, *e, *d, *iqmp, *p, *q; ++ BIGNUM *d, *iqmp, *p, *q; + -+ /* N can't be zero because it breaks blinding (seed). Count it now */ -+ /* E is zero because it is not in the protocol, but needed for RSA structure */ -+ n = BN_new(); -+ e = BN_new(); ++ /* N and E are already set so make sure we will not overwrite them */ + d = BN_new(); + iqmp = BN_new(); + p = BN_new(); + q = BN_new(); -+ BN_CTX *ctx = BN_CTX_new(); + -+ if (n == NULL || e == NULL || d == NULL || -+ iqmp == NULL || p == NULL || q == NULL || -+ ctx == NULL || ++ if (d == NULL || iqmp == NULL || p == NULL || ++ q == NULL || + (r = sshkey_froms(buf, &k)) != 0 || + (r = sshkey_add_private(k)) != 0 || + (r = sshbuf_get_bignum2(buf, d)) != 0 || + (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || + (r = sshbuf_get_bignum2(buf, p)) != 0 || + (r = sshbuf_get_bignum2(buf, q)) != 0 || -+ (r = ((BN_mul(n, p, q, ctx) == 0) /* N = P * Q */ -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || -+ (r = ((RSA_set0_key(k->rsa, n, e, d) == 0) ++ (r = ((RSA_set0_key(k->rsa, NULL, NULL, d) == 0) + ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || + (r = ((RSA_set0_factors(k->rsa, p, q) == 0) + ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || -+ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) { -+ BN_CTX_free(ctx); ++ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) + goto out; -+ } -+ BN_CTX_free(ctx); + } break; #endif /* WITH_OPENSSL */ diff --git a/openssh-7.4p1-daemon.patch b/openssh-7.4p1-daemon.patch index 3515398..7f35d36 100644 --- a/openssh-7.4p1-daemon.patch +++ b/openssh-7.4p1-daemon.patch @@ -1,12 +1,24 @@ +diff -up openssh-7.4p1/misc.c.daemon openssh-7.4p1/misc.c +--- openssh-7.4p1/misc.c.daemon 2017-02-03 13:08:14.751282516 +0100 ++++ openssh-7.4p1/misc.c 2017-02-03 13:08:14.778282474 +0100 +@@ -1273,6 +1273,9 @@ daemonized(void) + return 0; /* parent is not init */ + if (getsid(0) != getpid()) + return 0; /* not session leader */ ++ if (getenv("_SSH_DAEMONIZED") == NULL) ++ return 0; /* already reexeced */ ++ + debug3("already daemonized"); + return 1; + } diff -up openssh-7.4p1/sshd.c.daemon openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.daemon 2017-01-02 15:32:56.618447579 +0100 -+++ openssh-7.4p1/sshd.c 2017-01-02 15:33:07.606442751 +0100 -@@ -1943,7 +1943,7 @@ main(int ac, char **av) - * terminal, and fork. The original process exits. - */ - already_daemon = daemonized(); -- if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) { -+ if (!(debug_flag || inetd_flag || no_daemon_flag /*|| already_daemon*/)) { - +--- openssh-7.4p1/sshd.c.daemon 2017-02-03 13:08:14.755282510 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-03 13:09:29.765164356 +0100 +@@ -1866,6 +1866,7 @@ main(int ac, char **av) if (daemon(0, 0) < 0) fatal("daemon() failed: %.200s", strerror(errno)); + ++ setenv("_SSH_DAEMONIZED", "1", 1); + disconnect_controlling_tty(); + } + /* Reinitialize the log (because of the fork above). */ From 4d141e4d082ca8c51194d90925939c134a5542b8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 23 Feb 2017 13:17:38 +0100 Subject: [PATCH 038/146] Based on openssh-7.4p1-3.fc25 Remove MON_ONCE from the monitoring flags for MONITOR_REQ_GSSCHECKMIC (rhbz #1423000) --- gsi-openssh.spec | 24 +++++--- gsisshd.service | 5 +- openssh-6.6p1-keycat.patch | 4 +- openssh-6.6p1-redhat.patch | 2 +- openssh-6.7p1-ldap.patch | 4 +- openssh-7.4p1-daemon.patch | 24 -------- openssh-7.4p1-gsissh.patch | 13 ++-- openssh-7.4p1-include-errors.patch | 40 ++++++++++++ openssh-7.4p1-systemd.patch | 99 ++++++++++++++++++++++++++++++ 9 files changed, 169 insertions(+), 46 deletions(-) delete mode 100644 openssh-7.4p1-daemon.patch create mode 100644 openssh-7.4p1-include-errors.patch create mode 100644 openssh-7.4p1-systemd.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index b9116eb..1e1db13 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.4p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -136,7 +136,7 @@ Patch906: openssh-6.4p1-fromto-remote.patch Patch916: openssh-6.6.1p1-selinux-contexts.patch # use different values for DH for Cisco servers (#1026430) Patch917: openssh-6.6.1p1-cisco-dh-keys.patch -# log via monitor in chroots without /dev/log +# 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 @@ -167,10 +167,12 @@ Patch940: openssh-7.2p2-expose-pam.patch Patch942: openssh-7.2p2-chroot-capabilities.patch # Move MAX_DISPLAYS to a configuration option (#1341302) Patch944: openssh-7.3p1-x11-max-displays.patch -# Temporary workaround for upstream (#2641) -Patch945: openssh-7.4p1-daemon.patch # Whitelist /usr/lib*/ as planed upstream to prevent breakage Patch946: openssh-7.4p1-pkcs11-whitelist.patch +# Correct reporting errors from included files (#1408558) +Patch947: openssh-7.4p1-include-errors.patch +# Help systemd to track the running service +Patch948: openssh-7.4p1-systemd.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch @@ -193,6 +195,7 @@ BuildRequires: tcp_wrappers-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j BuildRequires: libcap-ng-devel +BuildRequires: systemd-devel %if %{kerberos5} BuildRequires: krb5-devel @@ -327,8 +330,9 @@ This version of OpenSSH has been modified to support GSI authentication. %patch940 -p1 -b .expose-pam %patch942 -p1 -b .chroot-cap %patch944 -p1 -b .x11max -%patch945 -p1 -b .daemon %patch946 -p1 -b .pkcs11-whitelist +%patch947 -p1 -b .include-errors +%patch948 -p1 -b .systemd %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -390,17 +394,14 @@ fi --with-ssl-engine \ --with-ipaddr-display \ --with-pie=no \ + --with-systemd \ %if %{ldap} --with-ldap \ %endif --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ -%ifnarch ppc --with-sandbox=seccomp_filter \ -%else - --with-sandbox=rlimit \ -%endif %endif %if %{kerberos5} --with-kerberos5${krb5_prefix:+=${krb5_prefix}} \ @@ -545,6 +546,11 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Feb 23 2017 Mattias Ellert - 7.4p1-3 +- Based on openssh-7.4p1-3.fc25 +- Remove MON_ONCE from the monitoring flags for MONITOR_REQ_GSSCHECKMIC + (rhbz #1423000) + * Tue Feb 07 2017 Mattias Ellert - 7.4p1-2 - Based on openssh-7.4p1-2.fc25 diff --git a/gsisshd.service b/gsisshd.service index 0ac73ab..afe165d 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -5,10 +5,9 @@ After=network.target gsisshd-keygen.target Wants=gsisshd-keygen.target [Service] -Type=forking -PIDFile=/var/run/gsisshd.pid +Type=notify EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd $OPTIONS +ExecStart=/usr/sbin/gsisshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index fd87fd5..2e8f977 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -61,8 +61,8 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in LIBOPENSSH_OBJS=\ ssh_api.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) - ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index ba2f2ae..818858a 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -13,7 +13,7 @@ diff -up openssh-7.4p1/ssh_config_redhat.redhat openssh-7.4p1/ssh_config_redhat --- openssh-7.4p1/ssh_config_redhat.redhat 2016-12-23 13:32:00.045220402 +0100 +++ openssh-7.4p1/ssh_config_redhat 2016-12-23 13:32:00.045220402 +0100 @@ -0,0 +1,20 @@ -+# Follow system-wide Crypto Poliicy, if defined: ++# Follow system-wide Crypto Policy, if defined: +Include /etc/crypto-policies/back-ends/openssh.config + +# Uncomment this if you want to use .local domain diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index 1c3cb3e..fd29ce4 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -162,8 +162,8 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o sshbuf-getput-basic.o ssherr.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ++ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o ++ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff --git a/openssh-7.4p1-daemon.patch b/openssh-7.4p1-daemon.patch deleted file mode 100644 index 7f35d36..0000000 --- a/openssh-7.4p1-daemon.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up openssh-7.4p1/misc.c.daemon openssh-7.4p1/misc.c ---- openssh-7.4p1/misc.c.daemon 2017-02-03 13:08:14.751282516 +0100 -+++ openssh-7.4p1/misc.c 2017-02-03 13:08:14.778282474 +0100 -@@ -1273,6 +1273,9 @@ daemonized(void) - return 0; /* parent is not init */ - if (getsid(0) != getpid()) - return 0; /* not session leader */ -+ if (getenv("_SSH_DAEMONIZED") == NULL) -+ return 0; /* already reexeced */ -+ - debug3("already daemonized"); - return 1; - } -diff -up openssh-7.4p1/sshd.c.daemon openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.daemon 2017-02-03 13:08:14.755282510 +0100 -+++ openssh-7.4p1/sshd.c 2017-02-03 13:09:29.765164356 +0100 -@@ -1866,6 +1866,7 @@ main(int ac, char **av) - if (daemon(0, 0) < 0) - fatal("daemon() failed: %.200s", strerror(errno)); - -+ setenv("_SSH_DAEMONIZED", "1", 1); - disconnect_controlling_tty(); - } - /* Reinitialize the log (because of the fork above). */ diff --git a/openssh-7.4p1-gsissh.patch b/openssh-7.4p1-gsissh.patch index cd2cb1a..1969c86 100644 --- a/openssh-7.4p1-gsissh.patch +++ b/openssh-7.4p1-gsissh.patch @@ -621,9 +621,9 @@ diff -Nur openssh-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac + AC_DEFINE([HAVE_GLOBUS_USAGE_SEND_ARRAY], 1, [Have Globus Usage send_array])) +fi + - # Looking for programs, paths and files - - PRIVSEP_PATH=/var/empty + # Check whether user wants systemd support + SYSTEMD_MSG="no" + AC_ARG_WITH(systemd, diff -Nur openssh-7.4p1.orig/gss-genr.c openssh-7.4p1/gss-genr.c --- openssh-7.4p1.orig/gss-genr.c 2017-01-24 13:03:15.312941458 +0100 +++ openssh-7.4p1/gss-genr.c 2017-01-24 13:04:06.437370468 +0100 @@ -1495,9 +1495,12 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -251,6 +254,9 @@ +@@ -249,8 +252,11 @@ + {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, +- {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, ++ {MONITOR_REQ_GSSCHECKMIC, 0, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, + {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, diff --git a/openssh-7.4p1-include-errors.patch b/openssh-7.4p1-include-errors.patch new file mode 100644 index 0000000..c4dfa0b --- /dev/null +++ b/openssh-7.4p1-include-errors.patch @@ -0,0 +1,40 @@ +diff --git a/readconf.c b/readconf.c +index fa3fab8..e7eb30d 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1499,7 +1499,7 @@ parse_keytypes: + oactive ? "" : " (parse only)"); + r = read_config_file_depth(gl.gl_pathv[i], + pw, host, original_host, options, +- flags | SSHCONF_CHECKPERM | ++ flags | SSHCONF_CHECKPERM | SSHCONF_IGNORE_READERR | + (oactive ? 0 : SSHCONF_NEVERMATCH), + activep, depth + 1); + /* +@@ -1707,8 +1707,13 @@ read_config_file_depth(const char *filename, struct passwd *pw, + if (depth < 0 || depth > READCONF_MAX_DEPTH) + fatal("Too many recursive configuration includes"); + +- if ((f = fopen(filename, "r")) == NULL) ++ if ((f = fopen(filename, "r")) == NULL) { ++ if (flags & SSHCONF_IGNORE_READERR) { ++ error("Can not open configuration file %s", filename); ++ return 1; ++ } + return 0; ++ } + + if (flags & SSHCONF_CHECKPERM) { + struct stat sb; +diff --git a/readconf.h b/readconf.h +index cef55f7..4f7d3b4 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -190,6 +190,7 @@ typedef struct { + #define SSHCONF_USERCONF 2 /* user provided config file not system */ + #define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ + #define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ ++#define SSHCONF_IGNORE_READERR 16 /* Treat unreadable files as errors; internal only */ + + #define SSH_UPDATE_HOSTKEYS_NO 0 + #define SSH_UPDATE_HOSTKEYS_YES 1 diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch new file mode 100644 index 0000000..455a5ec --- /dev/null +++ b/openssh-7.4p1-systemd.patch @@ -0,0 +1,99 @@ +commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31 +Author: Jakub Jelen +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 + #endif + ++#ifdef HAVE_SYSTEMD ++#include ++#endif ++ + #include "xmalloc.h" + #include "ssh.h" + #include "ssh2.h" +@@ -1833,6 +1837,11 @@ main(int ac, char **av) + /* ignore SIGPIPE */ + signal(SIGPIPE, SIG_IGN); + ++#ifdef HAVE_SYSTEMD ++ /* Signal systemd that we are ready to accept connections */ ++ sd_notify(0, "READY=1"); ++#endif ++ + /* Get a connection, either from inetd or a listening TCP socket */ + if (inetd_flag) { + server_accept_inetd(&sock_in, &sock_out); + From fba2e4ad34f73349040362ab925524eb9c7fbb42 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 4 Mar 2017 15:32:31 +0100 Subject: [PATCH 039/146] Based on openssh-7.4p1-4.fc25 --- gsi-openssh.spec | 5 ++++- gsisshd.service | 1 + openssh-6.7p1-kdf-cavs.patch | 5 +---- openssh-7.4p1-systemd.patch | 17 ++++++++--------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 1e1db13..86af350 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.4p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -546,6 +546,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat Mar 04 2017 Mattias Ellert - 7.4p1-4 +- Based on openssh-7.4p1-4.fc25 + * Thu Feb 23 2017 Mattias Ellert - 7.4p1-3 - Based on openssh-7.4p1-3.fc25 - Remove MON_ONCE from the monitoring flags for MONITOR_REQ_GSSCHECKMIC diff --git a/gsisshd.service b/gsisshd.service index afe165d..33ae6ce 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -12,6 +12,7 @@ ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s +RestartPreventExitStatus=255 [Install] WantedBy=multi-user.target diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index 2f5874a..65feb96 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in 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,383 @@ +@@ -0,0 +1,380 @@ +/* + * Copyright (C) 2015, Stephan Mueller + * @@ -317,9 +317,6 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c + hex, HEXOUTLEN, 0); + printf("Integrity key (server to client) = %s\n", hex); + -+ free(ctoskeys); -+ free(stockeys); -+ +out: + if (Kbn) + BN_free(Kbn); diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch index 455a5ec..4f9e58a 100644 --- a/openssh-7.4p1-systemd.patch +++ b/openssh-7.4p1-systemd.patch @@ -84,16 +84,15 @@ index 816611c..b8b9d13 100644 #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" -@@ -1833,6 +1837,11 @@ main(int ac, char **av) - /* ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); +@@ -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"); ++ /* Signal systemd that we are ready to accept connections */ ++ sd_notify(0, "READY=1"); +#endif + - /* Get a connection, either from inetd or a listening TCP socket */ - if (inetd_flag) { - server_accept_inetd(&sock_in, &sock_out); - + /* Accept a connection and return in a forked child */ + server_accept_loop(&sock_in, &sock_out, + &newsock, config_s); From f2493773202782c2567b13cfece3201b2c31b80a Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 25 Mar 2017 04:59:20 +0100 Subject: [PATCH 040/146] Based on openssh-7.5p1-2.fc26 --- gsi-openssh.spec | 22 +- gsisshd.service | 1 - openssh-6.2p1-vendor.patch | 8 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 2 +- openssh-6.6p1-kuserok.patch | 2 +- ...sh-6.7p1-debian-restore-tcp-wrappers.patch | 2 +- openssh-7.0p1-gssKexAlgorithms.patch | 8 +- openssh-7.2p1-audit.patch | 18 +- openssh-7.2p1-fips.patch | 16 +- openssh-7.2p1-gsskex.patch | 14 +- openssh-7.2p2-chroot-capabilities.patch | 103 ------ openssh-7.2p2-expose-pam.patch | 4 +- openssh-7.2p2-x11.patch | 2 +- openssh-7.3p1-openssl-1.1.0.patch | 26 +- openssh-7.4p1-include-errors.patch | 40 --- openssh-7.4p1-pkcs11-whitelist.patch | 24 -- ...gsissh.patch => openssh-7.5p1-gsissh.patch | 315 +++++++++--------- openssh-7.5p1-sandbox.patch | 23 ++ sources | 2 +- 19 files changed, 251 insertions(+), 381 deletions(-) delete mode 100644 openssh-7.2p2-chroot-capabilities.patch delete mode 100644 openssh-7.4p1-include-errors.patch delete mode 100644 openssh-7.4p1-pkcs11-whitelist.patch rename openssh-7.4p1-gsissh.patch => openssh-7.5p1-gsissh.patch (91%) create mode 100644 openssh-7.5p1-sandbox.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 86af350..6f1fa3f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.4p1 -%global openssh_rel 4 +%global openssh_ver 7.5p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -163,20 +163,16 @@ Patch939: openssh-7.2p2-s390-closefrom.patch # expose more information to PAM # https://github.com/openssh/openssh-portable/pull/47 Patch940: openssh-7.2p2-expose-pam.patch -# Rework SELinux context handling with chroot (#1357860) -Patch942: openssh-7.2p2-chroot-capabilities.patch # Move MAX_DISPLAYS to a configuration option (#1341302) Patch944: openssh-7.3p1-x11-max-displays.patch -# Whitelist /usr/lib*/ as planed upstream to prevent breakage -Patch946: openssh-7.4p1-pkcs11-whitelist.patch -# Correct reporting errors from included files (#1408558) -Patch947: openssh-7.4p1-include-errors.patch # Help systemd to track the running service Patch948: openssh-7.4p1-systemd.patch +# Fix typo in sandbox code; missing header for s390 +Patch949: openssh-7.5p1-sandbox.patch # This is the patch that adds GSI support # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch -Patch98: openssh-7.4p1-gsissh.patch +Patch98: openssh-7.5p1-gsissh.patch License: BSD Group: Applications/Internet @@ -194,7 +190,6 @@ BuildRequires: pam-devel BuildRequires: tcp_wrappers-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j -BuildRequires: libcap-ng-devel BuildRequires: systemd-devel %if %{kerberos5} @@ -328,11 +323,9 @@ This version of OpenSSH has been modified to support GSI authentication. %patch933 -p1 -b .fingerprint %patch939 -p1 -b .s390-dev %patch940 -p1 -b .expose-pam -%patch942 -p1 -b .chroot-cap %patch944 -p1 -b .x11max -%patch946 -p1 -b .pkcs11-whitelist -%patch947 -p1 -b .include-errors %patch948 -p1 -b .systemd +%patch949 -p1 -b .sandbox %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -546,6 +539,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Mar 24 2017 Mattias Ellert - 7.5p1-1 +- Based on openssh-7.5p1-2.fc26 + * Sat Mar 04 2017 Mattias Ellert - 7.4p1-4 - Based on openssh-7.4p1-4.fc25 diff --git a/gsisshd.service b/gsisshd.service index 33ae6ce..afe165d 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -12,7 +12,6 @@ ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s -RestartPreventExitStatus=255 [Install] WantedBy=multi-user.target diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index 2d946eb..02f4540 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -60,8 +60,8 @@ diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, @@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions - multistate_ptr = multistate_privsep; - goto parse_multistate; + intptr = &options->disable_forwarding; + goto parse_flag; + case sShowPatchLevel: + intptr = &options->show_patchlevel; @@ -138,12 +138,12 @@ diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c @@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh char remote_version[256]; /* Must be at least as big as buf. */ - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, + (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, *options.version_addendum == '\0' ? "" : " ", - options.version_addendum, newline); + options.version_addendum); @@ -1650,7 +1651,8 @@ main(int ac, char **av) exit(1); diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 069b36d..e64d320 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -82,7 +82,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_interval); @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 1af0fa4..3f10d60 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -235,8 +235,8 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_interval); @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); diff --git a/openssh-6.7p1-debian-restore-tcp-wrappers.patch b/openssh-6.7p1-debian-restore-tcp-wrappers.patch index 5fcc451..2bd6fdf 100644 --- a/openssh-6.7p1-debian-restore-tcp-wrappers.patch +++ b/openssh-6.7p1-debian-restore-tcp-wrappers.patch @@ -71,7 +71,7 @@ diff -up openssh-7.4p1/configure.ac.tcp_wrappers openssh-7.4p1/configure.ac +echo " TCP Wrappers support: $TCPW_MSG" echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" - echo " Solaris process contract support: $SPC_MSG" + echo " libldns support: $LDNS_MSG" diff -up openssh-7.4p1/sshd.8.tcp_wrappers openssh-7.4p1/sshd.8 --- openssh-7.4p1/sshd.8.tcp_wrappers 2016-12-23 15:36:38.759411194 +0100 +++ openssh-7.4p1/sshd.8 2016-12-23 15:36:38.778411197 +0100 diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 4e989dc..30519af 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -169,7 +169,7 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c { "gssapiserveridentity", oGssServerIdentity }, { "gssapirenewalforcesrekey", oGssRenewalRekey }, + { "gssapikexalgorithms", oGssKexAlgorithms }, - #else + # else { "gssapiauthentication", oUnsupported }, { "gssapikeyexchange", oUnsupported }, @@ -207,6 +209,7 @@ static struct { @@ -178,8 +178,8 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c { "gssapirenewalforcesrekey", oUnsupported }, + { "gssapikexalgorithms", oUnsupported }, #endif - { "fallbacktorsh", oDeprecated }, - { "usersh", oDeprecated }, + #ifdef ENABLE_PKCS11 + { "smartcarddevice", oPKCS11Provider }, @@ -929,6 +932,18 @@ parse_time: intptr = &options->gss_renewal_rekey; goto parse_flag; @@ -249,7 +249,7 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -288,6 +290,10 @@ fill_default_server_options(ServerOption - options->gss_strict_acceptor = 0; + options->gss_strict_acceptor = 1; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; +#ifdef GSSAPI diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index c8a4df3..755b93c 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -776,7 +776,7 @@ diff -up openssh-7.4p1/auth2.c.audit openssh-7.4p1/auth2.c +++ openssh-7.4p1/auth2.c 2016-12-23 18:54:54.434080419 +0100 @@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 } else { - logit("input_userauth_request: invalid user %s", user); + /* Invalid user, fake password information */ authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(SSH_INVALID_USER)); @@ -960,9 +960,9 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c +#endif return SSH_ERR_NO_CIPHER_ALG_MATCH; + } - if ((enc->cipher = cipher_by_name(name)) == NULL) + if ((enc->cipher = cipher_by_name(name)) == NULL) { + free(name); return SSH_ERR_INTERNAL_ERROR; - enc->name = name; @@ -702,8 +707,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -974,9 +974,9 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c +#endif return SSH_ERR_NO_MAC_ALG_MATCH; + } - if (mac_setup(mac, name) < 0) + if (mac_setup(mac, name) < 0) { + free(name); return SSH_ERR_INTERNAL_ERROR; - /* truncate the key */ @@ -720,8 +729,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -1739,16 +1739,16 @@ diff -up openssh-7.4p1/sandbox-seccomp-filter.c.audit openssh-7.4p1/sandbox-secc +++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 18:54:54.438080420 +0100 @@ -159,6 +159,12 @@ static const struct sock_filter preauth_ #ifdef __NR_gettimeofday - SC_ALLOW(gettimeofday), + SC_ALLOW(__NR_gettimeofday), #endif +#ifdef SSH_AUDIT_EVENTS -+ SC_ALLOW(getuid), ++ SC_ALLOW(__NR_getuid), +#ifdef __NR_getuid32 /* not defined on x86_64 */ -+ SC_ALLOW(getuid32), ++ SC_ALLOW(__NR_getuid32), +#endif +#endif #ifdef __NR_madvise - SC_ALLOW(madvise), + SC_ALLOW(__NR_madvise), #endif diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c --- openssh-7.4p1/session.c.audit 2016-12-23 18:54:54.430080418 +0100 diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index 37dcc91..cf03bd4 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -115,11 +115,14 @@ diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c #endif #include "ssh2.h" -@@ -125,6 +126,23 @@ static const struct kexalg kexalgs[] = { +@@ -125,6 +126,26 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; +static const struct kexalg kexalgs_fips[] = { ++ { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, +#ifdef HAVE_EVP_SHA256 + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif @@ -306,13 +309,14 @@ diff -up openssh-7.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h --- openssh-7.4p1/myproposal.h.fips 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/myproposal.h 2016-12-23 16:37:49.300741586 +0100 -@@ -138,6 +138,26 @@ +@@ -138,6 +138,27 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC +#define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ -+ KEX_SHA2_METHODS ++ KEX_SHA2_METHODS \ ++ KEX_SHA2_GROUP14 +#define KEX_FIPS_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-cbc,3des-cbc," \ @@ -357,13 +361,13 @@ diff -up openssh-7.4p1/sandbox-seccomp-filter.c.fips openssh-7.4p1/sandbox-secco +++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 16:37:49.300741586 +0100 @@ -118,6 +118,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open - SC_DENY(open, EACCES), + SC_DENY(__NR_open, EACCES), #endif +#ifdef __NR_socket -+ SC_DENY(socket, EACCES), ++ SC_DENY(__NR_socket, EACCES), +#endif #ifdef __NR_openat - SC_DENY(openat, EACCES), + SC_DENY(__NR_openat, EACCES), #endif diff -up openssh-7.4p1/servconf.c.fips openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.fips 2016-12-23 16:37:49.285741579 +0100 diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 0ab2e04..0b7c186 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1959,7 +1959,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, @@ -205,10 +207,19 @@ static struct { - { "afstokenpassing", oUnsupported }, + /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, + { "gssapikeyexchange", oGssKeyEx }, @@ -1968,7 +1968,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c + { "gssapiclientidentity", oGssClientIdentity }, + { "gssapiserveridentity", oGssServerIdentity }, + { "gssapirenewalforcesrekey", oGssRenewalRekey }, - #else + # else { "gssapiauthentication", oUnsupported }, + { "gssapikeyexchange", oUnsupported }, { "gssapidelegatecredentials", oUnsupported }, @@ -1976,8 +1976,8 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c + { "gssapiclientidentity", oUnsupported }, + { "gssapirenewalforcesrekey", oUnsupported }, #endif - { "fallbacktorsh", oDeprecated }, - { "usersh", oDeprecated }, + #ifdef ENABLE_PKCS11 + { "smartcarddevice", oPKCS11Provider }, @@ -961,10 +972,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2136,7 +2136,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->gss_strict_acceptor == -1) - options->gss_strict_acceptor = 0; + options->gss_strict_acceptor = 1; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; if (options->password_authentication == -1) @@ -2325,8 +2325,8 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c +#endif + if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits((u_int32_t)options.rekey_limit, - (time_t)options.rekey_interval); + packet_set_rekey_limits(options.rekey_limit, + options.rekey_interval); @@ -212,11 +248,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif diff --git a/openssh-7.2p2-chroot-capabilities.patch b/openssh-7.2p2-chroot-capabilities.patch deleted file mode 100644 index ea71cb9..0000000 --- a/openssh-7.2p2-chroot-capabilities.patch +++ /dev/null @@ -1,103 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index aeef42a..d01e67e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -4998,6 +4998,37 @@ if test -n "$conf_lastlog_location"; then - [Define if you want to specify the path to your lastlog file]) - fi - -+AC_ARG_WITH(libcap-ng, -+ [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],, -+ with_libcap_ng=auto) -+ -+dnl libcap-ng detection -+if test x$with_libcap_ng = xno ; then -+ have_libcap_ng=no; -+else -+ # Start by checking for header file -+ AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no) -+ -+ # See if we have libcap-ng library -+ AC_CHECK_LIB(cap-ng, capng_clear, CAPNG_LDADD=-lcap-ng,) -+ -+ # Check results are usable -+ if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then -+ AC_MSG_ERROR(libcap-ng support was requested and the library was not found) -+ fi -+ if test x$CAPNG_LDADD != x -a $capng_headers = no ; then -+ AC_MSG_ERROR(libcap-ng libraries found but headers are missing) -+ fi -+fi -+AC_MSG_CHECKING(whether to use libcap-ng) -+if test x$CAPNG_LDADD != x ; then -+ AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support]) -+ SSHDLIBS="$SSHDLIBS -lcap-ng" -+ AC_MSG_RESULT(yes) -+else -+ AC_MSG_RESULT(no) -+fi -+ - dnl utmp detection - AC_MSG_CHECKING([if your system defines UTMP_FILE]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -diff --git a/session.c b/session.c -index 6cfcba4..80d2806 100644 ---- a/session.c -+++ b/session.c -@@ -96,6 +96,10 @@ - #include "monitor_wrap.h" - #include "sftp.h" - -+#ifdef HAVE_LIBCAP_NG -+#include -+#endif -+ - #if defined(KRB5) && defined(USE_AFS) - #include - #endif -@@ -1586,6 +1590,7 @@ void - do_setusercontext(struct passwd *pw) - { - char *chroot_path, *tmp; -+ int dropped_suid = -1; - - platform_setusercontext(pw); - -@@ -1619,10 +1624,25 @@ do_setusercontext(struct passwd *pw) - pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); -+#ifdef HAVE_LIBCAP_NG -+ /* drop suid soon, retain SYS_CHROOT capability */ -+ capng_clear(CAPNG_SELECT_BOTH); -+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SYS_CHROOT); -+ if (pw->pw_uid != 0 && -+ (dropped_suid = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_INIT_SUPP_GRP)) != 0) -+ logit("capng_change_id() = %d (failure): Try to drop UID later", dropped_suid); -+#endif - #ifdef WITH_SELINUX - sshd_selinux_copy_context(); - #endif - safely_chroot(chroot_path, pw->pw_uid); -+#ifdef HAVE_LIBCAP_NG -+ /* Drop chroot capability. Already used */ -+ if (dropped_suid == 0) { -+ capng_clear(CAPNG_SELECT_BOTH); -+ capng_apply(CAPNG_SELECT_BOTH); -+ } -+#endif - free(tmp); - free(chroot_path); - /* Make sure we don't attempt to chroot again */ -@@ -1654,8 +1673,9 @@ do_setusercontext(struct passwd *pw) - if (!in_chroot && set_id(pw->pw_name) != 0) - fatal("set_id(%s) Failed", pw->pw_name); - # endif /* USE_LIBIAF */ -- /* Permanently switch to the desired uid. */ -- permanently_set_uid(pw); -+ /* Permanently switch to the desired uid if not yet done. */ -+ if (dropped_suid != 0) -+ permanently_set_uid(pw); - #endif - - #ifdef WITH_SELINUX diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch index c593f68..91428c3 100644 --- a/openssh-7.2p2-expose-pam.patch +++ b/openssh-7.2p2-expose-pam.patch @@ -2,8 +2,8 @@ diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c --- openssh-7.4p1/auth2.c.expose-pam 2016-12-23 15:40:26.768447868 +0100 +++ openssh-7.4p1/auth2.c 2016-12-23 15:40:26.818447876 +0100 @@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int - const char *submethod) { + struct ssh *ssh = active_state; /* XXX */ char *methods; + char *prev_auth_details; int partial = 0; @@ -217,7 +217,7 @@ diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c --- openssh-7.4p1/monitor.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 +++ openssh-7.4p1/monitor.c 2016-12-23 15:41:16.473455863 +0100 @@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx - { + struct ssh *ssh = active_state; /* XXX */ struct mon_table *ent; int authenticated = 0, partial = 0; + char *prev_auth_details; diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index 09e56e9..48ce840 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -50,4 +50,4 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c + return -1; } - int + #ifdef __APPLE__ diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 1117205..08354bd 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -2122,8 +2122,8 @@ diff -up openssh-7.4p1/sshconnect1.c.openssl openssh-7.4p1/sshconnect1.c int bits, rbits; int ssh_cipher_default = SSH_CIPHER_3DES; @@ -522,10 +530,14 @@ ssh_kex(char *host, struct sockaddr *hos - /* Get the public key. */ - server_key = key_new(KEY_RSA1); + if ((server_key = key_new(KEY_RSA1)) == NULL) + fatal("%s: key_new(KEY_RSA1) failed", __func__); bits = packet_get_int(); - packet_get_bignum(server_key->rsa->e); - packet_get_bignum(server_key->rsa->n); @@ -2140,8 +2140,8 @@ diff -up openssh-7.4p1/sshconnect1.c.openssl openssh-7.4p1/sshconnect1.c logit("Warning: Server lies about size of server public key: " "actual size is %d bits vs. announced %d.", rbits, bits); @@ -534,10 +546,14 @@ ssh_kex(char *host, struct sockaddr *hos - /* Get the host key. */ - host_key = key_new(KEY_RSA1); + if ((host_key = key_new(KEY_RSA1)) == NULL) + fatal("%s: key_new(KEY_RSA1) failed", __func__); bits = packet_get_int(); - packet_get_bignum(host_key->rsa->e); - packet_get_bignum(host_key->rsa->n); @@ -2633,7 +2633,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + BIGNUM *e = NULL, *n = NULL; #endif /* WITH_SSH1 */ - cp = *cpp; + if (ret == NULL) @@ -1303,12 +1319,21 @@ sshkey_read(struct sshkey *ret, char **c bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ @@ -3307,7 +3307,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c /* enable blinding */ @@ -3846,7 +4109,7 @@ sshkey_parse_private_pem_fileblob(struct - r = SSH_ERR_KEY_WRONG_PASSPHRASE; + r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if (pk->type == EVP_PKEY_RSA && @@ -3629,3 +3629,17 @@ diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; +diff --git a/sshkey.c b/sshkey.c +index ffc17ce..130217a 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -3815,7 +3815,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, + case EVP_R_BAD_DECRYPT: + r = SSH_ERR_KEY_WRONG_PASSPHRASE; + goto out; ++#ifdef EVP_R_BN_DECODE_ERROR + case EVP_R_BN_DECODE_ERROR: ++#endif + case EVP_R_DECODE_ERROR: + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + case EVP_R_PRIVATE_KEY_DECODE_ERROR: diff --git a/openssh-7.4p1-include-errors.patch b/openssh-7.4p1-include-errors.patch deleted file mode 100644 index c4dfa0b..0000000 --- a/openssh-7.4p1-include-errors.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/readconf.c b/readconf.c -index fa3fab8..e7eb30d 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -1499,7 +1499,7 @@ parse_keytypes: - oactive ? "" : " (parse only)"); - r = read_config_file_depth(gl.gl_pathv[i], - pw, host, original_host, options, -- flags | SSHCONF_CHECKPERM | -+ flags | SSHCONF_CHECKPERM | SSHCONF_IGNORE_READERR | - (oactive ? 0 : SSHCONF_NEVERMATCH), - activep, depth + 1); - /* -@@ -1707,8 +1707,13 @@ read_config_file_depth(const char *filename, struct passwd *pw, - if (depth < 0 || depth > READCONF_MAX_DEPTH) - fatal("Too many recursive configuration includes"); - -- if ((f = fopen(filename, "r")) == NULL) -+ if ((f = fopen(filename, "r")) == NULL) { -+ if (flags & SSHCONF_IGNORE_READERR) { -+ error("Can not open configuration file %s", filename); -+ return 1; -+ } - return 0; -+ } - - if (flags & SSHCONF_CHECKPERM) { - struct stat sb; -diff --git a/readconf.h b/readconf.h -index cef55f7..4f7d3b4 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -190,6 +190,7 @@ typedef struct { - #define SSHCONF_USERCONF 2 /* user provided config file not system */ - #define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ - #define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ -+#define SSHCONF_IGNORE_READERR 16 /* Treat unreadable files as errors; internal only */ - - #define SSH_UPDATE_HOSTKEYS_NO 0 - #define SSH_UPDATE_HOSTKEYS_YES 1 diff --git a/openssh-7.4p1-pkcs11-whitelist.patch b/openssh-7.4p1-pkcs11-whitelist.patch deleted file mode 100644 index 36b4232..0000000 --- a/openssh-7.4p1-pkcs11-whitelist.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up openssh-7.4p1/ssh-agent.1.pkcs11-whitelist openssh-7.4p1/ssh-agent.1 ---- openssh-7.4p1/ssh-agent.1.pkcs11-whitelist 2017-01-03 10:41:01.916331710 +0100 -+++ openssh-7.4p1/ssh-agent.1 2017-01-03 10:40:06.549366029 +0100 -@@ -129,7 +129,7 @@ that may be added using the - option to - .Xr ssh-add 1 . - The default is to allow loading PKCS#11 libraries from --.Dq /usr/lib/*,/usr/local/lib/* . -+.Dq /usr/lib*/*,/usr/local/lib*/* . - PKCS#11 libraries that do not match the whitelist will be refused. - See PATTERNS in - .Xr ssh_config 5 -diff -up openssh-7.4p1/ssh-agent.c.pkcs11-whitelist openssh-7.4p1/ssh-agent.c ---- openssh-7.4p1/ssh-agent.c.pkcs11-whitelist 2017-01-03 10:41:09.324327118 +0100 -+++ openssh-7.4p1/ssh-agent.c 2017-01-03 10:40:21.212356939 +0100 -@@ -89,7 +89,7 @@ - #endif - - #ifndef DEFAULT_PKCS11_WHITELIST --# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" -+# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" - #endif - - typedef enum { diff --git a/openssh-7.4p1-gsissh.patch b/openssh-7.5p1-gsissh.patch similarity index 91% rename from openssh-7.4p1-gsissh.patch rename to openssh-7.5p1-gsissh.patch index 1969c86..4718cb2 100644 --- a/openssh-7.4p1-gsissh.patch +++ b/openssh-7.5p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c ---- openssh-7.4p1.orig/auth2.c 2017-01-24 13:03:15.289941715 +0100 -+++ openssh-7.4p1/auth2.c 2017-01-24 13:04:06.432370524 +0100 -@@ -228,7 +228,27 @@ +diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c +--- openssh-7.5p1.orig/auth2.c 2017-03-24 21:49:39.696255466 +0100 ++++ openssh-7.5p1/auth2.c 2017-03-24 22:00:16.345972336 +0100 +@@ -229,7 +229,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -30,7 +30,7 @@ diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -239,23 +259,48 @@ +@@ -240,11 +260,32 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -65,9 +65,10 @@ diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c + authctxt->pw = PRIVSEP(getpwnamallow(user)); + if (authctxt->pw) { authctxt->valid = 1; - debug2("input_userauth_request: setting up authctxt for %s", user); - } else { - logit("input_userauth_request: invalid user %s", user); + debug2("%s: setting up authctxt for %s", + __func__, user); +@@ -252,6 +293,9 @@ + /* Invalid user, fake password information */ authctxt->pw = fakepw(); } +#ifdef GSSAPI @@ -76,14 +77,15 @@ diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); - #endif +@@ -260,6 +304,7 @@ + authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); + if (authctxt->attempt == 1) { authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -270,9 +315,10 @@ +@@ -274,9 +319,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -97,9 +99,9 @@ diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.4p1.orig/auth2-gss.c openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1.orig/auth2-gss.c 2017-01-24 13:03:15.270941928 +0100 -+++ openssh-7.4p1/auth2-gss.c 2017-01-24 13:04:06.432370524 +0100 +diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c +--- openssh-7.5p1.orig/auth2-gss.c 2017-03-24 21:49:39.672255251 +0100 ++++ openssh-7.5p1/auth2-gss.c 2017-03-24 21:50:18.891606581 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -280,9 +282,9 @@ diff -Nur openssh-7.4p1.orig/auth2-gss.c openssh-7.4p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.4p1.orig/auth.c openssh-7.4p1/auth.c ---- openssh-7.4p1.orig/auth.c 2017-01-24 13:03:15.290941704 +0100 -+++ openssh-7.4p1/auth.c 2017-01-24 13:04:06.433370512 +0100 +diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c +--- openssh-7.5p1.orig/auth.c 2017-03-24 21:49:39.697255475 +0100 ++++ openssh-7.5p1/auth.c 2017-03-24 21:50:18.892606590 +0100 @@ -77,6 +77,9 @@ #include "ssherr.h" #include "compat.h" @@ -348,9 +350,9 @@ diff -Nur openssh-7.4p1.orig/auth.c openssh-7.4p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.4p1.orig/auth-pam.c openssh-7.4p1/auth-pam.c ---- openssh-7.4p1.orig/auth-pam.c 2017-01-24 13:03:15.310941481 +0100 -+++ openssh-7.4p1/auth-pam.c 2017-01-24 13:04:06.434370501 +0100 +diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c +--- openssh-7.5p1.orig/auth-pam.c 2017-03-24 21:49:39.733255798 +0100 ++++ openssh-7.5p1/auth-pam.c 2017-03-24 21:50:18.893606599 +0100 @@ -289,6 +289,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -461,7 +463,7 @@ diff -Nur openssh-7.4p1.orig/auth-pam.c openssh-7.4p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -947,6 +1020,18 @@ +@@ -949,6 +1022,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -480,7 +482,7 @@ diff -Nur openssh-7.4p1.orig/auth-pam.c openssh-7.4p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1233,6 +1318,9 @@ +@@ -1235,6 +1320,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -490,9 +492,9 @@ diff -Nur openssh-7.4p1.orig/auth-pam.c openssh-7.4p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.4p1.orig/auth-pam.h openssh-7.4p1/auth-pam.h ---- openssh-7.4p1.orig/auth-pam.h 2017-01-24 13:03:15.169943056 +0100 -+++ openssh-7.4p1/auth-pam.h 2017-01-24 13:04:06.435370490 +0100 +diff -Nur openssh-7.5p1.orig/auth-pam.h openssh-7.5p1/auth-pam.h +--- openssh-7.5p1.orig/auth-pam.h 2017-03-24 21:49:39.507253773 +0100 ++++ openssh-7.5p1/auth-pam.h 2017-03-24 21:50:18.894606608 +0100 @@ -41,5 +41,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -500,9 +502,9 @@ diff -Nur openssh-7.4p1.orig/auth-pam.h openssh-7.4p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.4p1.orig/canohost.c openssh-7.4p1/canohost.c ---- openssh-7.4p1.orig/canohost.c 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/canohost.c 2017-01-24 13:04:06.435370490 +0100 +diff -Nur openssh-7.5p1.orig/canohost.c openssh-7.5p1/canohost.c +--- openssh-7.5p1.orig/canohost.c 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/canohost.c 2017-03-24 21:50:18.894606608 +0100 @@ -17,6 +17,7 @@ #include #include @@ -545,9 +547,9 @@ diff -Nur openssh-7.4p1.orig/canohost.c openssh-7.4p1/canohost.c + } + } +} -diff -Nur openssh-7.4p1.orig/canohost.h openssh-7.4p1/canohost.h ---- openssh-7.4p1.orig/canohost.h 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/canohost.h 2017-01-24 13:04:06.435370490 +0100 +diff -Nur openssh-7.5p1.orig/canohost.h openssh-7.5p1/canohost.h +--- openssh-7.5p1.orig/canohost.h 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/canohost.h 2017-03-24 21:50:18.895606617 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -555,10 +557,10 @@ diff -Nur openssh-7.4p1.orig/canohost.h openssh-7.4p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac ---- openssh-7.4p1.orig/configure.ac 2017-01-24 13:03:15.276941860 +0100 -+++ openssh-7.4p1/configure.ac 2017-01-24 13:04:06.436370479 +0100 -@@ -4428,6 +4428,14 @@ +diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac +--- openssh-7.5p1.orig/configure.ac 2017-03-24 21:49:39.687255386 +0100 ++++ openssh-7.5p1/configure.ac 2017-03-24 21:50:18.896606625 +0100 +@@ -4440,6 +4440,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -573,7 +575,7 @@ diff -Nur openssh-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4467,6 +4475,50 @@ +@@ -4479,6 +4487,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -624,9 +626,9 @@ diff -Nur openssh-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.4p1.orig/gss-genr.c openssh-7.4p1/gss-genr.c ---- openssh-7.4p1.orig/gss-genr.c 2017-01-24 13:03:15.312941458 +0100 -+++ openssh-7.4p1/gss-genr.c 2017-01-24 13:04:06.437370468 +0100 +diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c +--- openssh-7.5p1.orig/gss-genr.c 2017-03-24 21:49:39.736255824 +0100 ++++ openssh-7.5p1/gss-genr.c 2017-03-24 21:50:18.897606635 +0100 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -663,9 +665,9 @@ diff -Nur openssh-7.4p1.orig/gss-genr.c openssh-7.4p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.4p1.orig/gss-serv.c openssh-7.4p1/gss-serv.c ---- openssh-7.4p1.orig/gss-serv.c 2017-01-24 13:03:15.271941916 +0100 -+++ openssh-7.4p1/gss-serv.c 2017-01-24 16:22:25.069522257 +0100 +diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c +--- openssh-7.5p1.orig/gss-serv.c 2017-03-24 21:49:39.674255269 +0100 ++++ openssh-7.5p1/gss-serv.c 2017-03-24 21:50:18.897606635 +0100 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -904,9 +906,9 @@ diff -Nur openssh-7.4p1.orig/gss-serv.c openssh-7.4p1/gss-serv.c +} + #endif -diff -Nur openssh-7.4p1.orig/gss-serv-gsi.c openssh-7.4p1/gss-serv-gsi.c ---- openssh-7.4p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.4p1/gss-serv-gsi.c 2017-01-24 13:04:06.438370457 +0100 +diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +--- openssh-7.5p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.5p1/gss-serv-gsi.c 2017-03-24 21:50:18.898606643 +0100 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1237,9 +1239,9 @@ diff -Nur openssh-7.4p1.orig/gss-serv-gsi.c openssh-7.4p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.4p1.orig/gss-serv-krb5.c openssh-7.4p1/gss-serv-krb5.c ---- openssh-7.4p1.orig/gss-serv-krb5.c 2017-01-24 13:03:15.245942207 +0100 -+++ openssh-7.4p1/gss-serv-krb5.c 2017-01-24 13:04:06.438370457 +0100 +diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c +--- openssh-7.5p1.orig/gss-serv-krb5.c 2017-03-24 21:49:39.636254929 +0100 ++++ openssh-7.5p1/gss-serv-krb5.c 2017-03-24 21:50:18.898606643 +0100 @@ -378,6 +378,34 @@ return found_principal; } @@ -1293,9 +1295,9 @@ diff -Nur openssh-7.4p1.orig/gss-serv-krb5.c openssh-7.4p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.4p1.orig/kexgsss.c openssh-7.4p1/kexgsss.c ---- openssh-7.4p1.orig/kexgsss.c 2017-01-24 13:03:15.313941447 +0100 -+++ openssh-7.4p1/kexgsss.c 2017-01-24 13:04:06.438370457 +0100 +diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c +--- openssh-7.5p1.orig/kexgsss.c 2017-03-24 21:49:39.738255842 +0100 ++++ openssh-7.5p1/kexgsss.c 2017-03-24 21:50:18.898606643 +0100 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1355,9 +1357,9 @@ diff -Nur openssh-7.4p1.orig/kexgsss.c openssh-7.4p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.4p1.orig/LICENSE.globus_usage openssh-7.4p1/LICENSE.globus_usage ---- openssh-7.4p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.4p1/LICENSE.globus_usage 2017-01-24 13:04:06.439370445 +0100 +diff -Nur openssh-7.5p1.orig/LICENSE.globus_usage openssh-7.5p1/LICENSE.globus_usage +--- openssh-7.5p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.5p1/LICENSE.globus_usage 2017-03-24 21:50:18.899606652 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1377,9 +1379,9 @@ diff -Nur openssh-7.4p1.orig/LICENSE.globus_usage openssh-7.4p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.4p1.orig/Makefile.in openssh-7.4p1/Makefile.in ---- openssh-7.4p1.orig/Makefile.in 2017-01-24 13:03:15.314941436 +0100 -+++ openssh-7.4p1/Makefile.in 2017-01-24 13:12:49.715525415 +0100 +diff -Nur openssh-7.5p1.orig/Makefile.in openssh-7.5p1/Makefile.in +--- openssh-7.5p1.orig/Makefile.in 2017-03-24 21:49:39.739255851 +0100 ++++ openssh-7.5p1/Makefile.in 2017-03-24 21:50:18.899606652 +0100 @@ -114,8 +114,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1391,9 +1393,9 @@ diff -Nur openssh-7.4p1.orig/Makefile.in openssh-7.4p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o -diff -Nur openssh-7.4p1.orig/misc.c openssh-7.4p1/misc.c ---- openssh-7.4p1.orig/misc.c 2017-01-24 13:03:15.244942218 +0100 -+++ openssh-7.4p1/misc.c 2017-01-24 13:04:06.440370434 +0100 +diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c +--- openssh-7.5p1.orig/misc.c 2017-03-24 21:49:39.633254902 +0100 ++++ openssh-7.5p1/misc.c 2017-03-24 21:50:18.899606652 +0100 @@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1453,9 +1455,9 @@ diff -Nur openssh-7.4p1.orig/misc.c openssh-7.4p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.4p1.orig/misc.h openssh-7.4p1/misc.h ---- openssh-7.4p1.orig/misc.h 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/misc.h 2017-01-24 13:04:06.440370434 +0100 +diff -Nur openssh-7.5p1.orig/misc.h openssh-7.5p1/misc.h +--- openssh-7.5p1.orig/misc.h 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/misc.h 2017-03-24 21:50:18.900606661 +0100 @@ -69,6 +69,7 @@ void sock_set_v6only(int); @@ -1464,9 +1466,9 @@ diff -Nur openssh-7.4p1.orig/misc.h openssh-7.4p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c ---- openssh-7.4p1.orig/monitor.c 2017-01-24 13:03:15.314941436 +0100 -+++ openssh-7.4p1/monitor.c 2017-01-24 13:17:19.347511114 +0100 +diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c +--- openssh-7.5p1.orig/monitor.c 2017-03-24 21:49:39.739255851 +0100 ++++ openssh-7.5p1/monitor.c 2017-03-24 21:50:18.900606661 +0100 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1517,7 +1519,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -339,6 +347,8 @@ +@@ -340,6 +348,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1526,7 +1528,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -456,6 +466,8 @@ +@@ -458,6 +468,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1535,7 +1537,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c #endif if (!no_pty_flag) { -@@ -762,14 +774,17 @@ +@@ -765,14 +777,17 @@ debug3("%s", __func__); @@ -1556,7 +1558,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -1954,12 +1969,15 @@ +@@ -1959,12 +1974,15 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1573,7 +1575,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1967,7 +1985,10 @@ +@@ -1972,7 +1990,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1585,7 +1587,7 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c if (authenticated) authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -1976,6 +1997,68 @@ +@@ -1981,6 +2002,68 @@ return (authenticated); } @@ -1654,9 +1656,9 @@ diff -Nur openssh-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.4p1.orig/monitor.h openssh-7.4p1/monitor.h ---- openssh-7.4p1.orig/monitor.h 2017-01-24 13:03:15.292941682 +0100 -+++ openssh-7.4p1/monitor.h 2017-01-24 13:04:06.442370412 +0100 +diff -Nur openssh-7.5p1.orig/monitor.h openssh-7.5p1/monitor.h +--- openssh-7.5p1.orig/monitor.h 2017-03-24 21:49:39.701255511 +0100 ++++ openssh-7.5p1/monitor.h 2017-03-24 21:50:18.901606670 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1670,9 +1672,9 @@ diff -Nur openssh-7.4p1.orig/monitor.h openssh-7.4p1/monitor.h }; struct monitor { -diff -Nur openssh-7.4p1.orig/monitor_wrap.c openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1.orig/monitor_wrap.c 2017-01-24 13:03:15.306941525 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2017-01-24 13:04:06.442370412 +0100 +diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c +--- openssh-7.5p1.orig/monitor_wrap.c 2017-03-24 21:49:39.725255726 +0100 ++++ openssh-7.5p1/monitor_wrap.c 2017-03-24 21:50:18.901606670 +0100 @@ -977,12 +977,13 @@ } @@ -1772,9 +1774,9 @@ diff -Nur openssh-7.4p1.orig/monitor_wrap.c openssh-7.4p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.4p1.orig/monitor_wrap.h openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1.orig/monitor_wrap.h 2017-01-24 13:03:15.297941626 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2017-01-24 13:04:06.443370401 +0100 +diff -Nur openssh-7.5p1.orig/monitor_wrap.h openssh-7.5p1/monitor_wrap.h +--- openssh-7.5p1.orig/monitor_wrap.h 2017-03-24 21:49:39.708255574 +0100 ++++ openssh-7.5p1/monitor_wrap.h 2017-03-24 21:50:18.902606679 +0100 @@ -59,9 +59,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1790,10 +1792,10 @@ diff -Nur openssh-7.4p1.orig/monitor_wrap.h openssh-7.4p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.4p1.orig/readconf.c openssh-7.4p1/readconf.c ---- openssh-7.4p1.orig/readconf.c 2017-01-24 13:03:15.301941581 +0100 -+++ openssh-7.4p1/readconf.c 2017-01-24 13:04:06.444370390 +0100 -@@ -1973,13 +1973,13 @@ +diff -Nur openssh-7.5p1.orig/readconf.c openssh-7.5p1/readconf.c +--- openssh-7.5p1.orig/readconf.c 2017-03-24 21:49:39.716255645 +0100 ++++ openssh-7.5p1/readconf.c 2017-03-24 21:50:18.902606679 +0100 +@@ -1995,13 +1995,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1811,9 +1813,9 @@ diff -Nur openssh-7.4p1.orig/readconf.c openssh-7.4p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.4p1.orig/readconf.h openssh-7.4p1/readconf.h ---- openssh-7.4p1.orig/readconf.h 2017-01-24 13:03:15.266941972 +0100 -+++ openssh-7.4p1/readconf.h 2017-01-24 13:04:06.444370390 +0100 +diff -Nur openssh-7.5p1.orig/readconf.h openssh-7.5p1/readconf.h +--- openssh-7.5p1.orig/readconf.h 2017-03-24 21:49:39.666255198 +0100 ++++ openssh-7.5p1/readconf.h 2017-03-24 21:50:18.903606688 +0100 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1823,9 +1825,9 @@ diff -Nur openssh-7.4p1.orig/readconf.h openssh-7.4p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c ---- openssh-7.4p1.orig/servconf.c 2017-01-24 13:03:15.307941514 +0100 -+++ openssh-7.4p1/servconf.c 2017-01-24 13:25:28.276034742 +0100 +diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c +--- openssh-7.5p1.orig/servconf.c 2017-03-24 21:49:39.727255744 +0100 ++++ openssh-7.5p1/servconf.c 2017-03-24 22:02:56.629428886 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1878,8 +1880,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->gss_strict_acceptor == -1) -- options->gss_strict_acceptor = 0; -+ options->gss_strict_acceptor = 1; + options->gss_strict_acceptor = 1; + if (options->gsi_allow_limited_proxy == -1) + options->gsi_allow_limited_proxy = 0; if (options->gss_store_rekey == -1) @@ -1955,7 +1956,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1053,6 +1082,10 @@ +@@ -1062,6 +1091,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1966,7 +1967,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1259,6 +1292,10 @@ +@@ -1269,6 +1302,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1977,7 +1978,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1267,6 +1304,10 @@ +@@ -1277,6 +1314,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1988,7 +1989,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1287,6 +1328,12 @@ +@@ -1297,6 +1338,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2001,7 +2002,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1762,6 +1809,35 @@ +@@ -1768,6 +1815,35 @@ *charptr = xstrdup(arg); break; @@ -2037,7 +2038,7 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2058,6 +2134,7 @@ +@@ -2064,6 +2140,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2045,9 +2046,9 @@ diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.4p1.orig/servconf.h openssh-7.4p1/servconf.h ---- openssh-7.4p1.orig/servconf.h 2017-01-24 13:03:15.279941827 +0100 -+++ openssh-7.4p1/servconf.h 2017-01-24 13:04:06.445370378 +0100 +diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h +--- openssh-7.5p1.orig/servconf.h 2017-03-24 21:49:39.682255341 +0100 ++++ openssh-7.5p1/servconf.h 2017-03-24 21:50:18.905606706 +0100 @@ -118,9 +118,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if @@ -2080,9 +2081,9 @@ diff -Nur openssh-7.4p1.orig/servconf.h openssh-7.4p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.4p1.orig/ssh.1 openssh-7.4p1/ssh.1 ---- openssh-7.4p1.orig/ssh.1 2017-01-24 13:03:15.273941894 +0100 -+++ openssh-7.4p1/ssh.1 2017-01-24 13:04:06.446370367 +0100 +diff -Nur openssh-7.5p1.orig/ssh.1 openssh-7.5p1/ssh.1 +--- openssh-7.5p1.orig/ssh.1 2017-03-24 21:49:39.676255287 +0100 ++++ openssh-7.5p1/ssh.1 2017-03-24 21:50:18.905606706 +0100 @@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER @@ -2102,9 +2103,9 @@ diff -Nur openssh-7.4p1.orig/ssh.1 openssh-7.4p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.4p1.orig/ssh.c openssh-7.4p1/ssh.c ---- openssh-7.4p1.orig/ssh.c 2017-01-24 13:03:15.317941403 +0100 -+++ openssh-7.4p1/ssh.c 2017-01-24 13:04:06.447370356 +0100 +diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c +--- openssh-7.5p1.orig/ssh.c 2017-03-24 21:49:39.743255887 +0100 ++++ openssh-7.5p1/ssh.c 2017-03-24 21:50:18.906606715 +0100 @@ -472,6 +472,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2152,9 +2153,9 @@ diff -Nur openssh-7.4p1.orig/ssh.c openssh-7.4p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.4p1.orig/ssh_config openssh-7.4p1/ssh_config ---- openssh-7.4p1.orig/ssh_config 2017-01-24 13:03:15.219942497 +0100 -+++ openssh-7.4p1/ssh_config 2017-01-24 13:04:06.447370356 +0100 +diff -Nur openssh-7.5p1.orig/ssh_config openssh-7.5p1/ssh_config +--- openssh-7.5p1.orig/ssh_config 2017-03-24 21:49:39.588254499 +0100 ++++ openssh-7.5p1/ssh_config 2017-03-24 21:50:18.906606715 +0100 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2170,9 +2171,9 @@ diff -Nur openssh-7.4p1.orig/ssh_config openssh-7.4p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1.orig/ssh_config.5 2017-01-24 13:03:15.267941961 +0100 -+++ openssh-7.4p1/ssh_config.5 2017-01-24 13:39:41.675460732 +0100 +diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 +--- openssh-7.5p1.orig/ssh_config.5 2017-03-24 21:49:39.667255206 +0100 ++++ openssh-7.5p1/ssh_config.5 2017-03-24 21:50:18.907606724 +0100 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2186,7 +2187,7 @@ diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -748,7 +754,7 @@ +@@ -752,7 +758,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2195,7 +2196,7 @@ diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -756,12 +762,12 @@ +@@ -760,12 +766,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2210,7 +2211,7 @@ diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -793,7 +799,7 @@ +@@ -797,7 +803,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2219,9 +2220,9 @@ diff -Nur openssh-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -diff -Nur openssh-7.4p1.orig/sshconnect2.c openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1.orig/sshconnect2.c 2017-01-24 13:03:15.316941414 +0100 -+++ openssh-7.4p1/sshconnect2.c 2017-01-24 13:04:06.448370345 +0100 +diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c +--- openssh-7.5p1.orig/sshconnect2.c 2017-03-24 21:49:39.742255878 +0100 ++++ openssh-7.5p1/sshconnect2.c 2017-03-24 21:50:18.907606724 +0100 @@ -725,6 +725,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2287,9 +2288,9 @@ diff -Nur openssh-7.4p1.orig/sshconnect2.c openssh-7.4p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.4p1.orig/sshd.8 openssh-7.4p1/sshd.8 ---- openssh-7.4p1.orig/sshd.8 2017-01-24 13:03:15.248942173 +0100 -+++ openssh-7.4p1/sshd.8 2017-01-24 13:04:06.449370334 +0100 +diff -Nur openssh-7.5p1.orig/sshd.8 openssh-7.5p1/sshd.8 +--- openssh-7.5p1.orig/sshd.8 2017-03-24 21:49:39.642254982 +0100 ++++ openssh-7.5p1/sshd.8 2017-03-24 21:50:18.908606733 +0100 @@ -740,6 +740,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2335,10 +2336,10 @@ diff -Nur openssh-7.4p1.orig/sshd.8 openssh-7.4p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c ---- openssh-7.4p1.orig/sshd.c 2017-01-24 13:03:15.318941391 +0100 -+++ openssh-7.4p1/sshd.c 2017-01-24 13:04:06.450370322 +0100 -@@ -126,6 +126,7 @@ +diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c +--- openssh-7.5p1.orig/sshd.c 2017-03-24 21:49:39.744255896 +0100 ++++ openssh-7.5p1/sshd.c 2017-03-24 21:50:18.908606733 +0100 +@@ -130,6 +130,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -2346,7 +2347,7 @@ diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c #ifdef LIBWRAP #include -@@ -1708,6 +1709,13 @@ +@@ -1717,6 +1718,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2360,7 +2361,7 @@ diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2196,7 +2204,7 @@ +@@ -2219,7 +2227,7 @@ #endif #ifdef GSSAPI @@ -2369,9 +2370,9 @@ diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config ---- openssh-7.4p1.orig/sshd_config 2017-01-24 13:03:15.259942050 +0100 -+++ openssh-7.4p1/sshd_config 2017-01-24 13:04:06.450370322 +0100 +diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config +--- openssh-7.5p1.orig/sshd_config 2017-03-24 21:49:39.653255081 +0100 ++++ openssh-7.5p1/sshd_config 2017-03-24 21:50:18.909606742 +0100 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2397,7 +2398,7 @@ diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -131,6 +136,10 @@ +@@ -130,6 +135,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2408,10 +2409,10 @@ diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1.orig/sshd_config.5 2017-01-24 13:03:15.280941816 +0100 -+++ openssh-7.4p1/sshd_config.5 2017-01-24 13:11:48.226212823 +0100 -@@ -570,6 +570,15 @@ +diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 +--- openssh-7.5p1.orig/sshd_config.5 2017-03-24 21:49:39.683255350 +0100 ++++ openssh-7.5p1/sshd_config.5 2017-03-24 21:52:32.873806802 +0100 +@@ -574,6 +574,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. @@ -2427,7 +2428,7 @@ diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 .It Cm ExposeAuthenticationMethods When using SSH2, this option controls the exposure of the list of successful authentication methods to PAM during the authentication -@@ -634,15 +643,34 @@ +@@ -638,15 +647,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2463,7 +2464,7 @@ diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -653,7 +681,7 @@ +@@ -657,7 +685,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2472,7 +2473,7 @@ diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1493,6 +1521,103 @@ +@@ -1513,6 +1541,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2576,7 +2577,7 @@ diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1534,6 +1659,12 @@ +@@ -1554,6 +1679,12 @@ as a non-root user. The default is .Cm no . @@ -2586,12 +2587,12 @@ diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 +this will enable PAM authentication to change the name of the user being +authenticated. The default is +.Dq no . - .It Cm UsePrivilegeSeparation - Specifies whether - .Xr sshd 8 -diff -Nur openssh-7.4p1.orig/ssh-globus-usage.c openssh-7.4p1/ssh-globus-usage.c ---- openssh-7.4p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.4p1/ssh-globus-usage.c 2017-01-24 13:04:06.452370300 +0100 + .It Cm VersionAddendum + Optionally specifies additional text to append to the SSH protocol banner + sent by the server upon connection. +diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c +--- openssh-7.5p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.5p1/ssh-globus-usage.c 2017-03-24 21:50:18.910606751 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2989,9 +2990,9 @@ diff -Nur openssh-7.4p1.orig/ssh-globus-usage.c openssh-7.4p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.4p1.orig/ssh-globus-usage.h openssh-7.4p1/ssh-globus-usage.h ---- openssh-7.4p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.4p1/ssh-globus-usage.h 2017-01-24 13:04:06.452370300 +0100 +diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h +--- openssh-7.5p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.5p1/ssh-globus-usage.h 2017-03-24 21:50:18.910606751 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3041,9 +3042,9 @@ diff -Nur openssh-7.4p1.orig/ssh-globus-usage.h openssh-7.4p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.4p1.orig/ssh-gss.h openssh-7.4p1/ssh-gss.h ---- openssh-7.4p1.orig/ssh-gss.h 2017-01-24 13:03:15.274941883 +0100 -+++ openssh-7.4p1/ssh-gss.h 2017-01-24 13:04:06.452370300 +0100 +diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h +--- openssh-7.5p1.orig/ssh-gss.h 2017-03-24 21:49:39.677255296 +0100 ++++ openssh-7.5p1/ssh-gss.h 2017-03-24 21:50:18.910606751 +0100 @@ -95,6 +95,7 @@ gss_name_t name; struct ssh_gssapi_mech_struct *mech; @@ -3088,11 +3089,11 @@ diff -Nur openssh-7.4p1.orig/ssh-gss.h openssh-7.4p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.4p1.orig/version.h openssh-7.4p1/version.h ---- openssh-7.4p1.orig/version.h 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/version.h 2017-01-24 13:24:26.115731721 +0100 +diff -Nur openssh-7.5p1.orig/version.h openssh-7.5p1/version.h +--- openssh-7.5p1.orig/version.h 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/version.h 2017-03-24 21:54:48.743023927 +0100 @@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.78 2016/12/19 04:55:51 djm Exp $ */ + /* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */ +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3108,7 +3109,7 @@ diff -Nur openssh-7.4p1.orig/version.h openssh-7.4p1/version.h + +#define NCSA_VERSION " GSI_GSSAPI_20161122" + - #define SSH_VERSION "OpenSSH_7.4" + #define SSH_VERSION "OpenSSH_7.5" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch new file mode 100644 index 0000000..7d09632 --- /dev/null +++ b/openssh-7.5p1-sandbox.patch @@ -0,0 +1,23 @@ +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 3a1aedce72c2..a8d472a63ccb 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -50,6 +50,9 @@ + #include + + #include ++#ifdef __s390__ ++#include ++#endif + + #include + #include +@@ -235,7 +235,7 @@ static const struct sock_filter preauth_insns[] = { + * x86-64 syscall under some circumstances, e.g. + * https://bugs.debian.org/849923 + */ +- SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); ++ SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT), + #endif + + /* Default deny */ diff --git a/sources b/sources index 01c94ef..6289fb2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (openssh-7.4p1.tar.gz) = 4f3256f461f01366c5d5e0e45285eec65016e2643b3284b407f48f53d81087bf2c1caf7d5f7530d307a15c91c64de91446e1cba948e8fc68f82098290fe3b292 +SHA512 (openssh-7.5p1.tar.gz) = 58c542e8a110fb4316a68db94abb663fa1c810becd0638d45281df8aeca62c1f705090437a80e788e6c29121769b72a505feced537d3118c933fde01b5285c81 From 9246721f0bdfaf9a0eb82d38245539b7d1cfe280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Wed, 12 Jul 2017 14:43:23 +0200 Subject: [PATCH 041/146] perl dependency renamed to perl-interpreter --- gsi-openssh.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 6f1fa3f..6ee881d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -183,7 +183,7 @@ Obsoletes: %{name}-clients-fips, %{name}-server-fips %if %{ldap} BuildRequires: openldap-devel %endif -BuildRequires: autoconf, automake, perl, perl-generators, zlib-devel +BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel From f080e94f9358eb9f1f4abbe9fd2d1394db4db8a9 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 26 Jul 2017 12:07:26 +0000 Subject: [PATCH 042/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 6ee881d..c62c62c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -539,6 +539,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Jul 26 2017 Fedora Release Engineering - 7.5p1-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + * Fri Mar 24 2017 Mattias Ellert - 7.5p1-1 - Based on openssh-7.5p1-2.fc26 From b2977175384118589bb1435a7834a91e871d2b62 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 31 Jul 2017 00:45:36 +0200 Subject: [PATCH 043/146] Based on openssh-7.5p1-3.fc26 Update GSI patch with more openssl 1.1.0 fixes from Globus --- gsi-openssh.spec | 10 +- openssh-7.2p1-fips.patch | 277 +++++++++------ openssh-7.3p1-openssl-1.1.0.patch | 85 +++-- openssh-7.5p1-gsissh.patch | 542 ++++++++++++++++++------------ 4 files changed, 565 insertions(+), 349 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index c62c62c..39103f8 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.5p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -171,7 +171,7 @@ Patch948: openssh-7.4p1-systemd.patch Patch949: openssh-7.5p1-sandbox.patch # This is the patch that adds GSI support -# Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-7.0p1.patch +# Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream Patch98: openssh-7.5p1-gsissh.patch License: BSD @@ -539,6 +539,10 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Jul 31 2017 Mattias Ellert - 7.5p1-2 +- Based on openssh-7.5p1-3.fc26 +- Update GSI patch with more openssl 1.1.0 fixes from Globus + * Wed Jul 26 2017 Fedora Release Engineering - 7.5p1-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index cf03bd4..5be0cce 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.4p1/cipher.c.fips openssh-7.4p1/cipher.c ---- openssh-7.4p1/cipher.c.fips 2016-12-23 16:37:49.290741582 +0100 -+++ openssh-7.4p1/cipher.c 2016-12-23 16:37:49.300741586 +0100 +diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c +--- openssh-7.5p1/cipher.c.fips 2017-06-30 12:06:36.455713788 +0200 ++++ openssh-7.5p1/cipher.c 2017-06-30 12:06:36.465713761 +0200 @@ -39,6 +39,8 @@ #include @@ -67,9 +67,9 @@ diff -up openssh-7.4p1/cipher.c.fips openssh-7.4p1/cipher.c if (strcasecmp(c->name, name) == 0) return c->number; return -1; -diff -up openssh-7.4p1/cipher-ctr.c.fips openssh-7.4p1/cipher-ctr.c ---- openssh-7.4p1/cipher-ctr.c.fips 2016-12-23 16:37:49.225741551 +0100 -+++ openssh-7.4p1/cipher-ctr.c 2016-12-23 16:37:49.297741585 +0100 +diff -up openssh-7.5p1/cipher-ctr.c.fips openssh-7.5p1/cipher-ctr.c +--- openssh-7.5p1/cipher-ctr.c.fips 2017-06-30 12:06:36.386713974 +0200 ++++ openssh-7.5p1/cipher-ctr.c 2017-06-30 12:06:36.465713761 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -80,9 +80,22 @@ diff -up openssh-7.4p1/cipher-ctr.c.fips openssh-7.4p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.4p1/dh.h.fips openssh-7.4p1/dh.h ---- openssh-7.4p1/dh.h.fips 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/dh.h 2016-12-23 16:37:49.297741585 +0100 +diff -up openssh-7.5p1/clientloop.c.fips openssh-7.5p1/clientloop.c +--- openssh-7.5p1/clientloop.c.fips 2017-06-30 12:06:36.466713758 +0200 ++++ openssh-7.5p1/clientloop.c 2017-06-30 12:09:11.503295871 +0200 +@@ -2412,7 +2412,8 @@ key_accepted_by_hostkeyalgs(const struct + { + const char *ktype = sshkey_ssh_name(key); + const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? +- options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG; ++ options.hostkeyalgorithms : (FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG); + + if (key == NULL || key->type == KEY_UNSPEC) + return 0; +diff -up openssh-7.5p1/dh.h.fips openssh-7.5p1/dh.h +--- openssh-7.5p1/dh.h.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/dh.h 2017-06-30 12:06:36.466713758 +0200 @@ -51,6 +51,7 @@ u_int dh_estimate(int); * Miniumum increased in light of DH precomputation attacks. */ @@ -91,9 +104,9 @@ diff -up openssh-7.4p1/dh.h.fips openssh-7.4p1/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh-7.4p1/entropy.c.fips openssh-7.4p1/entropy.c ---- openssh-7.4p1/entropy.c.fips 2016-12-23 16:37:49.219741548 +0100 -+++ openssh-7.4p1/entropy.c 2016-12-23 16:37:49.297741585 +0100 +diff -up openssh-7.5p1/entropy.c.fips openssh-7.5p1/entropy.c +--- openssh-7.5p1/entropy.c.fips 2017-06-30 12:06:36.377713998 +0200 ++++ openssh-7.5p1/entropy.c 2017-06-30 12:06:36.466713758 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -104,9 +117,9 @@ diff -up openssh-7.4p1/entropy.c.fips openssh-7.4p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c ---- openssh-7.4p1/kex.c.fips 2016-12-23 16:37:49.290741582 +0100 -+++ openssh-7.4p1/kex.c 2016-12-23 16:37:49.300741586 +0100 +diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c +--- openssh-7.5p1/kex.c.fips 2017-06-30 12:06:36.455713788 +0200 ++++ openssh-7.5p1/kex.c 2017-06-30 12:06:36.466713758 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL #include @@ -142,7 +155,7 @@ diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c char * kex_alg_list(char sep) { -@@ -152,7 +170,7 @@ kex_alg_by_name(const char *name) +@@ -152,7 +173,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -151,7 +164,7 @@ diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -178,7 +196,10 @@ kex_names_valid(const char *names) +@@ -178,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) { @@ -163,9 +176,9 @@ diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c free(s); return 0; } -diff -up openssh-7.4p1/kexgexc.c.fips openssh-7.4p1/kexgexc.c ---- openssh-7.4p1/kexgexc.c.fips 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kexgexc.c 2016-12-23 16:38:38.727763540 +0100 +diff -up openssh-7.5p1/kexgexc.c.fips openssh-7.5p1/kexgexc.c +--- openssh-7.5p1/kexgexc.c.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/kexgexc.c 2017-06-30 12:06:36.467713756 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -183,9 +196,9 @@ diff -up openssh-7.4p1/kexgexc.c.fips openssh-7.4p1/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh-7.4p1/kexgexs.c.fips openssh-7.4p1/kexgexs.c ---- openssh-7.4p1/kexgexs.c.fips 2016-12-23 16:37:49.297741585 +0100 -+++ openssh-7.4p1/kexgexs.c 2016-12-23 16:39:35.009776626 +0100 +diff -up openssh-7.5p1/kexgexs.c.fips openssh-7.5p1/kexgexs.c +--- openssh-7.5p1/kexgexs.c.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/kexgexs.c 2017-06-30 12:06:36.467713756 +0200 @@ -83,9 +83,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; kex->min = min; @@ -198,9 +211,9 @@ diff -up openssh-7.4p1/kexgexs.c.fips openssh-7.4p1/kexgexs.c nbits = MINIMUM(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh-7.4p1/mac.c.fips openssh-7.4p1/mac.c ---- openssh-7.4p1/mac.c.fips 2016-12-23 16:37:49.291741582 +0100 -+++ openssh-7.4p1/mac.c 2016-12-23 16:37:49.298741585 +0100 +diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c +--- openssh-7.5p1/mac.c.fips 2017-06-30 12:06:36.456713785 +0200 ++++ openssh-7.5p1/mac.c 2017-06-30 12:06:36.467713756 +0200 @@ -27,6 +27,8 @@ #include @@ -262,9 +275,9 @@ diff -up openssh-7.4p1/mac.c.fips openssh-7.4p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-7.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.fips 2016-12-23 16:37:49.291741582 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 16:37:49.298741585 +0100 +diff -up openssh-7.5p1/Makefile.in.fips openssh-7.5p1/Makefile.in +--- openssh-7.5p1/Makefile.in.fips 2017-06-30 12:06:36.456713785 +0200 ++++ openssh-7.5p1/Makefile.in 2017-06-30 12:06:36.467713756 +0200 @@ -169,25 +169,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -306,23 +319,38 @@ diff -up openssh-7.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h ---- openssh-7.4p1/myproposal.h.fips 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/myproposal.h 2016-12-23 16:37:49.300741586 +0100 -@@ -138,6 +138,27 @@ +diff -up openssh-7.5p1/myproposal.h.fips openssh-7.5p1/myproposal.h +--- openssh-7.5p1/myproposal.h.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/myproposal.h 2017-06-30 12:10:21.953116208 +0200 +@@ -114,6 +114,14 @@ + "rsa-sha2-256," \ + "ssh-rsa" + ++#define KEX_FIPS_PK_ALG \ ++ HOSTKEY_ECDSA_CERT_METHODS \ ++ "ssh-rsa-cert-v01@openssh.com," \ ++ HOSTKEY_ECDSA_METHODS \ ++ "rsa-sha2-512," \ ++ "rsa-sha2-256," \ ++ "ssh-rsa" ++ + /* the actual algorithms */ + + #define KEX_SERVER_ENCRYPT \ +@@ -138,6 +146,37 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC -+#define KEX_DEFAULT_KEX_FIPS \ -+ KEX_ECDH_METHODS \ -+ KEX_SHA2_METHODS \ -+ KEX_SHA2_GROUP14 +#define KEX_FIPS_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-cbc,3des-cbc," \ + "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" +#ifdef HAVE_EVP_SHA256 -+#define KEX_FIPS_MAC \ ++# define KEX_DEFAULT_KEX_FIPS \ ++ KEX_ECDH_METHODS \ ++ KEX_SHA2_METHODS \ ++ "diffie-hellman-group14-sha256" ++# define KEX_FIPS_MAC \ + "hmac-sha1," \ + "hmac-sha2-256," \ + "hmac-sha2-512," \ @@ -330,6 +358,16 @@ diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h + "hmac-sha2-256-etm@openssh.com," \ + "hmac-sha2-512-etm@openssh.com" +#else ++# ifdef OPENSSL_HAS_NISTP521 ++# define KEX_DEFAULT_KEX_FIPS \ ++ "ecdh-sha2-nistp256," \ ++ "ecdh-sha2-nistp384," \ ++ "ecdh-sha2-nistp521" ++# else ++# define KEX_DEFAULT_KEX_FIPS \ ++ "ecdh-sha2-nistp256," \ ++ "ecdh-sha2-nistp384" ++# endif +#define KEX_FIPS_MAC \ + "hmac-sha1" +#endif @@ -337,29 +375,36 @@ diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h #else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ -diff -up openssh-7.4p1/readconf.c.fips openssh-7.4p1/readconf.c ---- openssh-7.4p1/readconf.c.fips 2016-12-23 16:37:49.274741574 +0100 -+++ openssh-7.4p1/readconf.c 2016-12-23 16:37:49.298741585 +0100 -@@ -2110,9 +2110,12 @@ fill_default_options(Options * options) +diff -up openssh-7.5p1/readconf.c.fips openssh-7.5p1/readconf.c +--- openssh-7.5p1/readconf.c.fips 2017-06-30 12:06:36.468713753 +0200 ++++ openssh-7.5p1/readconf.c 2017-06-30 12:12:40.560769198 +0200 +@@ -2132,12 +2132,17 @@ fill_default_options(Options * options) } if (options->update_hostkeys == -1) options->update_hostkeys = 0; - if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || - kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || - kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || +- kex_assemble_names(KEX_DEFAULT_PK_ALG, + if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT + : KEX_CLIENT_ENCRYPT), &options->ciphers) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC + : KEX_CLIENT_MAC), &options->macs) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS + : KEX_CLIENT_KEX), &options->kex_algorithms) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), &options->hostbased_key_types) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, -diff -up openssh-7.4p1/sandbox-seccomp-filter.c.fips openssh-7.4p1/sandbox-seccomp-filter.c ---- openssh-7.4p1/sandbox-seccomp-filter.c.fips 2016-12-23 16:37:49.292741583 +0100 -+++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 16:37:49.300741586 +0100 -@@ -118,6 +118,9 @@ static const struct sock_filter preauth_ +- kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), + &options->pubkey_key_types) != 0) + fatal("%s: kex_assemble_names failed", __func__); + +diff -up openssh-7.5p1/sandbox-seccomp-filter.c.fips openssh-7.5p1/sandbox-seccomp-filter.c +--- openssh-7.5p1/sandbox-seccomp-filter.c.fips 2017-06-30 12:06:36.458713780 +0200 ++++ openssh-7.5p1/sandbox-seccomp-filter.c 2017-06-30 12:06:36.468713753 +0200 +@@ -137,6 +137,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -369,52 +414,39 @@ diff -up openssh-7.4p1/sandbox-seccomp-filter.c.fips openssh-7.4p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-7.4p1/servconf.c.fips openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.fips 2016-12-23 16:37:49.285741579 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 16:37:49.299741586 +0100 -@@ -185,9 +185,12 @@ option_clear_or_none(const char *o) +diff -up openssh-7.5p1/servconf.c.fips openssh-7.5p1/servconf.c +--- openssh-7.5p1/servconf.c.fips 2017-06-30 12:06:36.468713753 +0200 ++++ openssh-7.5p1/servconf.c 2017-06-30 12:14:09.260547133 +0200 +@@ -185,14 +185,20 @@ option_clear_or_none(const char *o) static void assemble_algorithms(ServerOptions *o) { - if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || - kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || - kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || +- kex_assemble_names(KEX_DEFAULT_PK_ALG, + if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT + : KEX_SERVER_ENCRYPT), &o->ciphers) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC + : KEX_SERVER_MAC), &o->macs) != 0 || + kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS + : KEX_SERVER_KEX), &o->kex_algorithms) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), &o->hostkeyalgorithms) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, -@@ -2390,8 +2393,10 @@ dump_config(ServerOptions *o) - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); - dump_cfg_string(sXAuthLocation, o->xauth_location); -- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); -- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); -+ dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : FIPS_mode() -+ ? KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT); -+ dump_cfg_string(sMacs, o->macs ? o->macs : FIPS_mode() -+ ? KEX_FIPS_MAC : KEX_SERVER_MAC); - 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); -@@ -2406,8 +2411,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); - dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); - dump_cfg_string(sHostKeyAgent, o->host_key_agent); -- dump_cfg_string(sKexAlgorithms, -- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); -+ dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : -+ FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); - dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? - o->hostbased_key_types : KEX_DEFAULT_PK_ALG); - dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? -diff -up openssh-7.4p1/ssh.c.fips openssh-7.4p1/ssh.c ---- openssh-7.4p1/ssh.c.fips 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh.c 2016-12-23 16:37:49.299741586 +0100 +- kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), + &o->hostbased_key_types) != 0 || +- kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) ++ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), &o->pubkey_key_types) != 0) + fatal("kex_assemble_names failed"); + } + +diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c +--- openssh-7.5p1/ssh.c.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/ssh.c 2017-06-30 12:06:36.469713750 +0200 @@ -76,6 +76,8 @@ #include #include @@ -481,9 +513,9 @@ diff -up openssh-7.4p1/ssh.c.fips openssh-7.4p1/ssh.c /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, -diff -up openssh-7.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.fips 2016-12-23 16:37:49.275741574 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 16:37:49.299741586 +0100 +diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c +--- openssh-7.5p1/sshconnect2.c.fips 2017-06-30 12:06:36.439713831 +0200 ++++ openssh-7.5p1/sshconnect2.c 2017-06-30 12:06:36.469713750 +0200 @@ -44,6 +44,8 @@ #include #endif @@ -493,7 +525,17 @@ diff -up openssh-7.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -172,21 +174,26 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -117,7 +119,8 @@ order_hostkeyalgs(char *host, struct soc + for (i = 0; i < options.num_system_hostfiles; i++) + load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); + +- oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); ++ oavail = avail = xstrdup((FIPS_mode() ++ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); + maxlen = strlen(avail) + 1; + first = xmalloc(maxlen); + last = xmalloc(maxlen); +@@ -172,21 +175,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -535,9 +577,28 @@ diff -up openssh-7.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c } } #endif -diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.fips 2016-12-23 16:37:49.293741583 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 16:37:49.299741586 +0100 +@@ -204,14 +212,16 @@ ssh_kex2(char *host, struct sockaddr *ho + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + if (options.hostkeyalgorithms != NULL) { +- if (kex_assemble_names(KEX_DEFAULT_PK_ALG, ++ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), + &options.hostkeyalgorithms) != 0) + fatal("%s: kex_assemble_namelist", __func__); + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + compat_pkalg_proposal(options.hostkeyalgorithms); + } else { + /* Enforce default */ +- options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); ++ options.hostkeyalgorithms = xstrdup((FIPS_mode() ++ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); + /* Prefer algorithms that we already have keys for */ + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + compat_pkalg_proposal( +diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c +--- openssh-7.5p1/sshd.c.fips 2017-06-30 12:06:36.459713777 +0200 ++++ openssh-7.5p1/sshd.c 2017-06-30 12:06:36.469713750 +0200 @@ -66,6 +66,7 @@ #include #include @@ -555,7 +616,7 @@ diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1475,6 +1478,18 @@ main(int ac, char **av) +@@ -1484,6 +1487,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -574,7 +635,7 @@ diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1623,7 +1638,7 @@ main(int ac, char **av) +@@ -1632,7 +1647,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -583,7 +644,7 @@ diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1937,6 +1952,10 @@ main(int ac, char **av) +@@ -1951,6 +1966,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); @@ -594,7 +655,7 @@ diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2309,10 +2328,14 @@ do_ssh2_kex(void) +@@ -2328,10 +2347,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -613,9 +674,9 @@ diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.fips 2016-12-23 16:37:49.293741583 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 16:37:49.300741586 +0100 +diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c +--- openssh-7.5p1/sshkey.c.fips 2017-06-30 12:06:36.459713777 +0200 ++++ openssh-7.5p1/sshkey.c 2017-06-30 12:06:36.470713747 +0200 @@ -34,6 +34,7 @@ #include #include @@ -624,15 +685,15 @@ diff -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c #endif #include "crypto_api.h" -@@ -56,6 +57,7 @@ - #include "digest.h" - #define SSHKEY_INTERNAL +@@ -58,6 +59,7 @@ #include "sshkey.h" -+#include "log.h" #include "match.h" #include "xmalloc.h" ++#include "log.h" -@@ -1580,6 +1582,8 @@ rsa_generate_private_key(u_int bits, RSA + /* openssh private key file format */ + #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" +@@ -1587,6 +1589,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -641,3 +702,19 @@ diff -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } +diff -up openssh-7.5p1/ssh-keygen.c.fips openssh-7.5p1/ssh-keygen.c +--- openssh-7.5p1/ssh-keygen.c.fips 2017-03-20 03:39:27.000000000 +0100 ++++ openssh-7.5p1/ssh-keygen.c 2017-06-30 12:06:36.470713747 +0200 +@@ -217,6 +217,12 @@ type_bits_valid(int type, const char *na + OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; + if (*bitsp > maxbits) + fatal("key bits exceeds maximum %d", maxbits); ++ 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"); ++ } + if (type == KEY_DSA && *bitsp != 1024) + fatal("DSA keys must be 1024 bits"); + else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 08354bd..99ed90f 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -18,8 +18,8 @@ diff -up openssh-7.4p1/authfd.c.openssl openssh-7.4p1/authfd.c + (r = sshbuf_get_u32(ids, &bits)) != 0 || + (r = sshbuf_get_bignum1(ids, e)) != 0 || + (r = sshbuf_get_bignum1(ids, n)) != 0 || -+ (RSA_set0_key(key->rsa, n, e, NULL) == 0) || -+ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) { ++ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0 || ++ (RSA_set0_key(key->rsa, n, e, NULL) == 0)) { + BN_free(n); + BN_free(e); goto out; @@ -2003,7 +2003,7 @@ diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c if (bits != sshkey_size(key)) logit("Warning: identity keysize mismatch: " -@@ -565,23 +577,38 @@ agent_decode_rsa1(struct sshbuf *m, stru +@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, stru { struct sshkey *k = NULL; int r = SSH_ERR_INTERNAL_ERROR; @@ -2032,16 +2032,24 @@ diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c - (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ + (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */ + (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */ -+ RSA_set0_key(k->rsa, n, e, d) == 0 || -+ RSA_set0_factors(k->rsa, p, q) == 0 || -+ RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) { ++ RSA_set0_key(k->rsa, n, e, d) == 0) { + BN_free(n); + BN_free(e); + BN_free(d); + BN_free(p); + BN_free(q); ++ BN_free(iqmp); ++ goto out; ++ } ++ if (RSA_set0_factors(k->rsa, p, q) == 0) { ++ BN_free(p); ++ BN_free(q); + BN_free(iqmp); goto out; ++ } ++ if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) { ++ BN_free(iqmp); ++ goto out; + } /* Generate additional parameters */ @@ -3088,7 +3096,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2819,24 +2995,71 @@ sshkey_private_deserialize(struct sshbuf +@@ -2819,24 +2995,84 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3168,11 +3176,24 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + (r = sshbuf_get_bignum2(buf, p)) != 0 || + (r = sshbuf_get_bignum2(buf, q)) != 0 || + (r = ((RSA_set0_key(k->rsa, NULL, NULL, d) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || -+ (r = ((RSA_set0_factors(k->rsa, p, q) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || -+ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) ++ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { ++ BN_free(d); ++ BN_free(iqmp); ++ BN_free(p); ++ BN_free(q); + goto out; ++ } ++ if (RSA_set0_factors(k->rsa, p, q) == 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ BN_free(p); ++ BN_free(q); ++ goto out; ++ } ++ if (rsa_generate_additional_parameters(k->rsa, iqmp) != 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ free(iqmp); ++ goto out; ++ } + } break; #endif /* WITH_OPENSSL */ @@ -3275,7 +3296,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); -@@ -3786,14 +4038,25 @@ sshkey_parse_private_rsa1(struct sshbuf +@@ -3786,15 +4038,33 @@ sshkey_parse_private_rsa1(struct sshbuf } /* Read the rest of the private key. */ @@ -3291,22 +3312,40 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 || + (r = sshbuf_get_bignum1(decrypted, q)) != 0 || + (r = sshbuf_get_bignum1(decrypted, p)) != 0 || -+ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0) || -+ (RSA_set0_factors(prv->rsa, p, q) == 0)) { ++ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0)) { + BN_free(d); + BN_free(p); + BN_free(q); ++ BN_free(iqmp); ++ goto out; ++ } ++ if (RSA_set0_factors(prv->rsa, p, q) == 0) { ++ BN_free(p); ++ BN_free(q); + BN_free(iqmp); goto out; + } /* calculate p-1 and q-1 */ - if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) -+ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) ++ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) { ++ BN_free(iqmp); goto out; ++ } /* enable blinding */ -@@ -3846,7 +4109,7 @@ sshkey_parse_private_pem_fileblob(struct + if (RSA_blinding_on(prv->rsa, NULL) != 1) { +@@ -3874,7 +4146,9 @@ sshkey_parse_private_pem_fileblob(struct + case EVP_R_BAD_DECRYPT: + r = SSH_ERR_KEY_WRONG_PASSPHRASE; + goto out; ++#ifdef EVP_R_BN_DECODE_ERROR + case EVP_R_BN_DECODE_ERROR: ++#endif + case EVP_R_DECODE_ERROR: + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + case EVP_R_PRIVATE_KEY_DECODE_ERROR: +@@ -3892,7 +4166,7 @@ sshkey_parse_private_pem_fileblob(struct r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -3629,17 +3668,3 @@ diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; -diff --git a/sshkey.c b/sshkey.c -index ffc17ce..130217a 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -3815,7 +3815,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - case EVP_R_BAD_DECRYPT: - r = SSH_ERR_KEY_WRONG_PASSPHRASE; - goto out; -+#ifdef EVP_R_BN_DECODE_ERROR - case EVP_R_BN_DECODE_ERROR: -+#endif - case EVP_R_DECODE_ERROR: - #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR - case EVP_R_PRIVATE_KEY_DECODE_ERROR: diff --git a/openssh-7.5p1-gsissh.patch b/openssh-7.5p1-gsissh.patch index 4718cb2..fcd7508 100644 --- a/openssh-7.5p1-gsissh.patch +++ b/openssh-7.5p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c ---- openssh-7.5p1.orig/auth2.c 2017-03-24 21:49:39.696255466 +0100 -+++ openssh-7.5p1/auth2.c 2017-03-24 22:00:16.345972336 +0100 +--- openssh-7.5p1.orig/auth2.c 2017-07-30 23:44:44.760055252 +0200 ++++ openssh-7.5p1/auth2.c 2017-07-31 00:04:16.612262807 +0200 @@ -229,7 +229,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -100,8 +100,8 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c ---- openssh-7.5p1.orig/auth2-gss.c 2017-03-24 21:49:39.672255251 +0100 -+++ openssh-7.5p1/auth2-gss.c 2017-03-24 21:50:18.891606581 +0100 +--- openssh-7.5p1.orig/auth2-gss.c 2017-07-30 23:44:44.751055255 +0200 ++++ openssh-7.5p1/auth2-gss.c 2017-07-31 00:04:16.614262806 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -137,13 +137,13 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c - &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw)); -+ &gssbuf, &mic))) || ++ &gssbuf, &mic))) || + !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, -+ &gssbuf2, &mic)))) { ++ &gssbuf2, &mic)))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1 /* gssapi-keyex */)); ++ authctxt->pw, 1 /* gssapi-keyex */)); + } + } @@ -232,7 +232,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c + /* user should be set if valid but we double-check here */ + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0 /* !gssapi-keyex */)); ++ authctxt->pw, 0 /* !gssapi-keyex */)); + } else { + authenticated = 0; + } @@ -251,7 +251,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0 /* !gssapi-keyex */)); ++ authctxt->pw, 0 /* !gssapi-keyex */)); + } else { + authenticated = 0; + } @@ -265,7 +265,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c +static void ssh_gssapi_userauth_error(Gssctxt *ctxt) { + char *errstr; + OM_uint32 maj,min; -+ ++ + errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min)); + if (errstr) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR); @@ -283,8 +283,8 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c ---- openssh-7.5p1.orig/auth.c 2017-03-24 21:49:39.697255475 +0100 -+++ openssh-7.5p1/auth.c 2017-03-24 21:50:18.892606590 +0100 +--- openssh-7.5p1.orig/auth.c 2017-07-30 23:44:44.761055251 +0200 ++++ openssh-7.5p1/auth.c 2017-07-31 00:04:16.615262805 +0200 @@ -77,6 +77,9 @@ #include "ssherr.h" #include "compat.h" @@ -351,8 +351,8 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c ---- openssh-7.5p1.orig/auth-pam.c 2017-03-24 21:49:39.733255798 +0100 -+++ openssh-7.5p1/auth-pam.c 2017-03-24 21:50:18.893606599 +0100 +--- openssh-7.5p1.orig/auth-pam.c 2017-07-30 23:44:44.777055246 +0200 ++++ openssh-7.5p1/auth-pam.c 2017-07-31 00:04:16.616262804 +0200 @@ -289,6 +289,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -388,7 +388,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + fatal("PAM: could not get PAM_USER: %s", + pam_strerror(sshpam_handle, sshpam_err)); + debug("sshpam_check_userchanged: user was '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + if (strcmp(user, sshpam_authctxt->pw->pw_name) != 0) { + debug("PAM: user mapped from '%.100s' to '%.100s'", + sshpam_authctxt->pw->pw_name, user); @@ -404,7 +404,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + sshpam_authctxt->valid ? "" : "in"); + } + debug("sshpam_check_userchanged: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); +} + void @@ -426,11 +426,11 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + if (options.permit_pam_user_change) { + user = buffer_get_string(b, NULL); + debug("PAM: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + debug("PAM: got username '%.100s' from thread", user); + if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS) + fatal("PAM: failed to set PAM_USER: %s", -+ pam_strerror(sshpam_handle, err)); ++ pam_strerror(sshpam_handle, err)); + pwfree(sshpam_authctxt->pw); + sshpam_authctxt->pw = pwcopy(sshpam_getpw(user)); + } @@ -443,10 +443,10 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + if (options.permit_pam_user_change) { + debug("sshpam_thread: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + sshpam_check_userchanged(); + debug("sshpam_thread: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + } if (compat20) { if (!do_pam_account()) { @@ -457,7 +457,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); + if (options.permit_pam_user_change) { + debug("sshpam_thread: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name); + } @@ -469,14 +469,14 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + if (options.permit_pam_user_change) { + debug("do_pam_account: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + sshpam_check_userchanged(); + debug("do_pam_account: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + if (getpwnam(sshpam_authctxt->pw->pw_name) == NULL) -+ fatal("PAM: completed authentication but PAM account invalid"); ++ fatal("PAM: completed authentication but PAM account invalid"); + debug("do_pam_account: user is '%.100s'", -+ sshpam_authctxt->pw->pw_name); ++ sshpam_authctxt->pw->pw_name); + } + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { @@ -493,8 +493,8 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-7.5p1.orig/auth-pam.h openssh-7.5p1/auth-pam.h ---- openssh-7.5p1.orig/auth-pam.h 2017-03-24 21:49:39.507253773 +0100 -+++ openssh-7.5p1/auth-pam.h 2017-03-24 21:50:18.894606608 +0100 +--- openssh-7.5p1.orig/auth-pam.h 2017-07-30 23:44:44.677055280 +0200 ++++ openssh-7.5p1/auth-pam.h 2017-07-31 00:04:16.617262803 +0200 @@ -41,5 +41,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -504,7 +504,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.h openssh-7.5p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-7.5p1.orig/canohost.c openssh-7.5p1/canohost.c --- openssh-7.5p1.orig/canohost.c 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/canohost.c 2017-03-24 21:50:18.894606608 +0100 ++++ openssh-7.5p1/canohost.c 2017-07-31 00:04:16.617262803 +0200 @@ -17,6 +17,7 @@ #include #include @@ -549,7 +549,7 @@ diff -Nur openssh-7.5p1.orig/canohost.c openssh-7.5p1/canohost.c +} diff -Nur openssh-7.5p1.orig/canohost.h openssh-7.5p1/canohost.h --- openssh-7.5p1.orig/canohost.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/canohost.h 2017-03-24 21:50:18.895606617 +0100 ++++ openssh-7.5p1/canohost.h 2017-07-31 00:04:16.618262802 +0200 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -558,8 +558,8 @@ diff -Nur openssh-7.5p1.orig/canohost.h openssh-7.5p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac ---- openssh-7.5p1.orig/configure.ac 2017-03-24 21:49:39.687255386 +0100 -+++ openssh-7.5p1/configure.ac 2017-03-24 21:50:18.896606625 +0100 +--- openssh-7.5p1.orig/configure.ac 2017-07-30 23:44:44.757055253 +0200 ++++ openssh-7.5p1/configure.ac 2017-07-31 00:04:16.621262800 +0200 @@ -4440,6 +4440,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -597,7 +597,7 @@ diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac + AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Globus GSI.]) + fi + -+ if test -z "$GSSAPI" ; then ++ if test -z "$GSSAPI" ; then + GSSAPI="GSI" + fi + @@ -627,8 +627,8 @@ diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c ---- openssh-7.5p1.orig/gss-genr.c 2017-03-24 21:49:39.736255824 +0100 -+++ openssh-7.5p1/gss-genr.c 2017-03-24 21:50:18.897606635 +0100 +--- openssh-7.5p1.orig/gss-genr.c 2017-07-30 23:44:44.778055246 +0200 ++++ openssh-7.5p1/gss-genr.c 2017-07-31 00:04:16.622262799 +0200 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -646,13 +646,13 @@ diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c - xasprintf(&val, "host@%s", host); + /* Make a copy of the host name, in case it was returned by a -+ * previous call to gethostbyname(). */ ++ * previous call to gethostbyname(). */ + xhost = xstrdup(host); + + /* Make sure we have the FQDN. Some GSSAPI implementations don't do + * this for us themselves */ + resolve_localhost(&xhost); -+ ++ + xasprintf(&val, "host@%s", xhost); gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); @@ -666,8 +666,8 @@ diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c return (ctx->major); } diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c ---- openssh-7.5p1.orig/gss-serv.c 2017-03-24 21:49:39.674255269 +0100 -+++ openssh-7.5p1/gss-serv.c 2017-03-24 21:50:18.897606635 +0100 +--- openssh-7.5p1.orig/gss-serv.c 2017-07-30 23:44:44.751055255 +0200 ++++ openssh-7.5p1/gss-serv.c 2017-07-31 00:04:16.624262798 +0200 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -675,9 +675,10 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c +extern Authctxt *the_authctxt; static ssh_gssapi_client gssapi_client = - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, +- { 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, NULL}, GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, ++ GSS_C_NO_NAME, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, + GSS_C_NO_CONTEXT, 0, 0}; ssh_gssapi_mech gssapi_null_mech = @@ -696,8 +697,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c &gssapi_kerberos_mech, #endif +#ifdef GSI -+ &gssapi_gsi_mech, + &gssapi_gsi_mech_micv2, ++ &gssapi_gsi_mech, +#endif &gssapi_null_mech, }; @@ -741,7 +742,16 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -316,8 +348,11 @@ +@@ -309,21 +341,24 @@ + gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; + + if (options.gss_store_rekey && client->used && ctx->client_creds) { +- if (client->mech->oid.length != ctx->oid->length || +- (memcmp(client->mech->oid.elements, ++ if (client->oid.length != ctx->oid->length || ++ (memcmp(client->oid.elements, + ctx->oid->elements, ctx->oid->length) !=0)) { + debug("Rekeyed credentials have different mechanism"); return GSS_S_COMPLETE; } @@ -750,12 +760,36 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c + /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech + because GSI doesn't support the latter. -jbasney */ + -+ if ((ctx->major = gss_inquire_cred(&ctx->minor, -+ ctx->client_creds, &new_name, ++ if ((ctx->major = gss_inquire_cred(&ctx->minor, ++ ctx->client_creds, &new_name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); -@@ -360,9 +395,12 @@ + } + +- ctx->major = gss_compare_name(&ctx->minor, client->name, ++ ctx->major = gss_compare_name(&ctx->minor, client->cred_name, + new_name, &equal); + + if (GSS_ERROR(ctx->major)) { +@@ -338,9 +373,9 @@ + + debug("Marking rekeyed credentials for export"); + +- gss_release_name(&ctx->minor, &client->name); ++ gss_release_name(&ctx->minor, &client->cred_name); + gss_release_cred(&ctx->minor, &client->creds); +- client->name = new_name; ++ client->cred_name = new_name; + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; + client->updated = 1; +@@ -357,12 +392,17 @@ + i++; + } + ++ if (client->oid.elements == NULL) ++ client->oid = *ctx->oid; if (client->mech == NULL) return GSS_S_FAILURE; @@ -766,11 +800,27 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c - (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, - ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { + (ctx->major = gss_inquire_cred(&ctx->minor, -+ ctx->client_creds, &client->name, NULL, NULL, NULL))) { ++ ctx->client_creds, &client->cred_name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } -@@ -389,6 +427,10 @@ +@@ -379,16 +419,25 @@ + return (ctx->major); + } + +- if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, ++ if ((client->mech->oid.elements != NULL) && ++ (ctx->major = ssh_gssapi_parse_ename(ctx,&ename, + &client->exportedname))) { + return (ctx->major); + } + ++ if ((ctx->major = gss_duplicate_name(&ctx->minor, ctx->client, ++ &client->ctx_name))) ++ return ctx->major; ++ + gss_release_buffer(&ctx->minor, &ename); + /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -781,7 +831,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c return (ctx->major); } -@@ -396,6 +438,7 @@ +@@ -396,6 +445,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -789,7 +839,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -411,6 +454,14 @@ +@@ -411,6 +461,14 @@ gssapi_client.store.data = NULL; } } @@ -804,19 +854,19 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c } /* As user */ -@@ -418,6 +469,11 @@ +@@ -418,6 +476,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { + if (options.gss_creds_path) { + gssapi_client.store.filename = -+ expand_authorized_keys(options.gss_creds_path, -+ the_authctxt->pw); ++ expand_authorized_keys(options.gss_creds_path, ++ the_authctxt->pw); + } (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -451,8 +507,9 @@ +@@ -451,16 +514,19 @@ } /* Privileged */ @@ -827,20 +877,28 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c { OM_uint32 lmin; -@@ -461,6 +518,12 @@ - debug("No suitable client data"); - return 0; - } +- if (gssapi_client.exportedname.length == 0 || +- gssapi_client.exportedname.value == NULL) { +- debug("No suitable client data"); +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG + if (limited && options.gsi_allow_limited_proxy != 1) { + debug("limited proxy not acceptable for remote login"); -+ return 0; -+ } + return 0; + } +#endif ++ if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -480,6 +543,24 @@ +@@ -471,6 +537,7 @@ + gss_release_buffer(&lmin, &gssapi_client.displayname); + gss_release_buffer(&lmin, &gssapi_client.exportedname); + gss_release_cred(&lmin, &gssapi_client.creds); ++ gss_release_name(&lmin, &gssapi_client.ctx_name); + explicit_bzero(&gssapi_client, + sizeof(ssh_gssapi_client)); + return 0; +@@ -480,6 +547,24 @@ return (0); } @@ -848,24 +906,24 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c +int +ssh_gssapi_localname(char **user) +{ -+ *user = NULL; -+ if (gssapi_client.displayname.length == 0 || ++ *user = NULL; ++ if (gssapi_client.displayname.length == 0 || + gssapi_client.displayname.value == NULL) { + debug("No suitable client data"); -+ return(0); ++ return (0); + } + if (gssapi_client.mech && gssapi_client.mech->localname) { + return((*gssapi_client.mech->localname)(&gssapi_client,user)); + } else { + debug("Unknown client authentication type"); + } -+ return(0); ++ return (0); +} + /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -506,6 +587,7 @@ +@@ -506,6 +591,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -873,18 +931,18 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -535,6 +617,18 @@ +@@ -535,6 +621,18 @@ if (ret) return; -+ /* Put ssh pam stack env variables in this new pam stack env ++ /* Put ssh pam stack env variables in this new pam stack env + * Using pam-pkinit, KRB5CCNAME is set during do_pam_session -+ * this addition enables pam-pkinit to access KRB5CCNAME if used ++ * this addition enables pam-pkinit to access KRB5CCNAME if used + * in sshd-rekey stack too + */ + pw = p = fetch_pam_environment(); + while ( *pw != NULL ) { -+ pam_putenv(pamh, *pw); ++ pam_putenv(pamh, *pw); + pw++; + } + free_pam_environment(p); @@ -892,7 +950,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -566,4 +660,13 @@ +@@ -566,4 +664,13 @@ return ok; } @@ -908,7 +966,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c #endif diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c --- openssh-7.5p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/gss-serv-gsi.c 2017-03-24 21:50:18.898606643 +0100 ++++ openssh-7.5p1/gss-serv-gsi.c 2017-07-31 00:04:16.624262798 +0200 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -949,7 +1007,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +#include "hostfile.h" +#include "auth.h" +#include "log.h" -+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ ++#include "misc.h" +#include "servconf.h" + +#include "buffer.h" @@ -964,9 +1022,9 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client); +static void ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client); +static int ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store, -+ ssh_gssapi_client *client); ++ ssh_gssapi_client *client); +static int ssh_gssapi_gsi_updatecreds_micv2(ssh_gssapi_ccache *store, -+ ssh_gssapi_client *client); ++ ssh_gssapi_client *client); + +ssh_gssapi_mech gssapi_gsi_mech = { + "dZuIebMjgUqaxvbF7hDbAw==", @@ -1240,13 +1298,13 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c ---- openssh-7.5p1.orig/gss-serv-krb5.c 2017-03-24 21:49:39.636254929 +0100 -+++ openssh-7.5p1/gss-serv-krb5.c 2017-03-24 21:50:18.898606643 +0100 +--- openssh-7.5p1.orig/gss-serv-krb5.c 2017-07-30 23:44:44.733055261 +0200 ++++ openssh-7.5p1/gss-serv-krb5.c 2017-07-31 00:04:16.624262798 +0200 @@ -378,6 +378,34 @@ return found_principal; } -+/* Retrieve the local username associated with a set of Kerberos ++/* Retrieve the local username associated with a set of Kerberos + * credentials. Hopefully we can use this for the 'empty' username + * logins discussed in the draft */ +static int @@ -1257,9 +1315,9 @@ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c + if (ssh_gssapi_krb5_init() == 0) + return 0; + -+ if ((retval=krb5_parse_name(krb_context, client->displayname.value, -+ &princ))) { -+ logit("krb5_parse_name(): %.100s", ++ if ((retval=krb5_parse_name(krb_context, client->displayname.value, ++ &princ))) { ++ logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context,retval)); + return 0; + } @@ -1296,8 +1354,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c ---- openssh-7.5p1.orig/kexgsss.c 2017-03-24 21:49:39.738255842 +0100 -+++ openssh-7.5p1/kexgsss.c 2017-03-24 21:50:18.898606643 +0100 +--- openssh-7.5p1.orig/kexgsss.c 2017-07-30 23:44:44.779055245 +0200 ++++ openssh-7.5p1/kexgsss.c 2017-07-31 00:04:16.625262797 +0200 @@ -47,6 +47,7 @@ #include "ssh-gss.h" #include "digest.h" @@ -1338,12 +1396,12 @@ diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c return 0; } + -+static void ++static void +kex_gss_send_error(Gssctxt *ctxt) { + char *errstr; -+ OM_uint32 maj,min; -+ -+ errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min)); ++ OM_uint32 maj, min; ++ ++ errstr = PRIVSEP(ssh_gssapi_last_error(ctxt, &maj, &min)); + if (errstr) { + packet_start(SSH2_MSG_KEXGSS_ERROR); + packet_put_int(maj); @@ -1359,7 +1417,7 @@ diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c #endif /* GSSAPI */ diff -Nur openssh-7.5p1.orig/LICENSE.globus_usage openssh-7.5p1/LICENSE.globus_usage --- openssh-7.5p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/LICENSE.globus_usage 2017-03-24 21:50:18.899606652 +0100 ++++ openssh-7.5p1/LICENSE.globus_usage 2017-07-31 00:04:16.625262797 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1380,8 +1438,8 @@ diff -Nur openssh-7.5p1.orig/LICENSE.globus_usage openssh-7.5p1/LICENSE.globus_u + * limitations under the License. + */ diff -Nur openssh-7.5p1.orig/Makefile.in openssh-7.5p1/Makefile.in ---- openssh-7.5p1.orig/Makefile.in 2017-03-24 21:49:39.739255851 +0100 -+++ openssh-7.5p1/Makefile.in 2017-03-24 21:50:18.899606652 +0100 +--- openssh-7.5p1.orig/Makefile.in 2017-07-30 23:44:44.779055245 +0200 ++++ openssh-7.5p1/Makefile.in 2017-07-31 00:04:16.625262797 +0200 @@ -114,8 +114,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1394,8 +1452,8 @@ diff -Nur openssh-7.5p1.orig/Makefile.in openssh-7.5p1/Makefile.in sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c ---- openssh-7.5p1.orig/misc.c 2017-03-24 21:49:39.633254902 +0100 -+++ openssh-7.5p1/misc.c 2017-03-24 21:50:18.899606652 +0100 +--- openssh-7.5p1.orig/misc.c 2017-07-30 23:44:44.732055261 +0200 ++++ openssh-7.5p1/misc.c 2017-07-31 00:04:16.625262797 +0200 @@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1457,7 +1515,7 @@ diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c * Port must be >=0 and <=65535. diff -Nur openssh-7.5p1.orig/misc.h openssh-7.5p1/misc.h --- openssh-7.5p1.orig/misc.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/misc.h 2017-03-24 21:50:18.900606661 +0100 ++++ openssh-7.5p1/misc.h 2017-07-31 00:04:16.625262797 +0200 @@ -69,6 +69,7 @@ void sock_set_v6only(int); @@ -1467,8 +1525,8 @@ diff -Nur openssh-7.5p1.orig/misc.h openssh-7.5p1/misc.h typedef struct arglist arglist; diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c ---- openssh-7.5p1.orig/monitor.c 2017-03-24 21:49:39.739255851 +0100 -+++ openssh-7.5p1/monitor.c 2017-03-24 21:50:18.900606661 +0100 +--- openssh-7.5p1.orig/monitor.c 2017-07-30 23:44:44.780055245 +0200 ++++ openssh-7.5p1/monitor.c 2017-07-31 00:04:16.626262796 +0200 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1502,7 +1560,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, -+ {MONITOR_REQ_GSSCHECKMIC, 0, mm_answer_gss_checkmic}, ++ {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error}, + {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs}, @@ -1622,7 +1680,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c + buffer_put_int(m, mech_set->count); + for (i = 0; i < mech_set->count; i++) { + buffer_put_string(m, mech_set->elements[i].elements, -+ mech_set->elements[i].length); ++ mech_set->elements[i].length); + } + + gss_release_oid_set(&minor, &mech_set); @@ -1657,8 +1715,8 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c mm_answer_gss_sign(int socket, Buffer *m) { diff -Nur openssh-7.5p1.orig/monitor.h openssh-7.5p1/monitor.h ---- openssh-7.5p1.orig/monitor.h 2017-03-24 21:49:39.701255511 +0100 -+++ openssh-7.5p1/monitor.h 2017-03-24 21:50:18.901606670 +0100 +--- openssh-7.5p1.orig/monitor.h 2017-07-30 23:44:44.762055251 +0200 ++++ openssh-7.5p1/monitor.h 2017-07-31 00:04:16.626262796 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1673,8 +1731,8 @@ diff -Nur openssh-7.5p1.orig/monitor.h openssh-7.5p1/monitor.h struct monitor { diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c ---- openssh-7.5p1.orig/monitor_wrap.c 2017-03-24 21:49:39.725255726 +0100 -+++ openssh-7.5p1/monitor_wrap.c 2017-03-24 21:50:18.901606670 +0100 +--- openssh-7.5p1.orig/monitor_wrap.c 2017-07-30 23:44:44.774055247 +0200 ++++ openssh-7.5p1/monitor_wrap.c 2017-07-31 00:04:16.626262796 +0200 @@ -977,12 +977,13 @@ } @@ -1731,10 +1789,10 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS, -+ &m); ++ &m); + major=buffer_get_int(&m); + count=buffer_get_int(&m); -+ ++ + gss_create_empty_oid_set(&minor,mech_set); + while(count-->0) { + oid.elements=buffer_get_string(&m,&length); @@ -1743,7 +1801,7 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c + } + + buffer_free(&m); -+ ++ + return(major); +} + @@ -1757,15 +1815,15 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c + + debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME, -+ &m); ++ &m); + + *lname = buffer_get_string(&m, NULL); + + buffer_free(&m); + if (lname[0] == '\0') { -+ debug3("%s: gssapi identity mapping failed", __func__); ++ debug3("%s: gssapi identity mapping failed", __func__); + } else { -+ debug3("%s: gssapi identity mapped to %s", __func__, *lname); ++ debug3("%s: gssapi identity mapped to %s", __func__, *lname); + } + + return(0); @@ -1775,8 +1833,8 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-7.5p1.orig/monitor_wrap.h openssh-7.5p1/monitor_wrap.h ---- openssh-7.5p1.orig/monitor_wrap.h 2017-03-24 21:49:39.708255574 +0100 -+++ openssh-7.5p1/monitor_wrap.h 2017-03-24 21:50:18.902606679 +0100 +--- openssh-7.5p1.orig/monitor_wrap.h 2017-07-30 23:44:44.766055250 +0200 ++++ openssh-7.5p1/monitor_wrap.h 2017-07-31 00:04:16.626262796 +0200 @@ -59,9 +59,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1787,14 +1845,14 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.h openssh-7.5p1/monitor_wrap.h OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); +int mm_ssh_gssapi_localname(char **user); +OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status, -+ gss_OID_set *mech_set); ++ gss_OID_set *mech_set); +char *mm_ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min); int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif diff -Nur openssh-7.5p1.orig/readconf.c openssh-7.5p1/readconf.c ---- openssh-7.5p1.orig/readconf.c 2017-03-24 21:49:39.716255645 +0100 -+++ openssh-7.5p1/readconf.c 2017-03-24 21:50:18.902606679 +0100 +--- openssh-7.5p1.orig/readconf.c 2017-07-30 23:44:44.770055248 +0200 ++++ openssh-7.5p1/readconf.c 2017-07-31 00:04:16.626262796 +0200 @@ -1995,13 +1995,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1814,8 +1872,8 @@ diff -Nur openssh-7.5p1.orig/readconf.c openssh-7.5p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-7.5p1.orig/readconf.h openssh-7.5p1/readconf.h ---- openssh-7.5p1.orig/readconf.h 2017-03-24 21:49:39.666255198 +0100 -+++ openssh-7.5p1/readconf.h 2017-03-24 21:50:18.903606688 +0100 +--- openssh-7.5p1.orig/readconf.h 2017-07-30 23:44:44.748055256 +0200 ++++ openssh-7.5p1/readconf.h 2017-07-31 00:04:16.626262796 +0200 @@ -86,6 +86,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1826,8 +1884,8 @@ diff -Nur openssh-7.5p1.orig/readconf.h openssh-7.5p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c ---- openssh-7.5p1.orig/servconf.c 2017-03-24 21:49:39.727255744 +0100 -+++ openssh-7.5p1/servconf.c 2017-03-24 22:02:56.629428886 +0100 +--- openssh-7.5p1.orig/servconf.c 2017-07-30 23:44:44.775055247 +0200 ++++ openssh-7.5p1/servconf.c 2017-07-31 00:04:16.627262795 +0200 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1857,7 +1915,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -207,6 +212,8 @@ +@@ -210,6 +215,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1866,7 +1924,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -280,13 +287,17 @@ +@@ -283,13 +290,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1886,7 +1944,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -414,7 +425,7 @@ +@@ -417,7 +428,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1895,7 +1953,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -436,10 +447,14 @@ +@@ -439,10 +450,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1910,7 +1968,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -465,8 +480,10 @@ +@@ -468,8 +483,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1921,7 +1979,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -512,7 +529,14 @@ +@@ -515,7 +532,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1936,7 +1994,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -520,7 +544,10 @@ +@@ -523,7 +547,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1947,7 +2005,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -589,6 +616,8 @@ +@@ -592,6 +619,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1956,7 +2014,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1062,6 +1091,10 @@ +@@ -1065,6 +1094,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1967,7 +2025,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1269,6 +1302,10 @@ +@@ -1272,6 +1305,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1978,7 +2036,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1277,6 +1314,10 @@ +@@ -1280,6 +1317,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1989,7 +2047,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1297,6 +1338,12 @@ +@@ -1300,6 +1341,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2002,7 +2060,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1768,6 +1815,35 @@ +@@ -1771,6 +1818,35 @@ *charptr = xstrdup(arg); break; @@ -2038,7 +2096,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2064,6 +2140,7 @@ +@@ -2067,6 +2143,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2047,8 +2105,8 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h ---- openssh-7.5p1.orig/servconf.h 2017-03-24 21:49:39.682255341 +0100 -+++ openssh-7.5p1/servconf.h 2017-03-24 21:50:18.905606706 +0100 +--- openssh-7.5p1.orig/servconf.h 2017-07-30 23:44:44.755055253 +0200 ++++ openssh-7.5p1/servconf.h 2017-07-31 01:10:42.382769264 +0200 @@ -118,9 +118,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if @@ -2082,8 +2140,8 @@ diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h char *trusted_user_ca_keys; char *authorized_keys_command; diff -Nur openssh-7.5p1.orig/ssh.1 openssh-7.5p1/ssh.1 ---- openssh-7.5p1.orig/ssh.1 2017-03-24 21:49:39.676255287 +0100 -+++ openssh-7.5p1/ssh.1 2017-03-24 21:50:18.905606706 +0100 +--- openssh-7.5p1.orig/ssh.1 2017-07-30 23:44:44.753055254 +0200 ++++ openssh-7.5p1/ssh.1 2017-07-31 00:04:16.628262794 +0200 @@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER @@ -2104,8 +2162,8 @@ diff -Nur openssh-7.5p1.orig/ssh.1 openssh-7.5p1/ssh.1 .Pp Additionally, diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c ---- openssh-7.5p1.orig/ssh.c 2017-03-24 21:49:39.743255887 +0100 -+++ openssh-7.5p1/ssh.c 2017-03-24 21:50:18.906606715 +0100 +--- openssh-7.5p1.orig/ssh.c 2017-07-30 23:44:44.781055245 +0200 ++++ openssh-7.5p1/ssh.c 2017-07-31 00:04:16.628262794 +0200 @@ -472,6 +472,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2154,8 +2212,8 @@ diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); diff -Nur openssh-7.5p1.orig/ssh_config openssh-7.5p1/ssh_config ---- openssh-7.5p1.orig/ssh_config 2017-03-24 21:49:39.588254499 +0100 -+++ openssh-7.5p1/ssh_config 2017-03-24 21:50:18.906606715 +0100 +--- openssh-7.5p1.orig/ssh_config 2017-07-30 23:44:44.714055267 +0200 ++++ openssh-7.5p1/ssh_config 2017-07-31 00:04:16.628262794 +0200 @@ -24,10 +24,10 @@ # RSAAuthentication yes # PasswordAuthentication yes @@ -2172,17 +2230,17 @@ diff -Nur openssh-7.5p1.orig/ssh_config openssh-7.5p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 ---- openssh-7.5p1.orig/ssh_config.5 2017-03-24 21:49:39.667255206 +0100 -+++ openssh-7.5p1/ssh_config.5 2017-03-24 21:50:18.907606724 +0100 +--- openssh-7.5p1.orig/ssh_config.5 2017-07-30 23:44:44.748055256 +0200 ++++ openssh-7.5p1/ssh_config.5 2017-07-31 00:04:16.628262794 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config .It +GSSAPI configuration file -+.Pq Pa ~/.ssh/config.gssapi ++.Pq Pa $HOME/.ssh/config.gssapi +.It +Kerberos configuration file -+.Pq Pa ~/.ssh/config.krb ++.Pq Pa $HOME/.ssh/config.krb +.It system-wide configuration file .Pq Pa /etc/ssh/ssh_config @@ -2220,10 +2278,37 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are +@@ -1243,7 +1249,7 @@ + .Cm password ) . + The default is: + .Bd -literal -offset indent +-gssapi-with-mic,hostbased,publickey, ++gssapi-keyex,gssapi-with-mic,hostbased,publickey, + keyboard-interactive,password + .Ed + .It Cm Protocol diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c ---- openssh-7.5p1.orig/sshconnect2.c 2017-03-24 21:49:39.742255878 +0100 -+++ openssh-7.5p1/sshconnect2.c 2017-03-24 21:50:18.907606724 +0100 -@@ -725,6 +725,11 @@ +--- openssh-7.5p1.orig/sshconnect2.c 2017-07-30 23:44:44.781055245 +0200 ++++ openssh-7.5p1/sshconnect2.c 2017-07-31 06:05:17.317851971 +0200 +@@ -167,7 +167,7 @@ + + #ifdef GSSAPI + char *orig = NULL, *gss = NULL; +- char *gss_host = NULL; ++ const char *gss_host = NULL; + #endif + + xxx_host = host; +@@ -184,7 +184,7 @@ + orig = options.kex_algorithms; + + if (options.gss_trust_dns) +- gss_host = (char *)get_canonical_hostname(active_state, 1); ++ gss_host = get_canonical_hostname(active_state, 1); + else + gss_host = host; + +@@ -728,6 +728,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2235,13 +2320,24 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -962,6 +967,19 @@ +@@ -817,7 +822,8 @@ + + if (status == GSS_S_COMPLETE) { + /* send either complete or MIC, depending on mechanism */ +- if (!(flags & GSS_C_INTEG_FLAG)) { ++ if (strcmp(authctxt->method->name, "gssapi") == 0 || ++ (!(flags & GSS_C_INTEG_FLAG))) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); + packet_send(); + } else { +@@ -965,6 +971,20 @@ return 0; } +#ifdef GSI +extern +const gss_OID_desc * const gss_mech_globus_gssapi_openssl; ++extern +const gss_OID_desc * const gss_mech_globus_gssapi_openssl_micv2; +#define is_gsi_oid(oid) \ + ((oid->length == gss_mech_globus_gssapi_openssl->length && \ @@ -2255,7 +2351,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -979,8 +997,16 @@ +@@ -982,8 +1002,16 @@ return (0); } @@ -2272,7 +2368,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -991,7 +1017,15 @@ +@@ -994,7 +1022,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2289,8 +2385,8 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-7.5p1.orig/sshd.8 openssh-7.5p1/sshd.8 ---- openssh-7.5p1.orig/sshd.8 2017-03-24 21:49:39.642254982 +0100 -+++ openssh-7.5p1/sshd.8 2017-03-24 21:50:18.908606733 +0100 +--- openssh-7.5p1.orig/sshd.8 2017-07-30 23:44:44.737055260 +0200 ++++ openssh-7.5p1/sshd.8 2017-07-31 00:04:16.629262793 +0200 @@ -740,6 +740,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2337,8 +2433,8 @@ diff -Nur openssh-7.5p1.orig/sshd.8 openssh-7.5p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c ---- openssh-7.5p1.orig/sshd.c 2017-03-24 21:49:39.744255896 +0100 -+++ openssh-7.5p1/sshd.c 2017-03-24 21:50:18.908606733 +0100 +--- openssh-7.5p1.orig/sshd.c 2017-07-30 23:44:44.782055244 +0200 ++++ openssh-7.5p1/sshd.c 2017-07-31 00:04:16.629262793 +0200 @@ -130,6 +130,7 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2353,7 +2449,7 @@ diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c +#ifdef HAVE_GLOBUS_USAGE + if (ssh_usage_stats_init(options.disable_usage_stats, -+ options.usage_stats_targets) != GLOBUS_SUCCESS) { ++ options.usage_stats_targets) != GLOBUS_SUCCESS) { + error("Error initializing Globus Usage Metrics, but continuing ..."); + } +#endif /* HAVE_GLOBUS_USAGE */ @@ -2371,8 +2467,8 @@ diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config ---- openssh-7.5p1.orig/sshd_config 2017-03-24 21:49:39.653255081 +0100 -+++ openssh-7.5p1/sshd_config 2017-03-24 21:50:18.909606742 +0100 +--- openssh-7.5p1.orig/sshd_config 2017-07-30 23:44:44.742055258 +0200 ++++ openssh-7.5p1/sshd_config 2017-07-31 00:04:16.630262793 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2410,8 +2506,8 @@ diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config #Match User anoncvs # X11Forwarding no diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 ---- openssh-7.5p1.orig/sshd_config.5 2017-03-24 21:49:39.683255350 +0100 -+++ openssh-7.5p1/sshd_config.5 2017-03-24 21:52:32.873806802 +0100 +--- openssh-7.5p1.orig/sshd_config.5 2017-07-30 23:44:44.756055253 +0200 ++++ openssh-7.5p1/sshd_config.5 2017-07-31 00:04:16.630262793 +0200 @@ -574,6 +574,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may @@ -2435,7 +2531,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 +.It Cm GSIAllowLimitedProxy +Specifies whether to accept limited proxy credentials for authentication. +The default is -+.Dq no . ++.Cm no . .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2448,9 +2544,9 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .Cm yes . +.It Cm GSSAPICredentialsPath +If specified, the delegated GSSAPI credential is stored in the -+given path, overwriting any existing credentials. -+Paths can be specified with syntax similar to the AuthorizedKeysFile -+option (i.e., accepting %h and %u tokens). ++given path, overwriting any existing credentials. ++Paths can be specified with syntax similar to the AuthorizedKeysFile ++option (i.e., accepting %h and %u tokens). +When using this option, +setting 'GssapiCleanupCredentials no' is recommended, +so logging out of one session @@ -2460,7 +2556,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 +.It Cm GSSAPIDelegateCredentials +Specifies whether delegated credentials are stored in the user's environment. +The default is -+.Dq yes . ++.Cm yes . .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in @@ -2473,7 +2569,15 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1513,6 +1541,103 @@ +@@ -692,7 +720,6 @@ + .Pp + The default is + .Dq gss-gex-sha1-,gss-group14-sha1- . +-This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a comma-separated pattern list. +@@ -1513,6 +1540,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2553,20 +2657,20 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 +.Sm on +.Pp +If no tags are specified in a host spec, or the special string -+.Dq default ++.Cm default +is specified, the tags -+.Dq VvMm ++.Cm VvMm +are assumed. A site could choose to allow a +different set of data to be reported by specifying a different tag set. The +last 3 tags -+.Dq I , -+.Dq u ++.Cm I , ++.Cm u +and -+.Dq U ++.Cm U +above are more meant for a local collector that a +site might like to deploy since they could be construed as private information. +The special string -+.Dq all ++.Cm all +denotes all tags. +.El +.Pp @@ -2577,22 +2681,22 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1554,6 +1679,12 @@ +@@ -1554,6 +1678,12 @@ as a non-root user. The default is .Cm no . +.It Cm PermitPAMUserChange +If set to -+.Dq yes ++.Cm yes +this will enable PAM authentication to change the name of the user being +authenticated. The default is -+.Dq no . ++.Cm no . .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c --- openssh-7.5p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/ssh-globus-usage.c 2017-03-24 21:50:18.910606751 +0100 ++++ openssh-7.5p1/ssh-globus-usage.c 2017-07-31 00:04:16.630262793 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -2623,7 +2727,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c +#ifdef HAVE_GLOBUS_USAGE + +#include -+#include ++#include + +#include "log.h" +#include "ssh-globus-usage.h" @@ -2737,7 +2841,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + goto error; + } + } -+ ++ + if(strcasecmp(usage_ent->taglist, "default") == 0) + { + free(usage_ent->taglist); @@ -2747,7 +2851,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + error("ERROR: couldn't allocate for taglist"); + goto error; + } -+ } ++ } + else if(strcasecmp(usage_ent->taglist, "all") == 0) + { + free(usage_ent->taglist); @@ -2758,7 +2862,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + goto error; + } + } -+ ++ + usage_ent->target = entry; + + globus_list_insert(&usage_handle_list, usage_ent); @@ -2816,12 +2920,12 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c +error: + if (target_str) + { -+ free(target_str); ++ free(target_str); + target_str = NULL; + } + if (entry) + { -+ free(target_str); ++ free(target_str); + target_str = NULL; + } + return GLOBUS_FAILURE; @@ -2836,14 +2940,14 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + return; + + list = usage_handle_list; -+ ++ + while(!globus_list_empty(list)) + { + ssh_usage_ent_t *usage_ent; -+ -+ usage_ent = (ssh_usage_ent_t *) ++ ++ usage_ent = (ssh_usage_ent_t *) + globus_list_remove(&list, list); -+ ++ + if(usage_ent) + { + if(usage_ent->handle) @@ -2889,12 +2993,12 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + + if(!usage_ent || usage_ent->handle == NULL) + continue; -+ -+ if(save_taglist == NULL || ++ ++ if(save_taglist == NULL || + strcmp(save_taglist, usage_ent->taglist) != 0) + { + save_taglist = usage_ent->taglist; -+ ++ + ptr = usage_ent->taglist; + i = 0; + while(ptr && *ptr) @@ -2905,50 +3009,50 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + key = "SSH_VER"; + value = (char *) ssh_release; + break; -+ ++ + case SSH_GLOBUS_USAGE_SSL_VER: + key = "SSL_VER"; + value = (char *) ssl_release; + break; -+ ++ + case SSH_GLOBUS_USAGE_METHOD: + key = "METHOD"; + value = (char *) method; + break; -+ ++ + case SSH_GLOBUS_USAGE_MECHANISM: + key = "MECH"; + value = (char *) mechanism?:""; + break; -+ ++ + case SSH_GLOBUS_USAGE_CLIENTIP: + key = "CLIENTIP"; + value = (char *) clientip?:""; + break; -+ ++ + case SSH_GLOBUS_USAGE_USERNAME: + key = "USER"; + value = (char *) username?:""; + break; -+ ++ + case SSH_GLOBUS_USAGE_USERDN: + key = "USERDN"; + value = (char *) userdn?:""; + break; -+ ++ + default: + key = NULL; + value = NULL; + break; + } -+ ++ + if(key != NULL && value != NULL) + { + keys[i] = key; + values[i] = value; + i++; + } -+ ++ + ptr++; + } + } @@ -2969,7 +3073,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + i>6?keys[6]:NULL, i>6?values[6]:NULL); +#endif /* HAVE_GLOBUS_USAGE_SEND_ARRAY */ + } -+ ++ + return; +} +#endif /* HAVE_GLOBUS_USAGE */ @@ -2992,7 +3096,7 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c +} diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h --- openssh-7.5p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/ssh-globus-usage.h 2017-03-24 21:50:18.910606751 +0100 ++++ openssh-7.5p1/ssh-globus-usage.h 2017-07-31 00:04:16.630262793 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3001,13 +3105,13 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h + * Portions, specifically ssh_usage_stats_init(), ssh_usage_stats_close() + * were based on those from: gridftp/server/source/globus_i_gfs_log.h + * Copyright 1999-2006 University of Chicago -+ * ++ * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at -+ * ++ * + * http://www.apache.org/licenses/LICENSE-2.0 -+ * ++ * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -3043,17 +3147,25 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h + +#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h ---- openssh-7.5p1.orig/ssh-gss.h 2017-03-24 21:49:39.677255296 +0100 -+++ openssh-7.5p1/ssh-gss.h 2017-03-24 21:50:18.910606751 +0100 -@@ -95,6 +95,7 @@ - gss_name_t name; +--- openssh-7.5p1.orig/ssh-gss.h 2017-07-30 23:44:44.753055254 +0200 ++++ openssh-7.5p1/ssh-gss.h 2017-07-31 00:04:16.630262793 +0200 +@@ -89,12 +89,14 @@ + } ssh_gssapi_ccache; + + typedef struct { ++ gss_OID_desc oid; + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; +- gss_name_t name; ++ gss_name_t cred_name, ctx_name; struct ssh_gssapi_mech_struct *mech; ssh_gssapi_ccache store; + gss_ctx_id_t context; /* needed for globus_gss_assist_map_and_authorize() */ int used; int updated; } ssh_gssapi_client; -@@ -115,7 +116,7 @@ +@@ -115,7 +117,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -3062,7 +3174,7 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -148,6 +149,9 @@ +@@ -148,6 +150,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -3072,7 +3184,7 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -158,7 +162,7 @@ +@@ -158,7 +163,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -3081,7 +3193,7 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h char* ssh_gssapi_get_displayname(void); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); -@@ -171,6 +175,7 @@ +@@ -171,6 +176,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -3091,9 +3203,10 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h #endif /* _SSH_GSS_H */ diff -Nur openssh-7.5p1.orig/version.h openssh-7.5p1/version.h --- openssh-7.5p1.orig/version.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/version.h 2017-03-24 21:54:48.743023927 +0100 -@@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */ ++++ openssh-7.5p1/version.h 2017-07-31 00:04:16.630262793 +0200 +@@ -2,5 +2,19 @@ + + #define SSH_VERSION "OpenSSH_7.5" +#ifdef GSI +#define GSI_VERSION " GSI" @@ -3107,11 +3220,8 @@ diff -Nur openssh-7.5p1.orig/version.h openssh-7.5p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20161122" -+ - #define SSH_VERSION "OpenSSH_7.5" - #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE -+#define SSH_RELEASE SSH_VERSION SSH_PORTABLE \ -+ NCSA_VERSION GSI_VERSION KRB5_VERSION ++#define GSI_PORTABLE "b-GSI" ++#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ ++ GSI_VERSION KRB5_VERSION From 2f685df7e6960574bdb459a60bbea1a99356a807 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 11 Nov 2017 23:12:08 +0100 Subject: [PATCH 044/146] Based on openssh-7.5p1-5.fc27 --- gsi-openssh.spec | 6 +++++- gsisshd.service | 3 ++- gsisshd.sysconfig | 4 ++++ gsisshd@.service | 3 ++- openssh-6.6p1-redhat.patch | 11 ++++++++++- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 39103f8..4d139af 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.5p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -338,6 +338,7 @@ This version of OpenSSH has been modified to support GSI authentication. sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in +sed 's!/etc/sysconfig/sshd!/etc/sysconfig/gsisshd!' -i sshd_config cp -p %{SOURCE99} . @@ -539,6 +540,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat Nov 11 2017 Mattias Ellert - 7.5p1-3 +- Based on openssh-7.5p1-5.fc27 + * Mon Jul 31 2017 Mattias Ellert - 7.5p1-2 - Based on openssh-7.5p1-3.fc26 - Update GSI patch with more openssl 1.1.0 fixes from Globus diff --git a/gsisshd.service b/gsisshd.service index afe165d..f1eac35 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -6,8 +6,9 @@ Wants=gsisshd-keygen.target [Service] Type=notify +EnvironmentFile=-/etc/crypto-policies/back-ends/openssh-server.config EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd -D $OPTIONS +ExecStart=/usr/sbin/gsisshd -D $OPTIONS $CRYPTO_POLICY ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 482f734..a668d82 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -11,3 +11,7 @@ SSH_USE_STRONG_RNG=0 # SSH_USE_STRONG_RNG=1 + +# System-wide crypto policy: +# To opt-out, uncomment the following line +# CRYPTO_POLICY= diff --git a/gsisshd@.service b/gsisshd@.service index 3f5ecbd..23ebbf8 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -5,6 +5,7 @@ Wants=gsisshd-keygen.target After=gsisshd-keygen.target [Service] +EnvironmentFile=-/etc/crypto-policies/back-ends/openssh-server.config EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=-/usr/sbin/gsisshd -i $OPTIONS +ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $CRYPTO_POLICY StandardInput=socket diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index 818858a..426ba66 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -64,7 +64,7 @@ diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config --- openssh-7.4p1/sshd_config.redhat 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/sshd_config 2016-12-23 13:33:05.386233133 +0100 -@@ -10,21 +10,26 @@ +@@ -10,21 +10,35 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -88,6 +88,15 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config # Ciphers and keying #RekeyLimit default none ++# System-wide Crypto policy: ++# If this system is following system-wide crypto policy, the changes to ++# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any ++# effect here. They will be overridden by command-line options passed on ++# the server start up. ++# To opt out, uncomment a line with redefinition of CRYPTO_POLICY= ++# variable in /etc/sysconfig/sshd to overwrite the policy. ++# For more information, see manual page for update-crypto-policies(8). ++ # Logging #SyslogFacility AUTH +SyslogFacility AUTHPRIV From c7d42e73dbb24a56de517bf1e7cf84ba8f495a75 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 22 Nov 2017 22:56:38 +0100 Subject: [PATCH 045/146] Based on openssh-7.6p1-2.fc27 --- gsi-openssh.spec | 33 +- gsisshd.pam | 6 +- openssh-6.6.1p1-log-in-chroot.patch | 28 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 46 +- openssh-6.6p1-ctr-cavstest.patch | 2 +- openssh-6.6p1-entropy.patch | 22 +- openssh-6.6p1-keycat.patch | 10 +- openssh-6.6p1-kuserok.patch | 58 +- openssh-6.6p1-privsep-selinux.patch | 2 +- openssh-6.6p1-role-mls.patch | 68 +- openssh-6.7p1-ldap.patch | 42 +- openssh-6.8p1-memory-problems.patch | 2 +- openssh-7.0p1-gssKexAlgorithms.patch | 10 +- openssh-7.0p1-show-more-fingerprints.patch | 95 +- openssh-7.1p2-audit-race-condition.patch | 12 +- openssh-7.2p1-fips.patch | 82 +- openssh-7.2p1-gsskex.patch | 775 ++++---- openssh-7.2p2-expose-pam.patch | 517 ----- openssh-7.3p1-openssl-1.1.0.patch | 1692 ++++------------- openssh-7.3p1-x11-max-displays.patch | 41 +- openssh-7.5p1-gss-environment.patch | 259 +++ openssh-7.5p1-gssapi-kex-with-ec.patch | 1374 +++++++++++++ openssh-7.5p1-sandbox.patch | 110 +- ...1-audit.patch => openssh-7.6p1-audit.patch | 629 +++--- openssh-7.6p1-cleanup-selinux.patch | 253 +++ ...gsissh.patch => openssh-7.6p1-gsissh.patch | 539 +++--- openssh-7.6p1-permitopen-bug.patch | 47 + sources | 2 +- 28 files changed, 3556 insertions(+), 3200 deletions(-) delete mode 100644 openssh-7.2p2-expose-pam.patch create mode 100644 openssh-7.5p1-gss-environment.patch create mode 100644 openssh-7.5p1-gssapi-kex-with-ec.patch rename openssh-7.2p1-audit.patch => openssh-7.6p1-audit.patch (75%) create mode 100644 openssh-7.6p1-cleanup-selinux.patch rename openssh-7.5p1-gsissh.patch => openssh-7.6p1-gsissh.patch (88%) create mode 100644 openssh-7.6p1-permitopen-bug.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 4d139af..d5dc637 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.5p1 -%global openssh_rel 3 +%global openssh_ver 7.6p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -65,7 +65,7 @@ Patch104: openssh-7.3p1-openssl-1.1.0.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event -Patch200: openssh-7.2p1-audit.patch +Patch200: openssh-7.6p1-audit.patch # Audit race condition in forked child (#1310684) Patch201: openssh-7.1p2-audit-race-condition.patch @@ -126,6 +126,10 @@ Patch803: openssh-7.1p1-gssapi-documentation.patch Patch804: openssh-6.3p1-krb5-use-default_ccache_name.patch # Respect k5login_directory option in krk5.conf (#1328243) Patch805: openssh-7.2p2-k5login_directory.patch +# Do not export KRBCCNAME if the default path is used (#1199363) +Patch806: openssh-7.5p1-gss-environment.patch +# Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02 +Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 @@ -160,19 +164,20 @@ Patch932: openssh-7.0p1-gssKexAlgorithms.patch Patch933: openssh-7.0p1-show-more-fingerprints.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch -# expose more information to PAM -# https://github.com/openssh/openssh-portable/pull/47 -Patch940: openssh-7.2p2-expose-pam.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 -# Fix typo in sandbox code; missing header for s390 -Patch949: openssh-7.5p1-sandbox.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 +# PermitOpen bug in OpenSSH 7.6: +Patch951: openssh-7.6p1-permitopen-bug.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-7.5p1-gsissh.patch +Patch98: openssh-7.6p1-gsissh.patch License: BSD Group: Applications/Internet @@ -304,6 +309,7 @@ This version of OpenSSH has been modified to support GSI authentication. %patch803 -p1 -b .gss-docs %patch804 -p1 -b .ccache_name %patch805 -p1 -b .k5login +%patch806 -p1 -b .gss-env %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok @@ -322,10 +328,12 @@ This version of OpenSSH has been modified to support GSI authentication. %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint %patch939 -p1 -b .s390-dev -%patch940 -p1 -b .expose-pam %patch944 -p1 -b .x11max %patch948 -p1 -b .systemd -%patch949 -p1 -b .sandbox +%patch807 -p1 -b .gsskex-ec +%patch949 -p1 -b .refactor +%patch950 -p1 -b .sandbox +%patch951 -p1 -b .permitOpen %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -540,6 +548,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Nov 22 2017 Mattias Ellert - 7.6p1-1 +- Based on openssh-7.6p1-2.fc27 + * Sat Nov 11 2017 Mattias Ellert - 7.5p1-3 - Based on openssh-7.5p1-5.fc27 diff --git a/gsisshd.pam b/gsisshd.pam index eae0ba6..4354458 100644 --- a/gsisshd.pam +++ b/gsisshd.pam @@ -1,9 +1,7 @@ #%PAM-1.0 -auth required pam_sepermit.so auth substack password-auth auth include postlogin -# Used with polkit to reauthorize users in remote sessions --auth optional pam_reauthorize.so prepare +account required pam_sepermit.so account required pam_nologin.so account include password-auth password include password-auth @@ -16,5 +14,3 @@ session required pam_namespace.so session optional pam_keyinit.so force revoke session include password-auth session include postlogin -# Used with polkit to reauthorize users in remote sessions --session optional pam_reauthorize.so prepare diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index f36d83f..44c345b 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -34,7 +34,7 @@ diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h void log_init(char *, LogLevel, SyslogFacility, int); +void log_init_handler(char *, LogLevel, SyslogFacility, int, int); - void log_change_level(LogLevel); + int log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c @@ -123,30 +123,8 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c static int in_chroot = 0; +static int have_dev_log = 1; - /* Name and directory of socket for authentication agent forwarding. */ - static char *auth_sock_name = NULL; -@@ -365,8 +366,8 @@ do_exec_no_pty(Session *s, const char *c - is_child = 1; - - /* Child. Reinitialize the log since the pid has changed. */ -- log_init(__progname, options.log_level, -- options.log_facility, log_stderr); -+ log_init_handler(__progname, options.log_level, -+ options.log_facility, log_stderr, have_dev_log); - - /* - * Create a new session and process group since the 4.4BSD -@@ -523,8 +524,8 @@ do_exec_pty(Session *s, const char *comm - close(ptymaster); - - /* Child. Reinitialize the log because the pid has changed. */ -- log_init(__progname, options.log_level, -- options.log_facility, log_stderr); -+ log_init_handler(__progname, options.log_level, -+ options.log_facility, log_stderr, have_dev_log); - /* Close the master side of the pseudo tty. */ - close(ptyfd); - + /* 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; diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index e64d320..9f91f14 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -22,22 +22,22 @@ 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->fingerprint_hash = -1; - options->disable_forwarding = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; options->use_kuserok = -1; + options->enable_k5users = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption - options->disable_forwarding = 0; + options->gss_store_rekey = 0; if (options->use_kuserok == -1) options->use_kuserok = 1; + if (options->enable_k5users == -1) + options->enable_k5users = 0; - - assemble_algorithms(options); - + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) @@ -418,7 +421,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, @@ -80,28 +80,26 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + M_CP_INTOPT(enable_k5users); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); - + M_CP_INTOPT(log_level); @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + # endif dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); + #endif + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h --- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 +++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100 -@@ -174,7 +174,8 @@ typedef struct { - - int num_permitted_opens; - -- int use_kuserok; -+ int use_kuserok; +@@ -174,6 +174,7 @@ typedef struct { + int kerberos_get_afs_token; /* If true, try to get AFS token if + * authenticated with Kerberos. */ + int use_kuserok; + int enable_k5users; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100 diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index eb43c79..8aa6872 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -20,7 +20,7 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in ssh_api.o \ @@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o - $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index db8ce54..f1fc6c9 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -16,7 +16,7 @@ diff -up openssh-7.4p1/openbsd-compat/Makefile.in.entropy openssh-7.4p1/openbsd- +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 18:35:15.890769493 +0100 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o @@ -123,26 +123,6 @@ diff -up openssh-7.4p1/ssh.1.entropy openssh-7.4p1/ssh.1 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.rhosts -diff -up openssh-7.4p1/ssh-add.0.entropy openssh-7.4p1/ssh-add.0 ---- openssh-7.4p1/ssh-add.0.entropy 2016-12-19 06:21:21.000000000 +0100 -+++ openssh-7.4p1/ssh-add.0 2016-12-23 18:34:27.770753571 +0100 -@@ -88,6 +88,16 @@ ENVIRONMENT - Identifies the path of a UNIX-domain socket used to communicate - with the agent. - -+ SSH_USE_STRONG_RNG -+ The reseeding of the OpenSSL random generator is usually done -+ from /dev/urandom. If the SSH_USE_STRONG_RNG environment vari- -+ able is set to value other than 0 the OpenSSL random generator is -+ reseeded from /dev/random. The number of bytes read is defined -+ by the SSH_USE_STRONG_RNG value. Minimum is 14 bytes. This set- -+ ting is not recommended on the computers without the hardware -+ random generator because insufficient entropy causes the connec- -+ tion to be blocked until enough entropy is available. -+ - FILES - ~/.ssh/identity - Contains the protocol version 1 RSA authentication identity of diff -up openssh-7.4p1/ssh-add.1.entropy openssh-7.4p1/ssh-add.1 --- openssh-7.4p1/ssh-add.1.entropy 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/ssh-add.1 2016-12-23 18:34:27.770753571 +0100 diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 2e8f977..9304c1f 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,6 +1,6 @@ -diff -up openssh/auth2-pubkey.c.keycat openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.keycat 2015-06-24 10:57:50.158849606 +0200 -+++ openssh/auth2-pubkey.c 2015-06-24 11:04:23.989868638 +0200 +diff -up openssh/misc.c.keycat openssh/misc.c +--- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 ++++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 @@ -490,6 +490,14 @@ subprocess(const char *tag, struct passw _exit(1); } @@ -62,10 +62,10 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in ssh_api.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o -+ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) ++ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 3f10d60..47768aa 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -175,23 +175,23 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c 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 -@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions - options->version_addendum = NULL; - options->fingerprint_hash = -1; - options->disable_forwarding = -1; +@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions + options->gss_cleanup_creds = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; + options->use_kuserok = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -342,6 +343,8 @@ fill_default_server_options(ServerOption - options->fingerprint_hash = SSH_FP_HASH_DEFAULT; - if (options->disable_forwarding == -1) - options->disable_forwarding = 0; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; +@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption + options->gss_strict_acceptor = 1; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; - - assemble_algorithms(options); - + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) @@ -399,7 +402,7 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, @@ -233,26 +233,26 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c + M_CP_INTOPT(use_kuserok); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); - + M_CP_INTOPT(log_level); @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); - dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + # ifdef USE_AFS + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + # endif + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); + #endif + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h --- openssh-7.4p1/servconf.h.kuserok 2016-12-23 14:36:07.630465944 +0100 +++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100 -@@ -174,6 +174,7 @@ typedef struct { - - int num_permitted_opens; - +@@ -118,6 +118,7 @@ typedef struct { + * file on logout. */ + int kerberos_get_afs_token; /* If true, try to get AFS token if + * authenticated with Kerberos. */ + int use_kuserok; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100 @@ -272,9 +272,9 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , +.Cm KerberosUseKuserok , + .Cm LogLevel , .Cm MaxAuthTries , .Cm MaxSessions , - .Cm PasswordAuthentication , 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 diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 6933b39..bc2c15d 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -107,7 +107,7 @@ diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c +#endif + /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) { + if (privsep_chroot) { /* Change our root directory */ @@ -633,6 +637,9 @@ privsep_postauth(Authctxt *authctxt) { diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index f2bfa5a..ad2411f 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -2,7 +2,7 @@ diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c --- openssh-7.4p1/auth2.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2.c 2016-12-23 12:19:58.587459379 +0100 @@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; char *user, *service, *method, *style = NULL; +#ifdef WITH_SELINUX @@ -44,7 +44,7 @@ diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c --- openssh-7.4p1/auth2-gss.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-gss.c 2016-12-23 12:19:58.586459382 +0100 @@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; int authenticated = 0; + char *micuser; @@ -74,34 +74,35 @@ diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c + free(micuser); free(mic.value); - authctxt->postponed = 0; + if ((!use_privsep || mm_is_monitor()) && diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased.c --- openssh-7.4p1/auth2-hostbased.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 12:19:58.586459382 +0100 -@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); +@@ -121,7 +121,16 @@ userauth_hostbased(Authctxt *authctxt) /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); + if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || +- (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else ++ (authctxt->role ++ ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 || ++ (r = sshbuf_put(b, authctxt->user, strlen(authctxt->user))) != 0 || ++ (r = sshbuf_put_u8(b, '/') != 0) || ++ (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0) ++ : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) || ++#else ++ (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); + (r = sshbuf_put_cstring(b, service)) != 0 || + (r = sshbuf_put_cstring(b, "hostbased")) != 0 || + (r = sshbuf_put_string(b, pkalg, alen)) != 0 || diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c --- openssh-7.4p1/auth2-pubkey.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 12:19:58.587459379 +0100 @@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) + __func__, ssh_err(r)); } /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - xasprintf(&userstyle, "%s%s%s", authctxt->user, + xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, authctxt->style ? ":" : "", @@ -113,9 +114,9 @@ diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c +#else + "", ""); +#endif - buffer_put_cstring(&b, userstyle); - free(userstyle); - buffer_put_cstring(&b, + if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshbuf_put_cstring(b, userstyle)) != 0 || + (r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ? diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h --- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth.h 2016-12-23 12:19:43.478510375 +0100 @@ -126,9 +127,9 @@ diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h +#ifdef WITH_SELINUX + char *role; +#endif - void *kbdintctxt; - char *info; /* Extra info for next auth_log */ - #ifdef BSD_AUTH + + /* Method lists for multiple authentication */ + char **auth_methods; /* modified from server config */ diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c --- openssh-7.4p1/auth-pam.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth-pam.c 2016-12-23 12:19:43.477510378 +0100 @@ -320,8 +321,8 @@ diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h --- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 @@ -42,6 +42,9 @@ int mm_is_monitor(void); - DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); + int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, + const char *); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -334,7 +335,7 @@ diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 12:24:06.042643938 +0100 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o @@ -863,3 +864,16 @@ diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(1); +--- openssh/configure.ac.role-mls 2017-09-27 12:54:52.926425979 +0200 ++++ openssh/configure.ac 2017-09-27 12:57:06.854224956 +0200 +@@ -4158,10 +4158,7 @@ + LIBS="$LIBS -lselinux" + ], + AC_MSG_ERROR([SELinux support requires libselinux library])) +- SSHLIBS="$SSHLIBS $LIBSELINUX" +- SSHDLIBS="$SSHDLIBS $LIBSELINUX" + AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) +- LIBS="$save_LIBS" + fi ] + ) + AC_SUBST([SSHLIBS]) diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index fd29ce4..20faa95 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -136,6 +136,14 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +@@ -50,6 +50,7 @@ + CFLAGS=@CFLAGS@ + CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ + LIBS=@LIBS@ ++LDAPLIBS=@LDAPLIBS@ + K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHLIBS=@SSHLIBS@ @@ -61,8 +63,9 @@ XAUTH_PATH=@XAUTH_PATH@ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ EXEEXT=@EXEEXT@ @@ -163,7 +171,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) ++ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -224,7 +232,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac --- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 -@@ -1605,6 +1605,106 @@ if test "x$use_pie" != "xno"; then +@@ -1605,6 +1605,110 @@ if test "x$use_pie" != "xno"; then fi fi @@ -259,35 +267,37 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac + fi + + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then -+ AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes) -+ AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(lber, main, LDAPLIBS="-llber $LDAPLIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldap, main, LDAPLIBS="-lldap $LDAPLIBS" found_ldap_lib=yes) + fi + + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then -+ AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldap50, main, LDAPLIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LDAPLIBS" found_ldap_lib=yes) + fi + + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then -+ AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldapssl41, main, LDAPLIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LDAPLIBS" found_ldap_lib=yes) + if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldapssl40, main, LDAPLIBS="-lldapssl40 $LDAPLIBS" found_ldap_lib=yes) + fi + if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldap41, main, LDAPLIBS="-lldap41 $LDAPLIBS" found_ldap_lib=yes) + fi + if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldap40, main, LDAPLIBS="-lldap40 $LDAPLIBS" found_ldap_lib=yes) + fi + fi + + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then -+ AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes) ++ AC_CHECK_LIB(ldapssl30, main, LDAPLIBS="-lldapssl30 $LDAPLIBS" found_ldap_lib=yes) + fi + + if test -z "$found_ldap_lib"; then + AC_MSG_ERROR(could not locate a valid LDAP library) + fi + ++ saved_LIBS="$LIBS" ++ LIBS="$LIBS $LDAPLIBS" + AC_MSG_CHECKING([for working LDAP support]) + AC_TRY_COMPILE( + [#include @@ -323,14 +333,26 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac + AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) + AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) + ) ++ LIBS="$saved_LIBS" + fi + ] +) +AC_SUBST(INSTALL_SSH_LDAP_HELPER) ++AC_SUBST(LDAPLIBS) + dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ Blowfish_initstate \ +@@ -5227,6 +5352,9 @@ + echo "Preprocessor flags: ${CPPFLAGS}" + echo " Linker flags: ${LDFLAGS}" + echo " Libraries: ${LIBS}" ++if test ! -z "${LDAPLIBS}"; then ++echo " +for ldap: ${LDAPLIBS}" ++fi + if test ! -z "${SSHDLIBS}"; then + echo " +for sshd: ${SSHDLIBS}" + fi diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c --- openssh-6.8p1/ldap-helper.c.ldap 2015-03-18 11:11:29.030801464 +0100 +++ openssh-6.8p1/ldap-helper.c 2015-03-18 11:11:29.030801464 +0100 diff --git a/openssh-6.8p1-memory-problems.patch b/openssh-6.8p1-memory-problems.patch index e112033..b2da05e 100644 --- a/openssh-6.8p1-memory-problems.patch +++ b/openssh-6.8p1-memory-problems.patch @@ -21,4 +21,4 @@ diff -up openssh-7.4p1/servconf.c.memory openssh-7.4p1/servconf.c + dst->n[dst->num_n] = src->n[dst->num_n]; \ } \ } while(0) - + #define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 30519af..6200eaa 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -245,9 +245,9 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c options->gss_strict_acceptor = -1; 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->challenge_response_authentication = -1; @@ -288,6 +290,10 @@ fill_default_server_options(ServerOption options->gss_strict_acceptor = 1; if (options->gss_store_rekey == -1) @@ -256,9 +256,9 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c + if (options->gss_kex_algorithms == NULL) + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); +#endif - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) + if (options->use_kuserok == -1) + options->use_kuserok = 1; + if (options->enable_k5users == -1) @@ -427,7 +431,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index d4637f5..aeb3daa 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c ---- openssh-7.4p1/clientloop.c.fingerprint 2016-12-23 15:38:50.520432387 +0100 -+++ openssh-7.4p1/clientloop.c 2016-12-23 15:38:50.564432394 +0100 -@@ -2279,7 +2279,7 @@ update_known_hosts(struct hostkeys_updat +diff -up openssh/clientloop.c.fingerprint openssh/clientloop.c +--- openssh/clientloop.c.fingerprint 2017-09-26 15:21:22.582477729 +0200 ++++ openssh/clientloop.c 2017-09-26 15:21:22.620477932 +0200 +@@ -1854,7 +1854,7 @@ update_known_hosts(struct hostkeys_updat if (ctx->keys_seen[i] != 2) continue; if ((fp = sshkey_fingerprint(ctx->keys[i], @@ -10,7 +10,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Learned new hostkey: %s %s", sshkey_type(ctx->keys[i]), fp); -@@ -2287,7 +2287,7 @@ update_known_hosts(struct hostkeys_updat +@@ -1862,7 +1862,7 @@ update_known_hosts(struct hostkeys_updat } for (i = 0; i < ctx->nold; i++) { if ((fp = sshkey_fingerprint(ctx->old_keys[i], @@ -19,7 +19,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", sshkey_type(ctx->old_keys[i]), fp); -@@ -2330,7 +2330,7 @@ update_known_hosts(struct hostkeys_updat +@@ -1905,7 +1905,7 @@ update_known_hosts(struct hostkeys_updat (r = hostfile_replace_entries(options.user_hostfiles[0], ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, options.hash_known_hosts, 0, @@ -28,7 +28,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c error("%s: hostfile_replace_entries failed: %s", __func__, ssh_err(r)); } -@@ -2443,7 +2443,7 @@ client_input_hostkeys(void) +@@ -2038,7 +2038,7 @@ client_input_hostkeys(void) error("%s: parse key: %s", __func__, ssh_err(r)); goto out; } @@ -37,10 +37,10 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c SSH_FP_DEFAULT); debug3("%s: received %s key %s", __func__, sshkey_type(key), fp); -diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c ---- openssh-7.4p1/readconf.c.fingerprint 2016-12-23 15:38:50.559432393 +0100 -+++ openssh-7.4p1/readconf.c 2016-12-23 15:38:50.565432394 +0100 -@@ -1668,16 +1668,18 @@ parse_keytypes: +diff -up openssh/readconf.c.fingerprint openssh/readconf.c +--- openssh/readconf.c.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/readconf.c 2017-09-26 15:21:22.621477937 +0200 +@@ -1681,16 +1681,18 @@ parse_keytypes: goto parse_string; case oFingerprintHash: @@ -69,7 +69,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c break; case oUpdateHostkeys: -@@ -1905,7 +1907,7 @@ initialize_options(Options * options) +@@ -1917,7 +1919,7 @@ initialize_options(Options * options) options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; @@ -78,7 +78,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c options->update_hostkeys = -1; options->hostbased_key_types = NULL; options->pubkey_key_types = NULL; -@@ -2102,8 +2104,10 @@ fill_default_options(Options * options) +@@ -2096,8 +2098,10 @@ fill_default_options(Options * options) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; @@ -91,7 +91,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c if (options->update_hostkeys == -1) options->update_hostkeys = 0; if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || -@@ -2489,6 +2493,17 @@ dump_cfg_strarray(OpCodes code, u_int co +@@ -2474,6 +2478,17 @@ dump_cfg_strarray(OpCodes code, u_int co } static void @@ -109,7 +109,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) { u_int i; -@@ -2564,7 +2579,6 @@ dump_client_config(Options *o, const cha +@@ -2549,7 +2564,6 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); @@ -117,7 +117,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); -@@ -2634,6 +2648,7 @@ dump_client_config(Options *o, const cha +@@ -2618,6 +2632,7 @@ dump_client_config(Options *o, const cha dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); @@ -125,9 +125,9 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c /* Special cases */ -diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h ---- openssh-7.4p1/readconf.h.fingerprint 2016-12-23 15:38:50.559432393 +0100 -+++ openssh-7.4p1/readconf.h 2016-12-23 15:38:50.565432394 +0100 +diff -up openssh/readconf.h.fingerprint openssh/readconf.h +--- openssh/readconf.h.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/readconf.h 2017-09-26 15:21:22.621477937 +0200 @@ -21,6 +21,7 @@ #define MAX_SEND_ENV 256 #define SSH_MAX_HOSTS_FILES 32 @@ -136,7 +136,7 @@ diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { -@@ -162,7 +163,8 @@ typedef struct { +@@ -157,7 +158,8 @@ typedef struct { char *revoked_host_keys; @@ -146,10 +146,10 @@ diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ -diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1/ssh_config.5.fingerprint 2016-12-23 15:38:50.565432394 +0100 -+++ openssh-7.4p1/ssh_config.5 2016-12-23 15:40:03.754444166 +0100 -@@ -652,12 +652,13 @@ or +diff -up openssh/ssh_config.5.fingerprint openssh/ssh_config.5 +--- openssh/ssh_config.5.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/ssh_config.5 2017-09-26 15:21:22.621477937 +0200 +@@ -624,12 +624,13 @@ or .Cm no (the default). .It Cm FingerprintHash @@ -166,10 +166,10 @@ diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. -diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.fingerprint 2016-12-23 15:38:50.561432394 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 15:38:50.566432394 +0100 -@@ -677,7 +677,7 @@ input_userauth_pk_ok(int type, u_int32_t +diff -up openssh/sshconnect2.c.fingerprint openssh/sshconnect2.c +--- openssh/sshconnect2.c.fingerprint 2017-09-26 15:21:22.619477926 +0200 ++++ openssh/sshconnect2.c 2017-09-26 15:21:50.677628003 +0200 +@@ -679,7 +679,7 @@ input_userauth_pk_ok(int type, u_int32_t key->type, pktype); goto done; } @@ -178,7 +178,7 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) goto done; debug2("input_userauth_pk_ok: fp %s", fp); -@@ -1172,7 +1172,7 @@ sign_and_send_pubkey(Authctxt *authctxt, +@@ -1198,7 +1198,7 @@ sign_and_send_pubkey(Authctxt *authctxt, int matched, ret = -1, have_sig = 1; char *fp; @@ -187,7 +187,16 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) return 0; debug3("%s: %s %s", __func__, key_type(id->key), fp); -@@ -1864,7 +1864,7 @@ userauth_hostbased(Authctxt *authctxt) +@@ -1620,7 +1620,7 @@ userauth_pubkey(Authctxt *authctxt) + if (id->key != NULL) { + if (try_identity(id)) { + if ((fp = sshkey_fingerprint(id->key, +- options.fingerprint_hash, ++ options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", + __func__); +@@ -1914,7 +1914,7 @@ userauth_hostbased(Authctxt *authctxt) goto out; } @@ -196,10 +205,10 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; -diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c ---- openssh-7.4p1/sshconnect.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect.c 2016-12-23 15:38:50.566432394 +0100 -@@ -922,9 +922,9 @@ check_host_key(char *hostname, struct so +diff -up openssh/sshconnect.c.fingerprint openssh/sshconnect.c +--- openssh/sshconnect.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshconnect.c 2017-09-26 15:21:22.622477943 +0200 +@@ -861,9 +861,9 @@ check_host_key(char *hostname, struct so "of known hosts.", type, ip); } else if (options.visual_host_key) { fp = sshkey_fingerprint(host_key, @@ -211,7 +220,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("Host key fingerprint is %s\n%s", fp, ra); -@@ -966,12 +966,6 @@ check_host_key(char *hostname, struct so +@@ -907,12 +907,6 @@ check_host_key(char *hostname, struct so else snprintf(msg1, sizeof(msg1), "."); /* The default */ @@ -224,7 +233,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) -@@ -985,16 +979,28 @@ check_host_key(char *hostname, struct so +@@ -926,16 +920,28 @@ check_host_key(char *hostname, struct so } snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " @@ -262,7 +271,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (!confirm(msg)) goto fail; hostkey_trusted = 1; /* user explicitly confirmed */ -@@ -1244,7 +1250,7 @@ verify_host_key(char *host, struct socka +@@ -1192,7 +1198,7 @@ verify_host_key(char *host, struct socka struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, @@ -271,7 +280,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c error("%s: fingerprint host key: %s", __func__, ssh_err(r)); r = -1; goto out; -@@ -1252,7 +1258,7 @@ verify_host_key(char *host, struct socka +@@ -1200,7 +1206,7 @@ verify_host_key(char *host, struct socka if (sshkey_is_cert(host_key)) { if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, @@ -280,7 +289,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c error("%s: fingerprint CA key: %s", __func__, ssh_err(r)); r = -1; -@@ -1432,9 +1438,9 @@ show_other_keys(struct hostkeys *hostkey +@@ -1369,9 +1375,9 @@ show_other_keys(struct hostkeys *hostkey if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; fp = sshkey_fingerprint(found->key, @@ -292,7 +301,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" -@@ -1457,7 +1463,7 @@ warn_changed_key(Key *host_key) +@@ -1394,7 +1400,7 @@ warn_changed_key(struct sshkey *host_key { char *fp; @@ -301,9 +310,9 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c SSH_FP_DEFAULT); if (fp == NULL) fatal("%s: sshkey_fingerprint fail", __func__); -diff -up openssh-7.4p1/ssh-keysign.c.fingerprint openssh-7.4p1/ssh-keysign.c ---- openssh-7.4p1/ssh-keysign.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keysign.c 2016-12-23 15:38:50.566432394 +0100 +diff -up openssh/ssh-keysign.c.fingerprint openssh/ssh-keysign.c +--- openssh/ssh-keysign.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh-keysign.c 2017-09-26 15:21:22.622477943 +0200 @@ -285,7 +285,7 @@ main(int argc, char **argv) } } diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 035f0ac..ec274eb 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -92,7 +92,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + child_destory_sensitive_data(); + /* Do processing for the child (exec command etc). */ - do_child(s, command); + do_child(ssh, s, command); /* NOTREACHED */ @@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm /* Close the extra descriptor for the pseudo tty. */ @@ -112,7 +112,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + fatal("pipe: %s", strerror(errno)); #endif if (s->ttyfd != -1) - ret = do_exec_pty(s, command); + ret = do_exec_pty(ssh, s, command); @@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) */ buffer_clear(&loginmsg); @@ -134,7 +134,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c return ret; } -@@ -1538,6 +1565,33 @@ child_close_fds(void) +@@ -1538,6 +1565,34 @@ child_close_fds(void) endpwent(); } @@ -157,23 +157,25 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + * which we can't do using one-way pipe. + */ + packet_destroy_all(0, 1); ++ /* XXX this will clean the rest but should not audit anymore */ ++ /* packet_clear_keys(); */ + +#ifdef SSH_AUDIT_EVENTS + /* Notify parent that we are done */ + close(pparent); +#endif -+ +} + /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group -@@ -1554,12 +1608,6 @@ do_child(Session *s, const char *command +@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command struct passwd *pw = s->pw; int r = 0; - /* remove hostkey from the child's memory */ - destroy_sensitive_data(1); +- packet_clear_keys(); - /* Don't audit this - both us and the parent would be talking to the - monitor over a single socket, with no synchronization. */ - packet_destroy_all(0, 1); diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index 5be0cce..f0a178a 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -10,22 +10,29 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c #include #include #include -@@ -116,6 +118,20 @@ static const struct sshcipher ciphers[] - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } +@@ -116,6 +118,27 @@ static const struct sshcipher ciphers[] + { NULL, 0, 0, 0, 0, 0, NULL } }; +static const struct sshcipher fips_ciphers[] = { -+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, -+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, -+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, -+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, -+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, ++#ifdef WITH_OPENSSL ++ { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, ++ { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc }, ++ { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc }, ++ { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, + { "rijndael-cbc@lysator.liu.se", -+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, -+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, -+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, -+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, -+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } ++ 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, ++ { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, ++ { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, ++ { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, ++#else ++ { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, ++ { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, ++ { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL }, ++#endif ++ { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, ++ ++ { NULL, 0, 0, 0, 0, 0, NULL } +}; + /*--*/ @@ -37,7 +44,7 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c - for (c = ciphers; c->name != NULL; c++) { + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { - if (c->number != SSH_CIPHER_SSH2) + if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) @@ -222,7 +238,7 @@ const struct sshcipher * @@ -49,24 +56,6 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c if (strcmp(c->name, name) == 0) return c; return NULL; -@@ -232,7 +248,7 @@ const struct sshcipher * - cipher_by_number(int id) - { - const struct sshcipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (c->number == id) - return c; - return NULL; -@@ -273,7 +289,7 @@ cipher_number(const char *name) - const struct sshcipher *c; - if (name == NULL) - return -1; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcasecmp(c->name, name) == 0) - return c->number; - return -1; diff -up openssh-7.5p1/cipher-ctr.c.fips openssh-7.5p1/cipher-ctr.c --- openssh-7.5p1/cipher-ctr.c.fips 2017-06-30 12:06:36.386713974 +0200 +++ openssh-7.5p1/cipher-ctr.c 2017-06-30 12:06:36.465713761 +0200 @@ -471,16 +460,6 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -609,6 +619,9 @@ main(int ac, char **av) - "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { - switch (opt) { - case '1': -+ if (FIPS_mode()) { -+ fatal("Protocol 1 not allowed in the FIPS mode."); -+ } - options.protocol = SSH_PROTO_1; - break; - case '2': @@ -964,7 +977,6 @@ main(int ac, char **av) host_arg = xstrdup(host); @@ -500,19 +479,6 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1263,6 +1279,12 @@ main(int ac, char **av) - - timeout_ms = options.connection_timeout * 1000; - -+ if (FIPS_mode()) { -+ options.protocol &= SSH_PROTO_2; -+ if (options.protocol == 0) -+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); -+ } -+ - /* Open a connection to the remote host. */ - if (ssh_connect(host, addrs, &hostaddr, options.port, - options.address_family, options.connection_attempts, diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c --- openssh-7.5p1/sshconnect2.c.fips 2017-06-30 12:06:36.439713831 +0200 +++ openssh-7.5p1/sshconnect2.c 2017-06-30 12:06:36.469713750 +0200 @@ -686,9 +652,9 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c #include "crypto_api.h" @@ -58,6 +59,7 @@ + #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" - #include "xmalloc.h" +#include "log.h" /* openssh private key file format */ @@ -715,6 +681,6 @@ diff -up openssh-7.5p1/ssh-keygen.c.fips openssh-7.5p1/ssh-keygen.c + if (type == KEY_ED25519) + fatal("ED25519 keys are not allowed in FIPS mode"); + } - if (type == KEY_DSA && *bitsp != 1024) - fatal("DSA keys must be 1024 bits"); - else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) + switch (type) { + case KEY_DSA: + if (*bitsp != 1024) diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 0b7c186..8c0523b 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.gsskex 2016-12-23 13:38:53.685300997 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 13:38:53.725301005 +0100 -@@ -70,6 +70,7 @@ extern Authmethod method_passwd; +diff -up openssh/auth2.c.gsskex openssh/auth2.c +--- openssh/auth2.c.gsskex 2017-09-27 13:54:53.539534068 +0200 ++++ openssh/auth2.c 2017-09-27 13:54:53.590534348 +0200 +@@ -72,6 +72,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -9,7 +9,7 @@ diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c extern Authmethod method_gssapi; #endif -@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { +@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -17,9 +17,9 @@ diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c &method_gssapi, #endif &method_passwd, -diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1/auth2-gss.c.gsskex 2016-12-23 13:38:53.685300997 +0100 -+++ openssh-7.4p1/auth2-gss.c 2016-12-23 13:38:53.725301005 +0100 +diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c +--- openssh/auth2-gss.c.gsskex 2017-09-27 13:54:53.539534068 +0200 ++++ openssh/auth2-gss.c 2017-09-27 13:54:53.590534348 +0200 @@ -31,6 +31,7 @@ #include @@ -28,16 +28,17 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c #include "xmalloc.h" #include "key.h" -@@ -53,6 +54,40 @@ static int input_gssapi_mic(int type, u_ - static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); - static int input_gssapi_errtok(int, u_int32_t, void *); +@@ -53,6 +54,41 @@ static int input_gssapi_mic(int type, u_ + 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 *); +/* + * The 'gssapi_keyex' userauth mechanism. + */ +static int -+userauth_gsskeyex(Authctxt *authctxt) ++userauth_gsskeyex(struct ssh *ssh) +{ ++ Authctxt *authctxt = ssh->authctxt; + int authenticated = 0; + Buffer b; + gss_buffer_desc mic, gssbuf; @@ -69,7 +70,7 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -238,7 +273,8 @@ input_gssapi_exchange_complete(int type, +@@ -240,7 +275,8 @@ input_gssapi_exchange_complete(int type, packet_check_eom(); @@ -77,9 +78,9 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -281,7 +317,8 @@ input_gssapi_mic(int type, u_int32_t ple + if ((!use_privsep || mm_is_monitor()) && + (displayname = ssh_gssapi_displayname()) != NULL) +@@ -288,7 +324,8 @@ input_gssapi_mic(int type, u_int32_t ple gssbuf.length = buffer_len(&b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -89,7 +90,7 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -299,6 +336,12 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -310,6 +347,12 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } @@ -102,10 +103,21 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c ---- openssh-7.4p1/clientloop.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/clientloop.c 2016-12-23 13:38:53.725301005 +0100 -@@ -113,6 +113,10 @@ +diff -up openssh/auth.c.gsskex openssh/auth.c +--- openssh/auth.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/auth.c 2017-09-27 13:54:53.591534353 +0200 +@@ -395,6 +395,7 @@ auth_root_allowed(const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || ++ strcmp(method, "gssapi-keyex") == 0 || + strcmp(method, "gssapi-with-mic") == 0) + return 1; + break; +diff -up openssh/clientloop.c.gsskex openssh/clientloop.c +--- openssh/clientloop.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/clientloop.c 2017-09-27 13:54:53.591534353 +0200 +@@ -112,6 +112,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -116,13 +128,13 @@ diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c /* import options */ extern Options options; -@@ -1664,9 +1668,18 @@ client_loop(int have_pty, int escape_cha +@@ -1349,9 +1353,18 @@ client_loop(struct ssh *ssh, int have_pt break; /* Do channel operations unless rekeying in progress. */ -- if (!ssh_packet_is_rekeying(active_state)) -+ if (!ssh_packet_is_rekeying(active_state)) { - channel_after_select(readset, writeset); +- if (!ssh_packet_is_rekeying(ssh)) ++ if (!ssh_packet_is_rekeying(ssh)) { + channel_after_select(ssh, readset, writeset); +#ifdef GSSAPI + if (options.gss_renewal_rekey && @@ -136,10 +148,10 @@ diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c /* Buffer input from the connection. */ client_process_net_input(readset); -diff -up openssh-7.4p1/configure.ac.gsskex openssh-7.4p1/configure.ac ---- openssh-7.4p1/configure.ac.gsskex 2016-12-23 13:38:53.716301003 +0100 -+++ openssh-7.4p1/configure.ac 2016-12-23 13:38:53.726301005 +0100 -@@ -623,6 +623,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +diff -up openssh/configure.ac.gsskex openssh/configure.ac +--- openssh/configure.ac.gsskex 2017-09-27 13:54:53.581534298 +0200 ++++ openssh/configure.ac 2017-09-27 13:54:53.592534359 +0200 +@@ -621,6 +621,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -170,9 +182,9 @@ diff -up openssh-7.4p1/configure.ac.gsskex openssh-7.4p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-7.4p1/gss-genr.c.gsskex openssh-7.4p1/gss-genr.c ---- openssh-7.4p1/gss-genr.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-genr.c 2016-12-23 13:38:53.726301005 +0100 +diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +--- openssh/gss-genr.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-genr.c 2017-09-27 13:54:53.592534359 +0200 @@ -40,12 +40,167 @@ #include "buffer.h" #include "log.h" @@ -510,9 +522,9 @@ diff -up openssh-7.4p1/gss-genr.c.gsskex openssh-7.4p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c ---- openssh-7.4p1/gss-serv.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-serv.c 2016-12-23 13:38:53.727301005 +0100 +diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c +--- openssh/gss-serv.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-serv.c 2017-09-27 13:54:53.592534359 +0200 @@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" @@ -565,7 +577,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c void ssh_gssapi_supported_oids(gss_OID_set *oidset) { -@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o +@@ -151,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -576,7 +588,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -277,8 +304,48 @@ OM_uint32 +@@ -277,8 +303,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -598,8 +610,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + ssh_gssapi_error(ctx); + return (ctx->major); + } - -- gss_buffer_desc ename; ++ + ctx->major = gss_compare_name(&ctx->minor, client->name, + new_name, &equal); + @@ -614,7 +625,8 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + } + + debug("Marking rekeyed credentials for export"); -+ + +- gss_buffer_desc ename; + gss_release_name(&ctx->minor, &client->name); + gss_release_cred(&ctx->minor, &client->creds); + client->name = new_name; @@ -626,7 +638,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c client->mech = NULL; -@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -293,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -640,7 +652,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -310,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -649,7 +661,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -320,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -675,7 +687,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c } } -@@ -357,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int +@@ -357,7 +441,7 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -684,7 +696,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c { OM_uint32 lmin; -@@ -367,9 +452,11 @@ ssh_gssapi_userok(char *user) +@@ -367,9 +451,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -698,7 +710,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -383,14 +470,90 @@ ssh_gssapi_userok(char *user) +@@ -383,14 +469,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -794,10 +806,10 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + return ok; } - #endif -diff -up openssh-7.4p1/gss-serv-krb5.c.gsskex openssh-7.4p1/gss-serv-krb5.c ---- openssh-7.4p1/gss-serv-krb5.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 13:38:53.727301005 +0100 + /* Privileged */ +diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c +--- openssh/gss-serv-krb5.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-serv-krb5.c 2017-09-27 13:54:53.593534364 +0200 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -925,9 +937,9 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.gsskex openssh-7.4p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c ---- openssh-7.4p1/kex.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kex.c 2016-12-23 13:39:56.064313151 +0100 +diff -up openssh/kex.c.gsskex openssh/kex.c +--- openssh/kex.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/kex.c 2017-09-27 13:54:53.593534364 +0200 @@ -54,6 +54,10 @@ #include "sshbuf.h" #include "digest.h" @@ -936,10 +948,10 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c +#include "ssh-gss.h" +#endif + - #if OPENSSL_VERSION_NUMBER >= 0x00907000L - # if defined(HAVE_EVP_SHA256) - # define evp_ssh_sha256 EVP_sha256 -@@ -111,6 +115,11 @@ static const struct kexalg kexalgs[] = { + /* prototype */ + static int kex_choose_conf(struct ssh *); + static int kex_input_newkeys(int, u_int32_t, struct ssh *); +@@ -103,6 +107,11 @@ static const struct kexalg kexalgs[] = { { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -951,7 +963,7 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c { NULL, -1, -1, -1}, }; -@@ -144,6 +153,12 @@ kex_alg_by_name(const char *name) +@@ -136,6 +145,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -964,9 +976,9 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c } return NULL; } -diff -up openssh-7.4p1/kexgssc.c.gsskex openssh-7.4p1/kexgssc.c ---- openssh-7.4p1/kexgssc.c.gsskex 2016-12-23 13:38:53.727301005 +0100 -+++ openssh-7.4p1/kexgssc.c 2016-12-23 13:38:53.727301005 +0100 +diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c +--- openssh/kexgssc.c.gsskex 2017-09-27 13:54:53.593534364 +0200 ++++ openssh/kexgssc.c 2017-09-27 13:54:53.593534364 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1306,9 +1318,9 @@ diff -up openssh-7.4p1/kexgssc.c.gsskex openssh-7.4p1/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh-7.4p1/kexgsss.c.gsskex openssh-7.4p1/kexgsss.c ---- openssh-7.4p1/kexgsss.c.gsskex 2016-12-23 13:38:53.728301005 +0100 -+++ openssh-7.4p1/kexgsss.c 2016-12-23 13:38:53.728301005 +0100 +diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c +--- openssh/kexgsss.c.gsskex 2017-09-27 13:54:53.593534364 +0200 ++++ openssh/kexgsss.c 2017-09-27 13:54:53.593534364 +0200 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1607,9 +1619,9 @@ diff -up openssh-7.4p1/kexgsss.c.gsskex openssh-7.4p1/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh-7.4p1/kex.h.gsskex openssh-7.4p1/kex.h ---- openssh-7.4p1/kex.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kex.h 2016-12-23 13:38:53.728301005 +0100 +diff -up openssh/kex.h.gsskex openssh/kex.h +--- openssh/kex.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/kex.h 2017-09-27 13:54:53.593534364 +0200 @@ -99,6 +99,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, @@ -1646,11 +1658,11 @@ diff -up openssh-7.4p1/kex.h.gsskex openssh-7.4p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh-7.4p1/Makefile.in.gsskex openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.gsskex 2016-12-23 13:38:53.723301004 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 13:40:32.226320197 +0100 +diff -up openssh/Makefile.in.gsskex openssh/Makefile.in +--- openssh/Makefile.in.gsskex 2017-09-27 13:54:53.588534337 +0200 ++++ openssh/Makefile.in 2017-09-27 13:54:53.594534370 +0200 @@ -91,6 +91,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ + readpass.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ @@ -1666,9 +1678,9 @@ diff -up openssh-7.4p1/Makefile.in.gsskex openssh-7.4p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 13:45:49.347381091 +0100 +diff -up openssh/monitor.c.gsskex openssh/monitor.c +--- openssh/monitor.c.gsskex 2017-09-27 13:54:53.541534079 +0200 ++++ openssh/monitor.c 2017-09-27 13:54:53.594534370 +0200 @@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); @@ -1697,7 +1709,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -307,6 +316,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -308,6 +317,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1708,7 +1720,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -406,6 +419,10 @@ monitor_child_postauth(struct monitor *p +@@ -414,6 +427,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1719,7 +1731,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c if (!no_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1633,6 +1650,13 @@ monitor_apply_keystate(struct monitor *p +@@ -1656,6 +1673,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1733,7 +1745,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1712,7 +1736,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -1744,7 +1768,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -1742,7 +1754,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); goid.elements = buffer_get_string(m, &len); -@@ -1742,7 +1766,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -1774,7 +1798,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1751,7 +1763,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); in.value = buffer_get_string(m, &len); -@@ -1762,6 +1786,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -1794,6 +1818,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1759,7 +1771,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c } return (0); } -@@ -1773,7 +1798,7 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -1805,7 +1830,7 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -1768,9 +1780,9 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); gssbuf.value = buffer_get_string(m, &len); -@@ -1802,10 +1827,11 @@ mm_answer_gss_userok(int sock, Buffer *m - { +@@ -1835,10 +1860,11 @@ mm_answer_gss_userok(int sock, Buffer *m int authenticated; + const char *displayname; - if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) @@ -1782,7 +1794,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1818,5 +1844,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1854,5 +1880,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1856,9 +1868,9 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c + #endif /* GSSAPI */ -diff -up openssh-7.4p1/monitor.h.gsskex openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 13:38:53.729301005 +0100 +diff -up openssh/monitor.h.gsskex openssh/monitor.h +--- openssh/monitor.h.gsskex 2017-09-27 13:54:53.541534079 +0200 ++++ openssh/monitor.h 2017-09-27 13:54:53.594534370 +0200 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1868,10 +1880,10 @@ diff -up openssh-7.4p1/monitor.h.gsskex openssh-7.4p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 13:38:53.729301005 +0100 -@@ -943,7 +943,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.gsskex 2017-09-27 13:54:53.542534084 +0200 ++++ openssh/monitor_wrap.c 2017-09-27 13:54:53.595534375 +0200 +@@ -950,7 +950,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1880,7 +1892,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -960,5 +960,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -967,5 +967,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1931,10 +1943,10 @@ diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh-7.4p1/monitor_wrap.h.gsskex openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 13:38:53.729301005 +0100 -@@ -58,8 +58,10 @@ int mm_key_verify(Key *, u_char *, u_int +diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.gsskex 2017-09-27 13:54:53.542534084 +0200 ++++ openssh/monitor_wrap.h 2017-09-27 13:54:53.595534375 +0200 +@@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1946,9 +1958,9 @@ diff -up openssh-7.4p1/monitor_wrap.h.gsskex openssh-7.4p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c ---- openssh-7.4p1/readconf.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/readconf.c 2016-12-23 13:38:53.730301005 +0100 +diff -up openssh/readconf.c.gsskex openssh/readconf.c +--- openssh/readconf.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/readconf.c 2017-09-27 13:54:53.596534381 +0200 @@ -160,6 +160,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, @@ -1958,7 +1970,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -205,10 +207,19 @@ static struct { +@@ -199,10 +201,19 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1978,7 +1990,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c #endif #ifdef ENABLE_PKCS11 { "smartcarddevice", oPKCS11Provider }, -@@ -961,10 +972,30 @@ parse_time: +@@ -976,10 +987,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2009,7 +2021,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1776,7 +1807,12 @@ initialize_options(Options * options) +@@ -1790,7 +1821,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2022,7 +2034,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1920,8 +1956,14 @@ fill_default_options(Options * options) +@@ -1930,8 +1966,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2037,10 +2049,10 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-7.4p1/readconf.h.gsskex openssh-7.4p1/readconf.h ---- openssh-7.4p1/readconf.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/readconf.h 2016-12-23 13:38:53.730301005 +0100 -@@ -45,7 +45,12 @@ typedef struct { +diff -up openssh/readconf.h.gsskex openssh/readconf.h +--- openssh/readconf.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/readconf.h 2017-09-27 13:54:53.596534381 +0200 +@@ -42,7 +42,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -2053,9 +2065,9 @@ diff -up openssh-7.4p1/readconf.h.gsskex openssh-7.4p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-7.4p1/regress/cert-hostkey.sh.gsskex openssh-7.4p1/regress/cert-hostkey.sh ---- openssh-7.4p1/regress/cert-hostkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/cert-hostkey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh +--- openssh/regress/cert-hostkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/cert-hostkey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -59,7 +59,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca @@ -2065,9 +2077,9 @@ diff -up openssh-7.4p1/regress/cert-hostkey.sh.gsskex openssh-7.4p1/regress/cert if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh-7.4p1/regress/cert-userkey.sh.gsskex openssh-7.4p1/regress/cert-userkey.sh ---- openssh-7.4p1/regress/cert-userkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/cert-userkey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh +--- openssh/regress/cert-userkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/cert-userkey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2077,9 +2089,9 @@ diff -up openssh-7.4p1/regress/cert-userkey.sh.gsskex openssh-7.4p1/regress/cert if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh-7.4p1/regress/kextype.sh.gsskex openssh-7.4p1/regress/kextype.sh ---- openssh-7.4p1/regress/kextype.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/kextype.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh +--- openssh/regress/kextype.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/kextype.sh 2017-09-27 13:54:53.596534381 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2090,9 +2102,9 @@ diff -up openssh-7.4p1/regress/kextype.sh.gsskex openssh-7.4p1/regress/kextype.s verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh-7.4p1/regress/rekey.sh.gsskex openssh-7.4p1/regress/rekey.sh ---- openssh-7.4p1/regress/rekey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/rekey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh +--- openssh/regress/rekey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/rekey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2113,9 +2125,9 @@ diff -up openssh-7.4p1/regress/rekey.sh.gsskex openssh-7.4p1/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.gsskex 2016-12-23 13:38:53.717301003 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 13:38:53.732301006 +0100 +diff -up openssh/servconf.c.gsskex openssh/servconf.c +--- openssh/servconf.c.gsskex 2017-09-27 13:54:53.581534298 +0200 ++++ openssh/servconf.c 2017-09-27 13:54:53.597534386 +0200 @@ -113,8 +113,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -2127,7 +2139,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -268,10 +270,14 @@ fill_default_server_options(ServerOption +@@ -269,10 +271,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2142,7 +2154,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -410,7 +416,7 @@ typedef enum { +@@ -413,7 +419,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -2151,7 +2163,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -484,11 +490,17 @@ static struct { +@@ -488,11 +494,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2169,7 +2181,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1211,6 +1223,10 @@ process_server_config_line(ServerOptions +@@ -1257,6 +1269,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2180,7 +2192,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1219,6 +1235,10 @@ process_server_config_line(ServerOptions +@@ -1265,6 +1281,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2191,7 +2203,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2257,6 +2277,9 @@ dump_config(ServerOptions *o) +@@ -2302,6 +2322,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2201,10 +2213,10 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-7.4p1/servconf.h.gsskex openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.gsskex 2016-12-23 13:38:53.717301003 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 13:38:53.732301006 +0100 -@@ -112,8 +112,10 @@ typedef struct { +diff -up openssh/servconf.h.gsskex openssh/servconf.h +--- openssh/servconf.h.gsskex 2017-09-27 13:54:53.582534304 +0200 ++++ openssh/servconf.h 2017-09-27 13:54:53.597534386 +0200 +@@ -119,8 +119,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2215,10 +2227,10 @@ diff -up openssh-7.4p1/servconf.h.gsskex openssh-7.4p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-7.4p1/ssh_config.5.gsskex openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1/ssh_config.5.gsskex 2016-12-23 13:38:53.732301006 +0100 -+++ openssh-7.4p1/ssh_config.5 2016-12-23 13:48:00.502331870 +0100 -@@ -748,10 +748,40 @@ The default is +diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 +--- openssh/ssh_config.5.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh_config.5 2017-09-27 13:54:53.597534386 +0200 +@@ -720,10 +720,40 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -2259,10 +2271,10 @@ diff -up openssh-7.4p1/ssh_config.5.gsskex openssh-7.4p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-7.4p1/ssh_config.gsskex openssh-7.4p1/ssh_config ---- openssh-7.4p1/ssh_config.gsskex 2016-12-23 13:38:53.708301001 +0100 -+++ openssh-7.4p1/ssh_config 2016-12-23 13:38:53.733301006 +0100 -@@ -26,6 +26,8 @@ +diff -up openssh/ssh_config.gsskex openssh/ssh_config +--- openssh/ssh_config.gsskex 2017-09-27 13:54:53.571534243 +0200 ++++ openssh/ssh_config 2017-09-27 13:54:53.597534386 +0200 +@@ -24,6 +24,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no @@ -2271,10 +2283,135 @@ diff -up openssh-7.4p1/ssh_config.gsskex openssh-7.4p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 13:38:53.733301006 +0100 -@@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c +--- openssh/sshconnect2.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshconnect2.c 2017-09-27 13:57:23.418358207 +0200 +@@ -82,6 +82,124 @@ extern char *client_version_string; + extern char *server_version_string; + extern Options options; + ++/* XXX from auth.h -- refactoring move these useful functions away of client context*/ ++ ++/* ++ * 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 legacy rhosts-style authentication. ++ * XXX is RhostsRSAAuthentication vulnerable to these? ++ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) ++ */ ++ ++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) < 0) { ++ debug("getpeername failed: %.100s", strerror(errno)); ++ return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); ++ } ++ return strdup(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. ++ */ ++ ++const char * ++get_canonical_hostname(struct ssh *ssh, int use_dns) ++{ ++ static char *dnsname; ++ ++ if (!use_dns) ++ return ssh_remote_ipaddr(ssh); ++ else if (dnsname != NULL) ++ return dnsname; ++ else { ++ dnsname = remote_hostname(ssh); ++ return dnsname; ++ } ++} ++ ++ ++ + /* + * SSH2 key exchange + */ +@@ -162,9 +280,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2309,7 +2446,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -192,6 +217,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -192,6 +335,17 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2327,7 +2464,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, options.rekey_interval); -@@ -212,11 +248,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -212,11 +366,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2356,18 +2493,18 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c + } +#endif + - dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); + ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); /* remove ext-info from the KEX proposals for rekeying */ -@@ -311,6 +367,7 @@ int input_gssapi_token(int type, u_int32 - int input_gssapi_hash(int type, u_int32_t, void *); - int input_gssapi_error(int, u_int32_t, void *); - int input_gssapi_errtok(int, u_int32_t, void *); +@@ -311,6 +485,7 @@ int input_gssapi_token(int type, u_int32 + int input_gssapi_hash(int type, u_int32_t, struct ssh *); + int input_gssapi_error(int, u_int32_t, struct ssh *); + int input_gssapi_errtok(int, u_int32_t, struct ssh *); +int userauth_gsskeyex(Authctxt *authctxt); #endif void userauth(Authctxt *, char *); -@@ -327,6 +384,11 @@ static char *authmethods_get(void); +@@ -327,6 +502,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2379,7 +2516,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -652,19 +714,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -654,19 +834,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2413,9 +2550,9 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -761,8 +835,8 @@ input_gssapi_response(int type, u_int32_ +@@ -763,8 +955,8 @@ input_gssapi_response(int type, u_int32_ { - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; - int oidlen; - char *oidv; @@ -2424,7 +2561,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -875,6 +949,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -877,6 +1069,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); return 0; } @@ -2473,10 +2610,10 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c ---- openssh-7.2p1/sshd.c.gsskex 2016-02-19 10:01:04.860969328 +0100 -+++ openssh-7.2p1/sshd.c 2016-02-19 10:01:04.872969321 +0100 -@@ -547,7 +547,7 @@ privsep_preauth_child(void) +diff -up openssh/sshd.c.gsskex openssh/sshd.c +--- openssh/sshd.c.gsskex 2017-09-27 13:54:53.584534315 +0200 ++++ openssh/sshd.c 2017-09-27 13:54:53.600534403 +0200 +@@ -530,7 +530,7 @@ privsep_preauth_child(void) #ifdef GSSAPI /* Cache supported mechanism OIDs for later use */ @@ -2485,7 +2622,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c ssh_gssapi_prepare_supported_oids(); #endif -@@ -974,8 +974,9 @@ notify_hostkeys(struct ssh *ssh) +@@ -871,8 +871,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %d hostkeys", __func__, nkeys); if (nkeys == 0) @@ -2497,7 +2634,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c sshbuf_free(buf); } -@@ -1739,7 +1740,8 @@ main(int ac, char **av) +@@ -1738,7 +1739,8 @@ main(int ac, char **av) key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); free(fp); } @@ -2507,7 +2644,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c logit("sshd: no hostkeys available -- exiting."); exit(1); } -@@ -2196,6 +2198,48 @@ do_ssh2_kex(void) +@@ -2203,6 +2205,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2556,7 +2693,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2213,6 +2257,13 @@ do_ssh2_kex(void) +@@ -2220,6 +2264,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2570,10 +2707,10 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.gsskex 2016-12-23 13:38:53.734301006 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:48:57.825310358 +0100 -@@ -628,6 +628,11 @@ Specifies whether to automatically destr +diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 +--- openssh/sshd_config.5.gsskex 2017-09-27 13:54:53.582534304 +0200 ++++ openssh/sshd_config.5 2017-09-27 13:54:53.600534403 +0200 +@@ -638,6 +638,11 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -2585,7 +2722,7 @@ diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -642,6 +647,11 @@ machine's default store. +@@ -652,6 +657,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -2597,10 +2734,10 @@ diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -diff -up openssh-7.4p1/sshd_config.gsskex openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.gsskex 2016-12-23 13:38:53.719301003 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 13:38:53.734301006 +0100 -@@ -77,6 +77,8 @@ ChallengeResponseAuthentication no +diff -up openssh/sshd_config.gsskex openssh/sshd_config +--- openssh/sshd_config.gsskex 2017-09-27 13:54:53.585534320 +0200 ++++ openssh/sshd_config 2017-09-27 13:54:53.601534408 +0200 +@@ -86,6 +86,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes GSSAPICleanupCredentials no @@ -2609,11 +2746,11 @@ diff -up openssh-7.4p1/sshd_config.gsskex 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-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h ---- openssh-7.4p1/ssh-gss.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-gss.h 2016-12-23 13:38:53.734301006 +0100 +diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h +--- openssh/ssh-gss.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh-gss.h 2017-09-27 13:54:53.601534408 +0200 @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.12 2017/06/24 06:34:38 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2676,7 +2813,7 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); +@@ -119,17 +136,33 @@ void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); @@ -2701,6 +2838,7 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); void ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); +char *ssh_gssapi_server_mechanisms(void); +int ssh_gssapi_oid_table_ok(); @@ -2711,10 +2849,10 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -up openssh-7.4p1/sshkey.c.gsskex openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 13:38:53.735301006 +0100 -@@ -114,6 +114,7 @@ static const struct keytype keytypes[] = +diff -up openssh/sshkey.c.gsskex openssh/sshkey.c +--- openssh/sshkey.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshkey.c 2017-09-27 13:54:53.601534408 +0200 +@@ -112,6 +112,7 @@ static const struct keytype keytypes[] = # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2722,10 +2860,10 @@ diff -up openssh-7.4p1/sshkey.c.gsskex openssh-7.4p1/sshkey.c { NULL, NULL, -1, -1, 0, 0 } }; -diff -up openssh-7.4p1/sshkey.h.gsskex openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 13:38:53.735301006 +0100 -@@ -62,6 +62,7 @@ enum sshkey_types { +diff -up openssh/sshkey.h.gsskex openssh/sshkey.h +--- openssh/sshkey.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshkey.h 2017-09-27 13:54:53.602534414 +0200 +@@ -61,6 +61,7 @@ enum sshkey_types { KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, @@ -2733,268 +2871,3 @@ diff -up openssh-7.4p1/sshkey.h.gsskex openssh-7.4p1/sshkey.h KEY_UNSPEC }; -diff -up openssh-7.4p1/auth.c.gsskex openssh-7.4p1/auth.c ---- openssh-7.4p1/auth.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth.c 2016-12-23 13:38:53.735301006 +0100 -@@ -372,6 +372,7 @@ auth_root_allowed(const char *method) - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -+ strcmp(method, "gssapi-keyex") == 0 || - strcmp(method, "gssapi-with-mic") == 0) - return 1; - break; -@@ -795,99 +796,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 legacy rhosts-style authentication. -- * XXX is RhostsRSAAuthentication vulnerable to these? -- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) -- */ -- --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) < 0) { -- debug("getpeername failed: %.100s", strerror(errno)); -- return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); -- } -- return strdup(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 -up openssh-7.4p1/openbsd-compat/port-linux.c.gsskex openssh-7.4p1/openbsd-compat/port-linux.c ---- openssh-7.4p1/openbsd-compat/port-linux.c.gsskex 2016-12-23 13:38:53.688300997 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.c 2016-12-23 13:38:53.735301006 +0100 -@@ -30,6 +30,8 @@ - #include "log.h" - #include "xmalloc.h" - #include "port-linux.h" -+#include "canohost.h" -+#include "misc.h" - - #ifdef WITH_SELINUX - #include -@@ -279,4 +281,121 @@ oom_adjust_restore(void) - return; - } - #endif /* LINUX_OOM_ADJUST */ -+ -+/**************** XXX moved from auth.c ****************/ -+ -+/* -+ * 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 legacy rhosts-style authentication. -+ * XXX is RhostsRSAAuthentication vulnerable to these? -+ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) -+ */ -+ -+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) < 0) { -+ debug("getpeername failed: %.100s", strerror(errno)); -+ return strdup(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 strdup(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 strdup(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 - POSSIBLE BREAK-IN ATTEMPT!", name, ntop); -+ return strdup(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 - POSSIBLE BREAK-IN ATTEMPT!", -+ ntop, name); -+ return strdup(ntop); -+ } -+ return strdup(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. -+ */ -+ -+const char * -+get_canonical_hostname(struct ssh *ssh, int use_dns) -+{ -+ static char *dnsname; -+ -+ if (!use_dns) -+ return ssh_remote_ipaddr(ssh); -+ else if (dnsname != NULL) -+ return dnsname; -+ else { -+ dnsname = remote_hostname(ssh); -+ return dnsname; -+ } -+} - #endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff -up openssh-7.4p1/openbsd-compat/port-linux.h.gsskex openssh-7.4p1/openbsd-compat/port-linux.h ---- openssh-7.4p1/openbsd-compat/port-linux.h.gsskex 2016-12-23 13:38:53.712301002 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 13:38:53.735301006 +0100 -@@ -16,6 +16,7 @@ - - #ifndef _PORT_LINUX_H - #define _PORT_LINUX_H -+#include "packet.h" - - #ifdef WITH_SELINUX - int ssh_selinux_enabled(void); -@@ -36,4 +37,8 @@ void oom_adjust_setup(void); - - void linux_seed(void); - -+const char *get_canonical_hostname(struct ssh *, int); -+char *remote_hostname(struct ssh *); -+ -+ - #endif /* ! _PORT_LINUX_H */ diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch deleted file mode 100644 index 91428c3..0000000 --- a/openssh-7.2p2-expose-pam.patch +++ /dev/null @@ -1,517 +0,0 @@ -diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.expose-pam 2016-12-23 15:40:26.768447868 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 15:40:26.818447876 +0100 -@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int - { - struct ssh *ssh = active_state; /* XXX */ - char *methods; -+ char *prev_auth_details; - int partial = 0; - - if (!authctxt->valid && authenticated) -@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int - if (authctxt->postponed) - return; - -+ if (authenticated || partial) { -+ prev_auth_details = authctxt->auth_details; -+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", -+ prev_auth_details ? prev_auth_details : "", -+ prev_auth_details ? ", " : "", method, -+ authctxt->last_details ? ": " : "", -+ authctxt->last_details ? authctxt->last_details : ""); -+ free(prev_auth_details); -+ } -+ free(authctxt->last_details); -+ authctxt->last_details = NULL; -+ - #ifdef USE_PAM - if (options.use_pam && authenticated) { - if (!PRIVSEP(do_pam_account())) { -diff -up openssh-7.4p1/auth2-gss.c.expose-pam openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1/auth2-gss.c.expose-pam 2016-12-23 15:40:26.769447868 +0100 -+++ openssh-7.4p1/auth2-gss.c 2016-12-23 15:40:26.818447876 +0100 -@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw)); - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); -@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple - else - logit("GSSAPI MIC check failed"); - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - buffer_free(&b); - if (micuser != authctxt->user) - free(micuser); -diff -up openssh-7.4p1/auth2-hostbased.c.expose-pam openssh-7.4p1/auth2-hostbased.c ---- openssh-7.4p1/auth2-hostbased.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 -+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 15:40:26.818447876 +0100 -@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) - { - Buffer b; - Key *key = NULL; -- char *pkalg, *cuser, *chost, *service; -+ char *pkalg, *cuser, *chost, *service, *pubkey; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int pktype; -@@ -140,15 +140,21 @@ userauth_hostbased(Authctxt *authctxt) - buffer_dump(&b); - #endif - -- pubkey_auth_info(authctxt, key, -- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, -+ "%s, client user \"%.100s\", client host \"%.100s\"", -+ pubkey, cuser, chost); - - /* test for allowed key and correct signature */ - authenticated = 0; - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), -- buffer_len(&b))) == 1) -+ buffer_len(&b))) == 1) { - authenticated = 1; -+ authctxt->last_details = pubkey; -+ } else { -+ free(pubkey); -+ } - - buffer_free(&b); - done: -diff -up openssh-7.4p1/auth2-pubkey.c.expose-pam openssh-7.4p1/auth2-pubkey.c ---- openssh-7.4p1/auth2-pubkey.c.expose-pam 2016-12-23 15:40:26.746447864 +0100 -+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 15:40:26.819447876 +0100 -@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) - { - Buffer b; - Key *key = NULL; -- char *pkalg, *userstyle, *fp = NULL; -+ char *pkalg, *userstyle, *pubkey, *fp = NULL; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int have_sig, pktype; -@@ -177,7 +177,8 @@ userauth_pubkey(Authctxt *authctxt) - #ifdef DEBUG_PK - buffer_dump(&b); - #endif -- pubkey_auth_info(authctxt, key, NULL); -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, "%s", pubkey); - - /* test for correct signature */ - authenticated = 0; -@@ -185,9 +186,12 @@ userauth_pubkey(Authctxt *authctxt) - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) { - authenticated = 1; -+ authctxt->last_details = pubkey; - /* Record the successful key to prevent reuse */ - auth2_record_userkey(authctxt, key); - key = NULL; /* Don't free below */ -+ } else { -+ free(pubkey); - } - buffer_free(&b); - free(sig); -@@ -228,7 +232,7 @@ done: - void - pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) - { -- char *fp, *extra; -+ char *extra, *pubkey; - va_list ap; - int i; - -@@ -238,27 +242,13 @@ pubkey_auth_info(Authctxt *authctxt, con - i = vasprintf(&extra, fmt, ap); - va_end(ap); - if (i < 0 || extra == NULL) -- fatal("%s: vasprintf failed", __func__); -+ fatal("%s: vasprintf failed", __func__); - } - -- if (key_is_cert(key)) { -- fp = sshkey_fingerprint(key->cert->signature_key, -- options.fingerprint_hash, SSH_FP_DEFAULT); -- auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", -- key_type(key), key->cert->key_id, -- (unsigned long long)key->cert->serial, -- key_type(key->cert->signature_key), -- fp == NULL ? "(null)" : fp, -- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); -- free(fp); -- } else { -- fp = sshkey_fingerprint(key, options.fingerprint_hash, -- SSH_FP_DEFAULT); -- auth_info(authctxt, "%s %s%s%s", key_type(key), -- fp == NULL ? "(null)" : fp, -- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); -- free(fp); -- } -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", -+ extra == NULL ? "" : extra); -+ free(pubkey); - free(extra); - } - -diff -up openssh-7.4p1/auth.h.expose-pam openssh-7.4p1/auth.h ---- openssh-7.4p1/auth.h.expose-pam 2016-12-23 15:40:26.782447870 +0100 -+++ openssh-7.4p1/auth.h 2016-12-23 15:40:26.819447876 +0100 -@@ -84,6 +84,9 @@ struct Authctxt { - - struct sshkey **prev_userkeys; - u_int nprev_userkeys; -+ -+ char *last_details; -+ char *auth_details; - }; - /* - * Every authentication method has to handle authentication requests for -diff -up openssh-7.4p1/auth-pam.c.expose-pam openssh-7.4p1/auth-pam.c ---- openssh-7.4p1/auth-pam.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 -+++ openssh-7.4p1/auth-pam.c 2016-12-23 15:40:26.819447876 +0100 -@@ -688,6 +688,11 @@ sshpam_init_ctx(Authctxt *authctxt) - return (NULL); - } - -+ /* Notify PAM about any already successful auth methods */ -+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY && -+ authctxt->auth_details) -+ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); -+ - ctxt = xcalloc(1, sizeof *ctxt); - - /* Start the authentication thread */ -diff -up openssh-7.4p1/gss-serv.c.expose-pam openssh-7.4p1/gss-serv.c ---- openssh-7.4p1/gss-serv.c.expose-pam 2016-12-23 15:40:26.808447874 +0100 -+++ openssh-7.4p1/gss-serv.c 2016-12-23 15:40:26.819447876 +0100 -@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int - } - - /* Privileged */ -+char* -+ssh_gssapi_get_displayname(void) -+{ -+ if (gssapi_client.displayname.length != 0 && -+ gssapi_client.displayname.value != NULL) -+ return strdup((char *)gssapi_client.displayname.value); -+ return NULL; -+} -+ -+/* Privileged */ - int - ssh_gssapi_userok(char *user, struct passwd *pw) - { -diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 15:41:16.473455863 +0100 -@@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx - struct ssh *ssh = active_state; /* XXX */ - struct mon_table *ent; - int authenticated = 0, partial = 0; -+ char *prev_auth_details; - - debug3("preauth child monitor started"); - -@@ -330,6 +331,18 @@ monitor_child_preauth(Authctxt *_authctx - auth_submethod = NULL; - authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); - -+ if (authenticated) { -+ prev_auth_details = authctxt->auth_details; -+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", -+ prev_auth_details ? prev_auth_details : "", -+ prev_auth_details ? ", " : "", auth_method, -+ authctxt->last_details ? ": " : "", -+ authctxt->last_details ? authctxt->last_details : ""); -+ free(prev_auth_details); -+ } -+ free(authctxt->last_details); -+ authctxt->last_details = NULL; -+ - /* Special handling for multiple required authentications */ - if (options.num_auth_methods != 0) { - if (authenticated && -@@ -1417,6 +1430,10 @@ mm_answer_keyverify(int sock, Buffer *m) - debug3("%s: key %p signature %s", - __func__, key, (verified == 1) ? "verified" : "unverified"); - -+ if (verified == 1) -+ authctxt->last_details = sshkey_format_oneline(key, -+ options.fingerprint_hash); -+ - /* If auth was successful then record key to ensure it isn't reused */ - if (verified == 1 && key_blobtype == MM_USERKEY) - auth2_record_userkey(authctxt, key); -@@ -1860,6 +1877,9 @@ mm_answer_gss_userok(int sock, Buffer *m - - auth_method = "gssapi-with-mic"; - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - /* Monitor loop will terminate if authenticated */ - return (authenticated); - } -diff -up openssh-7.4p1/servconf.c.expose-pam openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:44:04.691482920 +0100 -@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions - options->disable_forwarding = -1; - options->use_kuserok = -1; - options->enable_k5users = -1; -+ options->expose_auth_methods = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -354,6 +355,8 @@ fill_default_server_options(ServerOption - options->use_kuserok = 1; - if (options->enable_k5users == -1) - options->enable_k5users = 0; -+ if (options->expose_auth_methods == -1) -+ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; - - assemble_algorithms(options); - -@@ -439,6 +442,7 @@ typedef enum { - sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, - sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, -+ sExposeAuthenticationMethods, - sDeprecated, sIgnore, sUnsupported - } ServerOpCodes; - -@@ -595,6 +599,7 @@ static struct { - { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, - { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, - { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, -+ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, - { NULL, sBadOption, 0 } - }; - -@@ -984,6 +989,12 @@ static const struct multistate multistat - { "local", FORWARD_LOCAL }, - { NULL, -1 } - }; -+static const struct multistate multistate_exposeauthmeth[] = { -+ { "never", EXPOSE_AUTHMETH_NEVER }, -+ { "pam-only", EXPOSE_AUTHMETH_PAMONLY }, -+ { "pam-and-env", EXPOSE_AUTHMETH_PAMENV }, -+ { NULL, -1} -+}; - - int - process_server_config_line(ServerOptions *options, char *line, -@@ -1902,6 +1913,11 @@ process_server_config_line(ServerOptions - options->fingerprint_hash = value; - break; - -+ case sExposeAuthenticationMethods: -+ intptr = &options->expose_auth_methods; -+ multistate_ptr = multistate_exposeauthmeth; -+ goto parse_multistate; -+ - case sDeprecated: - case sIgnore: - case sUnsupported: -@@ -2060,6 +2076,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(enable_k5users); - M_CP_INTOPT(rekey_limit); - M_CP_INTOPT(rekey_interval); -+ M_CP_INTOPT(expose_auth_methods); - - /* - * The bind_mask is a mode_t that may be unsigned, so we can't use -@@ -2176,6 +2193,8 @@ fmt_intarg(ServerOpCodes code, int val) - return fmt_multistate_int(val, multistate_tcpfwd); - case sFingerprintHash: - return ssh_digest_alg_name(val); -+ case sExposeAuthenticationMethods: -+ return fmt_multistate_int(val, multistate_exposeauthmeth); - default: - switch (val) { - case 0: -@@ -2356,6 +2375,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); - dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); -+ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-7.4p1/servconf.h.expose-pam openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 15:40:26.821447876 +0100 -@@ -48,6 +48,11 @@ - #define FORWARD_LOCAL (1<<1) - #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) - -+/* Expose AuthenticationMethods */ -+#define EXPOSE_AUTHMETH_NEVER 0 -+#define EXPOSE_AUTHMETH_PAMONLY 1 -+#define EXPOSE_AUTHMETH_PAMENV 2 -+ - #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ - #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ - -@@ -195,6 +200,8 @@ typedef struct { - char *auth_methods[MAX_AUTH_METHODS]; - - int fingerprint_hash; -+ -+ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ - } ServerOptions; - - /* Information about the incoming connection as used by Match */ -diff -up openssh-7.4p1/session.c.expose-pam openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:40:26.821447876 +0100 -@@ -997,6 +997,12 @@ copy_environment(char **source, char *** - } - *var_val++ = '\0'; - -+ if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV && -+ strcmp(var_name, "SSH_USER_AUTH") == 0) { -+ free(var_name); -+ continue; -+ } -+ - debug3("Copy environment: %s=%s", var_name, var_val); - child_set_env(env, envsize, var_name, var_val); - -@@ -1173,6 +1179,11 @@ do_setup_env(Session *s, const char *she - } - #endif /* USE_PAM */ - -+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV && -+ s->authctxt->auth_details) -+ child_set_env(&env, &envsize, "SSH_USER_AUTH", -+ s->authctxt->auth_details); -+ - if (auth_sock_name != NULL) - child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, - auth_sock_name); -@@ -2561,6 +2572,9 @@ do_cleanup(Authctxt *authctxt) - if (authctxt == NULL) - return; - -+ free(authctxt->auth_details); -+ authctxt->auth_details = NULL; -+ - #ifdef USE_PAM - if (options.use_pam) { - sshpam_cleanup(); -diff -up openssh-7.4p1/ssh.1.expose-pam openssh-7.4p1/ssh.1 ---- openssh-7.4p1/ssh.1.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/ssh.1 2016-12-23 15:40:26.822447877 +0100 -@@ -1421,6 +1421,10 @@ server IP address, and server port numbe - This variable contains the original command line if a forced command - is executed. - It can be used to extract the original arguments. -+.It Ev SSH_USER_AUTH -+This variable contains, for SSH2 only, a comma-separated list of authentication -+methods that were successfuly used to authenticate. When possible, these -+methods are extended with detailed information on the credential used. - .It Ev SSH_TTY - This is set to the name of the tty (path to the device) associated - with the current shell or command. -diff -up openssh-7.4p1/sshd_config.5.expose-pam openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.expose-pam 2016-12-23 15:40:26.822447877 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:45:22.411495421 +0100 -@@ -570,6 +570,21 @@ Disables all forwarding features, includ - TCP and StreamLocal. - This option overrides all other forwarding-related options and may - simplify restricted configurations. -+.It Cm ExposeAuthenticationMethods -+When using SSH2, this option controls the exposure of the list of -+successful authentication methods to PAM during the authentication -+and to the shell environment via the -+.Cm SSH_USER_AUTH -+variable. See the description of this variable for more details. -+Valid options are: -+.Cm never -+(Do not expose successful authentication methods), -+.Cm pam-only -+(Only expose them to PAM during authentication, not afterwards), -+.Cm pam-and-env -+(Expose them to PAM and keep them in the shell environment). -+The default is -+.Cm never . - .It Cm FingerprintHash - Specifies the hash algorithm used when logging key fingerprints. - Valid options are: -diff -up openssh-7.4p1/ssh-gss.h.expose-pam openssh-7.4p1/ssh-gss.h ---- openssh-7.4p1/ssh-gss.h.expose-pam 2016-12-23 15:40:26.811447875 +0100 -+++ openssh-7.4p1/ssh-gss.h 2016-12-23 15:40:26.823447877 +0100 -@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt - const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); - int ssh_gssapi_userok(char *name, struct passwd *); -+char* ssh_gssapi_get_displayname(void); - 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); -diff -up openssh-7.4p1/sshkey.c.expose-pam openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.expose-pam 2016-12-23 15:40:26.777447869 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 15:40:26.823447877 +0100 -@@ -57,6 +57,7 @@ - #define SSHKEY_INTERNAL - #include "sshkey.h" - #include "match.h" -+#include "xmalloc.h" - - /* openssh private key file format */ - #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" -@@ -1191,6 +1192,30 @@ sshkey_fingerprint(const struct sshkey * - return retval; - } - -+char * -+sshkey_format_oneline(const struct sshkey *key, int dgst_alg) -+{ -+ char *fp, *result; -+ -+ if (sshkey_is_cert(key)) { -+ fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg, -+ SSH_FP_DEFAULT); -+ xasprintf(&result, "%s ID %s (serial %llu) CA %s %s", -+ sshkey_type(key), key->cert->key_id, -+ (unsigned long long)key->cert->serial, -+ sshkey_type(key->cert->signature_key), -+ fp == NULL ? "(null)" : fp); -+ free(fp); -+ } else { -+ fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT); -+ xasprintf(&result, "%s %s", sshkey_type(key), -+ fp == NULL ? "(null)" : fp); -+ free(fp); -+ } -+ -+ return result; -+} -+ - #ifdef WITH_SSH1 - /* - * Reads a multiple-precision integer in decimal from the buffer, and advances -diff -up openssh-7.4p1/sshkey.h.expose-pam openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.expose-pam 2016-12-23 15:40:26.777447869 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 15:40:26.823447877 +0100 -@@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s - int, enum sshkey_fp_rep); - int sshkey_fingerprint_raw(const struct sshkey *k, - int, u_char **retp, size_t *lenp); -+char *sshkey_format_oneline(const struct sshkey *k, int dgst_alg); - const char *sshkey_type(const struct sshkey *); - const char *sshkey_cert_type(const struct sshkey *); - int sshkey_write(const struct sshkey *, FILE *); diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 99ed90f..8efda19 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -1,103 +1,7 @@ -diff -up openssh-7.4p1/authfd.c.openssl openssh-7.4p1/authfd.c ---- openssh-7.4p1/authfd.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/authfd.c 2016-12-23 17:47:36.429817751 +0100 -@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids - int r, keybits; - u_int32_t bits; - char *comment = NULL; -+ BIGNUM *e = NULL, *n = NULL; - - if ((key = sshkey_new(KEY_RSA1)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if ((r = sshbuf_get_u32(ids, &bits)) != 0 || -- (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || -- (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) -+ if ((e = BN_new()) == NULL || -+ (n = BN_new()) == NULL || -+ (r = sshbuf_get_u32(ids, &bits)) != 0 || -+ (r = sshbuf_get_bignum1(ids, e)) != 0 || -+ (r = sshbuf_get_bignum1(ids, n)) != 0 || -+ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0 || -+ (RSA_set0_key(key->rsa, n, e, NULL) == 0)) { -+ BN_free(n); -+ BN_free(e); - goto out; -- keybits = BN_num_bits(key->rsa->n); -+ } -+ keybits = BN_num_bits(n); - /* XXX previously we just warned here. I think we should be strict */ - if (keybits < 0 || bits != (u_int)keybits) { - r = SSH_ERR_KEY_BITS_MISMATCH; -@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct s - struct sshbuf *msg; - int r; - u_char type; -+ const BIGNUM *e, *n; - - if (key->type != KEY_RSA1) - return SSH_ERR_INVALID_ARGUMENT; - if ((msg = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; -+ RSA_get0_key(key->rsa, &n, &e, NULL); - if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || -- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || -+ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, n)) != 0 || - (r = sshbuf_put_bignum1(msg, challenge)) != 0 || - (r = sshbuf_put(msg, session_id, 16)) != 0 || - (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ -@@ -499,15 +508,19 @@ static int - ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) - { - int r; -+ const BIGNUM *n, *e, *d, *q, *p, *iqmp; - -+ RSA_get0_key(key, &n, &e, &d); -+ RSA_get0_factors(key, &p, &q); -+ RSA_get0_crt_params(key, NULL, NULL, &iqmp); - /* To keep within the protocol: p < q for ssh. in SSL p > q */ -- if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 || -- (r = sshbuf_put_bignum1(b, key->n)) != 0 || -- (r = sshbuf_put_bignum1(b, key->e)) != 0 || -- (r = sshbuf_put_bignum1(b, key->d)) != 0 || -- (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || -- (r = sshbuf_put_bignum1(b, key->q)) != 0 || -- (r = sshbuf_put_bignum1(b, key->p)) != 0 || -+ if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(b, n)) != 0 || -+ (r = sshbuf_put_bignum1(b, e)) != 0 || -+ (r = sshbuf_put_bignum1(b, d)) != 0 || -+ (r = sshbuf_put_bignum1(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum1(b, q)) != 0 || -+ (r = sshbuf_put_bignum1(b, p)) != 0 || - (r = sshbuf_put_cstring(b, comment)) != 0) - return r; - return 0; -@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct ssh - - #ifdef WITH_SSH1 - if (key->type == KEY_RSA1) { -+ const BIGNUM *e, *n; -+ RSA_get0_key(key->rsa, &n, &e, NULL); - if ((r = sshbuf_put_u8(msg, - SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || -- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) -+ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, n)) != 0) - goto out; - } else - #endif -diff -up openssh-7.4p1/auth-pam.c.openssl openssh-7.4p1/auth-pam.c ---- openssh-7.4p1/auth-pam.c.openssl 2016-12-23 17:47:36.400817739 +0100 -+++ openssh-7.4p1/auth-pam.c 2016-12-23 17:47:36.430817752 +0100 -@@ -129,6 +129,10 @@ extern u_int utmp_len; +diff -up openssh/auth-pam.c.openssl openssh/auth-pam.c +--- openssh/auth-pam.c.openssl 2017-09-26 13:19:31.662248869 +0200 ++++ openssh/auth-pam.c 2017-09-26 13:19:31.793249672 +0200 +@@ -128,6 +128,10 @@ extern u_int utmp_len; typedef pthread_t sp_pthread_t; #else typedef pid_t sp_pthread_t; @@ -108,169 +12,10 @@ diff -up openssh-7.4p1/auth-pam.c.openssl openssh-7.4p1/auth-pam.c #endif struct pam_ctxt { -diff -up openssh-7.4p1/cipher-3des1.c.openssl openssh-7.4p1/cipher-3des1.c ---- openssh-7.4p1/cipher-3des1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher-3des1.c 2016-12-23 17:47:36.430817752 +0100 -@@ -44,7 +44,7 @@ - */ - struct ssh1_3des_ctx - { -- EVP_CIPHER_CTX k1, k2, k3; -+ EVP_CIPHER_CTX *k1, *k2, *k3; - }; - - const EVP_CIPHER * evp_ssh1_3des(void); -@@ -65,7 +65,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons - if (key == NULL) - return 1; - if (enc == -1) -- enc = ctx->encrypt; -+ enc = EVP_CIPHER_CTX_encrypting(ctx); - k1 = k2 = k3 = (u_char *) key; - k2 += 8; - if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { -@@ -74,12 +74,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons - else - k1 += 16; - } -- EVP_CIPHER_CTX_init(&c->k1); -- EVP_CIPHER_CTX_init(&c->k2); -- EVP_CIPHER_CTX_init(&c->k3); -- if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || -- EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || -- EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { -+ c->k1 = EVP_CIPHER_CTX_new(); -+ c->k2 = EVP_CIPHER_CTX_new(); -+ c->k3 = EVP_CIPHER_CTX_new(); -+ if (c->k1 == NULL || c->k2 == NULL || c->k3 == NULL) { -+ EVP_CIPHER_CTX_free(c->k1); -+ EVP_CIPHER_CTX_free(c->k2); -+ EVP_CIPHER_CTX_free(c->k3); -+ free(c); -+ return 0; -+ } -+ if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || -+ EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || -+ EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { - explicit_bzero(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -95,9 +102,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) - return 0; -- if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || -- EVP_Cipher(&c->k2, dest, dest, len) == 0 || -- EVP_Cipher(&c->k3, dest, dest, len) == 0) -+ if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || -+ EVP_Cipher(c->k2, dest, dest, len) == 0 || -+ EVP_Cipher(c->k3, dest, dest, len) == 0) - return 0; - return 1; - } -@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { -- EVP_CIPHER_CTX_cleanup(&c->k1); -- EVP_CIPHER_CTX_cleanup(&c->k2); -- EVP_CIPHER_CTX_cleanup(&c->k3); -+ EVP_CIPHER_CTX_free(c->k1); -+ EVP_CIPHER_CTX_free(c->k2); -+ EVP_CIPHER_CTX_free(c->k3); - explicit_bzero(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -128,13 +135,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do - if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) - return SSH_ERR_INTERNAL_ERROR; - if (doset) { -- memcpy(c->k1.iv, iv, 8); -- memcpy(c->k2.iv, iv + 8, 8); -- memcpy(c->k3.iv, iv + 16, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); - } else { -- memcpy(iv, c->k1.iv, 8); -- memcpy(iv + 8, c->k2.iv, 8); -- memcpy(iv + 16, c->k3.iv, 8); -+ memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); -+ memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); -+ memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); - } - return 0; - } -@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do - const EVP_CIPHER * - evp_ssh1_3des(void) - { -- static EVP_CIPHER ssh1_3des; -+ EVP_CIPHER *ssh1_3des; - -- memset(&ssh1_3des, 0, sizeof(ssh1_3des)); -- ssh1_3des.nid = NID_undef; -- ssh1_3des.block_size = 8; -- ssh1_3des.iv_len = 0; -- ssh1_3des.key_len = 16; -- ssh1_3des.init = ssh1_3des_init; -- ssh1_3des.cleanup = ssh1_3des_cleanup; -- ssh1_3des.do_cipher = ssh1_3des_cbc; -- ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; -- return &ssh1_3des; -+ ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16); -+ EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0); -+ EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init); -+ EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup); -+ EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc); -+ EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); -+ return ssh1_3des; - } - #endif /* WITH_SSH1 */ -diff -up openssh-7.4p1/cipher-bf1.c.openssl openssh-7.4p1/cipher-bf1.c ---- openssh-7.4p1/cipher-bf1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher-bf1.c 2016-12-23 17:47:36.430817752 +0100 -@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_ch - const EVP_CIPHER * - evp_ssh1_bf(void) - { -- static EVP_CIPHER ssh1_bf; -+ EVP_CIPHER *ssh1_bf; - -- memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); -- orig_bf = ssh1_bf.do_cipher; -- ssh1_bf.nid = NID_undef; -+ orig_bf = EVP_CIPHER_meth_get_do_cipher(EVP_bf_cbc()); -+ /* block_size, length, flags from openssl/crypto/engine/eng_cryptodev.c:638 */ -+ ssh1_bf = EVP_CIPHER_meth_new(NID_undef, 8, 32); -+ EVP_CIPHER_meth_set_iv_length(ssh1_bf, 8); -+ EVP_CIPHER_meth_set_flags(ssh1_bf, EVP_CIPH_CBC_MODE); - #ifdef SSH_OLD_EVP -- ssh1_bf.init = bf_ssh1_init; -+ EVP_CIPHER_meth_set_init(ssh1_bf, ssh1_bf_init); -+#else -+ EVP_CIPHER_meth_set_init(ssh1_bf, -+ EVP_CIPHER_meth_get_init(EVP_bf_cbc())); - #endif -- ssh1_bf.do_cipher = bf_ssh1_cipher; -- ssh1_bf.key_len = 32; -- return (&ssh1_bf); -+ /* copy methods and parameters from old EVP_BF_cbc() -+ * meth_dup does not allow to change type and key_len */ -+ EVP_CIPHER_meth_set_cleanup(ssh1_bf, -+ EVP_CIPHER_meth_get_cleanup(EVP_bf_cbc())); -+ EVP_CIPHER_meth_set_ctrl(ssh1_bf, -+ EVP_CIPHER_meth_get_ctrl(EVP_bf_cbc())); -+ /* ASN1 params??? */ -+ EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_cipher); -+ return ssh1_bf; - } - #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */ - -diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c ---- openssh-7.4p1/cipher.c.openssl 2016-12-23 17:47:36.418817747 +0100 -+++ openssh-7.4p1/cipher.c 2016-12-23 17:47:36.430817752 +0100 -@@ -368,7 +368,7 @@ cipher_init(struct sshcipher_ctx **ccp, +diff -up openssh/cipher.c.openssl openssh/cipher.c +--- openssh/cipher.c.openssl 2017-09-26 13:19:31.782249605 +0200 ++++ openssh/cipher.c 2017-09-26 13:27:37.424040367 +0200 +@@ -283,7 +283,7 @@ cipher_init(struct sshcipher_ctx **ccp, ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -279,7 +24,7 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; -@@ -386,10 +386,6 @@ cipher_init(struct sshcipher_ctx **ccp, +@@ -301,10 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, goto out; } } @@ -287,28 +32,26 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - - if (cipher->discard_len > 0) { - if ((junk = malloc(cipher->discard_len)) == NULL || -@@ -621,7 +617,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c - len, iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(iv, cc->evp->iv, len); -+ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); - break; + ret = 0; + #endif /* WITH_OPENSSL */ + out: +@@ -490,7 +486,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c + len, iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(iv, cc->evp->iv, len); ++ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); #endif - #ifdef WITH_SSH1 -@@ -667,7 +663,7 @@ cipher_set_keyiv(struct sshcipher_ctx *c - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(cc->evp->iv, iv, evplen); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); - break; + return 0; + } +@@ -524,14 +520,14 @@ cipher_set_keyiv(struct sshcipher_ctx *c + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(cc->evp->iv, iv, evplen); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); #endif - #ifdef WITH_SSH1 -@@ -681,8 +677,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c + return 0; } #ifdef WITH_OPENSSL @@ -319,9 +62,9 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c #endif int -diff -up openssh-7.4p1/ctr-cavstest.c.openssl openssh-7.4p1/ctr-cavstest.c ---- openssh-7.4p1/ctr-cavstest.c.openssl 2016-12-23 17:47:36.344817716 +0100 -+++ openssh-7.4p1/ctr-cavstest.c 2016-12-23 17:47:36.430817752 +0100 +diff -up openssh/ctr-cavstest.c.openssl openssh/ctr-cavstest.c +--- openssh/ctr-cavstest.c.openssl 2017-09-26 13:19:31.707249145 +0200 ++++ openssh/ctr-cavstest.c 2017-09-26 13:19:31.794249679 +0200 @@ -144,7 +144,7 @@ int main (int argc, char *argv[]) usage(); } @@ -331,9 +74,9 @@ diff -up openssh-7.4p1/ctr-cavstest.c.openssl openssh-7.4p1/ctr-cavstest.c c = cipher_by_name(algo); if (c == NULL) { -diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c ---- openssh-7.4p1/dh.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/dh.c 2016-12-23 17:47:36.430817752 +0100 +diff -up openssh/dh.c.openssl openssh/dh.c +--- openssh/dh.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/dh.c 2017-09-26 13:19:31.794249679 +0200 @@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max /* diffie-hellman-groupN-sha1 */ @@ -409,11 +152,11 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c return SSH_ERR_LIBCRYPTO_ERROR; } return 0; -@@ -284,15 +290,22 @@ DH * +@@ -284,15 +289,22 @@ DH * dh_new_group_asc(const char *gen, const char *modulus) { DH *dh; -+ BIGNUM *p, *g; ++ BIGNUM *p = NULL, *g = NULL; - if ((dh = DH_new()) == NULL) - return NULL; @@ -439,7 +182,7 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c } /* -@@ -307,8 +320,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu +@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu if ((dh = DH_new()) == NULL) return NULL; @@ -449,9 +192,9 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c return (dh); } -diff -up openssh-7.4p1/dh.h.openssl openssh-7.4p1/dh.h ---- openssh-7.4p1/dh.h.openssl 2016-12-23 17:47:36.418817747 +0100 -+++ openssh-7.4p1/dh.h 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/dh.h.openssl openssh/dh.h +--- openssh/dh.h.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/dh.h 2017-09-26 13:19:31.794249679 +0200 @@ -42,7 +42,7 @@ DH *dh_new_group18(void); DH *dh_new_group_fallback(int); @@ -461,9 +204,9 @@ diff -up openssh-7.4p1/dh.h.openssl openssh-7.4p1/dh.h u_int dh_estimate(int); -diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c ---- openssh-7.4p1/digest-openssl.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/digest-openssl.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/digest-openssl.c.openssl openssh/digest-openssl.c +--- openssh/digest-openssl.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/digest-openssl.c 2017-09-26 13:19:31.795249685 +0200 @@ -43,7 +43,7 @@ struct ssh_digest_ctx { @@ -473,7 +216,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c }; struct ssh_digest { -@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg) +@@ -106,7 +106,7 @@ ssh_digest_bytes(int alg) size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx) { @@ -482,7 +225,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c } struct ssh_digest_ctx * -@@ -119,8 +119,9 @@ ssh_digest_start(int alg) +@@ -118,8 +118,10 @@ ssh_digest_start(int alg) if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) return NULL; ret->alg = alg; @@ -491,10 +234,11 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c + ret->mdctx = EVP_MD_CTX_new(); + if (ret->mdctx == NULL || + EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) { ++ EVP_MD_CTX_free(ret->mdctx); free(ret); return NULL; } -@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ +@@ -132,7 +133,7 @@ ssh_digest_copy_state(struct ssh_digest_ if (from->alg != to->alg) return SSH_ERR_INVALID_ARGUMENT; /* we have bcopy-style order while openssl has memcpy-style */ @@ -503,7 +247,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; return 0; } -@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ +@@ -140,7 +141,7 @@ ssh_digest_copy_state(struct ssh_digest_ int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) { @@ -512,7 +256,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; return 0; } -@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx * +@@ -161,7 +162,7 @@ ssh_digest_final(struct ssh_digest_ctx * return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) /* No truncation allowed */ return SSH_ERR_INVALID_ARGUMENT; @@ -521,7 +265,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; if (l != digest->digest_len) /* sanity */ return SSH_ERR_INTERNAL_ERROR; -@@ -173,7 +174,7 @@ void +@@ -172,7 +173,7 @@ void ssh_digest_free(struct ssh_digest_ctx *ctx) { if (ctx != NULL) { @@ -530,9 +274,9 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } -diff -up openssh-7.4p1/entropy.c.openssl openssh-7.4p1/entropy.c ---- openssh-7.4p1/entropy.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/entropy.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/entropy.c.openssl openssh/entropy.c +--- openssh/entropy.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/entropy.c 2017-09-26 13:19:31.795249685 +0200 @@ -218,7 +218,9 @@ seed_rng(void) "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -543,9 +287,9 @@ diff -up openssh-7.4p1/entropy.c.openssl openssh-7.4p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { -diff -up openssh-7.4p1/gss-genr.c.openssl openssh-7.4p1/gss-genr.c ---- openssh-7.4p1/gss-genr.c.openssl 2016-12-23 17:47:36.392817736 +0100 -+++ openssh-7.4p1/gss-genr.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/gss-genr.c.openssl openssh/gss-genr.c +--- openssh/gss-genr.c.openssl 2017-09-26 13:19:31.773249550 +0200 ++++ openssh/gss-genr.c 2017-09-26 13:19:31.796249691 +0200 @@ -99,7 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup u_char digest[EVP_MAX_MD_SIZE]; char deroid[2]; @@ -589,10 +333,10 @@ diff -up openssh-7.4p1/gss-genr.c.openssl openssh-7.4p1/gss-genr.c gss_enc2oid[oidpos].oid = NULL; gss_enc2oid[oidpos].encoded = NULL; -diff -up openssh-7.4p1/includes.h.openssl openssh-7.4p1/includes.h ---- openssh-7.4p1/includes.h.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/includes.h 2016-12-23 17:47:36.431817752 +0100 -@@ -163,6 +163,7 @@ +diff -up openssh/includes.h.openssl openssh/includes.h +--- openssh/includes.h.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/includes.h 2017-09-26 13:19:31.796249691 +0200 +@@ -166,6 +166,7 @@ #ifdef WITH_OPENSSL #include /* For OPENSSL_VERSION_NUMBER */ @@ -600,9 +344,9 @@ diff -up openssh-7.4p1/includes.h.openssl openssh-7.4p1/includes.h #endif #include "defines.h" -diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c ---- openssh-7.4p1/kexdhc.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kexdhc.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/kexdhc.c.openssl openssh/kexdhc.c +--- openssh/kexdhc.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/kexdhc.c 2017-09-26 13:19:31.797249697 +0200 @@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) { struct kex *kex = ssh->kex; @@ -643,7 +387,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c return r; } -@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -109,6 +116,7 @@ input_kex_dh(int type, u_int32_t seq, st u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; @@ -651,7 +395,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; -@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -168,6 +176,7 @@ input_kex_dh(int type, u_int32_t seq, st #endif /* calc and verify H */ @@ -659,7 +403,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c hashlen = sizeof(hash); if ((r = kex_dh_hash( kex->hash_alg, -@@ -177,7 +186,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -176,7 +185,7 @@ input_kex_dh(int type, u_int32_t seq, st sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, @@ -668,9 +412,9 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c ---- openssh-7.4p1/kexdhs.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kexdhs.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/kexdhs.c.openssl openssh/kexdhs.c +--- openssh/kexdhs.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/kexdhs.c 2017-09-26 13:19:31.797249697 +0200 @@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); r = 0; @@ -682,7 +426,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c return r; } -@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -101,6 +105,7 @@ input_kex_dh_init(int type, u_int32_t se size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; @@ -690,7 +434,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { -@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -163,6 +168,7 @@ input_kex_dh_init(int type, u_int32_t se goto out; /* calc H */ hashlen = sizeof(hash); @@ -698,7 +442,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c if ((r = kex_dh_hash( kex->hash_alg, kex->client_version_string, -@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -171,7 +177,7 @@ input_kex_dh_init(int type, u_int32_t se sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, dh_client_pub, @@ -707,7 +451,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c shared_secret, hash, &hashlen)) != 0) goto out; -@@ -198,7 +204,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -197,7 +203,7 @@ input_kex_dh_init(int type, u_int32_t se /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || @@ -716,10 +460,10 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c ---- openssh-7.4p1/kexgexc.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/kexgexc.c 2016-12-23 17:47:36.431817752 +0100 -@@ -96,6 +96,7 @@ input_kex_dh_gex_group(int type, u_int32 +diff -up openssh/kexgexc.c.openssl openssh/kexgexc.c +--- openssh/kexgexc.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/kexgexc.c 2017-09-26 13:19:31.797249697 +0200 +@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32 struct kex *kex = ssh->kex; BIGNUM *p = NULL, *g = NULL; int r, bits; @@ -727,7 +471,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); -@@ -120,26 +121,30 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -119,26 +120,30 @@ input_kex_dh_gex_group(int type, u_int32 p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ @@ -766,7 +510,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c return r; } -@@ -154,6 +159,7 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -152,6 +157,7 @@ input_kex_dh_gex_reply(int type, u_int32 u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; @@ -774,7 +518,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); if (kex->verify_host_key == NULL) { -@@ -220,6 +226,8 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -214,6 +220,8 @@ input_kex_dh_gex_reply(int type, u_int32 kex->min = kex->max = -1; /* calc and verify H */ @@ -783,7 +527,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c hashlen = sizeof(hash); if ((r = kexgex_hash( kex->hash_alg, -@@ -229,8 +237,8 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -223,8 +231,8 @@ input_kex_dh_gex_reply(int type, u_int32 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, @@ -794,10 +538,10 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c ---- openssh-7.4p1/kexgexs.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/kexgexs.c 2016-12-23 17:47:36.432817753 +0100 -@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int +diff -up openssh/kexgexs.c.openssl openssh/kexgexs.c +--- openssh/kexgexs.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/kexgexs.c 2017-09-26 13:19:31.797249697 +0200 +@@ -72,6 +72,7 @@ input_kex_dh_gex_request(int type, u_int struct kex *kex = ssh->kex; int r; u_int min = 0, max = 0, nbits = 0; @@ -805,7 +549,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); if ((r = sshpkt_get_u32(ssh, &min)) != 0 || -@@ -102,9 +103,10 @@ input_kex_dh_gex_request(int type, u_int +@@ -101,9 +102,10 @@ input_kex_dh_gex_request(int type, u_int goto out; } debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); @@ -818,7 +562,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c (r = sshpkt_send(ssh)) != 0) goto out; -@@ -116,6 +118,10 @@ input_kex_dh_gex_request(int type, u_int +@@ -115,6 +117,10 @@ input_kex_dh_gex_request(int type, u_int ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); r = 0; out: @@ -829,7 +573,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c return r; } -@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -129,6 +135,7 @@ input_kex_dh_gex_init(int type, u_int32_ size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; @@ -837,7 +581,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { -@@ -193,6 +200,8 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -191,6 +198,8 @@ input_kex_dh_gex_init(int type, u_int32_ goto out; /* calc H */ hashlen = sizeof(hash); @@ -846,7 +590,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, -@@ -201,9 +210,9 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -199,9 +208,9 @@ input_kex_dh_gex_init(int type, u_int32_ sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, @@ -858,7 +602,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c shared_secret, hash, &hashlen)) != 0) goto out; -@@ -229,7 +238,7 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -227,7 +236,7 @@ input_kex_dh_gex_init(int type, u_int32_ /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || @@ -867,10 +611,10 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c ---- openssh-7.4p1/kexgssc.c.openssl 2016-12-23 17:47:36.349817718 +0100 -+++ openssh-7.4p1/kexgssc.c 2016-12-23 17:47:36.432817753 +0100 -@@ -58,6 +58,7 @@ kexgss_client(struct ssh *ssh) { +diff -up openssh/kexgssc.c.openssl openssh/kexgssc.c +--- openssh/kexgssc.c.openssl 2017-09-26 13:19:31.771249537 +0200 ++++ openssh/kexgssc.c 2017-09-26 13:19:31.797249697 +0200 +@@ -59,6 +59,7 @@ kexgss_client(struct ssh *ssh) { BIGNUM *shared_secret = NULL; BIGNUM *p = NULL; BIGNUM *g = NULL; @@ -878,7 +622,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c u_char *kbuf; u_char *serverhostkey = NULL; u_char *empty = ""; -@@ -121,6 +122,7 @@ kexgss_client(struct ssh *ssh) { +@@ -126,6 +127,7 @@ kexgss_client(struct ssh *ssh) { /* Step 1 - e is dh->pub_key */ dh_gen_key(dh, ssh->kex->we_need * 8); @@ -886,7 +630,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c /* This is f, we initialise it now to make life easier */ dh_server_pub = BN_new(); -@@ -168,7 +170,7 @@ kexgss_client(struct ssh *ssh) { +@@ -173,7 +175,7 @@ kexgss_client(struct ssh *ssh) { packet_start(SSH2_MSG_KEXGSS_INIT); packet_put_string(send_tok.value, send_tok.length); @@ -895,7 +639,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c first = 0; } else { packet_start(SSH2_MSG_KEXGSS_CONTINUE); -@@ -275,13 +277,14 @@ kexgss_client(struct ssh *ssh) { +@@ -282,13 +284,14 @@ kexgss_client(struct ssh *ssh) { buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, @@ -911,7 +655,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c kexgex_hash( ssh->kex->hash_alg, ssh->kex->client_version_string, -@@ -290,8 +293,8 @@ kexgss_client(struct ssh *ssh) { +@@ -297,8 +300,8 @@ kexgss_client(struct ssh *ssh) { buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, min, nbits, max, @@ -922,10 +666,10 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c dh_server_pub, shared_secret, hash, &hashlen -diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c ---- openssh-7.4p1/kexgsss.c.openssl 2016-12-23 17:47:36.349817718 +0100 -+++ openssh-7.4p1/kexgsss.c 2016-12-23 17:47:36.432817753 +0100 -@@ -77,6 +77,7 @@ kexgss_server(struct ssh *ssh) +diff -up openssh/kexgsss.c.openssl openssh/kexgsss.c +--- openssh/kexgsss.c.openssl 2017-09-26 13:19:31.771249537 +0200 ++++ openssh/kexgsss.c 2017-09-26 13:19:31.798249703 +0200 +@@ -78,6 +78,7 @@ kexgss_server(struct ssh *ssh) char *mechs; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t hashlen; @@ -933,7 +677,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c /* Initialise GSSAPI */ -@@ -122,9 +123,10 @@ kexgss_server(struct ssh *ssh) +@@ -127,9 +128,10 @@ kexgss_server(struct ssh *ssh) if (dh == NULL) packet_disconnect("Protocol error: no matching group found"); @@ -946,7 +690,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c packet_send(); packet_write_wait(); -@@ -216,6 +218,7 @@ kexgss_server(struct ssh *ssh) +@@ -221,6 +223,7 @@ kexgss_server(struct ssh *ssh) memset(kbuf, 0, klen); free(kbuf); @@ -954,7 +698,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c hashlen = sizeof(hash); switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -225,7 +228,7 @@ kexgss_server(struct ssh *ssh) +@@ -232,7 +235,7 @@ kexgss_server(struct ssh *ssh) buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), NULL, 0, /* Change this if we start sending host keys */ @@ -963,7 +707,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c hash, &hashlen ); break; -@@ -237,9 +240,9 @@ kexgss_server(struct ssh *ssh) +@@ -244,9 +247,9 @@ kexgss_server(struct ssh *ssh) buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), NULL, 0, cmin, nbits, cmax, @@ -975,7 +719,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c shared_secret, hash, &hashlen ); -@@ -263,7 +266,7 @@ kexgss_server(struct ssh *ssh) +@@ -270,7 +273,7 @@ kexgss_server(struct ssh *ssh) fatal("Couldn't get MIC"); packet_start(SSH2_MSG_KEXGSS_COMPLETE); @@ -984,10 +728,10 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c packet_put_string(msg_tok.value,msg_tok.length); if (send_tok.length != 0) { -diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat.c ---- openssh-7.4p1/libcrypto-compat.c.openssl 2016-12-23 17:47:36.432817753 +0100 -+++ openssh-7.4p1/libcrypto-compat.c 2016-12-23 17:47:36.432817753 +0100 -@@ -0,0 +1,546 @@ +diff -up openssh/libcrypto-compat.c.openssl openssh/libcrypto-compat.c +--- openssh/libcrypto-compat.c.openssl 2017-09-26 13:19:31.798249703 +0200 ++++ openssh/libcrypto-compat.c 2017-09-26 13:19:31.798249703 +0200 +@@ -0,0 +1,428 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * @@ -1270,27 +1014,6 @@ diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat + *priv_key = dh->priv_key; +} + -+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) -+{ -+ /* If the field pub_key in dh is NULL, the corresponding input -+ * parameters MUST be non-NULL. The priv_key field may -+ * be left NULL. -+ */ -+ if (dh->pub_key == NULL && pub_key == NULL) -+ return 0; -+ -+ if (pub_key != NULL) { -+ BN_free(dh->pub_key); -+ dh->pub_key = pub_key; -+ } -+ if (priv_key != NULL) { -+ BN_free(dh->priv_key); -+ dh->priv_key = priv_key; -+ } -+ -+ return 1; -+} -+ +int DH_set_length(DH *dh, long length) +{ + dh->length = length; @@ -1436,108 +1159,11 @@ diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat + return pkey->pkey.rsa; +} + -+EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) -+{ -+ EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); -+ -+ if (cipher != NULL) { -+ cipher->nid = cipher_type; -+ cipher->block_size = block_size; -+ cipher->key_len = key_len; -+ } -+ return cipher; -+} -+ -+void EVP_CIPHER_meth_free(EVP_CIPHER *cipher) -+{ -+ OPENSSL_free(cipher); -+} -+ -+int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) -+{ -+ cipher->iv_len = iv_len; -+ return 1; -+} -+ -+int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) -+{ -+ cipher->flags = flags; -+ return 1; -+} -+ -+int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, -+ int (*init) (EVP_CIPHER_CTX *ctx, -+ const unsigned char *key, -+ const unsigned char *iv, -+ int enc)) -+{ -+ cipher->init = init; -+ return 1; -+} -+ -+int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, -+ int (*do_cipher) (EVP_CIPHER_CTX *ctx, -+ unsigned char *out, -+ const unsigned char *in, -+ size_t inl)) -+{ -+ cipher->do_cipher = do_cipher; -+ return 1; -+} -+ -+int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, -+ int (*cleanup) (EVP_CIPHER_CTX *)) -+{ -+ cipher->cleanup = cleanup; -+ return 1; -+} -+ -+int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, -+ int (*ctrl) (EVP_CIPHER_CTX *, int type, -+ int arg, void *ptr)) -+{ -+ cipher->ctrl = ctrl; -+ return 1; -+} -+ -+int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, -+ const unsigned char *key, -+ const unsigned char *iv, -+ int enc) -+{ -+ return cipher->init; -+} -+ -+int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, -+ unsigned char *out, -+ const unsigned char *in, -+ size_t inl) -+{ -+ return cipher->do_cipher; -+} -+ -+int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *) -+{ -+ return cipher->cleanup; -+} -+ -+int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, -+ int type, int arg, -+ void *ptr) -+{ -+ return cipher->ctrl; -+} -+ -+int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) -+{ -+ return ctx->encrypt; -+} -+ +#endif /* OPENSSL_VERSION_NUMBER */ -diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat.h ---- openssh-7.4p1/libcrypto-compat.h.openssl 2016-12-23 17:47:36.432817753 +0100 -+++ openssh-7.4p1/libcrypto-compat.h 2016-12-23 17:47:36.432817753 +0100 -@@ -0,0 +1,98 @@ +diff -up openssh/libcrypto-compat.h.openssl openssh/libcrypto-compat.h +--- openssh/libcrypto-compat.h.openssl 2017-09-26 13:19:31.798249703 +0200 ++++ openssh/libcrypto-compat.h 2017-09-26 13:19:31.798249703 +0200 +@@ -0,0 +1,59 @@ +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H + @@ -1570,7 +1196,6 @@ diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat +void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); -+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +int DH_set_length(DH *dh, long length); + +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); @@ -1594,64 +1219,26 @@ diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat + +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); + -+EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); -+void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); -+ -+int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); -+int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); -+int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, -+ int (*init) (EVP_CIPHER_CTX *ctx, -+ const unsigned char *key, -+ const unsigned char *iv, -+ int enc)); -+int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, -+ int (*do_cipher) (EVP_CIPHER_CTX *ctx, -+ unsigned char *out, -+ const unsigned char *in, -+ size_t inl)); -+int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, -+ int (*cleanup) (EVP_CIPHER_CTX *)); -+int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, -+ int (*ctrl) (EVP_CIPHER_CTX *, int type, -+ int arg, void *ptr)); -+ -+int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, -+ const unsigned char *key, -+ const unsigned char *iv, -+ int enc); -+int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, -+ unsigned char *out, -+ const unsigned char *in, -+ size_t inl); -+int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); -+int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, -+ int type, int arg, -+ void *ptr); -+ -+#define EVP_CIPHER_CTX_reset(c) EVP_CIPHER_CTX_init(c) -+ -+int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); -+ +#endif /* OPENSSL_VERSION_NUMBER */ + +#endif /* LIBCRYPTO_COMPAT_H */ + -diff -up openssh-7.4p1/Makefile.in.openssl openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.openssl 2016-12-23 17:47:36.420817748 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 17:47:36.432817753 +0100 -@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +diff -up openssh/Makefile.in.openssl openssh/Makefile.in +--- openssh/Makefile.in.openssl 2017-09-26 13:19:31.784249617 +0200 ++++ openssh/Makefile.in 2017-09-26 13:19:31.798249703 +0200 +@@ -101,7 +101,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ -- platform-pledge.o platform-tracing.o auditstub.o -+ platform-pledge.o platform-tracing.o auditstub.o libcrypto-compat.o + platform-pledge.o platform-tracing.o platform-misc.o \ +- auditstub.o ++ auditstub.o libcrypto-compat.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.4p1/monitor.c.openssl openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.openssl 2016-12-23 17:47:36.426817750 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 17:47:36.433817753 +0100 -@@ -636,9 +636,12 @@ mm_answer_moduli(int sock, Buffer *m) + sshconnect.o sshconnect2.o mux.o +diff -up openssh/monitor.c.openssl openssh/monitor.c +--- openssh/monitor.c.openssl 2017-09-26 13:19:31.789249648 +0200 ++++ openssh/monitor.c 2017-09-26 13:19:31.799249709 +0200 +@@ -631,9 +631,12 @@ mm_answer_moduli(int sock, Buffer *m) return (0); } else { /* Send first bignum */ @@ -1666,9 +1253,9 @@ diff -up openssh-7.4p1/monitor.c.openssl openssh-7.4p1/monitor.c DH_free(dh); } -diff -up openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl openssh-7.4p1/openbsd-compat/openssl-compat.c ---- openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/openbsd-compat/openssl-compat.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/openbsd-compat/openssl-compat.c.openssl openssh/openbsd-compat/openssl-compat.c +--- openssh/openbsd-compat/openssl-compat.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/openbsd-compat/openssl-compat.c 2017-09-26 13:19:31.799249709 +0200 @@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, l void ssh_OpenSSL_add_all_algorithms(void) @@ -1689,9 +1276,9 @@ diff -up openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl openssh-7.4p1/ope } #endif -diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_file.c ---- openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/unittests/sshkey/test_file.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/regress/unittests/sshkey/test_file.c.openssl openssh/regress/unittests/sshkey/test_file.c +--- openssh/regress/unittests/sshkey/test_file.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/regress/unittests/sshkey/test_file.c 2017-09-26 13:19:31.799249709 +0200 @@ -46,6 +46,7 @@ sshkey_file_tests(void) struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; @@ -1700,17 +1287,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p TEST_START("load passphrase"); pw = load_text_file("pw"); -@@ -58,7 +59,8 @@ sshkey_file_tests(void) - sshbuf_free(buf); - ASSERT_PTR_NE(k1, NULL); - a = load_bignum("rsa1_1.param.n"); -- ASSERT_BIGNUM_EQ(k1->rsa->n, a); -+ RSA_get0_key(k1->rsa, &n, NULL, NULL); -+ ASSERT_BIGNUM_EQ(n, a); - BN_free(a); - TEST_DONE(); - -@@ -109,9 +111,11 @@ sshkey_file_tests(void) +@@ -60,9 +61,11 @@ sshkey_file_tests(void) a = load_bignum("rsa_1.param.n"); b = load_bignum("rsa_1.param.p"); c = load_bignum("rsa_1.param.q"); @@ -1725,7 +1302,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p BN_free(a); BN_free(b); BN_free(c); -@@ -200,9 +204,11 @@ sshkey_file_tests(void) +@@ -151,9 +154,11 @@ sshkey_file_tests(void) a = load_bignum("dsa_1.param.g"); b = load_bignum("dsa_1.param.priv"); c = load_bignum("dsa_1.param.pub"); @@ -1740,20 +1317,10 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p BN_free(a); BN_free(b); BN_free(c); -diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c ---- openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/regress/unittests/sshkey/test_sshkey.c.openssl openssh/regress/unittests/sshkey/test_sshkey.c +--- openssh/regress/unittests/sshkey/test_sshkey.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/regress/unittests/sshkey/test_sshkey.c 2017-09-26 13:19:31.800249715 +0200 @@ -197,9 +197,6 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_RSA1); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); - sshkey_free(k1); - TEST_DONE(); - -@@ -207,9 +204,6 @@ sshkey_tests(void) k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1763,7 +1330,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. sshkey_free(k1); TEST_DONE(); -@@ -217,8 +211,6 @@ sshkey_tests(void) +@@ -207,8 +204,6 @@ sshkey_tests(void) k1 = sshkey_new(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1772,7 +1339,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. sshkey_free(k1); TEST_DONE(); -@@ -244,9 +236,6 @@ sshkey_tests(void) +@@ -234,9 +229,6 @@ sshkey_tests(void) k1 = sshkey_new_private(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1782,7 +1349,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); -@@ -255,8 +244,6 @@ sshkey_tests(void) +@@ -245,8 +237,6 @@ sshkey_tests(void) k1 = sshkey_new_private(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1791,7 +1358,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); -@@ -295,18 +282,13 @@ sshkey_tests(void) +@@ -285,18 +275,13 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr->rsa, NULL); @@ -1811,7 +1378,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); #ifdef OPENSSL_HAS_ECC -@@ -333,9 +315,6 @@ sshkey_tests(void) +@@ -323,9 +308,6 @@ sshkey_tests(void) ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1821,7 +1388,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); TEST_START("equal KEY_RSA/demoted KEY_RSA"); -@@ -349,8 +328,6 @@ sshkey_tests(void) +@@ -339,8 +321,6 @@ sshkey_tests(void) ASSERT_PTR_NE(kd, k1); ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1830,399 +1397,10 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -up openssh-7.4p1/rsa.c.openssl openssh-7.4p1/rsa.c ---- openssh-7.4p1/rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/rsa.c 2016-12-23 17:47:36.434817754 +0100 -@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM * - { - u_char *inbuf = NULL, *outbuf = NULL; - int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; -+ const BIGNUM *e, *n; - -- if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) -+ RSA_get0_key(key, &n, &e, NULL); -+ -+ if (BN_num_bits(e) < 2 || !BN_is_odd(e)) - return SSH_ERR_INVALID_ARGUMENT; - -- olen = BN_num_bytes(key->n); -+ olen = BN_num_bytes(n); - if ((outbuf = malloc(olen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; -@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM - { - u_char *inbuf = NULL, *outbuf = NULL; - int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; -+ const BIGNUM *n; -+ -+ RSA_get0_key(key, &n, NULL, NULL); - -- olen = BN_num_bytes(key->n); -+ olen = BN_num_bytes(n); - if ((outbuf = malloc(olen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; -@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM - return r; - } - --/* calculate p-1 and q-1 */ -+/* calculate d mod p-1 and d mod q-1 */ - int --rsa_generate_additional_parameters(RSA *rsa) -+rsa_generate_additional_parameters(RSA *rsa, BIGNUM *iqmp) - { - BIGNUM *aux = NULL; - BN_CTX *ctx = NULL; - int r; -+ const BIGNUM *p, *q, *d; -+ BIGNUM *dmp1 = NULL, *dmq1 = NULL; -+ -+ RSA_get0_factors(rsa, &p, &q); -+ RSA_get0_key(rsa, NULL, NULL, &d); - -- if ((ctx = BN_CTX_new()) == NULL) -- return SSH_ERR_ALLOC_FAIL; -- if ((aux = BN_new()) == NULL) { -+ if ((ctx = BN_CTX_new()) == NULL || -+ (aux = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL || -+ (dmq1 = BN_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - -- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || -- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || -- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || -- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { -+ if ((BN_sub(aux, q, BN_value_one()) == 0) || -+ (BN_mod(dmq1, d, aux, ctx) == 0) || -+ (BN_sub(aux, p, BN_value_one()) == 0) || -+ (BN_mod(dmp1, d, aux, ctx) == 0) || -+ (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ dmp1 = NULL; -+ dmq1 = NULL; - r = 0; - out: - BN_clear_free(aux); -+ BN_clear_free(dmp1); -+ BN_clear_free(dmq1); - BN_CTX_free(ctx); - return r; - } -diff -up openssh-7.4p1/rsa.h.openssl openssh-7.4p1/rsa.h ---- openssh-7.4p1/rsa.h.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/rsa.h 2016-12-23 17:47:36.434817754 +0100 -@@ -21,6 +21,6 @@ - - int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); - int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); --int rsa_generate_additional_parameters(RSA *); -+int rsa_generate_additional_parameters(RSA *, BIGNUM *); - - #endif /* RSA_H */ -diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c ---- openssh-7.4p1/ssh-agent.c.openssl 2016-12-23 17:47:36.428817751 +0100 -+++ openssh-7.4p1/ssh-agent.c 2016-12-23 17:47:36.434817754 +0100 -@@ -258,12 +258,12 @@ process_request_identities(SocketEntry * - TAILQ_FOREACH(id, &tab->idlist, next) { - if (id->key->type == KEY_RSA1) { - #ifdef WITH_SSH1 -+ const BIGNUM *r_n, *r_e; -+ RSA_get0_key(id->key->rsa, &r_n, &r_e, NULL); - if ((r = sshbuf_put_u32(msg, -- BN_num_bits(id->key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, -- id->key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, -- id->key->rsa->n)) != 0) -+ BN_num_bits(r_n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, r_e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, r_n)) != 0) - fatal("%s: buffer error: %s", - __func__, ssh_err(r)); - #endif -@@ -302,6 +302,7 @@ process_authentication_challenge1(Socket - struct sshbuf *msg; - struct ssh_digest_ctx *md; - struct sshkey *key; -+ BIGNUM *r_n = NULL, *r_e = NULL; - - if ((msg = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); -@@ -310,11 +311,16 @@ process_authentication_challenge1(Socket - if ((challenge = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - -- if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ -- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(e->request, challenge))) -+ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ -+ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, challenge)) || -+ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { -+ BN_free(r_n); -+ BN_free(r_e); - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ } - - /* Only protocol 1.1 is supported */ - if (sshbuf_len(e->request) == 0) -@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, - u_char *blob; - #ifdef WITH_SSH1 - u_int bits; -+ BIGNUM *r_n = NULL, *r_e = NULL; - #endif /* WITH_SSH1 */ - - switch (version) { -@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, - error("%s: sshkey_new failed", __func__); - return; - } -- if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) -+ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(e->request, &bits)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || -+ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { -+ BN_free(r_n); -+ BN_free(r_e); - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ } - - if (bits != sshkey_size(key)) - logit("Warning: identity keysize mismatch: " -@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, stru - { - struct sshkey *k = NULL; - int r = SSH_ERR_INTERNAL_ERROR; -+ BIGNUM *n = NULL, *e = NULL, *d = NULL, -+ *iqmp = NULL, *q = NULL, *p = NULL; - - *kp = NULL; - if ((k = sshkey_new_private(KEY_RSA1)) == NULL) - return SSH_ERR_ALLOC_FAIL; - -- if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ -- (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || -+ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || -+ (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL || -+ (q = BN_new()) == NULL || (p = BN_new()) == NULL || -+ (r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ -+ (r = sshbuf_get_bignum1(m, n)) != 0 || -+ (r = sshbuf_get_bignum1(m, e)) != 0 || -+ (r = sshbuf_get_bignum1(m, d)) != 0 || -+ (r = sshbuf_get_bignum1(m, iqmp)) != 0 || - /* SSH1 and SSL have p and q swapped */ -- (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ -- (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ -+ (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */ -+ (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */ -+ RSA_set0_key(k->rsa, n, e, d) == 0) { -+ BN_free(n); -+ BN_free(e); -+ BN_free(d); -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); -+ goto out; -+ } -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); - goto out; -+ } -+ if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) { -+ BN_free(iqmp); -+ goto out; -+ } - - /* Generate additional parameters */ -- if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) -+ if ((r = rsa_generate_additional_parameters(k->rsa, NULL)) != 0) - goto out; - /* enable blinding */ - if (RSA_blinding_on(k->rsa, NULL) != 1) { -diff -up openssh-7.4p1/sshconnect1.c.openssl openssh-7.4p1/sshconnect1.c ---- openssh-7.4p1/sshconnect1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect1.c 2016-12-23 17:47:36.434817754 +0100 -@@ -70,6 +70,7 @@ try_agent_authentication(void) - u_char response[16]; - size_t i; - BIGNUM *challenge; -+ const BIGNUM *n; - struct ssh_identitylist *idlist = NULL; - - /* Get connection to the agent. */ -@@ -96,8 +97,9 @@ try_agent_authentication(void) - idlist->comments[i]); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(idlist->keys[i]->rsa, &n, NULL, NULL); - packet_start(SSH_CMSG_AUTH_RSA); -- packet_put_bignum(idlist->keys[i]->rsa->n); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -220,6 +222,7 @@ static int - try_rsa_authentication(int idx) - { - BIGNUM *challenge; -+ const BIGNUM *n; - Key *public, *private; - char buf[300], *passphrase = NULL, *comment, *authfile; - int i, perm_ok = 1, type, quit; -@@ -231,8 +234,9 @@ try_rsa_authentication(int idx) - debug("Trying RSA authentication with key '%.100s'", comment); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(public->rsa, &n, NULL, NULL); - packet_start(SSH_CMSG_AUTH_RSA); -- packet_put_bignum(public->rsa->n); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char - { - int type; - BIGNUM *challenge; -+ const BIGNUM *n, *e; - - debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(host_key->rsa, &n, &e, NULL); - packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); - packet_put_cstring(local_user); -- packet_put_int(BN_num_bits(host_key->rsa->n)); -- packet_put_bignum(host_key->rsa->e); -- packet_put_bignum(host_key->rsa->n); -+ packet_put_int(BN_num_bits(n)); -+ packet_put_bignum((BIGNUM *)e); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hos - { - int i; - BIGNUM *key; -+ BIGNUM *server_n = NULL, *server_e = NULL, -+ *host_n = NULL, *host_e = NULL; - Key *host_key, *server_key; - int bits, rbits; - int ssh_cipher_default = SSH_CIPHER_3DES; -@@ -522,10 +530,14 @@ ssh_kex(char *host, struct sockaddr *hos - if ((server_key = key_new(KEY_RSA1)) == NULL) - fatal("%s: key_new(KEY_RSA1) failed", __func__); - bits = packet_get_int(); -- packet_get_bignum(server_key->rsa->e); -- packet_get_bignum(server_key->rsa->n); -+ if ((server_e = BN_new()) == NULL || -+ (server_n = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum(server_e); -+ packet_get_bignum(server_n); -+ RSA_set0_key(server_key->rsa, server_n, server_e, NULL); - -- rbits = BN_num_bits(server_key->rsa->n); -+ rbits = BN_num_bits(server_n); - if (bits != rbits) { - logit("Warning: Server lies about size of server public key: " - "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -534,10 +546,14 @@ ssh_kex(char *host, struct sockaddr *hos - if ((host_key = key_new(KEY_RSA1)) == NULL) - fatal("%s: key_new(KEY_RSA1) failed", __func__); - bits = packet_get_int(); -- packet_get_bignum(host_key->rsa->e); -- packet_get_bignum(host_key->rsa->n); -+ if ((host_e = BN_new()) == NULL || -+ (host_n = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum(host_e); -+ packet_get_bignum(host_n); -+ RSA_set0_key(host_key->rsa, host_n, host_e, NULL); - -- rbits = BN_num_bits(host_key->rsa->n); -+ rbits = BN_num_bits(host_n); - if (bits != rbits) { - logit("Warning: Server lies about size of server host key: " - "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -553,14 +569,14 @@ ssh_kex(char *host, struct sockaddr *hos - packet_check_eom(); - - debug("Received server public key (%d bits) and host key (%d bits).", -- BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); -+ BN_num_bits(server_n), BN_num_bits(host_n)); - - if (verify_host_key(host, hostaddr, host_key) == -1) - fatal("Host key verification failed."); - - client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - -- derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); -+ derive_ssh1_session_id(host_n, server_n, cookie, session_id); - - /* - * Generate an encryption key for the session. The key is a 256 bit -@@ -595,14 +611,14 @@ ssh_kex(char *host, struct sockaddr *hos - * Encrypt the integer using the public key and host key of the - * server (key with smaller modulus first). - */ -- if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { -+ if (BN_cmp(server_n, host_n) < 0) { - /* Public key has smaller modulus. */ -- if (BN_num_bits(host_key->rsa->n) < -- BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { -+ if (BN_num_bits(host_n) < -+ BN_num_bits(server_n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " - "SSH_KEY_BITS_RESERVED %d", -- BN_num_bits(host_key->rsa->n), -- BN_num_bits(server_key->rsa->n), -+ BN_num_bits(host_n), -+ BN_num_bits(server_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || -@@ -610,12 +626,12 @@ ssh_kex(char *host, struct sockaddr *hos - fatal("%s: rsa_public_encrypt failed", __func__); - } else { - /* Host key has smaller modulus (or they are equal). */ -- if (BN_num_bits(server_key->rsa->n) < -- BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { -+ if (BN_num_bits(server_n) < -+ BN_num_bits(host_n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " - "SSH_KEY_BITS_RESERVED %d", -- BN_num_bits(server_key->rsa->n), -- BN_num_bits(host_key->rsa->n), -+ BN_num_bits(server_n), -+ BN_num_bits(host_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || -diff -up openssh-7.4p1/sshconnect2.c.openssl openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.openssl 2016-12-23 17:47:36.423817749 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 17:47:36.434817754 +0100 -@@ -299,6 +299,7 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh/sshconnect2.c.openssl openssh/sshconnect2.c +--- openssh/sshconnect2.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/sshconnect2.c 2017-09-26 13:19:31.800249715 +0200 +@@ -306,6 +306,7 @@ ssh_kex2(char *host, struct sockaddr *ho packet_send(); packet_write_wait(); #endif @@ -2230,10 +1408,10 @@ diff -up openssh-7.4p1/sshconnect2.c.openssl openssh-7.4p1/sshconnect2.c } /* -diff -up openssh-7.4p1/sshconnect.c.openssl openssh-7.4p1/sshconnect.c ---- openssh-7.4p1/sshconnect.c.openssl 2016-12-23 17:47:36.397817738 +0100 -+++ openssh-7.4p1/sshconnect.c 2016-12-23 17:47:36.435817754 +0100 -@@ -1369,6 +1369,7 @@ ssh_login(Sensitive *sensitive, const ch +diff -up openssh/sshconnect.c.openssl openssh/sshconnect.c +--- openssh/sshconnect.c.openssl 2017-09-26 13:19:31.759249464 +0200 ++++ openssh/sshconnect.c 2017-09-26 13:19:31.800249715 +0200 +@@ -1316,6 +1316,7 @@ ssh_login(Sensitive *sensitive, const ch char *server_user, *local_user; local_user = xstrdup(pw->pw_name); @@ -2241,10 +1419,10 @@ diff -up openssh-7.4p1/sshconnect.c.openssl openssh-7.4p1/sshconnect.c server_user = options.user ? options.user : local_user; /* Convert the user-supplied hostname into all lowercase. */ -diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c ---- openssh-7.4p1/ssh.c.openssl 2016-12-23 17:47:36.422817748 +0100 -+++ openssh-7.4p1/ssh.c 2016-12-23 17:47:36.435817754 +0100 -@@ -532,7 +532,9 @@ main(int ac, char **av) +diff -up openssh/ssh.c.openssl openssh/ssh.c +--- openssh/ssh.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/ssh.c 2017-09-26 13:19:31.800249715 +0200 +@@ -530,7 +530,9 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -2254,7 +1432,7 @@ diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)){ if (FIPS_mode()) -@@ -1247,6 +1249,7 @@ main(int ac, char **av) +@@ -1263,6 +1265,7 @@ main(int ac, char **av) free(cp); } free(conn_hash_hex); @@ -2262,10 +1440,10 @@ diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c if (config_test) { dump_client_config(&options, host); -diff -up openssh-7.4p1/sshd.c.openssl openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.openssl 2016-12-23 17:47:36.428817751 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 17:47:36.435817754 +0100 -@@ -1483,7 +1483,7 @@ main(int ac, char **av) +diff -up openssh/sshd.c.openssl openssh/sshd.c +--- openssh/sshd.c.openssl 2017-09-26 13:19:31.792249666 +0200 ++++ openssh/sshd.c 2017-09-26 13:19:31.801249721 +0200 +@@ -1485,7 +1485,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -2274,9 +1452,9 @@ diff -up openssh-7.4p1/sshd.c.openssl openssh-7.4p1/sshd.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)) { openlog(__progname, LOG_PID, LOG_AUTHPRIV); -diff -up openssh-7.4p1/ssh-dss.c.openssl openssh-7.4p1/ssh-dss.c ---- openssh-7.4p1/ssh-dss.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-dss.c 2016-12-23 17:47:36.435817754 +0100 +diff -up openssh/ssh-dss.c.openssl openssh/ssh-dss.c +--- openssh/ssh-dss.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-dss.c 2017-09-26 13:19:31.801249721 +0200 @@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; @@ -2350,9 +1528,9 @@ diff -up openssh-7.4p1/ssh-dss.c.openssl openssh-7.4p1/ssh-dss.c sshbuf_free(b); free(ktype); if (sigblob != NULL) { -diff -up openssh-7.4p1/ssh-ecdsa.c.openssl openssh-7.4p1/ssh-ecdsa.c ---- openssh-7.4p1/ssh-ecdsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-ecdsa.c 2016-12-23 17:47:36.436817754 +0100 +diff -up openssh/ssh-ecdsa.c.openssl openssh/ssh-ecdsa.c +--- openssh/ssh-ecdsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-ecdsa.c 2017-09-26 13:19:31.801249721 +0200 @@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, size_t len, dlen; struct sshbuf *b = NULL, *bb = NULL; @@ -2420,11 +1598,11 @@ diff -up openssh-7.4p1/ssh-ecdsa.c.openssl openssh-7.4p1/ssh-ecdsa.c free(ktype); return ret; } -diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.openssl 2016-12-23 17:47:36.424817749 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 17:47:56.652826110 +0100 -@@ -275,10 +275,10 @@ sshkey_size(const struct sshkey *k) - case KEY_RSA1: +diff -up openssh/sshkey.c.openssl openssh/sshkey.c +--- openssh/sshkey.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/sshkey.c 2017-09-26 13:19:31.802249728 +0200 +@@ -267,10 +267,10 @@ sshkey_size(const struct sshkey *k) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - return BN_num_bits(k->rsa->n); @@ -2436,10 +1614,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: return sshkey_curve_nid_to_bits(k->ecdsa_nid); -@@ -311,11 +311,17 @@ sshkey_is_private(const struct sshkey *k +@@ -302,11 +302,17 @@ sshkey_is_private(const struct sshkey *k + switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA_CERT: - case KEY_RSA1: - case KEY_RSA: - return k->rsa->d != NULL; + case KEY_RSA: { @@ -2458,8 +1636,8 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -505,11 +511,7 @@ sshkey_new(int type) - case KEY_RSA1: +@@ -496,11 +501,7 @@ sshkey_new(int type) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - if ((rsa = RSA_new()) == NULL || @@ -2471,7 +1649,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c free(k); return NULL; } -@@ -517,13 +519,7 @@ sshkey_new(int type) +@@ -508,13 +509,7 @@ sshkey_new(int type) break; case KEY_DSA: case KEY_DSA_CERT: @@ -2486,8 +1664,8 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c free(k); return NULL; } -@@ -563,21 +559,10 @@ sshkey_add_private(struct sshkey *k) - case KEY_RSA1: +@@ -553,21 +548,10 @@ sshkey_add_private(struct sshkey *k) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: -#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) @@ -2508,9 +1686,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ -@@ -696,17 +681,31 @@ sshkey_equal_public(const struct sshkey +@@ -684,17 +668,31 @@ sshkey_equal_public(const struct sshkey + switch (a->type) { #ifdef WITH_OPENSSL - case KEY_RSA1: case KEY_RSA_CERT: - case KEY_RSA: - return a->rsa != NULL && b->rsa != NULL && @@ -2550,7 +1728,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -781,15 +780,21 @@ to_blob_buf(const struct sshkey *key, st +@@ -769,15 +767,21 @@ to_blob_buf(const struct sshkey *key, st return ret; break; #ifdef WITH_OPENSSL @@ -2581,7 +1759,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -802,13 +807,18 @@ to_blob_buf(const struct sshkey *key, st +@@ -790,13 +794,18 @@ to_blob_buf(const struct sshkey *key, st return ret; break; # endif @@ -2607,93 +1785,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519: -@@ -914,8 +924,13 @@ sshkey_fingerprint_raw(const struct sshk - - if (k->type == KEY_RSA1) { - #ifdef WITH_OPENSSL -- int nlen = BN_num_bytes(k->rsa->n); -- int elen = BN_num_bytes(k->rsa->e); -+ const BIGNUM *n, *e; -+ int nlen, elen; -+ -+ RSA_get0_key(k->rsa, &n, &e, NULL); -+ -+ nlen = BN_num_bytes(n); -+ elen = BN_num_bytes(e); - - if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) { - r = SSH_ERR_INVALID_FORMAT; -@@ -926,8 +941,8 @@ sshkey_fingerprint_raw(const struct sshk - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- BN_bn2bin(k->rsa->n, blob); -- BN_bn2bin(k->rsa->e, blob + nlen); -+ BN_bn2bin(n, blob); -+ BN_bn2bin(e, blob + nlen); - #endif /* WITH_OPENSSL */ - } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) - goto out; -@@ -1290,6 +1305,7 @@ sshkey_read(struct sshkey *ret, char **c - struct sshbuf *blob; - #ifdef WITH_SSH1 - u_long bits; -+ BIGNUM *e = NULL, *n = NULL; - #endif /* WITH_SSH1 */ - - if (ret == NULL) -@@ -1303,12 +1319,21 @@ sshkey_read(struct sshkey *ret, char **c - bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) - return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ - /* Get public exponent, public modulus. */ -- if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) -+ if ((e = BN_new()) == NULL || (n = BN_new()) == NULL) { -+ BN_free(e); -+ return SSH_ERR_ALLOC_FAIL; -+ } -+ if ((r = read_decimal_bignum(&ep, e)) < 0) - return r; -- if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) -+ if ((r = read_decimal_bignum(&ep, n)) < 0) - return r; -+ if (RSA_set0_key(ret->rsa, n, e, NULL) == 0) { -+ BN_free(e); -+ BN_free(n); -+ return -1; -+ } - /* validate the claimed number of bits */ -- if (BN_num_bits(ret->rsa->n) != (int)bits) -+ if (BN_num_bits(n) != (int)bits) - return SSH_ERR_KEY_BITS_MISMATCH; - *cpp = ep; - retval = 0; -@@ -1473,19 +1498,20 @@ sshkey_format_rsa1(const struct sshkey * - #ifdef WITH_SSH1 - u_int bits = 0; - char *dec_e = NULL, *dec_n = NULL; -+ const BIGNUM *e, *n; - -- if (key->rsa == NULL || key->rsa->e == NULL || -- key->rsa->n == NULL) { -+ RSA_get0_key(key->rsa, &n, &e, NULL); -+ if (key->rsa == NULL || e == NULL || n == NULL) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || -- (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { -+ if ((dec_e = BN_bn2dec(e)) == NULL || -+ (dec_n = BN_bn2dec(n)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - /* size of modulus 'n' */ -- if ((bits = BN_num_bits(key->rsa->n)) <= 0) { -+ if ((bits = BN_num_bits(n)) <= 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -@@ -1819,15 +1845,32 @@ sshkey_from_private(const struct sshkey +@@ -1672,15 +1681,32 @@ sshkey_from_private(const struct sshkey switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA: @@ -2735,10 +1827,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; # ifdef OPENSSL_HAS_ECC -@@ -1850,13 +1893,22 @@ sshkey_from_private(const struct sshkey +@@ -1702,13 +1728,22 @@ sshkey_from_private(const struct sshkey + break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: - case KEY_RSA1: - case KEY_RSA_CERT: - if ((n = sshkey_new(k->type)) == NULL) - return SSH_ERR_ALLOC_FAIL; @@ -2765,7 +1857,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; #endif /* WITH_OPENSSL */ -@@ -2054,10 +2106,20 @@ sshkey_from_blob_internal(struct sshbuf +@@ -1907,12 +1942,22 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -2788,9 +1880,12 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + goto out; + } } - #ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); -@@ -2075,12 +2137,34 @@ sshkey_from_blob_internal(struct sshbuf +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { ++ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + ret = SSH_ERR_KEY_LENGTH; + goto out; + } +@@ -1932,12 +1977,34 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -2831,10 +1926,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } #ifdef DEBUG_PK DSA_print_fp(stderr, key->dsa, 8); -@@ -2320,26 +2404,53 @@ sshkey_demote(const struct sshkey *k, st +@@ -2171,26 +2238,53 @@ sshkey_demote(const struct sshkey *k, st + if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ - case KEY_RSA1: - case KEY_RSA: - if ((pk->rsa = RSA_new()) == NULL || - (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || @@ -2899,7 +1994,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; case KEY_ECDSA_CERT: -@@ -2460,12 +2571,17 @@ sshkey_certify(struct sshkey *k, struct +@@ -2312,12 +2406,17 @@ sshkey_certify_custom(struct sshkey *k, /* XXX this substantially duplicates to_blob(); refactor */ switch (k->type) { #ifdef WITH_OPENSSL @@ -2923,7 +2018,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: -@@ -2477,10 +2593,15 @@ sshkey_certify(struct sshkey *k, struct +@@ -2329,10 +2428,15 @@ sshkey_certify_custom(struct sshkey *k, goto out; break; # endif /* OPENSSL_HAS_ECC */ @@ -2943,7 +2038,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: -@@ -2637,43 +2758,65 @@ sshkey_private_serialize(const struct ss +@@ -2505,43 +2609,65 @@ sshkey_private_serialize(const struct ss goto out; switch (key->type) { #ifdef WITH_OPENSSL @@ -3033,7 +2128,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2749,18 +2892,51 @@ sshkey_private_deserialize(struct sshbuf +@@ -2617,18 +2743,51 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3096,7 +2191,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2819,24 +2995,84 @@ sshkey_private_deserialize(struct sshbuf +@@ -2687,29 +2846,89 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3106,8 +2201,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- (r = ssh_rsa_generate_additional_parameters(k)) != 0) - goto out; +- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + { + BIGNUM *n, *e, *d, *iqmp, *p, *q; + @@ -3143,11 +2239,15 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + BN_free(q); + goto out; + } -+ if ((r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) { ++ if ((r = ssh_rsa_generate_additional_parameters(k, iqmp)) != 0) { + BN_free(iqmp); + goto out; + } + } ++ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } break; - case KEY_RSA_CERT: - if ((r = sshkey_froms(buf, &k)) != 0 || @@ -3156,8 +2256,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- (r = ssh_rsa_generate_additional_parameters(k)) != 0) - goto out; +- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + case KEY_RSA_CERT: { + BIGNUM *d, *iqmp, *p, *q; + @@ -3189,164 +2290,28 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + BN_free(q); + goto out; + } -+ if (rsa_generate_additional_parameters(k->rsa, iqmp) != 0) { ++ if (ssh_rsa_generate_additional_parameters(k, iqmp) != 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + free(iqmp); + goto out; + } + } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519: -@@ -3471,6 +3704,7 @@ sshkey_private_rsa1_to_blob(struct sshke - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher; - u_char *cp; -+ const BIGNUM *n, *e, *d, *q, *p, *iqmp; - - /* - * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting -@@ -3497,10 +3731,13 @@ sshkey_private_rsa1_to_blob(struct sshke - * format would just give known plaintext). - * Note: q and p are stored in reverse order to SSL. - */ -- if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) -+ RSA_get0_key(key->rsa, &n, &e, &d); -+ RSA_get0_factors(key->rsa, &p, &q); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ if ((r = sshbuf_put_bignum1(buffer, d)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, iqmp)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, q)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, p)) != 0) - goto out; - - /* Pad the part to be encrypted to a size that is a multiple of 8. */ -@@ -3525,9 +3762,9 @@ sshkey_private_rsa1_to_blob(struct sshke - goto out; - - /* Store public key. This will be in plain text. */ -- if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || -- (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || -+ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(encrypted, n)) != 0 || -+ (r = sshbuf_put_bignum1(encrypted, e)) != 0 || - (r = sshbuf_put_cstring(encrypted, comment)) != 0) - goto out; - -@@ -3654,6 +3891,7 @@ sshkey_parse_public_rsa1_fileblob(struct - int r; - struct sshkey *pub = NULL; - struct sshbuf *copy = NULL; -+ BIGNUM *n = NULL, *e = NULL; - - if (keyp != NULL) - *keyp = NULL; -@@ -3683,10 +3921,16 @@ sshkey_parse_public_rsa1_fileblob(struct - goto out; - - /* Read the public key from the buffer. */ -- if ((pub = sshkey_new(KEY_RSA1)) == NULL || -- (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) -+ if ((n = BN_new()) == NULL || -+ (e = BN_new()) == NULL || -+ (pub = sshkey_new(KEY_RSA1)) == NULL || -+ (r = sshbuf_get_bignum1(copy, n)) != 0 || -+ (r = sshbuf_get_bignum1(copy, e)) != 0 || -+ RSA_set0_key(pub->rsa, n, e, NULL) == 0) { -+ BN_free(n); -+ BN_free(e); - goto out; -+ } - - /* Finally, the comment */ - if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) -@@ -3718,6 +3962,8 @@ sshkey_parse_private_rsa1(struct sshbuf - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher; - struct sshkey *prv = NULL; -+ BIGNUM *n = NULL, *e = NULL, *d = NULL, *q = NULL, *p = NULL, -+ *iqmp = NULL; - - if (keyp != NULL) - *keyp = NULL; -@@ -3753,11 +3999,17 @@ sshkey_parse_private_rsa1(struct sshbuf - goto out; - - /* Read the public key and comment from the buffer. */ -- if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ -- (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || -- (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) -+ if ((n = BN_new()) == NULL || -+ (e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ -+ (r = sshbuf_get_bignum1(copy, n)) != 0 || -+ (r = sshbuf_get_bignum1(copy, e)) != 0 || -+ (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0 || -+ RSA_set0_key(prv->rsa, n, e, NULL) == 0) { -+ BN_free(n); -+ BN_free(e); - goto out; -+ } - - /* Check that it is a supported cipher. */ - cipher = cipher_by_number(cipher_type); -@@ -3786,15 +4038,33 @@ sshkey_parse_private_rsa1(struct sshbuf - } - - /* Read the rest of the private key. */ -- if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) -+ if ((d = BN_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (iqmp = BN_new()) == NULL || -+ (r = sshbuf_get_bignum1(decrypted, d)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, q)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, p)) != 0 || -+ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0)) { -+ BN_free(d); -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); -+ goto out; -+ } -+ if (RSA_set0_factors(prv->rsa, p, q) == 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); - goto out; -+ } - - /* calculate p-1 and q-1 */ -- if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) -+ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) { -+ BN_free(iqmp); - goto out; -+ } - - /* enable blinding */ - if (RSA_blinding_on(prv->rsa, NULL) != 1) { -@@ -3874,7 +4146,9 @@ sshkey_parse_private_pem_fileblob(struct - case EVP_R_BAD_DECRYPT: - r = SSH_ERR_KEY_WRONG_PASSPHRASE; - goto out; ++ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } +@@ -3427,7 +3646,9 @@ translate_libcrypto_error(unsigned long + switch (pem_reason) { + case EVP_R_BAD_DECRYPT: + return SSH_ERR_KEY_WRONG_PASSPHRASE; +#ifdef EVP_R_BN_DECODE_ERROR - case EVP_R_BN_DECODE_ERROR: + case EVP_R_BN_DECODE_ERROR: +#endif - case EVP_R_DECODE_ERROR: + case EVP_R_DECODE_ERROR: #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR - case EVP_R_PRIVATE_KEY_DECODE_ERROR: -@@ -3892,7 +4166,7 @@ sshkey_parse_private_pem_fileblob(struct - r = SSH_ERR_LIBCRYPTO_ERROR; + case EVP_R_PRIVATE_KEY_DECODE_ERROR: +@@ -3492,7 +3713,7 @@ sshkey_parse_private_pem_fileblob(struct + r = convert_libcrypto_error(); goto out; } - if (pk->type == EVP_PKEY_RSA && @@ -3354,16 +2319,21 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3861,7 +4124,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3507,11 +3728,11 @@ sshkey_parse_private_pem_fileblob(struct r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } +- if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { ++ if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } - } else if (pk->type == EVP_PKEY_DSA && + } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3873,7 +4136,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3523,7 +3744,7 @@ sshkey_parse_private_pem_fileblob(struct DSA_print_fp(stderr, prv->dsa, 8); #endif #ifdef OPENSSL_HAS_ECC @@ -3372,10 +2342,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c ---- openssh-7.4p1/ssh-keygen.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keygen.c 2016-12-23 17:47:36.437817755 +0100 -@@ -480,40 +480,67 @@ do_convert_private_ssh2_from_blob(u_char +diff -up openssh/ssh-keygen.c.openssl openssh/ssh-keygen.c +--- openssh/ssh-keygen.c.openssl 2017-09-26 13:19:31.787249636 +0200 ++++ openssh/ssh-keygen.c 2017-09-26 13:19:31.802249728 +0200 +@@ -501,40 +501,67 @@ do_convert_private_ssh2_from_blob(u_char free(type); switch (key->type) { @@ -3456,7 +2426,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c + if (RSA_set0_key(key->rsa, bn_n, bn_e, bn_d) == 0 || + RSA_set0_factors(key->rsa, bn_p, bn_q) == 0) + fatal("Failed to set RSA parameters"); -+ if ((r = rsa_generate_additional_parameters(key->rsa, bn_iqmp)) != 0) ++ if ((r = ssh_rsa_generate_additional_parameters(key, bn_iqmp)) != 0) + fatal("generate RSA parameters failed: %s", ssh_err(r)); } - if (!BN_set_word(key->rsa->e, e)) { @@ -3469,12 +2439,12 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c - buffer_get_bignum_bits(b, key->rsa->iqmp); - buffer_get_bignum_bits(b, key->rsa->q); - buffer_get_bignum_bits(b, key->rsa->p); -- if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) +- if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) - fatal("generate RSA parameters failed: %s", ssh_err(r)); break; } rlen = sshbuf_len(b); -@@ -621,7 +648,7 @@ do_convert_from_pkcs8(struct sshkey **k, +@@ -642,7 +669,7 @@ do_convert_from_pkcs8(struct sshkey **k, identity_file); } fclose(fp); @@ -3483,7 +2453,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c case EVP_PKEY_RSA: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); -@@ -645,7 +672,7 @@ do_convert_from_pkcs8(struct sshkey **k, +@@ -666,7 +693,7 @@ do_convert_from_pkcs8(struct sshkey **k, #endif default: fatal("%s: unsupported pubkey type %d", __func__, @@ -3492,7 +2462,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c } EVP_PKEY_free(pubkey); return; -@@ -1683,6 +1710,7 @@ do_ca_sign(struct passwd *pw, int argc, +@@ -1798,6 +1825,7 @@ do_ca_sign(struct passwd *pw, int argc, #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif @@ -3500,45 +2470,22 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c exit(0); } -diff -up openssh-7.4p1/ssh-keyscan.c.openssl openssh-7.4p1/ssh-keyscan.c ---- openssh-7.4p1/ssh-keyscan.c.openssl 2016-12-23 17:47:36.325817708 +0100 -+++ openssh-7.4p1/ssh-keyscan.c 2016-12-23 17:47:36.437817755 +0100 -@@ -195,6 +195,7 @@ keygrab_ssh1(con *c) - static struct sshbuf *msg; - int r; - u_char type; -+ BIGNUM *n = NULL, *e = NULL; +diff -up openssh/sshkey.h.openssl openssh/sshkey.h +--- openssh/sshkey.h.openssl 2017-09-26 13:19:31.780249593 +0200 ++++ openssh/sshkey.h 2017-09-26 13:19:31.803249734 +0200 +@@ -199,7 +199,7 @@ int sshkey_parse_private_fileblob_type(s + const char *passphrase, struct sshkey **keyp, char **commentp); - if (rsa == NULL) { - if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { -@@ -213,16 +214,20 @@ keygrab_ssh1(con *c) - sshbuf_reset(msg); - return NULL; - } -- if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ -+ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || -+ (r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ - /* server key */ - (r = sshbuf_get_u32(msg, NULL)) != 0 || - (r = sshbuf_get_bignum1(msg, NULL)) != 0 || - (r = sshbuf_get_bignum1(msg, NULL)) != 0 || - /* host key */ - (r = sshbuf_get_u32(msg, NULL)) != 0 || -- (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { -+ (r = sshbuf_get_bignum1(msg, e)) != 0 || -+ (r = sshbuf_get_bignum1(msg, n)) != 0 || -+ RSA_set0_key(rsa->rsa, n, e, NULL) == 0) { - buf_err: -+ BN_free(n); -+ BN_free(e); - error("%s: buffer error: %s", __func__, ssh_err(r)); - sshbuf_reset(msg); - return NULL; -diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-client.c ---- openssh-7.4p1/ssh-pkcs11-client.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-pkcs11-client.c 2016-12-23 17:47:36.437817755 +0100 -@@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, con + /* XXX should be internal, but used by ssh-keygen */ +-int ssh_rsa_generate_additional_parameters(struct sshkey *); ++int ssh_rsa_generate_additional_parameters(struct sshkey *, BIGNUM *iqmp); + + #ifdef SSHKEY_INTERNAL + int ssh_rsa_sign(const struct sshkey *key, +diff -up openssh/ssh-pkcs11-client.c.openssl openssh/ssh-pkcs11-client.c +--- openssh/ssh-pkcs11-client.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-pkcs11-client.c 2017-09-26 13:19:31.803249734 +0200 +@@ -143,12 +143,16 @@ pkcs11_rsa_private_encrypt(int flen, con static int wrap_key(RSA *rsa) { @@ -3551,6 +2498,8 @@ diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-clie - RSA_set_method(rsa, &helper_rsa); + if (helper_rsa == NULL) { + helper_rsa = RSA_meth_dup(RSA_get_default_method()); ++ if (helper_rsa == NULL) ++ error("RSA_meth_dup failed"); + RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper"); + RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt); + } @@ -3558,9 +2507,9 @@ diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-clie return (0); } -diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c ---- openssh-7.4p1/ssh-pkcs11.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-pkcs11.c 2016-12-23 17:47:36.437817755 +0100 +diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c +--- openssh/ssh-pkcs11.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-pkcs11.c 2017-09-26 13:19:31.803249734 +0200 @@ -67,7 +67,7 @@ struct pkcs11_key { struct pkcs11_provider *provider; CK_ULONG slotidx; @@ -3570,6 +2519,14 @@ diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c char *keyid; int keyid_len; }; +@@ -183,6 +183,7 @@ pkcs11_rsa_finish(RSA *rsa) + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ RSA_meth_free(k11->rsa_method); + free(k11); + } + return (rv); @@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider * k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); @@ -3607,7 +2564,7 @@ diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c f = p->function_list; session = p->slotinfo[slotidx].session; -@@ -512,10 +521,14 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -512,10 +521,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_p if ((rsa = RSA_new()) == NULL) { error("RSA_new failed"); } else { @@ -3619,12 +2576,14 @@ diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c - rsa->e = BN_bin2bn(attribs[2].pValue, + rsa_e = BN_bin2bn(attribs[2].pValue, attribs[2].ulValueLen, NULL); ++ if (rsa_n == NULL || rsa_e == NULL) ++ error("BN_bin2bn failed"); + if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0) + error("RSA_set0_key failed"); } } else { cp = attribs[2].pValue; -@@ -525,17 +538,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -525,17 +538,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p == NULL) { error("d2i_X509 failed"); } else if ((evp = X509_get_pubkey(x509)) == NULL || @@ -3642,29 +2601,98 @@ diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c X509_free(x509); } - if (rsa && rsa->n && rsa->e && -+ RSA_get0_key(rsa, &n, &e, NULL); ++ if (rsa) ++ RSA_get0_key(rsa, &n, &e, NULL); + if (rsa && n && e && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - key = sshkey_new(KEY_UNSPEC); - key->rsa = rsa; -diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c ---- openssh-7.4p1/ssh-rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-rsa.c 2016-12-23 17:47:36.437817755 +0100 -@@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u - hash_alg = rsa_hash_alg_from_ident(alg_ident); - if (key == NULL || key->rsa == NULL || hash_alg == -1 || - sshkey_type_plain(key->type) != KEY_RSA || -- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_INVALID_ARGUMENT; - slen = RSA_size(key->rsa); - if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) -@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key, + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); +diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c +--- openssh/ssh-rsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-rsa.c 2017-09-26 13:19:31.803249734 +0200 +@@ -78,37 +78,46 @@ rsa_hash_alg_nid(int type) + } + } + +-/* calculate p-1 and q-1 */ ++/* calculate d mod p-1 and d mod q-1 */ + int +-ssh_rsa_generate_additional_parameters(struct sshkey *key) ++ssh_rsa_generate_additional_parameters(struct sshkey *key, BIGNUM *iqmp) + { +- RSA *rsa; + BIGNUM *aux = NULL; + BN_CTX *ctx = NULL; + int r; ++ const BIGNUM *p, *q, *d; ++ BIGNUM *dmp1 = NULL, *dmq1 = NULL; if (key == NULL || key->rsa == NULL || - sshkey_type_plain(key->type) != KEY_RSA || -- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE || -+ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE || - sig == NULL || siglen == 0) + sshkey_type_plain(key->type) != KEY_RSA) return SSH_ERR_INVALID_ARGUMENT; +- if ((ctx = BN_CTX_new()) == NULL) +- return SSH_ERR_ALLOC_FAIL; +- if ((aux = BN_new()) == NULL) { ++ RSA_get0_factors(key->rsa, &p, &q); ++ RSA_get0_key(key->rsa, NULL, NULL, &d); ++ ++ if ((ctx = BN_CTX_new()) == NULL || ++ (aux = BN_new()) == NULL || ++ (dmp1 = BN_new()) == NULL || ++ (dmq1 = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- rsa = key->rsa; + +- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || +- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || +- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || +- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { ++ if ((BN_sub(aux, q, BN_value_one()) == 0) || ++ (BN_mod(dmq1, d, aux, ctx) == 0) || ++ (BN_sub(aux, p, BN_value_one()) == 0) || ++ (BN_mod(dmp1, d, aux, ctx) == 0) || ++ (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0)) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ++ dmp1 = NULL; ++ dmq1 = NULL; + r = 0; + out: + BN_clear_free(aux); ++ BN_clear_free(dmp1); ++ BN_clear_free(dmq1); + BN_CTX_free(ctx); + return r; + } +@@ -136,7 +145,7 @@ ssh_rsa_sign(const struct sshkey *key, u + if (key == NULL || key->rsa == NULL || hash_alg == -1 || + sshkey_type_plain(key->type) != KEY_RSA) + return SSH_ERR_INVALID_ARGUMENT; +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) ++ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; + slen = RSA_size(key->rsa); + if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) +@@ -210,7 +219,7 @@ ssh_rsa_verify(const struct sshkey *key, + sshkey_type_plain(key->type) != KEY_RSA || + sig == NULL || siglen == 0) + return SSH_ERR_INVALID_ARGUMENT; +- if (BN_num_bits(key->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) +--- openssh-7.6p1/configure.ac.openssl 2017-10-04 15:47:48.440672023 +0200 ++++ openssh-7.6p1/configure.ac 2017-10-04 15:47:23.327531495 +0200 +@@ -2730,6 +2730,7 @@ + AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) + ;; + 100*) ;; # 1.0.x ++ 101*) ;; # 1.1.x is supported by this patch too + 200*) ;; # LibreSSL + *) + AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")]) diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index f973010..b36671d 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -2,26 +2,25 @@ 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 - /* Saved X11 local (client) display. */ - static char *x11_saved_display = NULL; -@@ -4228,7 +4228,8 @@ channel_send_window_changes(void) + /* + * Data structure for storing which hosts are permitted for forward requests. +@@ -4228,7 +4228,7 @@ channel_send_window_changes(void) */ int - x11_create_display_inet(int x11_display_offset, int x11_use_localhost, -- int single_connection, u_int *display_numberp, int **chanids) -+ int x11_max_displays, int single_connection, u_int *display_numberp, -+ int **chanids) + x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +- int x11_use_localhost, int single_connection, ++ int x11_use_localhost, int x11_max_displays, int single_connection, + u_int *display_numberp, int **chanids) { Channel *nc = NULL; - int display_number, sock; @@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ if (chanids == NULL) return -1; @@ -38,7 +37,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c + if (port < X11_PORT_MIN) /* overflow */ + break; memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; + 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) @@ -51,7 +50,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c } @@ -4441,7 +4447,7 @@ x11_connect_display(void) memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; + 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); @@ -71,8 +70,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c } freeaddrinfo(aitop); if (!ai) { -- error("connect %.100s port %u: %.100s", buf, 6000 + display_number, -- strerror(errno)); +- 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; @@ -83,13 +82,13 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h +++ 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(u_int); - int x11_connect_display(void); --int x11_create_display_inet(int, int, int, u_int *, int **); -+int x11_create_display_inet(int, int, int, int, u_int *, int **); - int x11_input_open(int, u_int32_t, void *); - void x11_request_forwarding_with_spoofing(int, const char *, const char *, - const char *, int); + 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); + 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 @@ -179,7 +178,7 @@ diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c @@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s) return 0; } - if (x11_create_display_inet(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, diff --git a/openssh-7.5p1-gss-environment.patch b/openssh-7.5p1-gss-environment.patch new file mode 100644 index 0000000..5b5d661 --- /dev/null +++ b/openssh-7.5p1-gss-environment.patch @@ -0,0 +1,259 @@ +diff --git a/auth-krb5.c b/auth-krb5.c +index 09ed151..282fcca 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -182,7 +182,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, &authctxt->krb5_set_env); + if (problem) + goto out; + +@@ -192,7 +192,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) + + + #ifdef USE_PAM +- if (options.use_pam) ++ if (options.use_pam && authctxt->krb5_set_env) + do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); + #endif + +@@ -412,7 +413,7 @@ ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { + + #ifndef HEIMDAL + krb5_error_code +-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { ++ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno; + char *ccname; + #ifdef USE_CCAPI +@@ -423,8 +424,10 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { + + #endif + ++ if (need_environment) ++ *need_environment = 0; + ret = ssh_krb5_get_cctemplate(ctx, &ccname); +- ++ /* fallback to the ccache in /tmp */ + if (ret) { + ret = asprintf(&ccname, cctemplate, geteuid()); + if (ret == -1) +@@ -444,6 +447,9 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { + close(tmpfd); + return oerrno; + } ++ /* make sure the KRBCCNAME is set for non-standard location */ ++ if (need_environment) ++ *need_environment = 1; + close(tmpfd); + } + debug("%s: Setting ccname to %s", __func__, ccname); +diff --git a/auth.h b/auth.h +index 954a0dd..0819483 100644 +--- a/auth.h ++++ b/auth.h +@@ -78,6 +78,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -220,7 +221,7 @@ int sys_auth_passwd(Authctxt *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) + #include +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *, int *); + krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, + char **k5login_directory); + #endif +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 0fa3838..4127245 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -382,7 +382,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, + /* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ + +-static void ++static int + ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + { + krb5_ccache ccache; +@@ -391,14 +391,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + OM_uint32 maj_status, min_status; + const char *new_ccname, *new_cctype; + const char *errmsg; ++ int set_env = 0; + + if (client->creds == NULL) { + debug("No credentials stored"); +- return; ++ return 0; + } + + if (ssh_gssapi_krb5_init() == 0) +- return; ++ return 0; + + #ifdef HEIMDAL + # ifdef HAVE_KRB5_CC_NEW_UNIQUE +@@ -412,14 +413,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_get_err_text(krb_context, problem)); + # endif + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + #else +- if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { ++ if ((problem = ssh_krb5_cc_gen(krb_context, &ccache, &set_env))) { + errmsg = krb5_get_error_message(krb_context, problem); + logit("ssh_krb5_cc_gen(): %.100s", errmsg); + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + #endif /* #ifdef HEIMDAL */ + +@@ -428,7 +429,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + errmsg = krb5_get_error_message(krb_context, problem); + logit("krb5_parse_name(): %.100s", errmsg); + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + + if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { +@@ -437,7 +438,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_free_error_message(krb_context, errmsg); + krb5_free_principal(krb_context, princ); + krb5_cc_destroy(krb_context, ccache); +- return; ++ return 0; + } + + krb5_free_principal(krb_context, princ); +@@ -446,7 +447,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + client->creds, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); +- return; ++ return 0; + } + + new_cctype = krb5_cc_get_type(krb_context, ccache); +@@ -471,7 +478,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + #endif + + #ifdef USE_PAM +- if (options.use_pam) ++ if (options.use_pam && set_env) + do_pam_putenv(client->store.envvar, client->store.envval); + #endif + +@@ -479,7 +486,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + + client->store.data = krb_context; + +- return; ++ return set_env; + } + + int +diff --git a/gss-serv.c b/gss-serv.c +index 681847a..2a02dae 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -404,7 +404,7 @@ ssh_gssapi_cleanup_creds(void) + debug("%s: krb5_cc_resolve(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { +- debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ debug("%s: krb5_cc_destroy(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else { + krb5_free_context(gssapi_client.store.data); +@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) + } + + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } + + /* This allows GSSAPI methods to do things to the childs environment based +diff --git a/session.c b/session.c +index df4985a..b7a6a57 100644 +--- a/session.c ++++ b/session.c +@@ -1084,7 +1084,8 @@ do_setup_env(Session *s, const char *shell) + /* Allow any GSSAPI methods that we've used to alter + * the childs environment as they see fit + */ +- ssh_gssapi_do_child(&env, &envsize); ++ if (s->authctxt->krb5_set_env) ++ ssh_gssapi_do_child(&env, &envsize); + #endif + + /* Set basic environment. */ +@@ -1196,7 +1197,7 @@ do_setup_env(Session *s, const char *shell) + } + #endif + #ifdef KRB5 +- if (s->authctxt->krb5_ccname) ++ if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env) + child_set_env(&env, &envsize, "KRB5CCNAME", + s->authctxt->krb5_ccname); + #endif +diff --git a/ssh-gss.h b/ssh-gss.h +index 6f2b0ac..73ef2c2 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -106,7 +106,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -163,7 +163,7 @@ char* ssh_gssapi_get_displayname(void); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); +diff --git a/sshd.c b/sshd.c +index ce2e374..3c4e13e 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2221,7 +2221,7 @@ main(int ac, char **av) + #ifdef GSSAPI + if (options.gss_authentication) { + temporarily_use_uid(authctxt->pw); +- ssh_gssapi_storecreds(); ++ authctxt->krb5_set_env = ssh_gssapi_storecreds(); + restore_uid(); + } + #endif + diff --git a/openssh-7.5p1-gssapi-kex-with-ec.patch b/openssh-7.5p1-gssapi-kex-with-ec.patch new file mode 100644 index 0000000..437cce6 --- /dev/null +++ b/openssh-7.5p1-gssapi-kex-with-ec.patch @@ -0,0 +1,1374 @@ +From 6ff8f667f792052fd47689c3e421fcd6ddca1cd0 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 25 Aug 2017 19:15:48 +0200 +Subject: [PATCH 1/3] GSSAPI Key exchange methods with DH and SHA2 + +--- + gss-genr.c | 10 ++++++++++ + kex.c | 2 ++ + kex.h | 2 ++ + kexgssc.c | 6 ++++++ + kexgsss.c | 6 ++++++ + monitor.c | 2 ++ + regress/kextype.sh | 4 +++- + regress/rekey.sh | 8 ++++++-- + ssh-gss.h | 2 ++ + ssh_config.5 | 4 +++- + sshconnect2.c | 2 ++ + sshd.c | 2 ++ + sshd_config.5 | 4 +++- + 13 files changed, 49 insertions(+), 5 deletions(-) + +diff --git a/gss-genr.c b/gss-genr.c +index dc63682d..c6eff3d7 100644 +--- a/gss-genr.c ++++ b/gss-genr.c +@@ -183,6 +183,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { + return GSS_C_NO_OID; + name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; + break; ++ case KEX_GSS_GRP14_SHA256: ++ if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID)) ++ return GSS_C_NO_OID; ++ name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1; ++ break; ++ case KEX_GSS_GRP16_SHA512: ++ if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID)) ++ return GSS_C_NO_OID; ++ name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1; ++ break; + case KEX_GSS_GEX_SHA1: + if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) + return GSS_C_NO_OID; +diff --git a/kex.c b/kex.c +index 63e028fa..e798fecb 100644 +--- a/kex.c ++++ b/kex.c +@@ -112,6 +112,8 @@ static const struct kexalg kexalgs[] = { + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, + #endif + { NULL, -1, -1, -1}, + }; +diff --git a/kex.h b/kex.h +index 8a2b37c5..f27958ae 100644 +--- a/kex.h ++++ b/kex.h +@@ -102,6 +102,8 @@ enum kex_exchange { + #ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GRP14_SHA256, ++ KEX_GSS_GRP16_SHA512, + KEX_GSS_GEX_SHA1, + #endif + KEX_MAX +diff --git a/kexgssc.c b/kexgssc.c +index 132df8b5..ed23f06d 100644 +--- a/kexgssc.c ++++ b/kexgssc.c +@@ -88,8 +88,12 @@ kexgss_client(struct ssh *ssh) { + dh = dh_new_group1(); + break; + case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: + dh = dh_new_group14(); + break; ++ case KEX_GSS_GRP16_SHA512: ++ dh = dh_new_group16(); ++ break; + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange\n"); + nbits = dh_estimate(ssh->kex->we_need * 8); +@@ -272,6 +276,8 @@ kexgss_client(struct ssh *ssh) { + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: + kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, + ssh->kex->server_version_string, + buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), +diff --git a/kexgsss.c b/kexgsss.c +index 82a715cc..b7da8823 100644 +--- a/kexgsss.c ++++ b/kexgsss.c +@@ -104,8 +104,12 @@ kexgss_server(struct ssh *ssh) + dh = dh_new_group1(); + break; + case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: + dh = dh_new_group14(); + break; ++ case KEX_GSS_GRP16_SHA512: ++ dh = dh_new_group16(); ++ break; + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange"); + packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); +@@ -223,6 +227,8 @@ kexgss_server(struct ssh *ssh) + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: + kex_dh_hash(ssh->kex->hash_alg, + ssh->kex->client_version_string, ssh->kex->server_version_string, + buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), +diff --git a/monitor.c b/monitor.c +index 17046936..d6bc7ac7 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -1648,6 +1648,8 @@ monitor_apply_keystate(struct monitor *pmonitor) + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; + } + #endif +diff --git a/regress/kextype.sh b/regress/kextype.sh +index 780362ca..45f4f16d 100644 +--- a/regress/kextype.sh ++++ b/regress/kextype.sh +@@ -14,7 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy + + tries="1 2 3 4" + for k in `${SSH} -Q kex`; do +- if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o $k = "gss-group14-sha1-" ]; then ++ if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ ++ $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ ++ $k = "gss-group16-sha512-" ]; then + continue + fi + verbose "kex $k" +diff --git a/regress/rekey.sh b/regress/rekey.sh +index 9fbe9b38..a2921bef 100644 +--- a/regress/rekey.sh ++++ b/regress/rekey.sh +@@ -38,7 +38,9 @@ increase_datafile_size 300 + + opts="" + for i in `${SSH} -Q kex`; do +- if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o $i = "gss-group14-sha1-" ]; then ++ if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ ++ $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ ++ $i = "gss-group16-sha512-" ]; then + continue + fi + opts="$opts KexAlgorithms=$i" +@@ -59,7 +61,9 @@ done + if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do +- if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o $kex = "gss-group14-sha1-" ]; then ++ if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ ++ $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ ++ $kex = "gss-group16-sha512-" ]; then + continue + fi + verbose "client rekey $c $kex" +diff --git a/ssh-gss.h b/ssh-gss.h +index 6b6adb2b..7bf8d75e 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -70,6 +70,8 @@ + #define SSH2_MSG_KEXGSS_GROUP 41 + #define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" + #define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" ++#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" ++#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" + #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" + + #define GSS_KEX_DEFAULT_KEX \ +diff --git a/ssh_config.5 b/ssh_config.5 +index 6b24649e..3d6da510 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -760,7 +760,9 @@ key exchange. Possible values are + .Bd -literal -offset 3n + gss-gex-sha1-, + gss-group1-sha1-, +-gss-group14-sha1- ++gss-group14-sha1-, ++gss-group14-sha256-, ++gss-group16-sha512- + .Ed + .Pp + The default is +diff --git a/sshconnect2.c b/sshconnect2.c +index 8db98293..5d6b8be0 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -253,6 +253,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; + } + #endif +diff --git a/sshd.c b/sshd.c +index 895df26f..e4c879a2 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2244,6 +2244,8 @@ do_ssh2_kex(void) + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; + } + #endif +diff --git a/sshd_config.5 b/sshd_config.5 +index bf81f6af..0793418b 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -675,7 +675,9 @@ key exchange. Possible values are + .Bd -literal -offset 3n + gss-gex-sha1-, + gss-group1-sha1-, +-gss-group14-sha1- ++gss-group14-sha1-, ++gss-group14-sha256-, ++gss-group16-sha512- + .Ed + .Pp + The default is +-- +2.13.5 + + +From 7d56144903fc625c33da7fabf103f4f6bba4d43a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 29 Aug 2017 15:32:14 +0200 +Subject: [PATCH 2/3] GSSAPI Key exchange using ECDH and SHA2 + +--- + gss-genr.c | 10 ++ + kex.c | 3 + + kex.h | 4 + + kexgssc.c | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + kexgsss.c | 333 +++++++++++++++++++++++++++++++++++++++++++++ + monitor.c | 5 +- + regress/kextype.sh | 1 + + regress/rekey.sh | 2 + + ssh-gss.h | 2 + + ssh_config.5 | 4 +- + sshconnect2.c | 2 + + sshd.c | 2 + + sshd_config.5 | 4 +- + 13 files changed, 754 insertions(+), 10 deletions(-) + +diff --git a/gss-genr.c b/gss-genr.c +index c6eff3d7..22040244 100644 +--- a/gss-genr.c ++++ b/gss-genr.c +@@ -198,6 +198,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { + return GSS_C_NO_OID; + name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; + break; ++ case KEX_GSS_NISTP256_SHA256: ++ if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID)) ++ return GSS_C_NO_OID; ++ name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1; ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID)) ++ return GSS_C_NO_OID; ++ name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1; ++ break; + default: + return GSS_C_NO_OID; + } +diff --git a/kex.c b/kex.c +index e798fecb..bdeeada9 100644 +--- a/kex.c ++++ b/kex.c +@@ -114,6 +114,9 @@ static const struct kexalg kexalgs[] = { + { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, + #endif + { NULL, -1, -1, -1}, + }; +diff --git a/kex.h b/kex.h +index f27958ae..7def8561 100644 +--- a/kex.h ++++ b/kex.h +@@ -105,6 +105,8 @@ enum kex_exchange { + KEX_GSS_GRP14_SHA256, + KEX_GSS_GRP16_SHA512, + KEX_GSS_GEX_SHA1, ++ KEX_GSS_NISTP256_SHA256, ++ KEX_GSS_C25519_SHA256, + #endif + KEX_MAX + }; +@@ -211,6 +213,8 @@ int kexecdh_server(struct ssh *); + int kexc25519_client(struct ssh *); + int kexc25519_server(struct ssh *); + #ifdef GSSAPI ++int kexecgss_client(struct ssh *); ++int kexecgss_server(struct ssh *); + int kexgss_client(struct ssh *); + int kexgss_server(struct ssh *); + #endif +diff --git a/kexgssc.c b/kexgssc.c +index ed23f06d..bdb3109a 100644 +--- a/kexgssc.c ++++ b/kexgssc.c +@@ -43,6 +43,7 @@ + #include "packet.h" + #include "dh.h" + #include "digest.h" ++#include "ssherr.h" + + #include "ssh-gss.h" + +@@ -52,7 +53,7 @@ kexgss_client(struct ssh *ssh) { + gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; + Gssctxt *ctxt; + OM_uint32 maj_status, min_status, ret_flags; +- u_int klen, kout, slen = 0, strlen; ++ u_int klen, kout, slen = 0, packet_len; + DH *dh; + BIGNUM *dh_server_pub = NULL; + BIGNUM *shared_secret = NULL; +@@ -201,20 +202,20 @@ kexgss_client(struct ssh *ssh) { + debug("Received GSSAPI_CONTINUE"); + if (maj_status == GSS_S_COMPLETE) + fatal("GSSAPI Continue received from server when complete"); +- recv_tok.value = packet_get_string(&strlen); +- recv_tok.length = strlen; ++ recv_tok.value = packet_get_string(&packet_len); ++ recv_tok.length = packet_len; + break; + case SSH2_MSG_KEXGSS_COMPLETE: + debug("Received GSSAPI_COMPLETE"); + packet_get_bignum2(dh_server_pub); +- msg_tok.value = packet_get_string(&strlen); +- msg_tok.length = strlen; ++ msg_tok.value = packet_get_string(&packet_len); ++ msg_tok.length = packet_len; + + /* Is there a token included? */ + if (packet_get_char()) { + recv_tok.value= +- packet_get_string(&strlen); +- recv_tok.length = strlen; ++ packet_get_string(&packet_len); ++ recv_tok.length = packet_len; + /* If we're already complete - protocol error */ + if (maj_status == GSS_S_COMPLETE) + packet_disconnect("Protocol error: received token when complete"); +@@ -344,4 +345,381 @@ kexgss_client(struct ssh *ssh) { + return kex_send_newkeys(ssh); + } + ++int ++kexecgss_client(struct ssh *ssh) { ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; ++ Gssctxt *ctxt; ++ OM_uint32 maj_status, min_status, ret_flags; ++ u_int klen = 0, slen = 0, packet_len; ++ u_char *server_pub = NULL; ++ u_int server_pub_len = 0; ++ BIGNUM *shared_secret = NULL; ++ u_char *kbuf; ++ u_char *serverhostkey = NULL; ++ u_char *empty = ""; ++ char *msg; ++ char *lang; ++ int type = 0; ++ int first = 1; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ const EC_GROUP *group = NULL; ++ const EC_POINT *public_key; ++ struct sshbuf *Q_C = NULL; ++ struct kex *kex = ssh->kex; ++ EC_POINT *server_public = NULL; ++ struct sshbuf *c25519_shared_secret = NULL; ++ int r; ++ ++ /* Initialise our GSSAPI world */ ++ ssh_gssapi_build_ctx(&ctxt); ++ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) ++ == GSS_C_NO_OID) ++ fatal("Couldn't identify host exchange"); ++ ++ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ fatal("Couldn't import hostname"); ++ ++ if (kex->gss_client && ++ ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ fatal("Couldn't acquire client credentials"); ++ ++ if ((Q_C = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if ((kex->ec_client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if (EC_KEY_generate_key(kex->ec_client_key) != 1) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ group = EC_KEY_get0_group(kex->ec_client_key); ++ public_key = EC_KEY_get0_public_key(kex->ec_client_key); ++#ifdef DEBUG_KEXECDH ++ fputs("client private key:\n", stderr); ++ sshkey_dump_ec_key(kex->ec_client_key); ++#endif ++ ++ sshbuf_put_ec(Q_C, public_key, group); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey); ++#ifdef DEBUG_KEXECDH ++ dump_digest("client private key:", kex->c25519_client_key, ++ sizeof(kex->c25519_client_key)); ++#endif ++ ++ sshbuf_put_string(Q_C, kex->c25519_client_pubkey, ++ sizeof(kex->c25519_client_pubkey)); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ token_ptr = GSS_C_NO_BUFFER; ++ ++ do { ++ /* Step 2 - call GSS_Init_sec_context() */ ++ debug("Calling gss_init_sec_context"); ++ ++ maj_status = ssh_gssapi_init_ctx(ctxt, ++ kex->gss_deleg_creds, token_ptr, &send_tok, ++ &ret_flags); ++ ++ if (GSS_ERROR(maj_status)) { ++ if (send_tok.length != 0) { ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE); ++ packet_put_string(send_tok.value, ++ send_tok.length); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ free(recv_tok.value); ++ ++ if (maj_status == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (first) { ++ const u_char * ptr; ++ size_t len; ++ ++ packet_start(SSH2_MSG_KEXGSS_INIT); ++ packet_put_string(send_tok.value, ++ send_tok.length); ++ sshbuf_get_string_direct(Q_C, &ptr, &len); ++ packet_put_string(ptr, len); ++ first = 0; ++ } else { ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE); ++ packet_put_string(send_tok.value, ++ send_tok.length); ++ } ++ packet_send(); ++ gss_release_buffer(&min_status, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ do { ++ type = packet_read(); ++ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ debug("Received KEXGSS_HOSTKEY"); ++ if (serverhostkey) ++ fatal("Server host key received more than once"); ++ serverhostkey = ++ packet_get_string(&slen); ++ } ++ } while (type == SSH2_MSG_KEXGSS_HOSTKEY); ++ ++ switch (type) { ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ debug("Received GSSAPI_CONTINUE"); ++ if (maj_status == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ recv_tok.value = packet_get_string(&packet_len); ++ recv_tok.length = packet_len; ++ break; ++ case SSH2_MSG_KEXGSS_COMPLETE: ++ debug("Received GSSAPI_COMPLETE"); ++ server_pub = packet_get_string(&server_pub_len); ++ msg_tok.value = packet_get_string(&packet_len); ++ msg_tok.length = packet_len; ++ ++ /* Is there a token included? */ ++ if (packet_get_char()) { ++ recv_tok.value= ++ packet_get_string(&packet_len); ++ recv_tok.length = packet_len; ++ /* If we're already complete - protocol error */ ++ if (maj_status == GSS_S_COMPLETE) ++ packet_disconnect("Protocol error: received token when complete"); ++ } else { ++ /* No token included */ ++ if (maj_status != GSS_S_COMPLETE) ++ packet_disconnect("Protocol error: did not receive final token"); ++ } ++ break; ++ case SSH2_MSG_KEXGSS_ERROR: ++ debug("Received Error"); ++ maj_status = packet_get_int(); ++ min_status = packet_get_int(); ++ msg = packet_get_string(NULL); ++ lang = packet_get_string(NULL); ++ fatal("GSSAPI Error: \n%.400s",msg); ++ default: ++ packet_disconnect("Protocol error: didn't expect packet type %d", ++ type); ++ } ++ token_ptr = &recv_tok; ++ } else { ++ /* No data, and not complete */ ++ if (maj_status != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ /* ++ * We _must_ have received a COMPLETE message in reply from the ++ * server, which will have set dh_server_pub and msg_tok ++ */ ++ ++ if (type != SSH2_MSG_KEXGSS_COMPLETE) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ ++ /* 7. C verifies that the key Q_S is valid */ ++ /* 8. C computes shared secret */ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if (server_pub_len != 65) ++ fatal("The received NIST-P256 key did not match" ++ "expected length (expected 65, got %d)", server_pub_len); ++ ++ if (server_pub[0] != POINT_CONVERSION_UNCOMPRESSED) ++ fatal("The received NIST-P256 key does not have first octet 0x04"); ++ ++ if ((server_public = EC_POINT_new(group)) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if (!EC_POINT_oct2point(group, server_public, server_pub, ++ server_pub_len, NULL)) ++ fatal("Can not decode received NIST-P256 client key"); ++#ifdef DEBUG_KEXECDH ++ fputs("server public key:\n", stderr); ++ sshkey_dump_ec_point(group, server_public); ++#endif ++ ++ if (sshkey_ec_validate_public(group, server_public) != 0) { ++ sshpkt_disconnect(ssh, "invalid client public key"); ++ r = SSH_ERR_MESSAGE_INCOMPLETE; ++ goto out; ++ } ++ ++ if (!EC_POINT_is_on_curve(group, server_public, NULL)) ++ fatal("Received NIST-P256 client key is not on curve"); ++ ++ /* Calculate shared_secret */ ++ klen = (EC_GROUP_get_degree(group) + 7) / 8; ++ if ((kbuf = malloc(klen)) == NULL || ++ (shared_secret = BN_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if (ECDH_compute_key(kbuf, klen, server_public, ++ kex->ec_client_key, NULL) != (int)klen || ++ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++#ifdef DEBUG_KEXECDH ++ dump_digest("shared secret", kbuf, klen); ++#endif ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if (server_pub_len != 32) ++ fatal("The received curve25519 key did not match" ++ "expected length (expected 32, got %d)", server_pub_len); ++ ++ if (server_pub[server_pub_len-1] & 0x80) ++ fatal("The received key has MSB of last octet set!"); ++#ifdef DEBUG_KEXECDH ++ dump_digest("server public key:", server_pub, CURVE25519_SIZE); ++#endif ++ ++ /* generate shared secret */ ++ if ((c25519_shared_secret = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if ((r = kexc25519_shared_key(kex->c25519_client_key, ++ server_pub, c25519_shared_secret)) < 0) ++ goto out; ++ ++ /* if all octets of the shared secret are zero octets, ++ * is already checked in kexc25519_shared_key() */ ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ hashlen = sizeof(hash); ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ kex_ecdh_hash( ++ kex->hash_alg, ++ group, ++ kex->client_version_string, ++ kex->server_version_string, ++ sshbuf_ptr(kex->my), sshbuf_len(kex->my), ++ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), ++ (serverhostkey ? serverhostkey : empty), slen, ++ EC_KEY_get0_public_key(kex->ec_client_key), ++ server_public, ++ shared_secret, ++ hash, &hashlen ++ ); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ kex_c25519_hash( ++ kex->hash_alg, ++ kex->client_version_string, kex->server_version_string, ++ buffer_ptr(kex->my), buffer_len(kex->my), ++ buffer_ptr(kex->peer), buffer_len(kex->peer), ++ (serverhostkey ? serverhostkey : empty), slen, ++ kex->c25519_client_pubkey, server_pub, ++ sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), ++ hash, &hashlen ++ ); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ /* Verify that the hash matches the MIC we just got. */ ++ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ packet_disconnect("Hash's MIC didn't verify"); ++ ++ free(msg_tok.value); ++ ++ /* save session id */ ++ if (kex->session_id == NULL) { ++ kex->session_id_len = hashlen; ++ kex->session_id = xmalloc(kex->session_id_len); ++ memcpy(kex->session_id, hash, kex->session_id_len); ++ } ++ ++ if (kex->gss_deleg_creds) ++ ssh_gssapi_credentials_updated(ctxt); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ /* Finally derive the keys and send them */ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0) ++ goto out; ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0) ++ goto out; ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ r = kex_send_newkeys(ssh); ++out: ++ free(serverhostkey); ++ explicit_bzero(hash, sizeof(hash)); ++ sshbuf_free(Q_C); ++ if (server_pub) ++ free(server_pub); ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if (kex->ec_client_key) { ++ EC_KEY_free(kex->ec_client_key); ++ kex->ec_client_key = NULL; ++ } ++ if (server_public) ++ EC_POINT_clear_free(server_public); ++ if (kbuf) { ++ explicit_bzero(kbuf, klen); ++ free(kbuf); ++ } ++ if (shared_secret) ++ BN_clear_free(shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); ++ sshbuf_free(c25519_shared_secret); ++ break; ++ } ++ return r; ++} + #endif /* GSSAPI */ +diff --git a/kexgsss.c b/kexgsss.c +index b7da8823..a7c42803 100644 +--- a/kexgsss.c ++++ b/kexgsss.c +@@ -46,6 +46,7 @@ + #include "servconf.h" + #include "ssh-gss.h" + #include "digest.h" ++#include "ssherr.h" + + extern ServerOptions options; + +@@ -303,4 +304,336 @@ kexgss_server(struct ssh *ssh) + ssh_gssapi_rekey_creds(); + return 0; + } ++ ++int ++kexecgss_server(struct ssh *ssh) ++{ ++ OM_uint32 maj_status, min_status; ++ ++ /* ++ * Some GSSAPI implementations use the input value of ret_flags (an ++ * output variable) as a means of triggering mechanism specific ++ * features. Initializing it to zero avoids inadvertently ++ * activating this non-standard behaviour. ++ */ ++ ++ OM_uint32 ret_flags = 0; ++ gss_buffer_desc gssbuf, recv_tok, msg_tok; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ Gssctxt *ctxt = NULL; ++ u_int slen, klen = 0; ++ u_char *kbuf; ++ BIGNUM *shared_secret = NULL; ++ int type = 0; ++ gss_OID oid; ++ char *mechs; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ u_char *client_pub = NULL; ++ u_int client_pub_len = 0; ++ const EC_GROUP *group = NULL; ++ EC_POINT *client_public = NULL; ++ EC_KEY *server_key = NULL; ++ const EC_POINT *public_key; ++ u_char c25519_server_key[CURVE25519_SIZE]; ++ u_char c25519_server_pubkey[CURVE25519_SIZE]; ++ struct sshbuf *c25519_shared_secret = NULL; ++ struct sshbuf *Q_S; ++ struct kex *kex = ssh->kex; ++ int r; ++ ++ /* Initialise GSSAPI */ ++ ++ /* If we're rekeying, privsep means that some of the private structures ++ * in the GSSAPI code are no longer available. This kludges them back ++ * into life ++ */ ++ if (!ssh_gssapi_oid_table_ok()) ++ if ((mechs = ssh_gssapi_server_mechanisms())) ++ free(mechs); ++ ++ debug2("%s: Identifying %s", __func__, kex->name); ++ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); ++ if (oid == GSS_C_NO_OID) ++ fatal("Unknown gssapi mechanism"); ++ ++ debug2("%s: Acquiring credentials", __func__); ++ ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ fatal("Unable to acquire credentials for the server"); ++ ++ if ((Q_S = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ /* 5. S generates an ephemeral key pair (do the allocations early) */ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ 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) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ group = EC_KEY_get0_group(server_key); ++ public_key = EC_KEY_get0_public_key(server_key); ++ ++ sshbuf_put_ec(Q_S, public_key, group); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ kexc25519_keygen(c25519_server_key, c25519_server_pubkey); ++#ifdef DEBUG_KEXECDH ++ dump_digest("server private key:", c25519_server_key, ++ sizeof(c25519_server_key)); ++#endif ++ sshbuf_put_string(Q_S, c25519_server_pubkey, ++ sizeof(c25519_server_pubkey)); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ do { ++ debug("Wait SSH2_MSG_GSSAPI_INIT"); ++ type = packet_read(); ++ switch(type) { ++ case SSH2_MSG_KEXGSS_INIT: ++ if (client_pub != NULL) ++ fatal("Received KEXGSS_INIT after initialising"); ++ recv_tok.value = packet_get_string(&slen); ++ recv_tok.length = slen; ++ ++ client_pub = packet_get_string(&client_pub_len); ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ break; ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ recv_tok.value = packet_get_string(&slen); ++ recv_tok.length = slen; ++ break; ++ default: ++ packet_disconnect( ++ "Protocol error: didn't expect packet type %d", ++ type); ++ } ++ ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags)); ++ ++ free(recv_tok.value); ++ ++ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) ++ fatal("Zero length token output when incomplete"); ++ ++ if (client_pub == NULL) ++ fatal("No client public key"); ++ ++ if (maj_status & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE); ++ packet_put_string(send_tok.value, send_tok.length); ++ packet_send(); ++ gss_release_buffer(&min_status, &send_tok); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ if (GSS_ERROR(maj_status)) { ++ if (send_tok.length > 0) { ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE); ++ packet_put_string(send_tok.value, send_tok.length); ++ packet_send(); ++ } ++ fatal("accept_ctx died"); ++ } ++ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual Authentication flag wasn't set"); ++ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity flag wasn't set"); ++ ++ /* 3. S verifies that the (client) key is valid */ ++ /* calculate shared secret */ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if (client_pub_len != 65) ++ fatal("The received NIST-P256 key did not match" ++ "expected length (expected 65, got %d)", client_pub_len); ++ ++ if (client_pub[0] != POINT_CONVERSION_UNCOMPRESSED) ++ fatal("The received NIST-P256 key does not have first octet 0x04"); ++ ++ if ((client_public = EC_POINT_new(group)) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if (!EC_POINT_oct2point(group, client_public, client_pub, ++ client_pub_len, NULL)) ++ fatal("Can not decode received NIST-P256 client key"); ++ ++ if (sshkey_ec_validate_public(group, client_public) != 0) { ++ sshpkt_disconnect(ssh, "invalid client public key"); ++ r = SSH_ERR_MESSAGE_INCOMPLETE; ++ goto out; ++ } ++ ++ if (!EC_POINT_is_on_curve(group, client_public, NULL)) ++ fatal("Received NIST-P256 client key is not on curve"); ++ ++ /* Calculate shared_secret */ ++ klen = (EC_GROUP_get_degree(group) + 7) / 8; ++ if ((kbuf = malloc(klen)) == NULL || ++ (shared_secret = BN_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if (ECDH_compute_key(kbuf, klen, client_public, ++ server_key, NULL) != (int)klen || ++ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if (client_pub_len != 32) ++ fatal("The received curve25519 key did not match" ++ "expected length (expected 32, got %d)", client_pub_len); ++ ++ if (client_pub[client_pub_len-1] & 0x80) ++ fatal("The received key has MSB of last octet set!"); ++ ++ /* generate shared secret */ ++ if ((c25519_shared_secret = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if ((r = kexc25519_shared_key(c25519_server_key, ++ client_pub, c25519_shared_secret)) < 0) ++ goto out; ++ ++ /* if all octets of the shared secret are zero octets, ++ * is already checked in kexc25519_shared_key() */ ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ hashlen = sizeof(hash); ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ kex_ecdh_hash( ++ kex->hash_alg, ++ group, ++ kex->client_version_string, ++ kex->server_version_string, ++ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), ++ sshbuf_ptr(kex->my), sshbuf_len(kex->my), ++ NULL, 0, ++ client_public, ++ EC_KEY_get0_public_key(server_key), ++ shared_secret, ++ hash, &hashlen ++ ); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ kex_c25519_hash( ++ kex->hash_alg, ++ kex->client_version_string, kex->server_version_string, ++ buffer_ptr(kex->peer), buffer_len(kex->peer), ++ buffer_ptr(kex->my), buffer_len(kex->my), ++ NULL, 0, ++ client_pub, c25519_server_pubkey, ++ sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), ++ hash, &hashlen ++ ); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ ++ if (kex->session_id == NULL) { ++ kex->session_id_len = hashlen; ++ kex->session_id = xmalloc(kex->session_id_len); ++ memcpy(kex->session_id, hash, kex->session_id_len); ++ } ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) ++ fatal("Couldn't get MIC"); ++ ++ packet_start(SSH2_MSG_KEXGSS_COMPLETE); ++ { ++ const u_char *ptr; ++ size_t len; ++ sshbuf_get_string_direct(Q_S, &ptr, &len); ++ packet_put_string(ptr, len); ++ } ++ packet_put_string(msg_tok.value, msg_tok.length); ++ ++ if (send_tok.length != 0) { ++ packet_put_char(1); /* true */ ++ packet_put_string(send_tok.value, send_tok.length); ++ } else { ++ packet_put_char(0); /* false */ ++ } ++ packet_send(); ++ ++ gss_release_buffer(&min_status, &send_tok); ++ gss_release_buffer(&min_status, &msg_tok); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ /* Finally derive the keys and send them */ ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0) ++ goto out; ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0) ++ goto out; ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ if ((r = kex_send_newkeys(ssh)) != 0) ++ goto out; ++ ++ /* If this was a rekey, then save out any delegated credentials we ++ * just exchanged. */ ++ if (options.gss_store_rekey) ++ ssh_gssapi_rekey_creds(); ++out: ++ explicit_bzero(hash, sizeof(hash)); ++ if (Q_S) ++ sshbuf_free(Q_S); ++ if (client_pub) ++ free(client_pub); ++ switch (kex->kex_type) { ++ case KEX_GSS_NISTP256_SHA256: ++ if (server_key) ++ EC_KEY_free(server_key); ++ if (kbuf) { ++ explicit_bzero(kbuf, klen); ++ free(kbuf); ++ } ++ if (shared_secret) ++ BN_clear_free(shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ explicit_bzero(c25519_server_key, sizeof(c25519_server_key)); ++ sshbuf_free(c25519_shared_secret); ++ break; ++ } ++ return r; ++} + #endif /* GSSAPI */ +diff --git a/monitor.c b/monitor.c +index d6bc7ac7..b11616c8 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -1651,6 +1651,8 @@ monitor_apply_keystate(struct monitor *pmonitor) + kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; + kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server; + } + #endif + kex->load_host_public_key=&get_hostkey_public_by_type; +@@ -1867,7 +1869,8 @@ mm_answer_gss_sign(int socket, Buffer *m) + + data.value = buffer_get_string(m, &len); + data.length = len; +- if (data.length != 20) ++ /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ ++ if (data.length != 20 && data.length != 32 && data.length != 64) + fatal("%s: data length incorrect: %d", __func__, + (int) data.length); + +diff --git a/regress/kextype.sh b/regress/kextype.sh +index 45f4f16d..d5b4a713 100644 +--- a/regress/kextype.sh ++++ b/regress/kextype.sh +@@ -15,6 +15,7 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy + tries="1 2 3 4" + for k in `${SSH} -Q kex`; do + if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ ++ $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \ + $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ + $k = "gss-group16-sha512-" ]; then + continue +diff --git a/regress/rekey.sh b/regress/rekey.sh +index a2921bef..b118c6c8 100644 +--- a/regress/rekey.sh ++++ b/regress/rekey.sh +@@ -39,6 +39,7 @@ increase_datafile_size 300 + opts="" + for i in `${SSH} -Q kex`; do + if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ ++ $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \ + $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ + $i = "gss-group16-sha512-" ]; then + continue +@@ -62,6 +63,7 @@ if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do + if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ ++ $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \ + $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ + $kex = "gss-group16-sha512-" ]; then + continue +diff --git a/ssh-gss.h b/ssh-gss.h +index 7bf8d75e..1f73721d 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -73,6 +73,8 @@ + #define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" + #define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" + #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" ++#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" ++#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" + + #define GSS_KEX_DEFAULT_KEX \ + KEX_GSS_GEX_SHA1_ID "," \ +diff --git a/ssh_config.5 b/ssh_config.5 +index 3d6da510..1dc29bf1 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -762,7 +762,9 @@ gss-gex-sha1-, + gss-group1-sha1-, + gss-group14-sha1-, + gss-group14-sha256-, +-gss-group16-sha512- ++gss-group16-sha512-, ++gss-nistp256-sha256-, ++gss-curve25519-sha256- + .Ed + .Pp + The default is +diff --git a/sshconnect2.c b/sshconnect2.c +index 5d6b8be0..280ae5a6 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -256,6 +256,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; + kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_client; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_client; + } + #endif + kex->kex[KEX_C25519_SHA256] = kexc25519_client; +diff --git a/sshd.c b/sshd.c +index e4c879a2..a35735d8 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2247,6 +2247,8 @@ do_ssh2_kex(void) + kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; + kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server; + } + #endif + kex->server = 1; +diff --git a/sshd_config.5 b/sshd_config.5 +index 0793418b..888316bf 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -677,7 +677,9 @@ gss-gex-sha1-, + gss-group1-sha1-, + gss-group14-sha1-, + gss-group14-sha256-, +-gss-group16-sha512- ++gss-group16-sha512-, ++gss-nistp256-sha256-, ++gss-curve25519-sha256- + .Ed + .Pp + The default is +-- +2.13.5 + + +From 0431695660d5eb1dd1169d42a1624c75a92aa5d2 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 30 Aug 2017 15:30:51 +0200 +Subject: [PATCH 3/3] Simplify rough edges of GSSAPI Kex + +--- + gss-genr.c | 53 +++++++++++++++++------------------------------------ + regress/kextype.sh | 10 ++++------ + regress/rekey.sh | 20 ++++++++------------ + 3 files changed, 29 insertions(+), 54 deletions(-) + +diff --git a/gss-genr.c b/gss-genr.c +index 22040244..c671be31 100644 +--- a/gss-genr.c ++++ b/gss-genr.c +@@ -171,47 +171,28 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, + gss_OID + ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { + int i = 0; +- +- switch (kex_type) { +- case KEX_GSS_GRP1_SHA1: +- if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; +- break; +- case KEX_GSS_GRP14_SHA1: +- if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; +- break; +- case KEX_GSS_GRP14_SHA256: +- if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1; +- break; +- case KEX_GSS_GRP16_SHA512: +- if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1; +- break; +- case KEX_GSS_GEX_SHA1: +- if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; +- break; +- case KEX_GSS_NISTP256_SHA256: +- if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1; +- break; +- case KEX_GSS_C25519_SHA256: +- if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID)) +- return GSS_C_NO_OID; +- name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1; ++ ++#define SKIP_KEX_NAME(type) \ ++ case type: \ ++ if (strlen(name) < sizeof(type##_ID)) \ ++ return GSS_C_NO_OID; \ ++ name += sizeof(type##_ID) - 1; \ + break; ++ ++ switch (kex_type) { ++ SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256) ++ SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512) ++ SKIP_KEX_NAME(KEX_GSS_GEX_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256) ++ SKIP_KEX_NAME(KEX_GSS_C25519_SHA256) + default: + return GSS_C_NO_OID; + } + ++#undef SKIP_KEX_NAME ++ + while (gss_enc2oid[i].encoded != NULL && + strcmp(name, gss_enc2oid[i].encoded) != 0) + i++; +diff --git a/regress/kextype.sh b/regress/kextype.sh +index d5b4a713..6b4af28a 100644 +--- a/regress/kextype.sh ++++ b/regress/kextype.sh +@@ -14,12 +14,10 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy + + tries="1 2 3 4" + for k in `${SSH} -Q kex`; do +- if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ +- $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \ +- $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ +- $k = "gss-group16-sha512-" ]; then +- continue +- fi ++ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) ++ case $k in ++ gss-* ) continue ;; ++ esac + verbose "kex $k" + for i in $tries; do + ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true +diff --git a/regress/rekey.sh b/regress/rekey.sh +index b118c6c8..d6a8742f 100644 +--- a/regress/rekey.sh ++++ b/regress/rekey.sh +@@ -38,12 +38,10 @@ increase_datafile_size 300 + + opts="" + for i in `${SSH} -Q kex`; do +- if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ +- $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \ +- $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ +- $i = "gss-group16-sha512-" ]; then +- continue +- fi ++ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) ++ case $i in ++ gss-* ) continue ;; ++ esac + opts="$opts KexAlgorithms=$i" + done + for i in `${SSH} -Q cipher`; do +@@ -62,12 +60,10 @@ done + if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then + for c in `${SSH} -Q cipher-auth`; do + for kex in `${SSH} -Q kex`; do +- if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ +- $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \ +- $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ +- $kex = "gss-group16-sha512-" ]; then +- continue +- fi ++ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) ++ case $kex in ++ gss-* ) continue ;; ++ esac + verbose "client rekey $c $kex" + ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c + done +-- +2.13.5 + diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7d09632..75b7e6e 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -1,23 +1,95 @@ +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 +--- + sandbox-seccomp-filter.c | 6 ++++++ + 1 file changed, 6 insertions(+) + diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 3a1aedce72c2..a8d472a63ccb 100644 +index ca75cc7..6e7de31 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c -@@ -50,6 +50,9 @@ - #include - - #include -+#ifdef __s390__ -+#include -+#endif - - #include - #include -@@ -235,7 +235,7 @@ static const struct sock_filter preauth_insns[] = { - * x86-64 syscall under some circumstances, e.g. - * https://bugs.debian.org/849923 - */ -- SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); -+ SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT), +@@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_exit_group + SC_ALLOW(__NR_exit_group), #endif - - /* Default deny */ ++#if defined(__NR_flock) && defined(__s390__) ++ SC_ALLOW(__NR_flock), ++#endif + #ifdef __NR_getpgid + SC_ALLOW(__NR_getpgid), + #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_madvise + SC_ALLOW(__NR_madvise), + #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 +--- + 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 + +The EP11 crypto card needs to make an ioctl call, which receives an +specific argument. This crypto card is for s390 only. + +Signed-off-by: Eduardo Barretto +--- + sandbox-seccomp-filter.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index e86aa2c..98062f1 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -250,6 +250,8 @@ static const struct sock_filter preauth_insns[] = { + SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), + SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), + SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), ++ /* Allow ioctls for EP11 crypto card on s390 */ ++ SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), + #endif + #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) + /* +-- +1.9.1 diff --git a/openssh-7.2p1-audit.patch b/openssh-7.6p1-audit.patch similarity index 75% rename from openssh-7.2p1-audit.patch rename to openssh-7.6p1-audit.patch index 755b93c..2058c60 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.4p1/audit-bsm.c.audit openssh-7.4p1/audit-bsm.c ---- openssh-7.4p1/audit-bsm.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit-bsm.c 2016-12-23 18:54:54.433080419 +0100 +diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c +--- openssh-7.6p1/audit-bsm.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit-bsm.c 2017-10-04 17:18:32.834505048 +0200 @@ -373,10 +373,23 @@ audit_connection_from(const char *host, #endif } @@ -80,9 +80,9 @@ diff -up openssh-7.4p1/audit-bsm.c.audit openssh-7.4p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c ---- openssh-7.4p1/audit.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit.c 2016-12-23 18:54:54.433080419 +0100 +diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c +--- openssh-7.6p1/audit.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit.c 2017-10-04 17:18:32.834505048 +0200 @@ -26,6 +26,7 @@ #include @@ -127,7 +127,7 @@ diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c return (the_authctxt->user); } -@@ -109,6 +113,40 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -109,6 +113,37 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -138,11 +138,8 @@ diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c + const char *crypto_name; + + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (key->type == KEY_RSA1) -+ crypto_name = "ssh-rsa1"; -+ else -+ crypto_name = key_ssh_name(key); -+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0) ++ crypto_name = key_ssh_name(key); ++ if (audit_keyusage(host_user, crypto_name, sshkey_size(key), fp, *rv) == 0) + *rv = 0; + free(fp); +} @@ -168,7 +165,7 @@ diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c # ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. -@@ -138,6 +176,17 @@ audit_event(ssh_audit_event_t event) +@@ -138,6 +173,17 @@ audit_event(ssh_audit_event_t event) } /* @@ -186,7 +183,7 @@ diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -172,13 +221,91 @@ audit_session_close(struct logininfo *li +@@ -172,13 +218,91 @@ audit_session_close(struct logininfo *li /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -280,9 +277,9 @@ diff -up openssh-7.4p1/audit.c.audit openssh-7.4p1/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/audit.h.audit openssh-7.4p1/audit.h ---- openssh-7.4p1/audit.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit.h 2016-12-23 18:54:54.433080419 +0100 +diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h +--- openssh-7.6p1/audit.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit.h 2017-10-04 17:18:32.834505048 +0200 @@ -26,6 +26,7 @@ # define _SSH_AUDIT_H @@ -326,9 +323,9 @@ diff -up openssh-7.4p1/audit.h.audit openssh-7.4p1/audit.h +void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ -diff -up openssh-7.4p1/audit-linux.c.audit openssh-7.4p1/audit-linux.c ---- openssh-7.4p1/audit-linux.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit-linux.c 2016-12-23 18:54:54.434080419 +0100 +diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +--- openssh-7.6p1/audit-linux.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit-linux.c 2017-10-04 17:18:32.835505053 +0200 @@ -33,25 +33,38 @@ #include "log.h" @@ -717,9 +714,9 @@ diff -up openssh-7.4p1/audit-linux.c.audit openssh-7.4p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-7.4p1/auditstub.c.audit openssh-7.4p1/auditstub.c ---- openssh-7.4p1/auditstub.c.audit 2016-12-23 18:54:54.434080419 +0100 -+++ openssh-7.4p1/auditstub.c 2016-12-23 18:54:54.434080419 +0100 +diff -up openssh-7.6p1/auditstub.c.audit openssh-7.6p1/auditstub.c +--- openssh-7.6p1/auditstub.c.audit 2017-10-04 17:18:32.835505053 +0200 ++++ openssh-7.6p1/auditstub.c 2017-10-04 17:18:32.835505053 +0200 @@ -0,0 +1,50 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -771,10 +768,10 @@ diff -up openssh-7.4p1/auditstub.c.audit openssh-7.4p1/auditstub.c +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-7.4p1/auth2.c.audit openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.audit 2016-12-23 18:54:54.422080416 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 18:54:54.434080419 +0100 -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 +diff -up openssh-7.6p1/auth2.c.audit openssh-7.6p1/auth2.c +--- openssh-7.6p1/auth2.c.audit 2017-10-04 17:18:32.746504598 +0200 ++++ openssh-7.6p1/auth2.c 2017-10-04 17:18:32.835505053 +0200 +@@ -255,9 +255,6 @@ input_userauth_request(int type, u_int32 } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); @@ -784,28 +781,29 @@ diff -up openssh-7.4p1/auth2.c.audit openssh-7.4p1/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-7.4p1/auth2-hostbased.c.audit openssh-7.4p1/auth2-hostbased.c ---- openssh-7.4p1/auth2-hostbased.c.audit 2016-12-23 18:54:54.422080416 +0100 -+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 18:54:54.434080419 +0100 -@@ -148,7 +148,7 @@ userauth_hostbased(Authctxt *authctxt) +diff -up openssh-7.6p1/auth2-hostbased.c.audit openssh-7.6p1/auth2-hostbased.c +--- openssh-7.6p1/auth2-hostbased.c.audit 2017-10-04 17:18:32.683504276 +0200 ++++ openssh-7.6p1/auth2-hostbased.c 2017-10-04 17:18:32.835505053 +0200 +@@ -152,7 +152,7 @@ userauth_hostbased(struct ssh *ssh) /* test for allowed key and correct signature */ authenticated = 0; if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), -+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) { +- PRIVSEP(sshkey_verify(key, sig, slen, ++ PRIVSEP(hostbased_key_verify(key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0) authenticated = 1; - authctxt->last_details = pubkey; -@@ -169,6 +169,18 @@ done: + +@@ -169,6 +169,19 @@ done: return authenticated; } +int -+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, ++ const u_char *data, size_t datalen, u_int compat) +{ + int rv; + -+ rv = key_verify(key, sig, slen, data, datalen); ++ rv = sshkey_verify(key, sig, slen, data, datalen, compat); +#ifdef SSH_AUDIT_EVENTS + audit_key(0, &rv, key); +#endif @@ -815,41 +813,42 @@ diff -up openssh-7.4p1/auth2-hostbased.c.audit openssh-7.4p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-7.4p1/auth2-pubkey.c.audit openssh-7.4p1/auth2-pubkey.c ---- openssh-7.4p1/auth2-pubkey.c.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 18:54:54.435080419 +0100 -@@ -183,7 +183,7 @@ userauth_pubkey(Authctxt *authctxt) +diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c +--- openssh-7.6p1/auth2-pubkey.c.audit 2017-10-04 17:18:32.828505018 +0200 ++++ openssh-7.6p1/auth2-pubkey.c 2017-10-04 17:18:32.835505053 +0200 +@@ -206,7 +206,7 @@ userauth_pubkey(struct ssh *ssh) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), -+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) { +- PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), ++ PRIVSEP(user_key_verify(key, sig, slen, sshbuf_ptr(b), + sshbuf_len(b), ssh->compat)) == 0) { authenticated = 1; - authctxt->last_details = pubkey; -@@ -252,6 +252,18 @@ pubkey_auth_info(Authctxt *authctxt, con - free(extra); + } +@@ -250,6 +250,19 @@ done: + return authenticated; } +int -+user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++user_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, ++ const u_char *data, size_t datalen, u_int compat) +{ + int rv; + -+ rv = key_verify(key, sig, slen, data, datalen); ++ rv = sshkey_verify(key, sig, slen, data, datalen, compat); +#ifdef SSH_AUDIT_EVENTS + audit_key(1, &rv, key); +#endif + return rv; +} + - /* - * Splits 's' into an argument vector. Handles quoted string and basic - * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh-7.4p1/auth.c.audit openssh-7.4p1/auth.c ---- openssh-7.4p1/auth.c.audit 2016-12-23 18:54:54.373080404 +0100 -+++ openssh-7.4p1/auth.c 2016-12-23 18:54:54.435080419 +0100 -@@ -666,9 +666,6 @@ getpwnamallow(const char *user) + static int + match_principals_option(const char *principal_list, struct sshkey_cert *cert) + { +diff -up openssh-7.6p1/auth.c.audit openssh-7.6p1/auth.c +--- openssh-7.6p1/auth.c.audit 2017-10-04 17:18:32.746504598 +0200 ++++ openssh-7.6p1/auth.c 2017-10-04 17:18:32.835505053 +0200 +@@ -599,9 +599,6 @@ getpwnamallow(const char *user) record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -859,45 +858,44 @@ diff -up openssh-7.4p1/auth.c.audit openssh-7.4p1/auth.c return (NULL); } if (!allowed_user(pw)) -diff -up openssh-7.4p1/auth.h.audit openssh-7.4p1/auth.h ---- openssh-7.4p1/auth.h.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/auth.h 2016-12-23 18:54:54.435080419 +0100 -@@ -185,6 +185,7 @@ struct passwd * getpwnamallow(const char +diff -up openssh-7.6p1/auth.h.audit openssh-7.6p1/auth.h +--- openssh-7.6p1/auth.h.audit 2017-10-04 17:18:32.768504711 +0200 ++++ openssh-7.6p1/auth.h 2017-10-04 17:18:32.836505059 +0200 +@@ -198,6 +198,7 @@ struct passwd * getpwnamallow(const char char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); -+int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); ++int user_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -204,6 +205,7 @@ Key *get_hostkey_private_by_type(int, in - int get_hostkey_index(Key *, int, struct ssh *); - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, - const u_char *, size_t, const char *, u_int); -+int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +@@ -217,6 +218,7 @@ struct sshkey *get_hostkey_private_by_ty + int get_hostkey_index(struct sshkey *, int, struct ssh *); + int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, + size_t *, const u_char *, size_t, const char *, u_int); ++int hostbased_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -diff -up openssh-7.4p1/cipher.c.audit openssh-7.4p1/cipher.c ---- openssh-7.4p1/cipher.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher.c 2016-12-23 18:54:54.435080419 +0100 -@@ -66,26 +66,6 @@ struct sshcipher_ctx { +diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c +--- openssh-7.6p1/cipher.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/cipher.c 2017-10-04 17:18:32.836505059 +0200 +@@ -61,25 +61,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; -struct sshcipher { - char *name; -- int number; /* for ssh1 only */ - u_int block_size; - u_int key_len; - u_int iv_len; /* defaults to block_size */ - u_int auth_len; -- u_int discard_len; - u_int flags; -#define CFLAG_CBC (1<<0) -#define CFLAG_CHACHAPOLY (1<<1) -#define CFLAG_AESCTR (1<<2) -#define CFLAG_NONE (1<<3) +-#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ -#ifdef WITH_OPENSSL - const EVP_CIPHER *(*evptype)(void); -#else @@ -906,41 +904,41 @@ diff -up openssh-7.4p1/cipher.c.audit openssh-7.4p1/cipher.c -}; - static const struct sshcipher ciphers[] = { - #ifdef WITH_SSH1 - { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, -diff -up openssh-7.4p1/cipher.h.audit openssh-7.4p1/cipher.h ---- openssh-7.4p1/cipher.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher.h 2016-12-23 18:54:54.436080419 +0100 -@@ -62,7 +62,25 @@ + #ifdef WITH_OPENSSL + { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, +diff -up openssh-7.6p1/cipher.h.audit openssh-7.6p1/cipher.h +--- openssh-7.6p1/cipher.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/cipher.h 2017-10-04 17:18:32.836505059 +0200 +@@ -45,7 +45,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 -struct sshcipher; -+struct sshcipher { /* from cipher.c */ ++struct sshcipher { + char *name; -+ int number; /* for ssh1 only */ + u_int block_size; + u_int key_len; + u_int iv_len; /* defaults to block_size */ + u_int auth_len; -+ u_int discard_len; + u_int flags; +#define CFLAG_CBC (1<<0) +#define CFLAG_CHACHAPOLY (1<<1) +#define CFLAG_AESCTR (1<<2) +#define CFLAG_NONE (1<<3) ++#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ +#ifdef WITH_OPENSSL + const EVP_CIPHER *(*evptype)(void); +#else + void *ignored; +#endif +}; ++ struct sshcipher_ctx; - u_int cipher_mask_ssh1(int); -diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c ---- openssh-7.4p1/kex.c.audit 2016-12-23 18:54:54.410080413 +0100 -+++ openssh-7.4p1/kex.c 2016-12-23 18:54:54.436080419 +0100 + const struct sshcipher *cipher_by_name(const char *); +diff -up openssh-7.6p1/kex.c.audit openssh-7.6p1/kex.c +--- openssh-7.6p1/kex.c.audit 2017-10-04 17:18:32.822504987 +0200 ++++ openssh-7.6p1/kex.c 2017-10-04 17:18:32.836505059 +0200 @@ -54,6 +54,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -949,7 +947,7 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -683,8 +684,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -692,8 +693,12 @@ choose_enc(struct sshenc *enc, char *cli { char *name = match_list(client, server, NULL); @@ -963,7 +961,7 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) { free(name); return SSH_ERR_INTERNAL_ERROR; -@@ -702,8 +707,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -713,8 +718,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -977,7 +975,7 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c if (mac_setup(mac, name) < 0) { free(name); return SSH_ERR_INTERNAL_ERROR; -@@ -720,8 +729,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -733,8 +742,12 @@ choose_comp(struct sshcomp *comp, char * { char *name = match_list(client, server, NULL); @@ -991,7 +989,7 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -890,6 +903,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -904,6 +917,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -1002,7 +1000,7 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1064,3 +1081,33 @@ dump_digest(char *msg, u_char *digest, i +@@ -1037,3 +1054,33 @@ dump_digest(char *msg, u_char *digest, i sshbuf_dump_data(digest, len, stderr); } #endif @@ -1036,10 +1034,10 @@ diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c + mac_destroy(&newkeys->mac); + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} -diff -up openssh-7.4p1/kex.h.audit openssh-7.4p1/kex.h ---- openssh-7.4p1/kex.h.audit 2016-12-23 18:54:54.410080413 +0100 -+++ openssh-7.4p1/kex.h 2016-12-23 18:54:54.436080419 +0100 -@@ -213,6 +213,8 @@ int kexgss_client(struct ssh *); +diff -up openssh-7.6p1/kex.h.audit openssh-7.6p1/kex.h +--- openssh-7.6p1/kex.h.audit 2017-10-04 17:18:32.822504987 +0200 ++++ openssh-7.6p1/kex.h 2017-10-04 17:18:32.836505059 +0200 +@@ -219,6 +219,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1048,21 +1046,21 @@ diff -up openssh-7.4p1/kex.h.audit openssh-7.4p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.4p1/key.h.audit openssh-7.4p1/key.h ---- openssh-7.4p1/key.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/key.h 2016-12-23 18:54:54.436080419 +0100 -@@ -50,6 +50,7 @@ typedef struct sshkey Key; - #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid - #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid +diff -up openssh-7.6p1/key.h.audit openssh-7.6p1/key.h +--- openssh-7.6p1/key.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/key.h 2017-10-04 17:18:32.836505059 +0200 +@@ -43,6 +43,7 @@ typedef struct sshkey Key; + #define key_ssh_name_plain sshkey_ssh_name_plain + #define key_type_from_name sshkey_type_from_name #define key_is_cert sshkey_is_cert +#define key_is_private sshkey_is_private #define key_type_plain sshkey_type_plain - #define key_curve_name_to_nid sshkey_curve_name_to_nid - #define key_curve_nid_to_bits sshkey_curve_nid_to_bits -diff -up openssh-7.4p1/mac.c.audit openssh-7.4p1/mac.c ---- openssh-7.4p1/mac.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/mac.c 2016-12-23 18:54:54.436080419 +0100 -@@ -249,6 +249,20 @@ mac_clear(struct sshmac *mac) + #endif + +diff -up openssh-7.6p1/mac.c.audit openssh-7.6p1/mac.c +--- openssh-7.6p1/mac.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/mac.c 2017-10-04 17:18:32.836505059 +0200 +@@ -242,6 +242,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1083,9 +1081,9 @@ diff -up openssh-7.4p1/mac.c.audit openssh-7.4p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-7.4p1/mac.h.audit openssh-7.4p1/mac.h ---- openssh-7.4p1/mac.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/mac.h 2016-12-23 18:54:54.436080419 +0100 +diff -up openssh-7.6p1/mac.h.audit openssh-7.6p1/mac.h +--- openssh-7.6p1/mac.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/mac.h 2017-10-04 17:18:32.837505064 +0200 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1093,21 +1091,22 @@ diff -up openssh-7.4p1/mac.h.audit openssh-7.4p1/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-7.4p1/Makefile.in.audit openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.audit 2016-12-23 18:54:54.375080404 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 18:54:54.436080419 +0100 -@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-7.6p1/Makefile.in.audit openssh-7.6p1/Makefile.in +--- openssh-7.6p1/Makefile.in.audit 2017-10-04 17:18:32.749504614 +0200 ++++ openssh-7.6p1/Makefile.in 2017-10-04 17:18:32.837505064 +0200 +@@ -100,7 +100,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ -- platform-pledge.o platform-tracing.o -+ platform-pledge.o platform-tracing.o auditstub.o +- platform-pledge.o platform-tracing.o platform-misc.o ++ platform-pledge.o platform-tracing.o platform-misc.o \ ++ auditstub.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 18:54:54.437080420 +0100 + sshconnect.o sshconnect2.o mux.o +diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +--- openssh-7.6p1/monitor.c.audit 2017-10-04 17:18:32.824504997 +0200 ++++ openssh-7.6p1/monitor.c 2017-10-04 17:18:32.837505064 +0200 @@ -102,6 +102,7 @@ #include "compat.h" #include "ssh2.h" @@ -1160,47 +1159,53 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c #endif {0, 0, NULL} }; -@@ -1396,9 +1413,11 @@ mm_answer_keyverify(int sock, Buffer *m) - Key *key; +@@ -1396,7 +1413,9 @@ mm_answer_keyverify(int sock, struct ssh u_char *signature, *data, *blob; - u_int signaturelen, datalen, bloblen; + size_t signaturelen, datalen, bloblen; + int r, ret, valid_data = 0, encoded_ret; + int type = 0; - int verified = 0; - int valid_data = 0; + type = buffer_get_int(m); - blob = buffer_get_string(m, &bloblen); - signature = buffer_get_string(m, &signaturelen); - data = buffer_get_string(m, &datalen); -@@ -1406,6 +1425,8 @@ mm_answer_keyverify(int sock, Buffer *m) + if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || + (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || + (r = sshbuf_get_string(m, &data, &datalen)) != 0) +@@ -1405,6 +1424,8 @@ mm_answer_keyverify(int sock, struct ssh if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); + if (type != key_blobtype) + fatal("%s: bad key type", __func__); - key = key_from_blob(blob, bloblen); - if (key == NULL) -@@ -1426,7 +1447,17 @@ mm_answer_keyverify(int sock, Buffer *m) + /* XXX use sshkey_froms here; need to change key_blob, etc. */ + if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0) +@@ -1414,21 +1435,24 @@ mm_answer_keyverify(int sock, struct ssh + case MM_USERKEY: + valid_data = monitor_valid_userblob(data, datalen); + auth_method = "publickey"; ++ ret = user_key_verify(key, signature, signaturelen, data, ++ datalen, active_state->compat); + break; + case MM_HOSTKEY: + valid_data = monitor_valid_hostbasedblob(data, datalen, + hostbased_cuser, hostbased_chost); ++ ret = hostbased_key_verify(key, signature, signaturelen, data, ++ datalen, active_state->compat); + auth_method = "hostbased"; + break; + default: + valid_data = 0; ++ ret = 0; + break; + } if (!valid_data) fatal("%s: bad signature data blob", __func__); -- verified = key_verify(key, signature, signaturelen, data, datalen); -+ switch (key_blobtype) { -+ case MM_USERKEY: -+ verified = user_key_verify(key, signature, signaturelen, data, datalen); -+ break; -+ case MM_HOSTKEY: -+ verified = hostbased_key_verify(key, signature, signaturelen, data, datalen); -+ break; -+ default: -+ verified = 0; -+ break; -+ } - debug3("%s: key %p signature %s", - __func__, key, (verified == 1) ? "verified" : "unverified"); - -@@ -1489,6 +1520,12 @@ mm_session_close(Session *s) +- ret = sshkey_verify(key, signature, signaturelen, data, datalen, +- active_state->compat); + debug3("%s: %s %p signature %s", __func__, auth_method, key, + (ret == 0) ? "verified" : "unverified"); + auth2_record_key(authctxt, ret == 0, key); +@@ -1485,6 +1509,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1213,7 +1218,7 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c session_unused(s->self); } -@@ -1591,6 +1628,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1588,6 +1618,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1222,7 +1227,7 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1633,11 +1672,45 @@ mm_answer_audit_command(int socket, Buff +@@ -1630,11 +1662,45 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1269,7 +1274,7 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c free(cmd); return (0); } -@@ -1690,6 +1763,7 @@ monitor_apply_keystate(struct monitor *p +@@ -1702,6 +1768,7 @@ monitor_apply_keystate(struct monitor *p void mm_get_keystate(struct monitor *pmonitor) { @@ -1277,19 +1282,17 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1697,6 +1771,21 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1709,6 +1776,19 @@ mm_get_keystate(struct monitor *pmonitor mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); + +#ifdef SSH_AUDIT_EVENTS -+ if (compat20) { -+ buffer_init(&m); -+ mm_request_receive_expect(pmonitor->m_sendfd, -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); -+ buffer_free(&m); -+ } ++ buffer_init(&m); ++ mm_request_receive_expect(pmonitor->m_sendfd, ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); ++ buffer_free(&m); +#endif + + /* Drain any buffered messages from the child */ @@ -1299,7 +1302,7 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c } -@@ -1953,3 +2042,86 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -1976,3 +2056,86 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ @@ -1386,9 +1389,9 @@ diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/monitor.h.audit openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.audit 2016-12-23 18:54:54.393080409 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 18:54:54.437080420 +0100 +diff -up openssh-7.6p1/monitor.h.audit openssh-7.6p1/monitor.h +--- openssh-7.6p1/monitor.h.audit 2017-10-04 17:18:32.781504777 +0200 ++++ openssh-7.6p1/monitor.h 2017-10-04 17:18:32.837505064 +0200 @@ -69,7 +69,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1404,19 +1407,19 @@ diff -up openssh-7.4p1/monitor.h.audit openssh-7.4p1/monitor.h }; -diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.audit 2016-12-23 18:54:54.376080405 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 18:54:54.437080420 +0100 -@@ -453,7 +453,7 @@ mm_key_allowed(enum mm_keytype type, con +diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +--- openssh-7.6p1/monitor_wrap.c.audit 2017-10-04 17:18:32.750504619 +0200 ++++ openssh-7.6p1/monitor_wrap.c 2017-10-04 17:18:32.838505069 +0200 +@@ -463,7 +463,7 @@ mm_key_allowed(enum mm_keytype type, con */ int --mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) -+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) +-mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++mm_sshkey_verify(enum mm_keytype type, const struct sshkey *key, const u_char *sig, size_t siglen, + const u_char *data, size_t datalen, u_int compat) { Buffer m; - u_char *blob; -@@ -467,6 +467,7 @@ mm_key_verify(Key *key, u_char *sig, u_i +@@ -478,6 +478,7 @@ mm_sshkey_verify(const struct sshkey *ke return (0); buffer_init(&m); @@ -1424,26 +1427,28 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); -@@ -484,6 +485,18 @@ mm_key_verify(Key *key, u_char *sig, u_i - return (verified); +@@ -497,6 +498,20 @@ mm_sshkey_verify(const struct sshkey *ke + return 0; } +int -+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) ++mm_hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++ const u_char *data, size_t datalen, u_int compat) +{ -+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen); ++ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, compat); +} + +int -+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) ++mm_user_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++ const u_char *data, size_t datalen, u_int compat) +{ -+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen); ++ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, compat); +} + void mm_send_keystate(struct monitor *monitor) { -@@ -861,10 +874,11 @@ mm_audit_event(ssh_audit_event_t event) +@@ -874,10 +889,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1456,7 +1461,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -872,6 +886,26 @@ mm_audit_run_command(const char *command +@@ -885,6 +901,26 @@ mm_audit_run_command(const char *command buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); @@ -1483,7 +1488,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1007,3 +1041,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1020,3 +1056,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc #endif /* GSSAPI */ @@ -1554,20 +1559,21 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c + buffer_free(&m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/monitor_wrap.h.audit openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.audit 2016-12-23 18:54:54.376080405 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 18:54:54.437080420 +0100 -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, cons - int mm_user_key_allowed(struct passwd *, Key *, int); +diff -up openssh-7.6p1/monitor_wrap.h.audit openssh-7.6p1/monitor_wrap.h +--- openssh-7.6p1/monitor_wrap.h.audit 2017-10-04 17:18:32.750504619 +0200 ++++ openssh-7.6p1/monitor_wrap.h 2017-10-04 17:18:32.838505069 +0200 +@@ -53,7 +53,9 @@ int mm_key_allowed(enum mm_keytype, cons + int mm_user_key_allowed(struct passwd *, struct sshkey *, int); int mm_hostbased_key_allowed(struct passwd *, const char *, - const char *, Key *); --int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); -+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); -+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); + const char *, struct sshkey *); +-int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, ++int mm_hostbased_key_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, u_int); ++int mm_user_key_verify(const struct sshkey *, const u_char *, size_t, + const u_char *, size_t, u_int); #ifdef GSSAPI - OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -@@ -76,7 +77,12 @@ void mm_sshpam_free_ctx(void *); +@@ -78,7 +80,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); @@ -1581,18 +1587,18 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit openssh-7.4p1/monitor_wrap.h #endif struct Session; -diff -up openssh-7.4p1/packet.c.audit openssh-7.4p1/packet.c ---- openssh-7.4p1/packet.c.audit 2016-12-23 18:54:54.318080390 +0100 -+++ openssh-7.4p1/packet.c 2016-12-23 18:54:54.438080420 +0100 +diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c +--- openssh-7.6p1/packet.c.audit 2017-10-04 17:18:32.672504220 +0200 ++++ openssh-7.6p1/packet.c 2017-10-04 17:25:48.141741390 +0200 @@ -67,6 +67,7 @@ #include "key.h" /* typedefs XXX */ #include "xmalloc.h" +#include "audit.h" #include "crc32.h" - #include "deattack.h" #include "compat.h" -@@ -494,6 +495,13 @@ ssh_packet_get_connection_out(struct ssh + #include "ssh2.h" +@@ -502,6 +503,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1606,53 +1612,62 @@ diff -up openssh-7.4p1/packet.c.audit openssh-7.4p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -562,13 +570,6 @@ ssh_packet_close(struct ssh *ssh) +@@ -566,22 +574,19 @@ ssh_packet_close_internal(struct ssh *ss + { + struct session_state *state = ssh->state; + u_int mode; ++ u_int had_keys = packet_state_has_keys(state); + if (!state->initialized) return; state->initialized = 0; -- if (state->connection_in == state->connection_out) { -- shutdown(state->connection_out, SHUT_RDWR); -- close(state->connection_out); -- } else { -- close(state->connection_in); -- close(state->connection_out); +- if (do_close) { +- if (state->connection_in == state->connection_out) { +- close(state->connection_out); +- } else { +- close(state->connection_in); +- close(state->connection_out); +- } - } sshbuf_free(state->input); ++ state->input = NULL; sshbuf_free(state->output); ++ state->output = NULL; sshbuf_free(state->outgoing_packet); -@@ -600,11 +601,21 @@ ssh_packet_close(struct ssh *ssh) - inflateEnd(stream); - } ++ state->outgoing_packet = NULL; + sshbuf_free(state->incoming_packet); ++ state->incoming_packet = NULL; + for (mode = 0; mode < MODE_MAX; mode++) { + kex_free_newkeys(state->newkeys[mode]); /* current keys */ + state->newkeys[mode] = NULL; +@@ -615,8 +616,18 @@ ssh_packet_close_internal(struct ssh *ss } -- cipher_free(state->send_context); -- cipher_free(state->receive_context); -+ if (packet_state_has_keys(state)) { -+ cipher_free(state->send_context); -+ cipher_free(state->receive_context); + cipher_free(state->send_context); + cipher_free(state->receive_context); ++ if (had_keys && state->server_side) { ++ /* Assuming this is called only from privsep child */ + audit_session_key_free(MODE_MAX); + } state->send_context = state->receive_context = NULL; - free(ssh->remote_ipaddr); - ssh->remote_ipaddr = NULL; -+ if (state->connection_in == state->connection_out) { -+ shutdown(state->connection_out, SHUT_RDWR); -+ close(state->connection_out); -+ } else { -+ close(state->connection_in); -+ close(state->connection_out); -+ } - free(ssh->state); - ssh->state = NULL; - } -@@ -950,6 +961,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - " (%llu bytes total)", __func__, - (unsigned long long)ps->blocks, dir, - (unsigned long long)ps->bytes); + if (do_close) { ++ if (state->connection_in == state->connection_out) { ++ close(state->connection_out); ++ } else { ++ close(state->connection_in); ++ close(state->connection_out); ++ } + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + free(ssh->state); +@@ -854,6 +863,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_read.blocks, + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); + audit_session_key_free(mode); cipher_free(*ccp); *ccp = NULL; - enc = &state->newkeys[mode]->enc; -@@ -2440,6 +2452,72 @@ ssh_packet_get_output(struct ssh *ssh) + kex_free_newkeys(state->newkeys[mode]); +@@ -2135,6 +2145,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1725,35 +1740,19 @@ diff -up openssh-7.4p1/packet.c.audit openssh-7.4p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-7.4p1/packet.h.audit openssh-7.4p1/packet.h ---- openssh-7.4p1/packet.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/packet.h 2016-12-23 18:54:54.438080420 +0100 -@@ -208,4 +208,5 @@ extern struct ssh *active_state; +diff -up openssh-7.6p1/packet.h.audit openssh-7.6p1/packet.h +--- openssh-7.6p1/packet.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/packet.h 2017-10-04 17:18:32.838505069 +0200 +@@ -217,4 +217,5 @@ extern struct ssh *active_state; # undef EC_POINT #endif +void packet_destroy_all(int, int); #endif /* PACKET_H */ -diff -up openssh-7.4p1/sandbox-seccomp-filter.c.audit openssh-7.4p1/sandbox-seccomp-filter.c ---- openssh-7.4p1/sandbox-seccomp-filter.c.audit 2016-12-23 18:54:54.377080405 +0100 -+++ openssh-7.4p1/sandbox-seccomp-filter.c 2016-12-23 18:54:54.438080420 +0100 -@@ -159,6 +159,12 @@ static const struct sock_filter preauth_ - #ifdef __NR_gettimeofday - SC_ALLOW(__NR_gettimeofday), - #endif -+#ifdef SSH_AUDIT_EVENTS -+ SC_ALLOW(__NR_getuid), -+#ifdef __NR_getuid32 /* not defined on x86_64 */ -+ SC_ALLOW(__NR_getuid32), -+#endif -+#endif - #ifdef __NR_madvise - SC_ALLOW(__NR_madvise), - #endif -diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.audit 2016-12-23 18:54:54.430080418 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 18:57:45.068115466 +0100 -@@ -142,7 +142,7 @@ extern int log_stderr; +diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c +--- openssh-7.6p1/session.c.audit 2017-10-04 17:18:32.812504936 +0200 ++++ openssh-7.6p1/session.c 2017-10-04 17:18:32.839505074 +0200 +@@ -138,7 +138,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1762,7 +1761,7 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c extern Buffer loginmsg; /* original command from peer. */ -@@ -576,6 +576,14 @@ do_exec_pty(Session *s, const char *comm +@@ -605,6 +605,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1777,7 +1776,7 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -696,15 +704,19 @@ do_exec(Session *s, const char *command) +@@ -724,15 +732,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1798,20 +1797,21 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c + s->command_handle = PRIVSEP(audit_run_command(s->command)); #endif if (s->ttyfd != -1) - ret = do_exec_pty(s, command); -@@ -1543,7 +1555,10 @@ do_child(Session *s, const char *command + ret = do_exec_pty(ssh, s, command); +@@ -1499,8 +1511,11 @@ do_child(struct ssh *ssh, Session *s, co int r = 0; /* remove hostkey from the child's memory */ - destroy_sensitive_data(); + destroy_sensitive_data(1); + packet_clear_keys(); + /* Don't audit this - both us and the parent would be talking to the + monitor over a single socket, with no synchronization. */ + packet_destroy_all(0, 1); /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1757,6 +1772,9 @@ session_unused(int id) +@@ -1714,6 +1729,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1821,7 +1821,7 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1839,6 +1857,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1796,6 +1814,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1841,8 +1841,8 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c session_by_tty(char *tty) { int i; -@@ -2351,6 +2382,32 @@ session_exit_message(Session *s, int sta - chan_write_failed(c); +@@ -2307,6 +2338,32 @@ session_exit_message(struct ssh *ssh, Se + chan_write_failed(ssh, c); } +#ifdef SSH_AUDIT_EVENTS @@ -1872,9 +1872,9 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c +#endif + void - session_close(Session *s) + session_close(struct ssh *ssh, Session *s) { -@@ -2365,6 +2422,10 @@ session_close(Session *s) +@@ -2320,6 +2377,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1885,8 +1885,8 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2575,6 +2636,15 @@ do_authenticated2(Authctxt *authctxt) - server_loop2(authctxt); +@@ -2528,6 +2589,15 @@ do_authenticated2(struct ssh *ssh, Authc + server_loop2(ssh, authctxt); } +static void @@ -1899,20 +1899,20 @@ diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c +} + void - do_cleanup(Authctxt *authctxt) + do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2626,7 +2696,7 @@ do_cleanup(Authctxt *authctxt) +@@ -2585,7 +2655,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) -- session_destroy_all(session_pty_cleanup2); -+ session_destroy_all(do_cleanup_one_session); +- session_destroy_all(ssh, session_pty_cleanup2); ++ session_destroy_all(ssh, do_cleanup_one_session); } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-7.4p1/session.h.audit openssh-7.4p1/session.h ---- openssh-7.4p1/session.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/session.h 2016-12-23 18:54:54.438080420 +0100 +diff -up openssh-7.6p1/session.h.audit openssh-7.6p1/session.h +--- openssh-7.6p1/session.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/session.h 2017-10-04 17:18:32.839505074 +0200 @@ -60,6 +60,12 @@ struct Session { char *name; char *val; @@ -1925,22 +1925,22 @@ diff -up openssh-7.4p1/session.h.audit openssh-7.4p1/session.h +#endif }; - void do_authenticated(Authctxt *); -@@ -72,8 +78,10 @@ void session_close_by_pid(pid_t, int); - void session_close_by_channel(int, void *); - void session_destroy_all(void (*)(Session *)); + void do_authenticated(struct ssh *, Authctxt *); +@@ -72,8 +78,10 @@ void session_close_by_pid(struct ssh *s + void session_close_by_channel(struct ssh *, int, void *); + void session_destroy_all(struct ssh *, void (*)(Session *)); void session_pty_cleanup2(Session *); +void session_end_command2(Session *); Session *session_new(void); +Session *session_by_id(int); Session *session_by_tty(char *); - void session_close(Session *); + void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.audit 2016-12-23 18:54:54.403080411 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 18:56:18.992101105 +0100 -@@ -119,6 +119,7 @@ +diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c +--- openssh-7.6p1/sshd.c.audit 2017-10-04 17:18:32.830505028 +0200 ++++ openssh-7.6p1/sshd.c 2017-10-04 17:18:32.839505074 +0200 +@@ -122,6 +122,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" @@ -1948,7 +1948,7 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" -@@ -244,7 +245,7 @@ Buffer loginmsg; +@@ -248,7 +249,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -1957,7 +1957,7 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c void demote_sensitive_data(void); static void do_ssh2_kex(void); -@@ -261,6 +262,15 @@ close_listen_socks(void) +@@ -265,6 +266,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -1973,7 +1973,7 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c static void close_startup_pipes(void) { -@@ -473,18 +483,45 @@ sshd_exchange_identification(struct ssh +@@ -475,18 +485,45 @@ sshd_exchange_identification(struct ssh } } @@ -2022,9 +2022,9 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -497,12 +534,30 @@ demote_sensitive_data(void) +@@ -499,12 +536,30 @@ demote_sensitive_data(void) { - Key *tmp; + struct sshkey *tmp; int i; +#ifdef SSH_AUDIT_EVENTS + pid_t pid; @@ -2053,7 +2053,7 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c } /* Certs do not need demotion */ } -@@ -585,7 +640,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -587,7 +642,7 @@ privsep_preauth(Authctxt *authctxt) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2062,20 +2062,7 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -665,6 +720,12 @@ privsep_postauth(Authctxt *authctxt) - else if (pmonitor->m_pid != 0) { - verbose("User child is on pid %ld", (long)pmonitor->m_pid); - buffer_clear(&loginmsg); -+ if (*pmonitor->m_pkex != NULL ){ -+ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); -+ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]); -+ audit_session_key_free_body(2, getpid(), getuid()); -+ packet_destroy_all(0, 0); -+ } - monitor_child_postauth(pmonitor); - - /* NEVERREACHED */ -@@ -1154,6 +1215,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1162,6 +1217,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2083,16 +2070,8 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2092,6 +2150,7 @@ main(int ac, char **av) - */ - if (use_privsep) { - mm_send_keystate(pmonitor); -+ packet_destroy_all(1, 1); - exit(0); - } - -@@ -2148,6 +2207,9 @@ main(int ac, char **av) - do_authenticated(authctxt); +@@ -2165,6 +2221,9 @@ main(int ac, char **av) + do_authenticated(ssh, authctxt); /* The connection has been terminated. */ + packet_destroy_all(1, 1); @@ -2101,10 +2080,10 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2321,6 +2383,16 @@ do_ssh2_kex(void) - void +@@ -2344,6 +2403,15 @@ void cleanup_exit(int i) { + struct ssh *ssh = active_state; /* XXX */ + static int in_cleanup = 0; + int is_privsep_child; + @@ -2114,11 +2093,10 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c + if (in_cleanup) + _exit(i); + in_cleanup = 1; -+ + if (the_authctxt) { - do_cleanup(the_authctxt); - if (use_privsep && privsep_is_preauth && -@@ -2332,9 +2404,14 @@ cleanup_exit(int i) + do_cleanup(ssh, the_authctxt); +@@ -2356,9 +2424,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2134,10 +2112,10 @@ diff -up openssh-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-7.4p1/sshkey.c.audit openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.audit 2016-12-23 18:54:54.425080417 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 18:54:54.439080420 +0100 -@@ -303,6 +303,33 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c +--- openssh-7.6p1/sshkey.c.audit 2017-10-04 17:18:32.758504660 +0200 ++++ openssh-7.6p1/sshkey.c 2017-10-04 17:18:32.839505074 +0200 +@@ -295,6 +295,32 @@ sshkey_type_is_valid_ca(int type) } int @@ -2146,7 +2124,6 @@ diff -up openssh-7.4p1/sshkey.c.audit openssh-7.4p1/sshkey.c + switch (k->type) { +#ifdef WITH_OPENSSL + case KEY_RSA_CERT: -+ case KEY_RSA1: + case KEY_RSA: + return k->rsa->d != NULL; + case KEY_DSA_CERT: @@ -2171,10 +2148,10 @@ diff -up openssh-7.4p1/sshkey.c.audit openssh-7.4p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-7.4p1/sshkey.h.audit openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.audit 2016-12-23 18:54:54.425080417 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 18:54:54.439080420 +0100 -@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-7.6p1/sshkey.h.audit openssh-7.6p1/sshkey.h +--- openssh-7.6p1/sshkey.h.audit 2017-10-04 17:18:32.758504660 +0200 ++++ openssh-7.6p1/sshkey.h 2017-10-04 17:18:32.840505079 +0200 +@@ -133,6 +133,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch new file mode 100644 index 0000000..49510f7 --- /dev/null +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -0,0 +1,253 @@ +diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.refactor 2017-09-27 13:10:19.556830609 +0200 ++++ openssh/auth2-pubkey.c 2017-09-27 13:10:19.677831274 +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 int + userauth_pubkey(struct ssh *ssh) +@@ -432,7 +435,8 @@ match_principals_command(struct passwd * + + if ((pid = subprocess("AuthorizedPrincipalsCommand", 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; +@@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd + + if ((pid = subprocess("AuthorizedKeysCommand", 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/misc.c.refactor openssh/misc.c +--- openssh/misc.c.refactor 2017-09-27 13:10:19.640831071 +0200 ++++ openssh/misc.c 2017-09-27 13:10:19.678831279 +0200 +@@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv) + */ + 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; +@@ -1551,7 +1552,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/misc.h.refactor openssh/misc.h +--- openssh/misc.h.refactor 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/misc.h 2017-09-27 13:10:19.678831279 +0200 +@@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *, + #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 *); + + struct stat; + int safe_path(const char *, struct stat *, const char *, uid_t, +diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.refactor 2017-09-27 13:10:19.634831038 +0200 ++++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +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 2017-09-27 13:10:19.634831038 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2017-09-27 13:12:06.811420371 +0200 +@@ -48,11 +48,6 @@ + #include + #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) +@@ -222,7 +217,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; +@@ -240,8 +236,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; +@@ -249,7 +245,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 +267,7 @@ sshd_selinux_getctxbyname(char *pwname, + + if (r == 0) { + /* If launched from xinetd, we must use current level */ +- if (inetd_flag && !rexeced_flag) { ++ if (inetd) { + security_context_t sshdsc=NULL; + + if (getcon_raw(&sshdsc) < 0) +@@ -332,7 +328,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 +338,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 = ""; +@@ -361,9 +358,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 +@@ -373,25 +371,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__); +@@ -409,7 +410,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 2017-09-27 13:10:19.574830708 +0200 ++++ openssh/platform.c 2017-09-27 13:11:45.475303050 +0200 +@@ -33,6 +33,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) +@@ -184,7 +187,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 2017-09-27 13:10:19.674831257 +0200 ++++ openssh/sshd.c 2017-09-27 13:12:01.635391909 +0200 +@@ -2135,7 +2135,9 @@ main(int ac, char **av) + } + #endif + #ifdef WITH_SELINUX +- sshd_selinux_setup_exec_context(authctxt->pw->pw_name); ++ sshd_selinux_setup_exec_context(authctxt->pw->pw_name, ++ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt, ++ options.use_pam); + #endif + #ifdef USE_PAM + if (options.use_pam) { diff --git a/openssh-7.5p1-gsissh.patch b/openssh-7.6p1-gsissh.patch similarity index 88% rename from openssh-7.5p1-gsissh.patch rename to openssh-7.6p1-gsissh.patch index fcd7508..118cf77 100644 --- a/openssh-7.5p1-gsissh.patch +++ b/openssh-7.6p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c ---- openssh-7.5p1.orig/auth2.c 2017-07-30 23:44:44.760055252 +0200 -+++ openssh-7.5p1/auth2.c 2017-07-31 00:04:16.612262807 +0200 -@@ -229,7 +229,27 @@ +diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c +--- openssh-7.6p1.orig/auth2.c 2017-11-22 17:20:57.185924812 +0100 ++++ openssh-7.6p1/auth2.c 2017-11-22 17:21:29.017573490 +0100 +@@ -233,7 +233,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -30,7 +30,7 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -240,11 +260,32 @@ +@@ -244,11 +264,32 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -67,7 +67,7 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c authctxt->valid = 1; debug2("%s: setting up authctxt for %s", __func__, user); -@@ -252,6 +293,9 @@ +@@ -256,6 +297,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -77,7 +77,7 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); -@@ -260,6 +304,7 @@ +@@ -264,6 +308,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -85,7 +85,7 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -274,9 +319,10 @@ +@@ -278,9 +323,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -99,20 +99,20 @@ diff -Nur openssh-7.5p1.orig/auth2.c openssh-7.5p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c ---- openssh-7.5p1.orig/auth2-gss.c 2017-07-30 23:44:44.751055255 +0200 -+++ openssh-7.5p1/auth2-gss.c 2017-07-31 00:04:16.614262806 +0200 +diff -Nur openssh-7.6p1.orig/auth2-gss.c openssh-7.6p1/auth2-gss.c +--- openssh-7.6p1.orig/auth2-gss.c 2017-11-22 17:20:57.105925695 +0100 ++++ openssh-7.6p1/auth2-gss.c 2017-11-22 17:27:53.583329418 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; +static void ssh_gssapi_userauth_error(Gssctxt *ctxt); - static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); - static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); - static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); -@@ -61,8 +62,8 @@ - userauth_gsskeyex(Authctxt *authctxt) + static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); + 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); +@@ -62,8 +63,8 @@ { + Authctxt *authctxt = ssh->authctxt; int authenticated = 0; - Buffer b; - gss_buffer_desc mic, gssbuf; @@ -121,7 +121,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c u_int len; mic.value = packet_get_string(&len); -@@ -76,13 +77,27 @@ +@@ -77,13 +78,27 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -152,7 +152,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -103,7 +118,10 @@ +@@ -105,7 +120,10 @@ u_int len; u_char *doid = NULL; @@ -164,7 +164,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c return (0); mechs = packet_get_int(); -@@ -168,7 +186,7 @@ +@@ -170,7 +188,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -173,7 +173,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c u_int len; if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) -@@ -186,6 +204,7 @@ +@@ -188,6 +206,7 @@ free(recv_tok.value); if (GSS_ERROR(maj_status)) { @@ -181,7 +181,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c if (send_tok.length != 0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); packet_put_string(send_tok.value, send_tok.length); -@@ -251,6 +270,32 @@ +@@ -253,6 +272,32 @@ return 0; } @@ -214,7 +214,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -266,6 +311,8 @@ +@@ -269,6 +314,8 @@ if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); @@ -223,7 +223,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -273,8 +320,13 @@ +@@ -276,8 +323,13 @@ packet_check_eom(); @@ -237,9 +237,9 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c + authenticated = 0; + } - if (authenticated) - authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -319,9 +371,16 @@ + if ((!use_privsep || mm_is_monitor()) && + (displayname = ssh_gssapi_displayname()) != NULL) +@@ -324,9 +376,16 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); @@ -258,7 +258,7 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -342,6 +401,23 @@ +@@ -348,6 +407,23 @@ return 0; } @@ -282,10 +282,10 @@ diff -Nur openssh-7.5p1.orig/auth2-gss.c openssh-7.5p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c ---- openssh-7.5p1.orig/auth.c 2017-07-30 23:44:44.761055251 +0200 -+++ openssh-7.5p1/auth.c 2017-07-31 00:04:16.615262805 +0200 -@@ -77,6 +77,9 @@ +diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c +--- openssh-7.6p1.orig/auth.c 2017-11-22 17:20:57.186924801 +0100 ++++ openssh-7.6p1/auth.c 2017-11-22 17:21:29.019573467 +0100 +@@ -74,6 +74,9 @@ #include "ssherr.h" #include "compat.h" @@ -295,7 +295,7 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -314,7 +317,8 @@ +@@ -337,7 +340,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -304,8 +304,8 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c + authctxt->user : "unknown", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), - authctxt->info != NULL ? ": " : "", -@@ -340,6 +344,23 @@ + extra != NULL ? ": " : "", +@@ -363,6 +367,23 @@ if (authenticated == 0 && !authctxt->postponed) audit_event(audit_classify_auth(method)); #endif @@ -329,7 +329,7 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c } -@@ -642,6 +663,10 @@ +@@ -575,6 +596,10 @@ #endif pw = getpwnam(user); @@ -340,7 +340,7 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -661,7 +686,8 @@ +@@ -594,7 +619,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -350,10 +350,22 @@ diff -Nur openssh-7.5p1.orig/auth.c openssh-7.5p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c ---- openssh-7.5p1.orig/auth-pam.c 2017-07-30 23:44:44.777055246 +0200 -+++ openssh-7.5p1/auth-pam.c 2017-07-31 00:04:16.616262804 +0200 -@@ -289,6 +289,56 @@ +diff -Nur openssh-7.6p1.orig/auth.h openssh-7.6p1/auth.h +--- openssh-7.6p1.orig/auth.h 2017-11-22 17:20:57.186924801 +0100 ++++ openssh-7.6p1/auth.h 2017-11-22 22:08:00.454673050 +0100 +@@ -83,6 +83,8 @@ + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++#endif ++#ifdef GSSAPI + int krb5_set_env; + #endif + struct sshbuf *loginmsg; +diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c +--- openssh-7.6p1.orig/auth-pam.c 2017-11-22 17:20:57.206924580 +0100 ++++ openssh-7.6p1/auth-pam.c 2017-11-22 17:33:46.528425133 +0100 +@@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -410,7 +422,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -311,7 +361,7 @@ +@@ -310,7 +360,7 @@ static void import_environments(Buffer *b) { @@ -419,7 +431,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c u_int i, num_env; int err; -@@ -321,6 +371,17 @@ +@@ -320,6 +370,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -437,7 +449,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -472,6 +533,13 @@ +@@ -471,6 +532,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -448,10 +460,10 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c + debug("sshpam_thread: user is '%.100s'", + sshpam_authctxt->pw->pw_name); + } - if (compat20) { - if (!do_pam_account()) { - sshpam_err = PAM_ACCT_EXPIRED; -@@ -492,6 +560,11 @@ + if (!do_pam_account()) { + sshpam_err = PAM_ACCT_EXPIRED; + goto auth_fail; +@@ -489,6 +557,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -463,7 +475,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -949,6 +1022,18 @@ +@@ -964,6 +1037,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -482,7 +494,7 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1235,6 +1320,9 @@ +@@ -1253,6 +1338,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -492,9 +504,9 @@ diff -Nur openssh-7.5p1.orig/auth-pam.c openssh-7.5p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.5p1.orig/auth-pam.h openssh-7.5p1/auth-pam.h ---- openssh-7.5p1.orig/auth-pam.h 2017-07-30 23:44:44.677055280 +0200 -+++ openssh-7.5p1/auth-pam.h 2017-07-31 00:04:16.617262803 +0200 +diff -Nur openssh-7.6p1.orig/auth-pam.h openssh-7.6p1/auth-pam.h +--- openssh-7.6p1.orig/auth-pam.h 2017-11-22 17:20:57.061926180 +0100 ++++ openssh-7.6p1/auth-pam.h 2017-11-22 17:21:29.020573456 +0100 @@ -41,5 +41,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -502,9 +514,9 @@ diff -Nur openssh-7.5p1.orig/auth-pam.h openssh-7.5p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.5p1.orig/canohost.c openssh-7.5p1/canohost.c ---- openssh-7.5p1.orig/canohost.c 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/canohost.c 2017-07-31 00:04:16.617262803 +0200 +diff -Nur openssh-7.6p1.orig/canohost.c openssh-7.6p1/canohost.c +--- openssh-7.6p1.orig/canohost.c 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/canohost.c 2017-11-22 17:21:29.020573456 +0100 @@ -17,6 +17,7 @@ #include #include @@ -547,9 +559,9 @@ diff -Nur openssh-7.5p1.orig/canohost.c openssh-7.5p1/canohost.c + } + } +} -diff -Nur openssh-7.5p1.orig/canohost.h openssh-7.5p1/canohost.h ---- openssh-7.5p1.orig/canohost.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/canohost.h 2017-07-31 00:04:16.618262802 +0200 +diff -Nur openssh-7.6p1.orig/canohost.h openssh-7.6p1/canohost.h +--- openssh-7.6p1.orig/canohost.h 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/canohost.h 2017-11-22 17:21:29.021573445 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -557,10 +569,10 @@ diff -Nur openssh-7.5p1.orig/canohost.h openssh-7.5p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac ---- openssh-7.5p1.orig/configure.ac 2017-07-30 23:44:44.757055253 +0200 -+++ openssh-7.5p1/configure.ac 2017-07-31 00:04:16.621262800 +0200 -@@ -4440,6 +4440,14 @@ +diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac +--- openssh-7.6p1.orig/configure.ac 2017-11-22 17:20:57.216924470 +0100 ++++ openssh-7.6p1/configure.ac 2017-11-22 17:21:29.022573434 +0100 +@@ -4455,6 +4455,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -575,7 +587,7 @@ diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4479,6 +4487,50 @@ +@@ -4494,6 +4502,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -626,9 +638,9 @@ diff -Nur openssh-7.5p1.orig/configure.ac openssh-7.5p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c ---- openssh-7.5p1.orig/gss-genr.c 2017-07-30 23:44:44.778055246 +0200 -+++ openssh-7.5p1/gss-genr.c 2017-07-31 00:04:16.622262799 +0200 +diff -Nur openssh-7.6p1.orig/gss-genr.c openssh-7.6p1/gss-genr.c +--- openssh-7.6p1.orig/gss-genr.c 2017-11-22 17:20:57.208924558 +0100 ++++ openssh-7.6p1/gss-genr.c 2017-11-22 17:21:29.023573423 +0100 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -637,7 +649,7 @@ diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "key.h" -@@ -370,9 +371,18 @@ +@@ -371,9 +372,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -657,7 +669,7 @@ diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -380,6 +390,7 @@ +@@ -381,6 +391,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -665,9 +677,9 @@ diff -Nur openssh-7.5p1.orig/gss-genr.c openssh-7.5p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c ---- openssh-7.5p1.orig/gss-serv.c 2017-07-30 23:44:44.751055255 +0200 -+++ openssh-7.5p1/gss-serv.c 2017-07-31 00:04:16.624262798 +0200 +diff -Nur openssh-7.6p1.orig/gss-serv.c openssh-7.6p1/gss-serv.c +--- openssh-7.6p1.orig/gss-serv.c 2017-11-22 17:20:57.153925165 +0100 ++++ openssh-7.6p1/gss-serv.c 2017-11-22 17:26:51.374016714 +0100 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -863,10 +875,10 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c + expand_authorized_keys(options.gss_creds_path, + the_authctxt->pw); + } - (*gssapi_client.mech->storecreds)(&gssapi_client); + return (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -451,16 +514,19 @@ +@@ -443,16 +506,19 @@ } /* Privileged */ @@ -890,7 +902,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -471,6 +537,7 @@ +@@ -463,6 +529,7 @@ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); @@ -898,7 +910,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c explicit_bzero(&gssapi_client, sizeof(ssh_gssapi_client)); return 0; -@@ -480,6 +547,24 @@ +@@ -472,6 +539,24 @@ return (0); } @@ -923,7 +935,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -506,6 +591,7 @@ +@@ -498,6 +583,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -931,7 +943,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c #endif if (gssapi_client.store.filename == NULL && -@@ -535,6 +621,18 @@ +@@ -527,6 +613,18 @@ if (ret) return; @@ -950,8 +962,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -566,4 +664,13 @@ - return ok; +@@ -567,4 +665,13 @@ + return (char *)gssapi_client.displayname.value; } +/* added for Globus usage */ @@ -964,10 +976,10 @@ diff -Nur openssh-7.5p1.orig/gss-serv.c openssh-7.5p1/gss-serv.c +} + #endif -diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c ---- openssh-7.5p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/gss-serv-gsi.c 2017-07-31 00:04:16.624262798 +0200 -@@ -0,0 +1,329 @@ +diff -Nur openssh-7.6p1.orig/gss-serv-gsi.c openssh-7.6p1/gss-serv-gsi.c +--- openssh-7.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.6p1/gss-serv-gsi.c 2017-11-22 22:06:29.452688621 +0100 +@@ -0,0 +1,331 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * @@ -1019,8 +1031,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + +static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name); +static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user); -+static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client); -+static void ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client); ++static int ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client); ++static int ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client); +static int ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client); +static int ssh_gssapi_gsi_updatecreds_micv2(ssh_gssapi_ccache *store, @@ -1146,7 +1158,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +/* + * Export GSI credentials to disk. + */ -+static void ++static int +ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client) +{ + OM_uint32 major_status; @@ -1155,7 +1167,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + char * p; + + if (!client || !client->creds) { -+ return; ++ return 0; + } + + major_status = gss_export_cred(&minor_status, @@ -1171,7 +1183,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid); + ssh_gssapi_error(ctx); + ssh_gssapi_delete_ctx(&ctx); -+ return; ++ return 0; + } + + p = strchr((char *) export_cred.value, '='); @@ -1179,7 +1191,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + logit("Failed to parse exported credentials string '%.100s'", + (char *)export_cred.value); + gss_release_buffer(&minor_status, &export_cred); -+ return; ++ return 0; + } + *p++ = '\0'; + if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { @@ -1207,12 +1219,14 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + do_pam_putenv(client->store.envvar, client->store.envval); +#endif + gss_release_buffer(&minor_status, &export_cred); ++ ++ return 1; +} + +/* + * Export GSI credentials to disk. + */ -+static void ++static int +ssh_gssapi_gsi_storecreds_micv2(ssh_gssapi_client *client) +{ + OM_uint32 major_status; @@ -1221,7 +1235,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + char * p; + + if (!client || !client->creds) { -+ return; ++ return 0; + } + + major_status = gss_export_cred(&minor_status, @@ -1237,7 +1251,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech_micv2.oid); + ssh_gssapi_error(ctx); + ssh_gssapi_delete_ctx(&ctx); -+ return; ++ return 0; + } + + p = strchr((char *) export_cred.value, '='); @@ -1245,7 +1259,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + logit("Failed to parse exported credentials string '%.100s'", + (char *)export_cred.value); + gss_release_buffer(&minor_status, &export_cred); -+ return; ++ return 0; + } + *p++ = '\0'; + if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) { @@ -1273,6 +1287,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c + do_pam_putenv(client->store.envvar, client->store.envval); +#endif + gss_release_buffer(&minor_status, &export_cred); ++ ++ return 1; +} + +/* @@ -1281,8 +1297,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +static int +ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,ssh_gssapi_client *client) +{ -+ ssh_gssapi_gsi_storecreds(client); -+ return 1; ++ return ssh_gssapi_gsi_storecreds(client); +} + +/* @@ -1291,15 +1306,14 @@ diff -Nur openssh-7.5p1.orig/gss-serv-gsi.c openssh-7.5p1/gss-serv-gsi.c +static int +ssh_gssapi_gsi_updatecreds_micv2(ssh_gssapi_ccache *store,ssh_gssapi_client *client) +{ -+ ssh_gssapi_gsi_storecreds_micv2(client); -+ return 1; ++ return ssh_gssapi_gsi_storecreds_micv2(client); +} + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c ---- openssh-7.5p1.orig/gss-serv-krb5.c 2017-07-30 23:44:44.733055261 +0200 -+++ openssh-7.5p1/gss-serv-krb5.c 2017-07-31 00:04:16.624262798 +0200 +diff -Nur openssh-7.6p1.orig/gss-serv-krb5.c openssh-7.6p1/gss-serv-krb5.c +--- openssh-7.6p1.orig/gss-serv-krb5.c 2017-11-22 17:20:57.140925308 +0100 ++++ openssh-7.6p1/gss-serv-krb5.c 2017-11-22 17:21:29.025573401 +0100 @@ -378,6 +378,34 @@ return found_principal; } @@ -1335,8 +1349,8 @@ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -482,7 +510,7 @@ - return; +@@ -483,7 +511,7 @@ + return set_env; } -int @@ -1344,7 +1358,7 @@ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -553,7 +581,7 @@ +@@ -554,7 +582,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1353,18 +1367,18 @@ diff -Nur openssh-7.5p1.orig/gss-serv-krb5.c openssh-7.5p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c ---- openssh-7.5p1.orig/kexgsss.c 2017-07-30 23:44:44.779055245 +0200 -+++ openssh-7.5p1/kexgsss.c 2017-07-31 00:04:16.625262797 +0200 -@@ -47,6 +47,7 @@ - #include "ssh-gss.h" +diff -Nur openssh-7.6p1.orig/kexgsss.c openssh-7.6p1/kexgsss.c +--- openssh-7.6p1.orig/kexgsss.c 2017-11-22 17:20:57.209924547 +0100 ++++ openssh-7.6p1/kexgsss.c 2017-11-22 17:21:29.026573390 +0100 +@@ -48,6 +48,7 @@ #include "digest.h" + #include "ssherr.h" +static void kex_gss_send_error(Gssctxt *ctxt); extern ServerOptions options; int -@@ -96,8 +97,10 @@ +@@ -97,8 +98,10 @@ debug2("%s: Acquiring credentials", __func__); @@ -1376,7 +1390,7 @@ diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -185,12 +188,13 @@ +@@ -190,12 +193,13 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1391,9 +1405,9 @@ diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -297,4 +301,23 @@ - ssh_gssapi_rekey_creds(); - return 0; +@@ -636,4 +640,23 @@ + } + return r; } + +static void @@ -1415,9 +1429,9 @@ diff -Nur openssh-7.5p1.orig/kexgsss.c openssh-7.5p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.5p1.orig/LICENSE.globus_usage openssh-7.5p1/LICENSE.globus_usage ---- openssh-7.5p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/LICENSE.globus_usage 2017-07-31 00:04:16.625262797 +0200 +diff -Nur openssh-7.6p1.orig/LICENSE.globus_usage openssh-7.6p1/LICENSE.globus_usage +--- openssh-7.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.6p1/LICENSE.globus_usage 2017-11-22 17:21:29.027573379 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1437,10 +1451,10 @@ diff -Nur openssh-7.5p1.orig/LICENSE.globus_usage openssh-7.5p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.5p1.orig/Makefile.in openssh-7.5p1/Makefile.in ---- openssh-7.5p1.orig/Makefile.in 2017-07-30 23:44:44.779055245 +0200 -+++ openssh-7.5p1/Makefile.in 2017-07-31 00:04:16.625262797 +0200 -@@ -114,8 +114,10 @@ +diff -Nur openssh-7.6p1.orig/Makefile.in openssh-7.6p1/Makefile.in +--- openssh-7.6p1.orig/Makefile.in 2017-11-22 17:20:57.210924536 +0100 ++++ openssh-7.6p1/Makefile.in 2017-11-22 17:21:29.027573379 +0100 +@@ -116,8 +116,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1451,10 +1465,10 @@ diff -Nur openssh-7.5p1.orig/Makefile.in openssh-7.5p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o -diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c ---- openssh-7.5p1.orig/misc.c 2017-07-30 23:44:44.732055261 +0200 -+++ openssh-7.5p1/misc.c 2017-07-31 00:04:16.625262797 +0200 -@@ -161,11 +161,14 @@ +diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c +--- openssh-7.6p1.orig/misc.c 2017-11-22 17:20:57.178924889 +0100 ++++ openssh-7.6p1/misc.c 2017-11-22 17:21:29.028573368 +0100 +@@ -171,11 +171,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1470,7 +1484,7 @@ diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c int wspace = 0; if (*s == NULL) -@@ -173,6 +176,21 @@ +@@ -183,6 +186,21 @@ old = *s; @@ -1492,7 +1506,7 @@ diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); -@@ -228,6 +246,20 @@ +@@ -238,6 +256,20 @@ return copy; } @@ -1513,10 +1527,10 @@ diff -Nur openssh-7.5p1.orig/misc.c openssh-7.5p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.5p1.orig/misc.h openssh-7.5p1/misc.h ---- openssh-7.5p1.orig/misc.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/misc.h 2017-07-31 00:04:16.625262797 +0200 -@@ -69,6 +69,7 @@ +diff -Nur openssh-7.6p1.orig/misc.h openssh-7.6p1/misc.h +--- openssh-7.6p1.orig/misc.h 2017-11-22 17:20:57.178924889 +0100 ++++ openssh-7.6p1/misc.h 2017-11-22 17:21:29.029573357 +0100 +@@ -70,6 +70,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1524,9 +1538,9 @@ diff -Nur openssh-7.5p1.orig/misc.h openssh-7.5p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c ---- openssh-7.5p1.orig/monitor.c 2017-07-30 23:44:44.780055245 +0200 -+++ openssh-7.5p1/monitor.c 2017-07-31 00:04:16.626262796 +0200 +diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c +--- openssh-7.6p1.orig/monitor.c 2017-11-22 17:20:57.210924536 +0100 ++++ openssh-7.6p1/monitor.c 2017-11-22 17:43:44.857793492 +0100 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1577,7 +1591,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -340,6 +348,8 @@ +@@ -339,6 +347,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1586,7 +1600,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -458,6 +468,8 @@ +@@ -451,6 +461,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1595,7 +1609,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c #endif if (!no_pty_flag) { -@@ -765,14 +777,17 @@ +@@ -758,14 +770,17 @@ debug3("%s", __func__); @@ -1616,11 +1630,12 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -1959,12 +1974,15 @@ +@@ -1966,13 +1981,16 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; + int gssapi_keyex; + const char *displayname; if (!options.gss_authentication && !options.gss_keyex) fatal("%s: GSSAPI authentication not enabled", __func__); @@ -1633,7 +1648,7 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1972,7 +1990,10 @@ +@@ -1980,7 +1998,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1643,9 +1658,9 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c + else + auth_method = "gssapi-with-mic"; - if (authenticated) - authctxt->last_details = ssh_gssapi_get_displayname(); -@@ -1981,6 +2002,68 @@ + if ((displayname = ssh_gssapi_displayname()) != NULL) + auth2_record_info(authctxt, "%s", displayname); +@@ -1989,6 +2010,68 @@ return (authenticated); } @@ -1714,9 +1729,9 @@ diff -Nur openssh-7.5p1.orig/monitor.c openssh-7.5p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.5p1.orig/monitor.h openssh-7.5p1/monitor.h ---- openssh-7.5p1.orig/monitor.h 2017-07-30 23:44:44.762055251 +0200 -+++ openssh-7.5p1/monitor.h 2017-07-31 00:04:16.626262796 +0200 +diff -Nur openssh-7.6p1.orig/monitor.h openssh-7.6p1/monitor.h +--- openssh-7.6p1.orig/monitor.h 2017-11-22 17:20:57.188924779 +0100 ++++ openssh-7.6p1/monitor.h 2017-11-22 17:21:29.031573335 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1730,10 +1745,10 @@ diff -Nur openssh-7.5p1.orig/monitor.h openssh-7.5p1/monitor.h }; struct monitor { -diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c ---- openssh-7.5p1.orig/monitor_wrap.c 2017-07-30 23:44:44.774055247 +0200 -+++ openssh-7.5p1/monitor_wrap.c 2017-07-31 00:04:16.626262796 +0200 -@@ -977,12 +977,13 @@ +diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c +--- openssh-7.6p1.orig/monitor_wrap.c 2017-11-22 17:20:57.203924613 +0100 ++++ openssh-7.6p1/monitor_wrap.c 2017-11-22 17:21:29.477568413 +0100 +@@ -992,12 +992,13 @@ } int @@ -1748,7 +1763,7 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -995,6 +996,83 @@ +@@ -1010,6 +1011,83 @@ return (authenticated); } @@ -1832,10 +1847,10 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.c openssh-7.5p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.5p1.orig/monitor_wrap.h openssh-7.5p1/monitor_wrap.h ---- openssh-7.5p1.orig/monitor_wrap.h 2017-07-30 23:44:44.766055250 +0200 -+++ openssh-7.5p1/monitor_wrap.h 2017-07-31 00:04:16.626262796 +0200 -@@ -59,9 +59,13 @@ +diff -Nur openssh-7.6p1.orig/monitor_wrap.h openssh-7.6p1/monitor_wrap.h +--- openssh-7.6p1.orig/monitor_wrap.h 2017-11-22 17:20:57.193924724 +0100 ++++ openssh-7.6p1/monitor_wrap.h 2017-11-22 17:21:29.477568413 +0100 +@@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1850,10 +1865,10 @@ diff -Nur openssh-7.5p1.orig/monitor_wrap.h openssh-7.5p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.5p1.orig/readconf.c openssh-7.5p1/readconf.c ---- openssh-7.5p1.orig/readconf.c 2017-07-30 23:44:44.770055248 +0200 -+++ openssh-7.5p1/readconf.c 2017-07-31 00:04:16.626262796 +0200 -@@ -1995,13 +1995,13 @@ +diff -Nur openssh-7.6p1.orig/readconf.c openssh-7.6p1/readconf.c +--- openssh-7.6p1.orig/readconf.c 2017-11-22 17:20:57.197924679 +0100 ++++ openssh-7.6p1/readconf.c 2017-11-22 17:21:29.478568402 +0100 +@@ -1983,13 +1983,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1871,10 +1886,10 @@ diff -Nur openssh-7.5p1.orig/readconf.c openssh-7.5p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.5p1.orig/readconf.h openssh-7.5p1/readconf.h ---- openssh-7.5p1.orig/readconf.h 2017-07-30 23:44:44.748055256 +0200 -+++ openssh-7.5p1/readconf.h 2017-07-31 00:04:16.626262796 +0200 -@@ -86,6 +86,8 @@ +diff -Nur openssh-7.6p1.orig/readconf.h openssh-7.6p1/readconf.h +--- openssh-7.6p1.orig/readconf.h 2017-11-22 17:20:57.158925110 +0100 ++++ openssh-7.6p1/readconf.h 2017-11-22 17:21:29.478568402 +0100 +@@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1883,9 +1898,9 @@ diff -Nur openssh-7.5p1.orig/readconf.h openssh-7.5p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c ---- openssh-7.5p1.orig/servconf.c 2017-07-30 23:44:44.775055247 +0200 -+++ openssh-7.5p1/servconf.c 2017-07-31 00:04:16.627262795 +0200 +diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c +--- openssh-7.6p1.orig/servconf.c 2017-11-22 17:20:57.204924602 +0100 ++++ openssh-7.6p1/servconf.c 2017-11-22 17:21:29.479568391 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -1905,8 +1920,8 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c + options->gsi_allow_limited_proxy = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; - options->password_authentication = -1; -@@ -160,6 +163,8 @@ + options->use_kuserok = -1; +@@ -162,6 +165,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -2014,7 +2029,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1065,6 +1094,10 @@ +@@ -1090,6 +1119,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2025,7 +2040,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1272,6 +1305,10 @@ +@@ -1297,6 +1330,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2036,7 +2051,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1280,6 +1317,10 @@ +@@ -1305,6 +1342,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2047,7 +2062,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1300,6 +1341,12 @@ +@@ -1325,6 +1366,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2060,7 +2075,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1771,6 +1818,35 @@ +@@ -1797,6 +1844,35 @@ *charptr = xstrdup(arg); break; @@ -2096,7 +2111,7 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2067,6 +2143,7 @@ +@@ -2092,6 +2168,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2104,13 +2119,13 @@ diff -Nur openssh-7.5p1.orig/servconf.c openssh-7.5p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h ---- openssh-7.5p1.orig/servconf.h 2017-07-30 23:44:44.755055253 +0200 -+++ openssh-7.5p1/servconf.h 2017-07-31 01:10:42.382769264 +0200 -@@ -118,9 +118,12 @@ - * file on logout. */ - int kerberos_get_afs_token; /* If true, try to get AFS token if +diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h +--- openssh-7.6p1.orig/servconf.h 2017-11-22 17:20:57.164925044 +0100 ++++ openssh-7.6p1/servconf.h 2017-11-22 17:30:04.398883887 +0100 +@@ -122,9 +122,12 @@ * authenticated with Kerberos. */ + int use_kuserok; + int enable_k5users; + int gsi_allow_limited_proxy; /* If true, accept limited proxies */ int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_deleg_creds; /* If true, store delegated GSSAPI credentials*/ @@ -2120,7 +2135,7 @@ diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -177,6 +180,7 @@ +@@ -181,6 +184,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2128,9 +2143,9 @@ diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h int permit_tun; -@@ -185,6 +189,10 @@ - int use_kuserok; - int enable_k5users; +@@ -188,6 +192,10 @@ + u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */ + char *chroot_directory; + + int disable_usage_stats; @@ -2139,10 +2154,10 @@ diff -Nur openssh-7.5p1.orig/servconf.h openssh-7.5p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.5p1.orig/ssh.1 openssh-7.5p1/ssh.1 ---- openssh-7.5p1.orig/ssh.1 2017-07-30 23:44:44.753055254 +0200 -+++ openssh-7.5p1/ssh.1 2017-07-31 00:04:16.628262794 +0200 -@@ -1436,6 +1436,18 @@ +diff -Nur openssh-7.6p1.orig/ssh.1 openssh-7.6p1/ssh.1 +--- openssh-7.6p1.orig/ssh.1 2017-11-22 17:20:57.155925143 +0100 ++++ openssh-7.6p1/ssh.1 2017-11-22 17:21:29.481568368 +0100 +@@ -1404,6 +1404,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2161,10 +2176,10 @@ diff -Nur openssh-7.5p1.orig/ssh.1 openssh-7.5p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c ---- openssh-7.5p1.orig/ssh.c 2017-07-30 23:44:44.781055245 +0200 -+++ openssh-7.5p1/ssh.c 2017-07-31 00:04:16.628262794 +0200 -@@ -472,6 +472,32 @@ +diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c +--- openssh-7.6p1.orig/ssh.c 2017-11-22 17:20:57.212924514 +0100 ++++ openssh-7.6p1/ssh.c 2017-11-22 17:21:29.481568368 +0100 +@@ -470,6 +470,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2197,7 +2212,7 @@ diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1193,8 +1219,12 @@ +@@ -1189,8 +1215,12 @@ logit("FIPS mode initialized"); } @@ -2211,11 +2226,11 @@ diff -Nur openssh-7.5p1.orig/ssh.c openssh-7.5p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.5p1.orig/ssh_config openssh-7.5p1/ssh_config ---- openssh-7.5p1.orig/ssh_config 2017-07-30 23:44:44.714055267 +0200 -+++ openssh-7.5p1/ssh_config 2017-07-31 00:04:16.628262794 +0200 -@@ -24,10 +24,10 @@ - # RSAAuthentication yes +diff -Nur openssh-7.6p1.orig/ssh_config openssh-7.6p1/ssh_config +--- openssh-7.6p1.orig/ssh_config 2017-11-22 17:20:57.112925618 +0100 ++++ openssh-7.6p1/ssh_config 2017-11-22 17:21:29.482568357 +0100 +@@ -22,10 +22,10 @@ + # ForwardX11 no # PasswordAuthentication yes # HostbasedAuthentication no -# GSSAPIAuthentication no @@ -2229,10 +2244,10 @@ diff -Nur openssh-7.5p1.orig/ssh_config openssh-7.5p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 ---- openssh-7.5p1.orig/ssh_config.5 2017-07-30 23:44:44.748055256 +0200 -+++ openssh-7.5p1/ssh_config.5 2017-07-31 00:04:16.628262794 +0200 -@@ -55,6 +55,12 @@ +diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 +--- openssh-7.6p1.orig/ssh_config.5 2017-11-22 17:20:57.173924944 +0100 ++++ openssh-7.6p1/ssh_config.5 2017-11-22 17:21:29.482568357 +0100 +@@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config .It @@ -2245,7 +2260,7 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -752,7 +758,7 @@ +@@ -720,7 +726,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2254,7 +2269,7 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -760,12 +766,12 @@ +@@ -728,12 +734,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2269,7 +2284,7 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -797,7 +803,7 @@ +@@ -765,7 +771,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2278,7 +2293,7 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1243,7 +1249,7 @@ +@@ -1214,7 +1220,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2286,11 +2301,11 @@ diff -Nur openssh-7.5p1.orig/ssh_config.5 openssh-7.5p1/ssh_config.5 +gssapi-keyex,gssapi-with-mic,hostbased,publickey, keyboard-interactive,password .Ed - .It Cm Protocol -diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c ---- openssh-7.5p1.orig/sshconnect2.c 2017-07-30 23:44:44.781055245 +0200 -+++ openssh-7.5p1/sshconnect2.c 2017-07-31 06:05:17.317851971 +0200 -@@ -167,7 +167,7 @@ + .It Cm ProxyCommand +diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c +--- openssh-7.6p1.orig/sshconnect2.c 2017-11-22 17:20:57.211924525 +0100 ++++ openssh-7.6p1/sshconnect2.c 2017-11-22 17:21:29.483568346 +0100 +@@ -285,7 +285,7 @@ #ifdef GSSAPI char *orig = NULL, *gss = NULL; @@ -2299,7 +2314,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c #endif xxx_host = host; -@@ -184,7 +184,7 @@ +@@ -302,7 +302,7 @@ orig = options.kex_algorithms; if (options.gss_trust_dns) @@ -2308,7 +2323,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c else gss_host = host; -@@ -728,6 +728,11 @@ +@@ -852,6 +852,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2320,7 +2335,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -817,7 +822,8 @@ +@@ -941,7 +946,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2330,7 +2345,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); packet_send(); } else { -@@ -965,6 +971,20 @@ +@@ -1089,6 +1095,20 @@ return 0; } @@ -2351,7 +2366,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -982,8 +1002,16 @@ +@@ -1106,8 +1126,16 @@ return (0); } @@ -2368,7 +2383,7 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -994,7 +1022,15 @@ +@@ -1118,7 +1146,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2384,10 +2399,10 @@ diff -Nur openssh-7.5p1.orig/sshconnect2.c openssh-7.5p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.5p1.orig/sshd.8 openssh-7.5p1/sshd.8 ---- openssh-7.5p1.orig/sshd.8 2017-07-30 23:44:44.737055260 +0200 -+++ openssh-7.5p1/sshd.8 2017-07-31 00:04:16.629262793 +0200 -@@ -740,6 +740,44 @@ +diff -Nur openssh-7.6p1.orig/sshd.8 openssh-7.6p1/sshd.8 +--- openssh-7.6p1.orig/sshd.8 2017-11-22 17:20:57.144925264 +0100 ++++ openssh-7.6p1/sshd.8 2017-11-22 17:21:29.484568335 +0100 +@@ -754,6 +754,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2432,10 +2447,10 @@ diff -Nur openssh-7.5p1.orig/sshd.8 openssh-7.5p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c ---- openssh-7.5p1.orig/sshd.c 2017-07-30 23:44:44.782055244 +0200 -+++ openssh-7.5p1/sshd.c 2017-07-31 00:04:16.629262793 +0200 -@@ -130,6 +130,7 @@ +diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c +--- openssh-7.6p1.orig/sshd.c 2017-11-22 17:20:57.212924514 +0100 ++++ openssh-7.6p1/sshd.c 2017-11-22 17:21:29.485568324 +0100 +@@ -129,6 +129,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -2443,7 +2458,7 @@ diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c #ifdef LIBWRAP #include -@@ -1717,6 +1718,13 @@ +@@ -1710,6 +1711,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2457,19 +2472,19 @@ diff -Nur openssh-7.5p1.orig/sshd.c openssh-7.5p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2219,7 +2227,7 @@ +@@ -2208,7 +2216,7 @@ #endif #ifdef GSSAPI - if (options.gss_authentication) { + if (options.gss_authentication && options.gss_deleg_creds) { temporarily_use_uid(authctxt->pw); - ssh_gssapi_storecreds(); + authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config ---- openssh-7.5p1.orig/sshd_config 2017-07-30 23:44:44.742055258 +0200 -+++ openssh-7.5p1/sshd_config 2017-07-31 00:04:16.630262793 +0200 -@@ -76,10 +76,11 @@ +diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config +--- openssh-7.6p1.orig/sshd_config 2017-11-22 17:20:57.151925187 +0100 ++++ openssh-7.6p1/sshd_config 2017-11-22 17:21:29.485568324 +0100 +@@ -85,10 +85,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2483,7 +2498,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -95,6 +96,10 @@ +@@ -104,6 +105,10 @@ # problems. UsePAM yes @@ -2494,7 +2509,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -130,6 +135,10 @@ +@@ -139,6 +144,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2505,9 +2520,9 @@ diff -Nur openssh-7.5p1.orig/sshd_config openssh-7.5p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 ---- openssh-7.5p1.orig/sshd_config.5 2017-07-30 23:44:44.756055253 +0200 -+++ openssh-7.5p1/sshd_config.5 2017-07-31 00:04:16.630262793 +0200 +diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 +--- openssh-7.6p1.orig/sshd_config.5 2017-11-22 17:20:57.174924933 +0100 ++++ openssh-7.6p1/sshd_config.5 2017-11-22 17:23:18.206368547 +0100 @@ -574,6 +574,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may @@ -2521,10 +2536,10 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 +Disabling reporting of usage metrics will cause the +.Cm UsageStatsTargets +setting to be ignored. - .It Cm ExposeAuthenticationMethods - When using SSH2, this option controls the exposure of the list of - successful authentication methods to PAM during the authentication -@@ -638,15 +647,34 @@ + .It Cm ExposeAuthInfo + Writes a temporary file containing a list of authentication methods and + public credentials (e.g. keys) used to authenticate the user. +@@ -631,15 +640,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2560,7 +2575,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -657,7 +685,7 @@ +@@ -650,7 +678,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2569,7 +2584,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -692,7 +720,6 @@ +@@ -689,7 +717,6 @@ .Pp The default is .Dq gss-gex-sha1-,gss-group14-sha1- . @@ -2577,7 +2592,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -@@ -1513,6 +1540,103 @@ +@@ -1509,6 +1536,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2681,7 +2696,7 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1554,6 +1678,12 @@ +@@ -1550,6 +1674,12 @@ as a non-root user. The default is .Cm no . @@ -2694,9 +2709,9 @@ diff -Nur openssh-7.5p1.orig/sshd_config.5 openssh-7.5p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c ---- openssh-7.5p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/ssh-globus-usage.c 2017-07-31 00:04:16.630262793 +0200 +diff -Nur openssh-7.6p1.orig/ssh-globus-usage.c openssh-7.6p1/ssh-globus-usage.c +--- openssh-7.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.6p1/ssh-globus-usage.c 2017-11-22 17:21:29.487568302 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3094,9 +3109,9 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.c openssh-7.5p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h ---- openssh-7.5p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.5p1/ssh-globus-usage.h 2017-07-31 00:04:16.630262793 +0200 +diff -Nur openssh-7.6p1.orig/ssh-globus-usage.h openssh-7.6p1/ssh-globus-usage.h +--- openssh-7.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.6p1/ssh-globus-usage.h 2017-11-22 17:21:29.487568302 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3146,10 +3161,10 @@ diff -Nur openssh-7.5p1.orig/ssh-globus-usage.h openssh-7.5p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h ---- openssh-7.5p1.orig/ssh-gss.h 2017-07-30 23:44:44.753055254 +0200 -+++ openssh-7.5p1/ssh-gss.h 2017-07-31 00:04:16.630262793 +0200 -@@ -89,12 +89,14 @@ +diff -Nur openssh-7.6p1.orig/ssh-gss.h openssh-7.6p1/ssh-gss.h +--- openssh-7.6p1.orig/ssh-gss.h 2017-11-22 17:20:57.173924944 +0100 ++++ openssh-7.6p1/ssh-gss.h 2017-11-22 17:30:42.783459732 +0100 +@@ -93,12 +93,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -3165,7 +3180,7 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -115,7 +117,7 @@ +@@ -119,7 +121,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -3174,7 +3189,7 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -148,6 +150,9 @@ +@@ -152,6 +154,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -3184,16 +3199,16 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -158,7 +163,7 @@ +@@ -162,7 +167,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -int ssh_gssapi_userok(char *name, struct passwd *); +int ssh_gssapi_userok(char *name, struct passwd *, int gssapi_keyex); - char* ssh_gssapi_get_displayname(void); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); -@@ -171,6 +176,7 @@ + void ssh_gssapi_cleanup_creds(void); +@@ -175,6 +180,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -3201,12 +3216,12 @@ diff -Nur openssh-7.5p1.orig/ssh-gss.h openssh-7.5p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.5p1.orig/version.h openssh-7.5p1/version.h ---- openssh-7.5p1.orig/version.h 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/version.h 2017-07-31 00:04:16.630262793 +0200 +diff -Nur openssh-7.6p1.orig/version.h openssh-7.6p1/version.h +--- openssh-7.6p1.orig/version.h 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/version.h 2017-11-22 17:21:29.488568291 +0100 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_7.5" + #define SSH_VERSION "OpenSSH_7.6" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-7.6p1-permitopen-bug.patch b/openssh-7.6p1-permitopen-bug.patch new file mode 100644 index 0000000..3dd4a57 --- /dev/null +++ b/openssh-7.6p1-permitopen-bug.patch @@ -0,0 +1,47 @@ +From 7c9613fac3371cf65fb07739212cdd1ebf6575da Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Wed, 4 Oct 2017 18:49:30 +0000 +Subject: [PATCH] upstream commit + +fix (another) problem in PermitOpen introduced during the +channels.c refactor: the third and subsequent arguments to PermitOpen were +being silently ignored; ok markus@ + +Upstream-ID: 067c89f1f53cbc381628012ba776d6861e6782fd +--- + servconf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/servconf.c b/servconf.c +index 2c321a4ad..956862959 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1,5 +1,5 @@ + +-/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */ ++/* $OpenBSD: servconf.c,v 1.313 2017/10/04 18:49:30 djm Exp $ */ + /* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved +@@ -1663,9 +1663,9 @@ process_server_config_line(ServerOptions *options, char *line, + if (!arg || *arg == '\0') + fatal("%s line %d: missing PermitOpen specification", + filename, linenum); +- i = options->num_permitted_opens; /* modified later */ ++ value = options->num_permitted_opens; /* modified later */ + if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { +- if (*activep && i == 0) { ++ if (*activep && value == 0) { + options->num_permitted_opens = 1; + options->permitted_opens = xcalloc(1, + sizeof(*options->permitted_opens)); +@@ -1683,7 +1683,7 @@ process_server_config_line(ServerOptions *options, char *line, + if (arg == NULL || ((port = permitopen_port(arg)) < 0)) + fatal("%s line %d: bad port number in " + "PermitOpen", filename, linenum); +- if (*activep && i == 0) { ++ if (*activep && value == 0) { + options->permitted_opens = xrecallocarray( + options->permitted_opens, + options->num_permitted_opens, + diff --git a/sources b/sources index 6289fb2..3d485c5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (openssh-7.5p1.tar.gz) = 58c542e8a110fb4316a68db94abb663fa1c810becd0638d45281df8aeca62c1f705090437a80e788e6c29121769b72a505feced537d3118c933fde01b5285c81 +SHA512 (openssh-7.6p1.tar.gz) = de17fdcb8239401f76740c8d689a8761802f6df94e68d953f3c70b9f4f8bdb403617c48c1d01cc8c368d88e9d50aee540bf03d5a36687dfb39dfd28d73029d72 From 3e0625ed70ad4e43d234122a6c64f7670a0e6b61 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 20 Dec 2017 10:03:02 +0100 Subject: [PATCH 046/146] Based on openssh-7.6p1-3.fc27 --- gsi-openssh.spec | 5 ++++- openssh-6.7p1-sftp-force-permission.patch | 2 +- openssh-7.6p1-audit.patch | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d5dc637..276ec2d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.6p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -548,6 +548,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Dec 20 2017 Mattias Ellert - 7.6p1-2 +- Based on openssh-7.6p1-3.fc27 + * Wed Nov 22 2017 Mattias Ellert - 7.6p1-1 - Based on openssh-7.6p1-2.fc27 diff --git a/openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch index 512996b..2d6e730 100644 --- a/openssh-6.7p1-sftp-force-permission.patch +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -38,7 +38,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; -+ mode_t old_umask; ++ mode_t old_umask = 0; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 2058c60..8ca4653 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -906,6 +906,15 @@ diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, +@@ -409,7 +409,7 @@ cipher_get_length(struct sshcipher_ctx * + void + cipher_free(struct sshcipher_ctx *cc) + { +- if (cc == NULL) ++ if (cc == NULL || cc->cipher == NULL) + return; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) + explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); diff -up openssh-7.6p1/cipher.h.audit openssh-7.6p1/cipher.h --- openssh-7.6p1/cipher.h.audit 2017-10-02 21:34:26.000000000 +0200 +++ openssh-7.6p1/cipher.h 2017-10-04 17:18:32.836505059 +0200 From 01510d75b6ee0a21b90ef7512037decceae85b96 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 20 Dec 2017 10:13:26 +0100 Subject: [PATCH 047/146] Based on openssh-7.6p1-4.fc28 --- gsi-openssh.spec | 5 ++++- openssh-7.5p1-sandbox.patch | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 276ec2d..2de9360 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.6p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -548,6 +548,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Dec 20 2017 Mattias Ellert - 7.6p1-3 +- Based on openssh-7.6p1-4.fc28 + * Wed Dec 20 2017 Mattias Ellert - 7.6p1-2 - Based on openssh-7.6p1-3.fc27 diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 75b7e6e..7cdb0aa 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -93,3 +93,16 @@ index e86aa2c..98062f1 100644 /* -- 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 From c99ce4eacce28e8185f30acbd316c2150be36952 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 18 Jan 2018 09:56:30 +0100 Subject: [PATCH 048/146] Based on openssh-7.6p1-5.1.fc28 --- gsi-openssh.spec | 11 +- ...sh-6.7p1-debian-restore-tcp-wrappers.patch | 140 ---------------- openssh-6.7p1-ldap.patch | 10 +- openssh-7.6p1-audit.patch | 107 +++++------- openssh-7.6p1-gsissh.patch | 154 +++++++++--------- 5 files changed, 124 insertions(+), 298 deletions(-) delete mode 100644 openssh-6.7p1-debian-restore-tcp-wrappers.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 2de9360..d487039 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.6p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -146,9 +146,6 @@ Patch918: openssh-6.6.1p1-log-in-chroot.patch Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch # Config parser shouldn't accept ip/port syntax (#1130733) Patch920: openssh-6.6.1p1-ip-port-config-parser.patch -# restore tcp wrappers support, based on Debian patch -# https://lists.mindrot.org/pipermail/openssh-unix-dev/2014-April/032497.html -Patch921: openssh-6.7p1-debian-restore-tcp-wrappers.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) @@ -192,7 +189,6 @@ BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel -BuildRequires: tcp_wrappers-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel @@ -320,7 +316,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch919 -p1 -b .scp %patch920 -p1 -b .config %patch802 -p1 -b .GSSAPIEnablek5users -%patch921 -p1 -b .tcp_wrappers %patch922 -p1 -b .sshdt %patch926 -p1 -b .sftp-force-mode %patch928 -p1 -b .memory @@ -386,7 +381,6 @@ fi --sysconfdir=%{_sysconfdir}/gsissh \ --libexecdir=%{_libexecdir}/gsissh \ --datadir=%{_datadir}/gsissh \ - --with-tcp-wrappers \ --with-default-path=/usr/local/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/gsisshd \ @@ -548,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Jan 18 2018 Mattias Ellert - 7.6p1-4 +- Based on openssh-7.6p1-5.1.fc28 + * Wed Dec 20 2017 Mattias Ellert - 7.6p1-3 - Based on openssh-7.6p1-4.fc28 diff --git a/openssh-6.7p1-debian-restore-tcp-wrappers.patch b/openssh-6.7p1-debian-restore-tcp-wrappers.patch deleted file mode 100644 index 2bd6fdf..0000000 --- a/openssh-6.7p1-debian-restore-tcp-wrappers.patch +++ /dev/null @@ -1,140 +0,0 @@ -diff -up openssh-7.4p1/configure.ac.tcp_wrappers openssh-7.4p1/configure.ac ---- openssh-7.4p1/configure.ac.tcp_wrappers 2016-12-23 15:36:38.745411192 +0100 -+++ openssh-7.4p1/configure.ac 2016-12-23 15:36:38.777411197 +0100 -@@ -1491,6 +1491,62 @@ AC_ARG_WITH([skey], - ] - ) - -+# Check whether user wants TCP wrappers support -+TCPW_MSG="no" -+AC_ARG_WITH([tcp-wrappers], -+ [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], -+ [ -+ if test "x$withval" != "xno" ; then -+ saved_LIBS="$LIBS" -+ saved_LDFLAGS="$LDFLAGS" -+ saved_CPPFLAGS="$CPPFLAGS" -+ if test -n "${withval}" && \ -+ test "x${withval}" != "xyes"; then -+ if test -d "${withval}/lib"; then -+ if test -n "${need_dash_r}"; then -+ LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" -+ else -+ LDFLAGS="-L${withval}/lib ${LDFLAGS}" -+ fi -+ else -+ if test -n "${need_dash_r}"; then -+ LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" -+ else -+ LDFLAGS="-L${withval} ${LDFLAGS}" -+ fi -+ fi -+ if test -d "${withval}/include"; then -+ CPPFLAGS="-I${withval}/include ${CPPFLAGS}" -+ else -+ CPPFLAGS="-I${withval} ${CPPFLAGS}" -+ fi -+ fi -+ LIBS="-lwrap $LIBS" -+ AC_MSG_CHECKING([for libwrap]) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -+#include -+#include -+#include -+#include -+int deny_severity = 0, allow_severity = 0; -+ ]], [[ -+ hosts_access(0); -+ ]])], [ -+ AC_MSG_RESULT([yes]) -+ AC_DEFINE([LIBWRAP], [1], -+ [Define if you want -+ TCP Wrappers support]) -+ SSHDLIBS="$SSHDLIBS -lwrap" -+ TCPW_MSG="yes" -+ ], [ -+ AC_MSG_ERROR([*** libwrap missing]) -+ -+ ]) -+ LIBS="$saved_LIBS" -+ fi -+ ] -+) -+ - # Check whether user wants to use ldns - LDNS_MSG="no" - AC_ARG_WITH(ldns, -@@ -5214,6 +5270,7 @@ echo " KerberosV support - echo " SELinux support: $SELINUX_MSG" - echo " Smartcard support: $SCARD_MSG" - echo " S/KEY support: $SKEY_MSG" -+echo " TCP Wrappers support: $TCPW_MSG" - echo " MD5 password support: $MD5_MSG" - echo " libedit support: $LIBEDIT_MSG" - echo " libldns support: $LDNS_MSG" -diff -up openssh-7.4p1/sshd.8.tcp_wrappers openssh-7.4p1/sshd.8 ---- openssh-7.4p1/sshd.8.tcp_wrappers 2016-12-23 15:36:38.759411194 +0100 -+++ openssh-7.4p1/sshd.8 2016-12-23 15:36:38.778411197 +0100 -@@ -836,6 +836,12 @@ the user's home directory becomes access - This file should be writable only by the user, and need not be - readable by anyone else. - .Pp -+.It Pa /etc/hosts.allow -+.It Pa /etc/hosts.deny -+Access controls that should be enforced by tcp-wrappers are defined here. -+Further details are described in -+.Xr hosts_access 5 . -+.Pp - .It Pa /etc/hosts.equiv - This file is for host-based authentication (see - .Xr ssh 1 ) . -@@ -960,6 +966,7 @@ IPv6 address can be used everywhere wher - .Xr ssh-keygen 1 , - .Xr ssh-keyscan 1 , - .Xr chroot 2 , -+.Xr hosts_access 5 , - .Xr login.conf 5 , - .Xr moduli 5 , - .Xr sshd_config 5 , -diff -up openssh-7.4p1/sshd.c.tcp_wrappers openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.tcp_wrappers 2016-12-23 15:36:38.772411196 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 15:37:15.032417028 +0100 -@@ -123,6 +123,13 @@ - #include "version.h" - #include "ssherr.h" - -+#ifdef LIBWRAP -+#include -+#include -+int allow_severity; -+int deny_severity; -+#endif /* LIBWRAP */ -+ - /* Re-exec fds */ - #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) - #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -@@ -2012,6 +2019,24 @@ main(int ac, char **av) - #ifdef SSH_AUDIT_EVENTS - audit_connection_from(remote_ip, remote_port); - #endif -+#ifdef LIBWRAP -+ allow_severity = options.log_facility|LOG_INFO; -+ deny_severity = options.log_facility|LOG_WARNING; -+ /* Check whether logins are denied from this host. */ -+ if (packet_connection_is_on_socket()) { -+ struct request_info req; -+ -+ request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); -+ fromhost(&req); -+ -+ if (!hosts_access(&req)) { -+ debug("Connection refused by tcp wrapper"); -+ refuse(&req); -+ /* NOTREACHED */ -+ fatal("libwrap refuse returns"); -+ } -+ } -+#endif /* LIBWRAP */ - - /* Log the connection. */ - laddr = get_local_ipaddr(sock_in); diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index 20faa95..1caa0a6 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -736,7 +736,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + timeout.tv_sec = options.bind_timelimit; + timeout.tv_usec = 0; + result = NULL; -+ if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) { ++ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { + error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0))); + ldap_msgfree (result); + return LDAP_OPERATIONS_ERROR; @@ -837,7 +837,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + } + + if (options.ssl_on != SSL_OFF) { -+ if ((ld = ldapssl_init (options.host, options.port, TRUE)) == NULL) ++ if ((ld = ldapssl_init (options.host, options.port, 1)) == NULL) + fatal ("ldapssl_init failed"); + debug3 ("LDAPssl init"); + } @@ -1041,7 +1041,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + + timeout.tv_sec = options.bind_timelimit; + timeout.tv_usec = 0; -+ if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) { ++ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { + ld_errno = ldap_get_lderrno (ld, 0, 0); + + error ("ldap_result %s", ldap_err2string (ld_errno)); @@ -1052,7 +1052,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + +#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) + controls = NULL; -+ if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE)) != LDAP_SUCCESS) ++ if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, 1)) != LDAP_SUCCESS) + fatal ("ldap_parse_result %s", ldap_err2string (parserc)); + debug3 ("LDAP parse result OK"); + @@ -1060,7 +1060,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + ldap_controls_free (controls); + } +#else -+ rc = ldap_result2error (session->ld, result, TRUE); ++ rc = ldap_result2error (session->ld, result, 1); +#endif + if (rc != LDAP_SUCCESS) + fatal ("error trying to bind as user \"%s\" (%s)", diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 8ca4653..b09ef65 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -39,7 +39,7 @@ diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c void audit_event(ssh_audit_event_t event) { -@@ -452,4 +471,40 @@ audit_event(ssh_audit_event_t event) +@@ -452,4 +471,34 @@ audit_event(ssh_audit_event_t event) debug("%s: unhandled event %d", __func__, event); } } @@ -72,12 +72,6 @@ diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c +audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) +{ + /* not implemented */ -+} -+ -+void -+audit_generate_ephemeral_server_key(const char *fp) -+{ -+ /* not implemented */ +} #endif /* BSM */ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c @@ -183,7 +177,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -172,13 +218,91 @@ audit_session_close(struct logininfo *li +@@ -172,13 +218,82 @@ audit_session_close(struct logininfo *li /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -265,15 +259,6 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c +{ + debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", + geteuid(), fp, (long)pid, (unsigned)uid); -+} -+ -+/* -+ * This will be called on generation of the ephemeral server key -+ */ -+void -+audit_generate_ephemeral_server_key(const char *) -+{ -+ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp); } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ @@ -288,7 +273,7 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, -@@ -43,13 +44,33 @@ enum ssh_audit_event_type { +@@ -43,13 +44,32 @@ enum ssh_audit_event_type { SSH_CONNECTION_ABANDON, /* closed without completing auth */ SSH_AUDIT_UNKNOWN }; @@ -320,13 +305,12 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h +void audit_session_key_free(int ctos); +void audit_session_key_free_body(int ctos, pid_t, uid_t); +void audit_destroy_sensitive_data(const char *, pid_t, uid_t); -+void audit_generate_ephemeral_server_key(const char *); #endif /* _SSH_AUDIT_H */ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c --- openssh-7.6p1/audit-linux.c.audit 2017-10-02 21:34:26.000000000 +0200 +++ openssh-7.6p1/audit-linux.c 2017-10-04 17:18:32.835505053 +0200 -@@ -33,25 +33,38 @@ +@@ -33,27 +33,40 @@ #include "log.h" #include "audit.h" @@ -353,7 +337,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c -linux_audit_record_event(int uid, const char *username, const char *hostname, - const char *ip, const char *ttyn, int success) +static void -+linux_audit_user_logxxx(int uid, const char *username, const char *hostname, ++linux_audit_user_logxxx(int uid, const char *username, + const char *ip, const char *ttyn, int success, int event) { int audit_fd, rc, saved_errno; @@ -370,8 +354,11 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c - rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, + rc = audit_log_acct_message(audit_fd, event, NULL, "login", username ? username : "(unknown)", - username == NULL ? uid : -1, hostname, ip, ttyn, success); +- username == NULL ? uid : -1, hostname, ip, ttyn, success); ++ username == NULL ? uid : -1, NULL, ip, ttyn, success); saved_errno = errno; + close(audit_fd); + @@ -65,9 +78,97 @@ linux_audit_record_event(int uid, const rc = 0; errno = saved_errno; @@ -385,7 +372,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + +static void +linux_audit_user_auth(int uid, const char *username, -+ const char *hostname, const char *ip, const char *ttyn, int success, int event) ++ const char *ip, const char *ttyn, int success, int event) +{ + int audit_fd, rc, saved_errno; + static const char *event_name[] = { @@ -419,7 +406,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, + NULL, event_name[event], username ? username : "(unknown)", -+ username == NULL ? uid : -1, hostname, ip, ttyn, success); ++ username == NULL ? uid : -1, NULL, ip, ttyn, success); + saved_errno = errno; + close(audit_fd); + /* @@ -471,7 +458,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c /* Below is the sshd audit API code */ void -@@ -76,24 +177,51 @@ audit_connection_from(const char *host, +@@ -76,24 +177,55 @@ audit_connection_from(const char *host, /* not implemented */ } @@ -481,21 +468,25 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c { - /* not implemented */ + if (!user_login_count++) -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_LOGIN); -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_START); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ ssh_remote_ipaddr(active_state), ++ "ssh", 1, AUDIT_USER_LOGIN); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ ssh_remote_ipaddr(active_state), ++ "ssh", 1, AUDIT_USER_START); + return 0; +} + +void +audit_end_command(int handle, const char *command) +{ -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_END); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ ssh_remote_ipaddr(active_state), ++ "ssh", 1, AUDIT_USER_END); + if (user_login_count && !--user_login_count) -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ ssh_remote_ipaddr(active_state), ++ "ssh", 1, AUDIT_USER_LOGOUT); +} + +void @@ -512,9 +503,9 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c - fatal("linux_audit_write_entry failed: %s", strerror(errno)); + if (!user_login_count++) + linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_LOGIN); ++ li->line, 1, AUDIT_USER_LOGIN); + linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_START); ++ li->line, 1, AUDIT_USER_START); } void @@ -522,28 +513,28 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c { - /* not implemented */ + linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_END); ++ li->line, 1, AUDIT_USER_END); + if (user_login_count && !--user_login_count) + linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_LOGOUT); ++ li->line, 1, AUDIT_USER_LOGOUT); } void -@@ -103,24 +231,180 @@ audit_event(ssh_audit_event_t event) +@@ -103,24 +231,158 @@ audit_event(ssh_audit_event_t event) switch(event) { case SSH_AUTH_SUCCESS: - case SSH_CONNECTION_CLOSE: -+ linux_audit_user_auth(-1, audit_username(), NULL, ++ linux_audit_user_auth(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 1, event); + break; + case SSH_NOLOGIN: - case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_LOGIN_ROOT_DENIED: -+ linux_audit_user_auth(-1, audit_username(), NULL, ++ linux_audit_user_auth(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, event); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ linux_audit_user_logxxx(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; + case SSH_LOGIN_EXCEED_MAXTRIES: @@ -553,7 +544,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c case SSH_AUTH_FAIL_PUBKEY: case SSH_AUTH_FAIL_HOSTBASED: case SSH_AUTH_FAIL_GSSAPI: -+ linux_audit_user_auth(-1, audit_username(), NULL, ++ linux_audit_user_auth(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, event); + break; + @@ -561,11 +552,11 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + if (user_login_count) { + while (user_login_count--) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_END); ++ ssh_remote_ipaddr(ssh), ++ "ssh", 1, AUDIT_USER_END); + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); ++ ssh_remote_ipaddr(ssh), ++ "ssh", 1, AUDIT_USER_LOGOUT); + } + break; + @@ -573,7 +564,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c case SSH_INVALID_USER: - linux_audit_record_event(-1, audit_username(), NULL, - ssh_remote_ipaddr(ssh), "sshd", 0); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ linux_audit_user_logxxx(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; default: @@ -690,28 +681,6 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + /* do not abort if the error is EPERM and sshd is run as non root user */ + if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) + error("cannot write into audit"); -+} -+ -+void -+audit_generate_ephemeral_server_key(const char *fp) -+{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ -+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && -+ errno != EAFNOSUPPORT) -+ error("cannot open audit"); -+ return; -+ } -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, 0, NULL, 1); -+ audit_close(audit_fd); -+ /* do not abort if the error is EPERM and sshd is run as non root user */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ diff -up openssh-7.6p1/auditstub.c.audit openssh-7.6p1/auditstub.c diff --git a/openssh-7.6p1-gsissh.patch b/openssh-7.6p1-gsissh.patch index 118cf77..84fb1be 100644 --- a/openssh-7.6p1-gsissh.patch +++ b/openssh-7.6p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c ---- openssh-7.6p1.orig/auth2.c 2017-11-22 17:20:57.185924812 +0100 -+++ openssh-7.6p1/auth2.c 2017-11-22 17:21:29.017573490 +0100 +--- openssh-7.6p1.orig/auth2.c 2018-01-18 09:33:46.564488115 +0100 ++++ openssh-7.6p1/auth2.c 2018-01-18 09:34:35.318942720 +0100 @@ -233,7 +233,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -100,8 +100,8 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-7.6p1.orig/auth2-gss.c openssh-7.6p1/auth2-gss.c ---- openssh-7.6p1.orig/auth2-gss.c 2017-11-22 17:20:57.105925695 +0100 -+++ openssh-7.6p1/auth2-gss.c 2017-11-22 17:27:53.583329418 +0100 +--- openssh-7.6p1.orig/auth2-gss.c 2018-01-18 09:33:46.462489256 +0100 ++++ openssh-7.6p1/auth2-gss.c 2018-01-18 09:34:35.319942709 +0100 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -283,8 +283,8 @@ diff -Nur openssh-7.6p1.orig/auth2-gss.c openssh-7.6p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c ---- openssh-7.6p1.orig/auth.c 2017-11-22 17:20:57.186924801 +0100 -+++ openssh-7.6p1/auth.c 2017-11-22 17:21:29.019573467 +0100 +--- openssh-7.6p1.orig/auth.c 2018-01-18 09:33:46.565488104 +0100 ++++ openssh-7.6p1/auth.c 2018-01-18 09:34:35.319942709 +0100 @@ -74,6 +74,9 @@ #include "ssherr.h" #include "compat.h" @@ -351,8 +351,8 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-7.6p1.orig/auth.h openssh-7.6p1/auth.h ---- openssh-7.6p1.orig/auth.h 2017-11-22 17:20:57.186924801 +0100 -+++ openssh-7.6p1/auth.h 2017-11-22 22:08:00.454673050 +0100 +--- openssh-7.6p1.orig/auth.h 2018-01-18 09:33:46.565488104 +0100 ++++ openssh-7.6p1/auth.h 2018-01-18 09:34:35.320942698 +0100 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -363,8 +363,8 @@ diff -Nur openssh-7.6p1.orig/auth.h openssh-7.6p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c ---- openssh-7.6p1.orig/auth-pam.c 2017-11-22 17:20:57.206924580 +0100 -+++ openssh-7.6p1/auth-pam.c 2017-11-22 17:33:46.528425133 +0100 +--- openssh-7.6p1.orig/auth-pam.c 2018-01-18 09:33:46.587487858 +0100 ++++ openssh-7.6p1/auth-pam.c 2018-01-18 09:34:35.320942698 +0100 @@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -505,8 +505,8 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-7.6p1.orig/auth-pam.h openssh-7.6p1/auth-pam.h ---- openssh-7.6p1.orig/auth-pam.h 2017-11-22 17:20:57.061926180 +0100 -+++ openssh-7.6p1/auth-pam.h 2017-11-22 17:21:29.020573456 +0100 +--- openssh-7.6p1.orig/auth-pam.h 2018-01-18 09:33:46.415489782 +0100 ++++ openssh-7.6p1/auth-pam.h 2018-01-18 09:34:35.321942687 +0100 @@ -41,5 +41,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -516,7 +516,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.h openssh-7.6p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-7.6p1.orig/canohost.c openssh-7.6p1/canohost.c --- openssh-7.6p1.orig/canohost.c 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/canohost.c 2017-11-22 17:21:29.020573456 +0100 ++++ openssh-7.6p1/canohost.c 2018-01-18 09:34:35.321942687 +0100 @@ -17,6 +17,7 @@ #include #include @@ -561,7 +561,7 @@ diff -Nur openssh-7.6p1.orig/canohost.c openssh-7.6p1/canohost.c +} diff -Nur openssh-7.6p1.orig/canohost.h openssh-7.6p1/canohost.h --- openssh-7.6p1.orig/canohost.h 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/canohost.h 2017-11-22 17:21:29.021573445 +0100 ++++ openssh-7.6p1/canohost.h 2018-01-18 09:34:35.321942687 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -570,9 +570,9 @@ diff -Nur openssh-7.6p1.orig/canohost.h openssh-7.6p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac ---- openssh-7.6p1.orig/configure.ac 2017-11-22 17:20:57.216924470 +0100 -+++ openssh-7.6p1/configure.ac 2017-11-22 17:21:29.022573434 +0100 -@@ -4455,6 +4455,14 @@ +--- openssh-7.6p1.orig/configure.ac 2018-01-18 09:33:46.601487702 +0100 ++++ openssh-7.6p1/configure.ac 2018-01-18 09:34:35.323942664 +0100 +@@ -4399,6 +4399,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -587,7 +587,7 @@ diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4494,6 +4502,50 @@ +@@ -4438,6 +4446,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,8 +639,8 @@ diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-7.6p1.orig/gss-genr.c openssh-7.6p1/gss-genr.c ---- openssh-7.6p1.orig/gss-genr.c 2017-11-22 17:20:57.208924558 +0100 -+++ openssh-7.6p1/gss-genr.c 2017-11-22 17:21:29.023573423 +0100 +--- openssh-7.6p1.orig/gss-genr.c 2018-01-18 09:33:46.589487836 +0100 ++++ openssh-7.6p1/gss-genr.c 2018-01-18 09:34:35.323942664 +0100 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -678,8 +678,8 @@ diff -Nur openssh-7.6p1.orig/gss-genr.c openssh-7.6p1/gss-genr.c return (ctx->major); } diff -Nur openssh-7.6p1.orig/gss-serv.c openssh-7.6p1/gss-serv.c ---- openssh-7.6p1.orig/gss-serv.c 2017-11-22 17:20:57.153925165 +0100 -+++ openssh-7.6p1/gss-serv.c 2017-11-22 17:26:51.374016714 +0100 +--- openssh-7.6p1.orig/gss-serv.c 2018-01-18 09:33:46.511488708 +0100 ++++ openssh-7.6p1/gss-serv.c 2018-01-18 09:34:35.324942653 +0100 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -978,7 +978,7 @@ diff -Nur openssh-7.6p1.orig/gss-serv.c openssh-7.6p1/gss-serv.c #endif diff -Nur openssh-7.6p1.orig/gss-serv-gsi.c openssh-7.6p1/gss-serv-gsi.c --- openssh-7.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/gss-serv-gsi.c 2017-11-22 22:06:29.452688621 +0100 ++++ openssh-7.6p1/gss-serv-gsi.c 2018-01-18 09:34:35.324942653 +0100 @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1312,8 +1312,8 @@ diff -Nur openssh-7.6p1.orig/gss-serv-gsi.c openssh-7.6p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-7.6p1.orig/gss-serv-krb5.c openssh-7.6p1/gss-serv-krb5.c ---- openssh-7.6p1.orig/gss-serv-krb5.c 2017-11-22 17:20:57.140925308 +0100 -+++ openssh-7.6p1/gss-serv-krb5.c 2017-11-22 17:21:29.025573401 +0100 +--- openssh-7.6p1.orig/gss-serv-krb5.c 2018-01-18 09:33:46.500488831 +0100 ++++ openssh-7.6p1/gss-serv-krb5.c 2018-01-18 09:34:35.325942642 +0100 @@ -378,6 +378,34 @@ return found_principal; } @@ -1368,8 +1368,8 @@ diff -Nur openssh-7.6p1.orig/gss-serv-krb5.c openssh-7.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-7.6p1.orig/kexgsss.c openssh-7.6p1/kexgsss.c ---- openssh-7.6p1.orig/kexgsss.c 2017-11-22 17:20:57.209924547 +0100 -+++ openssh-7.6p1/kexgsss.c 2017-11-22 17:21:29.026573390 +0100 +--- openssh-7.6p1.orig/kexgsss.c 2018-01-18 09:33:46.591487813 +0100 ++++ openssh-7.6p1/kexgsss.c 2018-01-18 09:34:35.325942642 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1431,7 +1431,7 @@ diff -Nur openssh-7.6p1.orig/kexgsss.c openssh-7.6p1/kexgsss.c #endif /* GSSAPI */ diff -Nur openssh-7.6p1.orig/LICENSE.globus_usage openssh-7.6p1/LICENSE.globus_usage --- openssh-7.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/LICENSE.globus_usage 2017-11-22 17:21:29.027573379 +0100 ++++ openssh-7.6p1/LICENSE.globus_usage 2018-01-18 09:34:35.325942642 +0100 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1452,8 +1452,8 @@ diff -Nur openssh-7.6p1.orig/LICENSE.globus_usage openssh-7.6p1/LICENSE.globus_u + * limitations under the License. + */ diff -Nur openssh-7.6p1.orig/Makefile.in openssh-7.6p1/Makefile.in ---- openssh-7.6p1.orig/Makefile.in 2017-11-22 17:20:57.210924536 +0100 -+++ openssh-7.6p1/Makefile.in 2017-11-22 17:21:29.027573379 +0100 +--- openssh-7.6p1.orig/Makefile.in 2018-01-18 09:33:46.591487813 +0100 ++++ openssh-7.6p1/Makefile.in 2018-01-18 09:34:35.326942631 +0100 @@ -116,8 +116,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1466,8 +1466,8 @@ diff -Nur openssh-7.6p1.orig/Makefile.in openssh-7.6p1/Makefile.in sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c ---- openssh-7.6p1.orig/misc.c 2017-11-22 17:20:57.178924889 +0100 -+++ openssh-7.6p1/misc.c 2017-11-22 17:21:29.028573368 +0100 +--- openssh-7.6p1.orig/misc.c 2018-01-18 09:33:46.557488194 +0100 ++++ openssh-7.6p1/misc.c 2018-01-18 09:34:35.326942631 +0100 @@ -171,11 +171,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1528,8 +1528,8 @@ diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-7.6p1.orig/misc.h openssh-7.6p1/misc.h ---- openssh-7.6p1.orig/misc.h 2017-11-22 17:20:57.178924889 +0100 -+++ openssh-7.6p1/misc.h 2017-11-22 17:21:29.029573357 +0100 +--- openssh-7.6p1.orig/misc.h 2018-01-18 09:33:46.557488194 +0100 ++++ openssh-7.6p1/misc.h 2018-01-18 09:34:35.326942631 +0100 @@ -70,6 +70,7 @@ void sock_set_v6only(int); @@ -1539,8 +1539,8 @@ diff -Nur openssh-7.6p1.orig/misc.h openssh-7.6p1/misc.h typedef struct arglist arglist; diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c ---- openssh-7.6p1.orig/monitor.c 2017-11-22 17:20:57.210924536 +0100 -+++ openssh-7.6p1/monitor.c 2017-11-22 17:43:44.857793492 +0100 +--- openssh-7.6p1.orig/monitor.c 2018-01-18 09:33:46.592487802 +0100 ++++ openssh-7.6p1/monitor.c 2018-01-18 09:34:35.327942620 +0100 @@ -164,6 +164,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1730,8 +1730,8 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c mm_answer_gss_sign(int socket, Buffer *m) { diff -Nur openssh-7.6p1.orig/monitor.h openssh-7.6p1/monitor.h ---- openssh-7.6p1.orig/monitor.h 2017-11-22 17:20:57.188924779 +0100 -+++ openssh-7.6p1/monitor.h 2017-11-22 17:21:29.031573335 +0100 +--- openssh-7.6p1.orig/monitor.h 2018-01-18 09:33:46.567488082 +0100 ++++ openssh-7.6p1/monitor.h 2018-01-18 09:34:35.327942620 +0100 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1746,8 +1746,8 @@ diff -Nur openssh-7.6p1.orig/monitor.h openssh-7.6p1/monitor.h struct monitor { diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c ---- openssh-7.6p1.orig/monitor_wrap.c 2017-11-22 17:20:57.203924613 +0100 -+++ openssh-7.6p1/monitor_wrap.c 2017-11-22 17:21:29.477568413 +0100 +--- openssh-7.6p1.orig/monitor_wrap.c 2018-01-18 09:33:46.583487903 +0100 ++++ openssh-7.6p1/monitor_wrap.c 2018-01-18 09:34:35.327942620 +0100 @@ -992,12 +992,13 @@ } @@ -1848,8 +1848,8 @@ diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-7.6p1.orig/monitor_wrap.h openssh-7.6p1/monitor_wrap.h ---- openssh-7.6p1.orig/monitor_wrap.h 2017-11-22 17:20:57.193924724 +0100 -+++ openssh-7.6p1/monitor_wrap.h 2017-11-22 17:21:29.477568413 +0100 +--- openssh-7.6p1.orig/monitor_wrap.h 2018-01-18 09:33:46.573488015 +0100 ++++ openssh-7.6p1/monitor_wrap.h 2018-01-18 09:34:35.328942608 +0100 @@ -62,9 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1866,8 +1866,8 @@ diff -Nur openssh-7.6p1.orig/monitor_wrap.h openssh-7.6p1/monitor_wrap.h #endif diff -Nur openssh-7.6p1.orig/readconf.c openssh-7.6p1/readconf.c ---- openssh-7.6p1.orig/readconf.c 2017-11-22 17:20:57.197924679 +0100 -+++ openssh-7.6p1/readconf.c 2017-11-22 17:21:29.478568402 +0100 +--- openssh-7.6p1.orig/readconf.c 2018-01-18 09:33:46.577487970 +0100 ++++ openssh-7.6p1/readconf.c 2018-01-18 09:34:35.328942608 +0100 @@ -1983,13 +1983,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1887,8 +1887,8 @@ diff -Nur openssh-7.6p1.orig/readconf.c openssh-7.6p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-7.6p1.orig/readconf.h openssh-7.6p1/readconf.h ---- openssh-7.6p1.orig/readconf.h 2017-11-22 17:20:57.158925110 +0100 -+++ openssh-7.6p1/readconf.h 2017-11-22 17:21:29.478568402 +0100 +--- openssh-7.6p1.orig/readconf.h 2018-01-18 09:33:46.517488641 +0100 ++++ openssh-7.6p1/readconf.h 2018-01-18 09:34:35.328942608 +0100 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1899,8 +1899,8 @@ diff -Nur openssh-7.6p1.orig/readconf.h openssh-7.6p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c ---- openssh-7.6p1.orig/servconf.c 2017-11-22 17:20:57.204924602 +0100 -+++ openssh-7.6p1/servconf.c 2017-11-22 17:21:29.479568391 +0100 +--- openssh-7.6p1.orig/servconf.c 2018-01-18 09:33:46.584487892 +0100 ++++ openssh-7.6p1/servconf.c 2018-01-18 09:34:35.329942597 +0100 @@ -75,6 +75,7 @@ /* Portable-specific options */ @@ -2120,8 +2120,8 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h ---- openssh-7.6p1.orig/servconf.h 2017-11-22 17:20:57.164925044 +0100 -+++ openssh-7.6p1/servconf.h 2017-11-22 17:30:04.398883887 +0100 +--- openssh-7.6p1.orig/servconf.h 2018-01-18 09:33:46.523488574 +0100 ++++ openssh-7.6p1/servconf.h 2018-01-18 09:34:35.329942597 +0100 @@ -122,9 +122,12 @@ * authenticated with Kerberos. */ int use_kuserok; @@ -2155,8 +2155,8 @@ diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h char *trusted_user_ca_keys; char *authorized_keys_command; diff -Nur openssh-7.6p1.orig/ssh.1 openssh-7.6p1/ssh.1 ---- openssh-7.6p1.orig/ssh.1 2017-11-22 17:20:57.155925143 +0100 -+++ openssh-7.6p1/ssh.1 2017-11-22 17:21:29.481568368 +0100 +--- openssh-7.6p1.orig/ssh.1 2018-01-18 09:33:46.514488675 +0100 ++++ openssh-7.6p1/ssh.1 2018-01-18 09:34:35.330942586 +0100 @@ -1404,6 +1404,18 @@ on to new connections). .It Ev USER @@ -2177,8 +2177,8 @@ diff -Nur openssh-7.6p1.orig/ssh.1 openssh-7.6p1/ssh.1 .Pp Additionally, diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c ---- openssh-7.6p1.orig/ssh.c 2017-11-22 17:20:57.212924514 +0100 -+++ openssh-7.6p1/ssh.c 2017-11-22 17:21:29.481568368 +0100 +--- openssh-7.6p1.orig/ssh.c 2018-01-18 09:33:46.594487780 +0100 ++++ openssh-7.6p1/ssh.c 2018-01-18 09:34:35.330942586 +0100 @@ -470,6 +470,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2227,8 +2227,8 @@ diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); diff -Nur openssh-7.6p1.orig/ssh_config openssh-7.6p1/ssh_config ---- openssh-7.6p1.orig/ssh_config 2017-11-22 17:20:57.112925618 +0100 -+++ openssh-7.6p1/ssh_config 2017-11-22 17:21:29.482568357 +0100 +--- openssh-7.6p1.orig/ssh_config 2018-01-18 09:33:46.470489167 +0100 ++++ openssh-7.6p1/ssh_config 2018-01-18 09:34:35.330942586 +0100 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2245,8 +2245,8 @@ diff -Nur openssh-7.6p1.orig/ssh_config openssh-7.6p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 ---- openssh-7.6p1.orig/ssh_config.5 2017-11-22 17:20:57.173924944 +0100 -+++ openssh-7.6p1/ssh_config.5 2017-11-22 17:21:29.482568357 +0100 +--- openssh-7.6p1.orig/ssh_config.5 2018-01-18 09:33:46.537488417 +0100 ++++ openssh-7.6p1/ssh_config.5 2018-01-18 09:34:35.331942575 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2303,8 +2303,8 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c ---- openssh-7.6p1.orig/sshconnect2.c 2017-11-22 17:20:57.211924525 +0100 -+++ openssh-7.6p1/sshconnect2.c 2017-11-22 17:21:29.483568346 +0100 +--- openssh-7.6p1.orig/sshconnect2.c 2018-01-18 09:33:46.593487791 +0100 ++++ openssh-7.6p1/sshconnect2.c 2018-01-18 09:34:35.331942575 +0100 @@ -285,7 +285,7 @@ #ifdef GSSAPI @@ -2400,8 +2400,8 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-7.6p1.orig/sshd.8 openssh-7.6p1/sshd.8 ---- openssh-7.6p1.orig/sshd.8 2017-11-22 17:20:57.144925264 +0100 -+++ openssh-7.6p1/sshd.8 2017-11-22 17:21:29.484568335 +0100 +--- openssh-7.6p1.orig/sshd.8 2018-01-18 09:33:46.480489055 +0100 ++++ openssh-7.6p1/sshd.8 2018-01-18 09:34:35.331942575 +0100 @@ -754,6 +754,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2448,17 +2448,17 @@ diff -Nur openssh-7.6p1.orig/sshd.8 openssh-7.6p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c ---- openssh-7.6p1.orig/sshd.c 2017-11-22 17:20:57.212924514 +0100 -+++ openssh-7.6p1/sshd.c 2017-11-22 17:21:29.485568324 +0100 +--- openssh-7.6p1.orig/sshd.c 2018-01-18 09:33:46.594487780 +0100 ++++ openssh-7.6p1/sshd.c 2018-01-18 09:34:35.332942564 +0100 @@ -129,6 +129,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" +#include "ssh-globus-usage.h" - #ifdef LIBWRAP - #include -@@ -1710,6 +1711,13 @@ + /* Re-exec fds */ + #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) +@@ -1703,6 +1704,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2472,7 +2472,7 @@ diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2208,7 +2216,7 @@ +@@ -2183,7 +2191,7 @@ #endif #ifdef GSSAPI @@ -2482,8 +2482,8 @@ diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config ---- openssh-7.6p1.orig/sshd_config 2017-11-22 17:20:57.151925187 +0100 -+++ openssh-7.6p1/sshd_config 2017-11-22 17:21:29.485568324 +0100 +--- openssh-7.6p1.orig/sshd_config 2018-01-18 09:33:46.510488719 +0100 ++++ openssh-7.6p1/sshd_config 2018-01-18 09:34:35.333942552 +0100 @@ -85,10 +85,11 @@ #KerberosUseKuserok yes @@ -2521,8 +2521,8 @@ diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config #Match User anoncvs # X11Forwarding no diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 ---- openssh-7.6p1.orig/sshd_config.5 2017-11-22 17:20:57.174924933 +0100 -+++ openssh-7.6p1/sshd_config.5 2017-11-22 17:23:18.206368547 +0100 +--- openssh-7.6p1.orig/sshd_config.5 2018-01-18 09:33:46.538488406 +0100 ++++ openssh-7.6p1/sshd_config.5 2018-01-18 09:34:35.333942552 +0100 @@ -574,6 +574,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may @@ -2711,7 +2711,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 sent by the server upon connection. diff -Nur openssh-7.6p1.orig/ssh-globus-usage.c openssh-7.6p1/ssh-globus-usage.c --- openssh-7.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/ssh-globus-usage.c 2017-11-22 17:21:29.487568302 +0100 ++++ openssh-7.6p1/ssh-globus-usage.c 2018-01-18 09:34:35.333942552 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3111,7 +3111,7 @@ diff -Nur openssh-7.6p1.orig/ssh-globus-usage.c openssh-7.6p1/ssh-globus-usage.c +} diff -Nur openssh-7.6p1.orig/ssh-globus-usage.h openssh-7.6p1/ssh-globus-usage.h --- openssh-7.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/ssh-globus-usage.h 2017-11-22 17:21:29.487568302 +0100 ++++ openssh-7.6p1/ssh-globus-usage.h 2018-01-18 09:34:35.333942552 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3162,8 +3162,8 @@ diff -Nur openssh-7.6p1.orig/ssh-globus-usage.h openssh-7.6p1/ssh-globus-usage.h + +#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-7.6p1.orig/ssh-gss.h openssh-7.6p1/ssh-gss.h ---- openssh-7.6p1.orig/ssh-gss.h 2017-11-22 17:20:57.173924944 +0100 -+++ openssh-7.6p1/ssh-gss.h 2017-11-22 17:30:42.783459732 +0100 +--- openssh-7.6p1.orig/ssh-gss.h 2018-01-18 09:33:46.537488417 +0100 ++++ openssh-7.6p1/ssh-gss.h 2018-01-18 09:34:35.334942541 +0100 @@ -93,12 +93,14 @@ } ssh_gssapi_ccache; @@ -3218,7 +3218,7 @@ diff -Nur openssh-7.6p1.orig/ssh-gss.h openssh-7.6p1/ssh-gss.h #endif /* _SSH_GSS_H */ diff -Nur openssh-7.6p1.orig/version.h openssh-7.6p1/version.h --- openssh-7.6p1.orig/version.h 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/version.h 2017-11-22 17:21:29.488568291 +0100 ++++ openssh-7.6p1/version.h 2018-01-18 09:34:35.334942541 +0100 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_7.6" From 261e529a3ee096521b7b9e3ca06ba4bdacfbb165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 20 Jan 2018 23:06:50 +0100 Subject: [PATCH 049/146] Rebuilt for switch to libxcrypt --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d487039..bbd6e18 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat Jan 20 2018 Björn Esser - 7.6p1-4.1 +- Rebuilt for switch to libxcrypt + * Thu Jan 18 2018 Mattias Ellert - 7.6p1-4 - Based on openssh-7.6p1-5.1.fc28 From 076d654b2075351e9c29e1e61baf5daf9440eac3 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 26 Jan 2018 17:11:36 +0100 Subject: [PATCH 050/146] Based on openssh-7.6p1-6.fc28 --- gsi-openssh.spec | 7 +++-- openssh-7.6p1-audit.patch | 58 +++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index bbd6e18..fd8b290 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.6p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Jan 26 2018 Mattias Ellert - 7.6p1-5 +- Based on openssh-7.6p1-6.fc28 + * Sat Jan 20 2018 Björn Esser - 7.6p1-4.1 - Rebuilt for switch to libxcrypt diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index b09ef65..e135a19 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -31,7 +31,7 @@ diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c } +int -+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++audit_keyusage(int host_user, char *fp, int rv) +{ + /* not implemented */ +} @@ -85,7 +85,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c #ifdef SSH_AUDIT_EVENTS -@@ -34,6 +35,11 @@ +@@ -34,6 +35,12 @@ #include "key.h" #include "hostfile.h" #include "auth.h" @@ -94,6 +94,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c +#include "xmalloc.h" +#include "misc.h" +#include "servconf.h" ++#include "ssherr.h" /* * Care must be taken when using this since it WILL NOT be initialized when @@ -121,7 +122,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c return (the_authctxt->user); } -@@ -109,6 +113,37 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -109,6 +113,35 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -129,12 +130,10 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c +audit_key(int host_user, int *rv, const Key *key) +{ + char *fp; -+ const char *crypto_name; + + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ crypto_name = key_ssh_name(key); -+ if (audit_keyusage(host_user, crypto_name, sshkey_size(key), fp, *rv) == 0) -+ *rv = 0; ++ if (audit_keyusage(host_user, fp, (*rv == 0)) == 0) ++ *rv = -SSH_ERR_INTERNAL_ERROR; + free(fp); +} + @@ -213,10 +212,10 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. + */ +int -+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++audit_keyusage(int host_user, char *fp, int rv) +{ -+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s, result %d", -+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, ++ debug("audit %s key usage euid %d user %s fingerprint %s, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), + fp, rv); +} + @@ -296,7 +295,7 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h +int audit_run_command(const char *); +void audit_end_command(int, const char *); ssh_audit_event_t audit_classify_auth(const char *); -+int audit_keyusage(int, const char *, unsigned, char *, int); ++int audit_keyusage(int, char *, int); +void audit_key(int, int *, const Key *); +void audit_unsupported(int); +void audit_kex(int, char *, char *, char *, char *); @@ -359,7 +358,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c saved_errno = errno; close(audit_fd); -@@ -65,9 +78,97 @@ linux_audit_record_event(int uid, const +@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const rc = 0; errno = saved_errno; @@ -423,7 +422,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +} + +int -+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++audit_keyusage(int host_user, char *fp, int rv) +{ + char buf[AUDIT_LOG_SIZE]; + int audit_fd, rc, saved_errno; @@ -436,15 +435,14 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + else + return 0; /* Must prevent login */ + } -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", ssh_remote_port(active_state)); ++ 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(active_state), NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", -+ type, bits, fp, ssh_remote_port(active_state)); -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), NULL, rv); ++ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp); ++ rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL, ++ ssh_remote_ipaddr(active_state), NULL, rv); +out: + saved_errno = errno; + audit_close(audit_fd); @@ -520,15 +518,12 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c } void -@@ -103,24 +231,158 @@ audit_event(ssh_audit_event_t event) +@@ -102,25 +231,155 @@ audit_event(ssh_audit_event_t event) + struct ssh *ssh = active_state; /* XXX */ switch(event) { - case SSH_AUTH_SUCCESS: +- case SSH_AUTH_SUCCESS: - case SSH_CONNECTION_CLOSE: -+ linux_audit_user_auth(-1, audit_username(), -+ ssh_remote_ipaddr(ssh), "ssh", 1, event); -+ break; -+ case SSH_NOLOGIN: - case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_LOGIN_ROOT_DENIED: @@ -537,9 +532,11 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + linux_audit_user_logxxx(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; -+ case SSH_LOGIN_EXCEED_MAXTRIES: - case SSH_AUTH_FAIL_NONE: +- case SSH_AUTH_FAIL_NONE: case SSH_AUTH_FAIL_PASSWD: ++ if (options.use_pam) ++ break; ++ case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_AUTH_FAIL_KBDINT: case SSH_AUTH_FAIL_PUBKEY: case SSH_AUTH_FAIL_HOSTBASED: @@ -817,6 +814,15 @@ diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c diff -up openssh-7.6p1/auth.c.audit openssh-7.6p1/auth.c --- openssh-7.6p1/auth.c.audit 2017-10-04 17:18:32.746504598 +0200 +++ openssh-7.6p1/auth.c 2017-10-04 17:18:32.835505053 +0200 +@@ -360,7 +360,7 @@ auth_log(Authctxt *authctxt, int authent + # endif + #endif + #ifdef SSH_AUDIT_EVENTS +- if (authenticated == 0 && !authctxt->postponed) ++ if (authenticated == 0 && !authctxt->postponed && !partial) + audit_event(audit_classify_auth(method)); + #endif + } @@ -599,9 +599,6 @@ getpwnamallow(const char *user) record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); From c6a932d44649425e70f2d39c4712c7f12c56936f Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 26 Jan 2018 17:22:22 +0100 Subject: [PATCH 051/146] Update GSI patch --- openssh-7.6p1-gsissh.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssh-7.6p1-gsissh.patch b/openssh-7.6p1-gsissh.patch index 84fb1be..553558f 100644 --- a/openssh-7.6p1-gsissh.patch +++ b/openssh-7.6p1-gsissh.patch @@ -306,7 +306,7 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c ssh_remote_port(ssh), extra != NULL ? ": " : "", @@ -363,6 +367,23 @@ - if (authenticated == 0 && !authctxt->postponed) + if (authenticated == 0 && !authctxt->postponed && !partial) audit_event(audit_classify_auth(method)); #endif + if (authenticated) { From 2763d0178d4ff2731f30472a97417b1ccba9af0d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 7 Feb 2018 15:33:04 +0000 Subject: [PATCH 052/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index fd8b290..6c7f11e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -542,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Feb 07 2018 Fedora Release Engineering - 7.6p1-5.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + * Fri Jan 26 2018 Mattias Ellert - 7.6p1-5 - Based on openssh-7.6p1-6.fc28 From ea308e0d4c5725caddae682eeae9564db627e39c Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Tue, 13 Feb 2018 23:28:36 +0100 Subject: [PATCH 053/146] Remove BuildRoot definition None of currently supported distributions need that. It was needed last for EL5 which is EOL now Signed-off-by: Igor Gnatenko --- gsi-openssh.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 6c7f11e..d1c8c3e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -178,7 +178,6 @@ Patch98: openssh-7.6p1-gsissh.patch License: BSD Group: Applications/Internet -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: /sbin/nologin Obsoletes: %{name}-clients-fips, %{name}-server-fips From 586f2ba02d7ee5c8f6d7723e83a78299e56b6926 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Wed, 14 Feb 2018 08:05:17 +0100 Subject: [PATCH 054/146] Remove %clean section None of currently supported distributions need that. Last one was EL5 which is EOL for a while. Signed-off-by: Igor Gnatenko --- gsi-openssh.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index d1c8c3e..842e270 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -475,9 +475,6 @@ done perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* -%clean -rm -rf $RPM_BUILD_ROOT - %pre getent group ssh_keys >/dev/null || groupadd -r ssh_keys || : From 33eb081b606b51ed7764be8c4b3aef1d428d2d24 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 10 Apr 2018 12:46:30 +0200 Subject: [PATCH 055/146] Based on openssh-7.7p1-1.fc28 --- .gitignore | 2 + gsi-openssh.spec | 42 +- gsisshd.service | 2 +- gsisshd@.service | 2 +- openssh-6.2p1-vendor.patch | 12 +- openssh-6.6.1p1-ip-port-config-parser.patch | 91 +- openssh-6.6.1p1-log-in-chroot.patch | 6 +- openssh-6.6.1p1-selinux-contexts.patch | 35 - openssh-6.6p1-ctr-cavstest.patch | 6 +- openssh-6.6p1-entropy.patch | 13 +- openssh-6.6p1-force_krb.patch | 2 +- openssh-6.6p1-keycat.patch | 19 +- openssh-6.6p1-kuserok.patch | 7 +- openssh-6.6p1-redhat.patch | 3 +- openssh-6.6p1-role-mls.patch | 23 +- openssh-6.7p1-coverity.patch | 10 +- openssh-6.7p1-kdf-cavs.patch | 6 +- openssh-6.7p1-ldap.patch | 10 +- openssh-6.8p1-memory-problems.patch | 24 - openssh-7.0p1-gssKexAlgorithms.patch | 4 +- openssh-7.1p2-audit-race-condition.patch | 6 +- openssh-7.2p1-fips.patch | 6 +- openssh-7.2p1-gsskex.patch | 9 +- openssh-7.3p1-openssl-1.1.0.patch | 177 +- openssh-7.6p1-audit.patch | 70 +- openssh-7.6p1-cleanup-selinux.patch | 30 +- openssh-7.6p1-permitopen-bug.patch | 47 - openssh-7.6p1-pkcs11-ecdsa.patch | 794 +++ openssh-7.6p1-pkcs11-uri.patch | 4797 +++++++++++++++++ ...gsissh.patch => openssh-7.7p1-gsissh.patch | 414 +- sources | 4 +- 31 files changed, 6110 insertions(+), 563 deletions(-) delete mode 100644 openssh-6.8p1-memory-problems.patch delete mode 100644 openssh-7.6p1-permitopen-bug.patch create mode 100644 openssh-7.6p1-pkcs11-ecdsa.patch create mode 100644 openssh-7.6p1-pkcs11-uri.patch rename openssh-7.6p1-gsissh.patch => openssh-7.7p1-gsissh.patch (90%) diff --git a/.gitignore b/.gitignore index 154e823..149e338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /*.tar.bz2 /*.tar.gz +/*.tar.gz.asc +/DJM-GPG-KEY.gpg diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 842e270..a58072a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,18 +30,20 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.6p1 -%global openssh_rel 5 +%global openssh_ver 7.7p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html -Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +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: DJM-GPG-KEY.gpg Source7: gsisshd.sysconfig Source9: gsisshd@.service Source10: gsisshd.socket @@ -150,9 +152,6 @@ Patch920: openssh-6.6.1p1-ip-port-config-parser.patch 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 -# Memory problems -# https://bugzilla.mindrot.org/show_bug.cgi?id=2401 -Patch928: openssh-6.8p1-memory-problems.patch # Restore compatible default (#89216) Patch929: openssh-6.9p1-permit-root-login.patch # Add GSSAPIKexAlgorithms option for server and client application @@ -169,12 +168,14 @@ Patch948: openssh-7.4p1-systemd.patch Patch949: openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit Patch950: openssh-7.5p1-sandbox.patch -# PermitOpen bug in OpenSSH 7.6: -Patch951: openssh-7.6p1-permitopen-bug.patch +# PKCS#11 URIs (upstream #2817, 2nd iteration) +Patch951: openssh-7.6p1-pkcs11-uri.patch +# PKCS#11 ECDSA keys (upstream #2474, 8th iteration) +Patch952: openssh-7.6p1-pkcs11-ecdsa.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-7.6p1-gsissh.patch +Patch98: openssh-7.7p1-gsissh.patch License: BSD Group: Applications/Internet @@ -191,6 +192,9 @@ BuildRequires: pam-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel +BuildRequires: gcc +BuildRequires: p11-kit-devel +Recommends: p11-kit %if %{kerberos5} BuildRequires: krb5-devel @@ -215,6 +219,8 @@ BuildRequires: audit-libs >= 1.0.8 %endif BuildRequires: xauth +# for tarball signature verification +BuildRequires: gnupg2 %package clients Summary: SSH client applications with GSI authentication @@ -223,7 +229,7 @@ Obsoletes: gsissh-clients < 5.8p2-2 Group: Applications/Internet Requires: %{name} = %{version}-%{release} Requires: fipscheck-lib%{_isa} >= 1.3.0 -Recommends: crypto-policies +Requires: crypto-policies >= 20180306-1 %package server Summary: SSH server daemon with GSI authentication @@ -234,9 +240,8 @@ Requires: %{name} = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 Requires: fipscheck-lib%{_isa} >= 1.3.0 -Requires(post): systemd-units -Requires(preun): systemd-units -Requires(postun): systemd-units +Requires: crypto-policies >= 20180306-1 +%{?systemd_requires} %description SSH (Secure SHell) is a program for logging into and executing @@ -270,6 +275,7 @@ securely connect to your SSH server. This version of OpenSSH has been modified to support GSI authentication. %prep +gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %setup -q -n openssh-%{version} # investigate %patch102 -p1 -b .getaddrinfo @@ -317,7 +323,6 @@ This version of OpenSSH has been modified to support GSI authentication. %patch802 -p1 -b .GSSAPIEnablek5users %patch922 -p1 -b .sshdt %patch926 -p1 -b .sftp-force-mode -%patch928 -p1 -b .memory %patch929 -p1 -b .root-login %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint @@ -327,7 +332,8 @@ This version of OpenSSH has been modified to support GSI authentication. %patch807 -p1 -b .gsskex-ec %patch949 -p1 -b .refactor %patch950 -p1 -b .sandbox -%patch951 -p1 -b .permitOpen +%patch951 -p1 -b .pkcs11-uri +%patch952 -p1 -b .pkcs11-ecdsa %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -390,6 +396,7 @@ fi --with-ipaddr-display \ --with-pie=no \ --with-systemd \ + --with-default-pkcs11-provider=yes \ %if %{ldap} --with-ldap \ %endif @@ -538,6 +545,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Apr 10 2018 Mattias Ellert - 7.7p1-1 +- Based on openssh-7.7p1-1.fc28 + * Wed Feb 07 2018 Fedora Release Engineering - 7.6p1-5.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild diff --git a/gsisshd.service b/gsisshd.service index f1eac35..bfa96b5 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -6,7 +6,7 @@ Wants=gsisshd-keygen.target [Service] Type=notify -EnvironmentFile=-/etc/crypto-policies/back-ends/openssh-server.config +EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/gsisshd ExecStart=/usr/sbin/gsisshd -D $OPTIONS $CRYPTO_POLICY ExecReload=/bin/kill -HUP $MAINPID diff --git a/gsisshd@.service b/gsisshd@.service index 23ebbf8..3bbdd78 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -5,7 +5,7 @@ Wants=gsisshd-keygen.target After=gsisshd-keygen.target [Service] -EnvironmentFile=-/etc/crypto-policies/back-ends/openssh-server.config +EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/gsisshd ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $CRYPTO_POLICY StandardInput=socket diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index 02f4540..68abb56 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -69,7 +69,7 @@ diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c + case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { - if (options->num_allow_users >= MAX_ALLOW_USERS) + if (match_user(NULL, NULL, NULL, arg) == -1) @@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); dump_cfg_fmtint(sCompression, o->compression); @@ -93,8 +93,8 @@ diff -up openssh-7.4p1/sshd_config.0.vendor openssh-7.4p1/sshd_config.0 --- openssh-7.4p1/sshd_config.0.vendor 2016-12-23 13:34:51.695253847 +0100 +++ openssh-7.4p1/sshd_config.0 2016-12-23 13:36:53.146277511 +0100 @@ -792,6 +792,11 @@ DESCRIPTION - ssh-keygen(1). For more information on KRLs, see the KEY - REVOCATION LISTS section in ssh-keygen(1). + rdomain(4). If the routing domain is set to %D, then the domain + in which the incoming connection was received will be applied. + ShowPatchLevel + Specifies whether sshd will display the specific patch level of @@ -108,9 +108,9 @@ diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100 @@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as - .Xr ssh-keygen 1 . - For more information on KRLs, see the KEY REVOCATION LISTS section in - .Xr ssh-keygen 1 . + If the routing domain is set to + .Cm \&%D , + then the domain in which the incoming connection was received will be applied. +.It Cm ShowPatchLevel +Specifies whether +.Nm sshd diff --git a/openssh-6.6.1p1-ip-port-config-parser.patch b/openssh-6.6.1p1-ip-port-config-parser.patch index d2746bf..88e1ca2 100644 --- a/openssh-6.6.1p1-ip-port-config-parser.patch +++ b/openssh-6.6.1p1-ip-port-config-parser.patch @@ -1,24 +1,75 @@ diff --git a/misc.c b/misc.c -index 2f11de4..36402d1 100644 +index 874dcc8a..7b7f7a58 100644 --- a/misc.c +++ b/misc.c -@@ -396,7 +396,7 @@ hpdelim(char **cp) - return NULL; - else - s++; -- } else if ((s = strpbrk(s, ":/")) == NULL) -+ } else if ((s = strpbrk(s, ":")) == NULL) - s = *cp + strlen(*cp); /* skip to end (see first case below) */ +@@ -466,7 +466,7 @@ put_host_port(const char *host, u_short port) + * The delimiter char, if present, is stored in delim. + * If this is the last field, *cp is set to NULL. + */ +-static char * ++char * + hpdelim2(char **cp, char *delim) + { + char *s, *old; +diff --git a/misc.h b/misc.h +index cdafea73..cf9c8f28 100644 +--- a/misc.h ++++ b/misc.h +@@ -54,6 +54,7 @@ int set_rdomain(int, const char *); + int a2port(const char *); + int a2tun(const char *, int *); + char *put_host_port(const char *, u_short); ++char *hpdelim2(char **, char *); + char *hpdelim(char **); + char *cleanhostname(char *); + char *colon(char *); +diff --git a/servconf.c b/servconf.c +index 0f0d0906..1679181e 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -821,7 +821,7 @@ process_permitopen(struct ssh *ssh, ServerOptions *options) + { + u_int i; + int port; +- char *host, *arg, *oarg; ++ char *host, *arg, *oarg, ch; - switch (*s) { -@@ -405,7 +405,6 @@ hpdelim(char **cp) - break; - - case ':': -- case '/': - *s = '\0'; /* terminate */ - *cp = s + 1; - break; --- -2.1.0 - + channel_clear_adm_permitted_opens(ssh); + if (options->num_permitted_opens == 0) +@@ -839,8 +839,8 @@ process_permitopen(struct ssh *ssh, ServerOptions *options) + /* Otherwise treat it as a list of permitted host:port */ + for (i = 0; i < options->num_permitted_opens; i++) { + oarg = arg = xstrdup(options->permitted_opens[i]); +- host = hpdelim(&arg); +- if (host == NULL) ++ host = hpdelim2(&arg, &ch); ++ if (host == NULL || ch == '/') + fatal("%s: missing host in PermitOpen", __func__); + host = cleanhostname(host); + if (arg == NULL || ((port = permitopen_port(arg)) < 0)) +@@ -1244,8 +1244,10 @@ process_server_config_line(ServerOptions *options, char *line, + port = 0; + p = arg; + } else { +- p = hpdelim(&arg); +- if (p == NULL) ++ char ch; ++ arg2 = NULL; ++ p = hpdelim2(&arg, &ch); ++ if (p == NULL || ch == '/') + fatal("%s line %d: bad address:port usage", + filename, linenum); + p = cleanhostname(p); +@@ -1815,9 +1817,10 @@ process_server_config_line(ServerOptions *options, char *line, + break; + } + for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { ++ char ch; + arg2 = xstrdup(arg); +- p = hpdelim(&arg); +- if (p == NULL) ++ p = hpdelim2(&arg, &ch); ++ if (p == NULL || ch == '/') + fatal("%s line %d: missing host in PermitOpen", + filename, linenum); + p = cleanhostname(p); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 44c345b..99e2e03 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -41,14 +41,14 @@ 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); + close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + pmonitor->m_state = "preauth"; + authctxt = _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; @@ -165,7 +165,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c - closefrom(STDERR_FILENO + 1); - - do_rc_files(s, shell); + do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ @@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 5a9233b..ea4cbd1 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -116,38 +116,3 @@ index 2871fe9..39b9c08 100644 #endif /* Demote the child */ -diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 12c014e..c5ef2ff 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -35,7 +35,6 @@ - - #ifdef WITH_SELINUX - #include --#include - #include - - #ifndef SSH_SELINUX_UNCONFINED_TYPE -@@ -110,6 +109,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) - security_context_t new_tty_ctx = NULL; - security_context_t user_ctx = NULL; - security_context_t old_tty_ctx = NULL; -+ security_class_t class; - - if (!ssh_selinux_enabled()) - return; -@@ -129,8 +129,13 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) - goto out; - } - -+ class = string_to_security_class("chr_file"); -+ if (!class) { -+ error("string_to_security_class failed to translate security class context"); -+ goto out; -+ } - if (security_compute_relabel(user_ctx, old_tty_ctx, -- SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { -+ class, &new_tty_ctx) != 0) { - error("%s: security_compute_relabel: %s", - __func__, strerror(errno)); - goto out; diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 8aa6872..08c6a35 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -10,14 +10,14 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -66,7 +67,7 @@ EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ + MKDIR_P=@MKDIR_P@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) - LIBOPENSSH_OBJS=\ - ssh_api.o \ + 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 $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index f1fc6c9..7f6f4d0 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -14,12 +14,13 @@ diff -up openssh-7.4p1/entropy.c.entropy openssh-7.4p1/entropy.c diff -up openssh-7.4p1/openbsd-compat/Makefile.in.entropy openssh-7.4p1/openbsd-compat/Makefile.in --- openssh-7.4p1/openbsd-compat/Makefile.in.entropy 2016-12-23 18:34:53.715762155 +0100 +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 18:35:15.890769493 +0100 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o - --PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o +@@ -20,7 +20,8 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf + port-solaris.o \ + port-net.o \ + port-uw.o \ +- port-linux-sshd.o ++ port-linux-sshd.o \ ++ port-linux-prng.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch index 19f075e..ae948f7 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -207,7 +207,7 @@ index 28659ec..9c94d8e 100644 --- a/session.c +++ b/session.c @@ -789,6 +789,29 @@ do_exec(Session *s, const char *command) - command = forced_command; + command = auth_opts->force_command; forced = "(key-option)"; } +#ifdef GSSAPI diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 9304c1f..108f461 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,7 +1,7 @@ -diff -up openssh/misc.c.keycat openssh/misc.c ---- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 -+++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 -@@ -490,6 +490,14 @@ subprocess(const char *tag, struct passw +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); } @@ -52,14 +52,14 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in AR=@AR@ AWK=@AWK@ @@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ + MKDIR_P=@MKDIR_P@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) - LIBOPENSSH_OBJS=\ - ssh_api.o \ + XMSS_OBJS=\ + ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) @@ -203,7 +203,7 @@ diff -up openssh/platform.c.keycat openssh/platform.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,238 @@ +@@ -0,0 +1,241 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions @@ -253,6 +253,9 @@ diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c +#include +#include +#include ++#ifdef HAVE_STDINT_H ++#include ++#endif + +#include + diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 47768aa..2c65890 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -192,15 +192,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -399,7 +402,7 @@ typedef enum { +@@ -399,7 +402,8 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, +- sKerberosGetAFSToken, sChallengeResponseAuthentication, + sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, ++ sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -478,11 +481,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, diff --git a/openssh-6.6p1-redhat.patch b/openssh-6.6p1-redhat.patch index 426ba66..0879b51 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -64,7 +64,7 @@ diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config --- openssh-7.4p1/sshd_config.redhat 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/sshd_config 2016-12-23 13:33:05.386233133 +0100 -@@ -10,21 +10,35 @@ +@@ -10,20 +10,34 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -79,7 +79,6 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config -#HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_rsa_key - #HostKey /etc/ssh/ssh_host_dsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_ecdsa_key diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index ad2411f..37ae70d 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -93,7 +93,7 @@ diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased. +#else + (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif - (r = sshbuf_put_cstring(b, service)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || (r = sshbuf_put_cstring(b, "hostbased")) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c @@ -116,7 +116,7 @@ diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c +#endif if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || - (r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ? + (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h --- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth.h 2016-12-23 12:19:43.478510375 +0100 @@ -146,7 +146,7 @@ diff -up openssh-7.4p1/auth-pam.h.role-mls openssh-7.4p1/auth-pam.h --- openssh-7.4p1/auth-pam.h.role-mls 2016-12-23 12:19:43.478510375 +0100 +++ openssh-7.4p1/auth-pam.h 2016-12-23 12:21:44.698101234 +0100 @@ -31,7 +31,7 @@ u_int do_pam_account(void); - void do_pam_session(void); + void do_pam_session(struct ssh *); void do_pam_setcred(int ); void do_pam_chauthtok(void); -int do_pam_putenv(char *, char *); @@ -316,7 +316,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.role-mls openssh-7.4p1/monitor_wrap.c + /* Do the password authentication */ int - mm_auth_password(Authctxt *authctxt, char *password) + mm_auth_password(struct ssh *ssh, char *password) diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h --- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 @@ -329,16 +329,17 @@ diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h +#endif struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); - int mm_auth_password(struct Authctxt *, char *); + int mm_auth_password(struct ssh *, char *); diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd-compat/Makefile.in --- openssh-7.4p1/openbsd-compat/Makefile.in.role-mls 2016-12-23 12:19:58.588459376 +0100 +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 12:24:06.042643938 +0100 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o - --PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +@@ -20,7 +20,8 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf + port-linux.o \ + port-solaris.o \ + port-net.o \ +- port-uw.o ++ port-uw.o \ ++ port-linux-sshd.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 5b12ddd..253e0ee 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -27,7 +27,7 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c + while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) ; - close(pmonitor->m_sendfd); + 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 @@ -127,11 +127,11 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c } tun = packet_get_int(); -- if (forced_tun_device != -1) { -+ if (forced_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && forced_tun_device != tun) +- if (auth_opts->force_tun_device != -1) { ++ if (auth_opts->force_tun_device >= 0) { + if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) goto done; - tun = forced_tun_device; + tun = auth_opts->force_tun_device; 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 diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index 65feb96..4e5c7a5 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -10,14 +10,14 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -67,7 +68,7 @@ EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ + MKDIR_P=@MKDIR_P@ INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT) - LIBOPENSSH_OBJS=\ - ssh_api.o \ + 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 -lfipscheck $(LIBS) diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index 1caa0a6..ddb3974 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -145,16 +145,16 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in GSSLIBS=@GSSLIBS@ SSHLIBS=@SSHLIBS@ @@ -61,8 +63,9 @@ XAUTH_PATH=@XAUTH_PATH@ - LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ + MKDIR_P=@MKDIR_P@ +INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ -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) +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-ldap-helper$(EXEEXT) - LIBOPENSSH_OBJS=\ - ssh_api.o \ + XMSS_OBJS=\ + ssh-xmss.o \ @@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o @@ -197,7 +197,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in + fi install-sysconf: - if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ + $(MKDIR_P) $(DESTDIR)$(sysconfdir) @@ -356,6 +370,13 @@ install-sysconf: else \ echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ @@ -228,7 +228,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 regress-prep: - [ -d `pwd`/regress ] || mkdir -p `pwd`/regress + $(MKDIR_P) `pwd`/regress/unittests/test_helper diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac --- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 diff --git a/openssh-6.8p1-memory-problems.patch b/openssh-6.8p1-memory-problems.patch deleted file mode 100644 index b2da05e..0000000 --- a/openssh-6.8p1-memory-problems.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up openssh-7.4p1/servconf.c.memory openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.memory 2016-12-23 15:37:48.181422360 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:38:30.189429116 +0100 -@@ -2006,6 +2006,8 @@ copy_set_server_options(ServerOptions *d - dst->n = src->n; \ - } while (0) - -+ u_int i; -+ - M_CP_INTOPT(password_authentication); - M_CP_INTOPT(gss_authentication); - M_CP_INTOPT(pubkey_authentication); -@@ -2058,8 +2060,10 @@ copy_set_server_options(ServerOptions *d - } while(0) - #define M_CP_STRARRAYOPT(n, num_n) do {\ - if (src->num_n != 0) { \ -+ for (i = 0; i < dst->num_n; i++) \ -+ free(dst->n[i]); \ - for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ -- dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ -+ dst->n[dst->num_n] = src->n[dst->num_n]; \ - } \ - } while(0) - #define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 6200eaa..57b5eaf 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -238,8 +238,8 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c #include "digest.h" +#include "ssh-gss.h" - static void add_listen_addr(ServerOptions *, char *, int); - static void add_one_listen_addr(ServerOptions *, char *, int); + static void add_listen_addr(ServerOptions *, const char *, + const char *, int); @@ -121,6 +122,7 @@ initialize_server_options(ServerOptions options->gss_cleanup_creds = -1; options->gss_strict_acceptor = -1; diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index ec274eb..d390f63 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -86,7 +86,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c /* * This is called to fork and execute a command when we have no tty. This @@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c - cray_init_job(s->pw); /* set up cray jid and tmpdir */ + close(err[0]); #endif + child_destory_sensitive_data(); @@ -102,8 +102,8 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + child_destory_sensitive_data(); + /* record login, etc. similar to login(1) */ - #ifdef _UNICOS - cray_init_job(s->pw); /* set up cray jid and tmpdir */ + #ifndef HAVE_OSF_SIA + do_login(ssh, s, command); @@ -717,6 +728,8 @@ do_exec(Session *s, const char *command) } if (s->command != NULL && s->ptyfd == -1) diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index f0a178a..8598463 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -652,13 +652,13 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c #include "crypto_api.h" @@ -58,6 +59,7 @@ - #define SSHKEY_INTERNAL #include "sshkey.h" + #include "sshkey-xmss.h" #include "match.h" +#include "log.h" - /* openssh private key file format */ - #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" + #include "xmss_fast.h" + @@ -1587,6 +1589,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 8c0523b..02436bd 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1729,7 +1729,7 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); +#endif - if (!no_pty_flag) { + if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); @@ -1656,6 +1673,13 @@ monitor_apply_keystate(struct monitor *p # endif @@ -2086,6 +2086,7 @@ diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh -PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` +PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` + EXTRA_TYPES="" if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" @@ -2624,7 +2625,7 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c @@ -871,8 +871,9 @@ notify_hostkeys(struct ssh *ssh) } - debug3("%s: sent %d hostkeys", __func__, nkeys); + debug3("%s: sent %u hostkeys", __func__, nkeys); if (nkeys == 0) - fatal("%s: no hostkeys", __func__); - packet_send(); @@ -2864,9 +2865,9 @@ diff -up openssh/sshkey.h.gsskex openssh/sshkey.h --- openssh/sshkey.h.gsskex 2017-09-25 01:48:10.000000000 +0200 +++ openssh/sshkey.h 2017-09-27 13:54:53.602534414 +0200 @@ -61,6 +61,7 @@ enum sshkey_types { - KEY_DSA_CERT, - KEY_ECDSA_CERT, KEY_ED25519_CERT, + KEY_XMSS, + KEY_XMSS_CERT, + KEY_NULL, KEY_UNSPEC }; diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index 8efda19..c3d16ac 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -471,7 +471,7 @@ diff -up openssh/kexgexc.c.openssl openssh/kexgexc.c debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); -@@ -119,26 +120,30 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -119,24 +120,30 @@ input_kex_dh_gex_group(int type, u_int32 p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ @@ -497,12 +497,8 @@ diff -up openssh/kexgexc.c.openssl openssh/kexgexc.c ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); r = 0; out: -- if (p) -- BN_clear_free(p); -- if (g) -- BN_clear_free(g); -+ BN_clear_free(p); -+ BN_clear_free(g); + BN_clear_free(p); + BN_clear_free(g); + if (r != 0) { + DH_free(kex->dh); + kex->dh = NULL; @@ -1408,17 +1404,6 @@ diff -up openssh/sshconnect2.c.openssl openssh/sshconnect2.c } /* -diff -up openssh/sshconnect.c.openssl openssh/sshconnect.c ---- openssh/sshconnect.c.openssl 2017-09-26 13:19:31.759249464 +0200 -+++ openssh/sshconnect.c 2017-09-26 13:19:31.800249715 +0200 -@@ -1316,6 +1316,7 @@ ssh_login(Sensitive *sensitive, const ch - char *server_user, *local_user; - - local_user = xstrdup(pw->pw_name); -+ free(pw); - server_user = options.user ? options.user : local_user; - - /* Convert the user-supplied hostname into all lowercase. */ diff -up openssh/ssh.c.openssl openssh/ssh.c --- openssh/ssh.c.openssl 2017-09-26 13:19:31.786249629 +0200 +++ openssh/ssh.c 2017-09-26 13:19:31.800249715 +0200 @@ -1432,14 +1417,6 @@ diff -up openssh/ssh.c.openssl openssh/ssh.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)){ if (FIPS_mode()) -@@ -1263,6 +1265,7 @@ main(int ac, char **av) - free(cp); - } - free(conn_hash_hex); -+ free(host_arg); - - if (config_test) { - dump_client_config(&options, host); diff -up openssh/sshd.c.openssl openssh/sshd.c --- openssh/sshd.c.openssl 2017-09-26 13:19:31.792249666 +0200 +++ openssh/sshd.c 2017-09-26 13:19:31.801249721 +0200 @@ -1482,8 +1459,8 @@ diff -up openssh/ssh-dss.c.openssl openssh/ssh-dss.c + BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); + BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen); - if (compat & SSH_BUG_SIGBLOB) { - if (sigp != NULL) { + if ((b = sshbuf_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; @@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key, int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; @@ -1516,15 +1493,13 @@ diff -up openssh/ssh-dss.c.openssl openssh/ssh-dss.c /* sha1 the data */ if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, -@@ -207,8 +213,9 @@ ssh_dss_verify(const struct sshkey *key, +@@ -207,7 +213,9 @@ ssh_dss_verify(const struct sshkey *key, out: explicit_bzero(digest, sizeof(digest)); -- if (sig != NULL) -- DSA_SIG_free(sig); + BN_free(r); + BN_free(s); -+ DSA_SIG_free(sig); + DSA_SIG_free(sig); sshbuf_free(b); free(ktype); if (sigblob != NULL) { @@ -1586,15 +1561,13 @@ diff -up openssh/ssh-ecdsa.c.openssl openssh/ssh-ecdsa.c if (sshbuf_len(sigbuf) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; -@@ -180,8 +191,9 @@ ssh_ecdsa_verify(const struct sshkey *ke +@@ -180,7 +191,9 @@ ssh_ecdsa_verify(const struct sshkey *ke explicit_bzero(digest, sizeof(digest)); sshbuf_free(sigbuf); sshbuf_free(b); -- if (sig != NULL) -- ECDSA_SIG_free(sig); + BN_free(r); + BN_free(s); -+ ECDSA_SIG_free(sig); + ECDSA_SIG_free(sig); free(ktype); return ret; } @@ -1636,20 +1609,19 @@ diff -up openssh/sshkey.c.openssl openssh/sshkey.c #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -496,11 +501,7 @@ sshkey_new(int type) +@@ -496,10 +501,7 @@ sshkey_new(int type) #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - if ((rsa = RSA_new()) == NULL || - (rsa->n = BN_new()) == NULL || - (rsa->e = BN_new()) == NULL) { -- if (rsa != NULL) -- RSA_free(rsa); +- RSA_free(rsa); + if ((rsa = RSA_new()) == NULL) { free(k); return NULL; } -@@ -508,13 +509,7 @@ sshkey_new(int type) +@@ -508,12 +509,7 @@ sshkey_new(int type) break; case KEY_DSA: case KEY_DSA_CERT: @@ -1658,8 +1630,7 @@ diff -up openssh/sshkey.c.openssl openssh/sshkey.c - (dsa->q = BN_new()) == NULL || - (dsa->g = BN_new()) == NULL || - (dsa->pub_key = BN_new()) == NULL) { -- if (dsa != NULL) -- DSA_free(dsa); +- DSA_free(dsa); + if ((dsa = DSA_new()) == NULL) { free(k); return NULL; @@ -2480,14 +2451,14 @@ diff -up openssh/sshkey.h.openssl openssh/sshkey.h -int ssh_rsa_generate_additional_parameters(struct sshkey *); +int ssh_rsa_generate_additional_parameters(struct sshkey *, BIGNUM *iqmp); - #ifdef SSHKEY_INTERNAL - int ssh_rsa_sign(const struct sshkey *key, + /* stateful keys (e.g. XMSS) */ + #ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS diff -up openssh/ssh-pkcs11-client.c.openssl openssh/ssh-pkcs11-client.c --- openssh/ssh-pkcs11-client.c.openssl 2017-09-19 06:26:43.000000000 +0200 +++ openssh/ssh-pkcs11-client.c 2017-09-26 13:19:31.803249734 +0200 @@ -143,12 +143,16 @@ pkcs11_rsa_private_encrypt(int flen, con static int - wrap_key(RSA *rsa) + wrap_rsa_key(RSA *rsa) { - static RSA_METHOD helper_rsa; + static RSA_METHOD *helper_rsa; @@ -2511,25 +2482,25 @@ diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c --- openssh/ssh-pkcs11.c.openssl 2017-09-19 06:26:43.000000000 +0200 +++ openssh/ssh-pkcs11.c 2017-09-26 13:19:31.803249734 +0200 @@ -67,7 +67,7 @@ struct pkcs11_key { - struct pkcs11_provider *provider; CK_ULONG slotidx; + CK_ULONG key_type; int (*orig_finish)(RSA *rsa); - RSA_METHOD rsa_method; + RSA_METHOD *rsa_method; char *keyid; int keyid_len; - }; + char *label; @@ -183,6 +183,7 @@ pkcs11_rsa_finish(RSA *rsa) - if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); + free(k11->label); + RSA_meth_free(k11->rsa_method); free(k11); } return (rv); @@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); + k11->label[label_attrib->ulValueLen] = 0; } - k11->orig_finish = def->finish; - memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); @@ -2562,69 +2533,81 @@ diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c CK_FUNCTION_LIST *f; + const BIGNUM *n, *e; - f = p->function_list; - session = p->slotinfo[slotidx].session; + f = p->module->function_list; + session = p->module->slotinfo[slotidx].session; @@ -512,10 +521,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_p if ((rsa = RSA_new()) == NULL) { error("RSA_new failed"); } else { -- rsa->n = BN_bin2bn(attribs[1].pValue, +- rsa->n = BN_bin2bn(attribs[2].pValue, + BIGNUM *rsa_n, *rsa_e; + -+ rsa_n = BN_bin2bn(attribs[1].pValue, - attribs[1].ulValueLen, NULL); -- rsa->e = BN_bin2bn(attribs[2].pValue, -+ rsa_e = BN_bin2bn(attribs[2].pValue, ++ rsa_n = BN_bin2bn(attribs[2].pValue, attribs[2].ulValueLen, NULL); +- rsa->e = BN_bin2bn(attribs[3].pValue, ++ rsa_e = BN_bin2bn(attribs[3].pValue, + attribs[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) + error("BN_bin2bn failed"); + if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0) + error("RSA_set0_key failed"); } - } else { - cp = attribs[2].pValue; -@@ -525,17 +538,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - == NULL) { - error("d2i_X509 failed"); - } else if ((evp = X509_get_pubkey(x509)) == NULL || -- evp->type != EVP_PKEY_RSA || -- evp->pkey.rsa == NULL) { -+ EVP_PKEY_id(evp) != EVP_PKEY_RSA || -+ EVP_PKEY_get0_RSA(evp) == NULL) { - debug("X509_get_pubkey failed or no rsa"); -- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) -+ } else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) - == NULL) { - error("RSAPublicKey_dup"); - } - if (x509) - X509_free(x509); + #ifdef ENABLE_PKCS11_ECDSA + } else if (attribs[2].type == CKA_EC_PARAMS ) { +@@ -920,19 +936,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } else if ((evp = X509_get_pubkey(x509)) == NULL) { + debug("X509_get_pubkey failed"); + } else { +- switch (evp->type) { ++ switch (EVP_PKEY_id(evp)) { + case EVP_PKEY_RSA: +- if (evp->pkey.rsa == NULL) ++ if (EVP_PKEY_get0_RSA(evp) == NULL) + debug("Missing RSA key"); +- else if ((rsa = RSAPublicKey_dup( +- evp->pkey.rsa)) == NULL) ++ else if ((rsa = RSAPublicKey_dup( ++ EVP_PKEY_get0_RSA(evp))) == NULL) + error("RSAPublicKey_dup failed"); + break; + case EVP_PKEY_EC: +- if (evp->pkey.ecdsa == NULL) ++ if (EVP_PKEY_get0_EC_KEY(evp) == NULL) + debug("Missing ECDSA key"); +- else if ((ecdsa = EC_KEY_dup( +- evp->pkey.ecdsa)) == NULL) ++ else if ((ecdsa = EC_KEY_dup( ++ EVP_PKEY_get0_EC_KEY(evp))) == NULL) + error("EC_KEY_dup failed"); + break; + default: +@@ -538,7 +551,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p } -- if (rsa && rsa->n && rsa->e && -+ if (rsa) -+ RSA_get0_key(rsa, &n, &e, NULL); -+ if (rsa && n && e && - pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); + key = NULL; + if (rsa || ecdsa) { +- if (rsa && rsa->n && rsa->e && ++ if (rsa) ++ RSA_get0_key(rsa, &n, &e, NULL); ++ if (rsa && n && e && + pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c --- openssh/ssh-rsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 +++ openssh/ssh-rsa.c 2017-09-26 13:19:31.803249734 +0200 -@@ -78,37 +78,46 @@ rsa_hash_alg_nid(int type) - } +@@ -78,38 +78,50 @@ rsa_hash_alg_nid(int type) } --/* calculate p-1 and q-1 */ -+/* calculate d mod p-1 and d mod q-1 */ int -ssh_rsa_generate_additional_parameters(struct sshkey *key) +ssh_rsa_generate_additional_parameters(struct sshkey *key, BIGNUM *iqmp) { -- RSA *rsa; BIGNUM *aux = NULL; BN_CTX *ctx = NULL; +- BIGNUM d; ++ BIGNUM *d = NULL; int r; -+ const BIGNUM *p, *q, *d; ++ const BIGNUM *p, *q, *rsa_d; + BIGNUM *dmp1 = NULL, *dmq1 = NULL; if (key == NULL || key->rsa == NULL || @@ -2635,21 +2618,26 @@ diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c - return SSH_ERR_ALLOC_FAIL; - if ((aux = BN_new()) == NULL) { + RSA_get0_factors(key->rsa, &p, &q); -+ RSA_get0_key(key->rsa, NULL, NULL, &d); ++ RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); + + if ((ctx = BN_CTX_new()) == NULL || + (aux = BN_new()) == NULL || ++ (d = BN_new()) == NULL || + (dmp1 = BN_new()) == NULL || + (dmq1 = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } -- rsa = key->rsa; + BN_set_flags(aux, BN_FLG_CONSTTIME); -- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || -- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || -- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || -- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { +- BN_init(&d); +- BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); ++ BN_with_flags(d, rsa_d, BN_FLG_CONSTTIME); + +- if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || +- (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || +- (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || +- (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { + if ((BN_sub(aux, q, BN_value_one()) == 0) || + (BN_mod(dmq1, d, aux, ctx) == 0) || + (BN_sub(aux, p, BN_value_one()) == 0) || @@ -2662,6 +2650,7 @@ diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c + dmq1 = NULL; r = 0; out: ++ BN_free(d); BN_clear_free(aux); + BN_clear_free(dmp1); + BN_clear_free(dmq1); diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index e135a19..c6e30a4 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -756,7 +756,7 @@ diff -up openssh-7.6p1/auth2-hostbased.c.audit openssh-7.6p1/auth2-hostbased.c if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && - PRIVSEP(sshkey_verify(key, sig, slen, + PRIVSEP(hostbased_key_verify(key, sig, slen, - sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0) + sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0) authenticated = 1; @@ -169,6 +169,19 @@ done: @@ -765,11 +765,11 @@ diff -up openssh-7.6p1/auth2-hostbased.c.audit openssh-7.6p1/auth2-hostbased.c +int +hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, -+ const u_char *data, size_t datalen, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + int rv; + -+ rv = sshkey_verify(key, sig, slen, data, datalen, compat); ++ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); +#ifdef SSH_AUDIT_EVENTS + audit_key(0, &rv, key); +#endif @@ -785,10 +785,10 @@ diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c @@ -206,7 +206,7 @@ userauth_pubkey(struct ssh *ssh) /* test for correct signature */ authenticated = 0; - if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && + if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && - PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), + PRIVSEP(user_key_verify(key, sig, slen, sshbuf_ptr(b), - sshbuf_len(b), ssh->compat)) == 0) { + sshbuf_len(b), NULL, ssh->compat)) == 0) { authenticated = 1; } @@ -250,6 +250,19 @@ done: @@ -797,11 +797,11 @@ diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c +int +user_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, -+ const u_char *data, size_t datalen, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + int rv; + -+ rv = sshkey_verify(key, sig, slen, data, datalen, compat); ++ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); +#ifdef SSH_AUDIT_EVENTS + audit_key(1, &rv, key); +#endif @@ -836,22 +836,24 @@ diff -up openssh-7.6p1/auth.c.audit openssh-7.6p1/auth.c diff -up openssh-7.6p1/auth.h.audit openssh-7.6p1/auth.h --- openssh-7.6p1/auth.h.audit 2017-10-04 17:18:32.768504711 +0200 +++ openssh-7.6p1/auth.h 2017-10-04 17:18:32.836505059 +0200 -@@ -198,6 +198,7 @@ struct passwd * getpwnamallow(const char +@@ -198,6 +198,8 @@ struct passwd * getpwnamallow(const char char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); -+int user_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); ++int user_key_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int); FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -217,6 +218,7 @@ struct sshkey *get_hostkey_private_by_ty +@@ -217,6 +218,8 @@ struct sshkey *get_hostkey_private_by_ty int get_hostkey_index(struct sshkey *, int, struct ssh *); int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); -+int hostbased_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); ++int hostbased_key_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int); - /* debug messages during authentication */ - void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); + /* Key / cert options linkage to auth layer */ + const struct sshauthopt *auth_options(struct ssh *); diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c --- openssh-7.6p1/cipher.c.audit 2017-10-02 21:34:26.000000000 +0200 +++ openssh-7.6p1/cipher.c 2017-10-04 17:18:32.836505059 +0200 @@ -1100,8 +1102,8 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #include "ssherr.h" @@ -117,6 +118,8 @@ extern Buffer auth_debug; - extern int auth_debug_init; extern Buffer loginmsg; + extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ +extern void destroy_sensitive_data(int); + @@ -1144,7 +1146,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c {0, 0, NULL} }; @@ -1396,7 +1413,9 @@ mm_answer_keyverify(int sock, struct ssh - u_char *signature, *data, *blob; + char *sigalg; size_t signaturelen, datalen, bloblen; int r, ret, valid_data = 0, encoded_ret; + int type = 0; @@ -1152,7 +1154,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + type = buffer_get_int(m); if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || - (r = sshbuf_get_string(m, &data, &datalen)) != 0) + (r = sshbuf_get_string(m, &data, &datalen)) != 0 || @@ -1405,6 +1424,8 @@ mm_answer_keyverify(int sock, struct ssh if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) @@ -1160,20 +1162,20 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + if (type != key_blobtype) + fatal("%s: bad key type", __func__); - /* XXX use sshkey_froms here; need to change key_blob, etc. */ - if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0) + /* Empty signature algorithm means NULL. */ + if (*sigalg == '\0') { @@ -1414,21 +1435,24 @@ mm_answer_keyverify(int sock, struct ssh case MM_USERKEY: valid_data = monitor_valid_userblob(data, datalen); auth_method = "publickey"; + ret = user_key_verify(key, signature, signaturelen, data, -+ datalen, active_state->compat); ++ datalen, sigalg, active_state->compat); break; case MM_HOSTKEY: valid_data = monitor_valid_hostbasedblob(data, datalen, hostbased_cuser, hostbased_chost); + ret = hostbased_key_verify(key, signature, signaturelen, data, -+ datalen, active_state->compat); ++ datalen, sigalg, active_state->compat); auth_method = "hostbased"; break; default: @@ -1185,7 +1187,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c fatal("%s: bad signature data blob", __func__); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, -- active_state->compat); +- sigalg, active_state->compat); debug3("%s: %s %p signature %s", __func__, auth_method, key, (ret == 0) ? "verified" : "unverified"); auth2_record_key(authctxt, ret == 0, key); @@ -1400,7 +1402,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c int -mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +mm_sshkey_verify(enum mm_keytype type, const struct sshkey *key, const u_char *sig, size_t siglen, - const u_char *data, size_t datalen, u_int compat) + const u_char *data, size_t datalen, const char *sigalg, u_int compat) { Buffer m; @@ -478,6 +478,7 @@ mm_sshkey_verify(const struct sshkey *ke @@ -1417,16 +1419,16 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +int +mm_hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, -+ const u_char *data, size_t datalen, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ -+ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, compat); ++ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, pkalg, compat); +} + +int +mm_user_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, -+ const u_char *data, size_t datalen, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ -+ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, compat); ++ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, pkalg, compat); +} + void @@ -1547,14 +1549,14 @@ diff -up openssh-7.6p1/monitor_wrap.h.audit openssh-7.6p1/monitor_wrap.h --- openssh-7.6p1/monitor_wrap.h.audit 2017-10-04 17:18:32.750504619 +0200 +++ openssh-7.6p1/monitor_wrap.h 2017-10-04 17:18:32.838505069 +0200 @@ -53,7 +53,9 @@ int mm_key_allowed(enum mm_keytype, cons - int mm_user_key_allowed(struct passwd *, struct sshkey *, int); + struct sshauthopt **); int mm_hostbased_key_allowed(struct passwd *, const char *, const char *, struct sshkey *); -int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +int mm_hostbased_key_verify(const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, u_int); ++ const u_char *, size_t, const char *, u_int); +int mm_user_key_verify(const struct sshkey *, const u_char *, size_t, - const u_char *, size_t, u_int); + const u_char *, size_t, const char *, u_int); #ifdef GSSAPI @@ -78,7 +80,12 @@ void mm_sshpam_free_ctx(void *); @@ -1743,8 +1745,8 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c -extern void destroy_sensitive_data(void); +extern void destroy_sensitive_data(int); extern Buffer loginmsg; - - /* original command from peer. */ + extern struct sshauthopt *auth_opts; + char *tun_fwd_ifnames; /* serverloop.c */ @@ -605,6 +605,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1930,8 +1932,8 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c #include "monitor_wrap.h" +#include "audit.h" #include "ssh-sandbox.h" + #include "auth-options.h" #include "version.h" - #include "ssherr.h" @@ -248,7 +249,7 @@ Buffer loginmsg; struct passwd *privsep_pw = NULL; @@ -1970,7 +1972,7 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c -destroy_sensitive_data(void) +destroy_sensitive_data(int privsep) { - int i; + u_int i; +#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; @@ -2009,7 +2011,7 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c @@ -499,12 +536,30 @@ demote_sensitive_data(void) { struct sshkey *tmp; - int i; + u_int i; +#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 49510f7..3b5001a 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -9,11 +9,11 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c +extern int rexeced_flag; +extern Authctxt *the_authctxt; - static int - userauth_pubkey(struct ssh *ssh) + static char * + format_key(const struct sshkey *key) @@ -432,7 +435,8 @@ match_principals_command(struct passwd * - if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command, + 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, @@ -23,7 +23,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c uid_swapped = 1; @@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd - if ((pid = subprocess("AuthorizedKeysCommand", pw, command, + 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, @@ -31,9 +31,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c goto out; uid_swapped = 1; -diff -up openssh/misc.c.refactor openssh/misc.c ---- openssh/misc.c.refactor 2017-09-27 13:10:19.640831071 +0200 -+++ openssh/misc.c 2017-09-27 13:10:19.678831279 +0200 +diff -up openssh/auth.c.refactor openssh/auth.c +--- openssh/auth.c.refactor 2017-09-27 13:10:19.640831071 +0200 ++++ openssh/auth.c 2017-09-27 13:10:19.678831279 +0200 @@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv) */ pid_t @@ -53,18 +53,18 @@ diff -up openssh/misc.c.refactor openssh/misc.c error ("failed to copy environment: %s", strerror(errno)); _exit(127); -diff -up openssh/misc.h.refactor openssh/misc.h ---- openssh/misc.h.refactor 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/misc.h 2017-09-27 13:10:19.678831279 +0200 +diff -up openssh/auth.h.refactor openssh/auth.h +--- openssh/auth.h.refactor 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/auth.h 2017-09-27 13:10:19.678831279 +0200 @@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *, - #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 *, + #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 *); - struct stat; - int safe_path(const char *, struct stat *, const char *, uid_t, + 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 2017-09-27 13:10:19.634831038 +0200 +++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +0200 diff --git a/openssh-7.6p1-permitopen-bug.patch b/openssh-7.6p1-permitopen-bug.patch deleted file mode 100644 index 3dd4a57..0000000 --- a/openssh-7.6p1-permitopen-bug.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 7c9613fac3371cf65fb07739212cdd1ebf6575da Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 4 Oct 2017 18:49:30 +0000 -Subject: [PATCH] upstream commit - -fix (another) problem in PermitOpen introduced during the -channels.c refactor: the third and subsequent arguments to PermitOpen were -being silently ignored; ok markus@ - -Upstream-ID: 067c89f1f53cbc381628012ba776d6861e6782fd ---- - servconf.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/servconf.c b/servconf.c -index 2c321a4ad..956862959 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -1,5 +1,5 @@ - --/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */ -+/* $OpenBSD: servconf.c,v 1.313 2017/10/04 18:49:30 djm Exp $ */ - /* - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved -@@ -1663,9 +1663,9 @@ process_server_config_line(ServerOptions *options, char *line, - if (!arg || *arg == '\0') - fatal("%s line %d: missing PermitOpen specification", - filename, linenum); -- i = options->num_permitted_opens; /* modified later */ -+ value = options->num_permitted_opens; /* modified later */ - if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { -- if (*activep && i == 0) { -+ if (*activep && value == 0) { - options->num_permitted_opens = 1; - options->permitted_opens = xcalloc(1, - sizeof(*options->permitted_opens)); -@@ -1683,7 +1683,7 @@ process_server_config_line(ServerOptions *options, char *line, - if (arg == NULL || ((port = permitopen_port(arg)) < 0)) - fatal("%s line %d: bad port number in " - "PermitOpen", filename, linenum); -- if (*activep && i == 0) { -+ if (*activep && value == 0) { - options->permitted_opens = xrecallocarray( - options->permitted_opens, - options->num_permitted_opens, - diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch new file mode 100644 index 0000000..b7fd2cf --- /dev/null +++ b/openssh-7.6p1-pkcs11-ecdsa.patch @@ -0,0 +1,794 @@ +diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-client.c +--- openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-02-16 13:25:59.426469253 +0100 ++++ openssh-7.6p1/ssh-pkcs11-client.c 2018-02-16 13:25:59.428469265 +0100 +@@ -31,6 +31,15 @@ + #include + + #include ++#ifdef OPENSSL_HAS_ECC ++#include ++#if ((defined(LIBRESSL_VERSION_NUMBER) && \ ++ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ ++ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ ++ (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++#define ENABLE_PKCS11_ECDSA 1 ++#endif ++#endif + + #include "pathnames.h" + #include "xmalloc.h" +@@ -139,9 +147,9 @@ pkcs11_rsa_private_encrypt(int flen, con + return (ret); + } + +-/* redirect the private key encrypt operation to the ssh-pkcs11-helper */ ++/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */ + static int +-wrap_key(RSA *rsa) ++wrap_rsa_key(RSA *rsa) + { + static RSA_METHOD helper_rsa; + +@@ -152,6 +160,81 @@ wrap_key(RSA *rsa) + return (0); + } + ++#ifdef ENABLE_PKCS11_ECDSA ++static ECDSA_SIG * ++pkcs11_ecdsa_private_sign(const unsigned char *from, int flen, ++ const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa) ++{ ++ Key key; ++ u_char *blob, *signature = NULL; ++ u_int blen, slen = 0; ++ Buffer msg; ++ ECDSA_SIG *ret = NULL; ++ BIGNUM *r = NULL, *s = NULL; ++ ++ key.type = KEY_ECDSA; ++ key.ecdsa = ecdsa; ++ key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); ++ if (key_to_blob(&key, &blob, &blen) == 0) ++ return NULL; ++ buffer_init(&msg); ++ buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); ++ buffer_put_string(&msg, blob, blen); ++ buffer_put_string(&msg, from, flen); ++ buffer_put_int(&msg, 0); ++ free(blob); ++ send_msg(&msg); ++ buffer_clear(&msg); ++ ++ if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { ++ signature = buffer_get_string(&msg, &slen); ++ if (slen <= (u_int)ECDSA_size(ecdsa)) { ++ int nlen = slen / 2; ++ ret = ECDSA_SIG_new(); ++ r = BN_new(); ++ s = BN_new(); ++ BN_bin2bn(&signature[0], nlen, r); ++ BN_bin2bn(&signature[nlen], nlen, s); ++ ECDSA_SIG_set0(ret, r, s); ++ } ++ free(signature); ++ } ++ buffer_free(&msg); ++ return (ret); ++} ++ ++/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */ ++static int ++wrap_ecdsa_key(EC_KEY *ecdsa) { ++#if (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++ static EC_KEY_METHOD *helper_ecdsa = NULL; ++ if (helper_ecdsa == NULL) { ++ const EC_KEY_METHOD *def = EC_KEY_get_default_method(); ++ helper_ecdsa = EC_KEY_METHOD_new(def); ++ EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign); ++ } ++ EC_KEY_set_method(ecdsa, helper_ecdsa); ++#else ++ static ECDSA_METHOD *helper_ecdsa = NULL; ++ if(helper_ecdsa == NULL) { ++ const ECDSA_METHOD *def = ECDSA_get_default_method(); ++# ifdef ECDSA_F_ECDSA_METHOD_NEW ++ helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def); ++ ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa"); ++ ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign); ++# else ++ helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa)); ++ memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa)); ++ helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa"; ++ helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign; ++# endif ++ } ++ ECDSA_set_method(ecdsa, helper_ecdsa); ++#endif ++ return (0); ++} ++#endif ++ + static int + pkcs11_start_helper(void) + { +@@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi + blob = buffer_get_string(&msg, &blen); + free(buffer_get_string(&msg, NULL)); + k = key_from_blob(blob, blen); +- wrap_key(k->rsa); ++ if(k->type == KEY_RSA) { ++ wrap_rsa_key(k->rsa); ++#ifdef ENABLE_PKCS11_ECDSA ++ } else if(k->type == KEY_ECDSA) { ++ wrap_ecdsa_key(k->ecdsa); ++#endif /* ENABLE_PKCS11_ECDSA */ ++ } else { ++ /* Unsupported type */ ++ } + (*keysp)[i] = k; + free(blob); + } +diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c +--- openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa 2018-02-16 13:25:59.427469259 +0100 ++++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 13:44:51.270554797 +0100 +@@ -32,6 +32,16 @@ + #include "openbsd-compat/sys-queue.h" + + #include ++#include ++#ifdef OPENSSL_HAS_ECC ++#include ++#if ((defined(LIBRESSL_VERSION_NUMBER) && \ ++ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ ++ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ ++ (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++#define ENABLE_PKCS11_ECDSA 1 ++#endif ++#endif + + #define CRYPTOKI_COMPAT + #include "pkcs11.h" +@@ -67,6 +76,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro + struct pkcs11_key { + struct pkcs11_provider *provider; + CK_ULONG slotidx; ++ CK_ULONG key_type; + int (*orig_finish)(RSA *rsa); + RSA_METHOD rsa_method; + char *keyid; +@@ -75,6 +85,9 @@ struct pkcs11_key { + }; + + int pkcs11_interactive = 0; ++#ifdef ENABLE_PKCS11_ECDSA ++static int pkcs11_key_idx = -1; ++#endif /* ENABLE_PKCS11_ECDSA */ + + /* + * This can't be in the ssh-pkcs11-uri, becase we can not depend on +@@ -289,6 +302,40 @@ pkcs11_find(struct pkcs11_provider *p, C + return (ret); + } + ++int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) { ++ char *pin = NULL, prompt[1024]; ++ CK_RV rv; ++ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { ++ if (!pkcs11_interactive) { ++ error("need pin entry%s", (si->token.flags & ++ CKF_PROTECTED_AUTHENTICATION_PATH) ? ++ " on reader keypad" : ""); ++ return (-1); ++ } ++ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ++ verbose("Deferring PIN entry to reader keypad."); ++ else { ++ snprintf(prompt, sizeof(prompt), ++ "Enter PIN for '%s': ", si->token.label); ++ pin = read_passphrase(prompt, RP_ALLOW_EOF); ++ if (pin == NULL) ++ return (-1); /* bail out */ ++ } ++ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, ++ (pin != NULL) ? strlen(pin) : 0); ++ if (pin != NULL) { ++ explicit_bzero(pin, strlen(pin)); ++ free(pin); ++ } ++ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { ++ error("C_Login failed: %lu", rv); ++ return (-1); ++ } ++ si->logged_in = 1; ++ } ++ return 0; ++} ++ + /* openssl callback doing the actual signing operation */ + static int + pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, +@@ -310,7 +357,6 @@ pkcs11_rsa_private_encrypt(int flen, con + {CKA_ID, NULL, 0}, + {CKA_SIGN, NULL, sizeof(true_val) } + }; +- char *pin = NULL, prompt[1024]; + int rval = -1; + + key_filter[0].pValue = &private_key_class; +@@ -326,33 +372,8 @@ pkcs11_rsa_private_encrypt(int flen, con + } + f = k11->provider->module->function_list; + si = &k11->provider->module->slotinfo[k11->slotidx]; +- if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { +- if (!pkcs11_interactive) { +- error("need pin entry%s", (si->token.flags & +- CKF_PROTECTED_AUTHENTICATION_PATH) ? +- " on reader keypad" : ""); +- return (-1); +- } +- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) +- verbose("Deferring PIN entry to reader keypad."); +- else { +- snprintf(prompt, sizeof(prompt), +- "Enter PIN for '%s': ", si->token.label); +- pin = read_passphrase(prompt, RP_ALLOW_EOF); +- if (pin == NULL) +- return (-1); /* bail out */ +- } +- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, +- (pin != NULL) ? strlen(pin) : 0); +- if (pin != NULL) { +- explicit_bzero(pin, strlen(pin)); +- free(pin); +- } +- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { +- error("C_Login failed: %lu", rv); +- return (-1); +- } +- si->logged_in = 1; ++ if(pkcs11_login(k11, f, si)) { ++ return (-1); + } + key_filter[1].pValue = k11->keyid; + key_filter[1].ulValueLen = k11->keyid_len; +@@ -390,6 +411,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + const RSA_METHOD *def = RSA_get_default_method(); + + k11 = xcalloc(1, sizeof(*k11)); ++ k11->key_type = CKK_RSA; + k11->provider = provider; + provider->refcount++; /* provider referenced by RSA key */ + k11->slotidx = slotidx; +@@ -415,6 +437,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + return (0); + } + ++#ifdef ENABLE_PKCS11_ECDSA ++static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len, ++ const BIGNUM *inv, const BIGNUM *rp, ++ EC_KEY *ecdsa) { ++ struct pkcs11_key *k11; ++ struct pkcs11_slotinfo *si; ++ CK_FUNCTION_LIST *f; ++ CK_OBJECT_HANDLE obj; ++ CK_ULONG tlen = 0; ++ CK_RV rv; ++ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; ++ CK_BBOOL true_val = CK_TRUE; ++ CK_MECHANISM mech = { ++ CKM_ECDSA, NULL_PTR, 0 ++ }; ++ CK_ATTRIBUTE key_filter[] = { ++ {CKA_CLASS, NULL, sizeof(private_key_class) }, ++ {CKA_ID, NULL, 0}, ++ {CKA_SIGN, NULL, sizeof(true_val) } ++ }; ++ ECDSA_SIG *rval = NULL; ++ key_filter[0].pValue = &private_key_class; ++ key_filter[2].pValue = &true_val; ++ ++ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++ if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) { ++ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa); ++ #else ++ if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) { ++ error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa); ++ #endif ++ return NULL; ++ } ++ if (!k11->provider || !k11->provider->valid) { ++ error("no pkcs11 (valid) provider for ecdsa %p", ecdsa); ++ return NULL; ++ } ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; ++ if(pkcs11_login(k11, f, si)) { ++ return NULL; ++ } ++ key_filter[1].pValue = k11->keyid; ++ key_filter[1].ulValueLen = k11->keyid_len; ++ /* try to find object w/CKA_SIGN first, retry w/o */ ++ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 && ++ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) { ++ error("cannot find private key"); ++ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { ++ error("C_SignInit failed: %lu", rv); ++ } else { ++ CK_BYTE_PTR buf = NULL; ++ BIGNUM *r = NULL, *s = NULL; ++ int nlen; ++ /* Make a call to C_Sign to find out the size of the signature */ ++ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen); ++ if (rv != CKR_OK) { ++ error("C_Sign failed: %lu", rv); ++ return NULL; ++ } ++ if ((buf = xmalloc(tlen)) == NULL) { ++ error("failure to allocate signature buffer"); ++ return NULL; ++ } ++ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen); ++ if (rv != CKR_OK) { ++ error("C_Sign failed: %lu", rv); ++ } ++ ++ if ((rval = ECDSA_SIG_new()) == NULL || ++ (r = BN_new()) == NULL || ++ (s = BN_new()) == NULL) { ++ error("failure to allocate ECDSA signature"); ++ } else { ++ /* ++ * ECDSA signature is 2 large integers of same size returned ++ * concatenated by PKCS#11, we separate them to create an ++ * ECDSA_SIG for OpenSSL. ++ */ ++ nlen = tlen / 2; ++ BN_bin2bn(&buf[0], nlen, r); ++ BN_bin2bn(&buf[nlen], nlen, s); ++ ECDSA_SIG_set0(rval, r, s); ++ } ++ free(buf); ++ } ++ return (rval); ++} ++ ++#if (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) { ++ static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL; ++ if(pkcs11_key_idx == -1) { ++ pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0); ++ } ++ if (pkcs11_ecdsa_method == NULL) { ++ const EC_KEY_METHOD *def = EC_KEY_get_default_method(); ++ pkcs11_ecdsa_method = EC_KEY_METHOD_new(def); ++ EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign); ++ } ++#else ++static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) { ++ static ECDSA_METHOD *pkcs11_ecdsa_method = NULL; ++ if(pkcs11_key_idx == -1) { ++ pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0); ++ } ++ if(pkcs11_ecdsa_method == NULL) { ++ const ECDSA_METHOD *def = ECDSA_get_default_method(); ++ #ifdef ECDSA_F_ECDSA_METHOD_NEW ++ pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def); ++ ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11"); ++ ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign); ++ #else ++ pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method)); ++ memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method)); ++ pkcs11_ecdsa_method->name = "pkcs11"; ++ pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign; ++ #endif ++ } ++#endif ++ return pkcs11_ecdsa_method; ++} ++ ++static int ++pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa) ++{ ++ struct pkcs11_key *k11; ++ k11 = xcalloc(1, sizeof(*k11)); ++ k11->key_type = CKK_EC; ++ k11->provider = provider; ++ provider->refcount++; /* provider referenced by ECDSA key */ ++ k11->slotidx = slotidx; ++ /* identify key object on smartcard */ ++ k11->keyid_len = keyid_attrib->ulValueLen; ++ if (k11->keyid_len > 0) { ++ k11->keyid = xmalloc(k11->keyid_len); ++ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); ++ } ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++ EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method()); ++ EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11); ++ #else ++ ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method()); ++ ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11); ++ #endif ++ return (0); ++} ++#endif /* ENABLE_PKCS11_ECDSA */ ++ ++int pkcs11_del_key(struct sshkey *key) { ++#ifdef ENABLE_PKCS11_ECDSA ++ if(key->type == KEY_ECDSA) { ++ struct pkcs11_key *k11 = (struct pkcs11_key *) ++ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++ EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx); ++ #else ++ ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx); ++ #endif ++ if (k11 == NULL) { ++ error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa); ++ } else { ++ if (k11->provider) ++ pkcs11_provider_unref(k11->provider); ++ free(k11->keyid); ++ free(k11); ++ } ++ } ++#endif /* ENABLE_PKCS11_ECDSA */ ++ sshkey_free(key); ++ return (0); ++} ++ + /* remove trailing spaces */ + static void + rmspace(u_char *buf, size_t len) +@@ -482,11 +646,13 @@ static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) + { +- size_t filter_size = 1; ++ size_t filter_size = 2; ++ CK_KEY_TYPE pubkey_type = CKK_RSA; + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; + CK_ATTRIBUTE pubkey_filter[] = { + { CKA_CLASS, NULL, sizeof(pubkey_class) }, ++ { CKA_KEY_TYPE, NULL, sizeof(pubkey_type) }, + { CKA_ID, NULL, 0 }, + { CKA_LABEL, NULL, 0 } + }; +@@ -507,29 +673,60 @@ pkcs11_fetch_keys(struct pkcs11_provider + { CKA_SUBJECT, NULL, 0 }, + { CKA_VALUE, NULL, 0 } + }; ++#ifdef ENABLE_PKCS11_ECDSA ++ CK_KEY_TYPE ecdsa_type = CKK_EC; ++ CK_ATTRIBUTE ecdsa_filter[] = { ++ { CKA_CLASS, NULL, sizeof(pubkey_class) }, ++ { CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) }, ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 } ++ }; ++ CK_ATTRIBUTE ecdsa_attribs[] = { ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 }, ++ { CKA_EC_PARAMS, NULL, 0 }, ++ { CKA_EC_POINT, NULL, 0 } ++ }; ++ ecdsa_filter[0].pValue = &pubkey_class; ++ ecdsa_filter[1].pValue = &ecdsa_type; ++#endif /* ENABLE_PKCS11_ECDSA */ + pubkey_filter[0].pValue = &pubkey_class; ++ pubkey_filter[1].pValue = &pubkey_type; + cert_filter[0].pValue = &cert_class; + + if (uri->id != NULL) { + pubkey_filter[filter_size].pValue = uri->id; + pubkey_filter[filter_size].ulValueLen = uri->id_len; +- cert_filter[filter_size].pValue = uri->id; +- cert_filter[filter_size].ulValueLen = uri->id_len; ++#ifdef ENABLE_PKCS11_ECDSA ++ ecdsa_filter[filter_size].pValue = uri->id; ++ ecdsa_filter[filter_size].ulValueLen = uri->id_len; ++#endif /* ENABLE_PKCS11_ECDSA */ ++ cert_filter[filter_size-1].pValue = uri->id; ++ cert_filter[filter_size-1].ulValueLen = uri->id_len; + filter_size++; + } + if (uri->object != NULL) { + pubkey_filter[filter_size].pValue = uri->object; + pubkey_filter[filter_size].ulValueLen = strlen(uri->object); + pubkey_filter[filter_size].type = CKA_LABEL; +- cert_filter[filter_size].pValue = uri->object; +- cert_filter[filter_size].ulValueLen = strlen(uri->object); +- cert_filter[filter_size].type = CKA_LABEL; ++#ifdef ENABLE_PKCS11_ECDSA ++ ecdsa_filter[filter_size].pValue = uri->object; ++ ecdsa_filter[filter_size].ulValueLen = strlen(uri->object); ++ ecdsa_filter[filter_size].type = CKA_LABEL; ++#endif /* ENABLE_PKCS11_ECDSA */ ++ cert_filter[filter_size-1].pValue = uri->object; ++ cert_filter[filter_size-1].ulValueLen = strlen(uri->object); ++ cert_filter[filter_size-1].type = CKA_LABEL; + filter_size++; + } + + if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, + pubkey_attribs, keysp, nkeys) < 0 || +- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, ++#ifdef ENABLE_PKCS11_ECDSA ++ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size, ++ ecdsa_attribs, keysp, nkeys) < 0|| ++#endif /* ENABLE_PKCS11_ECDSA */ ++ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1, + cert_attribs, keysp, nkeys) < 0) + return (-1); + return (0); +@@ -553,6 +746,11 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + { + struct sshkey *key; + RSA *rsa; ++#ifdef ENABLE_PKCS11_ECDSA ++ EC_KEY *ecdsa; ++#else ++ void *ecdsa; ++#endif /* ENABLE_PKCS11_ECDSA */ + X509 *x509; + EVP_PKEY *evp = NULL; + int i; +@@ -608,6 +806,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + * or ID, label, subject and value for certificates. + */ + rsa = NULL; ++#ifdef ENABLE_PKCS11_ECDSA ++ ecdsa = NULL; ++#endif /* ENABLE_PKCS11_ECDSA */ + if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); +@@ -620,6 +821,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + rsa->e = BN_bin2bn(attribs[3].pValue, + attribs[3].ulValueLen, NULL); + } ++#ifdef ENABLE_PKCS11_ECDSA ++ } else if (attribs[2].type == CKA_EC_PARAMS ) { ++ if ((ecdsa = EC_KEY_new()) == NULL) { ++ error("EC_KEY_new failed"); ++ } else { ++ const unsigned char *ptr1 = attribs[2].pValue; ++ const unsigned char *ptr2 = attribs[3].pValue; ++ CK_ULONG len1 = attribs[2].ulValueLen; ++ CK_ULONG len2 = attribs[3].ulValueLen; ++ ASN1_OCTET_STRING *point = NULL; ++ ++ /* ++ * CKA_EC_PARAMS contains the curve parameters of the key ++ * either referenced as an OID or directly with all values. ++ * CKA_EC_POINT contains the point (public key) on the curve. ++ * The point is should be returned inside a DER-encoded ++ * ASN.1 OCTET STRING value (but some implementation). ++ */ ++ if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) { ++ /* Pointing to OCTET STRING content */ ++ ptr2 = point->data; ++ len2 = point->length; ++ } else { ++ /* No OCTET STRING */ ++ ptr2 = attribs[3].pValue; ++ } ++ ++ if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) || ++ (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) { ++ EC_KEY_free(ecdsa); ++ ecdsa = NULL; ++ error("EC public key parsing failed"); ++ } ++ ++ if(point) { ++ ASN1_OCTET_STRING_free(point); ++ } ++ } ++#endif /* ENABLE_PKCS11_ECDSA */ + } else { + cp = attribs[3].pValue; + if ((x509 = X509_new()) == NULL) { +@@ -639,13 +879,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + X509_free(x509); + EVP_PKEY_free(evp); + } +- if (rsa && rsa->n && rsa->e && +- pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { +- if ((key = sshkey_new(KEY_UNSPEC)) == NULL) +- fatal("sshkey_new failed"); +- key->rsa = rsa; +- key->type = KEY_RSA; +- key->flags |= SSHKEY_FLAG_EXT; ++ key = NULL; ++ if (rsa || ecdsa) { ++ if (rsa && rsa->n && rsa->e && ++ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { ++ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) ++ fatal("sshkey_new failed"); ++ key->rsa = rsa; ++ key->type = KEY_RSA; ++ key->flags |= SSHKEY_FLAG_EXT; ++#ifdef ENABLE_PKCS11_ECDSA ++ } else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) { ++ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) ++ fatal("sshkey_new failed"); ++ key->ecdsa = ecdsa; ++ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); ++ key->type = KEY_ECDSA; ++ key->flags |= SSHKEY_FLAG_EXT; ++#endif /* ENABLE_PKCS11_ECDSA */ ++ } ++ } ++ ++ if(key) { + if (pkcs11_key_included(keysp, nkeys, key)) { + sshkey_free(key); + } else { +@@ -658,6 +913,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } + } else if (rsa) { + RSA_free(rsa); ++#ifdef ENABLE_PKCS11_ECDSA ++ } else if (ecdsa) { ++ EC_KEY_free(ecdsa); ++#endif /* ENABLE_PKCS11_ECDSA */ + } + for (i = 0; i < nattribs; i++) + free(attribs[i].pValue); +diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-helper.c +--- openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/ssh-pkcs11-helper.c 2018-02-16 13:25:59.428469265 +0100 +@@ -24,6 +24,17 @@ + + #include "openbsd-compat/sys-queue.h" + ++#include ++#ifdef OPENSSL_HAS_ECC ++#include ++#if ((defined(LIBRESSL_VERSION_NUMBER) && \ ++ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ ++ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ ++ (OPENSSL_VERSION_NUMBER >= 0x00010100L) ++#define ENABLE_PKCS11_ECDSA 1 ++#endif ++#endif ++ + #include + #include + #include +@@ -80,7 +90,7 @@ del_keys_by_name(char *name) + if (!strcmp(ki->providername, name)) { + TAILQ_REMOVE(&pkcs11_keylist, ki, next); + free(ki->providername); +- sshkey_free(ki->key); ++ pkcs11_del_key(ki->key); + free(ki); + } + } +@@ -164,6 +174,20 @@ process_del(void) + sshbuf_free(msg); + } + ++#ifdef ENABLE_PKCS11_ECDSA ++static u_int EC_KEY_order_size(EC_KEY *key) ++{ ++ const EC_GROUP *group = EC_KEY_get0_group(key); ++ BIGNUM *order = BN_new(); ++ u_int nbytes = 0; ++ if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) { ++ nbytes = BN_num_bytes(order); ++ } ++ BN_clear_free(order); ++ return nbytes; ++} ++#endif /* ENABLE_PKCS11_ECDSA */ ++ + static void + process_sign(void) + { +@@ -180,14 +204,38 @@ process_sign(void) + else { + if ((found = lookup_key(key)) != NULL) { + #ifdef WITH_OPENSSL +- int ret; +- +- slen = RSA_size(key->rsa); +- signature = xmalloc(slen); +- if ((ret = RSA_private_encrypt(dlen, data, signature, +- found->rsa, RSA_PKCS1_PADDING)) != -1) { +- slen = ret; +- ok = 0; ++ if(found->type == KEY_RSA) { ++ int ret; ++ slen = RSA_size(key->rsa); ++ signature = xmalloc(slen); ++ if ((ret = RSA_private_encrypt(dlen, data, signature, ++ found->rsa, RSA_PKCS1_PADDING)) != -1) { ++ slen = ret; ++ ok = 0; ++ } ++#ifdef ENABLE_PKCS11_ECDSA ++ } else if(found->type == KEY_ECDSA) { ++ ECDSA_SIG *sig; ++ const BIGNUM *r = NULL, *s = NULL; ++ if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) { ++ /* PKCS11 2.3.1 recommends both r and s to have the order size for ++ backward compatiblity */ ++ ECDSA_SIG_get0(sig, &r, &s); ++ u_int o_len = EC_KEY_order_size(found->ecdsa); ++ u_int r_len = BN_num_bytes(r); ++ u_int s_len = BN_num_bytes(s); ++ if (o_len > 0 && r_len <= o_len && s_len <= o_len) { ++ signature = xcalloc(2, o_len); ++ BN_bn2bin(r, signature + o_len - r_len); ++ BN_bn2bin(s, signature + (2 * o_len) - s_len); ++ slen = 2 * o_len; ++ ok = 0; ++ } ++ ECDSA_SIG_free(sig); ++ } ++#endif /* ENABLE_PKCS11_ECDSA */ ++ } else { ++ /* Unsupported type */ + } + #endif /* WITH_OPENSSL */ + } +diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h +--- openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa 2018-02-16 13:25:59.429469272 +0100 ++++ openssh-7.6p1/ssh-pkcs11.h 2018-02-16 13:45:29.623800048 +0100 +@@ -20,6 +20,7 @@ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***); ++int pkcs11_del_key(struct sshkey *); + int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); + int pkcs11_del_provider(char *); + int pkcs11_uri_write(const struct sshkey *, FILE *); + + + +diff -up openssh-7.6p1/ssh-pkcs11.c.old openssh-7.6p1/ssh-pkcs11.c +--- openssh-7.6p1/ssh-pkcs11.c.old 2018-02-16 16:43:08.861520255 +0100 ++++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 16:56:35.312601451 +0100 +@@ -917,13 +917,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) + == NULL) { + error("d2i_X509 failed"); +- } else if ((evp = X509_get_pubkey(x509)) == NULL || +- evp->type != EVP_PKEY_RSA || +- evp->pkey.rsa == NULL) { +- debug("X509_get_pubkey failed or no rsa"); +- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) +- == NULL) { +- error("RSAPublicKey_dup"); ++ } else if ((evp = X509_get_pubkey(x509)) == NULL) { ++ debug("X509_get_pubkey failed"); ++ } else { ++ switch (evp->type) { ++ case EVP_PKEY_RSA: ++ if (evp->pkey.rsa == NULL) ++ debug("Missing RSA key"); ++ else if ((rsa = RSAPublicKey_dup( ++ evp->pkey.rsa)) == NULL) ++ error("RSAPublicKey_dup failed"); ++ break; ++ case EVP_PKEY_EC: ++ if (evp->pkey.ecdsa == NULL) ++ debug("Missing ECDSA key"); ++ else if ((ecdsa = EC_KEY_dup( ++ evp->pkey.ecdsa)) == NULL) ++ error("EC_KEY_dup failed"); ++ break; ++ default: ++ debug("not a RSA or ECDSA key"); ++ break; ++ } + } + X509_free(x509); + EVP_PKEY_free(evp); diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch new file mode 100644 index 0000000..0114eb7 --- /dev/null +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -0,0 +1,4797 @@ +diff --git a/Makefile.in b/Makefile.in +index ac959c1f..f8ed1781 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -248,6 +248,8 @@ clean: regressclean + rm -f regress/unittests/match/test_match$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) clean) +@@ -276,6 +278,8 @@ distclean: regressclean + rm -f regress/unittests/match/test_match + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + rm -f regress/unittests/misc/kexfuzz + (cd openbsd-compat && $(MAKE) distclean) + if test -d pkg ; then \ +@@ -437,6 +441,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/kex + $(MKDIR_P) `pwd`/regress/unittests/match + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/kexfuzz + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -455,6 +460,11 @@ regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++regress/soft-pkcs11.so: $(srcdir)/regress/soft-pkcs11.c $(REGRESSLIBS) ++ $(CC) $(CFLAGS) $(CPPFLAGS) -fpic -c $(srcdir)/regress/soft-pkcs11.c \ ++ -o $(srcdir)/regress/soft-pkcs11.o ++ $(CC) -shared -o $@ $(srcdir)/regress/soft-pkcs11.o ++ + regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +@@ -556,6 +566,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ + MISC_KEX_FUZZ_OBJS=\ + regress/misc/kexfuzz/kexfuzz.o + +@@ -566,6 +586,7 @@ regress/misc/kexfuzz/kexfuzz$(EXEEXT): ${MISC_KEX_FUZZ_OBJS} libssh.a + regress-binaries: regress/modpipe$(EXEEXT) \ + regress/setuid-allowed$(EXEEXT) \ + regress/netcat$(EXEEXT) \ ++ regress/soft-pkcs11.so \ + regress/check-perm$(EXEEXT) \ + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ +@@ -575,6 +596,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ + regress/unittests/kex/test_kex$(EXEEXT) \ + regress/unittests/match/test_match$(EXEEXT) \ + regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + regress/misc/kexfuzz/kexfuzz$(EXEEXT) + + REGRESSTMP = "$(PWD)/regress" +diff --git a/authfd.c b/authfd.c +index 1eff7ba9..35153f47 100644 +--- a/authfd.c ++++ b/authfd.c +@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identitylist *idl) + if (idl->comments != NULL) + free(idl->comments[i]); + } ++ free(idl->keys); ++ free(idl->comments); + free(idl); + } + +diff --git a/configure.ac b/configure.ac +index d7bcaf01..171a8597 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1895,12 +1895,14 @@ AC_LINK_IFELSE( + [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) + ]) + ++SCARD_MSG="yes" + disable_pkcs11= + AC_ARG_ENABLE([pkcs11], + [ --disable-pkcs11 disable PKCS#11 support code [no]], + [ + if test "x$enableval" = "xno" ; then + disable_pkcs11=1 ++ SCARD_MSG="no" + fi + ] + ) +@@ -1916,6 +1918,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then + ) + fi + ++# Check whether we have a p11-kit, we got default provider on command line ++DEFAULT_PKCS11_PROVIDER_MSG="no" ++AC_ARG_WITH([default-pkcs11-provider], ++ [ --with-default-pkcs11-provider[[=PATH]] Use default pkcs11 provider (p11-kit detected by default)], ++ [ if test "x$withval" != "xno" && test "x$disable_pkcs11" = "x"; then ++ if test "x$withval" = "xyes" ; then ++ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) ++ if test "x$PKGCONFIG" != "xno"; then ++ AC_MSG_CHECKING([if $PKGCONFIG knows about p11-kit]) ++ if "$PKGCONFIG" "p11-kit-1"; then ++ AC_MSG_RESULT([yes]) ++ use_pkgconfig_for_p11kit=yes ++ else ++ AC_MSG_RESULT([no]) ++ fi ++ fi ++ else ++ PKCS11_PATH="${withval}" ++ fi ++ if test "x$use_pkgconfig_for_p11kit" = "xyes"; then ++ PKCS11_PATH=`$PKGCONFIG --variable=proxy_module p11-kit-1` ++ fi ++ AC_CHECK_FILE("$PKCS11_PATH", ++ [ AC_DEFINE_UNQUOTED([PKCS11_DEFAULT_PROVIDER], ["$PKCS11_PATH"], [Path to default PKCS#11 provider (p11-kit proxy)]) ++ DEFAULT_PKCS11_PROVIDER_MSG="$PKCS11_PATH" ++ ], ++ [ AC_MSG_ERROR([Requested PKCS11 provided not found]) ] ++ ) ++ else ++ AC_MSG_WARN([Needs PKCS11 support to enable default pkcs11 provider]) ++ fi ] ++) ++ ++ + # IRIX has a const char return value for gai_strerror() + AC_CHECK_FUNCS([gai_strerror], [ + AC_DEFINE([HAVE_GAI_STRERROR]) +@@ -5226,6 +5262,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + echo " Random number source: $RAND_MSG" + echo " Privsep sandbox style: $SANDBOX_STYLE" + echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" ++echo " Default PKCS#11 provider: $DEFAULT_PKCS11_PROVIDER_MSG" + + echo "" + +diff --git a/readconf.c b/readconf.c +index 88051db5..c1e7ce93 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1016,7 +1016,8 @@ parse_time: + break; + + case oIdentityFile: +- arg = strdelim(&s); ++ /* Can't use strdelim() becase it would break on equal signs */ ++ arg = s; + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep) { +@@ -1027,7 +1028,7 @@ parse_time: + add_identity_file(options, NULL, + arg, flags & SSHCONF_USERCONF); + } +- break; ++ return 0; + + case oCertificateFile: + arg = strdelim(&s); +diff --git a/regress/Makefile b/regress/Makefile +index d15898ad..9c15afa4 100644 +--- a/regress/Makefile ++++ b/regress/Makefile +@@ -108,9 +110,11 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ + known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ + modpipe netcat no_identity_config \ + pidfile putty.rsa2 ready regress.log \ +- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ ++ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ ++ rsa-agent-cert.pub rsa.pub \ + rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ +- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ ++ soft-pkcs11.so soft-pkcs11.o pkcs11*.crt pkcs11*.key \ ++ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ + sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ + ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ +@@ -225,6 +229,7 @@ unit: + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ +diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh +index db3018b8..4991d0bc 100644 +--- a/regress/agent-pkcs11.sh ++++ b/regress/agent-pkcs11.sh +@@ -4,10 +4,17 @@ + tid="pkcs11 agent test" + + TEST_SSH_PIN="" +-TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 ++TEST_SSH_PKCS11=$OBJ/soft-pkcs11.so + + test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + ++# requires ssh-agent built with correct path to ssh-pkcs11-helper ++# otherwise it fails to start the helper ++strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" ++if [ $? -ne 0 ]; then ++ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" ++fi ++ + # setup environment for soft-pkcs11 token + SOFTPKCS11RC=$OBJ/pkcs11.info + export SOFTPKCS11RC +@@ -23,7 +30,7 @@ notty() { + } + + trace "start agent" +-eval `${SSHAGENT} -s` > /dev/null ++eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null + r=$? + if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +@@ -60,7 +67,7 @@ else + fi + + trace "remove pkcs11 keys" +- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 ++ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" +diff --git a/regress/locl.h b/regress/locl.h +new file mode 100644 +index 00000000..afefe27d +--- /dev/null ++++ b/regress/locl.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (c) 2004, Stockholms universitet ++ * (Stockholm University, Stockholm Sweden) ++ * All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * ++ * 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. Neither the name of the university nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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 ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* $Id: locl.h,v 1.5 2005/08/28 15:30:31 lha Exp $ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include "../libcrypto-compat.h" ++ ++#include ++#include ++#include ++#include ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++ ++#include "../pkcs11.h" ++ ++#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \ ++{ \ ++ unsigned char *p; \ ++ (BL) = i2d_##T((S), NULL); \ ++ if ((BL) <= 0) { \ ++ (R) = EINVAL; \ ++ } else { \ ++ (B) = malloc((BL)); \ ++ if ((B) == NULL) { \ ++ (R) = ENOMEM; \ ++ } else { \ ++ p = (B); \ ++ (R) = 0; \ ++ (BL) = i2d_##T((S), &p); \ ++ if ((BL) <= 0) { \ ++ free((B)); \ ++ (R) = EINVAL; \ ++ } \ ++ } \ ++ } \ ++} +diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh +new file mode 100644 +index 00000000..cf98e379 +--- /dev/null ++++ b/regress/pkcs11.sh +@@ -0,0 +1,300 @@ ++# ++# Copyright (c) 2017 Red Hat ++# ++# Authors: Jakub Jelen ++# ++# Permission to use, copy, modify, and distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ++tid="pkcs11 tests with soft token" ++ ++TEST_SSH_PIN="" ++TEST_SSH_PKCS11=$OBJ/soft-pkcs11.so ++ ++test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" ++ ++# requires ssh-agent built with correct path to ssh-pkcs11-helper ++# otherwise it fails to start the helper ++strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" ++if [ $? -ne 0 ]; then ++ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" ++fi ++ ++# setup environment for soft-pkcs11 token ++SOFTPKCS11RC=$OBJ/pkcs11.info ++rm -f $SOFTPKCS11RC ++export SOFTPKCS11RC ++# prevent ssh-agent from calling ssh-askpass ++SSH_ASKPASS=/usr/bin/true ++export SSH_ASKPASS ++unset DISPLAY ++ ++# start command w/o tty, so ssh accepts pin from stdin (from agent-pkcs11.sh) ++notty() { ++ perl -e 'use POSIX; POSIX::setsid(); ++ if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" ++} ++ ++create_key() { ++ ID=$1 ++ LABEL=$2 ++ rm -f $OBJ/pkcs11-${ID}.key $OBJ/pkcs11-${ID}.crt ++ openssl genrsa -out $OBJ/pkcs11-${ID}.key 2048 > /dev/null 2>&1 ++ chmod 600 $OBJ/pkcs11-${ID}.key ++ openssl req -key $OBJ/pkcs11-${ID}.key -new -x509 \ ++ -out $OBJ/pkcs11-${ID}.crt -text -subj '/CN=pkcs11 test' >/dev/null ++ printf "${ID}\t${LABEL}\t$OBJ/pkcs11-${ID}.crt\t$OBJ/pkcs11-${ID}.key\n" \ ++ >> $SOFTPKCS11RC ++} ++ ++trace "Create a key pairs on soft token" ++ID1="02" ++ID2="04" ++create_key "$ID1" "SSH RSA Key" ++create_key "$ID2" "SSH RSA Key 2" ++ ++trace "List the keys in the ssh-keygen with PKCS#11 URIs" ++${SSHKEYGEN} -D ${TEST_SSH_PKCS11} > $OBJ/token_keys ++if [ $? -ne 0 ]; then ++ fail "keygen fails to enumerate keys on PKCS#11 token" ++fi ++grep "pkcs11:" $OBJ/token_keys > /dev/null ++if [ $? -ne 0 ]; then ++ fail "The keys from ssh-keygen do not contain PKCS#11 URI as a comment" ++fi ++tail -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++ ++ ++trace "Simple connect with ssh (without PKCS#11 URI)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -I ${TEST_SSH_PKCS11} \ ++ -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with pkcs11 failed (exit code $r)" ++fi ++ ++ ++trace "Connect with PKCS#11 URI" ++trace " (second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (first key should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++trace "Connect with various filtering options in PKCS#11 URI" ++trace " (by object label, second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:object=SSH%20RSA%20Key%202?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (by object label, first key should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:object=SSH%20RSA%20Key?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++trace " (by token label, second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID2};token=SoftToken%20(token)?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (by wrong token label, should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:token=SoftToken?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++ ++ ++ ++trace "Test PKCS#11 URI specification in configuration files" ++echo "IdentityFile pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ >> $OBJ/ssh_proxy ++trace " (second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI in config failed (exit code $r)" ++fi ++ ++trace " (first key should fail)" ++head -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI in config succeeded (should fail)" ++fi ++sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy ++ ++trace "Test PKCS#11 URI specification in configuration files with bogus spaces" ++echo "IdentityFile pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} " \ ++ >> $OBJ/ssh_proxy ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI with bogus spaces in config failed" \ ++ "(exit code $r)" ++fi ++sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy ++ ++ ++trace "Combination of PKCS11Provider and PKCS11URI on commandline" ++trace " (first key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID1}" -I ${TEST_SSH_PKCS11} somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI and provider combination" \ ++ "failed (exit code $r)" ++fi ++ ++trace "Regress: Missing provider in PKCS11URI option" ++${SSH} -F $OBJ/ssh_proxy \ ++ -o IdentityFile='pkcs11:token=segfault' somehost exit 5 ++r=$? ++if [ $r -eq 139 ]; then ++ fail "ssh connect with missing provider_id from configuration option" \ ++ "crashed (exit code $r)" ++fi ++ ++ ++trace "SSH Agent can work with PKCS#11 URI" ++trace "start the agent" ++eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null ++ ++r=$? ++if [ $r -ne 0 ]; then ++ fail "could not start ssh-agent: exit code $r" ++else ++ trace "add whole provider to agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with whole provider: exit code $r" ++ fi ++ ++ trace " pkcs11 list via agent (all keys)" ++ ${SSHADD} -l > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -l failed with whole provider: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (all keys)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with whole provider (exit code $r)" ++ fi ++ ++ trace " remove pkcs11 keys (all keys)" ++ ${SSHADD} -d "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with whole provider: exit code $r" ++ fi ++ ++ trace "add only first key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with first key: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (first key)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with first key (exit code $r)" ++ fi ++ ++ trace " remove first pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with first key: exit code $r" ++ fi ++ ++ trace "add only second key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with second key: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (second key should fail)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -eq 5 ]; then ++ fail "ssh connect passed without key (should fail)" ++ fi ++ ++ trace "add also the first key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with first key: exit code $r" ++ fi ++ ++ trace " remove second pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with second key: exit code $r" ++ fi ++ ++ trace " remove already-removed pkcs11 key should fail" ++ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -eq 0 ]; then ++ fail "ssh-add -d passed with non-existing key (should fail)" ++ fi ++ ++ trace " pkcs11 connect via agent (the first key should be still usable)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with first key (after removing second): exit code $r" ++ fi ++ ++ trace "kill agent" ++ ${SSHAGENT} -k > /dev/null ++fi ++ ++rm -rf $OBJ/.tokens $OBJ/token_keys +diff --git a/regress/soft-pkcs11.c b/regress/soft-pkcs11.c +new file mode 100644 +index 00000000..8b4981bd +--- /dev/null ++++ b/regress/soft-pkcs11.c +@@ -0,0 +1,2058 @@ ++/* ++ * Copyright (c) 2004-2006, Stockholms universitet ++ * (Stockholm University, Stockholm Sweden) ++ * All rights reserved. ++ * ++ * 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, this list of conditions and the following disclaimer. ++ * ++ * 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. Neither the name of the university nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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 ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "locl.h" ++ ++/* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */ ++ ++#define OBJECT_ID_MASK 0xfff ++#define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK) ++#define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle) ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ #define RSA_PKCS1_SSLeay RSA_PKCS1_OpenSSL ++#endif ++ ++struct st_attr { ++ CK_ATTRIBUTE attribute; ++ int secret; ++}; ++ ++struct st_object { ++ CK_OBJECT_HANDLE object_handle; ++ struct st_attr *attrs; ++ int num_attributes; ++ enum { ++ STO_T_CERTIFICATE, ++ STO_T_PRIVATE_KEY, ++ STO_T_PUBLIC_KEY ++ } type; ++ union { ++ X509 *cert; ++ EVP_PKEY *public_key; ++ struct { ++ const char *file; ++ EVP_PKEY *key; ++ X509 *cert; ++ } private_key; ++ } u; ++}; ++ ++static struct soft_token { ++ CK_VOID_PTR application; ++ CK_NOTIFY notify; ++ struct { ++ struct st_object **objs; ++ int num_objs; ++ } object; ++ struct { ++ int hardware_slot; ++ int app_error_fatal; ++ int login_done; ++ } flags; ++ int open_sessions; ++ struct session_state { ++ CK_SESSION_HANDLE session_handle; ++ ++ struct { ++ CK_ATTRIBUTE *attributes; ++ CK_ULONG num_attributes; ++ int next_object; ++ } find; ++ ++ int encrypt_object; ++ CK_MECHANISM_PTR encrypt_mechanism; ++ int decrypt_object; ++ CK_MECHANISM_PTR decrypt_mechanism; ++ int sign_object; ++ CK_MECHANISM_PTR sign_mechanism; ++ int verify_object; ++ CK_MECHANISM_PTR verify_mechanism; ++ int digest_object; ++ } state[10]; ++#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0])) ++ FILE *logfile; ++} soft_token; ++ ++static void ++application_error(const char *fmt, ...) ++{ ++ va_list ap; ++ va_start(ap, fmt); ++ vprintf(fmt, ap); ++ va_end(ap); ++ if (soft_token.flags.app_error_fatal) ++ abort(); ++} ++ ++static void ++st_logf(const char *fmt, ...) ++{ ++ va_list ap; ++ if (soft_token.logfile == NULL) ++ return; ++ va_start(ap, fmt); ++ vfprintf(soft_token.logfile, fmt, ap); ++ va_end(ap); ++ fflush(soft_token.logfile); ++} ++ ++static void ++snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...) ++{ ++ int len; ++ va_list ap; ++ len = vsnprintf(str, size, fmt, ap); ++ va_end(ap); ++ if (len < 0 || len > (int) size) ++ return; ++ while(len < (int) size) ++ str[len++] = fillchar; ++} ++ ++#ifndef TEST_APP ++#define printf error_use_st_logf ++#endif ++ ++#define VERIFY_SESSION_HANDLE(s, state) \ ++{ \ ++ CK_RV ret; \ ++ ret = verify_session_handle(s, state); \ ++ if (ret != CKR_OK) { \ ++ /* return CKR_OK */; \ ++ } \ ++} ++ ++static CK_RV ++verify_session_handle(CK_SESSION_HANDLE hSession, ++ struct session_state **state) ++{ ++ size_t i; ++ ++ for (i = 0; i < MAX_NUM_SESSION; i++){ ++ if (soft_token.state[i].session_handle == hSession) ++ break; ++ } ++ if (i == MAX_NUM_SESSION) { ++ application_error("use of invalid handle: 0x%08lx\n", ++ (unsigned long)hSession); ++ return CKR_SESSION_HANDLE_INVALID; ++ } ++ if (state) ++ *state = &soft_token.state[i]; ++ return CKR_OK; ++} ++ ++static CK_RV ++object_handle_to_object(CK_OBJECT_HANDLE handle, ++ struct st_object **object) ++{ ++ int i = HANDLE_OBJECT_ID(handle); ++ ++ *object = NULL; ++ if (i >= soft_token.object.num_objs) ++ return CKR_ARGUMENTS_BAD; ++ if (soft_token.object.objs[i] == NULL) ++ return CKR_ARGUMENTS_BAD; ++ if (soft_token.object.objs[i]->object_handle != handle) ++ return CKR_ARGUMENTS_BAD; ++ *object = soft_token.object.objs[i]; ++ return CKR_OK; ++} ++ ++static int ++attributes_match(const struct st_object *obj, ++ const CK_ATTRIBUTE *attributes, ++ CK_ULONG num_attributes) ++{ ++ CK_ULONG i; ++ int j; ++ st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj)); ++ ++ for (i = 0; i < num_attributes; i++) { ++ int match = 0; ++ for (j = 0; j < obj->num_attributes; j++) { ++ if (attributes[i].type == obj->attrs[j].attribute.type && ++ attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen && ++ memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue, ++ attributes[i].ulValueLen) == 0) { ++ match = 1; ++ break; ++ } ++ } ++ if (match == 0) { ++ st_logf("type %d attribute have no match\n", attributes[i].type); ++ return 0; ++ } ++ } ++ st_logf("attribute matches\n"); ++ return 1; ++} ++ ++static void ++print_attributes(const CK_ATTRIBUTE *attributes, ++ CK_ULONG num_attributes) ++{ ++ CK_ULONG i; ++ ++ st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes); ++ ++ for (i = 0; i < num_attributes; i++) { ++ st_logf(" type: "); ++ switch (attributes[i].type) { ++ case CKA_TOKEN: { ++ CK_BBOOL *ck_true; ++ if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) { ++ application_error("token attribute wrong length\n"); ++ break; ++ } ++ ck_true = attributes[i].pValue; ++ st_logf("token: %s", *ck_true ? "TRUE" : "FALSE"); ++ break; ++ } ++ case CKA_CLASS: { ++ CK_OBJECT_CLASS *class; ++ if (attributes[i].ulValueLen != sizeof(CK_ULONG)) { ++ application_error("class attribute wrong length\n"); ++ break; ++ } ++ class = attributes[i].pValue; ++ st_logf("class "); ++ switch (*class) { ++ case CKO_CERTIFICATE: ++ st_logf("certificate"); ++ break; ++ case CKO_PUBLIC_KEY: ++ st_logf("public key"); ++ break; ++ case CKO_PRIVATE_KEY: ++ st_logf("private key"); ++ break; ++ case CKO_SECRET_KEY: ++ st_logf("secret key"); ++ break; ++ case CKO_DOMAIN_PARAMETERS: ++ st_logf("domain parameters"); ++ break; ++ default: ++ st_logf("[class %lx]", (long unsigned)*class); ++ break; ++ } ++ break; ++ } ++ case CKA_PRIVATE: ++ st_logf("private"); ++ break; ++ case CKA_LABEL: ++ st_logf("label"); ++ break; ++ case CKA_APPLICATION: ++ st_logf("application"); ++ break; ++ case CKA_VALUE: ++ st_logf("value"); ++ break; ++ case CKA_ID: ++ st_logf("id"); ++ break; ++ default: ++ st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type); ++ break; ++ } ++ st_logf("\n"); ++ } ++} ++ ++static struct st_object * ++add_st_object(void) ++{ ++ struct st_object *o, **objs; ++ int i; ++ ++ o = malloc(sizeof(*o)); ++ if (o == NULL) ++ return NULL; ++ memset(o, 0, sizeof(*o)); ++ o->attrs = NULL; ++ o->num_attributes = 0; ++ ++ for (i = 0; i < soft_token.object.num_objs; i++) { ++ if (soft_token.object.objs == NULL) { ++ soft_token.object.objs[i] = o; ++ break; ++ } ++ } ++ if (i == soft_token.object.num_objs) { ++ objs = realloc(soft_token.object.objs, ++ (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0])); ++ if (objs == NULL) { ++ free(o); ++ return NULL; ++ } ++ soft_token.object.objs = objs; ++ soft_token.object.objs[soft_token.object.num_objs++] = o; ++ } ++ soft_token.object.objs[i]->object_handle = ++ (random() & (~OBJECT_ID_MASK)) | i; ++ ++ return o; ++} ++ ++static CK_RV ++add_object_attribute(struct st_object *o, ++ int secret, ++ CK_ATTRIBUTE_TYPE type, ++ CK_VOID_PTR pValue, ++ CK_ULONG ulValueLen) ++{ ++ struct st_attr *a; ++ int i; ++ ++ i = o->num_attributes; ++ a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0])); ++ if (a == NULL) ++ return CKR_DEVICE_MEMORY; ++ o->attrs = a; ++ o->attrs[i].secret = secret; ++ o->attrs[i].attribute.type = type; ++ o->attrs[i].attribute.pValue = malloc(ulValueLen); ++ if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0) ++ return CKR_DEVICE_MEMORY; ++ memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen); ++ o->attrs[i].attribute.ulValueLen = ulValueLen; ++ o->num_attributes++; ++ ++ return CKR_OK; ++} ++ ++static CK_RV ++add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) ++{ ++ switch (key_type) { ++ case CKK_RSA: { ++ CK_BYTE *modulus = NULL; ++ size_t modulus_len = 0; ++ CK_ULONG modulus_bits = 0; ++ CK_BYTE *exponent = NULL; ++ size_t exponent_len = 0; ++ RSA* rsa = NULL; ++ const BIGNUM *n = NULL, *e = NULL; ++ ++ rsa = EVP_PKEY_get0_RSA(key); ++ RSA_get0_key(rsa, &n, &e, NULL); ++ ++ modulus_bits = BN_num_bits(n); ++ ++ modulus_len = BN_num_bytes(n); ++ modulus = malloc(modulus_len); ++ BN_bn2bin(n, modulus); ++ ++ exponent_len = BN_num_bytes(e); ++ exponent = malloc(exponent_len); ++ BN_bn2bin(e, exponent); ++ ++ add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); ++ add_object_attribute(o, 0, CKA_MODULUS_BITS, ++ &modulus_bits, sizeof(modulus_bits)); ++ add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, ++ exponent, exponent_len); ++ ++ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); ++ ++ free(modulus); ++ free(exponent); ++ } ++ default: ++ /* XXX */ ++ break; ++ } ++ return CKR_OK; ++} ++ ++ ++static int ++pem_callback(char *buf, int num, int w, void *key) ++{ ++ return -1; ++} ++ ++ ++static CK_RV ++add_certificate(char *label, ++ const char *cert_file, ++ const char *private_key_file, ++ char *id, ++ int anchor) ++{ ++ struct st_object *o = NULL; ++ CK_BBOOL bool_true = CK_TRUE; ++ CK_BBOOL bool_false = CK_FALSE; ++ CK_OBJECT_CLASS c; ++ CK_CERTIFICATE_TYPE cert_type = CKC_X_509; ++ CK_KEY_TYPE key_type; ++ CK_MECHANISM_TYPE mech_type; ++ void *cert_data = NULL; ++ size_t cert_length; ++ void *subject_data = NULL; ++ size_t subject_length; ++ void *issuer_data = NULL; ++ size_t issuer_length; ++ void *serial_data = NULL; ++ size_t serial_length; ++ CK_RV ret = CKR_GENERAL_ERROR; ++ X509 *cert; ++ EVP_PKEY *public_key; ++ ++ size_t id_len = strlen(id); ++ ++ { ++ FILE *f; ++ ++ f = fopen(cert_file, "r"); ++ if (f == NULL) { ++ st_logf("failed to open file %s\n", cert_file); ++ return CKR_GENERAL_ERROR; ++ } ++ ++ cert = PEM_read_X509(f, NULL, NULL, NULL); ++ fclose(f); ++ if (cert == NULL) { ++ st_logf("failed reading PEM cert\n"); ++ return CKR_GENERAL_ERROR; ++ } ++ ++ OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret); ++ if (ret) ++ goto out; ++ ++ OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length, ++ X509_get_issuer_name(cert), ret); ++ if (ret) ++ goto out; ++ ++ OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length, ++ X509_get_subject_name(cert), ret); ++ if (ret) ++ goto out; ++ ++ OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length, ++ X509_get_serialNumber(cert), ret); ++ if (ret) ++ goto out; ++ ++ } ++ ++ st_logf("done parsing, adding to internal structure\n"); ++ ++ o = add_st_object(); ++ if (o == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ o->type = STO_T_CERTIFICATE; ++ o->u.cert = cert; ++ public_key = X509_get_pubkey(o->u.cert); ++ ++ switch (EVP_PKEY_base_id(public_key)) { ++ case EVP_PKEY_RSA: ++ key_type = CKK_RSA; ++ break; ++ case EVP_PKEY_DSA: ++ key_type = CKK_DSA; ++ break; ++ default: ++ /* XXX */ ++ break; ++ } ++ ++ c = CKO_CERTIFICATE; ++ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); ++ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); ++ ++ add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); ++ add_object_attribute(o, 0, CKA_ID, id, id_len); ++ ++ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); ++ add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length); ++ add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length); ++ add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length); ++ if (anchor) ++ add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); ++ else ++ add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); ++ ++ st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); ++ ++ o = add_st_object(); ++ if (o == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ o->type = STO_T_PUBLIC_KEY; ++ o->u.public_key = public_key; ++ ++ c = CKO_PUBLIC_KEY; ++ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); ++ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); ++ ++ add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); ++ add_object_attribute(o, 0, CKA_ID, id, id_len); ++ add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ ++ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ ++ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); ++ mech_type = CKM_RSA_X_509; ++ add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); ++ ++ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); ++ add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); ++ ++ add_pubkey_info(o, key_type, public_key); ++ ++ st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); ++ ++ if (private_key_file) { ++ CK_FLAGS flags; ++ FILE *f; ++ ++ o = add_st_object(); ++ if (o == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ o->type = STO_T_PRIVATE_KEY; ++ o->u.private_key.file = strdup(private_key_file); ++ o->u.private_key.key = NULL; ++ ++ o->u.private_key.cert = cert; ++ ++ c = CKO_PRIVATE_KEY; ++ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); ++ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); ++ ++ add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); ++ add_object_attribute(o, 0, CKA_ID, id, id_len); ++ add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ ++ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ ++ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); ++ mech_type = CKM_RSA_X_509; ++ add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); ++ ++ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); ++ add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); ++ flags = 0; ++ add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); ++ ++ add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); ++ add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); ++ add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); ++ ++ add_pubkey_info(o, key_type, public_key); ++ ++ f = fopen(private_key_file, "r"); ++ if (f == NULL) { ++ st_logf("failed to open private key\n"); ++ return CKR_GENERAL_ERROR; ++ } ++ ++ o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL); ++ fclose(f); ++ if (o->u.private_key.key == NULL) { ++ st_logf("failed to read private key a startup\n"); ++ /* don't bother with this failure for now, ++ fix it at C_Login time */; ++ } else { ++ /* XXX verify keytype */ ++ ++ if (key_type == CKK_RSA) { ++ RSA *rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); ++ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); ++ } ++ ++ if (X509_check_private_key(cert, o->u.private_key.key) != 1) { ++ EVP_PKEY_free(o->u.private_key.key); ++ o->u.private_key.key = NULL; ++ st_logf("private key doesn't verify\n"); ++ } else { ++ st_logf("private key usable\n"); ++ soft_token.flags.login_done = 1; ++ } ++ } ++ } ++ ++ ret = CKR_OK; ++ out: ++ if (ret != CKR_OK) { ++ st_logf("something went wrong when adding cert!\n"); ++ ++ /* XXX wack o */; ++ } ++ free(cert_data); ++ free(serial_data); ++ free(issuer_data); ++ free(subject_data); ++ ++ return ret; ++} ++ ++static void ++find_object_final(struct session_state *state) ++{ ++ if (state->find.attributes) { ++ CK_ULONG i; ++ ++ for (i = 0; i < state->find.num_attributes; i++) { ++ if (state->find.attributes[i].pValue) ++ free(state->find.attributes[i].pValue); ++ } ++ free(state->find.attributes); ++ state->find.attributes = NULL; ++ state->find.num_attributes = 0; ++ state->find.next_object = -1; ++ } ++} ++ ++static void ++reset_crypto_state(struct session_state *state) ++{ ++ state->encrypt_object = -1; ++ if (state->encrypt_mechanism) ++ free(state->encrypt_mechanism); ++ state->encrypt_mechanism = NULL_PTR; ++ state->decrypt_object = -1; ++ if (state->decrypt_mechanism) ++ free(state->decrypt_mechanism); ++ state->decrypt_mechanism = NULL_PTR; ++ state->sign_object = -1; ++ if (state->sign_mechanism) ++ free(state->sign_mechanism); ++ state->sign_mechanism = NULL_PTR; ++ state->verify_object = -1; ++ if (state->verify_mechanism) ++ free(state->verify_mechanism); ++ state->verify_mechanism = NULL_PTR; ++ state->digest_object = -1; ++} ++ ++static void ++close_session(struct session_state *state) ++{ ++ if (state->find.attributes) { ++ application_error("application didn't do C_FindObjectsFinal\n"); ++ find_object_final(state); ++ } ++ ++ state->session_handle = CK_INVALID_HANDLE; ++ soft_token.application = NULL_PTR; ++ soft_token.notify = NULL_PTR; ++ reset_crypto_state(state); ++} ++ ++static const char * ++has_session(void) ++{ ++ return soft_token.open_sessions > 0 ? "yes" : "no"; ++} ++ ++static void ++read_conf_file(const char *fn) ++{ ++ char buf[1024], *cert, *key, *id, *label, *s, *p; ++ int anchor; ++ FILE *f; ++ ++ f = fopen(fn, "r"); ++ if (f == NULL) { ++ st_logf("can't open configuration file %s\n", fn); ++ return; ++ } ++ ++ while(fgets(buf, sizeof(buf), f) != NULL) { ++ buf[strcspn(buf, "\n")] = '\0'; ++ ++ anchor = 0; ++ ++ st_logf("line: %s\n", buf); ++ ++ p = buf; ++ while (isspace(*p)) ++ p++; ++ if (*p == '#') ++ continue; ++ while (isspace(*p)) ++ p++; ++ ++ s = NULL; ++ id = strtok_r(p, "\t", &s); ++ if (id == NULL) ++ continue; ++ label = strtok_r(NULL, "\t", &s); ++ if (label == NULL) ++ continue; ++ cert = strtok_r(NULL, "\t", &s); ++ if (cert == NULL) ++ continue; ++ key = strtok_r(NULL, "\t", &s); ++ ++ /* XXX */ ++ if (strcmp(id, "anchor") == 0) { ++ id = "\x00\x00"; ++ anchor = 1; ++ } ++ ++ st_logf("adding: %s\n", label); ++ ++ add_certificate(label, cert, key, id, anchor); ++ } ++} ++ ++static CK_RV ++func_not_supported(void) ++{ ++ st_logf("function not supported\n"); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_Initialize(CK_VOID_PTR a) ++{ ++ CK_C_INITIALIZE_ARGS_PTR args = a; ++ st_logf("Initialize\n"); ++ size_t i; ++ ++ OpenSSL_add_all_algorithms(); ++ ERR_load_crypto_strings(); ++ ++ srandom(getpid() ^ time(NULL)); ++ ++ for (i = 0; i < MAX_NUM_SESSION; i++) { ++ soft_token.state[i].session_handle = CK_INVALID_HANDLE; ++ soft_token.state[i].find.attributes = NULL; ++ soft_token.state[i].find.num_attributes = 0; ++ soft_token.state[i].find.next_object = -1; ++ reset_crypto_state(&soft_token.state[i]); ++ } ++ ++ soft_token.flags.hardware_slot = 1; ++ soft_token.flags.app_error_fatal = 0; ++ soft_token.flags.login_done = 0; ++ ++ soft_token.object.objs = NULL; ++ soft_token.object.num_objs = 0; ++ ++ soft_token.logfile = NULL; ++#if 1 ++// soft_token.logfile = stdout; ++#endif ++#if 0 ++ soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a"); ++#endif ++ ++ if (a != NULL_PTR) { ++ st_logf("\tCreateMutex:\t%p\n", args->CreateMutex); ++ st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex); ++ st_logf("\tLockMutext\t%p\n", args->LockMutex); ++ st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex); ++ st_logf("\tFlags\t%04x\n", (unsigned int)args->flags); ++ } ++ ++ { ++ char *fn = NULL, *home = NULL; ++ ++ if (getuid() == geteuid()) { ++ fn = getenv("SOFTPKCS11RC"); ++ if (fn) ++ fn = strdup(fn); ++ home = getenv("HOME"); ++ } ++ if (fn == NULL && home == NULL) { ++ struct passwd *pw = getpwuid(getuid()); ++ if(pw != NULL) ++ home = pw->pw_dir; ++ } ++ if (fn == NULL) { ++ if (home) ++ asprintf(&fn, "%s/.soft-token.rc", home); ++ else ++ fn = strdup("/etc/soft-token.rc"); ++ } ++ ++ read_conf_file(fn); ++ free(fn); ++ } ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_Finalize(CK_VOID_PTR args) ++{ ++ size_t i; ++ ++ st_logf("Finalize\n"); ++ ++ for (i = 0; i < MAX_NUM_SESSION; i++) { ++ if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) { ++ application_error("application finalized without " ++ "closing session\n"); ++ close_session(&soft_token.state[i]); ++ } ++ } ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetInfo(CK_INFO_PTR args) ++{ ++ st_logf("GetInfo\n"); ++ ++ memset(args, 17, sizeof(*args)); ++ args->cryptokiVersion.major = 2; ++ args->cryptokiVersion.minor = 10; ++ snprintf_fill((char *)args->manufacturerID, ++ sizeof(args->manufacturerID), ++ ' ', ++ "SoftToken"); ++ snprintf_fill((char *)args->libraryDescription, ++ sizeof(args->libraryDescription), ' ', ++ "SoftToken"); ++ args->libraryVersion.major = 1; ++ args->libraryVersion.minor = 8; ++ ++ return CKR_OK; ++} ++ ++extern CK_FUNCTION_LIST funcs; ++ ++CK_RV ++C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) ++{ ++ *ppFunctionList = &funcs; ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetSlotList(CK_BBOOL tokenPresent, ++ CK_SLOT_ID_PTR pSlotList, ++ CK_ULONG_PTR pulCount) ++{ ++ st_logf("GetSlotList: %s\n", ++ tokenPresent ? "tokenPresent" : "token not Present"); ++ if (pSlotList) ++ pSlotList[0] = 1; ++ *pulCount = 1; ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetSlotInfo(CK_SLOT_ID slotID, ++ CK_SLOT_INFO_PTR pInfo) ++{ ++ st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session()); ++ ++ memset(pInfo, 18, sizeof(*pInfo)); ++ ++ if (slotID != 1) ++ return CKR_ARGUMENTS_BAD; ++ ++ snprintf_fill((char *)pInfo->slotDescription, ++ sizeof(pInfo->slotDescription), ++ ' ', ++ "SoftToken (slot)"); ++ snprintf_fill((char *)pInfo->manufacturerID, ++ sizeof(pInfo->manufacturerID), ++ ' ', ++ "SoftToken (slot)"); ++ pInfo->flags = CKF_TOKEN_PRESENT; ++ if (soft_token.flags.hardware_slot) ++ pInfo->flags |= CKF_HW_SLOT; ++ pInfo->hardwareVersion.major = 1; ++ pInfo->hardwareVersion.minor = 0; ++ pInfo->firmwareVersion.major = 1; ++ pInfo->firmwareVersion.minor = 0; ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetTokenInfo(CK_SLOT_ID slotID, ++ CK_TOKEN_INFO_PTR pInfo) ++{ ++ st_logf("GetTokenInfo: %s\n", has_session()); ++ ++ memset(pInfo, 19, sizeof(*pInfo)); ++ ++ snprintf_fill((char *)pInfo->label, ++ sizeof(pInfo->label), ++ ' ', ++ "SoftToken (token)"); ++ snprintf_fill((char *)pInfo->manufacturerID, ++ sizeof(pInfo->manufacturerID), ++ ' ', ++ "SoftToken (token)"); ++ snprintf_fill((char *)pInfo->model, ++ sizeof(pInfo->model), ++ ' ', ++ "SoftToken (token)"); ++ snprintf_fill((char *)pInfo->serialNumber, ++ sizeof(pInfo->serialNumber), ++ ' ', ++ "4711"); ++ pInfo->flags = ++ CKF_TOKEN_INITIALIZED | ++ CKF_USER_PIN_INITIALIZED; ++ ++ if (soft_token.flags.login_done == 0) ++ pInfo->flags |= CKF_LOGIN_REQUIRED; ++ ++ /* CFK_RNG | ++ CKF_RESTORE_KEY_NOT_NEEDED | ++ */ ++ pInfo->ulMaxSessionCount = MAX_NUM_SESSION; ++ pInfo->ulSessionCount = soft_token.open_sessions; ++ pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION; ++ pInfo->ulRwSessionCount = soft_token.open_sessions; ++ pInfo->ulMaxPinLen = 1024; ++ pInfo->ulMinPinLen = 0; ++ pInfo->ulTotalPublicMemory = 4711; ++ pInfo->ulFreePublicMemory = 4712; ++ pInfo->ulTotalPrivateMemory = 4713; ++ pInfo->ulFreePrivateMemory = 4714; ++ pInfo->hardwareVersion.major = 2; ++ pInfo->hardwareVersion.minor = 0; ++ pInfo->firmwareVersion.major = 2; ++ pInfo->firmwareVersion.minor = 0; ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetMechanismList(CK_SLOT_ID slotID, ++ CK_MECHANISM_TYPE_PTR pMechanismList, ++ CK_ULONG_PTR pulCount) ++{ ++ st_logf("GetMechanismList\n"); ++ ++ *pulCount = 2; ++ if (pMechanismList == NULL_PTR) ++ return CKR_OK; ++ pMechanismList[0] = CKM_RSA_X_509; ++ pMechanismList[1] = CKM_RSA_PKCS; ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetMechanismInfo(CK_SLOT_ID slotID, ++ CK_MECHANISM_TYPE type, ++ CK_MECHANISM_INFO_PTR pInfo) ++{ ++ st_logf("GetMechanismInfo: slot %d type: %d\n", ++ (int)slotID, (int)type); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_InitToken(CK_SLOT_ID slotID, ++ CK_UTF8CHAR_PTR pPin, ++ CK_ULONG ulPinLen, ++ CK_UTF8CHAR_PTR pLabel) ++{ ++ st_logf("InitToken: slot %d\n", (int)slotID); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_OpenSession(CK_SLOT_ID slotID, ++ CK_FLAGS flags, ++ CK_VOID_PTR pApplication, ++ CK_NOTIFY Notify, ++ CK_SESSION_HANDLE_PTR phSession) ++{ ++ size_t i; ++ ++ st_logf("OpenSession: slot: %d\n", (int)slotID); ++ ++ if (soft_token.open_sessions == MAX_NUM_SESSION) ++ return CKR_SESSION_COUNT; ++ ++ soft_token.application = pApplication; ++ soft_token.notify = Notify; ++ ++ for (i = 0; i < MAX_NUM_SESSION; i++) ++ if (soft_token.state[i].session_handle == CK_INVALID_HANDLE) ++ break; ++ if (i == MAX_NUM_SESSION) ++ abort(); ++ ++ soft_token.open_sessions++; ++ ++ soft_token.state[i].session_handle = ++ (CK_SESSION_HANDLE)(random() & 0xfffff); ++ *phSession = soft_token.state[i].session_handle; ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_CloseSession(CK_SESSION_HANDLE hSession) ++{ ++ struct session_state *state; ++ st_logf("CloseSession\n"); ++ ++ if (verify_session_handle(hSession, &state) != CKR_OK) ++ application_error("closed session not open"); ++ else ++ close_session(state); ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_CloseAllSessions(CK_SLOT_ID slotID) ++{ ++ size_t i; ++ ++ st_logf("CloseAllSessions\n"); ++ ++ for (i = 0; i < MAX_NUM_SESSION; i++) ++ if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) ++ close_session(&soft_token.state[i]); ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_GetSessionInfo(CK_SESSION_HANDLE hSession, ++ CK_SESSION_INFO_PTR pInfo) ++{ ++ st_logf("GetSessionInfo\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ ++ memset(pInfo, 20, sizeof(*pInfo)); ++ ++ pInfo->slotID = 1; ++ if (soft_token.flags.login_done) ++ pInfo->state = CKS_RO_USER_FUNCTIONS; ++ else ++ pInfo->state = CKS_RO_PUBLIC_SESSION; ++ pInfo->flags = CKF_SERIAL_SESSION; ++ pInfo->ulDeviceError = 0; ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_Login(CK_SESSION_HANDLE hSession, ++ CK_USER_TYPE userType, ++ CK_UTF8CHAR_PTR pPin, ++ CK_ULONG ulPinLen) ++{ ++ char *pin = NULL; ++ int i; ++ ++ st_logf("Login\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ ++ if (pPin != NULL_PTR) { ++ asprintf(&pin, "%.*s", (int)ulPinLen, pPin); ++ st_logf("type: %d password: %s\n", (int)userType, pin); ++ } ++ ++ for (i = 0; i < soft_token.object.num_objs; i++) { ++ struct st_object *o = soft_token.object.objs[i]; ++ FILE *f; ++ ++ if (o->type != STO_T_PRIVATE_KEY) ++ continue; ++ ++ if (o->u.private_key.key) ++ continue; ++ ++ f = fopen(o->u.private_key.file, "r"); ++ if (f == NULL) { ++ st_logf("can't open private file: %s\n", o->u.private_key.file); ++ continue; ++ } ++ ++ o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin); ++ fclose(f); ++ if (o->u.private_key.key == NULL) { ++ st_logf("failed to read key: %s error: %s\n", ++ o->u.private_key.file, ++ ERR_error_string(ERR_get_error(), NULL)); ++ /* just ignore failure */; ++ continue; ++ } ++ ++ /* XXX check keytype */ ++ RSA *rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); ++ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); ++ ++ if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) { ++ EVP_PKEY_free(o->u.private_key.key); ++ o->u.private_key.key = NULL; ++ st_logf("private key %s doesn't verify\n", o->u.private_key.file); ++ continue; ++ } ++ ++ soft_token.flags.login_done = 1; ++ } ++ free(pin); ++ ++ return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT; ++} ++ ++CK_RV ++C_Logout(CK_SESSION_HANDLE hSession) ++{ ++ st_logf("Logout\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_GetObjectSize(CK_SESSION_HANDLE hSession, ++ CK_OBJECT_HANDLE hObject, ++ CK_ULONG_PTR pulSize) ++{ ++ st_logf("GetObjectSize\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_GetAttributeValue(CK_SESSION_HANDLE hSession, ++ CK_OBJECT_HANDLE hObject, ++ CK_ATTRIBUTE_PTR pTemplate, ++ CK_ULONG ulCount) ++{ ++ struct session_state *state; ++ struct st_object *obj; ++ CK_ULONG i; ++ CK_RV ret; ++ int j; ++ ++ st_logf("GetAttributeValue: %lx\n", ++ (unsigned long)HANDLE_OBJECT_ID(hObject)); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) { ++ st_logf("object not found: %lx\n", ++ (unsigned long)HANDLE_OBJECT_ID(hObject)); ++ return ret; ++ } ++ ++ ret = CKR_OK; ++ for (i = 0; i < ulCount; i++) { ++ st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type); ++ for (j = 0; j < obj->num_attributes; j++) { ++ if (obj->attrs[j].secret) { ++ pTemplate[i].ulValueLen = (CK_ULONG)-1; ++ break; ++ } ++ if (pTemplate[i].type == obj->attrs[j].attribute.type) { ++ if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) { ++ if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen) ++ memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue, ++ obj->attrs[j].attribute.ulValueLen); ++ } ++ pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen; ++ break; ++ } ++ } ++ if (j == obj->num_attributes) { ++ st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type); ++ pTemplate[i].ulValueLen = (CK_ULONG)-1; ++ ret = CKR_ATTRIBUTE_TYPE_INVALID; ++ } ++ ++ } ++ return ret; ++} ++ ++CK_RV ++C_FindObjectsInit(CK_SESSION_HANDLE hSession, ++ CK_ATTRIBUTE_PTR pTemplate, ++ CK_ULONG ulCount) ++{ ++ struct session_state *state; ++ ++ st_logf("FindObjectsInit\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->find.next_object != -1) { ++ application_error("application didn't do C_FindObjectsFinal\n"); ++ find_object_final(state); ++ } ++ if (ulCount) { ++ CK_ULONG i; ++ ++ print_attributes(pTemplate, ulCount); ++ ++ state->find.attributes = ++ calloc(1, ulCount * sizeof(state->find.attributes[0])); ++ if (state->find.attributes == NULL) ++ return CKR_DEVICE_MEMORY; ++ for (i = 0; i < ulCount; i++) { ++ state->find.attributes[i].pValue = ++ malloc(pTemplate[i].ulValueLen); ++ if (state->find.attributes[i].pValue == NULL) { ++ find_object_final(state); ++ return CKR_DEVICE_MEMORY; ++ } ++ memcpy(state->find.attributes[i].pValue, ++ pTemplate[i].pValue, pTemplate[i].ulValueLen); ++ state->find.attributes[i].type = pTemplate[i].type; ++ state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen; ++ } ++ state->find.num_attributes = ulCount; ++ state->find.next_object = 0; ++ } else { ++ st_logf("find all objects\n"); ++ state->find.attributes = NULL; ++ state->find.num_attributes = 0; ++ state->find.next_object = 0; ++ } ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_FindObjects(CK_SESSION_HANDLE hSession, ++ CK_OBJECT_HANDLE_PTR phObject, ++ CK_ULONG ulMaxObjectCount, ++ CK_ULONG_PTR pulObjectCount) ++{ ++ struct session_state *state; ++ int i; ++ ++ st_logf("FindObjects\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->find.next_object == -1) { ++ application_error("application didn't do C_FindObjectsInit\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ if (ulMaxObjectCount == 0) { ++ application_error("application asked for 0 objects\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ *pulObjectCount = 0; ++ for (i = state->find.next_object; i < soft_token.object.num_objs; i++) { ++ st_logf("FindObjects: %d\n", i); ++ state->find.next_object = i + 1; ++ if (attributes_match(soft_token.object.objs[i], ++ state->find.attributes, ++ state->find.num_attributes)) { ++ *phObject++ = soft_token.object.objs[i]->object_handle; ++ ulMaxObjectCount--; ++ (*pulObjectCount)++; ++ if (ulMaxObjectCount == 0) ++ break; ++ } ++ } ++ return CKR_OK; ++} ++ ++CK_RV ++C_FindObjectsFinal(CK_SESSION_HANDLE hSession) ++{ ++ struct session_state *state; ++ ++ st_logf("FindObjectsFinal\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ find_object_final(state); ++ return CKR_OK; ++} ++ ++static CK_RV ++commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len, ++ const CK_MECHANISM_TYPE *mechs, int mechs_len, ++ const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, ++ struct st_object **o) ++{ ++ CK_RV ret; ++ int i; ++ ++ *o = NULL; ++ if ((ret = object_handle_to_object(hKey, o)) != CKR_OK) ++ return ret; ++ ++ ret = attributes_match(*o, attr_match, attr_match_len); ++ if (!ret) { ++ application_error("called commonInit on key that doesn't " ++ "support required attr"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ for (i = 0; i < mechs_len; i++) ++ if (mechs[i] == pMechanism->mechanism) ++ break; ++ if (i == mechs_len) { ++ application_error("called mech (%08lx) not supported\n", ++ pMechanism->mechanism); ++ return CKR_ARGUMENTS_BAD; ++ } ++ return CKR_OK; ++} ++ ++ ++static CK_RV ++dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism) ++{ ++ CK_MECHANISM_PTR p; ++ ++ p = malloc(sizeof(*p)); ++ if (p == NULL) ++ return CKR_DEVICE_MEMORY; ++ ++ if (*dup) ++ free(*dup); ++ *dup = p; ++ memcpy(p, pMechanism, sizeof(*p)); ++ ++ return CKR_OK; ++} ++ ++ ++CK_RV ++C_EncryptInit(CK_SESSION_HANDLE hSession, ++ CK_MECHANISM_PTR pMechanism, ++ CK_OBJECT_HANDLE hKey) ++{ ++ struct session_state *state; ++ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; ++ CK_BBOOL bool_true = CK_TRUE; ++ CK_ATTRIBUTE attr[] = { ++ { CKA_ENCRYPT, &bool_true, sizeof(bool_true) } ++ }; ++ struct st_object *o; ++ CK_RV ret; ++ ++ st_logf("EncryptInit\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), ++ mechs, sizeof(mechs)/sizeof(mechs[0]), ++ pMechanism, hKey, &o); ++ if (ret) ++ return ret; ++ ++ ret = dup_mechanism(&state->encrypt_mechanism, pMechanism); ++ if (ret == CKR_OK) ++ state->encrypt_object = OBJECT_ID(o); ++ ++ return ret; ++} ++ ++CK_RV ++C_Encrypt(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pData, ++ CK_ULONG ulDataLen, ++ CK_BYTE_PTR pEncryptedData, ++ CK_ULONG_PTR pulEncryptedDataLen) ++{ ++ struct session_state *state; ++ struct st_object *o; ++ void *buffer = NULL; ++ CK_RV ret; ++ RSA *rsa; ++ int padding, len, buffer_len, padding_len; ++ ++ st_logf("Encrypt\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->encrypt_object == -1) ++ return CKR_ARGUMENTS_BAD; ++ ++ o = soft_token.object.objs[state->encrypt_object]; ++ ++ if (o->u.public_key == NULL) { ++ st_logf("public key NULL\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ rsa = EVP_PKEY_get0_RSA(o->u.public_key); ++ if (rsa == NULL) ++ return CKR_ARGUMENTS_BAD; ++ ++ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ ++ ++ buffer_len = RSA_size(rsa); ++ ++ buffer = malloc(buffer_len); ++ if (buffer == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ ++ ret = CKR_OK; ++ switch(state->encrypt_mechanism->mechanism) { ++ case CKM_RSA_PKCS: ++ padding = RSA_PKCS1_PADDING; ++ padding_len = RSA_PKCS1_PADDING_SIZE; ++ break; ++ case CKM_RSA_X_509: ++ padding = RSA_NO_PADDING; ++ padding_len = 0; ++ break; ++ default: ++ ret = CKR_FUNCTION_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ if (buffer_len + padding_len < (long) ulDataLen) { ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pulEncryptedDataLen == NULL) { ++ st_logf("pulEncryptedDataLen NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pData == NULL_PTR) { ++ st_logf("data NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding); ++ if (len <= 0) { ++ ret = CKR_DEVICE_ERROR; ++ goto out; ++ } ++ if (len > buffer_len) ++ abort(); ++ ++ if (pEncryptedData != NULL_PTR) ++ memcpy(pEncryptedData, buffer, len); ++ *pulEncryptedDataLen = len; ++ ++ out: ++ if (buffer) { ++ memset(buffer, 0, buffer_len); ++ free(buffer); ++ } ++ return ret; ++} ++ ++CK_RV ++C_EncryptUpdate(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pPart, ++ CK_ULONG ulPartLen, ++ CK_BYTE_PTR pEncryptedPart, ++ CK_ULONG_PTR pulEncryptedPartLen) ++{ ++ st_logf("EncryptUpdate\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++ ++CK_RV ++C_EncryptFinal(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pLastEncryptedPart, ++ CK_ULONG_PTR pulLastEncryptedPartLen) ++{ ++ st_logf("EncryptFinal\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++ ++/* C_DecryptInit initializes a decryption operation. */ ++CK_RV ++C_DecryptInit(CK_SESSION_HANDLE hSession, ++ CK_MECHANISM_PTR pMechanism, ++ CK_OBJECT_HANDLE hKey) ++{ ++ struct session_state *state; ++ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; ++ CK_BBOOL bool_true = CK_TRUE; ++ CK_ATTRIBUTE attr[] = { ++ { CKA_DECRYPT, &bool_true, sizeof(bool_true) } ++ }; ++ struct st_object *o; ++ CK_RV ret; ++ ++ st_logf("DecryptInit\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), ++ mechs, sizeof(mechs)/sizeof(mechs[0]), ++ pMechanism, hKey, &o); ++ if (ret) ++ return ret; ++ ++ ret = dup_mechanism(&state->decrypt_mechanism, pMechanism); ++ if (ret == CKR_OK) ++ state->decrypt_object = OBJECT_ID(o); ++ ++ return CKR_OK; ++} ++ ++ ++CK_RV ++C_Decrypt(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pEncryptedData, ++ CK_ULONG ulEncryptedDataLen, ++ CK_BYTE_PTR pData, ++ CK_ULONG_PTR pulDataLen) ++{ ++ struct session_state *state; ++ struct st_object *o; ++ void *buffer = NULL; ++ CK_RV ret; ++ RSA *rsa; ++ int padding, len, buffer_len, padding_len; ++ ++ st_logf("Decrypt\n"); ++ ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->decrypt_object == -1) ++ return CKR_ARGUMENTS_BAD; ++ ++ o = soft_token.object.objs[state->decrypt_object]; ++ ++ if (o->u.private_key.key == NULL) { ++ st_logf("private key NULL\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); ++ if (rsa == NULL) ++ return CKR_ARGUMENTS_BAD; ++ ++ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ ++ ++ buffer_len = RSA_size(rsa); ++ ++ buffer = malloc(buffer_len); ++ if (buffer == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ ++ ret = CKR_OK; ++ switch(state->decrypt_mechanism->mechanism) { ++ case CKM_RSA_PKCS: ++ padding = RSA_PKCS1_PADDING; ++ padding_len = RSA_PKCS1_PADDING_SIZE; ++ break; ++ case CKM_RSA_X_509: ++ padding = RSA_NO_PADDING; ++ padding_len = 0; ++ break; ++ default: ++ ret = CKR_FUNCTION_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ if (buffer_len + padding_len < (long) ulEncryptedDataLen) { ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pulDataLen == NULL) { ++ st_logf("pulDataLen NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pEncryptedData == NULL_PTR) { ++ st_logf("data NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer, ++ rsa, padding); ++ if (len <= 0) { ++ ret = CKR_DEVICE_ERROR; ++ goto out; ++ } ++ if (len > buffer_len) ++ abort(); ++ ++ if (pData != NULL_PTR) ++ memcpy(pData, buffer, len); ++ *pulDataLen = len; ++ ++ out: ++ if (buffer) { ++ memset(buffer, 0, buffer_len); ++ free(buffer); ++ } ++ return ret; ++} ++ ++ ++CK_RV ++C_DecryptUpdate(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pEncryptedPart, ++ CK_ULONG ulEncryptedPartLen, ++ CK_BYTE_PTR pPart, ++ CK_ULONG_PTR pulPartLen) ++ ++{ ++ st_logf("DecryptUpdate\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++ ++CK_RV ++C_DecryptFinal(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pLastPart, ++ CK_ULONG_PTR pulLastPartLen) ++{ ++ st_logf("DecryptFinal\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_DigestInit(CK_SESSION_HANDLE hSession, ++ CK_MECHANISM_PTR pMechanism) ++{ ++ st_logf("DigestInit\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_SignInit(CK_SESSION_HANDLE hSession, ++ CK_MECHANISM_PTR pMechanism, ++ CK_OBJECT_HANDLE hKey) ++{ ++ struct session_state *state; ++ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; ++ CK_BBOOL bool_true = CK_TRUE; ++ CK_ATTRIBUTE attr[] = { ++ { CKA_SIGN, &bool_true, sizeof(bool_true) } ++ }; ++ struct st_object *o; ++ CK_RV ret; ++ ++ st_logf("SignInit\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), ++ mechs, sizeof(mechs)/sizeof(mechs[0]), ++ pMechanism, hKey, &o); ++ if (ret) ++ return ret; ++ ++ ret = dup_mechanism(&state->sign_mechanism, pMechanism); ++ if (ret == CKR_OK) ++ state->sign_object = OBJECT_ID(o); ++ ++ return CKR_OK; ++} ++ ++CK_RV ++C_Sign(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pData, ++ CK_ULONG ulDataLen, ++ CK_BYTE_PTR pSignature, ++ CK_ULONG_PTR pulSignatureLen) ++{ ++ struct session_state *state; ++ struct st_object *o; ++ void *buffer = NULL; ++ CK_RV ret; ++ RSA *rsa; ++ int padding, len, buffer_len; ++ size_t padding_len; ++ ++ st_logf("Sign\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->sign_object == -1) ++ return CKR_ARGUMENTS_BAD; ++ ++ o = soft_token.object.objs[state->sign_object]; ++ ++ if (o->u.private_key.key == NULL) { ++ st_logf("private key NULL\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); ++ if (rsa == NULL) ++ return CKR_ARGUMENTS_BAD; ++ ++ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ ++ ++ buffer_len = RSA_size(rsa); ++ ++ buffer = malloc(buffer_len); ++ if (buffer == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ ++ switch(state->sign_mechanism->mechanism) { ++ case CKM_RSA_PKCS: ++ padding = RSA_PKCS1_PADDING; ++ padding_len = RSA_PKCS1_PADDING_SIZE; ++ break; ++ case CKM_RSA_X_509: ++ padding = RSA_NO_PADDING; ++ padding_len = 0; ++ break; ++ default: ++ ret = CKR_FUNCTION_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ if ((size_t) buffer_len < ulDataLen + padding_len) { ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pulSignatureLen == NULL) { ++ st_logf("signature len NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pData == NULL_PTR) { ++ st_logf("data NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding); ++ st_logf("private encrypt done\n"); ++ if (len <= 0) { ++ ret = CKR_DEVICE_ERROR; ++ goto out; ++ } ++ if (len > buffer_len) ++ abort(); ++ ++ if (pSignature != NULL_PTR) ++ memcpy(pSignature, buffer, len); ++ *pulSignatureLen = len; ++ ++ ret = CKR_OK; ++ ++ out: ++ if (buffer) { ++ memset(buffer, 0, buffer_len); ++ free(buffer); ++ } ++ return ret; ++} ++ ++CK_RV ++C_SignUpdate(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pPart, ++ CK_ULONG ulPartLen) ++{ ++ st_logf("SignUpdate\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++ ++CK_RV ++C_SignFinal(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pSignature, ++ CK_ULONG_PTR pulSignatureLen) ++{ ++ st_logf("SignUpdate\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_VerifyInit(CK_SESSION_HANDLE hSession, ++ CK_MECHANISM_PTR pMechanism, ++ CK_OBJECT_HANDLE hKey) ++{ ++ struct session_state *state; ++ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; ++ CK_BBOOL bool_true = CK_TRUE; ++ CK_ATTRIBUTE attr[] = { ++ { CKA_VERIFY, &bool_true, sizeof(bool_true) } ++ }; ++ struct st_object *o; ++ CK_RV ret; ++ ++ st_logf("VerifyInit\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), ++ mechs, sizeof(mechs)/sizeof(mechs[0]), ++ pMechanism, hKey, &o); ++ if (ret) ++ return ret; ++ ++ ret = dup_mechanism(&state->verify_mechanism, pMechanism); ++ if (ret == CKR_OK) ++ state->verify_object = OBJECT_ID(o); ++ ++ return ret; ++} ++ ++CK_RV ++C_Verify(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pData, ++ CK_ULONG ulDataLen, ++ CK_BYTE_PTR pSignature, ++ CK_ULONG ulSignatureLen) ++{ ++ struct session_state *state; ++ struct st_object *o; ++ void *buffer = NULL; ++ CK_RV ret; ++ RSA *rsa; ++ int padding, len, buffer_len; ++ ++ st_logf("Verify\n"); ++ VERIFY_SESSION_HANDLE(hSession, &state); ++ ++ if (state->verify_object == -1) ++ return CKR_ARGUMENTS_BAD; ++ ++ o = soft_token.object.objs[state->verify_object]; ++ ++ if (o->u.public_key == NULL) { ++ st_logf("public key NULL\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ rsa = EVP_PKEY_get0_RSA(o->u.public_key); ++ if (rsa == NULL) ++ return CKR_ARGUMENTS_BAD; ++ ++ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ ++ ++ buffer_len = RSA_size(rsa); ++ ++ buffer = malloc(buffer_len); ++ if (buffer == NULL) { ++ ret = CKR_DEVICE_MEMORY; ++ goto out; ++ } ++ ++ ret = CKR_OK; ++ switch(state->verify_mechanism->mechanism) { ++ case CKM_RSA_PKCS: ++ padding = RSA_PKCS1_PADDING; ++ break; ++ case CKM_RSA_X_509: ++ padding = RSA_NO_PADDING; ++ break; ++ default: ++ ret = CKR_FUNCTION_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ if (buffer_len < (long) ulDataLen) { ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pSignature == NULL) { ++ st_logf("signature NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ if (pData == NULL_PTR) { ++ st_logf("data NULL\n"); ++ ret = CKR_ARGUMENTS_BAD; ++ goto out; ++ } ++ ++ len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding); ++ st_logf("private encrypt done\n"); ++ if (len <= 0) { ++ ret = CKR_DEVICE_ERROR; ++ goto out; ++ } ++ if (len > buffer_len) ++ abort(); ++ ++ if ((size_t) len != ulSignatureLen) { ++ ret = CKR_GENERAL_ERROR; ++ goto out; ++ } ++ ++ if (memcmp(pSignature, buffer, len) != 0) { ++ ret = CKR_GENERAL_ERROR; ++ goto out; ++ } ++ ++ out: ++ if (buffer) { ++ memset(buffer, 0, buffer_len); ++ free(buffer); ++ } ++ return ret; ++} ++ ++ ++CK_RV ++C_VerifyUpdate(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pPart, ++ CK_ULONG ulPartLen) ++{ ++ st_logf("VerifyUpdate\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_VerifyFinal(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR pSignature, ++ CK_ULONG ulSignatureLen) ++{ ++ st_logf("VerifyFinal\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++CK_RV ++C_GenerateRandom(CK_SESSION_HANDLE hSession, ++ CK_BYTE_PTR RandomData, ++ CK_ULONG ulRandomLen) ++{ ++ st_logf("GenerateRandom\n"); ++ VERIFY_SESSION_HANDLE(hSession, NULL); ++ return CKR_FUNCTION_NOT_SUPPORTED; ++} ++ ++ ++CK_FUNCTION_LIST funcs = { ++ { 2, 11 }, ++ C_Initialize, ++ C_Finalize, ++ C_GetInfo, ++ C_GetFunctionList, ++ C_GetSlotList, ++ C_GetSlotInfo, ++ C_GetTokenInfo, ++ C_GetMechanismList, ++ C_GetMechanismInfo, ++ C_InitToken, ++ (void *)func_not_supported, /* C_InitPIN */ ++ (void *)func_not_supported, /* C_SetPIN */ ++ C_OpenSession, ++ C_CloseSession, ++ C_CloseAllSessions, ++ C_GetSessionInfo, ++ (void *)func_not_supported, /* C_GetOperationState */ ++ (void *)func_not_supported, /* C_SetOperationState */ ++ C_Login, ++ C_Logout, ++ (void *)func_not_supported, /* C_CreateObject */ ++ (void *)func_not_supported, /* C_CopyObject */ ++ (void *)func_not_supported, /* C_DestroyObject */ ++ (void *)func_not_supported, /* C_GetObjectSize */ ++ C_GetAttributeValue, ++ (void *)func_not_supported, /* C_SetAttributeValue */ ++ C_FindObjectsInit, ++ C_FindObjects, ++ C_FindObjectsFinal, ++ C_EncryptInit, ++ C_Encrypt, ++ C_EncryptUpdate, ++ C_EncryptFinal, ++ C_DecryptInit, ++ C_Decrypt, ++ C_DecryptUpdate, ++ C_DecryptFinal, ++ C_DigestInit, ++ (void *)func_not_supported, /* C_Digest */ ++ (void *)func_not_supported, /* C_DigestUpdate */ ++ (void *)func_not_supported, /* C_DigestKey */ ++ (void *)func_not_supported, /* C_DigestFinal */ ++ C_SignInit, ++ C_Sign, ++ C_SignUpdate, ++ C_SignFinal, ++ (void *)func_not_supported, /* C_SignRecoverInit */ ++ (void *)func_not_supported, /* C_SignRecover */ ++ C_VerifyInit, ++ C_Verify, ++ C_VerifyUpdate, ++ C_VerifyFinal, ++ (void *)func_not_supported, /* C_VerifyRecoverInit */ ++ (void *)func_not_supported, /* C_VerifyRecover */ ++ (void *)func_not_supported, /* C_DigestEncryptUpdate */ ++ (void *)func_not_supported, /* C_DecryptDigestUpdate */ ++ (void *)func_not_supported, /* C_SignEncryptUpdate */ ++ (void *)func_not_supported, /* C_DecryptVerifyUpdate */ ++ (void *)func_not_supported, /* C_GenerateKey */ ++ (void *)func_not_supported, /* C_GenerateKeyPair */ ++ (void *)func_not_supported, /* C_WrapKey */ ++ (void *)func_not_supported, /* C_UnwrapKey */ ++ (void *)func_not_supported, /* C_DeriveKey */ ++ (void *)func_not_supported, /* C_SeedRandom */ ++ C_GenerateRandom, ++ (void *)func_not_supported, /* C_GetFunctionStatus */ ++ (void *)func_not_supported, /* C_CancelFunction */ ++ (void *)func_not_supported /* C_WaitForSlotEvent */ ++}; +diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile +index e464b085..a0e5a37c 100644 +--- a/regress/unittests/Makefile ++++ b/regress/unittests/Makefile +@@ -2,6 +2,6 @@ + + REGRESS_FAIL_EARLY?= yes + SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion +-SUBDIR+=authopt ++SUBDIR+=pkcs11 authopt + + .include +diff --git a/regress/unittests/pkcs11/Makefile b/regress/unittests/pkcs11/Makefile +new file mode 100644 +index 00000000..481b13d0 +--- /dev/null ++++ b/regress/unittests/pkcs11/Makefile +@@ -0,0 +1,9 @@ ++ ++PROG=test_pkcs11 ++SRCS=tests.c ++REGRESS_TARGETS=run-regress-${PROG} ++ ++run-regress-${PROG}: ${PROG} ++ env ${TEST_ENV} ./${PROG} ++ ++.include +diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c +new file mode 100644 +index 00000000..e83aca54 +--- /dev/null ++++ b/regress/unittests/pkcs11/tests.c +@@ -0,0 +1,329 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#include ++#include ++ ++#include "../test_helper/test_helper.h" ++ ++#include "ssh-pkcs11-uri.h" ++ ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL) ++ ++/* prototypes are not public -- specify them here internally for tests */ ++struct sshbuf *percent_encode(const char *, size_t, char *); ++int percent_decode(char *, char **); ++ ++void ++compare_uri(struct pkcs11_uri *a, struct pkcs11_uri *b) ++{ ++ ASSERT_PTR_NE(a, NULL); ++ ASSERT_PTR_NE(b, NULL); ++ ASSERT_SIZE_T_EQ(a->id_len, b->id_len); ++ ASSERT_MEM_EQ(a->id, b->id, a->id_len); ++ if (b->object != NULL) ++ ASSERT_STRING_EQ(a->object, b->object); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->object, b->object); ++ if (b->module_path != NULL) ++ ASSERT_STRING_EQ(a->module_path, b->module_path); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->module_path, b->module_path); ++ if (b->token != NULL) ++ ASSERT_STRING_EQ(a->token, b->token); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->token, b->token); ++ if (b->manuf != NULL) ++ ASSERT_STRING_EQ(a->manuf, b->manuf); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->manuf, b->manuf); ++ if (b->lib_manuf != NULL) ++ ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); ++} ++ ++void ++check_parse_rv(char *uri, struct pkcs11_uri *expect, int expect_rv) ++{ ++ char *buf = NULL, *str; ++ struct pkcs11_uri *pkcs11uri = NULL; ++ int rv; ++ ++ if (expect_rv == 0) ++ str = "Valid"; ++ else ++ str = "Invalid"; ++ asprintf(&buf, "%s PKCS#11 URI parsing: %s", str, uri); ++ TEST_START(buf); ++ free(buf); ++ pkcs11uri = pkcs11_uri_init(); ++ rv = pkcs11_uri_parse(uri, pkcs11uri); ++ ASSERT_INT_EQ(rv, expect_rv); ++ if (rv == 0) /* in case of failure result is undefined */ ++ compare_uri(pkcs11uri, expect); ++ pkcs11_uri_cleanup(pkcs11uri); ++ free(expect); ++ TEST_DONE(); ++} ++ ++void ++check_parse(char *uri, struct pkcs11_uri *expect) ++{ ++ check_parse_rv(uri, expect, 0); ++} ++ ++struct pkcs11_uri * ++compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, ++ char *manuf, char *module_path, char *object) ++{ ++ struct pkcs11_uri *uri = pkcs11_uri_init(); ++ if (id_len > 0) { ++ uri->id_len = id_len; ++ uri->id = id; ++ } ++ uri->module_path = module_path; ++ uri->token = token; ++ uri->lib_manuf = lib_manuf; ++ uri->manuf = manuf; ++ uri->object = object; ++ return uri; ++} ++ ++static void ++test_parse_valid(void) ++{ ++ /* path arguments */ ++ check_parse("pkcs11:id=%01", ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:id=%00%01", ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:token=SSH%20Keys", ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:library-manufacturer=OpenSC", ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL)); ++ check_parse("pkcs11:manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL)); ++ check_parse("pkcs11:object=SIGN%20Key", ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key")); ++ /* query arguments */ ++ check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); ++ ++ /* combinations */ ++ /* ID SHOULD be percent encoded */ ++ check_parse("pkcs11:token=SSH%20Key;id=0", ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL)); ++ check_parse( ++ "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, "CAC", ++ "/usr/lib64/p11-kit-proxy.so", NULL)); ++ check_parse( ++ "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, ++ "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key")); ++ ++ /* empty path component matches everything */ ++ check_parse("pkcs11:", EMPTY_URI); ++ ++ /* empty string is a valid to match against (and different from NULL) */ ++ check_parse("pkcs11:token=", ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL)); ++ /* Percent character needs to be percent-encoded */ ++ check_parse("pkcs11:token=%25", ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL)); ++} ++ ++static void ++test_parse_invalid(void) ++{ ++ /* Invalid percent encoding */ ++ check_parse_rv("pkcs11:id=%0", EMPTY_URI, -1); ++ /* Invalid percent encoding */ ++ check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); ++ /* Space MUST be percent encoded -- XXX not enforced yet */ ++ check_parse("pkcs11:token=SSH Keys", ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); ++ /* MUST NOT contain duplicate attributes of the same name */ ++ check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); ++ /* Unrecognized attribute in path SHOULD be error */ ++ check_parse_rv("pkcs11:key_name=SSH", EMPTY_URI, -1); ++ /* Unrecognized attribute in query SHOULD be ignored */ ++ check_parse("pkcs11:?key_name=SSH", EMPTY_URI); ++} ++ ++void ++check_gen(char *expect, struct pkcs11_uri *uri) ++{ ++ char *buf = NULL, *uri_str; ++ ++ asprintf(&buf, "Valid PKCS#11 URI generation: %s", expect); ++ TEST_START(buf); ++ free(buf); ++ uri_str = pkcs11_uri_get(uri); ++ ASSERT_PTR_NE(uri_str, NULL); ++ ASSERT_STRING_EQ(uri_str, expect); ++ free(uri_str); ++ TEST_DONE(); ++} ++ ++static void ++test_generate_valid(void) ++{ ++ /* path arguments */ ++ check_gen("pkcs11:id=%01", ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:id=%00%01", ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); ++ /* library-manufacturer is not implmented now */ ++ /*check_gen("pkcs11:library-manufacturer=OpenSC", ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL));*/ ++ check_gen("pkcs11:manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL)); ++ check_gen("pkcs11:object=RSA%20Key", ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key")); ++ /* query arguments */ ++ check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); ++ ++ /* combinations */ ++ check_gen("pkcs11:id=%02;token=SSH%20Keys", ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); ++ check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key")); ++ ++ /* empty path component matches everything */ ++ check_gen("pkcs11:", EMPTY_URI); ++ ++} ++ ++void ++check_encode(char *source, size_t len, char *whitelist, char *expect) ++{ ++ char *buf = NULL; ++ struct sshbuf *b; ++ ++ asprintf(&buf, "percent_encode: expected %s", expect); ++ TEST_START(buf); ++ free(buf); ++ ++ b = percent_encode(source, len, whitelist); ++ ASSERT_STRING_EQ(sshbuf_ptr(b), expect); ++ sshbuf_free(b); ++ TEST_DONE(); ++} ++ ++static void ++test_percent_encode_multibyte(void) ++{ ++ /* SHOULD be encoded as octets according to the UTF-8 character encoding */ ++ ++ /* multi-byte characters are "for free" */ ++ check_encode("$", 1, "", "%24"); ++ check_encode("¢", 2, "", "%C2%A2"); ++ check_encode("€", 3, "", "%E2%82%AC"); ++ check_encode("𐍈", 4, "", "%F0%90%8D%88"); ++ ++ /* CK_UTF8CHAR is unsigned char (1 byte) */ ++ /* labels SHOULD be normalized to NFC [UAX15] */ ++ ++} ++ ++static void ++test_percent_encode(void) ++{ ++ /* Without whitelist encodes everything (for CKA_ID) */ ++ check_encode("A*", 2, "", "%41%2A"); ++ check_encode("\x00", 1, "", "%00"); ++ check_encode("\x7F", 1, "", "%7F"); ++ check_encode("\x80", 1, "", "%80"); ++ check_encode("\xff", 1, "", "%FF"); ++ ++ /* Default whitelist encodes anything but safe letters */ ++ check_encode("test" "\x00" "0alpha", 11, PKCS11_URI_WHITELIST, ++ "test%000alpha"); ++ check_encode(" ", 1, PKCS11_URI_WHITELIST, ++ "%20"); /* Space MUST be percent encoded */ ++ check_encode("/", 1, PKCS11_URI_WHITELIST, ++ "%2F"); /* '/' delimiter MUST be percent encoded (in the path) */ ++ check_encode("?", 1, PKCS11_URI_WHITELIST, ++ "%3F"); /* delimiter '?' MUST be percent encoded (in the path) */ ++ check_encode("#", 1, PKCS11_URI_WHITELIST, ++ "%23"); /* '#' MUST be always percent encoded */ ++ check_encode("key=value;separator?query&#anch", 35, PKCS11_URI_WHITELIST, ++ "key%3Dvalue%3Bseparator%3Fquery%26amp%3B%23anch"); ++ ++ /* Components in query can have '/' unencoded (useful for paths) */ ++ check_encode("/path/to.file", 13, PKCS11_URI_WHITELIST "/", ++ "/path/to.file"); ++} ++ ++void ++check_decode(char *source, char *expect, int expect_len) ++{ ++ char *buf = NULL, *out = NULL; ++ int rv; ++ ++ asprintf(&buf, "percent_decode: %s", source); ++ TEST_START(buf); ++ free(buf); ++ ++ rv = percent_decode(source, &out); ++ ASSERT_INT_EQ(rv, expect_len); ++ if (rv >= 0) ++ ASSERT_MEM_EQ(out, expect, expect_len); ++ free(out); ++ TEST_DONE(); ++} ++ ++static void ++test_percent_decode(void) ++{ ++ /* simple valid cases */ ++ check_decode("%00", "\x00", 1); ++ check_decode("%FF", "\xFF", 1); ++ ++ /* normal strings shold be kept intact */ ++ check_decode("strings are left", "strings are left", 16); ++ check_decode("10%25 of trees", "10% of trees", 12); ++ ++ /* make sure no more than 2 bytes are parsed */ ++ check_decode("%222", "\x22" "2", 2); ++ ++ /* invalid expects failure */ ++ check_decode("%0", "", -1); ++ check_decode("%Z", "", -1); ++ check_decode("%FG", "", -1); ++} ++ ++void ++tests(void) ++{ ++ test_percent_encode(); ++ test_percent_encode_multibyte(); ++ test_percent_decode(); ++ test_parse_valid(); ++ test_parse_invalid(); ++ test_generate_valid(); ++} +diff --git a/ssh-add.c b/ssh-add.c +index adcc4599..e4fd5623 100644 +--- a/ssh-add.c ++++ b/ssh-add.c +@@ -64,6 +64,7 @@ + #include "misc.h" + #include "ssherr.h" + #include "digest.h" ++#include "ssh-pkcs11-uri.h" + + /* argv0 */ + extern char *__progname; +@@ -188,6 +189,24 @@ delete_all(int agent_fd) + return ret; + } + ++#ifdef ENABLE_PKCS11 ++static int update_card(int, int, const char *); ++ ++int ++update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri) ++{ ++ struct pkcs11_uri *uri; ++ ++ /* dry-run parse to make sure the URI is valid and to report errors */ ++ uri = pkcs11_uri_init(); ++ if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ pkcs11_uri_cleanup(uri); ++ ++ return update_card(agent_fd, adding, pkcs11_uri); ++} ++#endif ++ + static int + add_file(int agent_fd, const char *filename, int key_only, int qflag) + { +@@ -480,6 +499,13 @@ lock_agent(int agent_fd, int lock) + static int + do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) + { ++#ifdef ENABLE_PKCS11 ++ if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(file, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ return update_pkcs11_uri(agent_fd, !deleting, file); ++ } ++#endif + if (deleting) { + if (delete_file(agent_fd, file, key_only, qflag) == -1) + return -1; +diff --git a/ssh-agent.c b/ssh-agent.c +index 2a4578b0..f6c86240 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -546,10 +546,70 @@ no_identities(SocketEntry *e) + } + + #ifdef ENABLE_PKCS11 ++static char * ++sanitize_pkcs11_provider(const char *provider) ++{ ++ struct pkcs11_uri *uri = NULL; ++ char *sane_uri, *module_path = NULL; /* default path */ ++ char canonical_provider[PATH_MAX]; ++ ++ if (provider == NULL) ++ return NULL; ++ ++ if (strlen(provider) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ /* PKCS#11 URI */ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) { ++ error("Failed to init PCKS#11 URI"); ++ return NULL; ++ } ++ ++ if (pkcs11_uri_parse(provider, uri) != 0) { ++ error("Failed to parse PKCS#11 URI"); ++ return NULL; ++ } ++ /* validate also provider from URI */ ++ if (uri->module_path) ++ module_path = strdup(uri->module_path); ++ } else ++ module_path = strdup(provider); /* simple path */ ++ ++ if (module_path != NULL) { /* do not validate default NULL path in URI */ ++ if (realpath(module_path, canonical_provider) == NULL) { ++ verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", ++ module_path, strerror(errno)); ++ free(module_path); ++ return NULL; ++ } ++ free(module_path); ++ if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { ++ verbose("refusing PKCS#11 provider \"%.100s\": " ++ "not whitelisted", canonical_provider); ++ return NULL; ++ } ++ ++ /* copy verified and sanitized provider path back to the uri */ ++ if (uri) { ++ free(uri->module_path); ++ uri->module_path = xstrdup(canonical_provider); ++ } ++ } ++ ++ if (uri) { ++ sane_uri = pkcs11_uri_get(uri); ++ pkcs11_uri_cleanup(uri); ++ return sane_uri; ++ } else { ++ return xstrdup(canonical_provider); /* simple path */ ++ } ++} ++ + static void + process_add_smartcard_key(SocketEntry *e) + { +- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; ++ char *provider = NULL, *pin = NULL, *sane_uri = NULL; + int r, i, count = 0, success = 0, confirm = 0; + u_int seconds; + time_t death = 0; +@@ -585,28 +645,23 @@ process_add_smartcard_key(SocketEntry *e) + goto send; + } + } +- if (realpath(provider, canonical_provider) == NULL) { +- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", +- provider, strerror(errno)); +- goto send; +- } +- if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { +- verbose("refusing PKCS#11 add of \"%.100s\": " +- "provider not whitelisted", canonical_provider); ++ ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; +- } +- debug("%s: add %.100s", __func__, canonical_provider); ++ + if (lifetime && !death) + death = monotime() + lifetime; + +- count = pkcs11_add_provider(canonical_provider, pin, &keys); ++ debug("%s: add %.100s", __func__, sane_uri); ++ count = pkcs11_add_provider(sane_uri, pin, &keys); + for (i = 0; i < count; i++) { + k = keys[i]; + if (lookup_identity(k) == NULL) { + id = xcalloc(1, sizeof(Identity)); + id->key = k; +- id->provider = xstrdup(canonical_provider); +- id->comment = xstrdup(canonical_provider); /* XXX */ ++ id->provider = xstrdup(sane_uri); ++ id->comment = xstrdup(sane_uri); + id->death = death; + id->confirm = confirm; + TAILQ_INSERT_TAIL(&idtab->idlist, id, next); +@@ -620,6 +675,7 @@ process_add_smartcard_key(SocketEntry *e) + send: + free(pin); + free(provider); ++ free(sane_uri); + free(keys); + send_status(e, success); + } +@@ -627,7 +683,7 @@ send: + static void + process_remove_smartcard_key(SocketEntry *e) + { +- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; ++ char *provider = NULL, *pin = NULL, *sane_uri = NULL; + int r, success = 0; + Identity *id, *nxt; + +@@ -638,30 +694,29 @@ process_remove_smartcard_key(SocketEntry *e) + } + free(pin); + +- if (realpath(provider, canonical_provider) == NULL) { +- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", +- provider, strerror(errno)); ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; +- } + +- debug("%s: remove %.100s", __func__, canonical_provider); ++ debug("%s: remove %.100s", __func__, sane_uri); + for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { + nxt = TAILQ_NEXT(id, next); + /* Skip file--based keys */ + if (id->provider == NULL) + continue; +- if (!strcmp(canonical_provider, id->provider)) { ++ if (!strcmp(sane_uri, id->provider)) { + TAILQ_REMOVE(&idtab->idlist, id, next); + free_identity(id); + idtab->nentries--; + } + } +- if (pkcs11_del_provider(canonical_provider) == 0) ++ if (pkcs11_del_provider(sane_uri) == 0) + success = 1; + else + error("%s: pkcs11_del_provider failed", __func__); + send: + free(provider); ++ free(sane_uri); + send_status(e, success); + } + #endif /* ENABLE_PKCS11 */ +diff --git a/ssh-keygen.c b/ssh-keygen.c +index d1ffc30c..00e38049 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -820,6 +820,7 @@ do_download(struct passwd *pw) + free(fp); + } else { + (void) sshkey_write(keys[i], stdout); /* XXX check */ ++ (void) pkcs11_uri_write(keys[i], stdout); + fprintf(stdout, "\n"); + } + sshkey_free(keys[i]); +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +index a023f5f4..882e8381 100644 +--- a/ssh-pkcs11-client.c ++++ b/ssh-pkcs11-client.c +@@ -117,6 +117,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + return (-1); + key.type = KEY_RSA; + key.rsa = rsa; ++ key.ecdsa_nid = 0; + if (key_to_blob(&key, &blob, &blen) == 0) + return -1; + buffer_init(&msg); +@@ -195,6 +196,8 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) + u_int blen; + Buffer msg; + ++ debug("%s: called, name = %s", __func__, name); ++ + if (fd < 0 && pkcs11_start_helper() < 0) + return (-1); + +@@ -208,6 +211,7 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) + if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) { + nkeys = buffer_get_int(&msg); + *keysp = xcalloc(nkeys, sizeof(Key *)); ++ debug("%s: nkeys = %d", __func__, nkeys); + for (i = 0; i < nkeys; i++) { + blob = buffer_get_string(&msg, &blen); + free(buffer_get_string(&msg, NULL)); +diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c +new file mode 100644 +index 00000000..da15c164 +--- /dev/null ++++ b/ssh-pkcs11-uri.c +@@ -0,0 +1,399 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#ifdef ENABLE_PKCS11 ++ ++#include ++#include ++ ++#include "sshkey.h" ++#include "log.h" ++ ++#define CRYPTOKI_COMPAT ++#include "pkcs11.h" ++ ++#include "ssh-pkcs11-uri.h" ++ ++#define PKCS11_URI_PATH_SEPARATOR ";" ++#define PKCS11_URI_QUERY_SEPARATOR "&" ++#define PKCS11_URI_VALUE_SEPARATOR "=" ++#define PKCS11_URI_ID "id" ++#define PKCS11_URI_TOKEN "token" ++#define PKCS11_URI_OBJECT "object" ++#define PKCS11_URI_LIB_MANUF "library-manufacturer" ++#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_MODULE_PATH "module-path" ++ ++/* Keyword tokens. */ ++typedef enum { ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pBadOption ++} pkcs11uriOpCodes; ++ ++/* Textual representation of the tokens. */ ++static struct { ++ const char *name; ++ pkcs11uriOpCodes opcode; ++} keywords[] = { ++ { PKCS11_URI_ID, pId }, ++ { PKCS11_URI_TOKEN, pToken }, ++ { PKCS11_URI_OBJECT, pObject }, ++ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, ++ { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_MODULE_PATH, pModulePath }, ++ { NULL, pBadOption } ++}; ++ ++static pkcs11uriOpCodes ++parse_token(const char *cp) ++{ ++ u_int i; ++ ++ for (i = 0; keywords[i].name; i++) ++ if (strncasecmp(cp, keywords[i].name, ++ strlen(keywords[i].name)) == 0) ++ return keywords[i].opcode; ++ ++ return pBadOption; ++} ++ ++int ++percent_decode(char *data, char **outp) ++{ ++ char tmp[3]; ++ char *out, *tmp_end; ++ char *p = data; ++ long value; ++ size_t outlen = 0; ++ ++ out = malloc(strlen(data)+1); /* upper bound */ ++ if (out == NULL) ++ return -1; ++ while (*p != '\0') { ++ switch (*p) { ++ case '%': ++ p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[0] = *p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[1] = *p++; ++ tmp[2] = '\0'; ++ tmp_end = NULL; ++ value = strtol(tmp, &tmp_end, 16); ++ if (tmp_end != tmp+2) ++ goto fail; ++ else ++ out[outlen++] = (char) value; ++ break; ++ default: ++ out[outlen++] = *p++; ++ break; ++ } ++ } ++ ++ /* zero terminate */ ++ out[outlen] = '\0'; ++ *outp = out; ++ return outlen; ++fail: ++ free(out); ++ return -1; ++} ++ ++struct sshbuf * ++percent_encode(const char *data, size_t length, const char *whitelist) ++{ ++ struct sshbuf *b = NULL; ++ char tmp[4], *cp; ++ size_t i; ++ ++ if ((b = sshbuf_new()) == NULL) ++ return NULL; ++ for (i = 0; i < length; i++) { ++ cp = strchr(whitelist, data[i]); ++ /* if c is specified as '\0' pointer to terminator is returned !! */ ++ if (cp != NULL && *cp != '\0') { ++ if (sshbuf_put(b, &data[i], 1) != 0) ++ goto err; ++ } else ++ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 ++ || sshbuf_put(b, tmp, 3) != 0) ++ goto err; ++ } ++ if (sshbuf_put(b, "\0", 1) == 0) ++ return b; ++err: ++ sshbuf_free(b); ++ return NULL; ++} ++ ++char * ++pkcs11_uri_append(char *part, const char *separator, const char *key, ++ struct sshbuf *value) ++{ ++ char *new_part; ++ size_t size; ++ ++ if (value == NULL) ++ return NULL; ++ ++ size = asprintf(&new_part, ++ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", ++ (part != NULL ? part : ""), ++ (part != NULL ? separator : ""), ++ key, sshbuf_ptr(value)); ++ sshbuf_free(value); ++ free(part); ++ ++ if (size < 0) ++ return NULL; ++ return new_part; ++} ++ ++char * ++pkcs11_uri_get(struct pkcs11_uri *uri) ++{ ++ size_t size = -1; ++ char *p = NULL, *path = NULL, *query = NULL; ++ ++ /* compose a percent-encoded ID */ ++ if (uri->id_len > 0) { ++ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_ID, key_id); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write object label */ ++ if (uri->object) { ++ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_OBJECT, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write token label */ ++ if (uri->token) { ++ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_TOKEN, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write manufacturer */ ++ if (uri->manuf) { ++ struct sshbuf *manuf = percent_encode(uri->manuf, ++ strlen(uri->manuf), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_MANUF, manuf); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write module_path */ ++ if (uri->module_path) { ++ struct sshbuf *module = percent_encode(uri->module_path, ++ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); ++ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, ++ PKCS11_URI_MODULE_PATH, module); ++ if (query == NULL) ++ goto err; ++ } ++ ++ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", ++ path != NULL ? path : "", ++ query != NULL ? "?" : "", ++ query != NULL ? query : ""); ++err: ++ free(query); ++ free(path); ++ if (size < 0) ++ return NULL; ++ return p; ++} ++ ++struct pkcs11_uri * ++pkcs11_uri_init() ++{ ++ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); ++ return d; ++} ++ ++void ++pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) ++{ ++ free(pkcs11->id); ++ free(pkcs11->module_path); ++ free(pkcs11->token); ++ free(pkcs11->object); ++ free(pkcs11->lib_manuf); ++ free(pkcs11->manuf); ++ free(pkcs11); ++} ++ ++int ++pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) ++{ ++ char *saveptr1, *saveptr2, *str1, *str2, *tok; ++ int rv = 0, len; ++ char *p = NULL; ++ ++ size_t scheme_len = strlen(PKCS11_URI_SCHEME); ++ if (strlen(uri) < scheme_len || /* empty URI matches everything */ ++ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { ++ error("%s: The '%s' does not look like PKCS#11 URI", ++ __func__, uri); ++ return -1; ++ } ++ ++ if (pkcs11 == NULL) { ++ error("%s: Bad arguments. The pkcs11 can't be null", __func__); ++ return -1; ++ } ++ ++ /* skip URI schema name */ ++ p = strdup(uri); ++ str1 = p; ++ ++ /* everything before ? */ ++ tok = strtok_r(str1, "?", &saveptr1); ++ if (tok == NULL) { ++ free(p); ++ error("%s: pk11-path expected, got EOF", __func__); ++ return -1; ++ } ++ ++ /* skip URI schema name: ++ * the scheme ensures that there is at least something before "?" ++ * allowing empty pk11-path. Resulting token at worst pointing to ++ * \0 byte */ ++ tok = tok + scheme_len; ++ ++ /* parse pk11-path */ ++ for (str2 = tok; ; str2 = NULL) { ++ char **charptr; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode == pBadOption) { ++ verbose("Unknown key in PKCS#11 URI: %s", tok); ++ return -1; ++ } ++ ++ char *arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ switch (opcode) { ++ case pId: ++ /* CKA_ID */ ++ if (pkcs11->id != NULL) { ++ verbose("%s: The id already set in the PKCS#11 URI", ++ __func__); ++ rv = -1; ++ } ++ len = percent_decode(arg, &pkcs11->id); ++ if (len <= 0) { ++ verbose("%s: Failed to percent-decode CKA_ID: %s", ++ __func__, arg); ++ rv = -1; ++ } else ++ pkcs11->id_len = len; ++ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", ++ __func__, arg); ++ break; ++ case pToken: ++ /* CK_TOKEN_INFO -> label */ ++ charptr = &pkcs11->token; ++ parse_string: ++ if (*charptr != NULL) { ++ verbose("%s: The %s already set in the PKCS#11 URI", ++ keywords[opcode].name, __func__); ++ rv = -1; ++ } ++ percent_decode(arg, charptr); ++ debug3("%s: Setting %s = %s from PKCS#11 URI", ++ __func__, keywords[opcode].name, *charptr); ++ break; ++ ++ case pObject: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->object; ++ goto parse_string; ++ ++ case pManufacturer: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->manuf; ++ goto parse_string; ++ ++ case pLibraryManufacturer: ++ /* CK_INFO -> manufacturerID */ ++ charptr = &pkcs11->lib_manuf; ++ goto parse_string; ++ ++ case pBadOption: ++ default: ++ /* Unrecognized attribute in the URI path SHOULD be error */ ++ verbose("%s: Unknown part of path in PKCS#11 URI: %s", ++ __func__, tok); ++ rv = -1; ++ } ++ } ++ ++ tok = strtok_r(NULL, "?", &saveptr1); ++ if (tok == NULL) { ++ free(p); ++ return rv; ++ } ++ /* parse pk11-query (optional) */ ++ for (str2 = tok; ; str2 = NULL) { ++ size_t key_len = strlen(PKCS11_URI_MODULE_PATH) + 1; ++ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ if (strncasecmp(tok, PKCS11_URI_MODULE_PATH ++ PKCS11_URI_VALUE_SEPARATOR, key_len) == 0) { ++ /* module-path is PKCS11Provider */ ++ if (pkcs11->module_path != NULL) { ++ verbose("%s: Multiple module-path attributes are" ++ "not supported the PKCS#11 URI", __func__); ++ rv = -1; ++ } ++ percent_decode(tok + key_len, &pkcs11->module_path); ++ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", ++ __func__, pkcs11->module_path); ++ /* } else if ( pin-value ) { */ ++ } else { ++ /* Unrecognized attribute in the URI query SHOULD be ignored */ ++ verbose("%s: Unknown part of query in PKCS#11 URI: %s", ++ __func__, tok); ++ } ++ } ++ free(p); ++ return rv; ++} ++ ++#endif /* ENABLE_PKCS11 */ +diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h +new file mode 100644 +index 00000000..609c4df1 +--- /dev/null ++++ b/ssh-pkcs11-uri.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#define PKCS11_URI_SCHEME "pkcs11:" ++#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789_-.()" ++ ++struct pkcs11_uri { ++ /* path */ ++ char *id; ++ size_t id_len; ++ char *token; ++ char *object; ++ char *lib_manuf; ++ char *manuf; ++ /* query */ ++ char *module_path; ++}; ++ ++struct pkcs11_uri *pkcs11_uri_init(); ++void pkcs11_uri_cleanup(struct pkcs11_uri *); ++int pkcs11_uri_parse(const char *, struct pkcs11_uri *); ++struct pkcs11_uri *pkcs11_uri_init(); ++char * pkcs11_uri_get(struct pkcs11_uri *uri); ++ +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index 88c9d6e2..a29b4451 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -48,8 +48,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -58,6 +58,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -70,10 +77,46 @@ struct pkcs11_key { + RSA_METHOD rsa_method; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ if (key->type != KEY_RSA || ++ (k11 = RSA_get_app_data(key->rsa)) == NULL) ++ return -1; ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + int + pkcs11_init(int interactive) + { +@@ -89,26 +132,63 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug("pkcs11_provider_finalize: %p refcount %d valid %d", +- p, p->refcount, p->valid); +- if (!p->valid) ++ debug("%s: %p refcount %d valid %d", __func__, ++ m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug("%s: %p refcount %d", __func__, m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error("%s: %p still valid", __func__, m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared libarary, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug("%s: %p refcount %d valid %d", __func__, ++ p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -118,12 +198,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) + static void + pkcs11_provider_unref(struct pkcs11_provider *p) + { +- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); ++ debug("%s: %p refcount %d", __func__, p, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error("pkcs11_provider_unref: %p still valid", p); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); ++ free(p->name); + free(p); + } + } +@@ -141,6 +220,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -155,19 +248,52 @@ pkcs11_provider_lookup(char *provider_id) + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) ++{ ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) + { + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3("%s(%s): called", __func__, provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + /* openssl callback for freeing an RSA key */ +@@ -183,6 +309,7 @@ pkcs11_rsa_finish(RSA *rsa) + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + return (rv); +@@ -199,8 +327,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -247,12 +375,13 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + error("RSA_get_app_data failed for rsa %p", rsa); + return (-1); + } +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || !k11->provider->module ++ || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider for rsa %p", rsa); + return (-1); + } +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (!pkcs11_interactive) { + error("need pin entry%s", (si->token.flags & +@@ -311,7 +440,7 @@ pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + const RSA_METHOD *def = RSA_get_default_method(); +@@ -326,6 +455,11 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } + k11->orig_finish = def->finish; + memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); + k11->rsa_method.name = "pkcs11"; +@@ -372,16 +506,16 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) + CK_SESSION_HANDLE session; + int login_required; + +- f = p->function_list; +- login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; ++ f = p->module->function_list; ++ login_required = p->module->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; + if (pin && login_required && !strlen(pin)) { + error("pin required"); + return (-1); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) + != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin) { +@@ -393,9 +527,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) + error("C_CloseSession failed: %lu", rv); + return (-1); + } +- p->slotinfo[slotidx].logged_in = 1; ++ p->module->slotinfo[slotidx].logged_in = 1; + } +- p->slotinfo[slotidx].session = session; ++ p->module->slotinfo[slotidx].session = session; + return (0); + } + +@@ -405,38 +539,62 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) + * keysp points to an (possibly empty) array with *nkeys keys. + */ + static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, +- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) ++ CK_ATTRIBUTE [], size_t, CK_ATTRIBUTE [3], struct sshkey ***, int *) + __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); + + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, int *nkeys) ++ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) + { ++ size_t filter_size = 1; + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; + CK_ATTRIBUTE pubkey_filter[] = { +- { CKA_CLASS, NULL, sizeof(pubkey_class) } ++ { CKA_CLASS, NULL, sizeof(pubkey_class) }, ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 } + }; + CK_ATTRIBUTE cert_filter[] = { +- { CKA_CLASS, NULL, sizeof(cert_class) } ++ { CKA_CLASS, NULL, sizeof(cert_class) }, ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 } + }; + CK_ATTRIBUTE pubkey_attribs[] = { + { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 } + }; + CK_ATTRIBUTE cert_attribs[] = { + { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 }, + { CKA_SUBJECT, NULL, 0 }, + { CKA_VALUE, NULL, 0 } + }; + pubkey_filter[0].pValue = &pubkey_class; + cert_filter[0].pValue = &cert_class; + +- if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, +- keysp, nkeys) < 0 || +- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, +- keysp, nkeys) < 0) ++ if (uri->id != NULL) { ++ pubkey_filter[filter_size].pValue = uri->id; ++ pubkey_filter[filter_size].ulValueLen = uri->id_len; ++ cert_filter[filter_size].pValue = uri->id; ++ cert_filter[filter_size].ulValueLen = uri->id_len; ++ filter_size++; ++ } ++ if (uri->object != NULL) { ++ pubkey_filter[filter_size].pValue = uri->object; ++ pubkey_filter[filter_size].ulValueLen = strlen(uri->object); ++ pubkey_filter[filter_size].type = CKA_LABEL; ++ cert_filter[filter_size].pValue = uri->object; ++ cert_filter[filter_size].ulValueLen = strlen(uri->object); ++ cert_filter[filter_size].type = CKA_LABEL; ++ filter_size++; ++ } ++ ++ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, ++ pubkey_attribs, keysp, nkeys) < 0 || ++ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, ++ cert_attribs, keysp, nkeys) < 0) + return (-1); + return (0); + } +@@ -454,14 +612,15 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) + + static int + pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, +- CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], ++ CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], + struct sshkey ***keysp, int *nkeys) + { + struct sshkey *key; + RSA *rsa; + X509 *x509; +- EVP_PKEY *evp; ++ EVP_PKEY *evp = NULL; + int i; ++ int nattribs = 4; + const u_char *cp; + CK_RV rv; + CK_OBJECT_HANDLE obj; +@@ -470,16 +629,15 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + /* setup a filter the looks for public keys */ +- if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { ++ if ((rv = f->C_FindObjectsInit(session, filter, filter_size)) != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + return (-1); + } + while (1) { +- /* XXX 3 attributes in attribs[] */ +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < nattribs; i++) { + attribs[i].pValue = NULL; + attribs[i].ulValueLen = 0; + } +@@ -487,22 +645,22 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + || nfound == 0) + break; + /* found a key, so figure out size of the attributes */ +- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) ++ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + continue; + } + /* +- * Allow CKA_ID (always first attribute) to be empty, but +- * ensure that none of the others are zero length. ++ * Allow CKA_ID (always first attribute) and CKA_LABEL (second) ++ * to be empty, but ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (attribs[1].ulValueLen == 0 || +- attribs[2].ulValueLen == 0) { ++ if (attribs[2].ulValueLen == 0 || ++ attribs[3].ulValueLen == 0) { + continue; + } + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < nattribs; i++) { + if (attribs[i].ulValueLen > 0) { + attribs[i].pValue = xmalloc( + attribs[i].ulValueLen); +@@ -510,27 +668,27 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + } + + /* +- * retrieve ID, modulus and public exponent of RSA key, +- * or ID, subject and value for certificates. ++ * retrieve ID, label, modulus and public exponent of RSA key, ++ * or ID, label, subject and value for certificates. + */ + rsa = NULL; +- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) ++ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); +- } else if (attribs[1].type == CKA_MODULUS ) { ++ } else if (attribs[2].type == CKA_MODULUS ) { + if ((rsa = RSA_new()) == NULL) { + error("RSA_new failed"); + } else { +- rsa->n = BN_bin2bn(attribs[1].pValue, +- attribs[1].ulValueLen, NULL); +- rsa->e = BN_bin2bn(attribs[2].pValue, ++ rsa->n = BN_bin2bn(attribs[2].pValue, + attribs[2].ulValueLen, NULL); ++ rsa->e = BN_bin2bn(attribs[3].pValue, ++ attribs[3].ulValueLen, NULL); + } + } else { +- cp = attribs[2].pValue; ++ cp = attribs[3].pValue; + if ((x509 = X509_new()) == NULL) { + error("X509_new failed"); +- } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) ++ } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) + == NULL) { + error("d2i_X509 failed"); + } else if ((evp = X509_get_pubkey(x509)) == NULL || +@@ -546,9 +704,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + error("RSAPublicKey_dup"); + } + X509_free(x509); ++ EVP_PKEY_free(evp); + } + if (rsa && rsa->n && rsa->e && +- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { ++ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + key->rsa = rsa; +@@ -569,7 +728,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + } else if (rsa) { + RSA_free(rsa); + } +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattribs; i++) + free(attribs[i].pValue); + } + if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) +@@ -581,126 +740,238 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + int + pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) + { +- int nkeys, need_finalize = 0; +- struct pkcs11_provider *p = NULL; ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_add_provider_by_uri(uri, pin, keyp); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++struct pkcs11_provider * ++pkcs11_provider_initialize(struct pkcs11_uri *uri) ++{ ++ int need_finalize = 0; + void *handle = NULL; + CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); + CK_RV rv; + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_provider *p; ++ struct pkcs11_module *m; + +- *keyp = NULL; +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug("%s: provider already registered: %s", +- __func__, provider_id); ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error("%s: No module path provided", __func__); + goto fail; ++#endif ++ } else ++ provider_module = strdup(uri->module_path); ++ ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); ++ ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug("%s: provider module already initialized: %s", ++ __func__, provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ return p; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-libarary */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ m->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug("%s: Skipping provider %s not matching library_manufacturer", ++ __func__, m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { ++ if (m->nslots == 0) { + debug("%s: provider %s returned no slots", __func__, +- provider_id); ++ provider_module); + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->valid = 1; + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (unsigned long)i, rv); ++ "failed: %lu", provider_module, (unsigned long)i, rv); + continue; + } + if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2("%s: ignoring uninitialised token in " +- "provider %s slot %lu", __func__, +- provider_id, (unsigned long)i); + continue; + } + rmspace(token->label, sizeof(token->label)); + rmspace(token->manufacturerID, sizeof(token->manufacturerID)); + rmspace(token->model, sizeof(token->model)); + rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ return p; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (handle) ++ dlclose(handle); ++ return NULL; ++} ++ ++int ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, struct sshkey ***keyp) ++{ ++ int nkeys; ++ struct pkcs11_provider *p = NULL; ++ CK_TOKEN_INFO *token; ++ CK_ULONG i; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug("%s: called, provider_uri = %s", __func__, provider_uri); ++ ++ *keyp = NULL; ++ if ((p = pkcs11_provider_initialize(uri)) == NULL) { ++ debug("%s: failed to initialize provider: %s", ++ __func__, provider_uri); ++ goto fail; ++ } ++ ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2("%s: ignoring uninitialised token in " ++ "provider %s slot %lu", __func__, ++ provider_uri, (unsigned long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2("%s: ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", __func__, ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2("%s: ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", __func__, ++ token->manufacturerID, (unsigned long)i); ++ continue; ++ } + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); +- /* open session, login with pin and retrieve public keys */ +- if (pkcs11_open_session(p, i, pin) == 0) +- pkcs11_fetch_keys(p, i, keyp, &nkeys); ++ /* open session if not yet opened, login with pin ++ * and retrieve public keys */ ++ if ((p->module->slotinfo[i].session != 0) || ++ pkcs11_open_session(p, i, pin) == 0) ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); + } + if (nkeys > 0) { +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ ++ free(provider_uri); + return (nkeys); + } +- debug("%s: provider %s returned no keys", __func__, provider_id); ++ debug("%s: provider %s returned no keys", __func__, provider_uri); + /* don't add the provider, since it does not have any keys */ + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); ++ free(provider_uri); + return (-1); + } + +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +index 0ced74f2..c63a88f6 100644 +--- a/ssh-pkcs11.h ++++ b/ssh-pkcs11.h +@@ -14,10 +14,15 @@ + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ ++ ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + + #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) + #undef ENABLE_PKCS11 +diff --git a/ssh.c b/ssh.c +index d3619fe2..180eb2e0 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -769,6 +769,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, original_real_uid); + if (stat(p, &st) < 0) + fprintf(stderr, "Warning: Identity file %s " +@@ -1999,6 +2007,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ key_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(struct passwd *pw) +@@ -2011,10 +2058,6 @@ load_public_identity_files(struct passwd *pw) + struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2023,35 +2066,48 @@ load_public_identity_files(struct passwd *pw) + memset(certificates, 0, sizeof(certificates)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- key_free(keys[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = +- xstrdup(options.pkcs11_provider); /* XXX */ +- n_ids++; +- } +- free(keys); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + if ((pw = getpwuid(original_real_uid)) == NULL) + fatal("load_public_identity_files: getpwuid failed"); + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], +- original_real_uid); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, original_real_uid); + filename = percent_expand(cp, "d", pw->pw_dir, + "u", pw->pw_name, "l", thishost, "h", host, + "r", options.user, (char *)NULL); +diff --git a/ssh_config.5 b/ssh_config.5 +index 71705cab..e0266609 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -919,6 +919,19 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query argument ++.Cm module-path ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. diff --git a/openssh-7.6p1-gsissh.patch b/openssh-7.7p1-gsissh.patch similarity index 90% rename from openssh-7.6p1-gsissh.patch rename to openssh-7.7p1-gsissh.patch index 553558f..6359ff4 100644 --- a/openssh-7.6p1-gsissh.patch +++ b/openssh-7.7p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c ---- openssh-7.6p1.orig/auth2.c 2018-01-18 09:33:46.564488115 +0100 -+++ openssh-7.6p1/auth2.c 2018-01-18 09:34:35.318942720 +0100 -@@ -233,7 +233,27 @@ +diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c +--- openssh-7.7p1.orig/auth2.c 2018-04-10 10:51:05.695456763 +0200 ++++ openssh-7.7p1/auth2.c 2018-04-10 10:51:43.733037632 +0200 +@@ -230,7 +230,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -30,7 +30,7 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -244,11 +264,32 @@ +@@ -241,11 +261,32 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -67,7 +67,7 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c authctxt->valid = 1; debug2("%s: setting up authctxt for %s", __func__, user); -@@ -256,6 +297,9 @@ +@@ -253,6 +294,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -77,7 +77,7 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); -@@ -264,6 +308,7 @@ +@@ -261,6 +305,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -85,7 +85,7 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -278,9 +323,10 @@ +@@ -275,9 +320,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -99,9 +99,9 @@ diff -Nur openssh-7.6p1.orig/auth2.c openssh-7.6p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.6p1.orig/auth2-gss.c openssh-7.6p1/auth2-gss.c ---- openssh-7.6p1.orig/auth2-gss.c 2018-01-18 09:33:46.462489256 +0100 -+++ openssh-7.6p1/auth2-gss.c 2018-01-18 09:34:35.319942709 +0100 +diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c +--- openssh-7.7p1.orig/auth2-gss.c 2018-04-10 10:51:05.602457788 +0200 ++++ openssh-7.7p1/auth2-gss.c 2018-04-10 10:51:43.734037621 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -282,12 +282,12 @@ diff -Nur openssh-7.6p1.orig/auth2-gss.c openssh-7.6p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c ---- openssh-7.6p1.orig/auth.c 2018-01-18 09:33:46.565488104 +0100 -+++ openssh-7.6p1/auth.c 2018-01-18 09:34:35.319942709 +0100 -@@ -74,6 +74,9 @@ - #include "ssherr.h" +diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c +--- openssh-7.7p1.orig/auth.c 2018-04-10 10:51:05.696456752 +0200 ++++ openssh-7.7p1/auth.c 2018-04-10 10:51:43.735037610 +0200 +@@ -76,6 +76,9 @@ #include "compat.h" + #include "channels.h" +#include "version.h" +#include "ssh-globus-usage.h" @@ -295,7 +295,7 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -337,7 +340,8 @@ +@@ -340,7 +343,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -305,7 +305,7 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -363,6 +367,23 @@ +@@ -366,6 +370,23 @@ if (authenticated == 0 && !authctxt->postponed && !partial) audit_event(audit_classify_auth(method)); #endif @@ -329,7 +329,7 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c } -@@ -575,6 +596,10 @@ +@@ -576,6 +597,10 @@ #endif pw = getpwnam(user); @@ -340,7 +340,7 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -594,7 +619,8 @@ +@@ -595,7 +620,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -350,10 +350,10 @@ diff -Nur openssh-7.6p1.orig/auth.c openssh-7.6p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.6p1.orig/auth.h openssh-7.6p1/auth.h ---- openssh-7.6p1.orig/auth.h 2018-01-18 09:33:46.565488104 +0100 -+++ openssh-7.6p1/auth.h 2018-01-18 09:34:35.320942698 +0100 -@@ -83,6 +83,8 @@ +diff -Nur openssh-7.7p1.orig/auth.h openssh-7.7p1/auth.h +--- openssh-7.7p1.orig/auth.h 2018-04-10 10:51:05.696456752 +0200 ++++ openssh-7.7p1/auth.h 2018-04-10 10:51:43.736037599 +0200 +@@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; char *krb5_ccname; @@ -362,9 +362,9 @@ diff -Nur openssh-7.6p1.orig/auth.h openssh-7.6p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c ---- openssh-7.6p1.orig/auth-pam.c 2018-01-18 09:33:46.587487858 +0100 -+++ openssh-7.6p1/auth-pam.c 2018-01-18 09:34:35.320942698 +0100 +diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c +--- openssh-7.7p1.orig/auth-pam.c 2018-04-10 10:51:05.719456498 +0200 ++++ openssh-7.7p1/auth-pam.c 2018-04-10 10:51:43.737037588 +0200 @@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -422,7 +422,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -310,7 +360,7 @@ +@@ -319,7 +369,7 @@ static void import_environments(Buffer *b) { @@ -431,7 +431,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c u_int i, num_env; int err; -@@ -320,6 +370,17 @@ +@@ -329,6 +379,17 @@ /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); @@ -449,7 +449,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -471,6 +532,13 @@ +@@ -480,6 +541,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -463,7 +463,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -489,6 +557,11 @@ +@@ -498,6 +566,11 @@ /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); @@ -475,7 +475,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -964,6 +1037,18 @@ +@@ -973,6 +1046,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -494,7 +494,7 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1253,6 +1338,9 @@ +@@ -1262,6 +1347,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -504,19 +504,19 @@ diff -Nur openssh-7.6p1.orig/auth-pam.c openssh-7.6p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.6p1.orig/auth-pam.h openssh-7.6p1/auth-pam.h ---- openssh-7.6p1.orig/auth-pam.h 2018-01-18 09:33:46.415489782 +0100 -+++ openssh-7.6p1/auth-pam.h 2018-01-18 09:34:35.321942687 +0100 -@@ -41,5 +41,6 @@ +diff -Nur openssh-7.7p1.orig/auth-pam.h openssh-7.7p1/auth-pam.h +--- openssh-7.7p1.orig/auth-pam.h 2018-04-10 10:51:05.555458306 +0200 ++++ openssh-7.7p1/auth-pam.h 2018-04-10 10:51:43.737037588 +0200 +@@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); int is_pam_session_open(void); +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.6p1.orig/canohost.c openssh-7.6p1/canohost.c ---- openssh-7.6p1.orig/canohost.c 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/canohost.c 2018-01-18 09:34:35.321942687 +0100 +diff -Nur openssh-7.7p1.orig/canohost.c openssh-7.7p1/canohost.c +--- openssh-7.7p1.orig/canohost.c 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/canohost.c 2018-04-10 10:51:43.738037577 +0200 @@ -17,6 +17,7 @@ #include #include @@ -559,9 +559,9 @@ diff -Nur openssh-7.6p1.orig/canohost.c openssh-7.6p1/canohost.c + } + } +} -diff -Nur openssh-7.6p1.orig/canohost.h openssh-7.6p1/canohost.h ---- openssh-7.6p1.orig/canohost.h 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/canohost.h 2018-01-18 09:34:35.321942687 +0100 +diff -Nur openssh-7.7p1.orig/canohost.h openssh-7.7p1/canohost.h +--- openssh-7.7p1.orig/canohost.h 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/canohost.h 2018-04-10 10:51:43.738037577 +0200 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -569,10 +569,10 @@ diff -Nur openssh-7.6p1.orig/canohost.h openssh-7.6p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac ---- openssh-7.6p1.orig/configure.ac 2018-01-18 09:33:46.601487702 +0100 -+++ openssh-7.6p1/configure.ac 2018-01-18 09:34:35.323942664 +0100 -@@ -4399,6 +4399,14 @@ +diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac +--- openssh-7.7p1.orig/configure.ac 2018-04-10 10:51:05.729456388 +0200 ++++ openssh-7.7p1/configure.ac 2018-04-10 10:51:43.739037566 +0200 +@@ -4542,6 +4542,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -587,7 +587,7 @@ diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4438,6 +4446,50 @@ +@@ -4581,6 +4589,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -638,9 +638,9 @@ diff -Nur openssh-7.6p1.orig/configure.ac openssh-7.6p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.6p1.orig/gss-genr.c openssh-7.6p1/gss-genr.c ---- openssh-7.6p1.orig/gss-genr.c 2018-01-18 09:33:46.589487836 +0100 -+++ openssh-7.6p1/gss-genr.c 2018-01-18 09:34:35.323942664 +0100 +diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c +--- openssh-7.7p1.orig/gss-genr.c 2018-04-10 10:51:05.721456476 +0200 ++++ openssh-7.7p1/gss-genr.c 2018-04-10 10:51:43.740037555 +0200 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -677,9 +677,9 @@ diff -Nur openssh-7.6p1.orig/gss-genr.c openssh-7.6p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.6p1.orig/gss-serv.c openssh-7.6p1/gss-serv.c ---- openssh-7.6p1.orig/gss-serv.c 2018-01-18 09:33:46.511488708 +0100 -+++ openssh-7.6p1/gss-serv.c 2018-01-18 09:34:35.324942653 +0100 +diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c +--- openssh-7.7p1.orig/gss-serv.c 2018-04-10 10:51:05.649457270 +0200 ++++ openssh-7.7p1/gss-serv.c 2018-04-10 10:51:43.740037555 +0200 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -976,9 +976,9 @@ diff -Nur openssh-7.6p1.orig/gss-serv.c openssh-7.6p1/gss-serv.c +} + #endif -diff -Nur openssh-7.6p1.orig/gss-serv-gsi.c openssh-7.6p1/gss-serv-gsi.c ---- openssh-7.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/gss-serv-gsi.c 2018-01-18 09:34:35.324942653 +0100 +diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c +--- openssh-7.7p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.7p1/gss-serv-gsi.c 2018-04-10 10:51:43.740037555 +0200 @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1311,9 +1311,9 @@ diff -Nur openssh-7.6p1.orig/gss-serv-gsi.c openssh-7.6p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.6p1.orig/gss-serv-krb5.c openssh-7.6p1/gss-serv-krb5.c ---- openssh-7.6p1.orig/gss-serv-krb5.c 2018-01-18 09:33:46.500488831 +0100 -+++ openssh-7.6p1/gss-serv-krb5.c 2018-01-18 09:34:35.325942642 +0100 +diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c +--- openssh-7.7p1.orig/gss-serv-krb5.c 2018-04-10 10:51:05.641457358 +0200 ++++ openssh-7.7p1/gss-serv-krb5.c 2018-04-10 10:51:43.741037544 +0200 @@ -378,6 +378,34 @@ return found_principal; } @@ -1367,9 +1367,9 @@ diff -Nur openssh-7.6p1.orig/gss-serv-krb5.c openssh-7.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.6p1.orig/kexgsss.c openssh-7.6p1/kexgsss.c ---- openssh-7.6p1.orig/kexgsss.c 2018-01-18 09:33:46.591487813 +0100 -+++ openssh-7.6p1/kexgsss.c 2018-01-18 09:34:35.325942642 +0100 +diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c +--- openssh-7.7p1.orig/kexgsss.c 2018-04-10 10:51:05.722456465 +0200 ++++ openssh-7.7p1/kexgsss.c 2018-04-10 10:51:43.741037544 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1429,9 +1429,9 @@ diff -Nur openssh-7.6p1.orig/kexgsss.c openssh-7.6p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.6p1.orig/LICENSE.globus_usage openssh-7.6p1/LICENSE.globus_usage ---- openssh-7.6p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/LICENSE.globus_usage 2018-01-18 09:34:35.325942642 +0100 +diff -Nur openssh-7.7p1.orig/LICENSE.globus_usage openssh-7.7p1/LICENSE.globus_usage +--- openssh-7.7p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.7p1/LICENSE.globus_usage 2018-04-10 10:51:43.741037544 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1451,10 +1451,10 @@ diff -Nur openssh-7.6p1.orig/LICENSE.globus_usage openssh-7.6p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.6p1.orig/Makefile.in openssh-7.6p1/Makefile.in ---- openssh-7.6p1.orig/Makefile.in 2018-01-18 09:33:46.591487813 +0100 -+++ openssh-7.6p1/Makefile.in 2018-01-18 09:34:35.326942631 +0100 -@@ -116,8 +116,10 @@ +diff -Nur openssh-7.7p1.orig/Makefile.in openssh-7.7p1/Makefile.in +--- openssh-7.7p1.orig/Makefile.in 2018-04-10 10:51:05.723456454 +0200 ++++ openssh-7.7p1/Makefile.in 2018-04-10 10:51:43.741037544 +0200 +@@ -124,8 +124,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1465,10 +1465,10 @@ diff -Nur openssh-7.6p1.orig/Makefile.in openssh-7.6p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o -diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c ---- openssh-7.6p1.orig/misc.c 2018-01-18 09:33:46.557488194 +0100 -+++ openssh-7.6p1/misc.c 2018-01-18 09:34:35.326942631 +0100 -@@ -171,11 +171,14 @@ +diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c +--- openssh-7.7p1.orig/misc.c 2018-04-10 10:51:05.639457380 +0200 ++++ openssh-7.7p1/misc.c 2018-04-10 10:51:43.742037533 +0200 +@@ -238,11 +238,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1484,7 +1484,7 @@ diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c int wspace = 0; if (*s == NULL) -@@ -183,6 +186,21 @@ +@@ -250,6 +253,21 @@ old = *s; @@ -1506,7 +1506,7 @@ diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); -@@ -238,6 +256,20 @@ +@@ -305,6 +323,20 @@ return copy; } @@ -1527,10 +1527,10 @@ diff -Nur openssh-7.6p1.orig/misc.c openssh-7.6p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.6p1.orig/misc.h openssh-7.6p1/misc.h ---- openssh-7.6p1.orig/misc.h 2018-01-18 09:33:46.557488194 +0100 -+++ openssh-7.6p1/misc.h 2018-01-18 09:34:35.326942631 +0100 -@@ -70,6 +70,7 @@ +diff -Nur openssh-7.7p1.orig/misc.h openssh-7.7p1/misc.h +--- openssh-7.7p1.orig/misc.h 2018-04-10 10:51:05.639457380 +0200 ++++ openssh-7.7p1/misc.h 2018-04-10 10:51:43.743037522 +0200 +@@ -82,6 +82,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1538,10 +1538,10 @@ diff -Nur openssh-7.6p1.orig/misc.h openssh-7.6p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c ---- openssh-7.6p1.orig/monitor.c 2018-01-18 09:33:46.592487802 +0100 -+++ openssh-7.6p1/monitor.c 2018-01-18 09:34:35.327942620 +0100 -@@ -164,6 +164,9 @@ +diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c +--- openssh-7.7p1.orig/monitor.c 2018-04-10 10:51:05.723456454 +0200 ++++ openssh-7.7p1/monitor.c 2018-04-10 10:51:43.744037511 +0200 +@@ -165,6 +165,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_sign(int, Buffer *); @@ -1551,7 +1551,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c int mm_answer_gss_updatecreds(int, Buffer *); #endif -@@ -213,7 +216,7 @@ +@@ -215,7 +218,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1560,7 +1560,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -221,7 +224,7 @@ +@@ -223,7 +226,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1569,7 +1569,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -249,8 +252,11 @@ +@@ -251,8 +254,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1582,7 +1582,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -260,6 +266,8 @@ +@@ -262,6 +268,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1591,7 +1591,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -339,6 +347,8 @@ +@@ -343,6 +351,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1600,7 +1600,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -451,6 +461,8 @@ +@@ -458,6 +468,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1608,8 +1608,8 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c + monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); #endif - if (!no_pty_flag) { -@@ -758,14 +770,17 @@ + if (auth_opts->permit_pty_flag) { +@@ -767,14 +779,17 @@ debug3("%s", __func__); @@ -1630,7 +1630,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -1966,13 +1981,16 @@ +@@ -1992,13 +2007,16 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1648,7 +1648,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1980,7 +1998,10 @@ +@@ -2006,7 +2024,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1660,7 +1660,7 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1989,6 +2010,68 @@ +@@ -2015,6 +2036,68 @@ return (authenticated); } @@ -1729,9 +1729,9 @@ diff -Nur openssh-7.6p1.orig/monitor.c openssh-7.6p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { -diff -Nur openssh-7.6p1.orig/monitor.h openssh-7.6p1/monitor.h ---- openssh-7.6p1.orig/monitor.h 2018-01-18 09:33:46.567488082 +0100 -+++ openssh-7.6p1/monitor.h 2018-01-18 09:34:35.327942620 +0100 +diff -Nur openssh-7.7p1.orig/monitor.h openssh-7.7p1/monitor.h +--- openssh-7.7p1.orig/monitor.h 2018-04-10 10:51:05.698456730 +0200 ++++ openssh-7.7p1/monitor.h 2018-04-10 10:51:43.744037511 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1745,10 +1745,10 @@ diff -Nur openssh-7.6p1.orig/monitor.h openssh-7.6p1/monitor.h }; struct monitor { -diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c ---- openssh-7.6p1.orig/monitor_wrap.c 2018-01-18 09:33:46.583487903 +0100 -+++ openssh-7.6p1/monitor_wrap.c 2018-01-18 09:34:35.327942620 +0100 -@@ -992,12 +992,13 @@ +diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c +--- openssh-7.7p1.orig/monitor_wrap.c 2018-04-10 10:51:05.715456543 +0200 ++++ openssh-7.7p1/monitor_wrap.c 2018-04-10 10:51:43.744037511 +0200 +@@ -998,12 +998,13 @@ } int @@ -1763,7 +1763,7 @@ diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1010,6 +1011,83 @@ +@@ -1016,6 +1017,83 @@ return (authenticated); } @@ -1847,10 +1847,10 @@ diff -Nur openssh-7.6p1.orig/monitor_wrap.c openssh-7.6p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-7.6p1.orig/monitor_wrap.h openssh-7.6p1/monitor_wrap.h ---- openssh-7.6p1.orig/monitor_wrap.h 2018-01-18 09:33:46.573488015 +0100 -+++ openssh-7.6p1/monitor_wrap.h 2018-01-18 09:34:35.328942608 +0100 -@@ -62,9 +62,13 @@ +diff -Nur openssh-7.7p1.orig/monitor_wrap.h openssh-7.7p1/monitor_wrap.h +--- openssh-7.7p1.orig/monitor_wrap.h 2018-04-10 10:51:05.704456664 +0200 ++++ openssh-7.7p1/monitor_wrap.h 2018-04-10 10:51:43.745037500 +0200 +@@ -65,9 +65,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1865,10 +1865,10 @@ diff -Nur openssh-7.6p1.orig/monitor_wrap.h openssh-7.6p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.6p1.orig/readconf.c openssh-7.6p1/readconf.c ---- openssh-7.6p1.orig/readconf.c 2018-01-18 09:33:46.577487970 +0100 -+++ openssh-7.6p1/readconf.c 2018-01-18 09:34:35.328942608 +0100 -@@ -1983,13 +1983,13 @@ +diff -Nur openssh-7.7p1.orig/readconf.c openssh-7.7p1/readconf.c +--- openssh-7.7p1.orig/readconf.c 2018-04-10 10:51:05.709456609 +0200 ++++ openssh-7.7p1/readconf.c 2018-04-10 10:51:43.746037489 +0200 +@@ -1960,13 +1960,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1886,9 +1886,9 @@ diff -Nur openssh-7.6p1.orig/readconf.c openssh-7.6p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.6p1.orig/readconf.h openssh-7.6p1/readconf.h ---- openssh-7.6p1.orig/readconf.h 2018-01-18 09:33:46.517488641 +0100 -+++ openssh-7.6p1/readconf.h 2018-01-18 09:34:35.328942608 +0100 +diff -Nur openssh-7.7p1.orig/readconf.h openssh-7.7p1/readconf.h +--- openssh-7.7p1.orig/readconf.h 2018-04-10 10:51:05.656457193 +0200 ++++ openssh-7.7p1/readconf.h 2018-04-10 10:51:43.746037489 +0200 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1898,10 +1898,10 @@ diff -Nur openssh-7.6p1.orig/readconf.h openssh-7.6p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c ---- openssh-7.6p1.orig/servconf.c 2018-01-18 09:33:46.584487892 +0100 -+++ openssh-7.6p1/servconf.c 2018-01-18 09:34:35.329942597 +0100 -@@ -75,6 +75,7 @@ +diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c +--- openssh-7.7p1.orig/servconf.c 2018-04-10 10:51:05.716456531 +0200 ++++ openssh-7.7p1/servconf.c 2018-04-10 10:51:43.747037477 +0200 +@@ -83,6 +83,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1909,7 +1909,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -115,9 +116,11 @@ +@@ -125,9 +126,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1921,7 +1921,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -162,6 +165,8 @@ +@@ -172,6 +175,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1930,7 +1930,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -210,6 +215,8 @@ +@@ -255,6 +260,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1939,7 +1939,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -283,13 +290,17 @@ +@@ -330,13 +337,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1959,7 +1959,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -417,7 +428,7 @@ +@@ -469,7 +480,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1968,7 +1968,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -439,10 +450,14 @@ +@@ -491,10 +502,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1983,7 +1983,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -468,8 +483,10 @@ +@@ -520,8 +535,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1994,7 +1994,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -515,7 +532,14 @@ +@@ -567,7 +584,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -2009,7 +2009,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -523,7 +547,10 @@ +@@ -575,7 +599,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -2020,7 +2020,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -592,6 +619,8 @@ +@@ -644,6 +671,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -2029,7 +2029,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1090,6 +1119,10 @@ +@@ -1244,6 +1273,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2040,7 +2040,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1297,6 +1330,10 @@ +@@ -1454,6 +1487,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2051,7 +2051,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1305,6 +1342,10 @@ +@@ -1462,6 +1499,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2062,7 +2062,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1325,6 +1366,12 @@ +@@ -1482,6 +1523,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2075,7 +2075,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1797,6 +1844,35 @@ +@@ -1939,6 +1986,35 @@ *charptr = xstrdup(arg); break; @@ -2111,7 +2111,7 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2092,6 +2168,7 @@ +@@ -2232,6 +2308,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2119,10 +2119,10 @@ diff -Nur openssh-7.6p1.orig/servconf.c openssh-7.6p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h ---- openssh-7.6p1.orig/servconf.h 2018-01-18 09:33:46.523488574 +0100 -+++ openssh-7.6p1/servconf.h 2018-01-18 09:34:35.329942597 +0100 -@@ -122,9 +122,12 @@ +diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h +--- openssh-7.7p1.orig/servconf.h 2018-04-10 10:51:05.661457138 +0200 ++++ openssh-7.7p1/servconf.h 2018-04-10 10:51:43.748037466 +0200 +@@ -133,9 +133,12 @@ * authenticated with Kerberos. */ int use_kuserok; int enable_k5users; @@ -2135,7 +2135,7 @@ diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -181,6 +184,7 @@ +@@ -192,6 +195,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2143,7 +2143,7 @@ diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h int permit_tun; -@@ -188,6 +192,10 @@ +@@ -199,6 +203,10 @@ u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */ char *chroot_directory; @@ -2154,10 +2154,10 @@ diff -Nur openssh-7.6p1.orig/servconf.h openssh-7.6p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.6p1.orig/ssh.1 openssh-7.6p1/ssh.1 ---- openssh-7.6p1.orig/ssh.1 2018-01-18 09:33:46.514488675 +0100 -+++ openssh-7.6p1/ssh.1 2018-01-18 09:34:35.330942586 +0100 -@@ -1404,6 +1404,18 @@ +diff -Nur openssh-7.7p1.orig/ssh.1 openssh-7.7p1/ssh.1 +--- openssh-7.7p1.orig/ssh.1 2018-04-10 10:51:05.652457237 +0200 ++++ openssh-7.7p1/ssh.1 2018-04-10 10:51:43.748037466 +0200 +@@ -1419,6 +1419,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2176,10 +2176,10 @@ diff -Nur openssh-7.6p1.orig/ssh.1 openssh-7.6p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c ---- openssh-7.6p1.orig/ssh.c 2018-01-18 09:33:46.594487780 +0100 -+++ openssh-7.6p1/ssh.c 2018-01-18 09:34:35.330942586 +0100 -@@ -470,6 +470,32 @@ +diff -Nur openssh-7.7p1.orig/ssh.c openssh-7.7p1/ssh.c +--- openssh-7.7p1.orig/ssh.c 2018-04-10 10:51:05.725456432 +0200 ++++ openssh-7.7p1/ssh.c 2018-04-10 10:51:43.749037455 +0200 +@@ -522,6 +522,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2212,7 +2212,7 @@ diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1189,8 +1215,12 @@ +@@ -1283,8 +1309,12 @@ logit("FIPS mode initialized"); } @@ -2224,11 +2224,11 @@ diff -Nur openssh-7.6p1.orig/ssh.c openssh-7.6p1/ssh.c + options.implicit = 0; + } + /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) - fatal("gethostname: %s", strerror(errno)); -diff -Nur openssh-7.6p1.orig/ssh_config openssh-7.6p1/ssh_config ---- openssh-7.6p1.orig/ssh_config 2018-01-18 09:33:46.470489167 +0100 -+++ openssh-7.6p1/ssh_config 2018-01-18 09:34:35.330942586 +0100 +diff -Nur openssh-7.7p1.orig/ssh_config openssh-7.7p1/ssh_config +--- openssh-7.7p1.orig/ssh_config 2018-04-10 10:51:05.610457699 +0200 ++++ openssh-7.7p1/ssh_config 2018-04-10 10:51:43.750037444 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2244,9 +2244,9 @@ diff -Nur openssh-7.6p1.orig/ssh_config openssh-7.6p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 ---- openssh-7.6p1.orig/ssh_config.5 2018-01-18 09:33:46.537488417 +0100 -+++ openssh-7.6p1/ssh_config.5 2018-01-18 09:34:35.331942575 +0100 +diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 +--- openssh-7.7p1.orig/ssh_config.5 2018-04-10 10:51:05.689456829 +0200 ++++ openssh-7.7p1/ssh_config.5 2018-04-10 10:51:43.750037444 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2260,7 +2260,7 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -720,7 +726,7 @@ +@@ -727,7 +733,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2269,7 +2269,7 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -728,12 +734,12 @@ +@@ -735,12 +741,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2284,7 +2284,7 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -765,7 +771,7 @@ +@@ -772,7 +778,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2293,7 +2293,7 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1214,7 +1220,7 @@ +@@ -1234,7 +1240,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2302,9 +2302,9 @@ diff -Nur openssh-7.6p1.orig/ssh_config.5 openssh-7.6p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c ---- openssh-7.6p1.orig/sshconnect2.c 2018-01-18 09:33:46.593487791 +0100 -+++ openssh-7.6p1/sshconnect2.c 2018-01-18 09:34:35.331942575 +0100 +diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c +--- openssh-7.7p1.orig/sshconnect2.c 2018-04-10 10:51:05.724456443 +0200 ++++ openssh-7.7p1/sshconnect2.c 2018-04-10 10:51:43.751037433 +0200 @@ -285,7 +285,7 @@ #ifdef GSSAPI @@ -2323,7 +2323,7 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c else gss_host = host; -@@ -852,6 +852,11 @@ +@@ -841,6 +841,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2335,7 +2335,7 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -941,7 +946,8 @@ +@@ -930,7 +935,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2345,7 +2345,7 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); packet_send(); } else { -@@ -1089,6 +1095,20 @@ +@@ -1078,6 +1084,20 @@ return 0; } @@ -2366,7 +2366,7 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -1106,8 +1126,16 @@ +@@ -1095,8 +1115,16 @@ return (0); } @@ -2383,7 +2383,7 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); -@@ -1118,7 +1146,15 @@ +@@ -1107,7 +1135,15 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2399,10 +2399,10 @@ diff -Nur openssh-7.6p1.orig/sshconnect2.c openssh-7.6p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.6p1.orig/sshd.8 openssh-7.6p1/sshd.8 ---- openssh-7.6p1.orig/sshd.8 2018-01-18 09:33:46.480489055 +0100 -+++ openssh-7.6p1/sshd.8 2018-01-18 09:34:35.331942575 +0100 -@@ -754,6 +754,44 @@ +diff -Nur openssh-7.7p1.orig/sshd.8 openssh-7.7p1/sshd.8 +--- openssh-7.7p1.orig/sshd.8 2018-04-10 10:51:05.620457589 +0200 ++++ openssh-7.7p1/sshd.8 2018-04-10 10:51:43.752037422 +0200 +@@ -760,6 +760,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2447,18 +2447,18 @@ diff -Nur openssh-7.6p1.orig/sshd.8 openssh-7.6p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c ---- openssh-7.6p1.orig/sshd.c 2018-01-18 09:33:46.594487780 +0100 -+++ openssh-7.6p1/sshd.c 2018-01-18 09:34:35.332942564 +0100 -@@ -129,6 +129,7 @@ - #include "ssh-sandbox.h" +diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c +--- openssh-7.7p1.orig/sshd.c 2018-04-10 10:51:05.725456432 +0200 ++++ openssh-7.7p1/sshd.c 2018-04-10 10:51:43.753037411 +0200 +@@ -130,6 +130,7 @@ + #include "auth-options.h" #include "version.h" #include "ssherr.h" +#include "ssh-globus-usage.h" /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -@@ -1703,6 +1704,13 @@ +@@ -1749,6 +1750,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2472,7 +2472,7 @@ diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2183,7 +2191,7 @@ +@@ -2247,7 +2255,7 @@ #endif #ifdef GSSAPI @@ -2481,10 +2481,10 @@ diff -Nur openssh-7.6p1.orig/sshd.c openssh-7.6p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config ---- openssh-7.6p1.orig/sshd_config 2018-01-18 09:33:46.510488719 +0100 -+++ openssh-7.6p1/sshd_config 2018-01-18 09:34:35.333942552 +0100 -@@ -85,10 +85,11 @@ +diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config +--- openssh-7.7p1.orig/sshd_config 2018-04-10 10:51:05.648457281 +0200 ++++ openssh-7.7p1/sshd_config 2018-04-10 10:51:43.753037411 +0200 +@@ -84,10 +84,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2498,7 +2498,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -104,6 +105,10 @@ +@@ -103,6 +104,10 @@ # problems. UsePAM yes @@ -2509,7 +2509,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -139,6 +144,10 @@ +@@ -138,6 +143,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2520,10 +2520,10 @@ diff -Nur openssh-7.6p1.orig/sshd_config openssh-7.6p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 ---- openssh-7.6p1.orig/sshd_config.5 2018-01-18 09:33:46.538488406 +0100 -+++ openssh-7.6p1/sshd_config.5 2018-01-18 09:34:35.333942552 +0100 -@@ -574,6 +574,15 @@ +diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 +--- openssh-7.7p1.orig/sshd_config.5 2018-04-10 10:51:05.673457005 +0200 ++++ openssh-7.7p1/sshd_config.5 2018-04-10 10:51:43.754037400 +0200 +@@ -575,6 +575,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. @@ -2539,7 +2539,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -631,15 +640,34 @@ +@@ -632,15 +641,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2575,7 +2575,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -650,7 +678,7 @@ +@@ -651,7 +679,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2584,7 +2584,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -689,7 +717,6 @@ +@@ -690,7 +718,6 @@ .Pp The default is .Dq gss-gex-sha1-,gss-group14-sha1- . @@ -2592,7 +2592,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -@@ -1509,6 +1536,103 @@ +@@ -1550,6 +1577,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2696,7 +2696,7 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1550,6 +1674,12 @@ +@@ -1591,6 +1715,12 @@ as a non-root user. The default is .Cm no . @@ -2709,9 +2709,9 @@ diff -Nur openssh-7.6p1.orig/sshd_config.5 openssh-7.6p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.6p1.orig/ssh-globus-usage.c openssh-7.6p1/ssh-globus-usage.c ---- openssh-7.6p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/ssh-globus-usage.c 2018-01-18 09:34:35.333942552 +0100 +diff -Nur openssh-7.7p1.orig/ssh-globus-usage.c openssh-7.7p1/ssh-globus-usage.c +--- openssh-7.7p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.7p1/ssh-globus-usage.c 2018-04-10 10:51:43.755037389 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3109,9 +3109,9 @@ diff -Nur openssh-7.6p1.orig/ssh-globus-usage.c openssh-7.6p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.6p1.orig/ssh-globus-usage.h openssh-7.6p1/ssh-globus-usage.h ---- openssh-7.6p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.6p1/ssh-globus-usage.h 2018-01-18 09:34:35.333942552 +0100 +diff -Nur openssh-7.7p1.orig/ssh-globus-usage.h openssh-7.7p1/ssh-globus-usage.h +--- openssh-7.7p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.7p1/ssh-globus-usage.h 2018-04-10 10:51:43.755037389 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3161,9 +3161,9 @@ diff -Nur openssh-7.6p1.orig/ssh-globus-usage.h openssh-7.6p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.6p1.orig/ssh-gss.h openssh-7.6p1/ssh-gss.h ---- openssh-7.6p1.orig/ssh-gss.h 2018-01-18 09:33:46.537488417 +0100 -+++ openssh-7.6p1/ssh-gss.h 2018-01-18 09:34:35.334942541 +0100 +diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h +--- openssh-7.7p1.orig/ssh-gss.h 2018-04-10 10:51:05.672457016 +0200 ++++ openssh-7.7p1/ssh-gss.h 2018-04-10 10:51:43.755037389 +0200 @@ -93,12 +93,14 @@ } ssh_gssapi_ccache; @@ -3216,12 +3216,12 @@ diff -Nur openssh-7.6p1.orig/ssh-gss.h openssh-7.6p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.6p1.orig/version.h openssh-7.6p1/version.h ---- openssh-7.6p1.orig/version.h 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/version.h 2018-01-18 09:34:35.334942541 +0100 +diff -Nur openssh-7.7p1.orig/version.h openssh-7.7p1/version.h +--- openssh-7.7p1.orig/version.h 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/version.h 2018-04-10 10:51:43.755037389 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_7.6" + #define SSH_VERSION "OpenSSH_7.7" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/sources b/sources index 3d485c5..391466e 100644 --- a/sources +++ b/sources @@ -1 +1,3 @@ -SHA512 (openssh-7.6p1.tar.gz) = de17fdcb8239401f76740c8d689a8761802f6df94e68d953f3c70b9f4f8bdb403617c48c1d01cc8c368d88e9d50aee540bf03d5a36687dfb39dfd28d73029d72 +SHA512 (openssh-7.7p1.tar.gz) = 597252cb48209a0cb98ca1928a67e8d63e4275252f25bc37269204c108f034baade6ba0634e32ae63422fddd280f73096a6b31ad2f2e7a848dde75ca30e14261 +SHA512 (openssh-7.7p1.tar.gz.asc) = 9445a589a84538fb0b4eae0f7bf6ce46def51b09254d6fffcc6ed64472f10ccf9e4d5d200387725043039d77ca886e2c8e8f3128e7969c582156fafb0783988d +SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From e4f9d5390631baadaf51e61fe28e0111a3f9cf18 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 12 Apr 2018 14:34:43 +0200 Subject: [PATCH 056/146] Based on openssh-7.7p1-2.fc28 --- gsi-openssh.spec | 5 ++++- openssh-7.6p1-pkcs11-uri.patch | 29 +++-------------------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a58072a..9d476e2 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.7p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -545,6 +545,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Apr 12 2018 Mattias Ellert - 7.7p1-2 +- Based on openssh-7.7p1-2.fc28 + * Tue Apr 10 2018 Mattias Ellert - 7.7p1-1 - Based on openssh-7.7p1-1.fc28 diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch index 0114eb7..efafa70 100644 --- a/openssh-7.6p1-pkcs11-uri.patch +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -163,29 +163,6 @@ index d7bcaf01..171a8597 100644 echo "" -diff --git a/readconf.c b/readconf.c -index 88051db5..c1e7ce93 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -1016,7 +1016,8 @@ parse_time: - break; - - case oIdentityFile: -- arg = strdelim(&s); -+ /* Can't use strdelim() becase it would break on equal signs */ -+ arg = s; - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep) { -@@ -1027,7 +1028,7 @@ parse_time: - add_identity_file(options, NULL, - arg, flags & SSHCONF_USERCONF); - } -- break; -+ return 0; - - case oCertificateFile: - arg = strdelim(&s); diff --git a/regress/Makefile b/regress/Makefile index d15898ad..9c15afa4 100644 --- a/regress/Makefile @@ -483,7 +460,7 @@ index 00000000..cf98e379 + + +trace "Test PKCS#11 URI specification in configuration files" -+echo "IdentityFile pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++echo "IdentityFile \"pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}\"" \ + >> $OBJ/ssh_proxy +trace " (second key should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 @@ -502,7 +479,7 @@ index 00000000..cf98e379 +sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy + +trace "Test PKCS#11 URI specification in configuration files with bogus spaces" -+echo "IdentityFile pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} " \ ++echo "IdentityFile \" pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} \"" \ + >> $OBJ/ssh_proxy +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 +r=$? @@ -525,7 +502,7 @@ index 00000000..cf98e379 + +trace "Regress: Missing provider in PKCS11URI option" +${SSH} -F $OBJ/ssh_proxy \ -+ -o IdentityFile='pkcs11:token=segfault' somehost exit 5 ++ -o IdentityFile=\"pkcs11:token=segfault\" somehost exit 5 +r=$? +if [ $r -eq 139 ]; then + fail "ssh connect with missing provider_id from configuration option" \ From 9975263d7c2208e23cf815bb0079172782d7089a Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 17 Apr 2018 12:57:28 +0200 Subject: [PATCH 057/146] Based on openssh-7.7p1-3.fc28 --- gsi-openssh.spec | 8 +- openssh-7.7p1-tun-devices.patch | 152 ++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 openssh-7.7p1-tun-devices.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9d476e2..e69e701 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.7p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -172,6 +172,8 @@ Patch950: openssh-7.5p1-sandbox.patch Patch951: openssh-7.6p1-pkcs11-uri.patch # PKCS#11 ECDSA keys (upstream #2474, 8th iteration) Patch952: openssh-7.6p1-pkcs11-ecdsa.patch +# Opening tun devices fails + other regressions in OpenSSH v7.7 (#2855, #1567775) +Patch953: openssh-7.7p1-tun-devices.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -334,6 +336,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch950 -p1 -b .sandbox %patch951 -p1 -b .pkcs11-uri %patch952 -p1 -b .pkcs11-ecdsa +%patch953 -p1 -b .tun-devices %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -545,6 +548,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Apr 17 2018 Mattias Ellert - 7.7p1-3 +- Based on openssh-7.7p1-3.fc28 + * Thu Apr 12 2018 Mattias Ellert - 7.7p1-2 - Based on openssh-7.7p1-2.fc28 diff --git a/openssh-7.7p1-tun-devices.patch b/openssh-7.7p1-tun-devices.patch new file mode 100644 index 0000000..efd82c3 --- /dev/null +++ b/openssh-7.7p1-tun-devices.patch @@ -0,0 +1,152 @@ +From 4f60e4f66b5880c9f50ef758e8b7f7a9ae786d21 Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Fri, 13 Apr 2018 13:13:33 +1000 +Subject: [PATCH 1/5] Revert $REGRESSTMP changes. + +Revert 3fd2d229 and subsequent changes as they turned out to be a +portability hassle. +--- + Makefile.in | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/Makefile.in b/Makefile.in +index 04e1c8e53..dd942ee7b 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -577,8 +577,6 @@ regress-binaries: regress/modpipe$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + regress/misc/kexfuzz/kexfuzz$(EXEEXT) + +-REGRESSTMP = "$(PWD)/regress" +- + tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) + BUILDDIR=`pwd`; \ + TEST_SSH_SCP="$${BUILDDIR}/scp"; \ +@@ -602,7 +600,7 @@ tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) + .OBJDIR="$${BUILDDIR}/regress" \ + .CURDIR="`pwd`" \ + BUILDDIR="$${BUILDDIR}" \ +- OBJ="$(REGRESSTMP)" \ ++ OBJ="$${BUILDDIR}/regress/" \ + PATH="$${BUILDDIR}:$${PATH}" \ + TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ + TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ + +From b81b2d120e9c8a83489e241620843687758925ad Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Fri, 13 Apr 2018 13:38:06 +1000 +Subject: [PATCH 2/5] Fix tunnel forwarding broken in 7.7p1 + +bz2855, ok dtucker@ +--- + openbsd-compat/port-net.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/openbsd-compat/port-net.c b/openbsd-compat/port-net.c +index 7050629c3..bb535626f 100644 +--- a/openbsd-compat/port-net.c ++++ b/openbsd-compat/port-net.c +@@ -185,7 +185,7 @@ sys_tun_open(int tun, int mode, char **ifname) + else + debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); + +- if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) ++ if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) + goto failed; + + return (fd); +@@ -272,7 +272,7 @@ sys_tun_open(int tun, int mode, char **ifname) + goto failed; + } + +- if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) ++ if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) + goto failed; + + close(sock); + +From 341727df910e12e26ef161508ed76d91c40a61eb Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Mon, 9 Apr 2018 23:54:49 +0000 +Subject: [PATCH 3/5] upstream: don't kill ssh-agent's listening socket + entriely if we + +fail to accept a connection; bz#2837, patch from Lukas Kuster + +OpenBSD-Commit-ID: 52413f5069179bebf30d38f524afe1a2133c738f +--- + ssh-agent.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/ssh-agent.c b/ssh-agent.c +index 2a4578b03..68de56ce6 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: ssh-agent.c,v 1.228 2018/02/23 15:58:37 markus Exp $ */ ++/* $OpenBSD: ssh-agent.c,v 1.229 2018/04/09 23:54:49 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -909,9 +909,8 @@ after_poll(struct pollfd *pfd, size_t npfd) + /* Process events */ + switch (sockets[socknum].type) { + case AUTH_SOCKET: +- if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && +- handle_socket_read(socknum) != 0) +- close_socket(&sockets[socknum]); ++ if ((pfd[i].revents & (POLLIN|POLLERR)) != 0) ++ handle_socket_read(socknum); + break; + case AUTH_CONNECTION: + if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && + +From 3402cc607049ac900f6d8574bc2ce657a8cdf4fe Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Fri, 13 Apr 2018 13:43:55 +1000 +Subject: [PATCH 4/5] Using "==" in shell tests is not portable. + +Patch from rsbecker at nexbridge.com. +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 663062bef..2e84d90b7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1398,7 +1398,7 @@ AC_RUN_IFELSE( + ) + AC_MSG_RESULT([$func_calloc_0_nonnull]) + +-if test "x$func_calloc_0_nonnull" == "xyes"; then ++if test "x$func_calloc_0_nonnull" = "xyes"; then + AC_DEFINE(HAVE_CALLOC, 1, [calloc(0, x) returns non-null]) + else + AC_DEFINE(HAVE_CALLOC, 0, [calloc(0, x) returns NULL]) + +From 85fe48fd49f2e81fa30902841b362cfbb7f1933b Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Sat, 14 Apr 2018 21:50:41 +0000 +Subject: [PATCH 5/5] upstream: don't free the %C expansion, it's used later + for + +LocalCommand + +OpenBSD-Commit-ID: 857b5cb37b2d856bfdfce61289a415257a487fb1 +--- + ssh.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ssh.c b/ssh.c +index d3619fe29..9c011dd7e 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -1323,7 +1323,6 @@ main(int ac, char **av) + (char *)NULL); + free(cp); + } +- free(conn_hash_hex); + + if (config_test) { + dump_client_config(&options, host); From db96e2a44de48bd8d1185df802e7409888db0703 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 5 Jul 2018 15:46:16 +0200 Subject: [PATCH 058/146] Based on openssh-7.7p1-5.fc28 --- gsi-openssh.spec | 15 +- gsisshd.pam | 1 + ...h-6.3p1-krb5-use-default_ccache_name.patch | 247 ------- openssh-6.6p1-GSSAPIEnablek5users.patch | 6 +- openssh-6.6p1-kuserok.patch | 24 +- openssh-7.0p1-gssKexAlgorithms.patch | 2 +- openssh-7.2p1-gsskex.patch | 19 +- openssh-7.2p2-k5login_directory.patch | 2 +- openssh-7.5p1-gss-environment.patch | 259 ------- openssh-7.7p1-gsissh.patch | 261 ++++--- openssh-7.7p1-gssapi-new-unique.patch | 646 ++++++++++++++++++ ...redhat.patch => openssh-7.7p1-redhat.patch | 57 +- 12 files changed, 859 insertions(+), 680 deletions(-) delete mode 100644 openssh-6.3p1-krb5-use-default_ccache_name.patch delete mode 100644 openssh-7.5p1-gss-environment.patch create mode 100644 openssh-7.7p1-gssapi-new-unique.patch rename openssh-6.6p1-redhat.patch => openssh-7.7p1-redhat.patch (72%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e69e701..ea90bde 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.7p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -99,7 +99,7 @@ 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-6.6p1-redhat.patch +Patch707: openssh-7.7p1-redhat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :) Patch708: openssh-6.6p1-entropy.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) @@ -124,12 +124,11 @@ Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch # Documentation about GSSAPI # from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655 Patch803: openssh-7.1p1-gssapi-documentation.patch -# use default_ccache_name from /etc/krb5.conf (#991186) -Patch804: openssh-6.3p1-krb5-use-default_ccache_name.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 -# Do not export KRBCCNAME if the default path is used (#1199363) -Patch806: openssh-7.5p1-gss-environment.patch # Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02 Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch @@ -312,7 +311,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch803 -p1 -b .gss-docs %patch804 -p1 -b .ccache_name %patch805 -p1 -b .k5login -%patch806 -p1 -b .gss-env %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok @@ -548,6 +546,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Jul 05 2018 Mattias Ellert - 7.7p1-4 +- Based on openssh-7.7p1-5.fc28 + * Tue Apr 17 2018 Mattias Ellert - 7.7p1-3 - Based on openssh-7.7p1-3.fc28 diff --git a/gsisshd.pam b/gsisshd.pam index 4354458..780f62e 100644 --- a/gsisshd.pam +++ b/gsisshd.pam @@ -12,5 +12,6 @@ session required pam_loginuid.so session required pam_selinux.so open env_params session required pam_namespace.so session optional pam_keyinit.so force revoke +session optional pam_motd.so session include password-auth session include postlogin diff --git a/openssh-6.3p1-krb5-use-default_ccache_name.patch b/openssh-6.3p1-krb5-use-default_ccache_name.patch deleted file mode 100644 index dd201a4..0000000 --- a/openssh-6.3p1-krb5-use-default_ccache_name.patch +++ /dev/null @@ -1,247 +0,0 @@ -diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c ---- openssh-6.3p1/auth-krb5.c.ccache_name 2013-10-23 22:03:52.322950759 +0200 -+++ openssh-6.3p1/auth-krb5.c 2013-10-23 22:04:24.295799873 +0200 -@@ -50,7 +50,9 @@ - #include - #include - #include -+#include - #include -+#include - - extern ServerOptions options; - -@@ -91,6 +93,7 @@ auth_krb5_password(Authctxt *authctxt, c - #endif - krb5_error_code problem; - krb5_ccache ccache = NULL; -+ const char *ccache_type; - int len; - char *client, *platform_client; - const char *errmsg; -@@ -191,12 +194,30 @@ auth_krb5_password(Authctxt *authctxt, c - goto out; - #endif - -+ ccache_type = krb5_cc_get_type(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - -- len = strlen(authctxt->krb5_ticket_file) + 6; -+ if (authctxt->krb5_ticket_file[0] == ':') -+ authctxt->krb5_ticket_file++; -+ -+ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type) + 2; - authctxt->krb5_ccname = xmalloc(len); -- snprintf(authctxt->krb5_ccname, len, "FILE:%s", -+ -+#ifdef USE_CCAPI -+ snprintf(authctxt->krb5_ccname, len, "API:%s", - authctxt->krb5_ticket_file); -+#else -+ snprintf(authctxt->krb5_ccname, len, "%s:%s", -+ ccache_type, authctxt->krb5_ticket_file); -+#endif -+ -+ if (strcmp(ccache_type, "DIR") == 0) { -+ char *p; -+ p = strrchr(authctxt->krb5_ccname, '/'); -+ if (p) -+ *p = '\0'; -+ } -+ - - #ifdef USE_PAM - if (options.use_pam) -@@ -235,10 +256,34 @@ auth_krb5_password(Authctxt *authctxt, c - void - krb5_cleanup_proc(Authctxt *authctxt) - { -+ struct stat krb5_ccname_stat; -+ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end; -+ - debug("krb5_cleanup_proc called"); - if (authctxt->krb5_fwd_ccache) { - krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - authctxt->krb5_fwd_ccache = NULL; -+ -+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10); -+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1; -+ *krb5_ccname_dir_start++ = '\0'; -+ if (strcmp(krb5_ccname, "DIR") == 0) { -+ -+ strcat(krb5_ccname_dir_start, "/primary"); -+ -+ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) { -+ if (unlink(krb5_ccname_dir_start) == 0) { -+ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/'); -+ *krb5_ccname_dir_end = '\0'; -+ if (rmdir(krb5_ccname_dir_start) == -1) -+ debug("cache dir '%s' remove failed: %s", krb5_ccname_dir_start, strerror(errno)); -+ } -+ else -+ debug("cache primary file '%s', remove failed: %s", -+ krb5_ccname_dir_start, strerror(errno) -+ ); -+ } -+ } - } - if (authctxt->krb5_user) { - krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); -@@ -250,34 +295,139 @@ krb5_cleanup_proc(Authctxt *authctxt) - } - } - -+int -+ssh_asprintf_append(char **dsc, const char *fmt, ...) { -+ char *src, *old; -+ va_list ap; -+ int i; -+ -+ va_start(ap, fmt); -+ i = vasprintf(&src, fmt, ap); -+ va_end(ap); -+ -+ if (i == -1 || src == NULL) -+ return -1; -+ -+ old = *dsc; -+ -+ i = asprintf(dsc, "%s%s", *dsc, src); -+ if (i == -1 || src == NULL) { -+ free(src); -+ return -1; -+ } -+ -+ free(old); -+ free(src); -+ -+ return i; -+} -+ -+int -+ssh_krb5_expand_template(char **result, const char *template) { -+ char *p_n, *p_o, *r, *tmp_template; -+ -+ if (template == NULL) -+ return -1; -+ -+ tmp_template = p_n = p_o = xstrdup(template); -+ r = xstrdup(""); -+ -+ while ((p_n = strstr(p_o, "%{")) != NULL) { -+ -+ *p_n++ = '\0'; -+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) -+ goto cleanup; -+ -+ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 || -+ strncmp(p_n, "{USERID}", 8) == 0) { -+ p_o = strchr(p_n, '}') + 1; -+ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1) -+ goto cleanup; -+ continue; -+ } -+ else if (strncmp(p_n, "{TEMP}", 6) == 0) { -+ p_o = strchr(p_n, '}') + 1; -+ if (ssh_asprintf_append(&r, "/tmp") == -1) -+ goto cleanup; -+ continue; -+ } else { -+ p_o = strchr(p_n, '}') + 1; -+ p_o = '\0'; -+ debug("%s: unsupported token %s in %s", __func__, p_n, template); -+ /* unknown token, fallback to the default */ -+ goto cleanup; -+ } -+ } -+ -+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) -+ goto cleanup; -+ -+ *result = r; -+ free(tmp_template); -+ return 0; -+ -+cleanup: -+ free(r); -+ free(tmp_template); -+ return -1; -+} -+ -+krb5_error_code -+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { -+ profile_t p; -+ int ret = 0; -+ char *value = NULL; -+ -+ ret = krb5_get_profile(ctx, &p); -+ if (ret) -+ return ret; -+ -+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); -+ if (ret) -+ return ret; -+ -+ ret = ssh_krb5_expand_template(ccname, value); -+ -+ return ret; -+} -+ - #ifndef HEIMDAL - krb5_error_code - ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { - int tmpfd, ret, oerrno; -- char ccname[40]; -+ char *ccname; -+#ifdef USE_CCAPI -+ char cctemplate[] = "API:krb5cc_%d"; -+#else - mode_t old_umask; -+ char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; - -- 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; -- } -+#endif -+ -+ ret = ssh_krb5_get_cctemplate(ctx, &ccname); - -- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { -+ if (ret) { -+ ret = asprintf(&ccname, cctemplate, geteuid()); -+ if (ret == -1) -+ return ENOMEM; -+ old_umask = umask(0177); -+ tmpfd = mkstemp(ccname + strlen("FILE:")); - oerrno = errno; -- logit("fchmod(): %.100s", strerror(oerrno)); -+ umask(old_umask); -+ if (tmpfd == -1) { -+ logit("mkstemp(): %.100s", strerror(oerrno)); -+ return oerrno; -+ } -+ -+ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { -+ oerrno = errno; -+ logit("fchmod(): %.100s", strerror(oerrno)); -+ close(tmpfd); -+ return oerrno; -+ } - close(tmpfd); -- return oerrno; - } -- close(tmpfd); -+ debug("%s: Setting ccname to %s", __func__, ccname); - - return (krb5_cc_resolve(ctx, ccname, ccache)); - } diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 9f91f14..5dec15b 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -82,8 +82,8 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif + dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); #endif @@ -93,8 +93,8 @@ 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_get_afs_token; /* If true, try to get AFS token if - * authenticated with Kerberos. */ + int kerberos_unique_ticket; /* If true, the aquired ticket will + * be stored in per-session ccache */ int use_kuserok; + int enable_k5users; int gss_authentication; /* If true, permit GSSAPI authentication */ diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 2c65890..23f47ae 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -192,26 +192,26 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -399,7 +402,8 @@ typedef enum { +@@ -399,7 +402,7 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, sChallengeResponseAuthentication, -+ sKerberosGetAFSToken, sKerberosUseKuserok, -+ sChallengeResponseAuthentication, +- sKerberosGetAFSToken, sKerberosUniqueTicket, ++ sKerberosGetAFSToken, sKerberosUniqueTicket, sKerberosUseKuserok, + sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, -@@ -478,11 +481,13 @@ static struct { - #else +@@ -478,12 +481,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif + { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL }, + { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, #else { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -236,9 +236,9 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) - # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif + dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); #endif #ifdef GSSAPI @@ -247,9 +247,9 @@ 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 { - * file on logout. */ - int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ + int kerberos_unique_ticket; /* If true, the aquired ticket will + * be stored in per-session ccache */ + int use_kuserok; int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ @@ -258,9 +258,9 @@ 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 - file on logout. + tickets aquired in different sessions of the same user. The default is - .Cm yes . + .Cm no . +.It Cm KerberosUseKuserok +Specifies whether to look at .k5login file for user's aliases. +The default is diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 57b5eaf..d2453d5 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -401,8 +401,8 @@ diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h + KEX_GSS_GRP14_SHA1_ID + typedef struct { - char *filename; char *envvar; + char *envval; @@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 02436bd..c9034e8 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -540,7 +540,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; + { 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}, 0, 0}; ssh_gssapi_mech gssapi_null_mech = - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; @@ -710,7 +710,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -383,14 +469,90 @@ ssh_gssapi_userok(char *user) +@@ -383,14 +469,89 @@ ssh_gssapi_userok(char *user) return (0); } @@ -748,8 +748,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c + char *envstr; +#endif + -+ if (gssapi_client.store.filename == NULL && -+ gssapi_client.store.envval == NULL && ++ if (gssapi_client.store.envval == NULL && + gssapi_client.store.envvar == NULL) + return; + @@ -819,7 +818,7 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c const char *errmsg; if (client->creds == NULL) { -@@ -181,11 +181,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -181,11 +181,23 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl return; } @@ -833,7 +832,6 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c - snprintf(client->store.envval, len, "FILE:%s", client->store.filename); +#ifdef USE_CCAPI + xasprintf(&client->store.envval, "API:%s", new_ccname); -+ client->store.filename = NULL; +#else + if (new_ccname[0] == ':') + new_ccname++; @@ -844,8 +842,6 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c + if (p) + *p = '\0'; + } -+ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) -+ client->store.filename = xstrdup(new_ccname); +#endif #ifdef USE_PAM @@ -1794,7 +1790,7 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1854,5 +1880,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1854,5 +1880,71 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1848,13 +1844,11 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c + ssh_gssapi_ccache store; + int ok; + -+ store.filename = buffer_get_string(m, NULL); + store.envvar = buffer_get_string(m, NULL); + store.envval = buffer_get_string(m, NULL); + + ok = ssh_gssapi_update_creds(&store); + -+ free(store.filename); + free(store.envvar); + free(store.envval); + @@ -1892,7 +1886,7 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -967,5 +967,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -967,5 +967,49 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1927,7 +1921,6 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c + + buffer_init(&m); + -+ buffer_put_cstring(&m, store->filename ? store->filename : ""); + buffer_put_cstring(&m, store->envvar ? store->envvar : ""); + buffer_put_cstring(&m, store->envval ? store->envval : ""); + diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 308c452..09369aa 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -32,7 +32,7 @@ index f9d191c..c432d2f 100644 @@ -222,5 +222,7 @@ int sys_auth_passwd(Authctxt *, const char *); #if defined(KRB5) && !defined(HEIMDAL) #include - krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); + krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, + char **k5login_directory); #endif diff --git a/openssh-7.5p1-gss-environment.patch b/openssh-7.5p1-gss-environment.patch deleted file mode 100644 index 5b5d661..0000000 --- a/openssh-7.5p1-gss-environment.patch +++ /dev/null @@ -1,259 +0,0 @@ -diff --git a/auth-krb5.c b/auth-krb5.c -index 09ed151..282fcca 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c -@@ -182,7 +182,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, &authctxt->krb5_set_env); - if (problem) - goto out; - -@@ -192,7 +192,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) - - - #ifdef USE_PAM -- if (options.use_pam) -+ if (options.use_pam && authctxt->krb5_set_env) - do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); - #endif - -@@ -412,7 +413,7 @@ ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { - - #ifndef HEIMDAL - krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -+ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { - int tmpfd, ret, oerrno; - char *ccname; - #ifdef USE_CCAPI -@@ -423,8 +424,10 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { - - #endif - -+ if (need_environment) -+ *need_environment = 0; - ret = ssh_krb5_get_cctemplate(ctx, &ccname); -- -+ /* fallback to the ccache in /tmp */ - if (ret) { - ret = asprintf(&ccname, cctemplate, geteuid()); - if (ret == -1) -@@ -444,6 +447,9 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { - close(tmpfd); - return oerrno; - } -+ /* make sure the KRBCCNAME is set for non-standard location */ -+ if (need_environment) -+ *need_environment = 1; - close(tmpfd); - } - debug("%s: Setting ccname to %s", __func__, ccname); -diff --git a/auth.h b/auth.h -index 954a0dd..0819483 100644 ---- a/auth.h -+++ b/auth.h -@@ -78,6 +78,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; - -@@ -220,7 +221,7 @@ int sys_auth_passwd(Authctxt *, const char *); - - #if defined(KRB5) && !defined(HEIMDAL) - #include --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *, int *); - krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, - char **k5login_directory); - #endif -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 0fa3838..4127245 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -382,7 +382,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, - /* This writes out any forwarded credentials from the structure populated - * during userauth. Called after we have setuid to the user */ - --static void -+static int - ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - { - krb5_ccache ccache; -@@ -391,14 +391,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - OM_uint32 maj_status, min_status; - const char *new_ccname, *new_cctype; - const char *errmsg; -+ int set_env = 0; - - if (client->creds == NULL) { - debug("No credentials stored"); -- return; -+ return 0; - } - - if (ssh_gssapi_krb5_init() == 0) -- return; -+ return 0; - - #ifdef HEIMDAL - # ifdef HAVE_KRB5_CC_NEW_UNIQUE -@@ -412,14 +413,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - krb5_get_err_text(krb_context, problem)); - # endif - krb5_free_error_message(krb_context, errmsg); -- return; -+ return 0; - } - #else -- if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { -+ if ((problem = ssh_krb5_cc_gen(krb_context, &ccache, &set_env))) { - errmsg = krb5_get_error_message(krb_context, problem); - logit("ssh_krb5_cc_gen(): %.100s", errmsg); - krb5_free_error_message(krb_context, errmsg); -- return; -+ return 0; - } - #endif /* #ifdef HEIMDAL */ - -@@ -428,7 +429,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - errmsg = krb5_get_error_message(krb_context, problem); - logit("krb5_parse_name(): %.100s", errmsg); - krb5_free_error_message(krb_context, errmsg); -- return; -+ return 0; - } - - if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { -@@ -437,7 +438,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - krb5_free_error_message(krb_context, errmsg); - krb5_free_principal(krb_context, princ); - krb5_cc_destroy(krb_context, ccache); -- return; -+ return 0; - } - - krb5_free_principal(krb_context, princ); -@@ -446,7 +447,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - client->creds, ccache))) { - logit("gss_krb5_copy_ccache() failed"); - krb5_cc_destroy(krb_context, ccache); -- return; -+ return 0; - } - - new_cctype = krb5_cc_get_type(krb_context, ccache); -@@ -471,7 +478,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - #endif - - #ifdef USE_PAM -- if (options.use_pam) -+ if (options.use_pam && set_env) - do_pam_putenv(client->store.envvar, client->store.envval); - #endif - -@@ -479,7 +486,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - - client->store.data = krb_context; - -- return; -+ return set_env; - } - - int -diff --git a/gss-serv.c b/gss-serv.c -index 681847a..2a02dae 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -404,7 +404,7 @@ ssh_gssapi_cleanup_creds(void) - debug("%s: krb5_cc_resolve(): %.100s", __func__, - krb5_get_err_text(gssapi_client.store.data, problem)); - } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -- debug("%s: krb5_cc_resolve(): %.100s", __func__, -+ debug("%s: krb5_cc_destroy(): %.100s", __func__, - krb5_get_err_text(gssapi_client.store.data, problem)); - } else { - krb5_free_context(gssapi_client.store.data); -@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) - } - - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } - - /* This allows GSSAPI methods to do things to the childs environment based -diff --git a/session.c b/session.c -index df4985a..b7a6a57 100644 ---- a/session.c -+++ b/session.c -@@ -1084,7 +1084,8 @@ do_setup_env(Session *s, const char *shell) - /* Allow any GSSAPI methods that we've used to alter - * the childs environment as they see fit - */ -- ssh_gssapi_do_child(&env, &envsize); -+ if (s->authctxt->krb5_set_env) -+ ssh_gssapi_do_child(&env, &envsize); - #endif - - /* Set basic environment. */ -@@ -1196,7 +1197,7 @@ do_setup_env(Session *s, const char *shell) - } - #endif - #ifdef KRB5 -- if (s->authctxt->krb5_ccname) -+ if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env) - child_set_env(&env, &envsize, "KRB5CCNAME", - s->authctxt->krb5_ccname); - #endif -diff --git a/ssh-gss.h b/ssh-gss.h -index 6f2b0ac..73ef2c2 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -106,7 +106,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*dochild) (ssh_gssapi_client *); - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -163,7 +163,7 @@ char* ssh_gssapi_get_displayname(void); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); -diff --git a/sshd.c b/sshd.c -index ce2e374..3c4e13e 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2221,7 +2221,7 @@ main(int ac, char **av) - #ifdef GSSAPI - if (options.gss_authentication) { - temporarily_use_uid(authctxt->pw); -- ssh_gssapi_storecreds(); -+ authctxt->krb5_set_env = ssh_gssapi_storecreds(); - restore_uid(); - } - #endif - diff --git a/openssh-7.7p1-gsissh.patch b/openssh-7.7p1-gsissh.patch index 6359ff4..2a02b2d 100644 --- a/openssh-7.7p1-gsissh.patch +++ b/openssh-7.7p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c ---- openssh-7.7p1.orig/auth2.c 2018-04-10 10:51:05.695456763 +0200 -+++ openssh-7.7p1/auth2.c 2018-04-10 10:51:43.733037632 +0200 +--- openssh-7.7p1.orig/auth2.c 2018-07-05 14:58:40.604584490 +0200 ++++ openssh-7.7p1/auth2.c 2018-07-05 13:40:25.453373817 +0200 @@ -230,7 +230,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -100,8 +100,8 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c ---- openssh-7.7p1.orig/auth2-gss.c 2018-04-10 10:51:05.602457788 +0200 -+++ openssh-7.7p1/auth2-gss.c 2018-04-10 10:51:43.734037621 +0200 +--- openssh-7.7p1.orig/auth2-gss.c 2018-07-05 14:58:40.604584490 +0200 ++++ openssh-7.7p1/auth2-gss.c 2018-07-05 13:40:25.453373817 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -283,8 +283,8 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c ---- openssh-7.7p1.orig/auth.c 2018-04-10 10:51:05.696456752 +0200 -+++ openssh-7.7p1/auth.c 2018-04-10 10:51:43.735037610 +0200 +--- openssh-7.7p1.orig/auth.c 2018-07-05 14:58:40.605584480 +0200 ++++ openssh-7.7p1/auth.c 2018-07-05 13:40:25.453373817 +0200 @@ -76,6 +76,9 @@ #include "compat.h" #include "channels.h" @@ -351,8 +351,8 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-7.7p1.orig/auth.h openssh-7.7p1/auth.h ---- openssh-7.7p1.orig/auth.h 2018-04-10 10:51:05.696456752 +0200 -+++ openssh-7.7p1/auth.h 2018-04-10 10:51:43.736037599 +0200 +--- openssh-7.7p1.orig/auth.h 2018-07-05 14:58:40.605584480 +0200 ++++ openssh-7.7p1/auth.h 2018-07-05 13:40:25.454373806 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -363,8 +363,8 @@ diff -Nur openssh-7.7p1.orig/auth.h openssh-7.7p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c ---- openssh-7.7p1.orig/auth-pam.c 2018-04-10 10:51:05.719456498 +0200 -+++ openssh-7.7p1/auth-pam.c 2018-04-10 10:51:43.737037588 +0200 +--- openssh-7.7p1.orig/auth-pam.c 2018-07-05 14:58:40.605584480 +0200 ++++ openssh-7.7p1/auth-pam.c 2018-07-05 13:40:25.454373806 +0200 @@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -505,8 +505,8 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-7.7p1.orig/auth-pam.h openssh-7.7p1/auth-pam.h ---- openssh-7.7p1.orig/auth-pam.h 2018-04-10 10:51:05.555458306 +0200 -+++ openssh-7.7p1/auth-pam.h 2018-04-10 10:51:43.737037588 +0200 +--- openssh-7.7p1.orig/auth-pam.h 2018-07-05 14:58:40.605584480 +0200 ++++ openssh-7.7p1/auth-pam.h 2018-07-05 13:40:25.454373806 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -515,8 +515,8 @@ diff -Nur openssh-7.7p1.orig/auth-pam.h openssh-7.7p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-7.7p1.orig/canohost.c openssh-7.7p1/canohost.c ---- openssh-7.7p1.orig/canohost.c 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/canohost.c 2018-04-10 10:51:43.738037577 +0200 +--- openssh-7.7p1.orig/canohost.c 2018-07-05 14:58:40.606584469 +0200 ++++ openssh-7.7p1/canohost.c 2018-07-05 13:40:25.454373806 +0200 @@ -17,6 +17,7 @@ #include #include @@ -560,8 +560,8 @@ diff -Nur openssh-7.7p1.orig/canohost.c openssh-7.7p1/canohost.c + } +} diff -Nur openssh-7.7p1.orig/canohost.h openssh-7.7p1/canohost.h ---- openssh-7.7p1.orig/canohost.h 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/canohost.h 2018-04-10 10:51:43.738037577 +0200 +--- openssh-7.7p1.orig/canohost.h 2018-07-05 14:58:40.615584372 +0200 ++++ openssh-7.7p1/canohost.h 2018-07-05 13:40:25.454373806 +0200 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -570,8 +570,8 @@ diff -Nur openssh-7.7p1.orig/canohost.h openssh-7.7p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac ---- openssh-7.7p1.orig/configure.ac 2018-04-10 10:51:05.729456388 +0200 -+++ openssh-7.7p1/configure.ac 2018-04-10 10:51:43.739037566 +0200 +--- openssh-7.7p1.orig/configure.ac 2018-07-05 14:58:40.616584361 +0200 ++++ openssh-7.7p1/configure.ac 2018-07-05 13:40:25.455373795 +0200 @@ -4542,6 +4542,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -639,8 +639,8 @@ diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c ---- openssh-7.7p1.orig/gss-genr.c 2018-04-10 10:51:05.721456476 +0200 -+++ openssh-7.7p1/gss-genr.c 2018-04-10 10:51:43.740037555 +0200 +--- openssh-7.7p1.orig/gss-genr.c 2018-07-05 14:58:40.616584361 +0200 ++++ openssh-7.7p1/gss-genr.c 2018-07-05 13:40:25.456373784 +0200 @@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" @@ -678,8 +678,8 @@ diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c return (ctx->major); } diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c ---- openssh-7.7p1.orig/gss-serv.c 2018-04-10 10:51:05.649457270 +0200 -+++ openssh-7.7p1/gss-serv.c 2018-04-10 10:51:43.740037555 +0200 +--- openssh-7.7p1.orig/gss-serv.c 2018-07-05 14:58:40.616584361 +0200 ++++ openssh-7.7p1/gss-serv.c 2018-07-05 15:02:46.526946800 +0200 @@ -51,10 +51,12 @@ #include "monitor_wrap.h" @@ -688,7 +688,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c 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}, 0, 0}; + { {0, NULL}, GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, + GSS_C_NO_NAME, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, + GSS_C_NO_CONTEXT, 0, 0}; @@ -935,15 +935,20 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -498,6 +583,7 @@ +@@ -498,9 +583,11 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; + char **p; char **pw; #endif - if (gssapi_client.store.filename == NULL && -@@ -527,6 +613,18 @@ +- if (gssapi_client.store.envval == NULL && ++ if (gssapi_client.store.filename == NULL && ++ gssapi_client.store.envval == NULL && + gssapi_client.store.envvar == NULL) + return; + +@@ -526,6 +613,18 @@ if (ret) return; @@ -962,7 +967,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -567,4 +665,13 @@ +@@ -566,4 +665,13 @@ return (char *)gssapi_client.displayname.value; } @@ -978,7 +983,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c #endif diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c --- openssh-7.7p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/gss-serv-gsi.c 2018-04-10 10:51:43.740037555 +0200 ++++ openssh-7.7p1/gss-serv-gsi.c 2018-07-05 13:40:25.459373752 +0200 @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1312,8 +1317,8 @@ diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c ---- openssh-7.7p1.orig/gss-serv-krb5.c 2018-04-10 10:51:05.641457358 +0200 -+++ openssh-7.7p1/gss-serv-krb5.c 2018-04-10 10:51:43.741037544 +0200 +--- openssh-7.7p1.orig/gss-serv-krb5.c 2018-07-05 14:58:40.617584351 +0200 ++++ openssh-7.7p1/gss-serv-krb5.c 2018-07-05 13:40:25.459373752 +0200 @@ -378,6 +378,34 @@ return found_principal; } @@ -1349,7 +1354,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -483,7 +511,7 @@ +@@ -470,7 +498,7 @@ return set_env; } @@ -1358,7 +1363,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -554,7 +582,7 @@ +@@ -541,7 +569,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1368,8 +1373,8 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c ---- openssh-7.7p1.orig/kexgsss.c 2018-04-10 10:51:05.722456465 +0200 -+++ openssh-7.7p1/kexgsss.c 2018-04-10 10:51:43.741037544 +0200 +--- openssh-7.7p1.orig/kexgsss.c 2018-07-05 14:58:40.617584351 +0200 ++++ openssh-7.7p1/kexgsss.c 2018-07-05 13:40:25.460373741 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1431,7 +1436,7 @@ diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c #endif /* GSSAPI */ diff -Nur openssh-7.7p1.orig/LICENSE.globus_usage openssh-7.7p1/LICENSE.globus_usage --- openssh-7.7p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/LICENSE.globus_usage 2018-04-10 10:51:43.741037544 +0200 ++++ openssh-7.7p1/LICENSE.globus_usage 2018-07-05 13:40:25.460373741 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1452,8 +1457,8 @@ diff -Nur openssh-7.7p1.orig/LICENSE.globus_usage openssh-7.7p1/LICENSE.globus_u + * limitations under the License. + */ diff -Nur openssh-7.7p1.orig/Makefile.in openssh-7.7p1/Makefile.in ---- openssh-7.7p1.orig/Makefile.in 2018-04-10 10:51:05.723456454 +0200 -+++ openssh-7.7p1/Makefile.in 2018-04-10 10:51:43.741037544 +0200 +--- openssh-7.7p1.orig/Makefile.in 2018-07-05 14:58:40.617584351 +0200 ++++ openssh-7.7p1/Makefile.in 2018-07-05 13:40:25.473373600 +0200 @@ -124,8 +124,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1466,8 +1471,8 @@ diff -Nur openssh-7.7p1.orig/Makefile.in openssh-7.7p1/Makefile.in sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c ---- openssh-7.7p1.orig/misc.c 2018-04-10 10:51:05.639457380 +0200 -+++ openssh-7.7p1/misc.c 2018-04-10 10:51:43.742037533 +0200 +--- openssh-7.7p1.orig/misc.c 2018-07-05 14:58:40.618584340 +0200 ++++ openssh-7.7p1/misc.c 2018-07-05 13:40:25.460373741 +0200 @@ -238,11 +238,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1528,8 +1533,8 @@ diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-7.7p1.orig/misc.h openssh-7.7p1/misc.h ---- openssh-7.7p1.orig/misc.h 2018-04-10 10:51:05.639457380 +0200 -+++ openssh-7.7p1/misc.h 2018-04-10 10:51:43.743037522 +0200 +--- openssh-7.7p1.orig/misc.h 2018-07-05 14:58:40.618584340 +0200 ++++ openssh-7.7p1/misc.h 2018-07-05 13:40:25.461373730 +0200 @@ -82,6 +82,7 @@ void sock_set_v6only(int); @@ -1539,8 +1544,8 @@ diff -Nur openssh-7.7p1.orig/misc.h openssh-7.7p1/misc.h typedef struct arglist arglist; diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c ---- openssh-7.7p1.orig/monitor.c 2018-04-10 10:51:05.723456454 +0200 -+++ openssh-7.7p1/monitor.c 2018-04-10 10:51:43.744037511 +0200 +--- openssh-7.7p1.orig/monitor.c 2018-07-05 14:58:40.619584329 +0200 ++++ openssh-7.7p1/monitor.c 2018-07-05 15:10:21.951050957 +0200 @@ -165,6 +165,9 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); @@ -1729,9 +1734,23 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c int mm_answer_gss_sign(int socket, Buffer *m) { +@@ -2065,11 +2148,13 @@ + ssh_gssapi_ccache store; + int ok; + ++ store.filename = buffer_get_string(m, NULL); + store.envvar = buffer_get_string(m, NULL); + store.envval = buffer_get_string(m, NULL); + + ok = ssh_gssapi_update_creds(&store); + ++ free(store.filename); + free(store.envvar); + free(store.envval); + diff -Nur openssh-7.7p1.orig/monitor.h openssh-7.7p1/monitor.h ---- openssh-7.7p1.orig/monitor.h 2018-04-10 10:51:05.698456730 +0200 -+++ openssh-7.7p1/monitor.h 2018-04-10 10:51:43.744037511 +0200 +--- openssh-7.7p1.orig/monitor.h 2018-07-05 14:58:40.619584329 +0200 ++++ openssh-7.7p1/monitor.h 2018-07-05 13:40:25.461373730 +0200 @@ -75,8 +75,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1746,8 +1765,8 @@ diff -Nur openssh-7.7p1.orig/monitor.h openssh-7.7p1/monitor.h struct monitor { diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c ---- openssh-7.7p1.orig/monitor_wrap.c 2018-04-10 10:51:05.715456543 +0200 -+++ openssh-7.7p1/monitor_wrap.c 2018-04-10 10:51:43.744037511 +0200 +--- openssh-7.7p1.orig/monitor_wrap.c 2018-07-05 14:58:40.619584329 +0200 ++++ openssh-7.7p1/monitor_wrap.c 2018-07-05 15:04:51.534606293 +0200 @@ -998,12 +998,13 @@ } @@ -1847,9 +1866,17 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { +@@ -1046,6 +1124,7 @@ + + buffer_init(&m); + ++ buffer_put_cstring(&m, store->filename ? store->filename : ""); + buffer_put_cstring(&m, store->envvar ? store->envvar : ""); + buffer_put_cstring(&m, store->envval ? store->envval : ""); + diff -Nur openssh-7.7p1.orig/monitor_wrap.h openssh-7.7p1/monitor_wrap.h ---- openssh-7.7p1.orig/monitor_wrap.h 2018-04-10 10:51:05.704456664 +0200 -+++ openssh-7.7p1/monitor_wrap.h 2018-04-10 10:51:43.745037500 +0200 +--- openssh-7.7p1.orig/monitor_wrap.h 2018-07-05 14:58:40.619584329 +0200 ++++ openssh-7.7p1/monitor_wrap.h 2018-07-05 13:40:25.462373719 +0200 @@ -65,9 +65,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1866,9 +1893,9 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.h openssh-7.7p1/monitor_wrap.h #endif diff -Nur openssh-7.7p1.orig/readconf.c openssh-7.7p1/readconf.c ---- openssh-7.7p1.orig/readconf.c 2018-04-10 10:51:05.709456609 +0200 -+++ openssh-7.7p1/readconf.c 2018-04-10 10:51:43.746037489 +0200 -@@ -1960,13 +1960,13 @@ +--- openssh-7.7p1.orig/readconf.c 2018-07-05 14:58:40.620584318 +0200 ++++ openssh-7.7p1/readconf.c 2018-07-05 13:40:25.462373719 +0200 +@@ -1959,13 +1959,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1887,8 +1914,8 @@ diff -Nur openssh-7.7p1.orig/readconf.c openssh-7.7p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-7.7p1.orig/readconf.h openssh-7.7p1/readconf.h ---- openssh-7.7p1.orig/readconf.h 2018-04-10 10:51:05.656457193 +0200 -+++ openssh-7.7p1/readconf.h 2018-04-10 10:51:43.746037489 +0200 +--- openssh-7.7p1.orig/readconf.h 2018-07-05 14:58:40.620584318 +0200 ++++ openssh-7.7p1/readconf.h 2018-07-05 13:40:25.462373719 +0200 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1899,8 +1926,8 @@ diff -Nur openssh-7.7p1.orig/readconf.h openssh-7.7p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c ---- openssh-7.7p1.orig/servconf.c 2018-04-10 10:51:05.716456531 +0200 -+++ openssh-7.7p1/servconf.c 2018-04-10 10:51:43.747037477 +0200 +--- openssh-7.7p1.orig/servconf.c 2018-07-05 14:58:40.621584308 +0200 ++++ openssh-7.7p1/servconf.c 2018-07-05 13:40:25.463373709 +0200 @@ -83,6 +83,7 @@ /* Portable-specific options */ @@ -1909,9 +1936,9 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -125,9 +126,11 @@ - options->kerberos_ticket_cleanup = -1; +@@ -126,9 +127,11 @@ options->kerberos_get_afs_token = -1; + options->kerberos_unique_ticket = -1; options->gss_authentication=-1; + options->gss_deleg_creds = -1; options->gss_keyex = -1; @@ -1921,7 +1948,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -172,6 +175,8 @@ +@@ -173,6 +176,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1930,7 +1957,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -255,6 +260,8 @@ +@@ -256,6 +261,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1939,9 +1966,9 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -330,13 +337,17 @@ - if (options->kerberos_get_afs_token == -1) - options->kerberos_get_afs_token = 0; +@@ -333,13 +340,17 @@ + if (options->kerberos_unique_ticket == -1) + options->kerberos_unique_ticket = 0; if (options->gss_authentication == -1) - options->gss_authentication = 0; + options->gss_authentication = 1; @@ -1959,7 +1986,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -469,7 +480,7 @@ +@@ -472,7 +483,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1968,7 +1995,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -491,10 +502,14 @@ +@@ -494,10 +505,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1983,7 +2010,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -520,8 +535,10 @@ +@@ -523,8 +538,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1994,7 +2021,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -567,7 +584,14 @@ +@@ -572,7 +589,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -2009,7 +2036,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -575,7 +599,10 @@ +@@ -580,7 +604,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -2020,7 +2047,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -644,6 +671,8 @@ +@@ -649,6 +676,8 @@ { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -2029,7 +2056,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1244,6 +1273,10 @@ +@@ -1249,6 +1278,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2040,7 +2067,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1454,6 +1487,10 @@ +@@ -1463,6 +1496,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2051,7 +2078,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1462,6 +1499,10 @@ +@@ -1471,6 +1508,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2062,7 +2089,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1482,6 +1523,12 @@ +@@ -1491,6 +1532,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2075,7 +2102,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1939,6 +1986,35 @@ +@@ -1948,6 +1995,35 @@ *charptr = xstrdup(arg); break; @@ -2111,7 +2138,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2232,6 +2308,7 @@ +@@ -2241,6 +2317,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2120,10 +2147,10 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h ---- openssh-7.7p1.orig/servconf.h 2018-04-10 10:51:05.661457138 +0200 -+++ openssh-7.7p1/servconf.h 2018-04-10 10:51:43.748037466 +0200 -@@ -133,9 +133,12 @@ - * authenticated with Kerberos. */ +--- openssh-7.7p1.orig/servconf.h 2018-07-05 14:58:40.621584308 +0200 ++++ openssh-7.7p1/servconf.h 2018-07-05 13:40:25.463373709 +0200 +@@ -135,9 +135,12 @@ + * be stored in per-session ccache */ int use_kuserok; int enable_k5users; + int gsi_allow_limited_proxy; /* If true, accept limited proxies */ @@ -2135,7 +2162,7 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -192,6 +195,7 @@ +@@ -194,6 +197,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2143,7 +2170,7 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h int permit_tun; -@@ -199,6 +203,10 @@ +@@ -201,6 +205,10 @@ u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */ char *chroot_directory; @@ -2155,8 +2182,8 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h char *trusted_user_ca_keys; char *authorized_keys_command; diff -Nur openssh-7.7p1.orig/ssh.1 openssh-7.7p1/ssh.1 ---- openssh-7.7p1.orig/ssh.1 2018-04-10 10:51:05.652457237 +0200 -+++ openssh-7.7p1/ssh.1 2018-04-10 10:51:43.748037466 +0200 +--- openssh-7.7p1.orig/ssh.1 2018-07-05 14:58:40.622584297 +0200 ++++ openssh-7.7p1/ssh.1 2018-07-05 13:40:25.463373709 +0200 @@ -1419,6 +1419,18 @@ on to new connections). .It Ev USER @@ -2177,8 +2204,8 @@ diff -Nur openssh-7.7p1.orig/ssh.1 openssh-7.7p1/ssh.1 .Pp Additionally, diff -Nur openssh-7.7p1.orig/ssh.c openssh-7.7p1/ssh.c ---- openssh-7.7p1.orig/ssh.c 2018-04-10 10:51:05.725456432 +0200 -+++ openssh-7.7p1/ssh.c 2018-04-10 10:51:43.749037455 +0200 +--- openssh-7.7p1.orig/ssh.c 2018-07-05 14:58:40.622584297 +0200 ++++ openssh-7.7p1/ssh.c 2018-07-05 13:40:25.464373698 +0200 @@ -522,6 +522,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2227,8 +2254,8 @@ diff -Nur openssh-7.7p1.orig/ssh.c openssh-7.7p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) diff -Nur openssh-7.7p1.orig/ssh_config openssh-7.7p1/ssh_config ---- openssh-7.7p1.orig/ssh_config 2018-04-10 10:51:05.610457699 +0200 -+++ openssh-7.7p1/ssh_config 2018-04-10 10:51:43.750037444 +0200 +--- openssh-7.7p1.orig/ssh_config 2018-07-05 14:58:40.622584297 +0200 ++++ openssh-7.7p1/ssh_config 2018-07-05 13:40:25.464373698 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2245,8 +2272,8 @@ diff -Nur openssh-7.7p1.orig/ssh_config openssh-7.7p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 ---- openssh-7.7p1.orig/ssh_config.5 2018-04-10 10:51:05.689456829 +0200 -+++ openssh-7.7p1/ssh_config.5 2018-04-10 10:51:43.750037444 +0200 +--- openssh-7.7p1.orig/ssh_config.5 2018-07-05 14:58:40.623584286 +0200 ++++ openssh-7.7p1/ssh_config.5 2018-07-05 13:40:25.464373698 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2303,8 +2330,8 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c ---- openssh-7.7p1.orig/sshconnect2.c 2018-04-10 10:51:05.724456443 +0200 -+++ openssh-7.7p1/sshconnect2.c 2018-04-10 10:51:43.751037433 +0200 +--- openssh-7.7p1.orig/sshconnect2.c 2018-07-05 14:58:40.623584286 +0200 ++++ openssh-7.7p1/sshconnect2.c 2018-07-05 13:40:25.465373687 +0200 @@ -285,7 +285,7 @@ #ifdef GSSAPI @@ -2400,8 +2427,8 @@ diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-7.7p1.orig/sshd.8 openssh-7.7p1/sshd.8 ---- openssh-7.7p1.orig/sshd.8 2018-04-10 10:51:05.620457589 +0200 -+++ openssh-7.7p1/sshd.8 2018-04-10 10:51:43.752037422 +0200 +--- openssh-7.7p1.orig/sshd.8 2018-07-05 14:58:40.624584275 +0200 ++++ openssh-7.7p1/sshd.8 2018-07-05 13:40:25.465373687 +0200 @@ -760,6 +760,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2448,8 +2475,8 @@ diff -Nur openssh-7.7p1.orig/sshd.8 openssh-7.7p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c ---- openssh-7.7p1.orig/sshd.c 2018-04-10 10:51:05.725456432 +0200 -+++ openssh-7.7p1/sshd.c 2018-04-10 10:51:43.753037411 +0200 +--- openssh-7.7p1.orig/sshd.c 2018-07-05 14:58:40.624584275 +0200 ++++ openssh-7.7p1/sshd.c 2018-07-05 13:40:25.466373676 +0200 @@ -130,6 +130,7 @@ #include "auth-options.h" #include "version.h" @@ -2482,8 +2509,8 @@ diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config ---- openssh-7.7p1.orig/sshd_config 2018-04-10 10:51:05.648457281 +0200 -+++ openssh-7.7p1/sshd_config 2018-04-10 10:51:43.753037411 +0200 +--- openssh-7.7p1.orig/sshd_config 2018-07-05 14:58:40.624584275 +0200 ++++ openssh-7.7p1/sshd_config 2018-07-05 13:40:25.475373579 +0200 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2509,7 +2536,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -138,6 +143,10 @@ +@@ -142,6 +147,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2521,8 +2548,8 @@ diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config #Match User anoncvs # X11Forwarding no diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 ---- openssh-7.7p1.orig/sshd_config.5 2018-04-10 10:51:05.673457005 +0200 -+++ openssh-7.7p1/sshd_config.5 2018-04-10 10:51:43.754037400 +0200 +--- openssh-7.7p1.orig/sshd_config.5 2018-07-05 14:58:40.626584254 +0200 ++++ openssh-7.7p1/sshd_config.5 2018-07-05 13:40:25.466373676 +0200 @@ -575,6 +575,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may @@ -2592,7 +2619,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -@@ -1550,6 +1577,103 @@ +@@ -1556,6 +1583,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2696,7 +2723,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1591,6 +1715,12 @@ +@@ -1597,6 +1721,12 @@ as a non-root user. The default is .Cm no . @@ -2711,7 +2738,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 sent by the server upon connection. diff -Nur openssh-7.7p1.orig/ssh-globus-usage.c openssh-7.7p1/ssh-globus-usage.c --- openssh-7.7p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/ssh-globus-usage.c 2018-04-10 10:51:43.755037389 +0200 ++++ openssh-7.7p1/ssh-globus-usage.c 2018-07-05 13:40:25.466373676 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3111,7 +3138,7 @@ diff -Nur openssh-7.7p1.orig/ssh-globus-usage.c openssh-7.7p1/ssh-globus-usage.c +} diff -Nur openssh-7.7p1.orig/ssh-globus-usage.h openssh-7.7p1/ssh-globus-usage.h --- openssh-7.7p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/ssh-globus-usage.h 2018-04-10 10:51:43.755037389 +0200 ++++ openssh-7.7p1/ssh-globus-usage.h 2018-07-05 13:40:25.467373665 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3162,9 +3189,17 @@ diff -Nur openssh-7.7p1.orig/ssh-globus-usage.h openssh-7.7p1/ssh-globus-usage.h + +#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h ---- openssh-7.7p1.orig/ssh-gss.h 2018-04-10 10:51:05.672457016 +0200 -+++ openssh-7.7p1/ssh-gss.h 2018-04-10 10:51:43.755037389 +0200 -@@ -93,12 +93,14 @@ +--- openssh-7.7p1.orig/ssh-gss.h 2018-07-05 14:58:40.627584243 +0200 ++++ openssh-7.7p1/ssh-gss.h 2018-07-05 13:40:25.467373665 +0200 +@@ -85,6 +85,7 @@ + KEX_GSS_GRP14_SHA1_ID + + typedef struct { ++ char *filename; + char *envvar; + char *envval; + struct passwd *owner; +@@ -92,12 +93,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -3180,7 +3215,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -119,7 +121,7 @@ +@@ -118,7 +121,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -3189,7 +3224,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -152,6 +154,9 @@ +@@ -151,6 +154,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -3199,7 +3234,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -162,7 +167,7 @@ +@@ -161,7 +167,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -3208,7 +3243,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h 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); -@@ -175,6 +180,7 @@ +@@ -174,6 +180,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -3217,8 +3252,8 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h #endif /* _SSH_GSS_H */ diff -Nur openssh-7.7p1.orig/version.h openssh-7.7p1/version.h ---- openssh-7.7p1.orig/version.h 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/version.h 2018-04-10 10:51:43.755037389 +0200 +--- openssh-7.7p1.orig/version.h 2018-07-05 14:58:40.627584243 +0200 ++++ openssh-7.7p1/version.h 2018-07-05 13:40:25.467373665 +0200 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_7.7" diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch new file mode 100644 index 0000000..7acc58a --- /dev/null +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -0,0 +1,646 @@ +diff --git a/auth-krb5.c b/auth-krb5.c +index a5a81ed2..63f877f2 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + extern ServerOptions options; + +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) + #endif + krb5_error_code problem; + krb5_ccache ccache = NULL; +- int len; ++ char *ticket_name = NULL; + char *client, *platform_client; + const char *errmsg; + +@@ -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_new_unique(authctxt->krb5_ctx, ++ &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env); + if (problem) + goto out; + +@@ -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 + +- authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); ++ problem = krb5_cc_get_full_name(authctxt->krb5_ctx, ++ authctxt->krb5_fwd_ccache, &ticket_name); + +- len = strlen(authctxt->krb5_ticket_file) + 6; +- authctxt->krb5_ccname = xmalloc(len); +- snprintf(authctxt->krb5_ccname, len, "FILE:%s", +- authctxt->krb5_ticket_file); ++ authctxt->krb5_ccname = xstrdup(ticket_name); ++ krb5_free_string(authctxt->krb5_ctx, ticket_name); + + #ifdef USE_PAM +- if (options.use_pam) ++ if (options.use_pam && authctxt->krb5_set_env) + do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); + #endif + +@@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) + void + krb5_cleanup_proc(Authctxt *authctxt) + { ++ struct stat krb5_ccname_stat; ++ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end; ++ + debug("krb5_cleanup_proc called"); + if (authctxt->krb5_fwd_ccache) { +- krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); ++ krb5_context ctx = authctxt->krb5_ctx; ++ krb5_cccol_cursor cursor; ++ krb5_ccache ccache; ++ int ret; ++ ++ krb5_cc_destroy(ctx, authctxt->krb5_fwd_ccache); + authctxt->krb5_fwd_ccache = NULL; ++ ++ ret = krb5_cccol_cursor_new(ctx, &cursor); ++ if (ret) ++ goto out; ++ ++ ret = krb5_cccol_cursor_next(ctx, cursor, &ccache); ++ if (ret == 0 && ccache != NULL) { ++ /* There is at least one other ccache in collection ++ * we can switch to */ ++ krb5_cc_switch(ctx, ccache); ++ } else { ++ /* Clean up the collection too */ ++ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10); ++ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1; ++ *krb5_ccname_dir_start++ = '\0'; ++ if (strcmp(krb5_ccname, "DIR") == 0) { ++ ++ strcat(krb5_ccname_dir_start, "/primary"); ++ ++ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) { ++ if (unlink(krb5_ccname_dir_start) == 0) { ++ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/'); ++ *krb5_ccname_dir_end = '\0'; ++ if (rmdir(krb5_ccname_dir_start) == -1) ++ debug("cache dir '%s' remove failed: %s", ++ krb5_ccname_dir_start, strerror(errno)); ++ } ++ else ++ debug("cache primary file '%s', remove failed: %s", ++ krb5_ccname_dir_start, strerror(errno)); ++ } ++ } ++ } ++ krb5_cccol_cursor_free(ctx, &cursor); + } ++out: + if (authctxt->krb5_user) { + krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); + authctxt->krb5_user = NULL; +@@ -237,36 +287,186 @@ 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, ...) { ++ char *src, *old; ++ va_list ap; ++ int i; ++ ++ va_start(ap, fmt); ++ i = vasprintf(&src, fmt, ap); ++ va_end(ap); ++ ++ if (i == -1 || src == NULL) ++ return -1; ++ ++ old = *dsc; ++ ++ i = asprintf(dsc, "%s%s", *dsc, src); ++ if (i == -1 || src == NULL) { ++ free(src); ++ return -1; ++ } ++ ++ free(old); ++ free(src); ++ ++ return i; ++} ++ ++int ++ssh_krb5_expand_template(char **result, const char *template) { ++ char *p_n, *p_o, *r, *tmp_template; ++ ++ debug3("%s: called, template = %s", __func__, template); ++ if (template == NULL) ++ return -1; ++ ++ tmp_template = p_n = p_o = xstrdup(template); ++ r = xstrdup(""); ++ ++ while ((p_n = strstr(p_o, "%{")) != NULL) { ++ ++ *p_n++ = '\0'; ++ if (ssh_asprintf_append(&r, "%s", p_o) == -1) ++ goto cleanup; ++ ++ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 || ++ strncmp(p_n, "{USERID}", 8) == 0) { ++ p_o = strchr(p_n, '}') + 1; ++ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1) ++ goto cleanup; ++ continue; ++ } ++ else if (strncmp(p_n, "{TEMP}", 6) == 0) { ++ p_o = strchr(p_n, '}') + 1; ++ if (ssh_asprintf_append(&r, "/tmp") == -1) ++ goto cleanup; ++ continue; ++ } else { ++ p_o = strchr(p_n, '}') + 1; ++ p_o = '\0'; ++ 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; ++ ++ *result = r; ++ free(tmp_template); ++ return 0; ++ ++cleanup: ++ free(r); ++ free(tmp_template); ++ return -1; ++} ++ ++krb5_error_code ++ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { ++ profile_t p; ++ int ret = 0; ++ char *value = NULL; ++ ++ debug3("%s: called", __func__); ++ ret = krb5_get_profile(ctx, &p); ++ if (ret) ++ return ret; ++ ++ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); ++ if (ret || !value) ++ return ret; ++ ++ ret = ssh_krb5_expand_template(ccname, value); ++ ++ debug3("%s: returning with ccname = %s", __func__, *ccname); ++ return ret; ++} ++ ++krb5_error_code ++ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { ++ int tmpfd, ret, oerrno, type_len; ++ char *ccname = NULL; ++ mode_t old_umask; ++ char *type = NULL, *colon = NULL; ++ ++ debug3("%s: called", __func__); ++ if (need_environment) ++ *need_environment = 0; ++ ret = ssh_krb5_get_cctemplate(ctx, &ccname); ++ if (ret || !ccname || options.kerberos_unique_ticket) { ++ /* Otherwise, go with the old method */ ++ if (ccname) ++ free(ccname); ++ ccname = NULL; ++ ++ ret = asprintf(&ccname, ++ "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); ++ if (ret < 0) ++ return ENOMEM; ++ ++ old_umask = umask(0177); ++ tmpfd = mkstemp(ccname + strlen("FILE:")); + oerrno = errno; +- logit("fchmod(): %.100s", strerror(oerrno)); ++ umask(old_umask); ++ if (tmpfd == -1) { ++ logit("mkstemp(): %.100s", strerror(oerrno)); ++ return oerrno; ++ } ++ ++ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { ++ oerrno = errno; ++ logit("fchmod(): %.100s", strerror(oerrno)); ++ close(tmpfd); ++ return oerrno; ++ } ++ /* make sure the KRB5CCNAME is set for non-standard location */ ++ if (need_environment) ++ *need_environment = 1; + close(tmpfd); +- return oerrno; + } +- close(tmpfd); + +- return (krb5_cc_resolve(ctx, ccname, ccache)); ++ 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) ++ return ret; ++ ++ if ((colon = strstr(ccname, ":")) != NULL) { ++ type_len = colon - ccname; ++ type = malloc((type_len + 1) * sizeof(char)); ++ if (type == NULL) ++ return ENOMEM; ++ strncpy(type, ccname, type_len); ++ type[type_len] = 0; ++ } else { ++ type = strdup(ccname); ++ } ++ ++ /* If we have a credential cache from krb5.conf, we need to switch ++ * a primary cache for this collection, if it supports that (non-FILE) ++ */ ++ if (krb5_cc_support_switch(ctx, type)) { ++ debug3("%s: calling cc_new_unique(%s)", __func__, ccname); ++ ret = krb5_cc_new_unique(ctx, type, NULL, ccache); ++ if (ret) ++ return ret; ++ ++ debug3("%s: calling cc_switch()", __func__); ++ return krb5_cc_switch(ctx, *ccache); ++ } else { ++ /* Otherwise, we can not create a unique ccname here (either ++ * it is already unique from above or the type does not support ++ * collections ++ */ ++ 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 29491df9..fdab5040 100644 +--- a/auth.h ++++ b/auth.h +@@ -82,6 +82,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -243,6 +244,6 @@ int sys_auth_passwd(struct ssh *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) + #include +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + #endif + #endif +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 795992d9..0623a107 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -114,7 +114,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + /* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ + +-static void ++static int + ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + { + krb5_ccache ccache; +@@ -121,16 +121,17 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; +- const char *new_ccname, *new_cctype; ++ int len; + const char *errmsg; ++ int set_env = 0; + + if (client->creds == NULL) { + debug("No credentials stored"); +- return; ++ return 0; + } + + if (ssh_gssapi_krb5_init() == 0) +- return; ++ return 0; + + #ifdef HEIMDAL + # ifdef HAVE_KRB5_CC_NEW_UNIQUE +@@ -144,14 +145,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_get_err_text(krb_context, problem)); + # endif + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + #else +- if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { ++ if ((problem = ssh_krb5_cc_new_unique(krb_context, &ccache, &set_env)) != 0) { + errmsg = krb5_get_error_message(krb_context, problem); +- logit("ssh_krb5_cc_gen(): %.100s", errmsg); ++ logit("ssh_krb5_cc_new_unique(): %.100s", errmsg); + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + #endif /* #ifdef HEIMDAL */ + +@@ -160,7 +161,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + errmsg = krb5_get_error_message(krb_context, problem); + logit("krb5_parse_name(): %.100s", errmsg); + krb5_free_error_message(krb_context, errmsg); +- return; ++ return 0; + } + + if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { +@@ -169,7 +170,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_free_error_message(krb_context, errmsg); + krb5_free_principal(krb_context, princ); + krb5_cc_destroy(krb_context, ccache); +- return; ++ return 0; + } + + krb5_free_principal(krb_context, princ); +@@ -178,37 +179,27 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + client->creds, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); +- return; ++ return 0; + } + +- new_cctype = krb5_cc_get_type(krb_context, ccache); +- new_ccname = krb5_cc_get_name(krb_context, ccache); +- +- client->store.envvar = "KRB5CCNAME"; +-#ifdef USE_CCAPI +- xasprintf(&client->store.envval, "API:%s", new_ccname); +-#else +- if (new_ccname[0] == ':') +- new_ccname++; +- xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); +- if (strcmp(new_cctype, "DIR") == 0) { +- char *p; +- p = strrchr(client->store.envval, '/'); +- if (p) +- *p = '\0'; +- } +-#endif ++ if (set_env) { ++ const char *filename = krb5_cc_get_name(krb_context, ccache); ++ client->store.envvar = "KRB5CCNAME"; ++ len = strlen(filename) + 6; ++ client->store.envval = xmalloc(len); ++ snprintf(client->store.envval, len, "FILE:%s", filename); ++ } + + #ifdef USE_PAM +- if (options.use_pam) ++ if (options.use_pam && set_env) + do_pam_putenv(client->store.envvar, client->store.envval); + #endif + + krb5_cc_close(krb_context, ccache); + + client->store.data = krb_context; + +- return; ++ return set_env; + } + + int +diff --git a/gss-serv.c b/gss-serv.c +index 6cae720e..16e55cbc 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + } + + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } + + /* This allows GSSAPI methods to do things to the childs environment based +diff --git a/servconf.c b/servconf.c +index cb578658..a6e01df2 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options) + options->kerberos_or_local_passwd = -1; + options->kerberos_ticket_cleanup = -1; + options->kerberos_get_afs_token = -1; ++ options->kerberos_unique_ticket = -1; + options->gss_authentication=-1; + options->gss_keyex = -1; + options->gss_cleanup_creds = -1; +@@ -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; ++ if (options->kerberos_unique_ticket == -1) ++ options->kerberos_unique_ticket = 0; + if (options->gss_authentication == -1) + options->gss_authentication = 0; + if (options->gss_keyex == -1) +@@ -447,7 +450,8 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsRSAAuthentication, sRSAAuthentication, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, sChallengeResponseAuthentication, ++ sKerberosGetAFSToken, sKerberosUniqueTicket, ++ sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, +@@ -526,11 +530,13 @@ static struct { + #else + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL }, + #else + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL }, + #endif + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, +@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line, + intptr = &options->kerberos_get_afs_token; + goto parse_flag; + ++ case sKerberosUniqueTicket: ++ intptr = &options->kerberos_unique_ticket; ++ goto parse_flag; ++ + case sGssAuthentication: + intptr = &options->gss_authentication; + goto parse_flag; +@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o) + # ifdef USE_AFS + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + # endif ++ dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); + #endif + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); +diff --git a/servconf.h b/servconf.h +index db8362c6..4fa42d64 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -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. */ ++ int kerberos_unique_ticket; /* If true, the aquired ticket will ++ * be stored in per-session ccache */ + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ +diff --git a/session.c b/session.c +index 85df6a27..480a5ead 100644 +--- a/session.c ++++ b/session.c +@@ -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 childs environment as they see fit + */ +- ssh_gssapi_do_child(&env, &envsize); ++ if (s->authctxt->krb5_set_env) ++ ssh_gssapi_do_child(&env, &envsize); + #endif + + /* Set basic environment. */ +@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) + } + #endif + #ifdef KRB5 +- if (s->authctxt->krb5_ccname) ++ if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env) + child_set_env(&env, &envsize, "KRB5CCNAME", + s->authctxt->krb5_ccname); + #endif +diff --git a/ssh-gss.h b/ssh-gss.h +index 6593e422..245178af 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -62,7 +62,6 @@ + #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" + + typedef struct { +- char *filename; + char *envvar; + char *envval; + struct passwd *owner; +@@ -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 **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -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); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); +diff --git a/sshd.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); +- ssh_gssapi_storecreds(); ++ authctxt->krb5_set_env = ssh_gssapi_storecreds(); + restore_uid(); + } + #endif +diff --git a/sshd_config.5 b/sshd_config.5 +index c0683d4a..2349f477 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -860,6 +860,12 @@ Specifies whether to automatically destroy the user's ticket cache + file on logout. + The default is + .Cm yes . ++.It Cm KerberosUniqueTicket ++Specifies whether to store the aquired tickets in the per-session credential ++cache or whether to use per-user credential cache, which might overwrite ++tickets aquired in different sessions of the same user. ++The default is ++.Cm no . + .It Cm KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. diff --git a/openssh-6.6p1-redhat.patch b/openssh-7.7p1-redhat.patch similarity index 72% rename from openssh-6.6p1-redhat.patch rename to openssh-7.7p1-redhat.patch index 0879b51..dc38d65 100644 --- a/openssh-6.6p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/ssh_config.redhat openssh-7.4p1/ssh_config ---- openssh-7.4p1/ssh_config.redhat 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh_config 2016-12-23 13:32:00.045220402 +0100 -@@ -48,3 +48,7 @@ +diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config +--- openssh-7.7p1/ssh_config.redhat 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/ssh_config 2018-07-03 10:44:06.522245125 +0200 +@@ -44,3 +44,7 @@ # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h @@ -9,9 +9,9 @@ diff -up openssh-7.4p1/ssh_config.redhat openssh-7.4p1/ssh_config +# To modify the system-wide ssh configuration, create a *.conf file under +# /etc/ssh/ssh_config.d/ which will be automatically included below +Include /etc/ssh/ssh_config.d/*.conf -diff -up openssh-7.4p1/ssh_config_redhat.redhat openssh-7.4p1/ssh_config_redhat ---- openssh-7.4p1/ssh_config_redhat.redhat 2016-12-23 13:32:00.045220402 +0100 -+++ openssh-7.4p1/ssh_config_redhat 2016-12-23 13:32:00.045220402 +0100 +diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat +--- openssh-7.7p1/ssh_config_redhat.redhat 2018-07-03 10:44:06.522245125 +0200 ++++ openssh-7.7p1/ssh_config_redhat 2018-07-03 10:44:06.522245125 +0200 @@ -0,0 +1,20 @@ +# Follow system-wide Crypto Policy, if defined: +Include /etc/crypto-policies/back-ends/openssh.config @@ -33,10 +33,10 @@ diff -up openssh-7.4p1/ssh_config_redhat.redhat openssh-7.4p1/ssh_config_redhat + SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT + SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE + SendEnv XMODIFIERS -diff -up openssh-7.4p1/sshd_config.0.redhat openssh-7.4p1/sshd_config.0 ---- openssh-7.4p1/sshd_config.0.redhat 2016-12-19 06:21:22.000000000 +0100 -+++ openssh-7.4p1/sshd_config.0 2016-12-23 13:32:00.045220402 +0100 -@@ -837,9 +837,9 @@ DESCRIPTION +diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0 +--- openssh-7.7p1/sshd_config.0.redhat 2018-04-02 07:39:27.000000000 +0200 ++++ openssh-7.7p1/sshd_config.0 2018-07-03 10:44:06.523245133 +0200 +@@ -872,9 +872,9 @@ DESCRIPTION SyslogFacility Gives the facility code that is used when logging messages from @@ -49,10 +49,10 @@ diff -up openssh-7.4p1/sshd_config.0.redhat openssh-7.4p1/sshd_config.0 TCPKeepAlive Specifies whether the system should send TCP keepalive messages -diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.redhat 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:32:00.046220403 +0100 -@@ -1393,7 +1393,7 @@ By default no subsystems are defined. +diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5 +--- openssh-7.7p1/sshd_config.5.redhat 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/sshd_config.5 2018-07-03 10:44:06.523245133 +0200 +@@ -1461,7 +1461,7 @@ By default no subsystems are defined. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . @@ -61,9 +61,9 @@ diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive -diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.redhat 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 13:33:05.386233133 +0100 +diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config +--- openssh-7.7p1/sshd_config.redhat 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/sshd_config 2018-07-03 10:45:16.950782466 +0200 @@ -10,20 +10,34 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -78,9 +78,9 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config #ListenAddress :: -#HostKey /etc/ssh/ssh_host_rsa_key -+HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key ++HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key @@ -88,7 +88,7 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config #RekeyLimit default none +# System-wide Crypto policy: -+# If this system is following system-wide crypto policy, the changes to ++# This system is following system-wide crypto policy. The changes to +# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any +# effect here. They will be overridden by command-line options passed on +# the server start up. @@ -102,7 +102,7 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config #LogLevel INFO # Authentication: -@@ -57,9 +62,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -56,9 +70,11 @@ AuthorizedKeysFile .ssh/authorized_keys # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no @@ -114,7 +114,7 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config # Kerberos options #KerberosAuthentication no -@@ -68,8 +75,8 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -67,8 +83,8 @@ AuthorizedKeysFile .ssh/authorized_keys #KerberosGetAFSToken no # GSSAPI options @@ -125,7 +125,7 @@ diff -up openssh-7.4p1/sshd_config.redhat 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 -@@ -80,12 +87,12 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -79,16 +95,20 @@ 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 ChallengeResponseAuthentication to 'no'. @@ -140,7 +140,16 @@ diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config #X11DisplayOffset 10 #X11UseLocalhost yes #PermitTTY yes -@@ -108,6 +115,12 @@ AuthorizedKeysFile .ssh/authorized_keys +-#PrintMotd yes ++ ++# It is recommended to use pam_motd in /etc/pam.d/ssh instead of PrintMotd, ++# as it is more configurable and versatile than the built-in version. ++PrintMotd no ++ + #PrintLastLog yes + #TCPKeepAlive yes + #UseLogin no +@@ -106,6 +126,12 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none From f751fba9b3409e58151ccbb9c05a3518b75cdcce Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 13 Jul 2018 04:34:59 +0000 Subject: [PATCH 059/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ea90bde..4c22797 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -546,6 +546,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Jul 13 2018 Fedora Release Engineering - 7.7p1-4.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + * Thu Jul 05 2018 Mattias Ellert - 7.7p1-4 - Based on openssh-7.7p1-5.fc28 From 50a1d2c05473826890a93ecbac39e5a0d7d12fa0 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 16 Aug 2018 15:00:52 +0200 Subject: [PATCH 060/146] Based on openssh-7.7p1-6.fc28 --- gsi-openssh.spec | 9 +- openssh-7.6p1-pkcs11-uri.patch | 10 +- ...2p1-fips.patch => openssh-7.7p1-fips.patch | 190 ++++++++++-------- 3 files changed, 116 insertions(+), 93 deletions(-) rename openssh-7.2p1-fips.patch => openssh-7.7p1-fips.patch (76%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 4c22797..039726f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.7p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -93,7 +93,7 @@ Patch607: openssh-5.8p2-sigpipe.patch Patch609: openssh-7.2p2-x11.patch #? -Patch700: openssh-7.2p1-fips.patch +Patch700: openssh-7.7p1-fips.patch #? Patch702: openssh-5.1p1-askpass-progress.patch #https://bugzilla.redhat.com/show_bug.cgi?id=198332 @@ -546,6 +546,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Aug 16 2018 Mattias Ellert - 7.7p1-5 +- Based on openssh-7.7p1-6.fc28 + * Fri Jul 13 2018 Fedora Release Engineering - 7.7p1-4.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch index efafa70..79c6a00 100644 --- a/openssh-7.6p1-pkcs11-uri.patch +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -3102,7 +3102,7 @@ diff --git a/ssh-agent.c b/ssh-agent.c index 2a4578b0..f6c86240 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -546,10 +546,70 @@ no_identities(SocketEntry *e) +@@ -546,10 +546,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -3141,12 +3141,14 @@ index 2a4578b0..f6c86240 100644 + verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", + module_path, strerror(errno)); + free(module_path); ++ pkcs11_uri_cleanup(uri); + return NULL; + } + free(module_path); + if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { + verbose("refusing PKCS#11 provider \"%.100s\": " + "not whitelisted", canonical_provider); ++ pkcs11_uri_cleanup(uri); + return NULL; + } + @@ -3311,7 +3313,7 @@ new file mode 100644 index 00000000..da15c164 --- /dev/null +++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,399 @@ +@@ -0,0 +1,400 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3616,6 +3618,7 @@ index 00000000..da15c164 + break; + opcode = parse_token(tok); + if (opcode == pBadOption) { ++ free(p); + verbose("Unknown key in PKCS#11 URI: %s", tok); + return -1; + } @@ -4290,7 +4293,7 @@ index 88c9d6e2..a29b4451 100644 free(attribs[i].pValue); } if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) -@@ -581,126 +740,238 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -581,126 +740,239 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, int pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { @@ -4497,6 +4500,7 @@ index 88c9d6e2..a29b4451 100644 + error("C_Finalize for provider %s failed: %lu", + provider_module, rv); + free(provider_module); ++ free(p); + if (handle) + dlclose(handle); + return NULL; diff --git a/openssh-7.2p1-fips.patch b/openssh-7.7p1-fips.patch similarity index 76% rename from openssh-7.2p1-fips.patch rename to openssh-7.7p1-fips.patch index 8598463..49c9178 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c ---- openssh-7.5p1/cipher.c.fips 2017-06-30 12:06:36.455713788 +0200 -+++ openssh-7.5p1/cipher.c 2017-06-30 12:06:36.465713761 +0200 +diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c +--- openssh-7.7p1/cipher.c.fips 2018-08-08 10:08:40.814719906 +0200 ++++ openssh-7.7p1/cipher.c 2018-08-08 10:08:40.821719965 +0200 @@ -39,6 +39,8 @@ #include @@ -10,7 +10,7 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c #include #include #include -@@ -116,6 +118,27 @@ static const struct sshcipher ciphers[] +@@ -90,6 +92,33 @@ static const struct sshcipher ciphers[] { NULL, 0, 0, 0, 0, 0, NULL } }; @@ -25,6 +25,12 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c + { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, ++# ifdef OPENSSL_HAVE_EVPGCM ++ { "aes128-gcm@openssh.com", ++ 16, 16, 12, 16, 0, EVP_aes_128_gcm }, ++ { "aes256-gcm@openssh.com", ++ 16, 32, 12, 16, 0, EVP_aes_256_gcm }, ++# endif /* OPENSSL_HAVE_EVPGCM */ +#else + { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, + { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, @@ -38,7 +44,7 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c /*--*/ /* Returns a comma-separated list of supported ciphers. */ -@@ -126,7 +142,7 @@ cipher_alg_list(char sep, int auth_only) +@@ -100,7 +129,7 @@ cipher_alg_list(char sep, int auth_only) size_t nlen, rlen = 0; const struct sshcipher *c; @@ -47,7 +53,7 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) -@@ -222,7 +238,7 @@ const struct sshcipher * +@@ -172,7 +201,7 @@ const struct sshcipher * cipher_by_name(const char *name) { const struct sshcipher *c; @@ -56,9 +62,9 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c if (strcmp(c->name, name) == 0) return c; return NULL; -diff -up openssh-7.5p1/cipher-ctr.c.fips openssh-7.5p1/cipher-ctr.c ---- openssh-7.5p1/cipher-ctr.c.fips 2017-06-30 12:06:36.386713974 +0200 -+++ openssh-7.5p1/cipher-ctr.c 2017-06-30 12:06:36.465713761 +0200 +diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c +--- openssh-7.7p1/cipher-ctr.c.fips 2018-08-08 10:08:40.709719021 +0200 ++++ openssh-7.7p1/cipher-ctr.c 2018-08-08 10:08:40.821719965 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -69,10 +75,10 @@ diff -up openssh-7.5p1/cipher-ctr.c.fips openssh-7.5p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.5p1/clientloop.c.fips openssh-7.5p1/clientloop.c ---- openssh-7.5p1/clientloop.c.fips 2017-06-30 12:06:36.466713758 +0200 -+++ openssh-7.5p1/clientloop.c 2017-06-30 12:09:11.503295871 +0200 -@@ -2412,7 +2412,8 @@ key_accepted_by_hostkeyalgs(const struct +diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c +--- openssh-7.7p1/clientloop.c.fips 2018-08-08 10:08:40.769719527 +0200 ++++ openssh-7.7p1/clientloop.c 2018-08-08 10:08:40.822719973 +0200 +@@ -1978,7 +1978,8 @@ key_accepted_by_hostkeyalgs(const struct { const char *ktype = sshkey_ssh_name(key); const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? @@ -82,9 +88,9 @@ diff -up openssh-7.5p1/clientloop.c.fips openssh-7.5p1/clientloop.c if (key == NULL || key->type == KEY_UNSPEC) return 0; -diff -up openssh-7.5p1/dh.h.fips openssh-7.5p1/dh.h ---- openssh-7.5p1/dh.h.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/dh.h 2017-06-30 12:06:36.466713758 +0200 +diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h +--- openssh-7.7p1/dh.h.fips 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/dh.h 2018-08-08 10:08:40.822719973 +0200 @@ -51,6 +51,7 @@ u_int dh_estimate(int); * Miniumum increased in light of DH precomputation attacks. */ @@ -93,9 +99,9 @@ diff -up openssh-7.5p1/dh.h.fips openssh-7.5p1/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh-7.5p1/entropy.c.fips openssh-7.5p1/entropy.c ---- openssh-7.5p1/entropy.c.fips 2017-06-30 12:06:36.377713998 +0200 -+++ openssh-7.5p1/entropy.c 2017-06-30 12:06:36.466713758 +0200 +diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c +--- openssh-7.7p1/entropy.c.fips 2018-08-08 10:08:40.698718928 +0200 ++++ openssh-7.7p1/entropy.c 2018-08-08 10:08:40.822719973 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -106,9 +112,9 @@ diff -up openssh-7.5p1/entropy.c.fips openssh-7.5p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c ---- openssh-7.5p1/kex.c.fips 2017-06-30 12:06:36.455713788 +0200 -+++ openssh-7.5p1/kex.c 2017-06-30 12:06:36.466713758 +0200 +diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c +--- openssh-7.7p1/kex.c.fips 2018-08-08 10:08:40.815719915 +0200 ++++ openssh-7.7p1/kex.c 2018-08-08 10:11:24.109081924 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL #include @@ -117,7 +123,7 @@ diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c #endif #include "ssh2.h" -@@ -125,6 +126,26 @@ static const struct kexalg kexalgs[] = { +@@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = { { NULL, -1, -1, -1}, }; @@ -144,7 +150,16 @@ diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c char * kex_alg_list(char sep) { -@@ -152,7 +173,7 @@ kex_alg_by_name(const char *name) +@@ -129,7 +150,7 @@ kex_alg_list(char sep) + size_t nlen, rlen = 0; + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -149,7 +170,7 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -153,7 +168,7 @@ diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c if (strcmp(k->name, name) == 0) return k; #ifdef GSSAPI -@@ -178,7 +199,10 @@ kex_names_valid(const char *names) +@@ -175,7 +196,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -165,9 +180,9 @@ diff -up openssh-7.5p1/kex.c.fips openssh-7.5p1/kex.c free(s); return 0; } -diff -up openssh-7.5p1/kexgexc.c.fips openssh-7.5p1/kexgexc.c ---- openssh-7.5p1/kexgexc.c.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/kexgexc.c 2017-06-30 12:06:36.467713756 +0200 +diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c +--- openssh-7.7p1/kexgexc.c.fips 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/kexgexc.c 2018-08-08 10:08:40.822719973 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -185,10 +200,10 @@ diff -up openssh-7.5p1/kexgexc.c.fips openssh-7.5p1/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh-7.5p1/kexgexs.c.fips openssh-7.5p1/kexgexs.c ---- openssh-7.5p1/kexgexs.c.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/kexgexs.c 2017-06-30 12:06:36.467713756 +0200 -@@ -83,9 +83,9 @@ input_kex_dh_gex_request(int type, u_int +diff -up openssh-7.7p1/kexgexs.c.fips openssh-7.7p1/kexgexs.c +--- openssh-7.7p1/kexgexs.c.fips 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/kexgexs.c 2018-08-08 10:08:40.823719982 +0200 +@@ -82,9 +82,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; kex->min = min; kex->max = max; @@ -200,9 +215,9 @@ diff -up openssh-7.5p1/kexgexs.c.fips openssh-7.5p1/kexgexs.c nbits = MINIMUM(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c ---- openssh-7.5p1/mac.c.fips 2017-06-30 12:06:36.456713785 +0200 -+++ openssh-7.5p1/mac.c 2017-06-30 12:06:36.467713756 +0200 +diff -up openssh-7.7p1/mac.c.fips openssh-7.7p1/mac.c +--- openssh-7.7p1/mac.c.fips 2018-08-08 10:08:40.815719915 +0200 ++++ openssh-7.7p1/mac.c 2018-08-08 10:11:56.915352642 +0200 @@ -27,6 +27,8 @@ #include @@ -221,7 +236,7 @@ diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, -@@ -89,6 +91,24 @@ static const struct macalg macs[] = { +@@ -82,6 +84,24 @@ static const struct macalg macs[] = { { NULL, 0, 0, 0, 0, 0, 0 } }; @@ -246,7 +261,7 @@ diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c /* Returns a list of supported MACs separated by the specified char. */ char * mac_alg_list(char sep) -@@ -97,7 +117,7 @@ mac_alg_list(char sep) +@@ -90,7 +110,7 @@ mac_alg_list(char sep) size_t nlen, rlen = 0; const struct macalg *m; @@ -255,7 +270,7 @@ diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c if (ret != NULL) ret[rlen++] = sep; nlen = strlen(m->name); -@@ -136,7 +156,7 @@ mac_setup(struct sshmac *mac, char *name +@@ -129,7 +149,7 @@ mac_setup(struct sshmac *mac, char *name { const struct macalg *m; @@ -264,10 +279,10 @@ diff -up openssh-7.5p1/mac.c.fips openssh-7.5p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-7.5p1/Makefile.in.fips openssh-7.5p1/Makefile.in ---- openssh-7.5p1/Makefile.in.fips 2017-06-30 12:06:36.456713785 +0200 -+++ openssh-7.5p1/Makefile.in 2017-06-30 12:06:36.467713756 +0200 -@@ -169,25 +169,25 @@ libssh.a: $(LIBSSH_OBJS) +diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in +--- openssh-7.7p1/Makefile.in.fips 2018-08-08 10:08:40.815719915 +0200 ++++ openssh-7.7p1/Makefile.in 2018-08-08 10:08:40.823719982 +0200 +@@ -179,25 +179,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) @@ -299,7 +314,7 @@ diff -up openssh-7.5p1/Makefile.in.fips openssh-7.5p1/Makefile.in ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -205,7 +205,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a +@@ -215,7 +215,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o @@ -308,9 +323,9 @@ diff -up openssh-7.5p1/Makefile.in.fips openssh-7.5p1/Makefile.in sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.5p1/myproposal.h.fips openssh-7.5p1/myproposal.h ---- openssh-7.5p1/myproposal.h.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/myproposal.h 2017-06-30 12:10:21.953116208 +0200 +diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h +--- openssh-7.7p1/myproposal.h.fips 2018-04-02 07:38:28.000000000 +0200 ++++ openssh-7.7p1/myproposal.h 2018-08-08 10:08:40.823719982 +0200 @@ -114,6 +114,14 @@ "rsa-sha2-256," \ "ssh-rsa" @@ -326,14 +341,15 @@ diff -up openssh-7.5p1/myproposal.h.fips openssh-7.5p1/myproposal.h /* the actual algorithms */ #define KEX_SERVER_ENCRYPT \ -@@ -138,6 +146,37 @@ +@@ -137,6 +145,38 @@ #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" ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" \ ++ AESGCM_CIPHER_MODES +#ifdef HAVE_EVP_SHA256 +# define KEX_DEFAULT_KEX_FIPS \ + KEX_ECDH_METHODS \ @@ -364,10 +380,10 @@ diff -up openssh-7.5p1/myproposal.h.fips openssh-7.5p1/myproposal.h #else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ -diff -up openssh-7.5p1/readconf.c.fips openssh-7.5p1/readconf.c ---- openssh-7.5p1/readconf.c.fips 2017-06-30 12:06:36.468713753 +0200 -+++ openssh-7.5p1/readconf.c 2017-06-30 12:12:40.560769198 +0200 -@@ -2132,12 +2132,17 @@ fill_default_options(Options * options) +diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c +--- openssh-7.7p1/readconf.c.fips 2018-08-08 10:08:40.769719527 +0200 ++++ openssh-7.7p1/readconf.c 2018-08-08 10:08:40.824719990 +0200 +@@ -2081,12 +2081,17 @@ fill_default_options(Options * options) } if (options->update_hostkeys == -1) options->update_hostkeys = 0; @@ -390,9 +406,9 @@ diff -up openssh-7.5p1/readconf.c.fips openssh-7.5p1/readconf.c &options->pubkey_key_types) != 0) fatal("%s: kex_assemble_names failed", __func__); -diff -up openssh-7.5p1/sandbox-seccomp-filter.c.fips openssh-7.5p1/sandbox-seccomp-filter.c ---- openssh-7.5p1/sandbox-seccomp-filter.c.fips 2017-06-30 12:06:36.458713780 +0200 -+++ openssh-7.5p1/sandbox-seccomp-filter.c 2017-06-30 12:06:36.468713753 +0200 +diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-seccomp-filter.c +--- openssh-7.7p1/sandbox-seccomp-filter.c.fips 2018-08-08 10:08:40.794719737 +0200 ++++ openssh-7.7p1/sandbox-seccomp-filter.c 2018-08-08 10:08:40.824719990 +0200 @@ -137,6 +137,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), @@ -403,10 +419,10 @@ diff -up openssh-7.5p1/sandbox-seccomp-filter.c.fips openssh-7.5p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-7.5p1/servconf.c.fips openssh-7.5p1/servconf.c ---- openssh-7.5p1/servconf.c.fips 2017-06-30 12:06:36.468713753 +0200 -+++ openssh-7.5p1/servconf.c 2017-06-30 12:14:09.260547133 +0200 -@@ -185,14 +185,20 @@ option_clear_or_none(const char *o) +diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c +--- openssh-7.7p1/servconf.c.fips 2018-08-08 10:08:40.778719603 +0200 ++++ openssh-7.7p1/servconf.c 2018-08-08 10:08:40.824719990 +0200 +@@ -196,14 +196,20 @@ option_clear_or_none(const char *o) static void assemble_algorithms(ServerOptions *o) { @@ -433,9 +449,9 @@ diff -up openssh-7.5p1/servconf.c.fips openssh-7.5p1/servconf.c fatal("kex_assemble_names failed"); } -diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c ---- openssh-7.5p1/ssh.c.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/ssh.c 2017-06-30 12:06:36.469713750 +0200 +diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c +--- openssh-7.7p1/ssh.c.fips 2018-08-08 10:08:40.811719881 +0200 ++++ openssh-7.7p1/ssh.c 2018-08-08 10:08:40.825719999 +0200 @@ -76,6 +76,8 @@ #include #include @@ -445,7 +461,7 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -530,6 +532,14 @@ main(int ac, char **av) +@@ -579,6 +581,14 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -460,7 +476,7 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -964,7 +977,6 @@ main(int ac, char **av) +@@ -1045,7 +1055,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -468,7 +484,7 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c ERR_load_crypto_strings(); #endif -@@ -1175,6 +1187,10 @@ main(int ac, char **av) +@@ -1268,6 +1277,10 @@ main(int ac, char **av) seed_rng(); @@ -479,9 +495,9 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c ---- openssh-7.5p1/sshconnect2.c.fips 2017-06-30 12:06:36.439713831 +0200 -+++ openssh-7.5p1/sshconnect2.c 2017-06-30 12:06:36.469713750 +0200 +diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c +--- openssh-7.7p1/sshconnect2.c.fips 2018-08-08 10:08:40.786719670 +0200 ++++ openssh-7.7p1/sshconnect2.c 2018-08-08 10:08:40.825719999 +0200 @@ -44,6 +44,8 @@ #include #endif @@ -491,7 +507,7 @@ diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -117,7 +119,8 @@ order_hostkeyalgs(char *host, struct soc +@@ -235,7 +237,8 @@ order_hostkeyalgs(char *host, struct soc for (i = 0; i < options.num_system_hostfiles; i++) load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); @@ -501,7 +517,7 @@ diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); -@@ -172,21 +175,26 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -290,21 +293,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -543,7 +559,7 @@ diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c } } #endif -@@ -204,14 +212,16 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -322,14 +330,16 @@ ssh_kex2(char *host, struct sockaddr *ho myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; if (options.hostkeyalgorithms != NULL) { @@ -562,9 +578,9 @@ diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( -diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c ---- openssh-7.5p1/sshd.c.fips 2017-06-30 12:06:36.459713777 +0200 -+++ openssh-7.5p1/sshd.c 2017-06-30 12:06:36.469713750 +0200 +diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c +--- openssh-7.7p1/sshd.c.fips 2018-08-08 10:08:40.818719940 +0200 ++++ openssh-7.7p1/sshd.c 2018-08-08 10:08:40.826720007 +0200 @@ -66,6 +66,7 @@ #include #include @@ -582,7 +598,7 @@ diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1484,6 +1487,18 @@ main(int ac, char **av) +@@ -1534,6 +1537,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -601,7 +617,7 @@ diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1632,7 +1647,7 @@ main(int ac, char **av) +@@ -1675,7 +1690,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -610,7 +626,7 @@ diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1951,6 +1966,10 @@ main(int ac, char **av) +@@ -1979,6 +1994,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); @@ -621,7 +637,7 @@ diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2328,10 +2347,14 @@ do_ssh2_kex(void) +@@ -2359,10 +2378,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -640,9 +656,9 @@ diff -up openssh-7.5p1/sshd.c.fips openssh-7.5p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c ---- openssh-7.5p1/sshkey.c.fips 2017-06-30 12:06:36.459713777 +0200 -+++ openssh-7.5p1/sshkey.c 2017-06-30 12:06:36.470713747 +0200 +diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c +--- openssh-7.7p1/sshkey.c.fips 2018-08-08 10:08:40.818719940 +0200 ++++ openssh-7.7p1/sshkey.c 2018-08-08 10:08:40.826720007 +0200 @@ -34,6 +34,7 @@ #include #include @@ -651,7 +667,7 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c #endif #include "crypto_api.h" -@@ -58,6 +59,7 @@ +@@ -57,6 +58,7 @@ #include "sshkey.h" #include "sshkey-xmss.h" #include "match.h" @@ -659,7 +675,7 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c #include "xmss_fast.h" -@@ -1587,6 +1589,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1526,6 +1528,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -668,10 +684,10 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff -up openssh-7.5p1/ssh-keygen.c.fips openssh-7.5p1/ssh-keygen.c ---- openssh-7.5p1/ssh-keygen.c.fips 2017-03-20 03:39:27.000000000 +0100 -+++ openssh-7.5p1/ssh-keygen.c 2017-06-30 12:06:36.470713747 +0200 -@@ -217,6 +217,12 @@ type_bits_valid(int type, const char *na +diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c +--- openssh-7.7p1/ssh-keygen.c.fips 2018-08-08 10:08:40.801719797 +0200 ++++ openssh-7.7p1/ssh-keygen.c 2018-08-08 10:08:40.827720016 +0200 +@@ -229,6 +229,12 @@ type_bits_valid(int type, const char *na OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (*bitsp > maxbits) fatal("key bits exceeds maximum %d", maxbits); From 5923b7b9360e644bd8da5606577b3801c2ba5dc4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 24 Oct 2018 22:15:12 +0200 Subject: [PATCH 061/146] Based on openssh-7.8p1-3.fc28 --- gsi-openssh.spec | 38 +- gsisshd.sysconfig | 6 - openssh-5.8p1-packet.patch | 12 - openssh-6.1p1-gssapi-canohost.patch | 4 +- openssh-6.2p1-vendor.patch | 25 +- openssh-6.6.1p1-cisco-dh-keys.patch | 54 -- openssh-6.6.1p1-ip-port-config-parser.patch | 75 -- openssh-6.6.1p1-log-in-chroot.patch | 4 +- openssh-6.6.1p1-selinux-contexts.patch | 14 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 10 +- openssh-6.6p1-ctr-cavstest.patch | 25 +- openssh-6.6p1-entropy.patch | 262 ------ openssh-6.6p1-force_krb.patch | 18 +- openssh-6.6p1-keycat.patch | 4 +- openssh-6.6p1-kuserok.patch | 4 +- openssh-6.6p1-privsep-selinux.patch | 6 +- openssh-6.7p1-coverity.patch | 2 +- openssh-6.7p1-kdf-cavs.patch | 19 +- openssh-6.7p1-ldap.patch | 19 +- openssh-7.0p1-gssKexAlgorithms.patch | 61 +- openssh-7.0p1-show-more-fingerprints.patch | 324 ------- openssh-7.1p1-gssapi-documentation.patch | 2 +- openssh-7.1p2-audit-race-condition.patch | 26 +- openssh-7.3p1-openssl-1.1.0.patch | 46 +- openssh-7.3p1-x11-max-displays.patch | 4 +- openssh-7.5p1-gssapi-kex-with-ec.patch | 37 +- openssh-7.5p1-sandbox.patch | 8 +- openssh-7.6p1-audit.patch | 351 ++++---- openssh-7.6p1-pkcs11-ecdsa.patch | 53 +- openssh-7.6p1-pkcs11-uri.patch | 75 +- openssh-7.7p1-fips.patch | 123 +-- openssh-7.7p1-redhat.patch | 2 +- openssh-7.7p1-tun-devices.patch | 152 ---- ...atch => openssh-7.8p1-UsePAM-warning.patch | 2 +- ...gsissh.patch => openssh-7.8p1-gsissh.patch | 846 +++++++++--------- ...gsskex.patch => openssh-7.8p1-gsskex.patch | 610 +++++++------ openssh-7.8p1-ip-port-config-parser.patch | 72 ++ ...-mls.patch => openssh-7.8p1-role-mls.patch | 313 +++---- openssh-7.8p1-scp-ipv6.patch | 16 + sources | 4 +- 40 files changed, 1502 insertions(+), 2226 deletions(-) delete mode 100644 openssh-5.8p1-packet.patch delete mode 100644 openssh-6.6.1p1-cisco-dh-keys.patch delete mode 100644 openssh-6.6.1p1-ip-port-config-parser.patch delete mode 100644 openssh-6.6p1-entropy.patch delete mode 100644 openssh-7.0p1-show-more-fingerprints.patch delete mode 100644 openssh-7.7p1-tun-devices.patch rename openssh-7.2p2-UsePAM-UseLogin-warning.patch => openssh-7.8p1-UsePAM-warning.patch (97%) rename openssh-7.7p1-gsissh.patch => openssh-7.8p1-gsissh.patch (83%) rename openssh-7.2p1-gsskex.patch => openssh-7.8p1-gsskex.patch (83%) create mode 100644 openssh-7.8p1-ip-port-config-parser.patch rename openssh-6.6p1-role-mls.patch => openssh-7.8p1-role-mls.patch (72%) create mode 100644 openssh-7.8p1-scp-ipv6.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 039726f..c76558b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.7p1 -%global openssh_rel 5 +%global openssh_ver 7.8p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -59,8 +59,6 @@ Patch100: openssh-6.7p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 #https://bugzilla.redhat.com/show_bug.cgi?id=735889 #Patch102: openssh-5.8p1-getaddrinfo.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1889 -Patch103: openssh-5.8p1-packet.patch # OpenSSL 1.1.0 compatibility Patch104: openssh-7.3p1-openssl-1.1.0.patch @@ -72,7 +70,7 @@ Patch200: openssh-7.6p1-audit.patch Patch201: openssh-7.1p2-audit-race-condition.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch400: openssh-6.6p1-role-mls.patch +Patch400: openssh-7.8p1-role-mls.patch #https://bugzilla.redhat.com/show_bug.cgi?id=781634 Patch404: openssh-6.6p1-privsep-selinux.patch @@ -100,12 +98,10 @@ Patch702: openssh-5.1p1-askpass-progress.patch Patch703: openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) Patch707: openssh-7.7p1-redhat.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :) -Patch708: openssh-6.6p1-entropy.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) Patch709: openssh-6.2p1-vendor.patch # warn users for unsupported UsePAM=no (#757545) -Patch711: openssh-7.2p2-UsePAM-UseLogin-warning.patch +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 @@ -115,7 +111,7 @@ Patch714: openssh-6.7p1-kdf-cavs.patch #http://www.sxw.org.uk/computing/patches/openssh.html #changed cache storage type - #848228 -Patch800: openssh-7.2p1-gsskex.patch +Patch800: openssh-7.8p1-gsskex.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) @@ -139,14 +135,12 @@ Patch901: openssh-6.6p1-kuserok.patch Patch906: openssh-6.4p1-fromto-remote.patch # privsep_preauth: use SELinux context from selinux-policy (#1008580) Patch916: openssh-6.6.1p1-selinux-contexts.patch -# use different values for DH for Cisco servers (#1026430) -Patch917: openssh-6.6.1p1-cisco-dh-keys.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 # Config parser shouldn't accept ip/port syntax (#1130733) -Patch920: openssh-6.6.1p1-ip-port-config-parser.patch +Patch920: openssh-7.8p1-ip-port-config-parser.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) @@ -155,8 +149,6 @@ Patch926: openssh-6.7p1-sftp-force-permission.patch Patch929: openssh-6.9p1-permit-root-login.patch # Add GSSAPIKexAlgorithms option for server and client application Patch932: openssh-7.0p1-gssKexAlgorithms.patch -# Possibility to validate legacy systems by more fingerprints (#1249626)(#2439) -Patch933: openssh-7.0p1-show-more-fingerprints.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch # Move MAX_DISPLAYS to a configuration option (#1341302) @@ -171,12 +163,12 @@ Patch950: openssh-7.5p1-sandbox.patch Patch951: openssh-7.6p1-pkcs11-uri.patch # PKCS#11 ECDSA keys (upstream #2474, 8th iteration) Patch952: openssh-7.6p1-pkcs11-ecdsa.patch -# Opening tun devices fails + other regressions in OpenSSH v7.7 (#2855, #1567775) -Patch953: openssh-7.7p1-tun-devices.patch +# Unbreak scp between two IPv6 hosts (#1620333) +Patch953: openssh-7.8p1-scp-ipv6.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-7.7p1-gsissh.patch +Patch98: openssh-7.8p1-gsissh.patch License: BSD Group: Applications/Internet @@ -279,8 +271,7 @@ This version of OpenSSH has been modified to support GSI authentication. gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %setup -q -n openssh-%{version} -# investigate %patch102 -p1 -b .getaddrinfo -%patch103 -p1 -b .packet +# investigate %%patch102 -p1 -b .getaddrinfo %patch400 -p1 -b .role-mls %patch404 -p1 -b .privsep-selinux @@ -299,7 +290,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch702 -p1 -b .progress %patch703 -p1 -b .grab-info %patch707 -p1 -b .redhat -%patch708 -p1 -b .entropy %patch709 -p1 -b .vendor %patch711 -p1 -b .log-usepam-no %patch712 -p1 -b .evp-ctr @@ -316,7 +306,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch901 -p1 -b .kuserok %patch906 -p1 -b .fromto-remote %patch916 -p1 -b .contexts -#%patch917 -p1 -b .cisco-dh # investigate %patch918 -p1 -b .log-in-chroot %patch919 -p1 -b .scp %patch920 -p1 -b .config @@ -325,7 +314,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch926 -p1 -b .sftp-force-mode %patch929 -p1 -b .root-login %patch932 -p1 -b .gsskexalg -%patch933 -p1 -b .fingerprint %patch939 -p1 -b .s390-dev %patch944 -p1 -b .x11max %patch948 -p1 -b .systemd @@ -334,7 +322,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch950 -p1 -b .sandbox %patch951 -p1 -b .pkcs11-uri %patch952 -p1 -b .pkcs11-ecdsa -%patch953 -p1 -b .tun-devices +%patch953 -p1 -b .scp-ipv6 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -396,6 +384,7 @@ fi --with-ssl-engine \ --with-ipaddr-display \ --with-pie=no \ + --without-hardening `# The hardening flags are configured by system` \ --with-systemd \ --with-default-pkcs11-provider=yes \ %if %{ldap} @@ -546,6 +535,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Oct 23 2018 Mattias Ellert - 7.8p1-1 +- Based on openssh-7.8p1-3.fc28 + * Thu Aug 16 2018 Mattias Ellert - 7.7p1-5 - Based on openssh-7.7p1-6.fc28 diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index a668d82..2981eee 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -6,12 +6,6 @@ # of DSA key or systemctl mask gsisshd-keygen@rsa.service to disable RSA key # creation. -# Do not change this option unless you have hardware random -# generator and you REALLY know what you are doing - -SSH_USE_STRONG_RNG=0 -# SSH_USE_STRONG_RNG=1 - # System-wide crypto policy: # To opt-out, uncomment the following line # CRYPTO_POLICY= diff --git a/openssh-5.8p1-packet.patch b/openssh-5.8p1-packet.patch deleted file mode 100644 index 2389903..0000000 --- a/openssh-5.8p1-packet.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-6.8p1/packet.c.packet openssh-6.8p1/packet.c ---- openssh-6.8p1/packet.c.packet 2015-03-18 10:56:32.286930601 +0100 -+++ openssh-6.8p1/packet.c 2015-03-18 10:58:38.535629739 +0100 -@@ -371,6 +371,8 @@ ssh_packet_connection_is_on_socket(struc - struct sockaddr_storage from, to; - socklen_t fromlen, tolen; - -+ if (!state) -+ return 0; - if (state->connection_in == -1 || state->connection_out == -1) - return 0; - diff --git a/openssh-6.1p1-gssapi-canohost.patch b/openssh-6.1p1-gssapi-canohost.patch index 124ac7f..3e6c9cc 100644 --- a/openssh-6.1p1-gssapi-canohost.patch +++ b/openssh-6.1p1-gssapi-canohost.patch @@ -4,7 +4,7 @@ diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c @@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; - int ok = 0; + int r, ok = 0; - const char *gss_host; + const char *gss_host = NULL; @@ -13,7 +13,7 @@ diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c - else if (options.gss_trust_dns) + else if (options.gss_trust_dns) { gss_host = get_canonical_hostname(active_state, 1); -+ if ( strcmp( gss_host, "UNKNOWN" ) == 0 ) ++ if (strcmp(gss_host, "UNKNOWN") == 0) + gss_host = authctxt->host; + } else diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index 68abb56..1af5e9d 100644 --- a/openssh-6.2p1-vendor.patch +++ b/openssh-6.2p1-vendor.patch @@ -34,7 +34,7 @@ diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c options->client_alive_interval = -1; options->client_alive_count_max = -1; @@ -325,6 +326,8 @@ fill_default_server_options(ServerOption - options->ip_qos_bulk = IPTOS_THROUGHPUT; + options->ip_qos_bulk = IPTOS_DSCP_CS1; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); + if (options->show_patchlevel == -1) @@ -71,7 +71,7 @@ diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c while ((arg = strdelim(&cp)) && *arg != '\0') { if (match_user(NULL, NULL, NULL, arg) == -1) @@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); + dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); + dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); @@ -89,28 +89,13 @@ diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h int use_dns; int client_alive_interval; /* * poke the client this often to -diff -up openssh-7.4p1/sshd_config.0.vendor openssh-7.4p1/sshd_config.0 ---- openssh-7.4p1/sshd_config.0.vendor 2016-12-23 13:34:51.695253847 +0100 -+++ openssh-7.4p1/sshd_config.0 2016-12-23 13:36:53.146277511 +0100 -@@ -792,6 +792,11 @@ DESCRIPTION - rdomain(4). If the routing domain is set to %D, then the domain - in which the incoming connection was received will be applied. - -+ ShowPatchLevel -+ Specifies whether sshd will display the specific patch level of -+ the binary in the server identification string. The patch level -+ is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^]. -+ - StreamLocalBindMask - Sets the octal file creation mode mask (umask) used when creating - a Unix-domain socket file for local or remote port forwarding. diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100 @@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as - If the routing domain is set to - .Cm \&%D , - then the domain in which the incoming connection was received will be applied. + .Cm AcceptEnv + or + .Cm PermitUserEnvironment . +.It Cm ShowPatchLevel +Specifies whether +.Nm sshd diff --git a/openssh-6.6.1p1-cisco-dh-keys.patch b/openssh-6.6.1p1-cisco-dh-keys.patch deleted file mode 100644 index 6890c05..0000000 --- a/openssh-6.6.1p1-cisco-dh-keys.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff -up openssh-6.8p1/compat.c.cisco-dh openssh-6.8p1/compat.c ---- openssh-6.8p1/compat.c.cisco-dh 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/compat.c 2015-03-19 12:57:58.862606969 +0100 -@@ -167,6 +167,7 @@ compat_datafellows(const char *version) - SSH_BUG_SCANNER }, - { "Probe-*", - SSH_BUG_PROBE }, -+ { "Cisco-*", SSH_BUG_MAX4096DH }, - { NULL, 0 } - }; - -diff -up openssh-6.8p1/compat.h.cisco-dh openssh-6.8p1/compat.h ---- openssh-6.8p1/compat.h.cisco-dh 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/compat.h 2015-03-19 12:57:58.862606969 +0100 -@@ -60,6 +60,7 @@ - #define SSH_NEW_OPENSSH 0x04000000 - #define SSH_BUG_DYNAMIC_RPORT 0x08000000 - #define SSH_BUG_CURVE25519PAD 0x10000000 -+#define SSH_BUG_MAX4096DH 0x20000000 - - void enable_compat13(void); - void enable_compat20(void); -diff -up openssh-6.8p1/kexgexc.c.cisco-dh openssh-6.8p1/kexgexc.c ---- openssh-6.8p1/kexgexc.c.cisco-dh 2015-03-19 12:57:58.862606969 +0100 -+++ openssh-6.8p1/kexgexc.c 2015-03-19 13:11:52.320519969 +0100 -@@ -64,8 +64,27 @@ kexgex_client(struct ssh *ssh) - - kex->min = DH_GRP_MIN; - kex->max = DH_GRP_MAX; -+ -+ /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. -+ * We need to also ensure that min < nbits < max */ -+ -+ if (datafellows & SSH_BUG_MAX4096DH) { -+ /* The largest min for these servers is 4096 */ -+ kex->min = MIN(kex->min, 4096); -+ } -+ - kex->nbits = nbits; -- if (ssh->compat & SSH_OLD_DHGEX) { -+ kex->nbits = MIN(nbits, kex->max); -+ kex->nbits = MAX(nbits, kex->min); -+ -+ if (ssh->compat & SSH_BUG_MAX4096DH) { -+ /* Cannot have a nbits > 4096 for these servers */ -+ kex->nbits = MIN(kex->nbits, 4096); -+ /* nbits has to be powers of two */ -+ if (kex->nbits == 3072) -+ kex->nbits = 4096; -+ } -+ if (ssh->compat & SSH_OLD_DHGEX) { /* Old GEX request */ - /* Old GEX request */ - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)) - != 0 || diff --git a/openssh-6.6.1p1-ip-port-config-parser.patch b/openssh-6.6.1p1-ip-port-config-parser.patch deleted file mode 100644 index 88e1ca2..0000000 --- a/openssh-6.6.1p1-ip-port-config-parser.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/misc.c b/misc.c -index 874dcc8a..7b7f7a58 100644 ---- a/misc.c -+++ b/misc.c -@@ -466,7 +466,7 @@ put_host_port(const char *host, u_short port) - * The delimiter char, if present, is stored in delim. - * If this is the last field, *cp is set to NULL. - */ --static char * -+char * - hpdelim2(char **cp, char *delim) - { - char *s, *old; -diff --git a/misc.h b/misc.h -index cdafea73..cf9c8f28 100644 ---- a/misc.h -+++ b/misc.h -@@ -54,6 +54,7 @@ int set_rdomain(int, const char *); - int a2port(const char *); - int a2tun(const char *, int *); - char *put_host_port(const char *, u_short); -+char *hpdelim2(char **, char *); - char *hpdelim(char **); - char *cleanhostname(char *); - char *colon(char *); -diff --git a/servconf.c b/servconf.c -index 0f0d0906..1679181e 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -821,7 +821,7 @@ process_permitopen(struct ssh *ssh, ServerOptions *options) - { - u_int i; - int port; -- char *host, *arg, *oarg; -+ char *host, *arg, *oarg, ch; - - channel_clear_adm_permitted_opens(ssh); - if (options->num_permitted_opens == 0) -@@ -839,8 +839,8 @@ process_permitopen(struct ssh *ssh, ServerOptions *options) - /* Otherwise treat it as a list of permitted host:port */ - for (i = 0; i < options->num_permitted_opens; i++) { - oarg = arg = xstrdup(options->permitted_opens[i]); -- host = hpdelim(&arg); -- if (host == NULL) -+ host = hpdelim2(&arg, &ch); -+ if (host == NULL || ch == '/') - fatal("%s: missing host in PermitOpen", __func__); - host = cleanhostname(host); - if (arg == NULL || ((port = permitopen_port(arg)) < 0)) -@@ -1244,8 +1244,10 @@ process_server_config_line(ServerOptions *options, char *line, - port = 0; - p = arg; - } else { -- p = hpdelim(&arg); -- if (p == NULL) -+ char ch; -+ arg2 = NULL; -+ p = hpdelim2(&arg, &ch); -+ if (p == NULL || ch == '/') - fatal("%s line %d: bad address:port usage", - filename, linenum); - p = cleanhostname(p); -@@ -1815,9 +1817,10 @@ process_server_config_line(ServerOptions *options, char *line, - break; - } - for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { -+ char ch; - arg2 = xstrdup(arg); -- p = hpdelim(&arg); -- if (p == NULL) -+ p = hpdelim2(&arg, &ch); -+ if (p == NULL || ch == '/') - fatal("%s line %d: missing host in PermitOpen", - filename, linenum); - p = cleanhostname(p); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 99e2e03..7f822ab 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -34,9 +34,9 @@ diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h 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); - void log_redirect_stderr_to(const char *); 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 @@ -65,7 +65,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c - do_log2(level, "%s [preauth]", msg); + do_log2(level, "%s [%s]", msg, pmonitor->m_state); - buffer_free(&logmsg); + sshbuf_free(logmsg); free(msg); @@ -1719,13 +1723,28 @@ monitor_init(void) mon = xcalloc(1, sizeof(*mon)); diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index ea4cbd1..8bf6c78 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -7,7 +7,7 @@ index 8f32464..18a2ca4 100644 #include "servconf.h" #include "port-linux.h" +#include "misc.h" - #include "key.h" + #include "sshkey.h" #include "hostfile.h" #include "auth.h" @@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname) @@ -50,10 +50,10 @@ index 8f32464..18a2ca4 100644 + + cp = line; + arg = strdelim(&cp); -+ if (*arg == '\0') ++ if (arg && *arg == '\0') + arg = strdelim(&cp); + -+ if (strcmp(arg, "privsep_preauth") == 0) { ++ if (arg && strcmp(arg, "privsep_preauth") == 0) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + debug("%s: privsep_preauth is empty", __func__); @@ -82,6 +82,14 @@ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 22ea8ef..1fc963d 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "log.h" + #include "xmalloc.h" @@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) strlcpy(newctx + len, newname, newlen - len); if ((cx = index(cx + 1, ':'))) diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 5dec15b..37e010d 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -4,7 +4,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-ser @@ -279,7 +279,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri FILE *fp; char file[MAXPATHLEN]; - char line[BUFSIZ] = ""; + char *line = NULL; - char kuser[65]; /* match krb5_kuserok() */ struct stat st; struct passwd *pw = the_authctxt->pw; @@ -44,8 +44,8 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, @@ -497,12 +500,14 @@ static struct { { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -70,9 +70,9 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + intptr = &options->enable_k5users; + goto parse_flag; + + case sPermitListen: case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') + 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); diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 08c6a35..c56313d 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -19,8 +19,8 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in 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 - $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) + ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o + $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) @@ -39,7 +39,7 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in 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,208 @@ +@@ -0,0 +1,215 @@ +/* + * + * invocation (all of the following are equal): @@ -60,6 +60,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + +#include "xmalloc.h" +#include "log.h" ++#include "ssherr.h" +#include "cipher.h" + +/* compatibility with old or broken OpenSSL versions */ @@ -148,7 +149,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + char *hexiv = "00000000000000000000000000000000"; + char *hexdata = NULL; + char *p; -+ int i; ++ int i, r; + int encrypt = 1; + void *key; + size_t keylen; @@ -221,10 +222,13 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + return 2; + } + -+ cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt); ++ 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); ++ free(key); ++ free(iv); + + outdata = malloc(datalen); + if(outdata == NULL) { @@ -232,9 +236,12 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + return 2; + } + -+ cipher_crypt(cc, 0, outdata, data, datalen, 0, 0); ++ 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); ++ free(data); + + cipher_free(cc); + diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch deleted file mode 100644 index 7f6f4d0..0000000 --- a/openssh-6.6p1-entropy.patch +++ /dev/null @@ -1,262 +0,0 @@ -diff -up openssh-7.4p1/entropy.c.entropy openssh-7.4p1/entropy.c ---- openssh-7.4p1/entropy.c.entropy 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/entropy.c 2016-12-23 18:34:27.769753570 +0100 -@@ -229,6 +229,9 @@ seed_rng(void) - memset(buf, '\0', sizeof(buf)); - - #endif /* OPENSSL_PRNG_ONLY */ -+#ifdef __linux__ -+ linux_seed(); -+#endif /* __linux__ */ - if (RAND_status() != 1) - fatal("PRNG is not seeded"); - } -diff -up openssh-7.4p1/openbsd-compat/Makefile.in.entropy openssh-7.4p1/openbsd-compat/Makefile.in ---- openssh-7.4p1/openbsd-compat/Makefile.in.entropy 2016-12-23 18:34:53.715762155 +0100 -+++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 18:35:15.890769493 +0100 -@@ -20,7 +20,8 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - port-solaris.o \ - port-net.o \ - port-uw.o \ -- port-linux-sshd.o -+ port-linux-sshd.o \ -+ port-linux-prng.o - - .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-7.4p1/openbsd-compat/port-linux.h.entropy openssh-7.4p1/openbsd-compat/port-linux.h ---- openssh-7.4p1/openbsd-compat/port-linux.h.entropy 2016-12-23 18:34:27.747753563 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 18:34:27.769753570 +0100 -@@ -34,4 +34,6 @@ void oom_adjust_restore(void); - void oom_adjust_setup(void); - #endif - -+void linux_seed(void); -+ - #endif /* ! _PORT_LINUX_H */ -diff -up openssh-7.4p1/openbsd-compat/port-linux-prng.c.entropy openssh-7.4p1/openbsd-compat/port-linux-prng.c ---- openssh-7.4p1/openbsd-compat/port-linux-prng.c.entropy 2016-12-23 18:34:27.769753570 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux-prng.c 2016-12-23 18:34:27.769753570 +0100 -@@ -0,0 +1,59 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2011 Jan F. Chadima -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - prng support -+ */ -+ -+#include "includes.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ -+#include "servconf.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+void -+linux_seed(void) -+{ -+ char *env = getenv("SSH_USE_STRONG_RNG"); -+ char *random = "/dev/random"; -+ size_t len, ienv, randlen = 14; -+ -+ if (!env || !strcmp(env, "0")) -+ random = "/dev/urandom"; -+ else if ((ienv = atoi(env)) > randlen) -+ randlen = ienv; -+ -+ errno = 0; -+ if ((len = RAND_load_file(random, randlen)) != randlen) { -+ if (errno) -+ fatal ("cannot read from %s, %s", random, strerror(errno)); -+ else -+ fatal ("EOF reading %s", random); -+ } -+} -diff -up openssh-7.4p1/ssh.1.entropy openssh-7.4p1/ssh.1 ---- openssh-7.4p1/ssh.1.entropy 2016-12-23 18:34:27.754753565 +0100 -+++ openssh-7.4p1/ssh.1 2016-12-23 18:34:27.770753571 +0100 -@@ -1441,6 +1441,23 @@ For more information, see the - .Cm PermitUserEnvironment - option in - .Xr sshd_config 5 . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh FILES - .Bl -tag -width Ds -compact - .It Pa ~/.rhosts -diff -up openssh-7.4p1/ssh-add.1.entropy openssh-7.4p1/ssh-add.1 ---- openssh-7.4p1/ssh-add.1.entropy 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-add.1 2016-12-23 18:34:27.770753571 +0100 -@@ -171,6 +171,20 @@ to make this work.) - Identifies the path of a - .Ux Ns -domain - socket used to communicate with the agent. -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. - .El - .Sh FILES - .Bl -tag -width Ds -diff -up openssh-7.4p1/ssh-agent.1.entropy openssh-7.4p1/ssh-agent.1 ---- openssh-7.4p1/ssh-agent.1.entropy 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-agent.1 2016-12-23 18:34:27.770753571 +0100 -@@ -214,6 +214,24 @@ sockets used to contain the connection t - These sockets should only be readable by the owner. - The sockets should get automatically removed when the agent exits. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-7.4p1/sshd.8.entropy openssh-7.4p1/sshd.8 ---- openssh-7.4p1/sshd.8.entropy 2016-12-23 18:34:27.755753566 +0100 -+++ openssh-7.4p1/sshd.8 2016-12-23 18:34:27.770753571 +0100 -@@ -920,6 +920,24 @@ concurrently for different ports, this c - started last). - The content of this file is not sensitive; it can be world-readable. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh IPV6 - IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO -diff -up openssh-7.4p1/ssh-keygen.1.entropy openssh-7.4p1/ssh-keygen.1 ---- openssh-7.4p1/ssh-keygen.1.entropy 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keygen.1 2016-12-23 18:34:27.770753571 +0100 -@@ -848,6 +848,24 @@ Contains Diffie-Hellman groups used for - The file format is described in - .Xr moduli 5 . - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-7.4p1/ssh-keysign.8.entropy openssh-7.4p1/ssh-keysign.8 ---- openssh-7.4p1/ssh-keysign.8.entropy 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keysign.8 2016-12-23 18:34:27.770753571 +0100 -@@ -80,6 +80,24 @@ must be set-uid root if host-based authe - If these files exist they are assumed to contain public certificate - information corresponding with the private keys above. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 14 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-keygen 1 , diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch index ae948f7..aeee77f 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -11,9 +11,9 @@ index 413b845..54dd383 100644 +#include #include "xmalloc.h" - #include "key.h" + #include "sshkey.h" @@ -45,6 +47,7 @@ - #include "buffer.h" + #include "ssh-gss.h" +extern Authctxt *the_authctxt; @@ -66,7 +66,7 @@ index 413b845..54dd383 100644 } else retval = 0; -@@ -110,6 +133,135 @@ 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; } @@ -97,13 +97,14 @@ index 413b845..54dd383 100644 +{ + FILE *fp; + char file[MAXPATHLEN]; -+ char line[BUFSIZ] = ""; ++ char *line = NULL; + char kuser[65]; /* match krb5_kuserok() */ + struct stat st; + struct passwd *pw = the_authctxt->pw; + int found_principal = 0; + int ncommands = 0, allcommands = 0; -+ u_long linenum; ++ u_long linenum = 0; ++ size_t linesize = 0; + + snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); + /* If both .k5login and .k5users DNE, self-login is ok. */ @@ -147,9 +148,9 @@ index 413b845..54dd383 100644 + k5users_allowed_cmds = xcalloc(++ncommands, + sizeof(*k5users_allowed_cmds)); + -+ /* Check each line. ksu allows unlimited length lines. We don't. */ -+ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), -+ &linenum) != -1) { ++ /* Check each line. ksu allows unlimited length lines. */ ++ while (!allcommands && getline(&line, &linesize, fp) != -1) { ++ linenum++; + char *token; + + /* we parse just like ksu, even though we could do better */ @@ -182,6 +183,7 @@ index 413b845..54dd383 100644 + } + } + } ++ free(line); + if (k5users_allowed_cmds) { + /* terminate vector */ + k5users_allowed_cmds[ncommands-1] = NULL; diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 108f461..e22a5f3 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -64,8 +64,8 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) -+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o -+ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) ++ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o ++ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 23f47ae..81ec2a4 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -224,9 +224,9 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c + intptr = &options->use_kuserok; + goto parse_flag; + + case sPermitListen: case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') + 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); diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index bc2c15d..1365506 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -54,9 +54,9 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { @@ -1361,6 +1361,9 @@ do_setusercontext(struct passwd *pw) - pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); + (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 diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 253e0ee..0d238dd 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -120,7 +120,7 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c - 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("notify_done: reading"); + debug2("%s: reading", __func__); } @@ -518,7 +518,7 @@ server_request_tun(void) diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index 4e5c7a5..181267c 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in 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,380 @@ +@@ -0,0 +1,377 @@ +/* + * Copyright (C) 2015, Stephan Mueller + * @@ -88,11 +88,12 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c +#include + +#include "xmalloc.h" -+#include "buffer.h" -+#include "key.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) +{ @@ -234,16 +235,16 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c + /* select the right hash based on struct ssh_digest digests */ + switch (test->ik_len) { + case 20: -+ kex.hash_alg = 2; ++ kex.hash_alg = SSH_DIGEST_SHA1; + break; + case 32: -+ kex.hash_alg = 3; ++ kex.hash_alg = SSH_DIGEST_SHA256; + break; + case 48: -+ kex.hash_alg = 4; ++ kex.hash_alg = SSH_DIGEST_SHA384; + break; + case 64: -+ kex.hash_alg = 5; ++ kex.hash_alg = SSH_DIGEST_SHA512; + break; + default: + printf("Wrong hash type %u\n", test->ik_len); @@ -320,10 +321,6 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c +out: + if (Kbn) + BN_free(Kbn); -+ if (kex.newkeys[0]) -+ free(kex.newkeys[0]); -+ if (kex.newkeys[1]) -+ free(kex.newkeys[1]); + if (ssh) + ssh_packet_close(ssh); + return ret; diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index ddb3974..ee44fdb 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -157,7 +157,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in ssh-xmss.o \ @@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o + sandbox-solaris.o uidswap.o -MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out -MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 @@ -356,7 +356,7 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c --- openssh-6.8p1/ldap-helper.c.ldap 2015-03-18 11:11:29.030801464 +0100 +++ openssh-6.8p1/ldap-helper.c 2015-03-18 11:11:29.030801464 +0100 -@@ -0,0 +1,155 @@ +@@ -0,0 +1,151 @@ +/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -390,6 +390,7 @@ diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c +#include "ldapbody.h" +#include +#include ++#include + +static int config_debug = 0; +int config_exclusive_config_file = 0; @@ -507,11 +508,6 @@ diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c + ldap_do_close(); + return 0; +} -+ -+/* Ugly hack */ -+void *buffer_get_string(Buffer *b, u_int *l) { return NULL; } -+void buffer_put_string(Buffer *b, const void *f, u_int l) {} -+ diff -up openssh-6.8p1/ldap-helper.h.ldap openssh-6.8p1/ldap-helper.h --- openssh-6.8p1/ldap-helper.h.ldap 2015-03-18 11:11:29.031801462 +0100 +++ openssh-6.8p1/ldap-helper.h 2015-03-18 11:11:29.031801462 +0100 @@ -650,7 +646,7 @@ diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c --- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100 +++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,493 @@ +@@ -0,0 +1,494 @@ +/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -684,6 +680,7 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c +#include "ldapbody.h" +#include +#include ++#include +#include "misc.h" + +#define LDAPSEARCH_FORMAT "(&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f)" @@ -804,7 +801,8 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + char *logfilename; + int logfilenamelen; + -+ logfilenamelen = strlen (LDAP_LOGFILE) + strlen ("000000") + strlen (options.logdir); ++ logfilenamelen = strlen(LDAP_LOGFILE) ++ + strlen("000000") + strlen (options.logdir); + logfilename = xmalloc (logfilenamelen); + snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ()); + logfilename[logfilenamelen - 1] = 0; @@ -1188,7 +1186,7 @@ diff -up openssh-6.8p1/ldapbody.h.ldap openssh-6.8p1/ldapbody.h diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c --- openssh-6.8p1/ldapconf.c.ldap 2015-03-18 11:11:29.032801460 +0100 +++ openssh-6.8p1/ldapconf.c 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,728 @@ +@@ -0,0 +1,729 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -1222,6 +1220,7 @@ diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c +#include "ldapconf.h" +#include +#include ++#include + +/* Keyword tokens. */ + diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index d2453d5..2ba360e 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -23,9 +23,9 @@ diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, - const char *host, const char *client) { + const char *host, const char *client, const char *kex) { - Buffer buf; + struct sshbuf *buf; size_t i; - int oidpos, enclen; + int oidpos, enclen, r; @@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup char deroid[2]; const EVP_MD *evp_md = EVP_md5(); @@ -35,39 +35,44 @@ diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c if (gss_enc2oid != NULL) { for (i = 0; gss_enc2oid[i].encoded != NULL; i++) @@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - buffer_init(&buf); + fatal("%s: sshbuf_new failed", __func__); oidpos = 0; + s = cp = xstrdup(kex); for (i = 0; i < gss_supported->count; i++) { if (gss_supported->elements[i].length < 128 && (*check)(NULL, &(gss_supported->elements[i]), host, client)) { -@@ -131,26 +134,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup +@@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup enclen = __b64_ntop(digest, EVP_MD_size(evp_md), encoded, EVP_MD_size(evp_md) * 2); - if (oidpos != 0) -- buffer_put_char(&buf, ','); +- if ((r = sshbuf_put_u8(buf, ',')) != 0) +- fatal("%s: buffer error: %s", __func__, ssh_err(r)); - -- buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, -- sizeof(KEX_GSS_GEX_SHA1_ID) - 1); -- buffer_append(&buf, encoded, enclen); -- buffer_put_char(&buf, ','); -- buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, -- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); -- buffer_append(&buf, encoded, enclen); -- buffer_put_char(&buf, ','); -- buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, -- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); -- buffer_append(&buf, encoded, enclen); +- if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID, +- sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 || +- (r = sshbuf_put(buf, encoded, enclen)) != 0 || +- (r = sshbuf_put_u8(buf, ',')) != 0 || +- (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, +- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 || +- (r = sshbuf_put(buf, encoded, enclen)) != 0 || +- (r = sshbuf_put_u8(buf, ',')) != 0 || +- (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID, +- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 || +- (r = sshbuf_put(buf, encoded, enclen)) != 0) +- fatal("%s: buffer error: %s", __func__, ssh_err(r)); + cp = strncpy(s, kex, strlen(kex)); + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { -+ if (buffer_len(&buf) != 0) -+ buffer_put_char(&buf, ','); -+ buffer_append(&buf, p, -+ strlen(p)); -+ buffer_append(&buf, encoded, enclen); ++ if (sshbuf_len(buf) != 0) ++ if ((r = sshbuf_put_u8(buf, ',')) != 0) ++ fatal("%s: buffer error: %s", ++ __func__, ssh_err(r)); ++ if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || ++ (r = sshbuf_put(buf, encoded, enclen)) != 0) ++ fatal("%s: buffer error: %s", ++ __func__, ssh_err(r)); + } gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); @@ -104,7 +109,7 @@ diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c #include "ssherr.h" #include "sshbuf.h" @@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char - return 0; + return r; } +/* Validate GSS KEX method name list */ @@ -139,7 +144,7 @@ diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h @@ -173,6 +173,7 @@ int kex_names_valid(const char *); char *kex_alg_list(char); char *kex_names_cat(const char *, const char *); - int kex_assemble_names(const char *, char **); + int kex_assemble_names(char **, const char *, const char *); +int gss_kex_names_valid(const char *); int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); @@ -162,7 +167,7 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c - oGssServerIdentity, + oGssServerIdentity, oGssKexAlgorithms, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, - oSendEnv, oControlPath, oControlMaster, oControlPersist, + oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, @@ -200,6 +201,7 @@ static struct { { "gssapiclientidentity", oGssClientIdentity }, @@ -263,9 +268,9 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, -- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, -+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, sChrootDirectory, +- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, @@ -506,6 +510,7 @@ static struct { @@ -388,7 +393,7 @@ diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c +This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication - as a comma-separated pattern list. + as a list of comma-separated patterns. diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h --- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200 +++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200 diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch deleted file mode 100644 index aeb3daa..0000000 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ /dev/null @@ -1,324 +0,0 @@ -diff -up openssh/clientloop.c.fingerprint openssh/clientloop.c ---- openssh/clientloop.c.fingerprint 2017-09-26 15:21:22.582477729 +0200 -+++ openssh/clientloop.c 2017-09-26 15:21:22.620477932 +0200 -@@ -1854,7 +1854,7 @@ update_known_hosts(struct hostkeys_updat - if (ctx->keys_seen[i] != 2) - continue; - if ((fp = sshkey_fingerprint(ctx->keys[i], -- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) -+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); - do_log2(loglevel, "Learned new hostkey: %s %s", - sshkey_type(ctx->keys[i]), fp); -@@ -1862,7 +1862,7 @@ update_known_hosts(struct hostkeys_updat - } - for (i = 0; i < ctx->nold; i++) { - if ((fp = sshkey_fingerprint(ctx->old_keys[i], -- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) -+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); - do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", - sshkey_type(ctx->old_keys[i]), fp); -@@ -1905,7 +1905,7 @@ update_known_hosts(struct hostkeys_updat - (r = hostfile_replace_entries(options.user_hostfiles[0], - ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, - options.hash_known_hosts, 0, -- options.fingerprint_hash)) != 0) -+ options.fingerprint_hash[0])) != 0) - error("%s: hostfile_replace_entries failed: %s", - __func__, ssh_err(r)); - } -@@ -2038,7 +2038,7 @@ client_input_hostkeys(void) - error("%s: parse key: %s", __func__, ssh_err(r)); - goto out; - } -- fp = sshkey_fingerprint(key, options.fingerprint_hash, -+ fp = sshkey_fingerprint(key, options.fingerprint_hash[0], - SSH_FP_DEFAULT); - debug3("%s: received %s key %s", __func__, - sshkey_type(key), fp); -diff -up openssh/readconf.c.fingerprint openssh/readconf.c ---- openssh/readconf.c.fingerprint 2017-09-26 15:21:22.618477921 +0200 -+++ openssh/readconf.c 2017-09-26 15:21:22.621477937 +0200 -@@ -1681,16 +1681,18 @@ parse_keytypes: - goto parse_string; - - case oFingerprintHash: -- intptr = &options->fingerprint_hash; -- arg = strdelim(&s); -- if (!arg || *arg == '\0') -- fatal("%.200s line %d: Missing argument.", -- filename, linenum); -- if ((value = ssh_digest_alg_by_name(arg)) == -1) -- fatal("%.200s line %d: Invalid hash algorithm \"%s\".", -- filename, linenum, arg); -- if (*activep && *intptr == -1) -- *intptr = value; -+ if (*activep && options->num_fingerprint_hash == 0) -+ while ((arg = strdelim(&s)) != NULL && *arg != '\0') { -+ value = ssh_digest_alg_by_name(arg); -+ if (value == -1) -+ fatal("%s line %d: unknown fingerprints algorithm specs: %s.", -+ filename, linenum, arg); -+ if (options->num_fingerprint_hash >= SSH_DIGEST_MAX) -+ fatal("%s line %d: too many fingerprints algorithm specs.", -+ filename, linenum); -+ options->fingerprint_hash[ -+ options->num_fingerprint_hash++] = value; -+ } - break; - - case oUpdateHostkeys: -@@ -1917,7 +1919,7 @@ initialize_options(Options * options) - options->canonicalize_fallback_local = -1; - options->canonicalize_hostname = -1; - options->revoked_host_keys = NULL; -- options->fingerprint_hash = -1; -+ options->num_fingerprint_hash = 0; - options->update_hostkeys = -1; - options->hostbased_key_types = NULL; - options->pubkey_key_types = NULL; -@@ -2096,8 +2098,10 @@ fill_default_options(Options * options) - options->canonicalize_fallback_local = 1; - if (options->canonicalize_hostname == -1) - options->canonicalize_hostname = SSH_CANONICALISE_NO; -- if (options->fingerprint_hash == -1) -- options->fingerprint_hash = SSH_FP_HASH_DEFAULT; -+ if (options->num_fingerprint_hash == 0) { -+ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_SHA256; -+ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_MD5; -+ } - if (options->update_hostkeys == -1) - options->update_hostkeys = 0; - if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || -@@ -2474,6 +2478,17 @@ dump_cfg_strarray(OpCodes code, u_int co - } - - static void -+dump_cfg_fmtarray(OpCodes code, u_int count, int *vals) -+{ -+ u_int i; -+ -+ printf("%s", lookup_opcode_name(code)); -+ for (i = 0; i < count; i++) -+ printf(" %s", fmt_intarg(code, vals[i])); -+ printf("\n"); -+} -+ -+static void - dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) - { - u_int i; -@@ -2549,7 +2564,6 @@ dump_client_config(Options *o, const cha - dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); - dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); - dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); -- dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); - dump_cfg_fmtint(oForwardAgent, o->forward_agent); - dump_cfg_fmtint(oForwardX11, o->forward_x11); - dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); -@@ -2618,6 +2632,7 @@ dump_client_config(Options *o, const cha - dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); - dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); - dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); -+ dump_cfg_fmtarray(oFingerprintHash, o->num_fingerprint_hash, o->fingerprint_hash); - - /* Special cases */ - -diff -up openssh/readconf.h.fingerprint openssh/readconf.h ---- openssh/readconf.h.fingerprint 2017-09-26 15:21:22.618477921 +0200 -+++ openssh/readconf.h 2017-09-26 15:21:22.621477937 +0200 -@@ -21,6 +21,7 @@ - #define MAX_SEND_ENV 256 - #define SSH_MAX_HOSTS_FILES 32 - #define MAX_CANON_DOMAINS 32 -+#define MAX_SSH_DIGESTS 32 - #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) - - struct allowed_cname { -@@ -157,7 +158,8 @@ typedef struct { - - char *revoked_host_keys; - -- int fingerprint_hash; -+ int num_fingerprint_hash; -+ int fingerprint_hash[MAX_SSH_DIGESTS]; - - int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ - -diff -up openssh/ssh_config.5.fingerprint openssh/ssh_config.5 ---- openssh/ssh_config.5.fingerprint 2017-09-26 15:21:22.618477921 +0200 -+++ openssh/ssh_config.5 2017-09-26 15:21:22.621477937 +0200 -@@ -624,12 +624,13 @@ or - .Cm no - (the default). - .It Cm FingerprintHash --Specifies the hash algorithm used when displaying key fingerprints. -+Specifies the hash algorithms used when displaying key fingerprints. - Valid options are: - .Cm md5 - and --.Cm sha256 --(the default). -+.Cm sha256 . -+The default is -+.Cm "sha256 md5". - .It Cm ForwardAgent - Specifies whether the connection to the authentication agent (if any) - will be forwarded to the remote machine. -diff -up openssh/sshconnect2.c.fingerprint openssh/sshconnect2.c ---- openssh/sshconnect2.c.fingerprint 2017-09-26 15:21:22.619477926 +0200 -+++ openssh/sshconnect2.c 2017-09-26 15:21:50.677628003 +0200 -@@ -679,7 +679,7 @@ input_userauth_pk_ok(int type, u_int32_t - key->type, pktype); - goto done; - } -- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) - goto done; - debug2("input_userauth_pk_ok: fp %s", fp); -@@ -1198,7 +1198,7 @@ sign_and_send_pubkey(Authctxt *authctxt, - int matched, ret = -1, have_sig = 1; - char *fp; - -- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) - return 0; - debug3("%s: %s %s", __func__, key_type(id->key), fp); -@@ -1620,7 +1620,7 @@ userauth_pubkey(Authctxt *authctxt) - if (id->key != NULL) { - if (try_identity(id)) { - if ((fp = sshkey_fingerprint(id->key, -- options.fingerprint_hash, -+ options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) { - error("%s: sshkey_fingerprint failed", - __func__); -@@ -1914,7 +1914,7 @@ userauth_hostbased(Authctxt *authctxt) - goto out; - } - -- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) { - error("%s: sshkey_fingerprint failed", __func__); - goto out; -diff -up openssh/sshconnect.c.fingerprint openssh/sshconnect.c ---- openssh/sshconnect.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/sshconnect.c 2017-09-26 15:21:22.622477943 +0200 -@@ -861,9 +861,9 @@ check_host_key(char *hostname, struct so - "of known hosts.", type, ip); - } else if (options.visual_host_key) { - fp = sshkey_fingerprint(host_key, -- options.fingerprint_hash, SSH_FP_DEFAULT); -+ options.fingerprint_hash[0], SSH_FP_DEFAULT); - ra = sshkey_fingerprint(host_key, -- options.fingerprint_hash, SSH_FP_RANDOMART); -+ options.fingerprint_hash[0], SSH_FP_RANDOMART); - if (fp == NULL || ra == NULL) - fatal("%s: sshkey_fingerprint fail", __func__); - logit("Host key fingerprint is %s\n%s", fp, ra); -@@ -907,12 +907,6 @@ check_host_key(char *hostname, struct so - else - snprintf(msg1, sizeof(msg1), "."); - /* The default */ -- fp = sshkey_fingerprint(host_key, -- options.fingerprint_hash, SSH_FP_DEFAULT); -- ra = sshkey_fingerprint(host_key, -- options.fingerprint_hash, SSH_FP_RANDOMART); -- if (fp == NULL || ra == NULL) -- fatal("%s: sshkey_fingerprint fail", __func__); - msg2[0] = '\0'; - if (options.verify_host_key_dns) { - if (matching_host_key_dns) -@@ -926,16 +920,28 @@ check_host_key(char *hostname, struct so - } - snprintf(msg, sizeof(msg), - "The authenticity of host '%.200s (%s)' can't be " -- "established%s\n" -- "%s key fingerprint is %s.%s%s\n%s" -+ "established%s\n", host, ip, msg1); -+ for (i = 0; i < (u_int) options.num_fingerprint_hash; i++) { -+ fp = sshkey_fingerprint(host_key, -+ options.fingerprint_hash[i], SSH_FP_DEFAULT); -+ ra = sshkey_fingerprint(host_key, -+ options.fingerprint_hash[i], SSH_FP_RANDOMART); -+ if (fp == NULL || ra == NULL) -+ fatal("%s: sshkey_fingerprint fail", __func__); -+ len = strlen(msg); -+ snprintf(msg+len, sizeof(msg)-len, -+ "%s key fingerprint is %s.%s%s\n%s", -+ type, fp, -+ options.visual_host_key ? "\n" : "", -+ options.visual_host_key ? ra : "", -+ msg2); -+ free(ra); -+ free(fp); -+ } -+ len = strlen(msg); -+ snprintf(msg+len, sizeof(msg)-len, - "Are you sure you want to continue connecting " -- "(yes/no)? ", -- host, ip, msg1, type, fp, -- options.visual_host_key ? "\n" : "", -- options.visual_host_key ? ra : "", -- msg2); -- free(ra); -- free(fp); -+ "(yes/no)? "); - if (!confirm(msg)) - goto fail; - hostkey_trusted = 1; /* user explicitly confirmed */ -@@ -1192,7 +1198,7 @@ verify_host_key(char *host, struct socka - struct sshkey *plain = NULL; - - if ((fp = sshkey_fingerprint(host_key, -- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { -+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { - error("%s: fingerprint host key: %s", __func__, ssh_err(r)); - r = -1; - goto out; -@@ -1200,7 +1206,7 @@ verify_host_key(char *host, struct socka - - if (sshkey_is_cert(host_key)) { - if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, -- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { -+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { - error("%s: fingerprint CA key: %s", - __func__, ssh_err(r)); - r = -1; -@@ -1369,9 +1375,9 @@ show_other_keys(struct hostkeys *hostkey - if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) - continue; - fp = sshkey_fingerprint(found->key, -- options.fingerprint_hash, SSH_FP_DEFAULT); -+ options.fingerprint_hash[0], SSH_FP_DEFAULT); - ra = sshkey_fingerprint(found->key, -- options.fingerprint_hash, SSH_FP_RANDOMART); -+ options.fingerprint_hash[0], SSH_FP_RANDOMART); - if (fp == NULL || ra == NULL) - fatal("%s: sshkey_fingerprint fail", __func__); - logit("WARNING: %s key found for host %s\n" -@@ -1394,7 +1400,7 @@ warn_changed_key(struct sshkey *host_key - { - char *fp; - -- fp = sshkey_fingerprint(host_key, options.fingerprint_hash, -+ fp = sshkey_fingerprint(host_key, options.fingerprint_hash[0], - SSH_FP_DEFAULT); - if (fp == NULL) - fatal("%s: sshkey_fingerprint fail", __func__); -diff -up openssh/ssh-keysign.c.fingerprint openssh/ssh-keysign.c ---- openssh/ssh-keysign.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/ssh-keysign.c 2017-09-26 15:21:22.622477943 +0200 -@@ -285,7 +285,7 @@ main(int argc, char **argv) - } - } - if (!found) { -- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, -+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], - SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __progname); - fatal("no matching hostkey found for key %s %s", diff --git a/openssh-7.1p1-gssapi-documentation.patch b/openssh-7.1p1-gssapi-documentation.patch index a97cbc4..db689d4 100644 --- a/openssh-7.1p1-gssapi-documentation.patch +++ b/openssh-7.1p1-gssapi-documentation.patch @@ -49,4 +49,4 @@ diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5 +needs to be enabled in the server and also used by the client. .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication - as a comma-separated pattern list. + as a list of comma-separated patterns. diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index d390f63..9a0d917 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -1,20 +1,21 @@ 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,48 @@ mm_audit_destroy_sensitive_data(const ch - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); - buffer_free(&m); +@@ -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); } + +int mm_forward_audit_messages(int fdin) +{ + u_char buf[4]; + u_int blen, msg_len; -+ Buffer m; -+ int ret = 0; ++ struct sshbuf *m; ++ int r, ret = 0; + + debug3("%s: entering", __func__); -+ buffer_init(&m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); + do { + blen = atomicio(read, fdin, buf, sizeof(buf)); + if (blen == 0) /* closed pipe */ @@ -28,21 +29,22 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c + msg_len = get_u32(buf); + if (msg_len > 256 * 1024) + fatal("%s: read: bad msg_len %d", __func__, msg_len); -+ buffer_clear(&m); -+ buffer_append_space(&m, msg_len); -+ if (atomicio(read, fdin, buffer_ptr(&m), msg_len) != msg_len) { ++ sshbuf_reset(m); ++ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) { + 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, buffer_ptr(&m), msg_len) != msg_len) { ++ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) { + error("%s: Failed to write the message to the monitor", __func__); + ret = -1; + break; + } + } while (1); -+ buffer_free(&m); ++ sshbuf_free(m); + return ret; +} +void mm_set_monitor_pipe(int fd) @@ -115,7 +117,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c ret = do_exec_pty(ssh, s, command); @@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) */ - buffer_clear(&loginmsg); + sshbuf_reset(loginmsg); +#ifdef SSH_AUDIT_EVENTS + close(paudit[1]); diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index c3d16ac..5c18666 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -136,7 +136,7 @@ diff -up openssh/dh.c.openssl openssh/dh.c need > INT_MAX / 2 || 2 * need > pbits) return SSH_ERR_INVALID_ARGUMENT; if (need < 256) -@@ -271,10 +275,11 @@ dh_gen_key(DH *dh, int need) +@@ -271,11 +275,11 @@ dh_gen_key(DH *dh, int need) * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), * so double requested need here. */ @@ -144,6 +144,7 @@ diff -up openssh/dh.c.openssl openssh/dh.c - if (DH_generate_key(dh) == 0 || - !dh_pub_is_valid(dh, dh->pub_key)) { - BN_clear_free(dh->priv_key); +- dh->priv_key = NULL; + DH_set_length(dh, MINIMUM(need * 2, pbits - 1)); + if (DH_generate_key(dh) == 0) + return SSH_ERR_LIBCRYPTO_ERROR; @@ -300,8 +301,8 @@ diff -up openssh/gss-genr.c.openssl openssh/gss-genr.c if (gss_enc2oid != NULL) { @@ -113,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - - buffer_init(&buf); + if ((buf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + md = EVP_MD_CTX_new(); oidpos = 0; @@ -452,7 +453,7 @@ diff -up openssh/kexdhs.c.openssl openssh/kexdhs.c hash, &hashlen)) != 0) goto out; @@ -197,7 +203,7 @@ input_kex_dh_init(int type, u_int32_t se - /* send server hostkey, DH pubkey 'f' and singed H */ + /* send server hostkey, DH pubkey 'f' and signed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ @@ -599,7 +600,7 @@ diff -up openssh/kexgexs.c.openssl openssh/kexgexs.c hash, &hashlen)) != 0) goto out; @@ -227,7 +236,7 @@ input_kex_dh_gex_init(int type, u_int32_ - /* send server hostkey, DH pubkey 'f' and singed H */ + /* send server hostkey, DH pubkey 'f' and signed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ @@ -636,8 +637,8 @@ diff -up openssh/kexgssc.c.openssl openssh/kexgssc.c } else { packet_start(SSH2_MSG_KEXGSS_CONTINUE); @@ -282,13 +284,14 @@ kexgss_client(struct ssh *ssh) { - buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), - buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, - dh->pub_key, /* e */ + pub_key, /* e */ @@ -652,7 +653,7 @@ diff -up openssh/kexgssc.c.openssl openssh/kexgssc.c ssh->kex->hash_alg, ssh->kex->client_version_string, @@ -297,8 +300,8 @@ kexgss_client(struct ssh *ssh) { - buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, min, nbits, max, - dh->p, dh->g, @@ -695,8 +696,8 @@ diff -up openssh/kexgsss.c.openssl openssh/kexgsss.c switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: @@ -232,7 +235,7 @@ kexgss_server(struct ssh *ssh) - buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), - buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), NULL, 0, /* Change this if we start sending host keys */ - dh_client_pub, dh->pub_key, shared_secret, + dh_client_pub, pub_key, shared_secret, @@ -704,7 +705,7 @@ diff -up openssh/kexgsss.c.openssl openssh/kexgsss.c ); break; @@ -244,9 +247,9 @@ kexgss_server(struct ssh *ssh) - buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), NULL, 0, cmin, nbits, cmax, - dh->p, dh->g, @@ -1241,14 +1242,14 @@ diff -up openssh/monitor.c.openssl openssh/monitor.c + const BIGNUM *p, *g; + + DH_get0_pqg(dh, &p, NULL, &g); - buffer_put_char(m, 1); -- buffer_put_bignum2(m, dh->p); -- buffer_put_bignum2(m, dh->g); -+ buffer_put_bignum2(m, p); -+ buffer_put_bignum2(m, g); + if ((r = sshbuf_put_u8(m, 1)) != 0 || +- (r = sshbuf_put_bignum2(m, dh->p)) != 0 || +- (r = sshbuf_put_bignum2(m, dh->g)) != 0) ++ (r = sshbuf_put_bignum2(m, p)) != 0 || ++ (r = sshbuf_put_bignum2(m, g)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); DH_free(dh); - } diff -up openssh/openbsd-compat/openssl-compat.c.openssl openssh/openbsd-compat/openssl-compat.c --- openssh/openbsd-compat/openssl-compat.c.openssl 2017-09-19 06:26:43.000000000 +0200 +++ openssh/openbsd-compat/openssl-compat.c 2017-09-26 13:19:31.799249709 +0200 @@ -1393,17 +1394,6 @@ diff -up openssh/regress/unittests/sshkey/test_sshkey.c.openssl openssh/regress/ TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -up openssh/sshconnect2.c.openssl openssh/sshconnect2.c ---- openssh/sshconnect2.c.openssl 2017-09-26 13:19:31.786249629 +0200 -+++ openssh/sshconnect2.c 2017-09-26 13:19:31.800249715 +0200 -@@ -306,6 +306,7 @@ ssh_kex2(char *host, struct sockaddr *ho - packet_send(); - packet_write_wait(); - #endif -+ /* XXX free myproposal ?? */ - } - - /* diff -up openssh/ssh.c.openssl openssh/ssh.c --- openssh/ssh.c.openssl 2017-09-26 13:19:31.786249629 +0200 +++ openssh/ssh.c 2017-09-26 13:19:31.800249715 +0200 diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index b36671d..94dac8f 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -10,8 +10,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c +/* Minimum port number for X11 forwarding */ +#define X11_PORT_MIN 6000 - /* - * Data structure for storing which hosts are permitted for forward requests. + /* 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 diff --git a/openssh-7.5p1-gssapi-kex-with-ec.patch b/openssh-7.5p1-gssapi-kex-with-ec.patch index 437cce6..5f2763a 100644 --- a/openssh-7.5p1-gssapi-kex-with-ec.patch +++ b/openssh-7.5p1-gssapi-kex-with-ec.patch @@ -91,7 +91,7 @@ index 132df8b5..ed23f06d 100644 + case KEX_GSS_GRP16_SHA512: kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, ssh->kex->server_version_string, - buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), diff --git a/kexgsss.c b/kexgsss.c index 82a715cc..b7da8823 100644 --- a/kexgsss.c @@ -117,7 +117,7 @@ index 82a715cc..b7da8823 100644 + case KEX_GSS_GRP16_SHA512: kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, ssh->kex->server_version_string, - buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), diff --git a/monitor.c b/monitor.c index 17046936..d6bc7ac7 100644 --- a/monitor.c @@ -371,7 +371,7 @@ index ed23f06d..bdb3109a 100644 /* If we're already complete - protocol error */ if (maj_status == GSS_S_COMPLETE) packet_disconnect("Protocol error: received token when complete"); -@@ -344,4 +345,381 @@ kexgss_client(struct ssh *ssh) { +@@ -344,4 +345,382 @@ kexgss_client(struct ssh *ssh) { return kex_send_newkeys(ssh); } @@ -385,7 +385,7 @@ index ed23f06d..bdb3109a 100644 + u_char *server_pub = NULL; + u_int server_pub_len = 0; + BIGNUM *shared_secret = NULL; -+ u_char *kbuf; ++ u_char *kbuf = NULL; + u_char *serverhostkey = NULL; + u_char *empty = ""; + char *msg; @@ -446,8 +446,9 @@ index ed23f06d..bdb3109a 100644 + sizeof(kex->c25519_client_key)); +#endif + -+ sshbuf_put_string(Q_C, kex->c25519_client_pubkey, -+ sizeof(kex->c25519_client_pubkey)); ++ if ((r = sshbuf_put_string(Q_C, kex->c25519_client_pubkey, ++ sizeof(kex->c25519_client_pubkey))) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); @@ -674,8 +675,8 @@ index ed23f06d..bdb3109a 100644 + kex_c25519_hash( + kex->hash_alg, + kex->client_version_string, kex->server_version_string, -+ buffer_ptr(kex->my), buffer_len(kex->my), -+ buffer_ptr(kex->peer), buffer_len(kex->peer), ++ sshbuf_ptr(kex->my), sshbuf_len(kex->my), ++ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + kex->c25519_client_pubkey, server_pub, + sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), @@ -765,7 +766,7 @@ index b7da8823..a7c42803 100644 extern ServerOptions options; -@@ -303,4 +304,336 @@ kexgss_server(struct ssh *ssh) +@@ -303,4 +304,338 @@ kexgss_server(struct ssh *ssh) ssh_gssapi_rekey_creds(); return 0; } @@ -787,7 +788,7 @@ index b7da8823..a7c42803 100644 + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; + u_int slen, klen = 0; -+ u_char *kbuf; ++ u_char *kbuf = NULL; + BIGNUM *shared_secret = NULL; + int type = 0; + gss_OID oid; @@ -854,8 +855,9 @@ index b7da8823..a7c42803 100644 + dump_digest("server private key:", c25519_server_key, + sizeof(c25519_server_key)); +#endif -+ sshbuf_put_string(Q_S, c25519_server_pubkey, -+ sizeof(c25519_server_pubkey)); ++ if ((r = sshbuf_put_string(Q_S, c25519_server_pubkey, ++ sizeof(c25519_server_pubkey))) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); @@ -1008,8 +1010,8 @@ index b7da8823..a7c42803 100644 + kex_c25519_hash( + kex->hash_alg, + kex->client_version_string, kex->server_version_string, -+ buffer_ptr(kex->peer), buffer_len(kex->peer), -+ buffer_ptr(kex->my), buffer_len(kex->my), ++ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), ++ sshbuf_ptr(kex->my), sshbuf_len(kex->my), + NULL, 0, + client_pub, c25519_server_pubkey, + sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), @@ -1036,7 +1038,8 @@ index b7da8823..a7c42803 100644 + { + const u_char *ptr; + size_t len; -+ sshbuf_get_string_direct(Q_S, &ptr, &len); ++ if ((r = sshbuf_get_string_direct(Q_S, &ptr, &len)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + packet_put_string(ptr, len); + } + packet_put_string(msg_tok.value, msg_tok.length); @@ -1117,8 +1120,8 @@ index d6bc7ac7..b11616c8 100644 kex->load_host_public_key=&get_hostkey_public_by_type; @@ -1867,7 +1869,8 @@ mm_answer_gss_sign(int socket, Buffer *m) - data.value = buffer_get_string(m, &len); - data.length = len; + if ((r = sshbuf_get_string(m, (u_char **)&data.value, &data.length)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (data.length != 20) + /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ + if (data.length != 20 && data.length != 32 && data.length != 64) diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7cdb0aa..b761962 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -20,8 +20,8 @@ index ca75cc7..6e7de31 100644 +#if defined(__NR_flock) && defined(__s390__) + SC_ALLOW(__NR_flock), +#endif - #ifdef __NR_getpgid - SC_ALLOW(__NR_getpgid), + #ifdef __NR_geteuid + SC_ALLOW(__NR_geteuid), #endif @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_gettimeofday @@ -30,8 +30,8 @@ index ca75cc7..6e7de31 100644 +#if defined(__NR_ipc) && defined(__s390__) + SC_ALLOW(__NR_ipc), +#endif - #ifdef __NR_madvise - SC_ALLOW(__NR_madvise), + #ifdef __NR_getuid + SC_ALLOW(__NR_getuid), #endif -- 1.9.1 diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index c6e30a4..e184894 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -77,16 +77,8 @@ diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c --- openssh-7.6p1/audit.c.audit 2017-10-02 21:34:26.000000000 +0200 +++ openssh-7.6p1/audit.c 2017-10-04 17:18:32.834505048 +0200 -@@ -26,6 +26,7 @@ - - #include - #include -+#include - - #ifdef SSH_AUDIT_EVENTS - @@ -34,6 +35,12 @@ - #include "key.h" + #include "log.h" #include "hostfile.h" #include "auth.h" +#include "ssh-gss.h" @@ -127,7 +119,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c } +void -+audit_key(int host_user, int *rv, const Key *key) ++audit_key(int host_user, int *rv, const struct sshkey *key) +{ + char *fp; + @@ -268,7 +260,7 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h # define _SSH_AUDIT_H #include "loginrec.h" -+#include "key.h" ++#include "sshkey.h" enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, @@ -296,7 +288,7 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h +void audit_end_command(int, const char *); ssh_audit_event_t audit_classify_auth(const char *); +int audit_keyusage(int, char *, int); -+void audit_key(int, int *, const Key *); ++void audit_key(int, int *, const struct sshkey *); +void audit_unsupported(int); +void audit_kex(int, char *, char *, char *, char *); +void audit_unsupported_body(int); @@ -313,7 +305,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c #include "log.h" #include "audit.h" -+#include "key.h" ++#include "sshkey.h" +#include "hostfile.h" +#include "auth.h" +#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ @@ -596,8 +588,8 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +const static char *direction[] = { "from-server", "from-client", "both" }; + +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, -+ uid_t uid) ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, ++ char *pfs, pid_t pid, uid_t uid) +{ +#ifdef AUDIT_CRYPTO_SESSION + char buf[AUDIT_LOG_SIZE]; @@ -786,11 +778,11 @@ diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && -- PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), -+ PRIVSEP(user_key_verify(key, sig, slen, sshbuf_ptr(b), - sshbuf_len(b), NULL, ssh->compat)) == 0) { - authenticated = 1; - } +- PRIVSEP(sshkey_verify(key, sig, slen, ++ PRIVSEP(user_key_verify(key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), + (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, + ssh->compat)) == 0) { @@ -250,6 +250,19 @@ done: return authenticated; } @@ -882,7 +874,7 @@ diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c - static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL - { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, + #ifndef OPENSSL_NO_DES @@ -409,7 +409,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) @@ -1032,17 +1024,6 @@ diff -up openssh-7.6p1/kex.h.audit openssh-7.6p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.6p1/key.h.audit openssh-7.6p1/key.h ---- openssh-7.6p1/key.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/key.h 2017-10-04 17:18:32.836505059 +0200 -@@ -43,6 +43,7 @@ typedef struct sshkey Key; - #define key_ssh_name_plain sshkey_ssh_name_plain - #define key_type_from_name sshkey_type_from_name - #define key_is_cert sshkey_is_cert -+#define key_is_private sshkey_is_private - #define key_type_plain sshkey_type_plain - #endif - diff -up openssh-7.6p1/mac.c.audit openssh-7.6p1/mac.c --- openssh-7.6p1/mac.c.audit 2017-10-02 21:34:26.000000000 +0200 +++ openssh-7.6p1/mac.c 2017-10-04 17:18:32.836505059 +0200 @@ -1102,7 +1083,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #include "ssherr.h" @@ -117,6 +118,8 @@ extern Buffer auth_debug; - extern Buffer loginmsg; + extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ +extern void destroy_sensitive_data(int); @@ -1112,13 +1093,13 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c @@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe #ifdef SSH_AUDIT_EVENTS - int mm_answer_audit_event(int, Buffer *); - int mm_answer_audit_command(int, Buffer *); -+int mm_answer_audit_end_command(int, Buffer *); -+int mm_answer_audit_unsupported_body(int, Buffer *); -+int mm_answer_audit_kex_body(int, Buffer *); -+int mm_answer_audit_session_key_free_body(int, Buffer *); -+int mm_answer_audit_server_key_free(int, Buffer *); + int mm_answer_audit_event(int, struct sshbuf *); + int mm_answer_audit_command(int, struct sshbuf *); ++int mm_answer_audit_end_command(int, struct sshbuf *); ++int mm_answer_audit_unsupported_body(int, struct sshbuf *); ++int mm_answer_audit_kex_body(int, struct sshbuf *); ++int mm_answer_audit_session_key_free_body(int, struct sshbuf *); ++int mm_answer_audit_server_key_free(int, struct sshbuf *); #endif static int monitor_read_log(struct monitor *); @@ -1145,16 +1126,18 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -1396,7 +1413,9 @@ mm_answer_keyverify(int sock, struct ssh +@@ -1396,8 +1413,10 @@ mm_answer_keyverify(int sock, struct ssh char *sigalg; size_t signaturelen, datalen, bloblen; int r, ret, valid_data = 0, encoded_ret; + int type = 0; -+ type = buffer_get_int(m); - if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || +- if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || ++ if ((r = sshbuf_get_u32(m, &type)) != 0 || ++ (r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string(m, &data, &datalen)) != 0 || + (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) @@ -1405,6 +1424,8 @@ mm_answer_keyverify(int sock, struct ssh if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) @@ -1213,14 +1196,15 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1630,11 +1662,45 @@ mm_answer_audit_command(int socket, Buff +@@ -1630,12 +1662,47 @@ mm_answer_audit_command(int socket, Buff { - u_int len; char *cmd; + int r; + Session *s; debug3("%s entering", __func__); - cmd = buffer_get_string(m, &len); + if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + /* sanity check command, if so how? */ - audit_run_command(cmd); @@ -1232,8 +1216,8 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + s->command_handle = audit_run_command(cmd); +#endif + -+ buffer_clear(m); -+ buffer_put_int(m, s->self); ++ sshbuf_reset(m); ++ sshbuf_put_u32(m, s->self); + + mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m); + @@ -1241,16 +1225,17 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +} + +int -+mm_answer_audit_end_command(int socket, Buffer *m) ++mm_answer_audit_end_command(int socket, struct sshbuf *m) +{ -+ int handle; -+ u_int len; -+ char *cmd; ++ int handle, r; ++ size_t len; ++ u_char *cmd = NULL; + Session *s; + + debug3("%s entering", __func__); -+ handle = buffer_get_int(m); -+ cmd = buffer_get_string(m, &len); ++ if ((r = sshbuf_get_u32(m, &handle)) != 0 || ++ (r = sshbuf_get_string(m, &cmd, &len)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + s = session_by_id(handle); + if (s == NULL || s->ttyfd != -1 || s->command == NULL || @@ -1264,7 +1249,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c void mm_get_keystate(struct monitor *pmonitor) { -+ Buffer m; ++ struct sshbuf *m; debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) @@ -1274,11 +1259,11 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c debug3("%s: GOT new keys", __func__); + +#ifdef SSH_AUDIT_EVENTS -+ buffer_init(&m); ++ m = sshbuf_new(); + mm_request_receive_expect(pmonitor->m_sendfd, -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); -+ buffer_free(&m); ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); ++ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, m); ++ sshbuf_free(m); +#endif + + /* Drain any buffered messages from the child */ @@ -1288,41 +1273,47 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c } -@@ -1976,3 +2056,86 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -1976,3 +2056,102 @@ mm_answer_gss_updatecreds(int socket, Bu #endif /* GSSAPI */ +#ifdef SSH_AUDIT_EVENTS +int -+mm_answer_audit_unsupported_body(int sock, Buffer *m) ++mm_answer_audit_unsupported_body(int sock, struct sshbuf *m) +{ -+ int what; ++ int what, r; + -+ what = buffer_get_int(m); ++ if ((r = sshbuf_get_u32(m, &what)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + audit_unsupported_body(what); + -+ buffer_clear(m); ++ sshbuf_reset(m); + + mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m); + return 0; +} + +int -+mm_answer_audit_kex_body(int sock, Buffer *m) ++mm_answer_audit_kex_body(int sock, struct sshbuf *m) +{ -+ int ctos, len; ++ int ctos, r; + char *cipher, *mac, *compress, *pfs; ++ u_int64_t tmp; + pid_t pid; + uid_t uid; + -+ ctos = buffer_get_int(m); -+ cipher = buffer_get_string(m, &len); -+ mac = buffer_get_string(m, &len); -+ compress = buffer_get_string(m, &len); -+ pfs = buffer_get_string(m, &len); -+ pid = buffer_get_int64(m); -+ uid = buffer_get_int64(m); ++ if ((r = sshbuf_get_u32(m, &ctos)) != 0 || ++ (r = sshbuf_get_cstring(m, &cipher, NULL)) != 0 || ++ (r = sshbuf_get_cstring(m, &mac, NULL)) != 0 || ++ (r = sshbuf_get_cstring(m, &compress, NULL)) != 0 || ++ (r = sshbuf_get_cstring(m, &pfs, NULL)) != 0 || ++ (r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ pid = (pid_t) tmp; ++ if ((r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ uid = (pid_t) tmp; + + audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); + @@ -1330,47 +1321,57 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + free(mac); + free(compress); + free(pfs); -+ buffer_clear(m); ++ sshbuf_reset(m); + + mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); + return 0; +} + +int -+mm_answer_audit_session_key_free_body(int sock, Buffer *m) ++mm_answer_audit_session_key_free_body(int sock, struct sshbuf *m) +{ -+ int ctos; ++ int ctos, r; ++ u_int64_t tmp; + pid_t pid; + uid_t uid; + -+ ctos = buffer_get_int(m); -+ pid = buffer_get_int64(m); -+ uid = buffer_get_int64(m); ++ if ((r = sshbuf_get_u32(m, &ctos)) != 0 || ++ (r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ pid = (pid_t) tmp; ++ if ((r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ uid = (uid_t) tmp; + + audit_session_key_free_body(ctos, pid, uid); + -+ buffer_clear(m); ++ sshbuf_reset(m); + + mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); + return 0; +} + +int -+mm_answer_audit_server_key_free(int sock, Buffer *m) ++mm_answer_audit_server_key_free(int sock, struct sshbuf *m) +{ -+ int len; ++ size_t len, r; + char *fp; ++ u_int64_t tmp; + pid_t pid; + uid_t uid; + -+ fp = buffer_get_string(m, &len); -+ pid = buffer_get_int64(m); -+ uid = buffer_get_int64(m); ++ if ((r = sshbuf_get_cstring(m, &fp, &len)) != 0 || ++ (r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ pid = (pid_t) tmp; ++ if ((r = sshbuf_get_u64(m, &tmp)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ uid = (uid_t) tmp; + + audit_destroy_sensitive_data(fp, pid, uid); + + free(fp); -+ buffer_clear(m); ++ sshbuf_reset(m); + + return 0; +} @@ -1404,15 +1405,17 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +mm_sshkey_verify(enum mm_keytype type, const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t datalen, const char *sigalg, u_int compat) { - Buffer m; -@@ -478,6 +478,7 @@ mm_sshkey_verify(const struct sshkey *ke - return (0); + struct sshbuf *m; +@@ -478,7 +478,8 @@ mm_sshkey_verify(const struct sshkey *ke - buffer_init(&m); -+ buffer_put_int(&m, type); - buffer_put_string(&m, blob, len); - buffer_put_string(&m, sig, siglen); - buffer_put_string(&m, data, datalen); + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); +- if ((r = sshkey_puts(key, m)) != 0 || ++ if ((r = sshbuf_put_u32(m, type)) != 0 || ++ (r = sshkey_puts(key, m)) != 0 || + (r = sshbuf_put_string(m, sig, siglen)) != 0 || + (r = sshbuf_put_string(m, data, datalen)) != 0 || + (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) @@ -497,6 +498,20 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } @@ -1434,27 +1437,29 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c void mm_send_keystate(struct monitor *monitor) { -@@ -874,10 +889,11 @@ mm_audit_event(ssh_audit_event_t event) - buffer_free(&m); +@@ -874,11 +889,12 @@ mm_audit_event(ssh_audit_event_t event) + sshbuf_free(m); } -void +int mm_audit_run_command(const char *command) { - Buffer m; + struct sshbuf *m; + int r; + int handle; debug3("%s entering command %s", __func__, command); -@@ -885,6 +901,26 @@ mm_audit_run_command(const char *command - buffer_put_cstring(&m, command); +@@ -885,6 +901,30 @@ mm_audit_run_command(const char *command + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); + -+ handle = buffer_get_int(&m); -+ buffer_free(&m); ++ if ((r = sshbuf_get_u32(m, &handle)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ sshbuf_free(m); + + return (handle); +} @@ -1462,87 +1467,103 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +void +mm_audit_end_command(int handle, const char *command) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + + debug3("%s entering command %s", __func__, command); + -+ buffer_init(&m); -+ buffer_put_int(&m, handle); -+ buffer_put_cstring(&m, command); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, handle)) != 0 || ++ (r = sshbuf_put_cstring(m, command)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m); - buffer_free(&m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, m); + sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1020,3 +1056,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc - +@@ -1020,3 +1056,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc + return (ok); + } #endif /* GSSAPI */ - +#ifdef SSH_AUDIT_EVENTS +void +mm_audit_unsupported_body(int what) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + -+ buffer_init(&m); -+ buffer_put_int(&m, what); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, what)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED, -+ &m); ++ m); + -+ buffer_free(&m); ++ sshbuf_free(m); +} + +void +mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, + uid_t uid) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + -+ buffer_init(&m); -+ buffer_put_int(&m, ctos); -+ buffer_put_cstring(&m, cipher); -+ buffer_put_cstring(&m, (mac ? mac : "")); -+ buffer_put_cstring(&m, compress); -+ buffer_put_cstring(&m, fps); -+ buffer_put_int64(&m, pid); -+ buffer_put_int64(&m, uid); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, ctos)) != 0 || ++ (r = sshbuf_put_cstring(m, cipher)) != 0 || ++ (r = sshbuf_put_cstring(m, (mac ? mac : ""))) != 0 || ++ (r = sshbuf_put_cstring(m, compress)) != 0 || ++ (r = sshbuf_put_cstring(m, fps)) != 0 || ++ (r = sshbuf_put_u64(m, pid)) != 0 || ++ (r = sshbuf_put_u64(m, uid)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX, -+ &m); ++ m); + -+ buffer_free(&m); ++ sshbuf_free(m); +} + +void +mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + -+ buffer_init(&m); -+ buffer_put_int(&m, ctos); -+ buffer_put_int64(&m, pid); -+ buffer_put_int64(&m, uid); -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, ctos)) != 0 || ++ (r = sshbuf_put_u64(m, pid)) != 0 || ++ (r = sshbuf_put_u64(m, uid)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, -+ &m); -+ buffer_free(&m); ++ m); ++ sshbuf_free(m); +} + +void +mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + -+ buffer_init(&m); -+ buffer_put_cstring(&m, fp); -+ buffer_put_int64(&m, pid); -+ buffer_put_int64(&m, uid); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_cstring(m, fp)) != 0 || ++ (r = sshbuf_put_u64(m, pid)) != 0 || ++ (r = sshbuf_put_u64(m, uid)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); -+ buffer_free(&m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); ++ sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ diff -up openssh-7.6p1/monitor_wrap.h.audit openssh-7.6p1/monitor_wrap.h @@ -1577,7 +1598,7 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c --- openssh-7.6p1/packet.c.audit 2017-10-04 17:18:32.672504220 +0200 +++ openssh-7.6p1/packet.c 2017-10-04 17:25:48.141741390 +0200 @@ -67,6 +67,7 @@ - #include "key.h" /* typedefs XXX */ + #include #include "xmalloc.h" +#include "audit.h" @@ -1642,9 +1663,9 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c + close(state->connection_in); + close(state->connection_out); + } + free(ssh->local_ipaddr); + ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); - ssh->remote_ipaddr = NULL; - free(ssh->state); @@ -854,6 +863,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod (unsigned long long)state->p_read.blocks, (unsigned long long)state->p_send.bytes, @@ -1685,16 +1706,16 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c + cipher_free(state->receive_context); + cipher_free(state->send_context); + -+ buffer_free(state->input); ++ sshbuf_free(state->input); + state->input = NULL; -+ buffer_free(state->output); ++ sshbuf_free(state->output); + state->output = NULL; -+ buffer_free(state->outgoing_packet); ++ sshbuf_free(state->outgoing_packet); + state->outgoing_packet = NULL; -+ buffer_free(state->incoming_packet); ++ sshbuf_free(state->incoming_packet); + state->incoming_packet = NULL; -+ if( state->compression_buffer ) { -+ buffer_free(state->compression_buffer); ++ if (state->compression_buffer) { ++ sshbuf_free(state->compression_buffer); + state->compression_buffer = NULL; + } + newkeys_destroy_and_free(state->newkeys[MODE_IN]); @@ -1744,7 +1765,7 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c extern int startup_pipe; -extern void destroy_sensitive_data(void); +extern void destroy_sensitive_data(int); - extern Buffer loginmsg; + extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; char *tun_fwd_ifnames; /* serverloop.c */ @@ -605,6 +605,14 @@ do_exec_pty(struct ssh *ssh, Session *s, @@ -1984,11 +2005,11 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c if (sensitive_data.host_keys[i]) { + char *fp; + -+ if (key_is_private(sensitive_data.host_keys[i])) ++ if (sshkey_is_private(sensitive_data.host_keys[i])) + fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; - key_free(sensitive_data.host_keys[i]); + sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = NULL; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS @@ -2005,13 +2026,13 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c - if (sensitive_data.host_certificates[i]) { + if (sensitive_data.host_certificates + && sensitive_data.host_certificates[i]) { - key_free(sensitive_data.host_certificates[i]); + sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -499,12 +536,30 @@ demote_sensitive_data(void) - { +@@ -499,16 +536,34 @@ demote_sensitive_data(void) struct sshkey *tmp; u_int i; + int r; +#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; @@ -2023,12 +2044,16 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c if (sensitive_data.host_keys[i]) { + char *fp; + -+ if (key_is_private(sensitive_data.host_keys[i])) ++ if (sshkey_is_private(sensitive_data.host_keys[i])) + fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; - tmp = key_demote(sensitive_data.host_keys[i]); - key_free(sensitive_data.host_keys[i]); + if ((r = sshkey_demote(sensitive_data.host_keys[i], + &tmp)) != 0) + fatal("could not demote host %s key: %s", + sshkey_type(sensitive_data.host_keys[i]), + ssh_err(r)); + sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch index b7fd2cf..2e73d45 100644 --- a/openssh-7.6p1-pkcs11-ecdsa.patch +++ b/openssh-7.6p1-pkcs11-ecdsa.patch @@ -29,7 +29,7 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 { static RSA_METHOD helper_rsa; -@@ -152,6 +160,81 @@ wrap_key(RSA *rsa) +@@ -152,6 +160,88 @@ wrap_key(RSA *rsa) return (0); } @@ -38,30 +38,35 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 +pkcs11_ecdsa_private_sign(const unsigned char *from, int flen, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa) +{ -+ Key key; ++ struct sshkey *key = NULL; + u_char *blob, *signature = NULL; -+ u_int blen, slen = 0; -+ Buffer msg; ++ size_t blen, slen = 0; ++ struct sshbuf *msg = NULL; + ECDSA_SIG *ret = NULL; + BIGNUM *r = NULL, *s = NULL; ++ int rv; + -+ key.type = KEY_ECDSA; -+ key.ecdsa = ecdsa; -+ key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); -+ if (key_to_blob(&key, &blob, &blen) == 0) -+ return NULL; -+ buffer_init(&msg); -+ buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); -+ buffer_put_string(&msg, blob, blen); -+ buffer_put_string(&msg, from, flen); -+ buffer_put_int(&msg, 0); ++ if ((key = sshkey_new(KEY_ECDSA)) == NULL) ++ fatal("%s: sshkey_new failed", __func__); ++ key->ecdsa = ecdsa; ++ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); ++ if (sshkey_to_blob(key, &blob, &blen) == 0) ++ goto out; ++ if ((msg = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((rv = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || ++ (rv = sshbuf_put_string(msg, blob, blen)) != 0 || ++ (rv = sshbuf_put_string(msg, from, flen)) != 0 || ++ (rv = sshbuf_put_u32(msg, 0)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(rv)); + free(blob); -+ send_msg(&msg); -+ buffer_clear(&msg); ++ send_msg(msg); ++ sshbuf_reset(msg); + -+ if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { -+ signature = buffer_get_string(&msg, &slen); -+ if (slen <= (u_int)ECDSA_size(ecdsa)) { ++ if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) { ++ if ((rv = sshbuf_get_string(msg, &signature, &slen)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(rv)); ++ if (slen <= (size_t)ECDSA_size(ecdsa)) { + int nlen = slen / 2; + ret = ECDSA_SIG_new(); + r = BN_new(); @@ -72,7 +77,9 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 + } + free(signature); + } -+ buffer_free(&msg); ++out: ++ sshkey_free(key); ++ sshbuf_free(msg); + return (ret); +} + @@ -112,9 +119,9 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 pkcs11_start_helper(void) { @@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi - blob = buffer_get_string(&msg, &blen); - free(buffer_get_string(&msg, NULL)); - k = key_from_blob(blob, blen); + __func__, ssh_err(r)); + if ((r = sshkey_from_blob(blob, blen, &k)) != 0) + fatal("%s: bad key: %s", __func__, ssh_err(r)); - wrap_key(k->rsa); + if(k->type == KEY_RSA) { + wrap_rsa_key(k->rsa); diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch index 79c6a00..6fd463e 100644 --- a/openssh-7.6p1-pkcs11-uri.patch +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -17,18 +17,18 @@ index ac959c1f..f8ed1781 100644 rm -f regress/unittests/utf8/test_utf8$(EXEEXT) + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - (cd openbsd-compat && $(MAKE) clean) + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) clean) @@ -276,6 +278,8 @@ distclean: regressclean rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/unittests/misc/kexfuzz - (cd openbsd-compat && $(MAKE) distclean) - if test -d pkg ; then \ + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz + (cd openbsd-compat && $(MAKE) distclean) @@ -437,6 +441,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/kex $(MKDIR_P) `pwd`/regress/unittests/match @@ -72,8 +72,8 @@ index ac959c1f..f8ed1781 100644 regress/netcat$(EXEEXT) \ + regress/soft-pkcs11.so \ regress/check-perm$(EXEEXT) \ + regress/mkdtemp$(EXEEXT) \ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ - regress/unittests/sshkey/test_sshkey$(EXEEXT) \ @@ -575,6 +596,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ @@ -81,7 +81,7 @@ index ac959c1f..f8ed1781 100644 + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ regress/misc/kexfuzz/kexfuzz$(EXEEXT) - REGRESSTMP = "$(PWD)/regress" + tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) diff --git a/authfd.c b/authfd.c index 1eff7ba9..35153f47 100644 --- a/authfd.c @@ -2717,7 +2717,7 @@ new file mode 100644 index 00000000..e83aca54 --- /dev/null +++ b/regress/unittests/pkcs11/tests.c -@@ -0,0 +1,329 @@ +@@ -0,0 +1,330 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -2743,6 +2743,7 @@ index 00000000..e83aca54 + +#include "../test_helper/test_helper.h" + ++#include "sshbuf.h" +#include "ssh-pkcs11-uri.h" + +#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL) @@ -3288,12 +3289,12 @@ index a023f5f4..882e8381 100644 key.type = KEY_RSA; key.rsa = rsa; + key.ecdsa_nid = 0; - if (key_to_blob(&key, &blob, &blen) == 0) + if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { + error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); return -1; - buffer_init(&msg); @@ -195,6 +196,8 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) - u_int blen; - Buffer msg; + u_int nkeys, i; + struct sshbuf *msg; + debug("%s: called, name = %s", __func__, name); + @@ -3301,19 +3302,19 @@ index a023f5f4..882e8381 100644 return (-1); @@ -208,6 +211,7 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) - if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) { - nkeys = buffer_get_int(&msg); - *keysp = xcalloc(nkeys, sizeof(Key *)); -+ debug("%s: nkeys = %d", __func__, nkeys); + if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); ++ debug("%s: nkeys = %u", __func__, nkeys); for (i = 0; i < nkeys; i++) { - blob = buffer_get_string(&msg, &blen); - free(buffer_get_string(&msg, NULL)); + /* XXX clean up properly instead of fatal() */ + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c new file mode 100644 index 00000000..da15c164 --- /dev/null +++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,400 @@ +@@ -0,0 +1,395 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3340,6 +3341,7 @@ index 00000000..da15c164 +#include + +#include "sshkey.h" ++#include "sshbuf.h" +#include "log.h" + +#define CRYPTOKI_COMPAT @@ -3467,7 +3469,7 @@ index 00000000..da15c164 + struct sshbuf *value) +{ + char *new_part; -+ size_t size; ++ size_t size = 0; + + if (value == NULL) + return NULL; @@ -3480,7 +3482,7 @@ index 00000000..da15c164 + sshbuf_free(value); + free(part); + -+ if (size < 0) ++ if (size <= 0) + return NULL; + return new_part; +} @@ -3488,7 +3490,7 @@ index 00000000..da15c164 +char * +pkcs11_uri_get(struct pkcs11_uri *uri) +{ -+ size_t size = -1; ++ size_t size = 0; + char *p = NULL, *path = NULL, *query = NULL; + + /* compose a percent-encoded ID */ @@ -3547,7 +3549,7 @@ index 00000000..da15c164 +err: + free(query); + free(path); -+ if (size < 0) ++ if (size <= 0) + return NULL; + return p; +} @@ -3617,11 +3619,6 @@ index 00000000..da15c164 + if (tok == NULL) + break; + opcode = parse_token(tok); -+ if (opcode == pBadOption) { -+ free(p); -+ verbose("Unknown key in PKCS#11 URI: %s", tok); -+ return -1; -+ } + + char *arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ + switch (opcode) { @@ -3676,7 +3673,6 @@ index 00000000..da15c164 + /* Unrecognized attribute in the URI path SHOULD be error */ + verbose("%s: Unknown part of path in PKCS#11 URI: %s", + __func__, tok); -+ rv = -1; + } + } + @@ -4624,7 +4620,7 @@ index d3619fe2..180eb2e0 100644 + break; + } +#endif - p = tilde_expand_filename(optarg, original_real_uid); + p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) < 0) fprintf(stderr, "Warning: Identity file %s " @@ -1999,6 +2007,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) @@ -4656,7 +4652,7 @@ index d3619fe2..180eb2e0 100644 + (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { + for (i = 0; i < nkeys; i++) { + if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ key_free(keys[i]); ++ sshkey_free(keys[i]); + continue; + } + identity_keys[*n_ids] = keys[i]; @@ -4674,9 +4670,9 @@ index d3619fe2..180eb2e0 100644 static void load_public_identity_files(struct passwd *pw) @@ -2011,10 +2058,6 @@ load_public_identity_files(struct passwd *pw) - struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; -#ifdef ENABLE_PKCS11 - struct sshkey **keys; - int nkeys; @@ -4684,8 +4680,8 @@ index d3619fe2..180eb2e0 100644 n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2023,35 +2066,48 @@ load_public_identity_files(struct passwd *pw) - memset(certificates, 0, sizeof(certificates)); +@@ -2023,32 +2066,46 @@ load_public_identity_files(struct passwd *pw) + sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 - if (options.pkcs11_provider != NULL && @@ -4695,7 +4691,7 @@ index d3619fe2..180eb2e0 100644 - &keys)) > 0) { - for (i = 0; i < nkeys; i++) { - if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- key_free(keys[i]); +- sshkey_free(keys[i]); - continue; - } - identity_keys[n_ids] = keys[i]; @@ -4725,8 +4721,6 @@ index d3619fe2..180eb2e0 100644 + pkcs11_uri_cleanup(uri); } #endif /* ENABLE_PKCS11 */ - if ((pw = getpwuid(original_real_uid)) == NULL) - fatal("load_public_identity_files: getpwuid failed"); for (i = 0; i < options.num_identity_files; i++) { + char *name = options.identity_files[i]; if (n_ids >= SSH_MAX_IDENTITY_FILES || @@ -4736,8 +4730,7 @@ index d3619fe2..180eb2e0 100644 options.identity_files[i] = NULL; continue; } -- cp = tilde_expand_filename(options.identity_files[i], -- original_real_uid); +- cp = tilde_expand_filename(options.identity_files[i], getuid()); +#ifdef ENABLE_PKCS11 + if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && + strncmp(name, PKCS11_URI_SCHEME, @@ -4748,7 +4741,7 @@ index d3619fe2..180eb2e0 100644 + continue; + } +#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, original_real_uid); ++ cp = tilde_expand_filename(name, getuid()); filename = percent_expand(cp, "d", pw->pw_dir, "u", pw->pw_name, "l", thishost, "h", host, "r", options.user, (char *)NULL); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 49c9178..084c903 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -294,7 +294,7 @@ diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o - $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -308,9 +308,9 @@ diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in - $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o -- $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o +- $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -383,29 +383,32 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c --- openssh-7.7p1/readconf.c.fips 2018-08-08 10:08:40.769719527 +0200 +++ openssh-7.7p1/readconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -2081,12 +2081,17 @@ fill_default_options(Options * options) - } - if (options->update_hostkeys == -1) - options->update_hostkeys = 0; -- if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || -- kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || -- kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || -- kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT -+ : KEX_CLIENT_ENCRYPT), &options->ciphers) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC -+ : KEX_CLIENT_MAC), &options->macs) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS -+ : KEX_CLIENT_KEX), &options->kex_algorithms) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), - &options->hostbased_key_types) != 0 || -- kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), - &options->pubkey_key_types) != 0) - fatal("%s: kex_assemble_names failed", __func__); - +@@ -2081,17 +2081,18 @@ fill_default_options(Options * options) + all_mac = mac_alg_list(','); + all_kex = kex_alg_list(','); + all_key = sshkey_alg_list(0, 0, 1, ','); +-#define ASSEMBLE(what, defaults, all) \ ++#define ASSEMBLE(what, defaults, fips_defaults, all) \ + do { \ + if ((r = kex_assemble_names(&options->what, \ +- defaults, all)) != 0) \ ++ (FIPS_mode() ? fips_defaults : defaults), \ ++ all)) != 0) \ + fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ + } while (0) +- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); +- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); +- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); +- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); +- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); ++ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); ++ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); ++ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); ++ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); ++ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + #undef ASSEMBLE + free(all_cipher); + free(all_mac); diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-seccomp-filter.c --- openssh-7.7p1/sandbox-seccomp-filter.c.fips 2018-08-08 10:08:40.794719737 +0200 +++ openssh-7.7p1/sandbox-seccomp-filter.c 2018-08-08 10:08:40.824719990 +0200 @@ -422,33 +425,33 @@ diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-secco diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c --- openssh-7.7p1/servconf.c.fips 2018-08-08 10:08:40.778719603 +0200 +++ openssh-7.7p1/servconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -196,14 +196,20 @@ option_clear_or_none(const char *o) - static void - assemble_algorithms(ServerOptions *o) - { -- if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || -- kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || -- kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || -- kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT -+ : KEX_SERVER_ENCRYPT), &o->ciphers) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC -+ : KEX_SERVER_MAC), &o->macs) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS -+ : KEX_SERVER_KEX), &o->kex_algorithms) != 0 || -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), - &o->hostkeyalgorithms) != 0 || -- kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), - &o->hostbased_key_types) != 0 || -- kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) -+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), &o->pubkey_key_types) != 0) - fatal("kex_assemble_names failed"); - } - +@@ -196,17 +196,18 @@ option_clear_or_none(const char *o) + all_mac = mac_alg_list(','); + all_kex = kex_alg_list(','); + all_key = sshkey_alg_list(0, 0, 1, ','); +-#define ASSEMBLE(what, defaults, all) \ ++#define ASSEMBLE(what, defaults, fips_defaults, all) \ + do { \ +- if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ ++ if ((r = kex_assemble_names(&o->what, (FIPS_mode() \ ++ ? fips_defaults : defaults), all)) != 0) \ + fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ + } while (0) +- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); +- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); +- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); +- ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); +- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); +- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); ++ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); ++ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); ++ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); ++ ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); ++ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); ++ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + #undef ASSEMBLE + free(all_cipher); + free(all_mac); diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c --- openssh-7.7p1/ssh.c.fips 2018-08-08 10:08:40.811719881 +0200 +++ openssh-7.7p1/ssh.c 2018-08-08 10:08:40.825719999 +0200 @@ -560,14 +563,14 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c } #endif @@ -322,14 +330,16 @@ ssh_kex2(char *host, struct sockaddr *ho - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; if (options.hostkeyalgorithms != NULL) { -- if (kex_assemble_names(KEX_DEFAULT_PK_ALG, -+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG -+ : KEX_DEFAULT_PK_ALG), - &options.hostkeyalgorithms) != 0) + all_key = sshkey_alg_list(0, 0, 1, ','); + if (kex_assemble_names(&options.hostkeyalgorithms, +- KEX_DEFAULT_PK_ALG, all_key) != 0) ++ (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), ++ all_key) != 0) fatal("%s: kex_assemble_namelist", __func__); + free(all_key); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(options.hostkeyalgorithms); } else { diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index dc38d65..99a4411 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -148,7 +148,7 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config + #PrintLastLog yes #TCPKeepAlive yes - #UseLogin no + #PermitUserEnvironment no @@ -106,6 +126,12 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none diff --git a/openssh-7.7p1-tun-devices.patch b/openssh-7.7p1-tun-devices.patch deleted file mode 100644 index efd82c3..0000000 --- a/openssh-7.7p1-tun-devices.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 4f60e4f66b5880c9f50ef758e8b7f7a9ae786d21 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Fri, 13 Apr 2018 13:13:33 +1000 -Subject: [PATCH 1/5] Revert $REGRESSTMP changes. - -Revert 3fd2d229 and subsequent changes as they turned out to be a -portability hassle. ---- - Makefile.in | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/Makefile.in b/Makefile.in -index 04e1c8e53..dd942ee7b 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -577,8 +577,6 @@ regress-binaries: regress/modpipe$(EXEEXT) \ - regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - regress/misc/kexfuzz/kexfuzz$(EXEEXT) - --REGRESSTMP = "$(PWD)/regress" -- - tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) - BUILDDIR=`pwd`; \ - TEST_SSH_SCP="$${BUILDDIR}/scp"; \ -@@ -602,7 +600,7 @@ tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) - .OBJDIR="$${BUILDDIR}/regress" \ - .CURDIR="`pwd`" \ - BUILDDIR="$${BUILDDIR}" \ -- OBJ="$(REGRESSTMP)" \ -+ OBJ="$${BUILDDIR}/regress/" \ - PATH="$${BUILDDIR}:$${PATH}" \ - TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ - TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ - -From b81b2d120e9c8a83489e241620843687758925ad Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Fri, 13 Apr 2018 13:38:06 +1000 -Subject: [PATCH 2/5] Fix tunnel forwarding broken in 7.7p1 - -bz2855, ok dtucker@ ---- - openbsd-compat/port-net.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/openbsd-compat/port-net.c b/openbsd-compat/port-net.c -index 7050629c3..bb535626f 100644 ---- a/openbsd-compat/port-net.c -+++ b/openbsd-compat/port-net.c -@@ -185,7 +185,7 @@ sys_tun_open(int tun, int mode, char **ifname) - else - debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); - -- if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) -+ if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) - goto failed; - - return (fd); -@@ -272,7 +272,7 @@ sys_tun_open(int tun, int mode, char **ifname) - goto failed; - } - -- if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) -+ if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) - goto failed; - - close(sock); - -From 341727df910e12e26ef161508ed76d91c40a61eb Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 9 Apr 2018 23:54:49 +0000 -Subject: [PATCH 3/5] upstream: don't kill ssh-agent's listening socket - entriely if we - -fail to accept a connection; bz#2837, patch from Lukas Kuster - -OpenBSD-Commit-ID: 52413f5069179bebf30d38f524afe1a2133c738f ---- - ssh-agent.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/ssh-agent.c b/ssh-agent.c -index 2a4578b03..68de56ce6 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh-agent.c,v 1.228 2018/02/23 15:58:37 markus Exp $ */ -+/* $OpenBSD: ssh-agent.c,v 1.229 2018/04/09 23:54:49 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -909,9 +909,8 @@ after_poll(struct pollfd *pfd, size_t npfd) - /* Process events */ - switch (sockets[socknum].type) { - case AUTH_SOCKET: -- if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && -- handle_socket_read(socknum) != 0) -- close_socket(&sockets[socknum]); -+ if ((pfd[i].revents & (POLLIN|POLLERR)) != 0) -+ handle_socket_read(socknum); - break; - case AUTH_CONNECTION: - if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && - -From 3402cc607049ac900f6d8574bc2ce657a8cdf4fe Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Fri, 13 Apr 2018 13:43:55 +1000 -Subject: [PATCH 4/5] Using "==" in shell tests is not portable. - -Patch from rsbecker at nexbridge.com. ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 663062bef..2e84d90b7 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1398,7 +1398,7 @@ AC_RUN_IFELSE( - ) - AC_MSG_RESULT([$func_calloc_0_nonnull]) - --if test "x$func_calloc_0_nonnull" == "xyes"; then -+if test "x$func_calloc_0_nonnull" = "xyes"; then - AC_DEFINE(HAVE_CALLOC, 1, [calloc(0, x) returns non-null]) - else - AC_DEFINE(HAVE_CALLOC, 0, [calloc(0, x) returns NULL]) - -From 85fe48fd49f2e81fa30902841b362cfbb7f1933b Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Sat, 14 Apr 2018 21:50:41 +0000 -Subject: [PATCH 5/5] upstream: don't free the %C expansion, it's used later - for - -LocalCommand - -OpenBSD-Commit-ID: 857b5cb37b2d856bfdfce61289a415257a487fb1 ---- - ssh.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/ssh.c b/ssh.c -index d3619fe29..9c011dd7e 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -1323,7 +1323,6 @@ main(int ac, char **av) - (char *)NULL); - free(cp); - } -- free(conn_hash_hex); - - if (config_test) { - dump_client_config(&options, host); diff --git a/openssh-7.2p2-UsePAM-UseLogin-warning.patch b/openssh-7.8p1-UsePAM-warning.patch similarity index 97% rename from openssh-7.2p2-UsePAM-UseLogin-warning.patch rename to openssh-7.8p1-UsePAM-warning.patch index b3038ea..da39361 100644 --- a/openssh-7.2p2-UsePAM-UseLogin-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -3,7 +3,7 @@ diff --git a/sshd.c b/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, NULL); + cfg, NULL); + /* 'UsePAM no' is not supported in Fedora */ + if (! options.use_pam) diff --git a/openssh-7.7p1-gsissh.patch b/openssh-7.8p1-gsissh.patch similarity index 83% rename from openssh-7.7p1-gsissh.patch rename to openssh-7.8p1-gsissh.patch index 2a02b2d..7e0d6dc 100644 --- a/openssh-7.7p1-gsissh.patch +++ b/openssh-7.8p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c ---- openssh-7.7p1.orig/auth2.c 2018-07-05 14:58:40.604584490 +0200 -+++ openssh-7.7p1/auth2.c 2018-07-05 13:40:25.453373817 +0200 -@@ -230,7 +230,27 @@ +diff -Nur openssh-7.8p1.orig/auth2.c openssh-7.8p1/auth2.c +--- openssh-7.8p1.orig/auth2.c 2018-10-24 14:09:16.619775688 +0200 ++++ openssh-7.8p1/auth2.c 2018-10-24 14:09:54.219377927 +0200 +@@ -270,7 +270,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -30,7 +30,7 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -241,11 +261,32 @@ +@@ -281,11 +301,32 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -67,7 +67,7 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c authctxt->valid = 1; debug2("%s: setting up authctxt for %s", __func__, user); -@@ -253,6 +294,9 @@ +@@ -293,6 +334,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -77,7 +77,7 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); -@@ -261,6 +305,7 @@ +@@ -301,6 +345,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -85,7 +85,7 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -275,9 +320,10 @@ +@@ -315,9 +360,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -99,10 +99,10 @@ diff -Nur openssh-7.7p1.orig/auth2.c openssh-7.7p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c ---- openssh-7.7p1.orig/auth2-gss.c 2018-07-05 14:58:40.604584490 +0200 -+++ openssh-7.7p1/auth2-gss.c 2018-07-05 13:40:25.453373817 +0200 -@@ -49,6 +49,7 @@ +diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c +--- openssh-7.8p1.orig/auth2-gss.c 2018-10-24 14:09:16.410777899 +0200 ++++ openssh-7.8p1/auth2-gss.c 2018-10-24 17:39:13.477216029 +0200 +@@ -50,6 +50,7 @@ extern ServerOptions options; @@ -110,27 +110,27 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); 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); -@@ -62,8 +63,8 @@ +@@ -63,8 +64,8 @@ { Authctxt *authctxt = ssh->authctxt; int authenticated = 0; -- Buffer b; +- struct sshbuf *b = NULL; - gss_buffer_desc mic, gssbuf; -+ Buffer b, b2; ++ struct sshbuf *b = NULL, *b2 = NULL; + gss_buffer_desc mic, gssbuf, gssbuf2; u_int len; mic.value = packet_get_string(&len); -@@ -77,13 +78,27 @@ - gssbuf.value = buffer_ptr(&b); - gssbuf.length = buffer_len(&b); +@@ -81,13 +82,27 @@ + gssbuf.value = sshbuf_mutable_ptr(b); + gssbuf.length = sshbuf_len(b); + /* client may have used empty username to determine target + name from GSSAPI context */ -+ ssh_gssapi_buildmic(&b2, "", authctxt->service, "gssapi-keyex"); ++ ssh_gssapi_buildmic(b2, "", authctxt->service, "gssapi-keyex"); + -+ gssbuf2.value = buffer_ptr(&b2); -+ gssbuf2.length = buffer_len(&b2); ++ gssbuf2.value = sshbuf_mutable_ptr(b2); ++ gssbuf2.length = sshbuf_len(b2); + /* gss_kex_context is NULL with privsep, so we can't check it here */ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, @@ -147,41 +147,40 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c + } + } - buffer_free(&b); -+ buffer_free(&b2); + sshbuf_free(b); ++ sshbuf_free(b2); free(mic.value); return (authenticated); -@@ -105,7 +120,10 @@ - u_int len; - u_char *doid = NULL; +@@ -142,7 +157,9 @@ + return (0); + } -- if (!authctxt->valid || authctxt->user == NULL) +- if (!authctxt->valid || authctxt->user == NULL) { + /* authctxt->valid may be 0 if we haven't yet determined + username from gssapi context. */ -+ -+ if (authctxt->user == NULL) ++ if (authctxt->user == NULL) { + debug2("%s: disabled because of invalid user", __func__); + free(doid); return (0); - - mechs = packet_get_int(); -@@ -170,7 +188,7 @@ +@@ -180,7 +197,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; - OM_uint32 maj_status, min_status, flags; + OM_uint32 maj_status, min_status, flags = 0; - u_int len; - - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) -@@ -188,6 +206,7 @@ - free(recv_tok.value); + u_char *p; + size_t len; + int r; +@@ -201,6 +218,7 @@ + free(p); if (GSS_ERROR(maj_status)) { + ssh_gssapi_userauth_error(gssctxt); if (send_tok.length != 0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); - packet_put_string(send_tok.value, send_tok.length); -@@ -253,6 +272,32 @@ + if ((r = sshpkt_start(ssh, + SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || +@@ -275,6 +293,32 @@ return 0; } @@ -214,7 +213,14 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -269,6 +314,8 @@ +@@ -285,12 +329,14 @@ + input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) + { + Authctxt *authctxt = ssh->authctxt; +- int r, authenticated; ++ int r, authenticated = 0; + const char *displayname; + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); @@ -223,42 +229,43 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -276,8 +323,13 @@ - - packet_check_eom(); +@@ -299,8 +345,11 @@ + if ((r = sshpkt_get_end(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw)); + /* user should be set if valid but we double-check here */ + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0 /* !gssapi-keyex */)); -+ } else { -+ authenticated = 0; ++ authctxt->pw, 1 /* gssapi-keyex */)); + } if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -324,9 +376,16 @@ - gssbuf.value = buffer_ptr(&b); - gssbuf.length = buffer_len(&b); +@@ -352,11 +401,17 @@ + fatal("%s: sshbuf_mutable_ptr failed", __func__); + gssbuf.length = sshbuf_len(b); -+ gssapi_set_username(authctxt); -+ - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) +- if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = - PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); +- else ++ gssapi_set_username(authctxt); ++ ++ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw, 0 /* !gssapi-keyex */)); -+ } else { -+ authenticated = 0; + } - else ++ } else { logit("GSSAPI MIC check failed"); ++ } -@@ -348,6 +407,23 @@ + sshbuf_free(b); + if (micuser != authctxt->user) +@@ -376,6 +431,23 @@ return 0; } @@ -282,9 +289,9 @@ diff -Nur openssh-7.7p1.orig/auth2-gss.c openssh-7.7p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c ---- openssh-7.7p1.orig/auth.c 2018-07-05 14:58:40.605584480 +0200 -+++ openssh-7.7p1/auth.c 2018-07-05 13:40:25.453373817 +0200 +diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c +--- openssh-7.8p1.orig/auth.c 2018-10-24 14:09:16.621775667 +0200 ++++ openssh-7.8p1/auth.c 2018-10-24 14:09:54.220377916 +0200 @@ -76,6 +76,9 @@ #include "compat.h" #include "channels.h" @@ -295,7 +302,7 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -340,7 +343,8 @@ +@@ -339,7 +342,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -305,7 +312,7 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -366,6 +370,23 @@ +@@ -365,6 +369,23 @@ if (authenticated == 0 && !authctxt->postponed && !partial) audit_event(audit_classify_auth(method)); #endif @@ -329,7 +336,7 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c } -@@ -576,6 +597,10 @@ +@@ -577,6 +598,10 @@ #endif pw = getpwnam(user); @@ -340,7 +347,7 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -595,7 +620,8 @@ +@@ -596,7 +621,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -350,9 +357,9 @@ diff -Nur openssh-7.7p1.orig/auth.c openssh-7.7p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.7p1.orig/auth.h openssh-7.7p1/auth.h ---- openssh-7.7p1.orig/auth.h 2018-07-05 14:58:40.605584480 +0200 -+++ openssh-7.7p1/auth.h 2018-07-05 13:40:25.454373806 +0200 +diff -Nur openssh-7.8p1.orig/auth.h openssh-7.8p1/auth.h +--- openssh-7.8p1.orig/auth.h 2018-10-24 14:09:16.622775656 +0200 ++++ openssh-7.8p1/auth.h 2018-10-24 14:09:54.220377916 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -362,10 +369,10 @@ diff -Nur openssh-7.7p1.orig/auth.h openssh-7.7p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c ---- openssh-7.7p1.orig/auth-pam.c 2018-07-05 14:58:40.605584480 +0200 -+++ openssh-7.7p1/auth-pam.c 2018-07-05 13:40:25.454373806 +0200 -@@ -288,6 +288,56 @@ +diff -Nur openssh-7.8p1.orig/auth-pam.c openssh-7.8p1/auth-pam.c +--- openssh-7.8p1.orig/auth-pam.c 2018-10-24 14:09:16.677775074 +0200 ++++ openssh-7.8p1/auth-pam.c 2018-10-24 14:09:54.221377906 +0200 +@@ -288,6 +288,55 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -389,7 +396,6 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c +void +sshpam_check_userchanged(void) +{ -+ int sshpam_err; + struct passwd *pw; + const char *user; + @@ -422,34 +428,36 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -319,7 +369,7 @@ +@@ -319,7 +368,7 @@ static void - import_environments(Buffer *b) + import_environments(struct sshbuf *b) { - char *env; + char *env, *user; - u_int i, num_env; - int err; + u_int n, i, num_env; + int r; -@@ -329,6 +379,17 @@ - /* Import variables set by do_pam_account */ - sshpam_account_status = buffer_get_int(b); - sshpam_password_change_required(buffer_get_int(b)); +@@ -335,6 +384,19 @@ + if ((r = sshbuf_get_u32(b, &n)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshpam_password_change_required(n != 0); + if (options.permit_pam_user_change) { -+ user = buffer_get_string(b, NULL); ++ if ((r = sshbuf_get_cstring(b, &user, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug("PAM: user is '%.100s'", + sshpam_authctxt->pw->pw_name); + debug("PAM: got username '%.100s' from thread", user); -+ if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS) ++ if ((sshpam_err = pam_set_item(sshpam_handle, PAM_USER, user)) ++ != PAM_SUCCESS) + fatal("PAM: failed to set PAM_USER: %s", -+ pam_strerror(sshpam_handle, err)); ++ pam_strerror(sshpam_handle, sshpam_err)); + pwfree(sshpam_authctxt->pw); + sshpam_authctxt->pw = pwcopy(sshpam_getpw(user)); + } /* Import environment from subprocess */ - num_env = buffer_get_int(b); -@@ -480,6 +541,13 @@ + if ((r = sshbuf_get_u32(b, &num_env)) != 0) +@@ -507,6 +569,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -463,19 +471,21 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -498,6 +566,11 @@ - /* Export variables set by do_pam_account */ - buffer_put_int(&buffer, sshpam_account_status); - buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); +@@ -527,6 +596,13 @@ + if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || + (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (options.permit_pam_user_change) { + debug("sshpam_thread: user is '%.100s'", + sshpam_authctxt->pw->pw_name); -+ buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name); ++ if ((r = sshbuf_put_cstring(buffer, ++ sshpam_authctxt->pw->pw_name)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + } /* Export any environment strings set in child */ - for(i = 0; environ[i] != NULL; i++) -@@ -973,6 +1046,18 @@ + for (i = 0; environ[i] != NULL; i++) { +@@ -1024,6 +1100,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -494,7 +504,7 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1262,6 +1347,9 @@ +@@ -1314,6 +1402,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -504,9 +514,9 @@ diff -Nur openssh-7.7p1.orig/auth-pam.c openssh-7.7p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.7p1.orig/auth-pam.h openssh-7.7p1/auth-pam.h ---- openssh-7.7p1.orig/auth-pam.h 2018-07-05 14:58:40.605584480 +0200 -+++ openssh-7.7p1/auth-pam.h 2018-07-05 13:40:25.454373806 +0200 +diff -Nur openssh-7.8p1.orig/auth-pam.h openssh-7.8p1/auth-pam.h +--- openssh-7.8p1.orig/auth-pam.h 2018-10-24 14:09:16.320778851 +0200 ++++ openssh-7.8p1/auth-pam.h 2018-10-24 14:09:54.221377906 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -514,9 +524,9 @@ diff -Nur openssh-7.7p1.orig/auth-pam.h openssh-7.7p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.7p1.orig/canohost.c openssh-7.7p1/canohost.c ---- openssh-7.7p1.orig/canohost.c 2018-07-05 14:58:40.606584469 +0200 -+++ openssh-7.7p1/canohost.c 2018-07-05 13:40:25.454373806 +0200 +diff -Nur openssh-7.8p1.orig/canohost.c openssh-7.8p1/canohost.c +--- openssh-7.8p1.orig/canohost.c 2018-08-23 07:41:42.000000000 +0200 ++++ openssh-7.8p1/canohost.c 2018-10-24 14:09:54.221377906 +0200 @@ -17,6 +17,7 @@ #include #include @@ -559,9 +569,9 @@ diff -Nur openssh-7.7p1.orig/canohost.c openssh-7.7p1/canohost.c + } + } +} -diff -Nur openssh-7.7p1.orig/canohost.h openssh-7.7p1/canohost.h ---- openssh-7.7p1.orig/canohost.h 2018-07-05 14:58:40.615584372 +0200 -+++ openssh-7.7p1/canohost.h 2018-07-05 13:40:25.454373806 +0200 +diff -Nur openssh-7.8p1.orig/canohost.h openssh-7.8p1/canohost.h +--- openssh-7.8p1.orig/canohost.h 2018-08-23 07:41:42.000000000 +0200 ++++ openssh-7.8p1/canohost.h 2018-10-24 14:09:54.221377906 +0200 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -569,10 +579,10 @@ diff -Nur openssh-7.7p1.orig/canohost.h openssh-7.7p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac ---- openssh-7.7p1.orig/configure.ac 2018-07-05 14:58:40.616584361 +0200 -+++ openssh-7.7p1/configure.ac 2018-07-05 13:40:25.455373795 +0200 -@@ -4542,6 +4542,14 @@ +diff -Nur openssh-7.8p1.orig/configure.ac openssh-7.8p1/configure.ac +--- openssh-7.8p1.orig/configure.ac 2018-10-24 14:09:16.709774736 +0200 ++++ openssh-7.8p1/configure.ac 2018-10-24 14:09:54.223377885 +0200 +@@ -4504,6 +4504,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -587,7 +597,7 @@ diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4581,6 +4589,50 @@ +@@ -4543,6 +4551,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -638,18 +648,18 @@ diff -Nur openssh-7.7p1.orig/configure.ac openssh-7.7p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c ---- openssh-7.7p1.orig/gss-genr.c 2018-07-05 14:58:40.616584361 +0200 -+++ openssh-7.7p1/gss-genr.c 2018-07-05 13:40:25.456373784 +0200 -@@ -39,6 +39,7 @@ - #include "xmalloc.h" - #include "buffer.h" +diff -Nur openssh-7.8p1.orig/gss-genr.c openssh-7.8p1/gss-genr.c +--- openssh-7.8p1.orig/gss-genr.c 2018-10-24 14:09:16.682775021 +0200 ++++ openssh-7.8p1/gss-genr.c 2018-10-24 14:09:54.223377885 +0200 +@@ -41,6 +41,7 @@ + #include "ssherr.h" + #include "sshbuf.h" #include "log.h" +#include "canohost.h" #include "ssh2.h" #include "cipher.h" - #include "key.h" -@@ -371,9 +372,18 @@ + #include "sshkey.h" +@@ -396,9 +397,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -669,7 +679,7 @@ diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -381,6 +391,7 @@ +@@ -406,6 +416,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -677,10 +687,10 @@ diff -Nur openssh-7.7p1.orig/gss-genr.c openssh-7.7p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c ---- openssh-7.7p1.orig/gss-serv.c 2018-07-05 14:58:40.616584361 +0200 -+++ openssh-7.7p1/gss-serv.c 2018-07-05 15:02:46.526946800 +0200 -@@ -51,10 +51,12 @@ +diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c +--- openssh-7.8p1.orig/gss-serv.c 2018-10-24 14:09:16.511776830 +0200 ++++ openssh-7.8p1/gss-serv.c 2018-10-24 14:09:54.224377874 +0200 +@@ -50,10 +50,12 @@ #include "monitor_wrap.h" extern ServerOptions options; @@ -695,7 +705,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -62,14 +64,26 @@ +@@ -61,14 +63,26 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -722,7 +732,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -230,6 +244,10 @@ +@@ -229,6 +243,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -733,7 +743,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c } return (status); -@@ -249,6 +267,20 @@ +@@ -248,6 +266,20 @@ tok = ename->value; @@ -754,7 +764,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -309,21 +341,24 @@ +@@ -308,21 +340,24 @@ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; if (options.gss_store_rekey && client->used && ctx->client_creds) { @@ -784,7 +794,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c new_name, &equal); if (GSS_ERROR(ctx->major)) { -@@ -338,9 +373,9 @@ +@@ -337,9 +372,9 @@ debug("Marking rekeyed credentials for export"); @@ -796,7 +806,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; -@@ -357,12 +392,17 @@ +@@ -356,12 +391,17 @@ i++; } @@ -816,7 +826,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -379,16 +419,25 @@ +@@ -378,16 +418,25 @@ return (ctx->major); } @@ -843,7 +853,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c return (ctx->major); } -@@ -396,6 +445,7 @@ +@@ -395,6 +444,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -851,7 +861,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -411,6 +461,14 @@ +@@ -410,6 +460,14 @@ gssapi_client.store.data = NULL; } } @@ -866,7 +876,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c } /* As user */ -@@ -418,6 +476,11 @@ +@@ -417,6 +475,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -878,7 +888,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c return (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -443,16 +506,19 @@ +@@ -442,16 +505,19 @@ } /* Privileged */ @@ -902,7 +912,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -463,6 +529,7 @@ +@@ -462,6 +528,7 @@ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); @@ -910,7 +920,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c explicit_bzero(&gssapi_client, sizeof(ssh_gssapi_client)); return 0; -@@ -472,6 +539,24 @@ +@@ -471,6 +538,24 @@ return (0); } @@ -935,7 +945,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -498,9 +583,11 @@ +@@ -497,9 +582,11 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -948,7 +958,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c gssapi_client.store.envvar == NULL) return; -@@ -526,6 +613,18 @@ +@@ -525,6 +612,18 @@ if (ret) return; @@ -967,7 +977,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -566,4 +665,13 @@ +@@ -565,4 +664,13 @@ return (char *)gssapi_client.displayname.value; } @@ -981,10 +991,10 @@ diff -Nur openssh-7.7p1.orig/gss-serv.c openssh-7.7p1/gss-serv.c +} + #endif -diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c ---- openssh-7.7p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/gss-serv-gsi.c 2018-07-05 13:40:25.459373752 +0200 -@@ -0,0 +1,331 @@ +diff -Nur openssh-7.8p1.orig/gss-serv-gsi.c openssh-7.8p1/gss-serv-gsi.c +--- openssh-7.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.8p1/gss-serv-gsi.c 2018-10-24 14:09:54.224377874 +0200 +@@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * @@ -1020,14 +1030,11 @@ diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c +#include + +#include "xmalloc.h" -+#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "misc.h" +#include "servconf.h" -+ -+#include "buffer.h" +#include "ssh-gss.h" + +extern ServerOptions options; @@ -1316,10 +1323,10 @@ diff -Nur openssh-7.7p1.orig/gss-serv-gsi.c openssh-7.7p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c ---- openssh-7.7p1.orig/gss-serv-krb5.c 2018-07-05 14:58:40.617584351 +0200 -+++ openssh-7.7p1/gss-serv-krb5.c 2018-07-05 13:40:25.459373752 +0200 -@@ -378,6 +378,34 @@ +diff -Nur openssh-7.8p1.orig/gss-serv-krb5.c openssh-7.8p1/gss-serv-krb5.c +--- openssh-7.8p1.orig/gss-serv-krb5.c 2018-10-24 14:09:16.497776978 +0200 ++++ openssh-7.8p1/gss-serv-krb5.c 2018-10-24 14:09:54.224377874 +0200 +@@ -379,6 +379,34 @@ return found_principal; } @@ -1354,7 +1361,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -470,7 +498,7 @@ +@@ -471,7 +499,7 @@ return set_env; } @@ -1363,7 +1370,7 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -541,7 +569,7 @@ +@@ -542,7 +570,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1372,9 +1379,9 @@ diff -Nur openssh-7.7p1.orig/gss-serv-krb5.c openssh-7.7p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c ---- openssh-7.7p1.orig/kexgsss.c 2018-07-05 14:58:40.617584351 +0200 -+++ openssh-7.7p1/kexgsss.c 2018-07-05 13:40:25.460373741 +0200 +diff -Nur openssh-7.8p1.orig/kexgsss.c openssh-7.8p1/kexgsss.c +--- openssh-7.8p1.orig/kexgsss.c 2018-10-24 14:09:16.685774989 +0200 ++++ openssh-7.8p1/kexgsss.c 2018-10-24 14:09:54.225377863 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1410,7 +1417,7 @@ diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -636,4 +640,23 @@ +@@ -638,4 +642,23 @@ } return r; } @@ -1434,9 +1441,9 @@ diff -Nur openssh-7.7p1.orig/kexgsss.c openssh-7.7p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.7p1.orig/LICENSE.globus_usage openssh-7.7p1/LICENSE.globus_usage ---- openssh-7.7p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/LICENSE.globus_usage 2018-07-05 13:40:25.460373741 +0200 +diff -Nur openssh-7.8p1.orig/LICENSE.globus_usage openssh-7.8p1/LICENSE.globus_usage +--- openssh-7.8p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.8p1/LICENSE.globus_usage 2018-10-24 14:09:54.225377863 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1456,9 +1463,9 @@ diff -Nur openssh-7.7p1.orig/LICENSE.globus_usage openssh-7.7p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.7p1.orig/Makefile.in openssh-7.7p1/Makefile.in ---- openssh-7.7p1.orig/Makefile.in 2018-07-05 14:58:40.617584351 +0200 -+++ openssh-7.7p1/Makefile.in 2018-07-05 13:40:25.473373600 +0200 +diff -Nur openssh-7.8p1.orig/Makefile.in openssh-7.8p1/Makefile.in +--- openssh-7.8p1.orig/Makefile.in 2018-10-24 14:09:16.688774958 +0200 ++++ openssh-7.8p1/Makefile.in 2018-10-24 14:09:54.225377863 +0200 @@ -124,8 +124,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1469,11 +1476,11 @@ diff -Nur openssh-7.7p1.orig/Makefile.in openssh-7.7p1/Makefile.in + ssh-globus-usage.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o -diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c ---- openssh-7.7p1.orig/misc.c 2018-07-05 14:58:40.618584340 +0200 -+++ openssh-7.7p1/misc.c 2018-07-05 13:40:25.460373741 +0200 -@@ -238,11 +238,14 @@ + sandbox-solaris.o uidswap.o +diff -Nur openssh-7.8p1.orig/misc.c openssh-7.8p1/misc.c +--- openssh-7.8p1.orig/misc.c 2018-10-24 14:09:16.494777010 +0200 ++++ openssh-7.8p1/misc.c 2018-10-24 14:09:54.226377853 +0200 +@@ -237,11 +237,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1481,15 +1488,15 @@ diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c +#define QUOTES "'\"" + /* return next token in configuration line */ - char * - strdelim(char **s) + static char * + strdelim_internal(char **s, int split_equals) { - char *old; + char *old, *p, *q; int wspace = 0; if (*s == NULL) -@@ -250,6 +253,21 @@ +@@ -249,6 +252,21 @@ old = *s; @@ -1508,10 +1515,10 @@ diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c + return (old); + } + - *s = strpbrk(*s, WHITESPACE QUOTE "="); + *s = strpbrk(*s, + split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) - return (old); -@@ -305,6 +323,20 @@ +@@ -324,6 +342,20 @@ return copy; } @@ -1532,9 +1539,9 @@ diff -Nur openssh-7.7p1.orig/misc.c openssh-7.7p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.7p1.orig/misc.h openssh-7.7p1/misc.h ---- openssh-7.7p1.orig/misc.h 2018-07-05 14:58:40.618584340 +0200 -+++ openssh-7.7p1/misc.h 2018-07-05 13:40:25.461373730 +0200 +diff -Nur openssh-7.8p1.orig/misc.h openssh-7.8p1/misc.h +--- openssh-7.8p1.orig/misc.h 2018-10-24 14:09:16.494777010 +0200 ++++ openssh-7.8p1/misc.h 2018-10-24 14:09:54.226377853 +0200 @@ -82,6 +82,7 @@ void sock_set_v6only(int); @@ -1543,20 +1550,20 @@ diff -Nur openssh-7.7p1.orig/misc.h openssh-7.7p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c ---- openssh-7.7p1.orig/monitor.c 2018-07-05 14:58:40.619584329 +0200 -+++ openssh-7.7p1/monitor.c 2018-07-05 15:10:21.951050957 +0200 -@@ -165,6 +165,9 @@ - int mm_answer_gss_userok(int, Buffer *); - int mm_answer_gss_checkmic(int, Buffer *); - int mm_answer_gss_sign(int, Buffer *); -+int mm_answer_gss_error(int, Buffer *); -+int mm_answer_gss_indicate_mechs(int, Buffer *); -+int mm_answer_gss_localname(int, Buffer *); - int mm_answer_gss_updatecreds(int, Buffer *); +diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c +--- openssh-7.8p1.orig/monitor.c 2018-10-24 14:09:16.689774947 +0200 ++++ openssh-7.8p1/monitor.c 2018-10-24 14:09:54.226377853 +0200 +@@ -150,6 +150,9 @@ + int mm_answer_gss_userok(int, struct sshbuf *); + int mm_answer_gss_checkmic(int, struct sshbuf *); + int mm_answer_gss_sign(int, struct sshbuf *); ++int mm_answer_gss_error(int, struct sshbuf *); ++int mm_answer_gss_indicate_mechs(int, struct sshbuf *); ++int mm_answer_gss_localname(int, struct sshbuf *); + int mm_answer_gss_updatecreds(int, struct sshbuf *); #endif -@@ -215,7 +218,7 @@ +@@ -200,7 +203,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1565,7 +1572,7 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -223,7 +226,7 @@ +@@ -208,7 +211,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1574,7 +1581,7 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -251,8 +254,11 @@ +@@ -232,8 +235,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1587,7 +1594,7 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c #endif {0, 0, NULL} }; -@@ -262,6 +268,8 @@ +@@ -243,6 +249,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1596,7 +1603,7 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -343,6 +351,8 @@ +@@ -324,6 +332,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1605,7 +1612,7 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -458,6 +468,8 @@ +@@ -442,6 +452,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1614,14 +1621,15 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -767,14 +779,17 @@ +@@ -763,15 +775,18 @@ debug3("%s", __func__); - if (authctxt->attempt++ != 0) - fatal("%s: multiple attempts for getpwnam", __func__); - - username = buffer_get_string(m, NULL); + if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); pwent = getpwnamallow(username); @@ -1635,25 +1643,26 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -1992,13 +2007,16 @@ - mm_answer_gss_userok(int sock, Buffer *m) +@@ -2010,13 +2025,17 @@ + mm_answer_gss_userok(int sock, struct sshbuf *m) { - int authenticated; + int r, authenticated; + int gssapi_keyex; const char *displayname; if (!options.gss_authentication && !options.gss_keyex) fatal("%s: GSSAPI authentication not enabled", __func__); -+ gssapi_keyex = buffer_get_int(m); ++ if ((r = sshbuf_get_u32(m, &gssapi_keyex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + authenticated = authctxt->valid && - ssh_gssapi_userok(authctxt->user, authctxt->pw); + ssh_gssapi_userok(authctxt->user, authctxt->pw, gssapi_keyex); - buffer_clear(m); - buffer_put_int(m, authenticated); -@@ -2006,7 +2024,10 @@ + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, authenticated)) != 0) +@@ -2025,7 +2044,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1665,20 +1674,23 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -2015,6 +2036,68 @@ +@@ -2034,6 +2056,79 @@ return (authenticated); } +int -+mm_answer_gss_error(int socket, Buffer *m) { ++mm_answer_gss_error(int socket, struct sshbuf *m) ++{ + OM_uint32 major, minor; + char *msg; ++ int r; + + msg=ssh_gssapi_last_error(gsscontext, &major, &minor); -+ buffer_clear(m); -+ buffer_put_int(m, major); -+ buffer_put_int(m, minor); -+ buffer_put_cstring(m, msg); ++ sshbuf_reset(m); ++ if ((r = sshbuf_put_u32(m, major)) != 0 || ++ (r = sshbuf_put_u32(m, minor)) != 0 || ++ (r = sshbuf_put_cstring(m, msg)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(socket, MONITOR_ANS_GSSERR, m); + @@ -1688,19 +1700,23 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c +} + +int -+mm_answer_gss_indicate_mechs(int socket, Buffer *m) { ++mm_answer_gss_indicate_mechs(int socket, struct sshbuf *m) ++{ + OM_uint32 major, minor; + gss_OID_set mech_set; + size_t i; ++ int r; + + major=gss_indicate_mechs(&minor, &mech_set); + -+ buffer_clear(m); -+ buffer_put_int(m, major); -+ buffer_put_int(m, mech_set->count); ++ sshbuf_reset(m); ++ if ((r = sshbuf_put_u32(m, major)) != 0 || ++ (r = sshbuf_put_u32(m, mech_set->count)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + for (i = 0; i < mech_set->count; i++) { -+ buffer_put_string(m, mech_set->elements[i].elements, -+ mech_set->elements[i].length); ++ if ((r = sshbuf_put_string(m, mech_set->elements[i].elements, ++ mech_set->elements[i].length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + } + + gss_release_oid_set(&minor, &mech_set); @@ -1711,18 +1727,22 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c +} + +int -+mm_answer_gss_localname(int socket, Buffer *m) { ++mm_answer_gss_localname(int socket, struct sshbuf *m) ++{ + char *name; ++ int r; + + ssh_gssapi_localname(&name); + -+ buffer_clear(m); ++ sshbuf_reset(m); + if (name) { -+ buffer_put_cstring(m, name); ++ if ((r = sshbuf_put_cstring(m, name)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug3("%s: sending result %s", __func__, name); + free(name); + } else { -+ buffer_put_cstring(m, ""); ++ if ((r = sshbuf_put_cstring(m, "")) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug3("%s: sending result \"\"", __func__); + } + @@ -1732,15 +1752,17 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c +} + int - mm_answer_gss_sign(int socket, Buffer *m) + mm_answer_gss_sign(int socket, struct sshbuf *m) { -@@ -2065,11 +2148,13 @@ +@@ -2085,12 +2180,14 @@ ssh_gssapi_ccache store; - int ok; + int ok, r; -+ store.filename = buffer_get_string(m, NULL); - store.envvar = buffer_get_string(m, NULL); - store.envval = buffer_get_string(m, NULL); +- if ((r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || ++ if ((r = sshbuf_get_cstring(m, &store.filename, NULL)) != 0 || ++ (r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); ok = ssh_gssapi_update_creds(&store); @@ -1748,10 +1770,10 @@ diff -Nur openssh-7.7p1.orig/monitor.c openssh-7.7p1/monitor.c free(store.envvar); free(store.envval); -diff -Nur openssh-7.7p1.orig/monitor.h openssh-7.7p1/monitor.h ---- openssh-7.7p1.orig/monitor.h 2018-07-05 14:58:40.619584329 +0200 -+++ openssh-7.7p1/monitor.h 2018-07-05 13:40:25.461373730 +0200 -@@ -75,8 +75,10 @@ +diff -Nur openssh-7.8p1.orig/monitor.h openssh-7.8p1/monitor.h +--- openssh-7.8p1.orig/monitor.h 2018-10-24 14:09:16.630775571 +0200 ++++ openssh-7.8p1/monitor.h 2018-10-24 14:09:54.227377842 +0200 +@@ -73,8 +73,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, @@ -1764,48 +1786,55 @@ diff -Nur openssh-7.7p1.orig/monitor.h openssh-7.7p1/monitor.h }; struct monitor { -diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c ---- openssh-7.7p1.orig/monitor_wrap.c 2018-07-05 14:58:40.619584329 +0200 -+++ openssh-7.7p1/monitor_wrap.c 2018-07-05 15:04:51.534606293 +0200 -@@ -998,12 +998,13 @@ +diff -Nur openssh-7.8p1.orig/monitor_wrap.c openssh-7.8p1/monitor_wrap.c +--- openssh-7.8p1.orig/monitor_wrap.c 2018-10-24 14:09:16.665775201 +0200 ++++ openssh-7.8p1/monitor_wrap.c 2018-10-24 14:33:40.976350751 +0200 +@@ -1045,13 +1045,15 @@ } int -mm_ssh_gssapi_userok(char *user, struct passwd *pw) +mm_ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex) { - Buffer m; - int authenticated = 0; + struct sshbuf *m; + int r, authenticated = 0; - buffer_init(&m); -+ buffer_put_int(&m, gssapi_keyex); + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, gssapi_keyex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, -@@ -1016,6 +1017,83 @@ + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); + mm_request_receive_expect(pmonitor->m_recvfd, +@@ -1065,6 +1067,94 @@ return (authenticated); } +char * -+mm_ssh_gssapi_last_error(Gssctxt *ctx, OM_uint32 *major, OM_uint32 *minor) { -+ Buffer m; ++mm_ssh_gssapi_last_error(Gssctxt *ctx, OM_uint32 *major, OM_uint32 *minor) ++{ ++ struct sshbuf *m = NULL; + OM_uint32 maj,min; + char *errstr; ++ int r; + -+ buffer_init(&m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, &m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, m); + -+ maj = buffer_get_int(&m); -+ min = buffer_get_int(&m); ++ if ((r = sshbuf_get_u32(m, &maj)) != 0 || ++ (r = sshbuf_get_u32(m, &min)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + if (major) *major=maj; + if (minor) *minor=min; + -+ errstr=buffer_get_string(&m,NULL); ++ if ((r = sshbuf_get_cstring(m, &errstr, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ buffer_free(&m); ++ sshbuf_free(m); + + return(errstr); +} @@ -1813,28 +1842,31 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c +OM_uint32 +mm_gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set) +{ -+ Buffer m; ++ struct sshbuf *m = NULL; + OM_uint32 major,minor; + int count; + gss_OID_desc oid; -+ u_int length; ++ size_t length; ++ int r; + -+ buffer_init(&m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS, -+ &m); -+ major=buffer_get_int(&m); -+ count=buffer_get_int(&m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS, m); ++ if ((r = sshbuf_get_u32(m, &major)) != 0 || ++ (r = sshbuf_get_u32(m, &count)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ gss_create_empty_oid_set(&minor,mech_set); ++ gss_create_empty_oid_set(&minor, mech_set); + while(count-->0) { -+ oid.elements=buffer_get_string(&m,&length); -+ oid.length=length; -+ gss_add_oid_set_member(&minor,&oid,mech_set); ++ if ((r = sshbuf_get_string(m, (u_char **)&oid.elements, &length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ oid.length = length; ++ gss_add_oid_set_member(&minor, &oid, mech_set); + } + -+ buffer_free(&m); ++ sshbuf_free(m); + + return(major); +} @@ -1842,19 +1874,22 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c +int +mm_ssh_gssapi_localname(char **lname) +{ -+ Buffer m; ++ struct sshbuf *m = NULL; ++ int r; + -+ buffer_init(&m); -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, &m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, m); + + debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME, -+ &m); ++ m); + -+ *lname = buffer_get_string(&m, NULL); ++ if ((r = sshbuf_get_cstring(m, lname, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ buffer_free(&m); -+ if (lname[0] == '\0') { ++ sshbuf_free(m); ++ if ((*lname == NULL) || (*lname[0] == '\0')) { + debug3("%s: gssapi identity mapping failed", __func__); + } else { + debug3("%s: gssapi identity mapped to %s", __func__, *lname); @@ -1866,17 +1901,19 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.c openssh-7.7p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -@@ -1046,6 +1124,7 @@ +@@ -1098,7 +1188,8 @@ + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); - buffer_init(&m); +- if ((r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || ++ if ((r = sshbuf_put_cstring(m, store->filename ? store->filename : "")) != 0 || ++ (r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || + (r = sshbuf_put_cstring(m, store->envval ? store->envval : "")) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ buffer_put_cstring(&m, store->filename ? store->filename : ""); - buffer_put_cstring(&m, store->envvar ? store->envvar : ""); - buffer_put_cstring(&m, store->envval ? store->envval : ""); - -diff -Nur openssh-7.7p1.orig/monitor_wrap.h openssh-7.7p1/monitor_wrap.h ---- openssh-7.7p1.orig/monitor_wrap.h 2018-07-05 14:58:40.619584329 +0200 -+++ openssh-7.7p1/monitor_wrap.h 2018-07-05 13:40:25.462373719 +0200 +diff -Nur openssh-7.8p1.orig/monitor_wrap.h openssh-7.8p1/monitor_wrap.h +--- openssh-7.8p1.orig/monitor_wrap.h 2018-10-24 14:09:16.647775391 +0200 ++++ openssh-7.8p1/monitor_wrap.h 2018-10-24 14:09:54.242377684 +0200 @@ -65,9 +65,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -1892,10 +1929,10 @@ diff -Nur openssh-7.7p1.orig/monitor_wrap.h openssh-7.7p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.7p1.orig/readconf.c openssh-7.7p1/readconf.c ---- openssh-7.7p1.orig/readconf.c 2018-07-05 14:58:40.620584318 +0200 -+++ openssh-7.7p1/readconf.c 2018-07-05 13:40:25.462373719 +0200 -@@ -1959,13 +1959,13 @@ +diff -Nur openssh-7.8p1.orig/readconf.c openssh-7.8p1/readconf.c +--- openssh-7.8p1.orig/readconf.c 2018-10-24 14:09:16.656775296 +0200 ++++ openssh-7.8p1/readconf.c 2018-10-24 14:09:54.246377641 +0200 +@@ -2013,13 +2013,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1913,10 +1950,10 @@ diff -Nur openssh-7.7p1.orig/readconf.c openssh-7.7p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.7p1.orig/readconf.h openssh-7.7p1/readconf.h ---- openssh-7.7p1.orig/readconf.h 2018-07-05 14:58:40.620584318 +0200 -+++ openssh-7.7p1/readconf.h 2018-07-05 13:40:25.462373719 +0200 -@@ -80,6 +80,8 @@ +diff -Nur openssh-7.8p1.orig/readconf.h openssh-7.8p1/readconf.h +--- openssh-7.8p1.orig/readconf.h 2018-10-24 14:09:16.522776714 +0200 ++++ openssh-7.8p1/readconf.h 2018-10-24 14:09:54.247377631 +0200 +@@ -77,6 +77,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1925,10 +1962,10 @@ diff -Nur openssh-7.7p1.orig/readconf.h openssh-7.7p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c ---- openssh-7.7p1.orig/servconf.c 2018-07-05 14:58:40.621584308 +0200 -+++ openssh-7.7p1/servconf.c 2018-07-05 13:40:25.463373709 +0200 -@@ -83,6 +83,7 @@ +diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c +--- openssh-7.8p1.orig/servconf.c 2018-10-24 14:09:16.672775127 +0200 ++++ openssh-7.8p1/servconf.c 2018-10-24 14:09:54.247377631 +0200 +@@ -84,6 +84,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1936,7 +1973,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -126,9 +127,11 @@ +@@ -127,9 +128,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ticket = -1; options->gss_authentication=-1; @@ -1948,7 +1985,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -173,6 +176,8 @@ +@@ -177,6 +180,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1957,7 +1994,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -256,6 +261,8 @@ +@@ -269,6 +274,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1966,7 +2003,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -333,13 +340,17 @@ +@@ -346,13 +353,17 @@ if (options->kerberos_unique_ticket == -1) options->kerberos_unique_ticket = 0; if (options->gss_authentication == -1) @@ -1986,7 +2023,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -472,7 +483,7 @@ +@@ -487,7 +498,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1995,7 +2032,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -494,10 +505,14 @@ +@@ -509,10 +520,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -2003,14 +2040,14 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, + sDisUsageStats, sUsageStatsTarg, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -523,8 +538,10 @@ +@@ -538,8 +553,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -2021,7 +2058,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -572,7 +589,14 @@ +@@ -587,7 +604,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -2036,7 +2073,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -580,7 +604,10 @@ +@@ -595,7 +619,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -2047,8 +2084,8 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -649,6 +676,8 @@ - { "permitopen", sPermitOpen, SSHCFG_ALL }, +@@ -666,6 +693,8 @@ + { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, + { "disableusagestats", sDisUsageStats, SSHCFG_GLOBAL}, @@ -2056,7 +2093,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1249,6 +1278,10 @@ +@@ -1296,6 +1325,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2067,7 +2104,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1463,6 +1496,10 @@ +@@ -1510,6 +1543,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2078,7 +2115,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1471,6 +1508,10 @@ +@@ -1518,6 +1555,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2089,7 +2126,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1491,6 +1532,12 @@ +@@ -1538,6 +1579,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2102,7 +2139,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1948,6 +1995,35 @@ +@@ -2051,6 +2098,35 @@ *charptr = xstrdup(arg); break; @@ -2138,7 +2175,7 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2241,6 +2317,7 @@ +@@ -2345,6 +2421,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2146,10 +2183,10 @@ diff -Nur openssh-7.7p1.orig/servconf.c openssh-7.7p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h ---- openssh-7.7p1.orig/servconf.h 2018-07-05 14:58:40.621584308 +0200 -+++ openssh-7.7p1/servconf.h 2018-07-05 13:40:25.463373709 +0200 -@@ -135,9 +135,12 @@ +diff -Nur openssh-7.8p1.orig/servconf.h openssh-7.8p1/servconf.h +--- openssh-7.8p1.orig/servconf.h 2018-10-24 14:09:16.535776576 +0200 ++++ openssh-7.8p1/servconf.h 2018-10-24 14:09:54.248377620 +0200 +@@ -129,9 +129,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2162,7 +2199,7 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -194,6 +197,7 @@ +@@ -191,6 +194,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2170,8 +2207,8 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h int permit_tun; -@@ -201,6 +205,10 @@ - u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */ +@@ -200,6 +204,10 @@ + u_int num_permitted_listens; char *chroot_directory; + @@ -2181,10 +2218,10 @@ diff -Nur openssh-7.7p1.orig/servconf.h openssh-7.7p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.7p1.orig/ssh.1 openssh-7.7p1/ssh.1 ---- openssh-7.7p1.orig/ssh.1 2018-07-05 14:58:40.622584297 +0200 -+++ openssh-7.7p1/ssh.1 2018-07-05 13:40:25.463373709 +0200 -@@ -1419,6 +1419,18 @@ +diff -Nur openssh-7.8p1.orig/ssh.1 openssh-7.8p1/ssh.1 +--- openssh-7.8p1.orig/ssh.1 2018-10-24 14:09:16.525776682 +0200 ++++ openssh-7.8p1/ssh.1 2018-10-24 14:09:54.249377610 +0200 +@@ -1423,6 +1423,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2203,10 +2240,10 @@ diff -Nur openssh-7.7p1.orig/ssh.1 openssh-7.7p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.7p1.orig/ssh.c openssh-7.7p1/ssh.c ---- openssh-7.7p1.orig/ssh.c 2018-07-05 14:58:40.622584297 +0200 -+++ openssh-7.7p1/ssh.c 2018-07-05 13:40:25.464373698 +0200 -@@ -522,6 +522,32 @@ +diff -Nur openssh-7.8p1.orig/ssh.c openssh-7.8p1/ssh.c +--- openssh-7.8p1.orig/ssh.c 2018-10-24 14:09:16.690774937 +0200 ++++ openssh-7.8p1/ssh.c 2018-10-24 14:09:54.249377610 +0200 +@@ -541,6 +541,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2253,9 +2290,9 @@ diff -Nur openssh-7.7p1.orig/ssh.c openssh-7.7p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) -diff -Nur openssh-7.7p1.orig/ssh_config openssh-7.7p1/ssh_config ---- openssh-7.7p1.orig/ssh_config 2018-07-05 14:58:40.622584297 +0200 -+++ openssh-7.7p1/ssh_config 2018-07-05 13:40:25.464373698 +0200 +diff -Nur openssh-7.8p1.orig/ssh_config openssh-7.8p1/ssh_config +--- openssh-7.8p1.orig/ssh_config 2018-10-24 14:09:16.427777719 +0200 ++++ openssh-7.8p1/ssh_config 2018-10-24 14:09:54.249377610 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2271,9 +2308,9 @@ diff -Nur openssh-7.7p1.orig/ssh_config openssh-7.7p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 ---- openssh-7.7p1.orig/ssh_config.5 2018-07-05 14:58:40.623584286 +0200 -+++ openssh-7.7p1/ssh_config.5 2018-07-05 13:40:25.464373698 +0200 +diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 +--- openssh-7.8p1.orig/ssh_config.5 2018-10-24 14:09:16.599775899 +0200 ++++ openssh-7.8p1/ssh_config.5 2018-10-24 14:09:54.250377599 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2287,7 +2324,7 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -727,7 +733,7 @@ +@@ -717,7 +723,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2296,7 +2333,7 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -735,12 +741,12 @@ +@@ -725,12 +731,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2311,7 +2348,7 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -772,7 +778,7 @@ +@@ -762,7 +768,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2320,7 +2357,7 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1234,7 +1240,7 @@ +@@ -1227,7 +1233,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2329,29 +2366,11 @@ diff -Nur openssh-7.7p1.orig/ssh_config.5 openssh-7.7p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c ---- openssh-7.7p1.orig/sshconnect2.c 2018-07-05 14:58:40.623584286 +0200 -+++ openssh-7.7p1/sshconnect2.c 2018-07-05 13:40:25.465373687 +0200 -@@ -285,7 +285,7 @@ - - #ifdef GSSAPI - char *orig = NULL, *gss = NULL; -- char *gss_host = NULL; -+ const char *gss_host = NULL; - #endif - - xxx_host = host; -@@ -302,7 +302,7 @@ - orig = options.kex_algorithms; - - if (options.gss_trust_dns) -- gss_host = (char *)get_canonical_hostname(active_state, 1); -+ gss_host = get_canonical_hostname(active_state, 1); - else - gss_host = host; - -@@ -841,6 +841,11 @@ - int ok = 0; +diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c +--- openssh-7.8p1.orig/sshconnect2.c 2018-10-24 14:09:16.658775275 +0200 ++++ openssh-7.8p1/sshconnect2.c 2018-10-24 14:09:54.257377525 +0200 +@@ -863,6 +863,11 @@ + int r, ok = 0; const char *gss_host = NULL; + if (!options.gss_authentication) { @@ -2362,18 +2381,18 @@ diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -930,7 +935,8 @@ +@@ -956,7 +961,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ - if (!(flags & GSS_C_INTEG_FLAG)) { + if (strcmp(authctxt->method->name, "gssapi") == 0 || -+ (!(flags & GSS_C_INTEG_FLAG))) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); - packet_send(); - } else { -@@ -1078,6 +1084,20 @@ - return 0; ++ !(flags & GSS_C_INTEG_FLAG)) { + if ((r = sshpkt_start(ssh, + SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || + (r = sshpkt_send(ssh)) != 0) +@@ -1126,6 +1132,20 @@ + return r; } +#ifdef GSI @@ -2393,43 +2412,36 @@ diff -Nur openssh-7.7p1.orig/sshconnect2.c openssh-7.7p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -1095,8 +1115,16 @@ - return (0); - } +@@ -1146,6 +1166,11 @@ + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); +#ifdef GSI -+ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { -+ ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex"); -+ } else { ++ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) ++ ssh_gssapi_buildmic(b, "", authctxt->service, "gssapi-keyex"); ++ else +#endif - ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -+#ifdef GSI -+ } -+#endif - gssbuf.value = buffer_ptr(&b); - gssbuf.length = buffer_len(&b); -@@ -1107,7 +1135,15 @@ +@@ -1158,7 +1183,13 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); +#ifdef GSI -+ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { ++ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) + packet_put_cstring(""); -+ } else { ++ else +#endif packet_put_cstring(authctxt->server_user); -+#ifdef GSI -+ } -+#endif ++ packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.7p1.orig/sshd.8 openssh-7.7p1/sshd.8 ---- openssh-7.7p1.orig/sshd.8 2018-07-05 14:58:40.624584275 +0200 -+++ openssh-7.7p1/sshd.8 2018-07-05 13:40:25.465373687 +0200 -@@ -760,6 +760,44 @@ +diff -Nur openssh-7.8p1.orig/sshd.8 openssh-7.8p1/sshd.8 +--- openssh-7.8p1.orig/sshd.8 2018-10-24 14:09:16.457777401 +0200 ++++ openssh-7.8p1/sshd.8 2018-10-24 14:09:54.258377514 +0200 +@@ -788,6 +788,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2474,9 +2486,9 @@ diff -Nur openssh-7.7p1.orig/sshd.8 openssh-7.7p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c ---- openssh-7.7p1.orig/sshd.c 2018-07-05 14:58:40.624584275 +0200 -+++ openssh-7.7p1/sshd.c 2018-07-05 13:40:25.466373676 +0200 +diff -Nur openssh-7.8p1.orig/sshd.c openssh-7.8p1/sshd.c +--- openssh-7.8p1.orig/sshd.c 2018-10-24 14:09:16.691774926 +0200 ++++ openssh-7.8p1/sshd.c 2018-10-24 14:09:54.259377504 +0200 @@ -130,6 +130,7 @@ #include "auth-options.h" #include "version.h" @@ -2485,7 +2497,7 @@ diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -@@ -1749,6 +1750,13 @@ +@@ -1797,6 +1798,13 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2499,7 +2511,7 @@ diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2247,7 +2255,7 @@ +@@ -2305,7 +2313,7 @@ #endif #ifdef GSSAPI @@ -2508,9 +2520,9 @@ diff -Nur openssh-7.7p1.orig/sshd.c openssh-7.7p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config ---- openssh-7.7p1.orig/sshd_config 2018-07-05 14:58:40.624584275 +0200 -+++ openssh-7.7p1/sshd_config 2018-07-05 13:40:25.475373579 +0200 +diff -Nur openssh-7.8p1.orig/sshd_config openssh-7.8p1/sshd_config +--- openssh-7.8p1.orig/sshd_config 2018-10-24 14:09:16.509776851 +0200 ++++ openssh-7.8p1/sshd_config 2018-10-24 14:09:54.259377504 +0200 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2536,7 +2548,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -142,6 +147,10 @@ +@@ -141,6 +146,10 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2547,10 +2559,10 @@ diff -Nur openssh-7.7p1.orig/sshd_config openssh-7.7p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 ---- openssh-7.7p1.orig/sshd_config.5 2018-07-05 14:58:40.626584254 +0200 -+++ openssh-7.7p1/sshd_config.5 2018-07-05 13:40:25.466373676 +0200 -@@ -575,6 +575,15 @@ +diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 +--- openssh-7.8p1.orig/sshd_config.5 2018-10-24 14:09:16.562776291 +0200 ++++ openssh-7.8p1/sshd_config.5 2018-10-24 14:09:54.259377504 +0200 +@@ -576,6 +576,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. @@ -2566,7 +2578,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -632,15 +641,34 @@ +@@ -633,15 +642,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2602,7 +2614,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -651,7 +679,7 @@ +@@ -652,7 +680,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2611,15 +2623,15 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -690,7 +718,6 @@ +@@ -691,7 +719,6 @@ .Pp The default is .Dq gss-gex-sha1-,gss-group14-sha1- . -This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication - as a comma-separated pattern list. -@@ -1556,6 +1583,103 @@ + as a list of comma-separated patterns. +@@ -1627,6 +1654,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2723,7 +2735,7 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1597,6 +1721,12 @@ +@@ -1668,6 +1792,12 @@ as a non-root user. The default is .Cm no . @@ -2736,9 +2748,9 @@ diff -Nur openssh-7.7p1.orig/sshd_config.5 openssh-7.7p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.7p1.orig/ssh-globus-usage.c openssh-7.7p1/ssh-globus-usage.c ---- openssh-7.7p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/ssh-globus-usage.c 2018-07-05 13:40:25.466373676 +0200 +diff -Nur openssh-7.8p1.orig/ssh-globus-usage.c openssh-7.8p1/ssh-globus-usage.c +--- openssh-7.8p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.8p1/ssh-globus-usage.c 2018-10-24 14:09:54.260377493 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3136,9 +3148,9 @@ diff -Nur openssh-7.7p1.orig/ssh-globus-usage.c openssh-7.7p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.7p1.orig/ssh-globus-usage.h openssh-7.7p1/ssh-globus-usage.h ---- openssh-7.7p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.7p1/ssh-globus-usage.h 2018-07-05 13:40:25.467373665 +0200 +diff -Nur openssh-7.8p1.orig/ssh-globus-usage.h openssh-7.8p1/ssh-globus-usage.h +--- openssh-7.8p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.8p1/ssh-globus-usage.h 2018-10-24 14:09:54.260377493 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3188,9 +3200,9 @@ diff -Nur openssh-7.7p1.orig/ssh-globus-usage.h openssh-7.7p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h ---- openssh-7.7p1.orig/ssh-gss.h 2018-07-05 14:58:40.627584243 +0200 -+++ openssh-7.7p1/ssh-gss.h 2018-07-05 13:40:25.467373665 +0200 +diff -Nur openssh-7.8p1.orig/ssh-gss.h openssh-7.8p1/ssh-gss.h +--- openssh-7.8p1.orig/ssh-gss.h 2018-10-24 14:09:16.560776312 +0200 ++++ openssh-7.8p1/ssh-gss.h 2018-10-24 14:09:54.260377493 +0200 @@ -85,6 +85,7 @@ KEX_GSS_GRP14_SHA1_ID @@ -3224,7 +3236,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -151,6 +154,9 @@ +@@ -155,6 +158,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -3234,7 +3246,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -161,7 +167,7 @@ +@@ -165,7 +171,7 @@ int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); @@ -3243,7 +3255,7 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h 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); -@@ -174,6 +180,7 @@ +@@ -178,6 +184,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); void ssh_gssapi_rekey_creds(void); @@ -3251,12 +3263,12 @@ diff -Nur openssh-7.7p1.orig/ssh-gss.h openssh-7.7p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.7p1.orig/version.h openssh-7.7p1/version.h ---- openssh-7.7p1.orig/version.h 2018-07-05 14:58:40.627584243 +0200 -+++ openssh-7.7p1/version.h 2018-07-05 13:40:25.467373665 +0200 +diff -Nur openssh-7.8p1.orig/version.h openssh-7.8p1/version.h +--- openssh-7.8p1.orig/version.h 2018-08-23 07:41:42.000000000 +0200 ++++ openssh-7.8p1/version.h 2018-10-24 14:09:54.260377493 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_7.7" + #define SSH_VERSION "OpenSSH_7.8" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.8p1-gsskex.patch similarity index 83% rename from openssh-7.2p1-gsskex.patch rename to openssh-7.8p1-gsskex.patch index c9034e8..6a350c7 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.8p1-gsskex.patch @@ -1,7 +1,7 @@ diff -up openssh/auth2.c.gsskex openssh/auth2.c ---- openssh/auth2.c.gsskex 2017-09-27 13:54:53.539534068 +0200 -+++ openssh/auth2.c 2017-09-27 13:54:53.590534348 +0200 -@@ -72,6 +72,7 @@ extern Authmethod method_passwd; +--- openssh/auth2.c.gsskex 2018-08-22 11:47:33.260216045 +0200 ++++ openssh/auth2.c 2018-08-22 11:47:33.307216424 +0200 +@@ -74,6 +74,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -9,7 +9,7 @@ diff -up openssh/auth2.c.gsskex openssh/auth2.c extern Authmethod method_gssapi; #endif -@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { +@@ -81,6 +82,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -18,8 +18,8 @@ diff -up openssh/auth2.c.gsskex openssh/auth2.c #endif &method_passwd, diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c ---- openssh/auth2-gss.c.gsskex 2017-09-27 13:54:53.539534068 +0200 -+++ openssh/auth2-gss.c 2017-09-27 13:54:53.590534348 +0200 +--- openssh/auth2-gss.c.gsskex 2018-08-22 11:47:33.260216045 +0200 ++++ openssh/auth2-gss.c 2018-08-22 13:00:48.722680124 +0200 @@ -31,6 +31,7 @@ #include @@ -27,8 +27,8 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c +#include #include "xmalloc.h" - #include "key.h" -@@ -53,6 +54,41 @@ static int input_gssapi_mic(int type, u_ + #include "sshkey.h" +@@ -54,6 +55,44 @@ static int input_gssapi_mic(int type, u_ 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 *); @@ -40,7 +40,7 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c +{ + Authctxt *authctxt = ssh->authctxt; + int authenticated = 0; -+ Buffer b; ++ struct sshbuf *b = NULL; + gss_buffer_desc mic, gssbuf; + u_int len; + @@ -49,11 +49,14 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c + + packet_check_eom(); + -+ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, ++ if ((b = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, + "gssapi-keyex"); + -+ gssbuf.value = buffer_ptr(&b); -+ gssbuf.length = buffer_len(&b); ++ gssbuf.value = sshbuf_mutable_ptr(b); ++ 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, @@ -61,7 +64,7 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); + -+ buffer_free(&b); ++ sshbuf_free(b); + free(mic.value); + + return (authenticated); @@ -70,9 +73,9 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -240,7 +275,8 @@ input_gssapi_exchange_complete(int type, - - packet_check_eom(); +@@ -260,7 +296,8 @@ input_gssapi_exchange_complete(int type, + if ((r = sshpkt_get_end(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, @@ -80,8 +83,8 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -288,7 +324,8 @@ input_gssapi_mic(int type, u_int32_t ple - gssbuf.length = buffer_len(&b); +@@ -313,7 +350,8 @@ input_gssapi_mic(int type, u_int32_t ple + gssbuf.length = sshbuf_len(b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); @@ -90,7 +93,7 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -310,6 +347,12 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -335,6 +373,12 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } @@ -104,9 +107,9 @@ diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c "gssapi-with-mic", userauth_gssapi, diff -up openssh/auth.c.gsskex openssh/auth.c ---- openssh/auth.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/auth.c 2017-09-27 13:54:53.591534353 +0200 -@@ -395,6 +395,7 @@ auth_root_allowed(const char *method) +--- openssh/auth.c.gsskex 2018-08-22 11:47:33.274216158 +0200 ++++ openssh/auth.c 2018-08-22 11:47:33.308216432 +0200 +@@ -395,6 +395,7 @@ auth_root_allowed(struct ssh *ssh, const case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -115,8 +118,8 @@ diff -up openssh/auth.c.gsskex openssh/auth.c return 1; break; diff -up openssh/clientloop.c.gsskex openssh/clientloop.c ---- openssh/clientloop.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/clientloop.c 2017-09-27 13:54:53.591534353 +0200 +--- openssh/clientloop.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/clientloop.c 2018-08-22 11:47:33.309216441 +0200 @@ -112,6 +112,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -128,7 +131,7 @@ diff -up openssh/clientloop.c.gsskex openssh/clientloop.c /* import options */ extern Options options; -@@ -1349,9 +1353,18 @@ client_loop(struct ssh *ssh, int have_pt +@@ -1357,9 +1361,18 @@ client_loop(struct ssh *ssh, int have_pt break; /* Do channel operations unless rekeying in progress. */ @@ -149,9 +152,9 @@ diff -up openssh/clientloop.c.gsskex openssh/clientloop.c client_process_net_input(readset); diff -up openssh/configure.ac.gsskex openssh/configure.ac ---- openssh/configure.ac.gsskex 2017-09-27 13:54:53.581534298 +0200 -+++ openssh/configure.ac 2017-09-27 13:54:53.592534359 +0200 -@@ -621,6 +621,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +--- openssh/configure.ac.gsskex 2018-08-22 11:47:33.296216335 +0200 ++++ openssh/configure.ac 2018-08-22 11:47:33.309216441 +0200 +@@ -673,6 +673,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -183,16 +186,22 @@ diff -up openssh/configure.ac.gsskex openssh/configure.ac AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c ---- openssh/gss-genr.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/gss-genr.c 2017-09-27 13:54:53.592534359 +0200 -@@ -40,12 +40,167 @@ - #include "buffer.h" +--- openssh/gss-genr.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/gss-genr.c 2018-08-22 13:18:47.444383602 +0200 +@@ -35,18 +35,177 @@ + #include + #include + #include ++#include + + #include "xmalloc.h" + #include "ssherr.h" + #include "sshbuf.h" #include "log.h" #include "ssh2.h" +#include "cipher.h" -+#include "key.h" ++#include "sshkey.h" +#include "kex.h" -+#include #include "ssh-gss.h" @@ -240,9 +249,9 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +char * +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, + const char *host, const char *client) { -+ Buffer buf; ++ struct sshbuf *buf; + size_t i; -+ int oidpos, enclen; ++ int oidpos, enclen, r; + char *mechs, *encoded; + u_char digest[EVP_MAX_MD_SIZE]; + char deroid[2]; @@ -258,7 +267,8 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * + (gss_supported->count + 1)); + -+ buffer_init(&buf); ++ if ((buf = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); + + oidpos = 0; + for (i = 0; i < gss_supported->count; i++) { @@ -280,19 +290,21 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + encoded, EVP_MD_size(evp_md) * 2); + + if (oidpos != 0) -+ buffer_put_char(&buf, ','); ++ if ((r = sshbuf_put_u8(buf, ',')) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, -+ sizeof(KEX_GSS_GEX_SHA1_ID) - 1); -+ buffer_append(&buf, encoded, enclen); -+ buffer_put_char(&buf, ','); -+ buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, -+ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); -+ buffer_append(&buf, encoded, enclen); -+ buffer_put_char(&buf, ','); -+ buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, -+ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); -+ buffer_append(&buf, encoded, enclen); ++ if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID, ++ sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 || ++ (r = sshbuf_put(buf, encoded, enclen)) != 0 || ++ (r = sshbuf_put_u8(buf, ',')) != 0 || ++ (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, ++ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 || ++ (r = sshbuf_put(buf, encoded, enclen)) != 0 || ++ (r = sshbuf_put_u8(buf, ',')) != 0 || ++ (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID, ++ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 || ++ (r = sshbuf_put(buf, encoded, enclen)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); + gss_enc2oid[oidpos].encoded = encoded; @@ -302,17 +314,18 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + gss_enc2oid[oidpos].oid = NULL; + gss_enc2oid[oidpos].encoded = NULL; + -+ buffer_put_char(&buf, '\0'); ++ if ((r = sshbuf_put_u8(buf, '\0')) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mechs = xmalloc(buffer_len(&buf)); -+ buffer_get(&buf, mechs, buffer_len(&buf)); -+ buffer_free(&buf); ++ mechs = xmalloc(sshbuf_len(buf)); ++ sshbuf_get(buf, mechs, sshbuf_len(buf)); ++ sshbuf_free(buf); + + if (strlen(mechs) == 0) { + free(mechs); + mechs = NULL; + } -+ ++ + return (mechs); +} + @@ -350,10 +363,10 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + return gss_enc2oid[i].oid; +} + - /* Check that the OID in a data stream matches that in the context */ + /* sshbuf_get for gss_buffer_desc */ int - ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de + ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -218,7 +373,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -362,7 +375,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -228,8 +383,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -248,8 +403,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -405,7 +418,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -257,6 +446,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -423,9 +436,9 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +} + void - ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, + ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context) -@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha +@@ -273,11 +475,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co } int @@ -443,7 +456,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -264,6 +471,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -287,6 +494,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -454,7 +467,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -296,10 +507,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -523,9 +536,9 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + #endif /* GSSAPI */ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c ---- openssh/gss-serv.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/gss-serv.c 2017-09-27 13:54:53.592534359 +0200 -@@ -45,17 +45,19 @@ +--- openssh/gss-serv.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/gss-serv.c 2018-08-22 11:47:33.310216448 +0200 +@@ -44,17 +44,19 @@ #include "session.h" #include "misc.h" #include "servconf.h" @@ -548,7 +561,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -142,6 +144,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss +@@ -141,6 +143,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss } /* Unprivileged */ @@ -577,7 +590,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c void ssh_gssapi_supported_oids(gss_OID_set *oidset) { -@@ -151,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o +@@ -150,7 +174,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -588,7 +601,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -277,8 +303,48 @@ OM_uint32 +@@ -276,8 +302,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -638,7 +651,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c client->mech = NULL; -@@ -293,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -292,6 +358,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -652,7 +665,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -310,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -309,6 +382,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -661,7 +674,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -320,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -319,11 +394,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -687,7 +700,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c } } -@@ -357,7 +441,7 @@ ssh_gssapi_do_child(char ***envp, u_int +@@ -356,7 +440,7 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -696,7 +709,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c { OM_uint32 lmin; -@@ -367,9 +451,11 @@ ssh_gssapi_userok(char *user) +@@ -366,9 +450,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -710,7 +723,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -383,14 +469,89 @@ ssh_gssapi_userok(char *user) +@@ -382,14 +468,89 @@ ssh_gssapi_userok(char *user) return (0); } @@ -807,9 +820,9 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c /* Privileged */ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c ---- openssh/gss-serv-krb5.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/gss-serv-krb5.c 2017-09-27 13:54:53.593534364 +0200 -@@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +--- openssh/gss-serv-krb5.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/gss-serv-krb5.c 2018-08-22 11:47:33.311216457 +0200 +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; @@ -818,7 +831,7 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c const char *errmsg; if (client->creds == NULL) { -@@ -181,11 +181,23 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -180,11 +180,23 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl return; } @@ -846,7 +859,7 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c #ifdef USE_PAM if (options.use_pam) -@@ -194,9 +209,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -193,9 +205,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_cc_close(krb_context, ccache); @@ -923,7 +936,7 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", -@@ -204,7 +286,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { +@@ -203,7 +282,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { NULL, &ssh_gssapi_krb5_userok, NULL, @@ -934,8 +947,8 @@ diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c #endif /* KRB5 */ diff -up openssh/kex.c.gsskex openssh/kex.c ---- openssh/kex.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/kex.c 2017-09-27 13:54:53.593534364 +0200 +--- openssh/kex.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/kex.c 2018-08-22 11:47:33.311216457 +0200 @@ -54,6 +54,10 @@ #include "sshbuf.h" #include "digest.h" @@ -973,8 +986,8 @@ diff -up openssh/kex.c.gsskex openssh/kex.c return NULL; } diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c ---- openssh/kexgssc.c.gsskex 2017-09-27 13:54:53.593534364 +0200 -+++ openssh/kexgssc.c 2017-09-27 13:54:53.593534364 +0200 +--- openssh/kexgssc.c.gsskex 2018-08-22 11:47:33.311216457 +0200 ++++ openssh/kexgssc.c 2018-08-22 11:47:33.311216457 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1012,9 +1025,9 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c +#include + +#include "xmalloc.h" -+#include "buffer.h" ++#include "sshbuf.h" +#include "ssh2.h" -+#include "key.h" ++#include "sshkey.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" @@ -1250,8 +1263,8 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + case KEX_GSS_GRP14_SHA1: + kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, + ssh->kex->server_version_string, -+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), -+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), ++ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), ++ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + dh->pub_key, /* e */ + dh_server_pub, /* f */ @@ -1264,8 +1277,8 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + ssh->kex->hash_alg, + ssh->kex->client_version_string, + ssh->kex->server_version_string, -+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), -+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), ++ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), ++ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + min, nbits, max, + dh->p, dh->g, @@ -1315,8 +1328,8 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + +#endif /* GSSAPI */ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c ---- openssh/kexgsss.c.gsskex 2017-09-27 13:54:53.593534364 +0200 -+++ openssh/kexgsss.c 2017-09-27 13:54:53.593534364 +0200 +--- openssh/kexgsss.c.gsskex 2018-08-22 11:47:33.311216457 +0200 ++++ openssh/kexgsss.c 2018-08-22 11:47:33.311216457 +0200 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1352,9 +1365,9 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c +#include + +#include "xmalloc.h" -+#include "buffer.h" ++#include "sshbuf.h" +#include "ssh2.h" -+#include "key.h" ++#include "sshkey.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" @@ -1542,8 +1555,8 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + case KEX_GSS_GRP14_SHA1: + kex_dh_hash(ssh->kex->hash_alg, + ssh->kex->client_version_string, ssh->kex->server_version_string, -+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), -+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), ++ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), ++ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + NULL, 0, /* Change this if we start sending host keys */ + dh_client_pub, dh->pub_key, shared_secret, + hash, &hashlen @@ -1553,8 +1566,8 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + kexgex_hash( + ssh->kex->hash_alg, + ssh->kex->client_version_string, ssh->kex->server_version_string, -+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), -+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), ++ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), ++ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + NULL, 0, + cmin, nbits, cmax, + dh->p, dh->g, @@ -1616,9 +1629,9 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c +} +#endif /* GSSAPI */ diff -up openssh/kex.h.gsskex openssh/kex.h ---- openssh/kex.h.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/kex.h 2017-09-27 13:54:53.593534364 +0200 -@@ -99,6 +99,11 @@ enum kex_exchange { +--- openssh/kex.h.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/kex.h 2018-08-22 11:47:33.311216457 +0200 +@@ -100,6 +100,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, @@ -1630,7 +1643,7 @@ diff -up openssh/kex.h.gsskex openssh/kex.h KEX_MAX }; -@@ -147,6 +152,12 @@ struct kex { +@@ -148,6 +153,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1643,7 +1656,7 @@ diff -up openssh/kex.h.gsskex openssh/kex.h char *client_version_string; char *server_version_string; char *failed_choice; -@@ -196,6 +207,10 @@ int kexecdh_client(struct ssh *); +@@ -197,6 +208,10 @@ int kexecdh_client(struct ssh *); int kexecdh_server(struct ssh *); int kexc25519_client(struct ssh *); int kexc25519_server(struct ssh *); @@ -1655,18 +1668,18 @@ diff -up openssh/kex.h.gsskex openssh/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, diff -up openssh/Makefile.in.gsskex openssh/Makefile.in ---- openssh/Makefile.in.gsskex 2017-09-27 13:54:53.588534337 +0200 -+++ openssh/Makefile.in 2017-09-27 13:54:53.594534370 +0200 -@@ -91,6 +91,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +--- openssh/Makefile.in.gsskex 2018-08-22 11:47:33.312216465 +0200 ++++ openssh/Makefile.in 2018-08-22 13:19:54.955928277 +0200 +@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o ttymodes.o xmalloc.o addrmatch.o \ - atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ + atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o \ -@@ -112,7 +113,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ +@@ -121,7 +122,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw + auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ @@ -1675,18 +1688,18 @@ diff -up openssh/Makefile.in.gsskex openssh/Makefile.in sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff -up openssh/monitor.c.gsskex openssh/monitor.c ---- openssh/monitor.c.gsskex 2017-09-27 13:54:53.541534079 +0200 -+++ openssh/monitor.c 2017-09-27 13:54:53.594534370 +0200 -@@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer - int mm_answer_gss_accept_ctx(int, Buffer *); - int mm_answer_gss_userok(int, Buffer *); - int mm_answer_gss_checkmic(int, Buffer *); -+int mm_answer_gss_sign(int, Buffer *); -+int mm_answer_gss_updatecreds(int, Buffer *); +--- openssh/monitor.c.gsskex 2018-08-22 11:47:33.263216069 +0200 ++++ openssh/monitor.c 2018-08-22 13:22:19.589095240 +0200 +@@ -146,6 +146,8 @@ int mm_answer_gss_setup_ctx(int, struct + int mm_answer_gss_accept_ctx(int, struct sshbuf *); + int mm_answer_gss_userok(int, struct sshbuf *); + int mm_answer_gss_checkmic(int, struct sshbuf *); ++int mm_answer_gss_sign(int, struct sshbuf *); ++int mm_answer_gss_updatecreds(int, struct sshbuf *); #endif #ifdef SSH_AUDIT_EVENTS -@@ -236,11 +238,18 @@ struct mon_table mon_dispatch_proto20[] +@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -1705,7 +1718,7 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -308,6 +317,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -293,6 +302,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1716,7 +1729,7 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -414,6 +427,10 @@ monitor_child_postauth(struct monitor *p +@@ -405,6 +418,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1727,7 +1740,7 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1656,6 +1673,13 @@ monitor_apply_keystate(struct monitor *p +@@ -1695,6 +1712,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1741,25 +1754,25 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1744,7 +1768,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer - OM_uint32 major; - u_int len; +@@ -1785,7 +1809,7 @@ mm_answer_gss_setup_ctx(int sock, struct + u_char *p; + int r; - if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) fatal("%s: GSSAPI authentication not enabled", __func__); - goid.elements = buffer_get_string(m, &len); -@@ -1774,7 +1798,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe + if ((r = sshbuf_get_string(m, &p, &len)) != 0) +@@ -1818,7 +1842,7 @@ mm_answer_gss_accept_ctx(int sock, struc OM_uint32 flags = 0; /* GSI needs this */ - u_int len; + int r; - if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) fatal("%s: GSSAPI authentication not enabled", __func__); - in.value = buffer_get_string(m, &len); -@@ -1794,6 +1818,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe + if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) +@@ -1839,6 +1863,7 @@ mm_answer_gss_accept_ctx(int sock, struc monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1767,17 +1780,17 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c } return (0); } -@@ -1805,7 +1830,7 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -1850,7 +1875,7 @@ mm_answer_gss_checkmic(int sock, struct OM_uint32 ret; - u_int len; + int r; - if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) fatal("%s: GSSAPI authentication not enabled", __func__); - gssbuf.value = buffer_get_string(m, &len); -@@ -1835,10 +1860,11 @@ mm_answer_gss_userok(int sock, Buffer *m - int authenticated; + if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || +@@ -1880,10 +1905,11 @@ mm_answer_gss_userok(int sock, struct ss + int r, authenticated; const char *displayname; - if (!options.gss_authentication) @@ -1788,26 +1801,26 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw); - buffer_clear(m); - buffer_put_int(m, authenticated); -@@ -1854,5 +1880,71 @@ mm_answer_gss_userok(int sock, Buffer *m + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, authenticated)) != 0) +@@ -1900,5 +1926,74 @@ mm_answer_gss_userok(int sock, struct ss /* Monitor loop will terminate if authenticated */ return (authenticated); } + +int -+mm_answer_gss_sign(int socket, Buffer *m) ++mm_answer_gss_sign(int socket, struct sshbuf *m) +{ + gss_buffer_desc data; + gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; + OM_uint32 major, minor; -+ u_int len; ++ int r; + + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + -+ data.value = buffer_get_string(m, &len); -+ data.length = len; ++ if ((r = sshbuf_get_string(m, (u_char **)&data.value, &data.length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (data.length != 20) + fatal("%s: data length incorrect: %d", __func__, + (int) data.length); @@ -1822,9 +1835,10 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c + + free(data.value); + -+ buffer_clear(m); -+ buffer_put_int(m, major); -+ buffer_put_string(m, hash.value, hash.length); ++ sshbuf_reset(m); ++ if ((r = sshbuf_put_u32(m, major)) != 0 || ++ (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); + @@ -1840,20 +1854,22 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c +} + +int -+mm_answer_gss_updatecreds(int socket, Buffer *m) { ++mm_answer_gss_updatecreds(int socket, struct sshbuf *m) { + ssh_gssapi_ccache store; -+ int ok; ++ int ok, r; + -+ store.envvar = buffer_get_string(m, NULL); -+ store.envval = buffer_get_string(m, NULL); ++ if ((r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || ++ (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + ok = ssh_gssapi_update_creds(&store); + + free(store.envvar); + free(store.envval); + -+ buffer_clear(m); -+ buffer_put_int(m, ok); ++ sshbuf_reset(m); ++ if ((r = sshbuf_put_u32(m, ok)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); + @@ -1863,9 +1879,9 @@ diff -up openssh/monitor.c.gsskex openssh/monitor.c #endif /* GSSAPI */ diff -up openssh/monitor.h.gsskex openssh/monitor.h ---- openssh/monitor.h.gsskex 2017-09-27 13:54:53.541534079 +0200 -+++ openssh/monitor.h 2017-09-27 13:54:53.594534370 +0200 -@@ -60,6 +60,8 @@ enum monitor_reqtype { +--- openssh/monitor.h.gsskex 2018-08-22 11:47:33.263216069 +0200 ++++ openssh/monitor.h 2018-08-22 11:47:33.313216473 +0200 +@@ -58,6 +58,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, #endif @@ -1875,18 +1891,18 @@ diff -up openssh/monitor.h.gsskex openssh/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.gsskex 2017-09-27 13:54:53.542534084 +0200 -+++ openssh/monitor_wrap.c 2017-09-27 13:54:53.595534375 +0200 -@@ -950,7 +950,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +--- openssh/monitor_wrap.c.gsskex 2018-08-22 11:47:33.313216473 +0200 ++++ openssh/monitor_wrap.c 2018-08-22 13:27:38.665669643 +0200 +@@ -1004,7 +1004,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int -mm_ssh_gssapi_userok(char *user) +mm_ssh_gssapi_userok(char *user, struct passwd *pw) { - Buffer m; - int authenticated = 0; -@@ -967,5 +967,49 @@ mm_ssh_gssapi_userok(char *user) + struct sshbuf *m; + int r, authenticated = 0; +@@ -1023,4 +1023,52 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1894,21 +1910,23 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c +OM_uint32 +mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) +{ -+ Buffer m; ++ struct sshbuf *m; + OM_uint32 major; -+ u_int len; ++ int r; + -+ buffer_init(&m); -+ buffer_put_string(&m, data->value, data->length); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); + -+ major = buffer_get_int(&m); -+ hash->value = buffer_get_string(&m, &len); -+ hash->length = len; ++ if ((r = sshbuf_get_u32(m, &major)) != 0 || ++ (r = sshbuf_get_string(m, (u_char **)&hash->value, &hash->length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ buffer_free(&m); ++ sshbuf_free(m); + + return(major); +} @@ -1916,30 +1934,31 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c +int +mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) +{ -+ Buffer m; -+ int ok; ++ struct sshbuf *m; ++ int ok, r; + -+ buffer_init(&m); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); + -+ buffer_put_cstring(&m, store->envvar ? store->envvar : ""); -+ buffer_put_cstring(&m, store->envval ? store->envval : ""); ++ if ((r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || ++ (r = sshbuf_put_cstring(m, store->envval ? store->envval : "")) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); + -+ ok = buffer_get_int(&m); ++ if ((r = sshbuf_get_u32(m, &ok)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ buffer_free(&m); ++ sshbuf_free(m); + + return (ok); +} -+ #endif /* GSSAPI */ - diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.gsskex 2017-09-27 13:54:53.542534084 +0200 -+++ openssh/monitor_wrap.h 2017-09-27 13:54:53.595534375 +0200 -@@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey +--- openssh/monitor_wrap.h.gsskex 2018-08-22 11:47:33.263216069 +0200 ++++ openssh/monitor_wrap.h 2018-08-22 11:47:33.313216473 +0200 +@@ -63,8 +63,10 @@ int mm_sshkey_verify(const struct sshkey OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1952,18 +1971,18 @@ diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h #ifdef USE_PAM diff -up openssh/readconf.c.gsskex openssh/readconf.c ---- openssh/readconf.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/readconf.c 2017-09-27 13:54:53.596534381 +0200 -@@ -160,6 +160,8 @@ typedef enum { +--- openssh/readconf.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/readconf.c 2018-08-22 13:28:17.487982869 +0200 +@@ -161,6 +161,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, + oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, + oGssServerIdentity, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, - oSendEnv, oControlPath, oControlMaster, oControlPersist, + oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -199,10 +201,19 @@ static struct { +@@ -201,10 +203,19 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1983,7 +2002,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c #endif #ifdef ENABLE_PKCS11 { "smartcarddevice", oPKCS11Provider }, -@@ -976,10 +987,30 @@ parse_time: +@@ -973,10 +984,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2014,7 +2033,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1790,7 +1821,12 @@ initialize_options(Options * options) +@@ -1817,7 +1848,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2027,7 +2046,7 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1930,8 +1966,14 @@ fill_default_options(Options * options) +@@ -1962,8 +1998,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2043,9 +2062,9 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) diff -up openssh/readconf.h.gsskex openssh/readconf.h ---- openssh/readconf.h.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/readconf.h 2017-09-27 13:54:53.596534381 +0200 -@@ -42,7 +42,12 @@ typedef struct { +--- openssh/readconf.h.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/readconf.h 2018-08-22 11:47:33.314216481 +0200 +@@ -40,7 +40,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -2059,9 +2078,9 @@ diff -up openssh/readconf.h.gsskex openssh/readconf.h * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh ---- openssh/regress/cert-hostkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/regress/cert-hostkey.sh 2017-09-27 13:54:53.596534381 +0200 -@@ -59,7 +59,7 @@ touch $OBJ/host_revoked_plain +--- openssh/regress/cert-hostkey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/regress/cert-hostkey.sh 2018-08-22 11:47:33.314216481 +0200 +@@ -66,7 +66,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca @@ -2071,8 +2090,8 @@ diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh ---- openssh/regress/cert-userkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/regress/cert-userkey.sh 2017-09-27 13:54:53.596534381 +0200 +--- openssh/regress/cert-userkey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/regress/cert-userkey.sh 2018-08-22 11:47:33.314216481 +0200 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2082,10 +2101,9 @@ diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh EXTRA_TYPES="" if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then - PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh ---- openssh/regress/kextype.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/regress/kextype.sh 2017-09-27 13:54:53.596534381 +0200 +--- openssh/regress/kextype.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/regress/kextype.sh 2018-08-22 11:47:33.315216489 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2097,8 +2115,8 @@ diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh ---- openssh/regress/rekey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/regress/rekey.sh 2017-09-27 13:54:53.596534381 +0200 +--- openssh/regress/rekey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/regress/rekey.sh 2018-08-22 11:47:33.315216489 +0200 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2120,9 +2138,9 @@ diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done diff -up openssh/servconf.c.gsskex openssh/servconf.c ---- openssh/servconf.c.gsskex 2017-09-27 13:54:53.581534298 +0200 -+++ openssh/servconf.c 2017-09-27 13:54:53.597534386 +0200 -@@ -113,8 +113,10 @@ initialize_server_options(ServerOptions +--- openssh/servconf.c.gsskex 2018-08-22 11:47:33.296216335 +0200 ++++ openssh/servconf.c 2018-08-22 13:28:41.905179879 +0200 +@@ -124,8 +124,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -2133,7 +2151,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -269,10 +271,14 @@ fill_default_server_options(ServerOption +@@ -334,10 +336,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2148,16 +2166,16 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -413,7 +419,7 @@ typedef enum { +@@ -484,7 +490,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, -- sAcceptEnv, sPermitTunnel, -+ sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, sChrootDirectory, +- sAcceptEnv, sSetEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -488,11 +494,17 @@ static struct { +@@ -559,11 +565,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2175,7 +2193,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1257,6 +1269,10 @@ process_server_config_line(ServerOptions +@@ -1463,6 +1475,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2186,7 +2204,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1265,6 +1281,10 @@ process_server_config_line(ServerOptions +@@ -1471,6 +1487,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2197,7 +2215,7 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2302,6 +2322,9 @@ dump_config(ServerOptions *o) +@@ -2560,6 +2580,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2208,9 +2226,9 @@ diff -up openssh/servconf.c.gsskex openssh/servconf.c dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff -up openssh/servconf.h.gsskex openssh/servconf.h ---- openssh/servconf.h.gsskex 2017-09-27 13:54:53.582534304 +0200 -+++ openssh/servconf.h 2017-09-27 13:54:53.597534386 +0200 -@@ -119,8 +119,10 @@ typedef struct { +--- openssh/servconf.h.gsskex 2018-08-22 11:47:33.296216335 +0200 ++++ openssh/servconf.h 2018-08-22 11:47:33.316216497 +0200 +@@ -124,8 +124,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2222,9 +2240,9 @@ diff -up openssh/servconf.h.gsskex openssh/servconf.h * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 ---- openssh/ssh_config.5.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/ssh_config.5 2017-09-27 13:54:53.597534386 +0200 -@@ -720,10 +720,40 @@ The default is +--- openssh/ssh_config.5.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/ssh_config.5 2018-08-22 11:47:33.316216497 +0200 +@@ -718,10 +718,40 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -2266,8 +2284,8 @@ diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 Indicates that .Xr ssh 1 diff -up openssh/ssh_config.gsskex openssh/ssh_config ---- openssh/ssh_config.gsskex 2017-09-27 13:54:53.571534243 +0200 -+++ openssh/ssh_config 2017-09-27 13:54:53.597534386 +0200 +--- openssh/ssh_config.gsskex 2018-08-22 11:47:33.289216279 +0200 ++++ openssh/ssh_config 2018-08-22 11:47:33.316216497 +0200 @@ -24,6 +24,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -2278,8 +2296,8 @@ diff -up openssh/ssh_config.gsskex openssh/ssh_config # CheckHostIP yes # AddressFamily any diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ---- openssh/sshconnect2.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/sshconnect2.c 2017-09-27 13:57:23.418358207 +0200 +--- openssh/sshconnect2.c.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/sshconnect2.c 2018-08-22 13:33:01.674275795 +0200 @@ -82,6 +82,124 @@ extern char *client_version_string; extern char *server_version_string; extern Options options; @@ -2440,7 +2458,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -192,6 +335,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -194,6 +337,17 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2449,7 +2467,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + * 'null' hostkey, as a last resort */ + if (options.gss_keyex && gss) { + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], + "%s,null", orig); + free(gss); + } @@ -2458,7 +2476,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, options.rekey_interval); -@@ -212,11 +366,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -214,11 +368,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2490,7 +2508,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); /* remove ext-info from the KEX proposals for rekeying */ -@@ -311,6 +485,7 @@ int input_gssapi_token(int type, u_int32 +@@ -314,6 +488,7 @@ int input_gssapi_token(int type, u_int32 int input_gssapi_hash(int type, u_int32_t, struct ssh *); int input_gssapi_error(int, u_int32_t, struct ssh *); int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -2498,7 +2516,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c #endif void userauth(Authctxt *, char *); -@@ -327,6 +502,11 @@ static char *authmethods_get(void); +@@ -330,6 +505,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2510,10 +2528,10 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -654,19 +834,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -657,19 +837,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; - int ok = 0; + int r, ok = 0; + const char *gss_host; + + if (options.gss_server_identity) @@ -2537,33 +2555,22 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c while (mech < gss_supported->count && !ok) { /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && - ssh_gssapi_check_mechanism(&gssctxt, + ssh_gssapi_check_mechanism(&gssctxt, - &gss_supported->elements[mech], authctxt->host)) { + &gss_supported->elements[mech], gss_host, + options.gss_client_identity)) { ok = 1; /* Mechanism works */ } else { mech++; -@@ -763,8 +955,8 @@ input_gssapi_response(int type, u_int32_ - { - Authctxt *authctxt = ssh->authctxt; - Gssctxt *gssctxt; -- int oidlen; -- char *oidv; -+ u_int oidlen; -+ u_char *oidv; - - if (authctxt == NULL) - fatal("input_gssapi_response: no authentication context"); -@@ -877,6 +1069,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -906,6 +1098,51 @@ input_gssapi_error(int type, u_int32_t p free(lang); - return 0; + return r; } + +int +userauth_gsskeyex(Authctxt *authctxt) +{ -+ Buffer b; ++ struct sshbuf *b = NULL; + gss_buffer_desc gssbuf; + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; + OM_uint32 ms; @@ -2577,14 +2584,17 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + return (0); + } + -+ ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, ++ if ((b = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, + "gssapi-keyex"); + -+ gssbuf.value = buffer_ptr(&b); -+ gssbuf.length = buffer_len(&b); ++ gssbuf.value = sshbuf_mutable_ptr(b); ++ gssbuf.length = sshbuf_len(b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { -+ buffer_free(&b); ++ sshbuf_free(b); + return (0); + } + @@ -2595,7 +2605,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + packet_put_string(mic.value, mic.length); + packet_send(); + -+ buffer_free(&b); ++ sshbuf_free(b); + gss_release_buffer(&ms, &mic); + + return (1); @@ -2605,18 +2615,19 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c int diff -up openssh/sshd.c.gsskex openssh/sshd.c ---- openssh/sshd.c.gsskex 2017-09-27 13:54:53.584534315 +0200 -+++ openssh/sshd.c 2017-09-27 13:54:53.600534403 +0200 -@@ -530,7 +530,7 @@ privsep_preauth_child(void) +--- openssh/sshd.c.gsskex 2018-08-22 11:47:33.299216360 +0200 ++++ openssh/sshd.c 2018-08-22 13:34:28.455975954 +0200 +@@ -537,8 +537,7 @@ privsep_preauth_child(void) #ifdef GSSAPI /* Cache supported mechanism OIDs for later use */ - if (options.gss_authentication) -+ if (options.gss_authentication || options.gss_keyex) - ssh_gssapi_prepare_supported_oids(); +- ssh_gssapi_prepare_supported_oids(); ++ ssh_gssapi_prepare_supported_oids(); #endif -@@ -871,8 +871,9 @@ notify_hostkeys(struct ssh *ssh) + reseed_prngs(); +@@ -887,8 +887,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %u hostkeys", __func__, nkeys); if (nkeys == 0) @@ -2628,17 +2639,17 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c sshbuf_free(buf); } -@@ -1738,7 +1739,8 @@ main(int ac, char **av) - key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); +@@ -1841,7 +1842,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); } -@@ -2203,6 +2205,48 @@ do_ssh2_kex(void) +@@ -2321,6 +2323,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2687,7 +2698,7 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2220,6 +2264,13 @@ do_ssh2_kex(void) +@@ -2338,6 +2382,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2702,9 +2713,9 @@ diff -up openssh/sshd.c.gsskex openssh/sshd.c kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 ---- openssh/sshd_config.5.gsskex 2017-09-27 13:54:53.582534304 +0200 -+++ openssh/sshd_config.5 2017-09-27 13:54:53.600534403 +0200 -@@ -638,6 +638,11 @@ Specifies whether to automatically destr +--- openssh/sshd_config.5.gsskex 2018-08-22 11:47:33.297216344 +0200 ++++ openssh/sshd_config.5 2018-08-22 13:35:05.531275099 +0200 +@@ -642,6 +642,11 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -2716,7 +2727,7 @@ diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -652,6 +657,11 @@ machine's default store. +@@ -656,6 +661,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -2727,11 +2738,11 @@ diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 +.Dq no . .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication - as a comma-separated pattern list. + as a list of comma-separated patterns. diff -up openssh/sshd_config.gsskex openssh/sshd_config ---- openssh/sshd_config.gsskex 2017-09-27 13:54:53.585534320 +0200 -+++ openssh/sshd_config 2017-09-27 13:54:53.601534408 +0200 -@@ -86,6 +86,8 @@ ChallengeResponseAuthentication no +--- openssh/sshd_config.gsskex 2018-08-22 11:47:33.299216360 +0200 ++++ openssh/sshd_config 2018-08-22 11:47:33.318216513 +0200 +@@ -85,6 +85,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes GSSAPICleanupCredentials no @@ -2741,10 +2752,10 @@ diff -up openssh/sshd_config.gsskex openssh/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/ssh-gss.h.gsskex openssh/ssh-gss.h ---- openssh/ssh-gss.h.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/ssh-gss.h 2017-09-27 13:54:53.601534408 +0200 +--- openssh/ssh-gss.h.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/ssh-gss.h 2018-08-22 13:36:44.773075793 +0200 @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.12 2017/06/24 06:34:38 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2807,10 +2818,10 @@ diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -119,17 +136,33 @@ void ssh_gssapi_build_ctx(Gssctxt **); - void ssh_gssapi_delete_ctx(Gssctxt **); +@@ -123,17 +140,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); + void ssh_gssapi_buildmic(struct sshbuf *, const char *, + const char *, const char *); -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); @@ -2844,24 +2855,51 @@ diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h #endif /* _SSH_GSS_H */ diff -up openssh/sshkey.c.gsskex openssh/sshkey.c ---- openssh/sshkey.c.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/sshkey.c 2017-09-27 13:54:53.601534408 +0200 -@@ -112,6 +112,7 @@ static const struct keytype keytypes[] = +--- openssh/sshkey.c.gsskex 2018-08-22 11:47:33.319216521 +0200 ++++ openssh/sshkey.c 2018-08-22 13:37:18.979351804 +0200 +@@ -140,6 +140,7 @@ static const struct keytype keytypes[] = # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ -+ { "null", "null", KEY_NULL, 0, 0, 1 }, - { NULL, NULL, -1, -1, 0, 0 } ++ { "null", "null", NULL, KEY_NULL, 0, 0, 1 }, + { NULL, NULL, NULL, -1, -1, 0, 0 } }; diff -up openssh/sshkey.h.gsskex openssh/sshkey.h ---- openssh/sshkey.h.gsskex 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/sshkey.h 2017-09-27 13:54:53.602534414 +0200 -@@ -61,6 +61,7 @@ enum sshkey_types { +--- openssh/sshkey.h.gsskex 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/sshkey.h 2018-08-22 11:47:33.320216529 +0200 +@@ -63,6 +63,7 @@ enum sshkey_types { KEY_ED25519_CERT, KEY_XMSS, KEY_XMSS_CERT, + KEY_NULL, KEY_UNSPEC }; + +--- openssh/sshconnect2.c.orig 2017-01-04 19:47:10.000000000 +0100 ++++ openssh/sshconnect2.c 2017-01-05 04:13:08.977425272 +0100 +@@ -344,7 +344,6 @@ + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], + "%s,null", orig); +- free(gss); + } + #endif + +@@ -398,6 +397,16 @@ + /* remove ext-info from the KEX proposals for rekeying */ + myproposal[PROPOSAL_KEX_ALGS] = + compat_kex_proposal(options.kex_algorithms); ++#ifdef GSSAPI ++ /* repair myproposal after it was crumpled by the */ ++ /* ext-info removal above */ ++ if (gss) { ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ free(gss); ++ } ++#endif + if ((r = kex_prop2buf(kex->my, myproposal)) != 0) + fatal("kex_prop2buf: %s", ssh_err(r)); diff --git a/openssh-7.8p1-ip-port-config-parser.patch b/openssh-7.8p1-ip-port-config-parser.patch new file mode 100644 index 0000000..6ca0cf5 --- /dev/null +++ b/openssh-7.8p1-ip-port-config-parser.patch @@ -0,0 +1,72 @@ +diff -up openssh/misc.c.config openssh/misc.c +--- openssh/misc.c.config 2018-08-22 13:58:54.922807799 +0200 ++++ openssh/misc.c 2018-08-22 13:58:55.000808428 +0200 +@@ -485,7 +485,7 @@ put_host_port(const char *host, u_short + * The delimiter char, if present, is stored in delim. + * If this is the last field, *cp is set to NULL. + */ +-static char * ++char * + hpdelim2(char **cp, char *delim) + { + char *s, *old; +diff -up openssh/misc.h.config openssh/misc.h +--- openssh/misc.h.config 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/misc.h 2018-08-22 13:58:55.001808436 +0200 +@@ -54,6 +54,7 @@ int set_rdomain(int, const char *); + int a2port(const char *); + int a2tun(const char *, int *); + char *put_host_port(const char *, u_short); ++char *hpdelim2(char **, char *); + char *hpdelim(char **); + char *cleanhostname(char *); + char *colon(char *); +diff -up openssh/servconf.c.config openssh/servconf.c +--- openssh/servconf.c.config 2018-08-22 13:58:54.989808340 +0200 ++++ openssh/servconf.c 2018-08-22 14:18:49.235443937 +0200 +@@ -886,7 +886,7 @@ process_permitopen_list(struct ssh *ssh, + { + u_int i; + int port; +- char *host, *arg, *oarg; ++ char *host, *arg, *oarg, ch; + int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; + const char *what = lookup_opcode_name(opcode); + +@@ -904,8 +904,8 @@ process_permitopen_list(struct ssh *ssh, + /* Otherwise treat it as a list of permitted host:port */ + for (i = 0; i < num_opens; i++) { + oarg = arg = xstrdup(opens[i]); +- host = hpdelim(&arg); +- if (host == NULL) ++ host = hpdelim2(&arg, &ch); ++ if (host == NULL || ch == '/') + fatal("%s: missing host in %s", __func__, what); + host = cleanhostname(host); + if (arg == NULL || ((port = permitopen_port(arg)) < 0)) +@@ -1323,8 +1323,10 @@ process_server_config_line(ServerOptions + port = 0; + p = arg; + } else { +- p = hpdelim(&arg); +- if (p == NULL) ++ char ch; ++ arg2 = NULL; ++ p = hpdelim2(&arg, &ch); ++ if (p == NULL || ch == '/') + fatal("%s line %d: bad address:port usage", + filename, linenum); + p = cleanhostname(p); +@@ -1965,9 +1967,10 @@ process_server_config_line(ServerOptions + */ + xasprintf(&arg2, "*:%s", arg); + } else { ++ char ch; + arg2 = xstrdup(arg); +- p = hpdelim(&arg); +- if (p == NULL) { ++ p = hpdelim2(&arg, &ch); ++ if (p == NULL || ch == '/') { + fatal("%s line %d: missing host in %s", + filename, linenum, + lookup_opcode_name(opcode)); diff --git a/openssh-6.6p1-role-mls.patch b/openssh-7.8p1-role-mls.patch similarity index 72% rename from openssh-6.6p1-role-mls.patch rename to openssh-7.8p1-role-mls.patch index 37ae70d..4c58d71 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 12:19:58.587459379 +0100 -@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 +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, *service, *method, *style = NULL; @@ -9,9 +9,9 @@ diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c + char *role = NULL; +#endif int authenticated = 0; + double tstart = monotime_double(); - if (authctxt == NULL) -@@ -226,6 +229,11 @@ input_userauth_request(int type, u_int32 +@@ -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); @@ -23,7 +23,7 @@ diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 +@@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -40,49 +40,48 @@ diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); -diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1/auth2-gss.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth2-gss.c 2016-12-23 12:19:58.586459382 +0100 -@@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple +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 authenticated = 0; + int r, authenticated = 0; + char *micuser; - Buffer b; + struct sshbuf *b; gss_buffer_desc mic, gssbuf; - u_int len; -@@ -267,7 +268,13 @@ input_gssapi_mic(int type, u_int32_t ple - mic.value = packet_get_string(&len); + 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, +- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, +#ifdef WITH_SELINUX + if (authctxt->role && (strlen(authctxt->role) > 0)) + xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); + else +#endif + micuser = authctxt->user; -+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, ++ ssh_gssapi_buildmic(b, micuser, authctxt->service, "gssapi-with-mic"); - gssbuf.value = buffer_ptr(&b); -@@ -279,6 +286,8 @@ input_gssapi_mic(int type, u_int32_t ple + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) +@@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple logit("GSSAPI MIC check failed"); - buffer_free(&b); + sshbuf_free(b); + if (micuser != authctxt->user) + free(micuser); free(mic.value); if ((!use_privsep || mm_is_monitor()) && -diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased.c ---- openssh-7.4p1/auth2-hostbased.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 12:19:58.586459382 +0100 -@@ -121,7 +121,16 @@ userauth_hostbased(Authctxt *authctxt) +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_string(b, session_id2, session_id2_len)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || -- (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#ifdef WITH_SELINUX + (authctxt->role + ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 || @@ -91,16 +90,16 @@ diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased. + (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0) + : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) || +#else -+ (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || (r = sshbuf_put_cstring(b, "hostbased")) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || -diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c ---- openssh-7.4p1/auth2-pubkey.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 12:19:58.587459379 +0100 -@@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) - __func__, ssh_err(r)); +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 */ - xasprintf(&userstyle, "%s%s%s", authctxt->user, @@ -110,17 +109,18 @@ diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c + authctxt->style ? authctxt->style : "", +#ifdef WITH_SELINUX + authctxt->role ? "/" : "", -+ authctxt->role ? authctxt->role : ""); ++ authctxt->role ? authctxt->role : "" +#else -+ "", ""); ++ "", "" +#endif ++ ); if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || -diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h ---- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth.h 2016-12-23 12:19:43.478510375 +0100 -@@ -62,6 +62,9 @@ struct Authctxt { +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; @@ -130,10 +130,10 @@ diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h /* Method lists for multiple authentication */ char **auth_methods; /* modified from server config */ -diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c ---- openssh-7.4p1/auth-pam.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth-pam.c 2016-12-23 12:19:43.477510378 +0100 -@@ -1087,7 +1087,7 @@ is_pam_session_open(void) +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 @@ -142,10 +142,10 @@ diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c { int ret = 1; #ifdef HAVE_PAM_PUTENV -diff -up openssh-7.4p1/auth-pam.h.role-mls openssh-7.4p1/auth-pam.h ---- openssh-7.4p1/auth-pam.h.role-mls 2016-12-23 12:19:43.478510375 +0100 -+++ openssh-7.4p1/auth-pam.h 2016-12-23 12:21:44.698101234 +0100 -@@ -31,7 +31,7 @@ u_int do_pam_account(void); +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); @@ -154,10 +154,24 @@ diff -up openssh-7.4p1/auth-pam.h.role-mls openssh-7.4p1/auth-pam.h char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh-7.4p1/misc.c.role-mls openssh-7.4p1/misc.c ---- openssh-7.4p1/misc.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/misc.c 2016-12-23 12:19:58.587459379 +0100 -@@ -432,6 +432,7 @@ char * +diff -up openssh/configure.ac.role-mls openssh/configure.ac +--- openssh/configure.ac.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/configure.ac 2018-08-22 11:14:56.820430957 +0200 +@@ -4241,10 +4241,7 @@ AC_ARG_WITH([selinux], + LIBS="$LIBS -lselinux" + ], + AC_MSG_ERROR([SELinux support requires libselinux library])) +- SSHLIBS="$SSHLIBS $LIBSELINUX" +- SSHDLIBS="$SSHDLIBS $LIBSELINUX" + AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) +- LIBS="$save_LIBS" + fi ] + ) + AC_SUBST([SSHLIBS]) +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; @@ -165,7 +179,7 @@ diff -up openssh-7.4p1/misc.c.role-mls openssh-7.4p1/misc.c if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -447,6 +448,13 @@ colon(char *cp) +@@ -557,6 +558,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -179,20 +193,20 @@ diff -up openssh-7.4p1/misc.c.role-mls openssh-7.4p1/misc.c } return NULL; } -diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 12:23:03.503835248 +0100 -@@ -127,6 +127,9 @@ int mm_answer_sign(int, Buffer *); - int mm_answer_pwnamallow(int, Buffer *); - int mm_answer_auth2_read_banner(int, Buffer *); - int mm_answer_authserv(int, Buffer *); +diff -up openssh/monitor.c.role-mls openssh/monitor.c +--- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200 +@@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *) + int mm_answer_pwnamallow(int, struct sshbuf *); + int mm_answer_auth2_read_banner(int, struct sshbuf *); + int mm_answer_authserv(int, struct sshbuf *); +#ifdef WITH_SELINUX -+int mm_answer_authrole(int, Buffer *); ++int mm_answer_authrole(int, struct sshbuf *); +#endif - int mm_answer_authpassword(int, Buffer *); - int mm_answer_bsdauthquery(int, Buffer *); - int mm_answer_bsdauthrespond(int, Buffer *); -@@ -202,6 +205,9 @@ struct mon_table mon_dispatch_proto20[] + int mm_answer_authpassword(int, struct sshbuf *); + int mm_answer_bsdauthquery(int, struct sshbuf *); + int mm_answer_bsdauthrespond(int, struct sshbuf *); +@@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, @@ -202,7 +216,7 @@ diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -769,6 +775,9 @@ mm_answer_pwnamallow(int sock, Buffer *m +@@ -796,6 +802,9 @@ mm_answer_pwnamallow(int sock, struct ss /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -212,19 +226,20 @@ diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -810,6 +819,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb return (0); } +#ifdef WITH_SELINUX +int -+mm_answer_authrole(int sock, Buffer *m) ++mm_answer_authrole(int sock, struct sshbuf *m) +{ ++ int r; + monitor_permit_authentications(1); + -+ authctxt->role = buffer_get_string(m, NULL); -+ debug3("%s: role=%s", -+ __func__, authctxt->role); ++ if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ debug3("%s: role=%s", __func__, authctxt->role); + + if (strlen(authctxt->role) == 0) { + free(authctxt->role); @@ -236,48 +251,48 @@ diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c +#endif + int - mm_answer_authpassword(int sock, Buffer *m) + mm_answer_authpassword(int sock, struct sshbuf *m) { -@@ -1208,7 +1236,7 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i { - Buffer b; - u_char *p; + struct sshbuf *b; + const u_char *p; - char *userstyle, *cp; -+ char *userstyle, *r, *cp; - u_int len; - int fail = 0; - -@@ -1234,6 +1262,8 @@ monitor_valid_userblob(u_char *data, u_i - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) ++ char *userstyle, *s, *cp; + size_t len; + u_char type; + int r, fail = 0; +@@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i fail++; - cp = buffer_get_cstring(&b, NULL); -+ if ((r = strchr(cp, '/')) != NULL) -+ *r = '\0'; + if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) + 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 : ""); -@@ -1269,7 +1299,7 @@ monitor_valid_hostbasedblob(u_char *data - char *chost) +@@ -1286,7 +1317,7 @@ monitor_valid_hostbasedblob(u_char *data { - Buffer b; -- char *p, *userstyle; -+ char *p, *r, *userstyle; - u_int len; - int fail = 0; - -@@ -1286,6 +1316,8 @@ monitor_valid_hostbasedblob(u_char *data - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + struct sshbuf *b; + const u_char *p; +- char *cp, *userstyle; ++ char *cp, *s, *userstyle; + size_t len; + int r, fail = 0; + u_char type; +@@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data fail++; - p = buffer_get_cstring(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; + if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ if ((s = strchr(p, '/')) != NULL) ++ *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh-7.4p1/monitor.h.role-mls openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 12:19:58.588459376 +0100 -@@ -57,6 +57,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, @@ -288,11 +303,11 @@ diff -up openssh-7.4p1/monitor.h.role-mls openssh-7.4p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff -up openssh-7.4p1/monitor_wrap.c.role-mls openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 12:19:58.588459376 +0100 -@@ -345,6 +345,25 @@ mm_inform_authserv(char *service, char * - buffer_free(&m); +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); } +/* Inform the privileged process about role */ @@ -301,28 +316,30 @@ diff -up openssh-7.4p1/monitor_wrap.c.role-mls openssh-7.4p1/monitor_wrap.c +void +mm_inform_authrole(char *role) +{ -+ Buffer m; ++ int r; ++ struct sshbuf *m; + + debug3("%s entering", __func__); + -+ buffer_init(&m); -+ buffer_put_cstring(&m, role ? role : ""); ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m); + -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); -+ -+ buffer_free(&m); ++ sshbuf_free(m); +} +#endif + /* Do the password authentication */ int mm_auth_password(struct ssh *ssh, char *password) -diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 -@@ -42,6 +42,9 @@ int mm_is_monitor(void); - int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, - const char *); +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); + int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, + const char *, u_int compat); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -330,10 +347,10 @@ diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); -diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd-compat/Makefile.in ---- openssh-7.4p1/openbsd-compat/Makefile.in.role-mls 2016-12-23 12:19:58.588459376 +0100 -+++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 12:24:06.042643938 +0100 -@@ -20,7 +20,8 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf +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 \ @@ -343,10 +360,10 @@ diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-7.4p1/openbsd-compat/port-linux.c.role-mls openssh-7.4p1/openbsd-compat/port-linux.c ---- openssh-7.4p1/openbsd-compat/port-linux.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.c 2016-12-23 12:19:58.590459369 +0100 -@@ -101,37 +101,6 @@ ssh_selinux_getctxbyname(char *pwname) +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; } @@ -397,9 +414,9 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux.c.role-mls openssh-7.4p1/openbs /* XXX: should these calls fatal() upon failure in enforcing mode? */ -diff -up openssh-7.4p1/openbsd-compat/port-linux.h.role-mls openssh-7.4p1/openbsd-compat/port-linux.h ---- openssh-7.4p1/openbsd-compat/port-linux.h.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 12:19:58.591459365 +0100 +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); @@ -412,10 +429,10 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux.h.role-mls openssh-7.4p1/openbs #endif #ifdef LINUX_OOM_ADJUST -diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-7.4p1/openbsd-compat/port-linux-sshd.c ---- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls 2016-12-23 12:19:58.590459369 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2016-12-23 12:19:58.590459369 +0100 -@@ -0,0 +1,424 @@ +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 + * Copyright (c) 2014 Petr Lautrbach @@ -444,13 +461,14 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-7.4p1/o +#include +#include +#include ++#include + +#include "log.h" +#include "xmalloc.h" +#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#include "servconf.h" +#include "port-linux.h" -+#include "key.h" ++#include "sshkey.h" +#include "hostfile.h" +#include "auth.h" + @@ -840,10 +858,10 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-7.4p1/o +#endif +#endif + -diff -up openssh-7.4p1/platform.c.role-mls openssh-7.4p1/platform.c ---- openssh-7.4p1/platform.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/platform.c 2016-12-23 12:19:58.591459365 +0100 -@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(stru +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 @@ -852,10 +870,10 @@ diff -up openssh-7.4p1/platform.c.role-mls openssh-7.4p1/platform.c #endif } -diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.role-mls 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 12:19:58.591459365 +0100 -@@ -2053,6 +2053,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 @@ -865,16 +883,3 @@ diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(1); ---- openssh/configure.ac.role-mls 2017-09-27 12:54:52.926425979 +0200 -+++ openssh/configure.ac 2017-09-27 12:57:06.854224956 +0200 -@@ -4158,10 +4158,7 @@ - LIBS="$LIBS -lselinux" - ], - AC_MSG_ERROR([SELinux support requires libselinux library])) -- SSHLIBS="$SSHLIBS $LIBSELINUX" -- SSHDLIBS="$SSHDLIBS $LIBSELINUX" - AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) -- LIBS="$save_LIBS" - fi ] - ) - AC_SUBST([SSHLIBS]) diff --git a/openssh-7.8p1-scp-ipv6.patch b/openssh-7.8p1-scp-ipv6.patch new file mode 100644 index 0000000..8ae0948 --- /dev/null +++ b/openssh-7.8p1-scp-ipv6.patch @@ -0,0 +1,16 @@ +diff --git a/scp.c b/scp.c +index 60682c68..9344806e 100644 +--- a/scp.c ++++ b/scp.c +@@ -714,7 +714,9 @@ toremote(int argc, char **argv) + addargs(&alist, "%s", host); + addargs(&alist, "%s", cmd); + addargs(&alist, "%s", src); +- addargs(&alist, "%s%s%s:%s", ++ addargs(&alist, ++ /* IPv6 address needs to be enclosed with sqare brackets */ ++ strchr(host, ':') != NULL ? "%s%s[%s]:%s" : "%s%s%s:%s", + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + if (do_local_cmd(&alist) != 0) + diff --git a/sources b/sources index 391466e..c629991 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-7.7p1.tar.gz) = 597252cb48209a0cb98ca1928a67e8d63e4275252f25bc37269204c108f034baade6ba0634e32ae63422fddd280f73096a6b31ad2f2e7a848dde75ca30e14261 -SHA512 (openssh-7.7p1.tar.gz.asc) = 9445a589a84538fb0b4eae0f7bf6ce46def51b09254d6fffcc6ed64472f10ccf9e4d5d200387725043039d77ca886e2c8e8f3128e7969c582156fafb0783988d +SHA512 (openssh-7.8p1.tar.gz) = 8e5b0c8682a9243e4e8b7c374ec989dccd1a752eb6f84e593b67141e8b23dcc8b9a7322b1f7525d18e2ce8830a767d0d9793f997486339db201a57986b910705 +SHA512 (openssh-7.8p1.tar.gz.asc) = 3a7bef84df3c07aa78965a11a6bbd6ca6e5d1e9265ac08871b3e5d304646be651b74f5302a195e86a56e6a83b19d79292e5599c9a9cf6f003a513d4354e8ad2f SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From afffcadde38fdb7f59826a4c3a230b04c3a1a6d9 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 24 Oct 2018 23:45:22 +0200 Subject: [PATCH 062/146] Based on openssh-7.9p1-1.fc29 --- gsi-openssh.spec | 15 +- openssh-6.6.1p1-selinux-contexts.patch | 8 - openssh-6.6p1-GSSAPIEnablek5users.patch | 4 +- openssh-6.6p1-ctr-cavstest.patch | 2 +- openssh-6.6p1-force_krb.patch | 4 +- openssh-6.6p1-kuserok.patch | 18 +- openssh-7.0p1-gssKexAlgorithms.patch | 6 +- openssh-7.3p1-openssl-1.1.0.patch | 2677 ----------------- openssh-7.5p1-sandbox.patch | 4 +- openssh-7.6p1-audit.patch | 28 +- openssh-7.6p1-pkcs11-ecdsa.patch | 199 +- openssh-7.6p1-pkcs11-uri.patch | 2400 ++++++++------- openssh-7.7p1-fips.patch | 40 +- openssh-7.7p1-gssapi-new-unique.patch | 44 +- openssh-7.8p1-gsskex.patch | 64 +- ...gsissh.patch => openssh-7.9p1-gsissh.patch | 462 ++- openssh-7.9p1-gsskex-method.patch | 150 + sources | 4 +- 18 files changed, 1754 insertions(+), 4375 deletions(-) delete mode 100644 openssh-7.3p1-openssl-1.1.0.patch rename openssh-7.8p1-gsissh.patch => openssh-7.9p1-gsissh.patch (88%) create mode 100644 openssh-7.9p1-gsskex-method.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index c76558b..8e80526 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,7 +30,7 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.8p1 +%global openssh_ver 7.9p1 %global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication @@ -59,8 +59,6 @@ Patch100: openssh-6.7p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 #https://bugzilla.redhat.com/show_bug.cgi?id=735889 #Patch102: openssh-5.8p1-getaddrinfo.patch -# OpenSSL 1.1.0 compatibility -Patch104: openssh-7.3p1-openssl-1.1.0.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 @@ -127,6 +125,8 @@ Patch804: openssh-7.7p1-gssapi-new-unique.patch Patch805: openssh-7.2p2-k5login_directory.patch # Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02 Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch +# Do not break when using AuthenticationMethods with gssapi-keyex auth method (#1625366) +Patch808: openssh-7.9p1-gsskex-method.patch Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 @@ -168,7 +168,7 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-7.8p1-gsissh.patch +Patch98: openssh-7.9p1-gsissh.patch License: BSD Group: Applications/Internet @@ -323,13 +323,13 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch951 -p1 -b .pkcs11-uri %patch952 -p1 -b .pkcs11-ecdsa %patch953 -p1 -b .scp-ipv6 +%patch808 -p1 -b .gsskex-method %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race %patch700 -p1 -b .fips %patch100 -p1 -b .coverity -%patch104 -p1 -b .openssl %patch98 -p1 -b .gsi @@ -375,7 +375,7 @@ fi --sysconfdir=%{_sysconfdir}/gsissh \ --libexecdir=%{_libexecdir}/gsissh \ --datadir=%{_datadir}/gsissh \ - --with-default-path=/usr/local/bin:/usr/bin \ + --with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/gsisshd \ --enable-vendor-patchlevel="FC-%{openssh_ver}-%{openssh_rel}" \ @@ -535,6 +535,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Oct 23 2018 Mattias Ellert - 7.9p1-1 +- Based on openssh-7.9p1-1.fc29 + * Tue Oct 23 2018 Mattias Ellert - 7.8p1-1 - Based on openssh-7.8p1-3.fc28 diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 8bf6c78..f26f343 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -82,14 +82,6 @@ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 22ea8ef..1fc963d 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include "log.h" - #include "xmalloc.h" @@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) strlcpy(newctx + len, newname, newlen - len); if ((cx = index(cx + 1, ':'))) diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 37e010d..c33bdac 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -83,7 +83,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c M_CP_INTOPT(log_level); @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) # endif - dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); + dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); #endif @@ -93,7 +93,7 @@ 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_ticket; /* If true, the aquired ticket will + int kerberos_unique_ccache; /* If true, the acquired ticket will * be stored in per-session ccache */ int use_kuserok; + int enable_k5users; diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index c56313d..2e31fbf 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -187,7 +187,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c + usage(); + } + -+ SSLeay_add_all_algorithms(); ++ OpenSSL_add_all_algorithms(); + + c = cipher_by_name(algo); + if (c == NULL) { diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch index aeee77f..90f8322 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -235,9 +235,9 @@ index 28659ec..9c94d8e 100644 +#endif +#endif + + s->forced = 0; if (forced != NULL) { - if (IS_INTERNAL_SFTP(command)) { - s->is_subsystem = s->is_subsystem ? + s->forced = 1; diff --git a/ssh-gss.h b/ssh-gss.h index 0374c88..509109a 100644 --- a/ssh-gss.h diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 81ec2a4..4b681ff 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -196,22 +196,22 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, sKerberosUniqueTicket, -+ sKerberosGetAFSToken, sKerberosUniqueTicket, sKerberosUseKuserok, +- sKerberosGetAFSToken, sKerberosUniqueCCache, ++ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, @@ -478,12 +481,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif - { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL }, + { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, + { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, #else { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -238,7 +238,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif - dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); + dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); #endif #ifdef GSSAPI @@ -248,7 +248,7 @@ diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h +++ 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_ticket; /* If true, the aquired ticket will + int kerberos_unique_ccache; /* If true, the acquired ticket will * be stored in per-session ccache */ + int use_kuserok; int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -258,9 +258,9 @@ 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 - tickets aquired in different sessions of the same user. - The default is - .Cm no . + .Cm no + can lead to overwriting previous tickets by subseqent connections to the same + user account. +.It Cm KerberosUseKuserok +Specifies whether to look at .k5login file for user's aliases. +The default is diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 2ba360e..1497049 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -29,14 +29,14 @@ diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c @@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup char deroid[2]; const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX md; + EVP_MD_CTX *md; + char *s, *cp, *p; if (gss_enc2oid != NULL) { for (i = 0; gss_enc2oid[i].encoded != NULL; i++) @@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - fatal("%s: sshbuf_new failed", __func__); + md = EVP_MD_CTX_new(); oidpos = 0; + s = cp = xstrdup(kex); for (i = 0; i < gss_supported->count; i++) { @@ -81,9 +81,9 @@ diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c } } + free(s); + EVP_MD_CTX_free(md); gss_enc2oid[oidpos].oid = NULL; gss_enc2oid[oidpos].encoded = NULL; - diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c --- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 +++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200 diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch deleted file mode 100644 index 5c18666..0000000 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ /dev/null @@ -1,2677 +0,0 @@ -diff -up openssh/auth-pam.c.openssl openssh/auth-pam.c ---- openssh/auth-pam.c.openssl 2017-09-26 13:19:31.662248869 +0200 -+++ openssh/auth-pam.c 2017-09-26 13:19:31.793249672 +0200 -@@ -128,6 +128,10 @@ extern u_int utmp_len; - typedef pthread_t sp_pthread_t; - #else - typedef pid_t sp_pthread_t; -+# define pthread_create(a, b, c, d) _ssh_compat_pthread_create(a, b, c, d) -+# define pthread_exit(a) _ssh_compat_pthread_exit(a) -+# define pthread_cancel(a) _ssh_compat_pthread_cancel(a) -+# define pthread_join(a, b) _ssh_compat_pthread_join(a, b) - #endif - - struct pam_ctxt { -diff -up openssh/cipher.c.openssl openssh/cipher.c ---- openssh/cipher.c.openssl 2017-09-26 13:19:31.782249605 +0200 -+++ openssh/cipher.c 2017-09-26 13:27:37.424040367 +0200 -@@ -283,7 +283,7 @@ cipher_init(struct sshcipher_ctx **ccp, - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, -+ if (EVP_CipherInit(cc->evp, type, (u_char *)key, (u_char *)iv, - (do_encrypt == CIPHER_ENCRYPT)) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; -@@ -301,10 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, - goto out; - } - } -- if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { -- ret = SSH_ERR_LIBCRYPTO_ERROR; -- goto out; -- } - ret = 0; - #endif /* WITH_OPENSSL */ - out: -@@ -490,7 +486,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c - len, iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(iv, cc->evp->iv, len); -+ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); - #endif - return 0; - } -@@ -524,14 +520,14 @@ cipher_set_keyiv(struct sshcipher_ctx *c - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(cc->evp->iv, iv, evplen); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); - #endif - return 0; - } - - #ifdef WITH_OPENSSL --#define EVP_X_STATE(evp) (evp)->cipher_data --#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size -+#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp) -+#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp)) - #endif - - int -diff -up openssh/ctr-cavstest.c.openssl openssh/ctr-cavstest.c ---- openssh/ctr-cavstest.c.openssl 2017-09-26 13:19:31.707249145 +0200 -+++ openssh/ctr-cavstest.c 2017-09-26 13:19:31.794249679 +0200 -@@ -144,7 +144,7 @@ int main (int argc, char *argv[]) - usage(); - } - -- SSLeay_add_all_algorithms(); -+ OpenSSL_add_all_algorithms(); - - c = cipher_by_name(algo); - if (c == NULL) { -diff -up openssh/dh.c.openssl openssh/dh.c ---- openssh/dh.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/dh.c 2017-09-26 13:19:31.794249679 +0200 -@@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max - /* diffie-hellman-groupN-sha1 */ - - int --dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) -+dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) - { - int i; - int n = BN_num_bits(dh_pub); - int bits_set = 0; - BIGNUM *tmp; -+ const BIGNUM *p; - -- if (dh_pub->neg) { -+ if (BN_is_negative(dh_pub)) { - logit("invalid public DH value: negative"); - return 0; - } -@@ -232,7 +233,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) - error("%s: BN_new failed", __func__); - return 0; - } -- if (!BN_sub(tmp, dh->p, BN_value_one()) || -+ DH_get0_pqg(dh, &p, NULL, NULL); -+ if (!BN_sub(tmp, p, BN_value_one()) || - BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ - BN_clear_free(tmp); - logit("invalid public DH value: >= p-1"); -@@ -243,14 +245,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) - for (i = 0; i <= n; i++) - if (BN_is_bit_set(dh_pub, i)) - bits_set++; -- debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); -+ debug2("bits set: %d/%d", bits_set, BN_num_bits(p)); - - /* - * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial - */ - if (bits_set < 4) { - logit("invalid public DH value (%d/%d)", -- bits_set, BN_num_bits(dh->p)); -+ bits_set, BN_num_bits(p)); - return 0; - } - return 1; -@@ -260,9 +262,11 @@ int - dh_gen_key(DH *dh, int need) - { - int pbits; -+ const BIGNUM *p, *pub_key; - -- if (need < 0 || dh->p == NULL || -- (pbits = BN_num_bits(dh->p)) <= 0 || -+ DH_get0_pqg(dh, &p, NULL, NULL); -+ if (need < 0 || p == NULL || -+ (pbits = BN_num_bits(p)) <= 0 || - need > INT_MAX / 2 || 2 * need > pbits) - return SSH_ERR_INVALID_ARGUMENT; - if (need < 256) -@@ -271,11 +275,11 @@ dh_gen_key(DH *dh, int need) - * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), - * so double requested need here. - */ -- dh->length = MINIMUM(need * 2, pbits - 1); -- if (DH_generate_key(dh) == 0 || -- !dh_pub_is_valid(dh, dh->pub_key)) { -- BN_clear_free(dh->priv_key); -- dh->priv_key = NULL; -+ DH_set_length(dh, MINIMUM(need * 2, pbits - 1)); -+ 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_LIBCRYPTO_ERROR; - } - return 0; -@@ -284,15 +289,22 @@ DH * - dh_new_group_asc(const char *gen, const char *modulus) - { - DH *dh; -+ BIGNUM *p = NULL, *g = NULL; - -- if ((dh = DH_new()) == NULL) -- return NULL; -- if (BN_hex2bn(&dh->p, modulus) == 0 || -- BN_hex2bn(&dh->g, gen) == 0) { -- DH_free(dh); -- return NULL; -- } -+ if ((dh = DH_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (g = BN_new()) == NULL) -+ goto err; -+ if (BN_hex2bn(&p, modulus) == 0 || -+ BN_hex2bn(&g, gen) == 0 || -+ DH_set0_pqg(dh, p, NULL, g) == 0) -+ goto err; - return (dh); -+err: -+ DH_free(dh); -+ BN_free(p); -+ BN_free(g); -+ return NULL; - } - - /* -@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu - - if ((dh = DH_new()) == NULL) - return NULL; -- dh->p = modulus; -- dh->g = gen; -+ DH_set0_pqg(dh, modulus, NULL, gen); - - return (dh); - } -diff -up openssh/dh.h.openssl openssh/dh.h ---- openssh/dh.h.openssl 2017-09-26 13:19:31.783249611 +0200 -+++ openssh/dh.h 2017-09-26 13:19:31.794249679 +0200 -@@ -42,7 +42,7 @@ DH *dh_new_group18(void); - DH *dh_new_group_fallback(int); - - int dh_gen_key(DH *, int); --int dh_pub_is_valid(DH *, BIGNUM *); -+int dh_pub_is_valid(const DH *, const BIGNUM *); - - u_int dh_estimate(int); - -diff -up openssh/digest-openssl.c.openssl openssh/digest-openssl.c ---- openssh/digest-openssl.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/digest-openssl.c 2017-09-26 13:19:31.795249685 +0200 -@@ -43,7 +43,7 @@ - - struct ssh_digest_ctx { - int alg; -- EVP_MD_CTX mdctx; -+ EVP_MD_CTX *mdctx; - }; - - struct ssh_digest { -@@ -106,7 +106,7 @@ ssh_digest_bytes(int alg) - size_t - ssh_digest_blocksize(struct ssh_digest_ctx *ctx) - { -- return EVP_MD_CTX_block_size(&ctx->mdctx); -+ return EVP_MD_CTX_block_size(ctx->mdctx); - } - - struct ssh_digest_ctx * -@@ -118,8 +118,10 @@ ssh_digest_start(int alg) - if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) - return NULL; - ret->alg = alg; -- EVP_MD_CTX_init(&ret->mdctx); -- if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { -+ ret->mdctx = EVP_MD_CTX_new(); -+ if (ret->mdctx == NULL || -+ EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) { -+ EVP_MD_CTX_free(ret->mdctx); - free(ret); - return NULL; - } -@@ -132,7 +133,7 @@ ssh_digest_copy_state(struct ssh_digest_ - if (from->alg != to->alg) - return SSH_ERR_INVALID_ARGUMENT; - /* we have bcopy-style order while openssl has memcpy-style */ -- if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) -+ if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx)) - return SSH_ERR_LIBCRYPTO_ERROR; - return 0; - } -@@ -140,7 +141,7 @@ ssh_digest_copy_state(struct ssh_digest_ - int - ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) - { -- if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) -+ if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; - return 0; - } -@@ -161,7 +162,7 @@ ssh_digest_final(struct ssh_digest_ctx * - return SSH_ERR_INVALID_ARGUMENT; - if (dlen < digest->digest_len) /* No truncation allowed */ - return SSH_ERR_INVALID_ARGUMENT; -- if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) -+ if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; - if (l != digest->digest_len) /* sanity */ - return SSH_ERR_INTERNAL_ERROR; -@@ -172,7 +173,7 @@ void - ssh_digest_free(struct ssh_digest_ctx *ctx) - { - if (ctx != NULL) { -- EVP_MD_CTX_cleanup(&ctx->mdctx); -+ EVP_MD_CTX_free(ctx->mdctx); - explicit_bzero(ctx, sizeof(*ctx)); - free(ctx); - } -diff -up openssh/entropy.c.openssl openssh/entropy.c ---- openssh/entropy.c.openssl 2017-09-26 13:19:31.783249611 +0200 -+++ openssh/entropy.c 2017-09-26 13:19:31.795249685 +0200 -@@ -218,7 +218,9 @@ seed_rng(void) - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); - - /* clean the PRNG status when exiting the program */ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L - atexit(RAND_cleanup); -+#endif - - #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { -diff -up openssh/gss-genr.c.openssl openssh/gss-genr.c ---- openssh/gss-genr.c.openssl 2017-09-26 13:19:31.773249550 +0200 -+++ openssh/gss-genr.c 2017-09-26 13:19:31.796249691 +0200 -@@ -99,7 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - u_char digest[EVP_MAX_MD_SIZE]; - char deroid[2]; - const EVP_MD *evp_md = EVP_md5(); -- EVP_MD_CTX md; -+ EVP_MD_CTX *md; - char *s, *cp, *p; - - if (gss_enc2oid != NULL) { -@@ -113,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - if ((buf = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); - -+ md = EVP_MD_CTX_new(); - oidpos = 0; - s = cp = xstrdup(kex); - for (i = 0; i < gss_supported->count; i++) { -@@ -122,12 +123,13 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - deroid[0] = SSH_GSS_OIDTYPE; - deroid[1] = gss_supported->elements[i].length; - -- EVP_DigestInit(&md, evp_md); -- EVP_DigestUpdate(&md, deroid, 2); -- EVP_DigestUpdate(&md, -+ EVP_MD_CTX_reset(md); -+ EVP_DigestInit(md, evp_md); -+ EVP_DigestUpdate(md, deroid, 2); -+ EVP_DigestUpdate(md, - gss_supported->elements[i].elements, - gss_supported->elements[i].length); -- EVP_DigestFinal(&md, digest, NULL); -+ EVP_DigestFinal(md, digest, NULL); - - encoded = xmalloc(EVP_MD_size(evp_md) * 2); - enclen = __b64_ntop(digest, EVP_MD_size(evp_md), -@@ -149,6 +151,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - } - } - free(s); -+ EVP_MD_CTX_free(md); - gss_enc2oid[oidpos].oid = NULL; - gss_enc2oid[oidpos].encoded = NULL; - -diff -up openssh/includes.h.openssl openssh/includes.h ---- openssh/includes.h.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/includes.h 2017-09-26 13:19:31.796249691 +0200 -@@ -166,6 +166,7 @@ - - #ifdef WITH_OPENSSL - #include /* For OPENSSL_VERSION_NUMBER */ -+#include "libcrypto-compat.h" - #endif - - #include "defines.h" -diff -up openssh/kexdhc.c.openssl openssh/kexdhc.c ---- openssh/kexdhc.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/kexdhc.c 2017-09-26 13:19:31.797249697 +0200 -@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) - { - struct kex *kex = ssh->kex; - int r; -+ const BIGNUM *pub_key; - - /* generate and send 'e', client DH public key */ - switch (kex->kex_type) { -@@ -81,21 +82,27 @@ kexdh_client(struct ssh *ssh) - goto out; - } - debug("sending SSH2_MSG_KEXDH_INIT"); -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || -- (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; - #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, kex->dh); - fprintf(stderr, "pub= "); -- BN_print_fp(stderr, kex->dh->pub_key); -+ BN_print_fp(stderr, pub_key); - fprintf(stderr, "\n"); - #endif - debug("expecting SSH2_MSG_KEXDH_REPLY"); - ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); - r = 0; - out: -+ if (r != 0) { -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ } - return r; - } - -@@ -109,6 +116,7 @@ input_kex_dh(int type, u_int32_t seq, st - u_char hash[SSH_DIGEST_MAX_LENGTH]; - size_t klen = 0, slen, sbloblen, hashlen; - int kout, r; -+ const BIGNUM *pub_key; - - if (kex->verify_host_key == NULL) { - r = SSH_ERR_INVALID_ARGUMENT; -@@ -168,6 +176,7 @@ input_kex_dh(int type, u_int32_t seq, st - #endif - - /* calc and verify H */ -+ DH_get0_key(kex->dh, &pub_key, NULL); - hashlen = sizeof(hash); - if ((r = kex_dh_hash( - kex->hash_alg, -@@ -176,7 +185,7 @@ input_kex_dh(int type, u_int32_t seq, st - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), - server_host_key_blob, sbloblen, -- kex->dh->pub_key, -+ pub_key, - dh_server_pub, - shared_secret, - hash, &hashlen)) != 0) -diff -up openssh/kexdhs.c.openssl openssh/kexdhs.c ---- openssh/kexdhs.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/kexdhs.c 2017-09-26 13:19:31.797249697 +0200 -@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) - ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); - r = 0; - out: -+ if (r != 0) { -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ } - return r; - } - -@@ -101,6 +105,7 @@ input_kex_dh_init(int type, u_int32_t se - size_t sbloblen, slen; - size_t klen = 0, hashlen; - int kout, r; -+ const BIGNUM *pub_key; - - if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) { -@@ -163,6 +168,7 @@ input_kex_dh_init(int type, u_int32_t se - goto out; - /* calc H */ - hashlen = sizeof(hash); -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kex_dh_hash( - kex->hash_alg, - kex->client_version_string, -@@ -171,7 +177,7 @@ input_kex_dh_init(int type, u_int32_t se - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, -- kex->dh->pub_key, -+ pub_key, - shared_secret, - hash, &hashlen)) != 0) - goto out; -@@ -197,7 +203,7 @@ input_kex_dh_init(int type, u_int32_t se - /* send server hostkey, DH pubkey 'f' and signed H */ - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || - (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ - (r = sshpkt_put_string(ssh, signature, slen)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; -diff -up openssh/kexgexc.c.openssl openssh/kexgexc.c ---- openssh/kexgexc.c.openssl 2017-09-26 13:19:31.783249611 +0200 -+++ openssh/kexgexc.c 2017-09-26 13:19:31.797249697 +0200 -@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32 - struct kex *kex = ssh->kex; - BIGNUM *p = NULL, *g = NULL; - int r, bits; -+ const BIGNUM *pub_key; - - debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); - -@@ -119,24 +120,30 @@ input_kex_dh_gex_group(int type, u_int32 - p = g = NULL; /* belong to kex->dh now */ - - /* generate and send 'e', client DH public key */ -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || -- (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; - debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); - #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, kex->dh); - fprintf(stderr, "pub= "); -- BN_print_fp(stderr, kex->dh->pub_key); -+ BN_print_fp(stderr, pub_key); - fprintf(stderr, "\n"); - #endif - ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); - ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); - r = 0; - out: - BN_clear_free(p); - BN_clear_free(g); -+ if (r != 0) { -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ } - return r; - } - -@@ -152,6 +157,7 @@ input_kex_dh_gex_reply(int type, u_int32 - u_char hash[SSH_DIGEST_MAX_LENGTH]; - size_t klen = 0, slen, sbloblen, hashlen; - int kout, r; -+ const BIGNUM *p, *g, *pub_key; - - debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); - if (kex->verify_host_key == NULL) { -@@ -214,6 +220,8 @@ input_kex_dh_gex_reply(int type, u_int32 - kex->min = kex->max = -1; - - /* calc and verify H */ -+ DH_get0_pqg(kex->dh, &p, NULL, &g); -+ DH_get0_key(kex->dh, &pub_key, NULL); - hashlen = sizeof(hash); - if ((r = kexgex_hash( - kex->hash_alg, -@@ -223,8 +231,8 @@ input_kex_dh_gex_reply(int type, u_int32 - sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), - server_host_key_blob, sbloblen, - kex->min, kex->nbits, kex->max, -- kex->dh->p, kex->dh->g, -- kex->dh->pub_key, -+ p, g, -+ pub_key, - dh_server_pub, - shared_secret, - hash, &hashlen)) != 0) -diff -up openssh/kexgexs.c.openssl openssh/kexgexs.c ---- openssh/kexgexs.c.openssl 2017-09-26 13:19:31.783249611 +0200 -+++ openssh/kexgexs.c 2017-09-26 13:19:31.797249697 +0200 -@@ -72,6 +72,7 @@ input_kex_dh_gex_request(int type, u_int - struct kex *kex = ssh->kex; - int r; - u_int min = 0, max = 0, nbits = 0; -+ const BIGNUM *p, *g; - - debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - if ((r = sshpkt_get_u32(ssh, &min)) != 0 || -@@ -101,9 +102,10 @@ input_kex_dh_gex_request(int type, u_int - goto out; - } - debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); -+ DH_get0_pqg(kex->dh, &p, NULL, &g); - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, p)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, g)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; - -@@ -115,6 +117,10 @@ input_kex_dh_gex_request(int type, u_int - ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); - r = 0; - out: -+ if (r != 0) { -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ } - return r; - } - -@@ -129,6 +135,7 @@ input_kex_dh_gex_init(int type, u_int32_ - size_t sbloblen, slen; - size_t klen = 0, hashlen; - int kout, r; -+ const BIGNUM *p, *g, *pub_key; - - if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) { -@@ -191,6 +198,8 @@ input_kex_dh_gex_init(int type, u_int32_ - goto out; - /* calc H */ - hashlen = sizeof(hash); -+ DH_get0_pqg(kex->dh, &p, NULL, &g); -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kexgex_hash( - kex->hash_alg, - kex->client_version_string, -@@ -199,9 +208,9 @@ input_kex_dh_gex_init(int type, u_int32_ - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - server_host_key_blob, sbloblen, - kex->min, kex->nbits, kex->max, -- kex->dh->p, kex->dh->g, -+ p, g, - dh_client_pub, -- kex->dh->pub_key, -+ pub_key, - shared_secret, - hash, &hashlen)) != 0) - goto out; -@@ -227,7 +236,7 @@ input_kex_dh_gex_init(int type, u_int32_ - /* send server hostkey, DH pubkey 'f' and signed H */ - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || - (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ - (r = sshpkt_put_string(ssh, signature, slen)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; -diff -up openssh/kexgssc.c.openssl openssh/kexgssc.c ---- openssh/kexgssc.c.openssl 2017-09-26 13:19:31.771249537 +0200 -+++ openssh/kexgssc.c 2017-09-26 13:19:31.797249697 +0200 -@@ -59,6 +59,7 @@ kexgss_client(struct ssh *ssh) { - BIGNUM *shared_secret = NULL; - BIGNUM *p = NULL; - BIGNUM *g = NULL; -+ const BIGNUM *pub_key, *p1, *g1; - u_char *kbuf; - u_char *serverhostkey = NULL; - u_char *empty = ""; -@@ -126,6 +127,7 @@ kexgss_client(struct ssh *ssh) { - - /* Step 1 - e is dh->pub_key */ - dh_gen_key(dh, ssh->kex->we_need * 8); -+ DH_get0_key(dh, &pub_key, NULL); - - /* This is f, we initialise it now to make life easier */ - dh_server_pub = BN_new(); -@@ -173,7 +175,7 @@ kexgss_client(struct ssh *ssh) { - packet_start(SSH2_MSG_KEXGSS_INIT); - packet_put_string(send_tok.value, - send_tok.length); -- packet_put_bignum2(dh->pub_key); -+ packet_put_bignum2((BIGNUM *)pub_key); - first = 0; - } else { - packet_start(SSH2_MSG_KEXGSS_CONTINUE); -@@ -282,13 +284,14 @@ kexgss_client(struct ssh *ssh) { - sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), - sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), - (serverhostkey ? serverhostkey : empty), slen, -- dh->pub_key, /* e */ -+ pub_key, /* e */ - dh_server_pub, /* f */ - shared_secret, /* K */ - hash, &hashlen - ); - break; - case KEX_GSS_GEX_SHA1: -+ DH_get0_pqg(dh, &p1, NULL, &g1); - kexgex_hash( - ssh->kex->hash_alg, - ssh->kex->client_version_string, -@@ -297,8 +300,8 @@ kexgss_client(struct ssh *ssh) { - sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), - (serverhostkey ? serverhostkey : empty), slen, - min, nbits, max, -- dh->p, dh->g, -- dh->pub_key, -+ p1, g1, -+ pub_key, - dh_server_pub, - shared_secret, - hash, &hashlen -diff -up openssh/kexgsss.c.openssl openssh/kexgsss.c ---- openssh/kexgsss.c.openssl 2017-09-26 13:19:31.771249537 +0200 -+++ openssh/kexgsss.c 2017-09-26 13:19:31.798249703 +0200 -@@ -78,6 +78,7 @@ kexgss_server(struct ssh *ssh) - char *mechs; - u_char hash[SSH_DIGEST_MAX_LENGTH]; - size_t hashlen; -+ const BIGNUM *p, *g, *pub_key; - - /* Initialise GSSAPI */ - -@@ -127,9 +128,10 @@ kexgss_server(struct ssh *ssh) - if (dh == NULL) - packet_disconnect("Protocol error: no matching group found"); - -+ DH_get0_pqg(dh, &p, NULL, &g); - packet_start(SSH2_MSG_KEXGSS_GROUP); -- packet_put_bignum2(dh->p); -- packet_put_bignum2(dh->g); -+ packet_put_bignum2((BIGNUM *)p); -+ packet_put_bignum2((BIGNUM *)g); - packet_send(); - - packet_write_wait(); -@@ -221,6 +223,7 @@ kexgss_server(struct ssh *ssh) - memset(kbuf, 0, klen); - free(kbuf); - -+ DH_get0_key(dh, &pub_key, NULL); - hashlen = sizeof(hash); - switch (ssh->kex->kex_type) { - case KEX_GSS_GRP1_SHA1: -@@ -232,7 +235,7 @@ kexgss_server(struct ssh *ssh) - sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), - sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), - NULL, 0, /* Change this if we start sending host keys */ -- dh_client_pub, dh->pub_key, shared_secret, -+ dh_client_pub, pub_key, shared_secret, - hash, &hashlen - ); - break; -@@ -244,9 +247,9 @@ kexgss_server(struct ssh *ssh) - sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), - NULL, 0, - cmin, nbits, cmax, -- dh->p, dh->g, -+ p, g, - dh_client_pub, -- dh->pub_key, -+ pub_key, - shared_secret, - hash, &hashlen - ); -@@ -270,7 +273,7 @@ kexgss_server(struct ssh *ssh) - fatal("Couldn't get MIC"); - - packet_start(SSH2_MSG_KEXGSS_COMPLETE); -- packet_put_bignum2(dh->pub_key); -+ packet_put_bignum2((BIGNUM *)pub_key); - packet_put_string(msg_tok.value,msg_tok.length); - - if (send_tok.length != 0) { -diff -up openssh/libcrypto-compat.c.openssl openssh/libcrypto-compat.c ---- openssh/libcrypto-compat.c.openssl 2017-09-26 13:19:31.798249703 +0200 -+++ openssh/libcrypto-compat.c 2017-09-26 13:19:31.798249703 +0200 -@@ -0,0 +1,428 @@ -+/* -+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "includes.h" -+ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ -+#include -+#include -+ -+static void *OPENSSL_zalloc(size_t num) -+{ -+ void *ret = OPENSSL_malloc(num); -+ -+ if (ret != NULL) -+ memset(ret, 0, num); -+ return ret; -+} -+ -+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -+{ -+ /* If the fields n and e in r are NULL, the corresponding input -+ * parameters MUST be non-NULL for n and e. d may be -+ * left NULL (in case only the public key is used). -+ */ -+ if ((r->n == NULL && n == NULL) -+ || (r->e == NULL && e == NULL)) -+ return 0; -+ -+ if (n != NULL) { -+ BN_free(r->n); -+ r->n = n; -+ } -+ if (e != NULL) { -+ BN_free(r->e); -+ r->e = e; -+ } -+ if (d != NULL) { -+ BN_free(r->d); -+ r->d = d; -+ } -+ -+ return 1; -+} -+ -+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) -+{ -+ /* If the fields p and q in r are NULL, the corresponding input -+ * parameters MUST be non-NULL. -+ */ -+ if ((r->p == NULL && p == NULL) -+ || (r->q == NULL && q == NULL)) -+ return 0; -+ -+ if (p != NULL) { -+ BN_free(r->p); -+ r->p = p; -+ } -+ if (q != NULL) { -+ BN_free(r->q); -+ r->q = q; -+ } -+ -+ return 1; -+} -+ -+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) -+{ -+ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input -+ * parameters MUST be non-NULL. -+ */ -+ if ((r->dmp1 == NULL && dmp1 == NULL) -+ || (r->dmq1 == NULL && dmq1 == NULL) -+ || (r->iqmp == NULL && iqmp == NULL)) -+ return 0; -+ -+ if (dmp1 != NULL) { -+ BN_free(r->dmp1); -+ r->dmp1 = dmp1; -+ } -+ if (dmq1 != NULL) { -+ BN_free(r->dmq1); -+ r->dmq1 = dmq1; -+ } -+ if (iqmp != NULL) { -+ BN_free(r->iqmp); -+ r->iqmp = iqmp; -+ } -+ -+ return 1; -+} -+ -+void RSA_get0_key(const RSA *r, -+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -+{ -+ if (n != NULL) -+ *n = r->n; -+ if (e != NULL) -+ *e = r->e; -+ if (d != NULL) -+ *d = r->d; -+} -+ -+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -+{ -+ if (p != NULL) -+ *p = r->p; -+ if (q != NULL) -+ *q = r->q; -+} -+ -+void RSA_get0_crt_params(const RSA *r, -+ const BIGNUM **dmp1, const BIGNUM **dmq1, -+ const BIGNUM **iqmp) -+{ -+ if (dmp1 != NULL) -+ *dmp1 = r->dmp1; -+ if (dmq1 != NULL) -+ *dmq1 = r->dmq1; -+ if (iqmp != NULL) -+ *iqmp = r->iqmp; -+} -+ -+void DSA_get0_pqg(const DSA *d, -+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -+{ -+ if (p != NULL) -+ *p = d->p; -+ if (q != NULL) -+ *q = d->q; -+ if (g != NULL) -+ *g = d->g; -+} -+ -+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) -+{ -+ /* If the fields p, q and g in d are NULL, the corresponding input -+ * parameters MUST be non-NULL. -+ */ -+ if ((d->p == NULL && p == NULL) -+ || (d->q == NULL && q == NULL) -+ || (d->g == NULL && g == NULL)) -+ return 0; -+ -+ if (p != NULL) { -+ BN_free(d->p); -+ d->p = p; -+ } -+ if (q != NULL) { -+ BN_free(d->q); -+ d->q = q; -+ } -+ if (g != NULL) { -+ BN_free(d->g); -+ d->g = g; -+ } -+ -+ return 1; -+} -+ -+void DSA_get0_key(const DSA *d, -+ const BIGNUM **pub_key, const BIGNUM **priv_key) -+{ -+ if (pub_key != NULL) -+ *pub_key = d->pub_key; -+ if (priv_key != NULL) -+ *priv_key = d->priv_key; -+} -+ -+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) -+{ -+ /* If the field pub_key in d is NULL, the corresponding input -+ * parameters MUST be non-NULL. The priv_key field may -+ * be left NULL. -+ */ -+ if (d->pub_key == NULL && pub_key == NULL) -+ return 0; -+ -+ if (pub_key != NULL) { -+ BN_free(d->pub_key); -+ d->pub_key = pub_key; -+ } -+ if (priv_key != NULL) { -+ BN_free(d->priv_key); -+ d->priv_key = priv_key; -+ } -+ -+ return 1; -+} -+ -+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -+{ -+ if (pr != NULL) -+ *pr = sig->r; -+ if (ps != NULL) -+ *ps = sig->s; -+} -+ -+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) -+{ -+ if (r == NULL || s == NULL) -+ return 0; -+ BN_clear_free(sig->r); -+ BN_clear_free(sig->s); -+ sig->r = r; -+ sig->s = s; -+ return 1; -+} -+ -+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -+{ -+ if (pr != NULL) -+ *pr = sig->r; -+ if (ps != NULL) -+ *ps = sig->s; -+} -+ -+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) -+{ -+ if (r == NULL || s == NULL) -+ return 0; -+ BN_clear_free(sig->r); -+ BN_clear_free(sig->s); -+ sig->r = r; -+ sig->s = s; -+ return 1; -+} -+ -+void DH_get0_pqg(const DH *dh, -+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -+{ -+ if (p != NULL) -+ *p = dh->p; -+ if (q != NULL) -+ *q = dh->q; -+ if (g != NULL) -+ *g = dh->g; -+} -+ -+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) -+{ -+ /* If the fields p and g in d are NULL, the corresponding input -+ * parameters MUST be non-NULL. q may remain NULL. -+ */ -+ if ((dh->p == NULL && p == NULL) -+ || (dh->g == NULL && g == NULL)) -+ return 0; -+ -+ if (p != NULL) { -+ BN_free(dh->p); -+ dh->p = p; -+ } -+ if (q != NULL) { -+ BN_free(dh->q); -+ dh->q = q; -+ } -+ if (g != NULL) { -+ BN_free(dh->g); -+ dh->g = g; -+ } -+ -+ if (q != NULL) { -+ dh->length = BN_num_bits(q); -+ } -+ -+ return 1; -+} -+ -+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) -+{ -+ if (pub_key != NULL) -+ *pub_key = dh->pub_key; -+ if (priv_key != NULL) -+ *priv_key = dh->priv_key; -+} -+ -+int DH_set_length(DH *dh, long length) -+{ -+ dh->length = length; -+ return 1; -+} -+ -+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) -+{ -+ return ctx->iv; -+} -+ -+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) -+{ -+ return ctx->iv; -+} -+ -+EVP_MD_CTX *EVP_MD_CTX_new(void) -+{ -+ return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); -+} -+ -+static void OPENSSL_clear_free(void *str, size_t num) -+{ -+ if (str == NULL) -+ return; -+ if (num) -+ OPENSSL_cleanse(str, num); -+ OPENSSL_free(str); -+} -+ -+/* This call frees resources associated with the context */ -+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) -+{ -+ if (ctx == NULL) -+ return 1; -+ -+ /* -+ * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because -+ * sometimes only copies of the context are ever finalised. -+ */ -+ if (ctx->digest && ctx->digest->cleanup -+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) -+ ctx->digest->cleanup(ctx); -+ if (ctx->digest && ctx->digest->ctx_size && ctx->md_data -+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { -+ OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); -+ } -+ EVP_PKEY_CTX_free(ctx->pctx); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_finish(ctx->engine); -+#endif -+ OPENSSL_cleanse(ctx, sizeof(*ctx)); -+ -+ return 1; -+} -+ -+void EVP_MD_CTX_free(EVP_MD_CTX *ctx) -+{ -+ EVP_MD_CTX_reset(ctx); -+ OPENSSL_free(ctx); -+} -+ -+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) -+{ -+ RSA_METHOD *ret; -+ -+ ret = OPENSSL_malloc(sizeof(RSA_METHOD)); -+ -+ if (ret != NULL) { -+ memcpy(ret, meth, sizeof(*meth)); -+ ret->name = OPENSSL_strdup(meth->name); -+ if (ret->name == NULL) { -+ OPENSSL_free(ret); -+ return NULL; -+ } -+ } -+ -+ return ret; -+} -+ -+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) -+{ -+ char *tmpname; -+ -+ tmpname = OPENSSL_strdup(name); -+ if (tmpname == NULL) { -+ return 0; -+ } -+ -+ OPENSSL_free((char *)meth->name); -+ meth->name = tmpname; -+ -+ return 1; -+} -+ -+int RSA_meth_set_priv_enc(RSA_METHOD *meth, -+ int (*priv_enc) (int flen, const unsigned char *from, -+ unsigned char *to, RSA *rsa, -+ int padding)) -+{ -+ meth->rsa_priv_enc = priv_enc; -+ return 1; -+} -+ -+int RSA_meth_set_priv_dec(RSA_METHOD *meth, -+ int (*priv_dec) (int flen, const unsigned char *from, -+ unsigned char *to, RSA *rsa, -+ int padding)) -+{ -+ meth->rsa_priv_dec = priv_dec; -+ return 1; -+} -+ -+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) -+{ -+ meth->finish = finish; -+ return 1; -+} -+ -+void RSA_meth_free(RSA_METHOD *meth) -+{ -+ if (meth != NULL) { -+ OPENSSL_free((char *)meth->name); -+ OPENSSL_free(meth); -+ } -+} -+ -+int RSA_bits(const RSA *r) -+{ -+ return (BN_num_bits(r->n)); -+} -+ -+int DSA_bits(const DSA *dsa) -+{ -+ return BN_num_bits(dsa->p); -+} -+ -+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) -+{ -+ if (pkey->type != EVP_PKEY_RSA) { -+ return NULL; -+ } -+ return pkey->pkey.rsa; -+} -+ -+#endif /* OPENSSL_VERSION_NUMBER */ -diff -up openssh/libcrypto-compat.h.openssl openssh/libcrypto-compat.h ---- openssh/libcrypto-compat.h.openssl 2017-09-26 13:19:31.798249703 +0200 -+++ openssh/libcrypto-compat.h 2017-09-26 13:19:31.798249703 +0200 -@@ -0,0 +1,59 @@ -+#ifndef LIBCRYPTO_COMPAT_H -+#define LIBCRYPTO_COMPAT_H -+ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ -+#include -+#include -+#include -+#include -+#include -+ -+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); -+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); -+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); -+void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); -+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); -+void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); -+ -+void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); -+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); -+void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key); -+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); -+ -+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); -+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); -+ -+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); -+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); -+ -+void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); -+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); -+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); -+int DH_set_length(DH *dh, long length); -+ -+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); -+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); -+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); -+EVP_MD_CTX *EVP_MD_CTX_new(void); -+void EVP_MD_CTX_free(EVP_MD_CTX *ctx); -+#define EVP_CIPHER_impl_ctx_size(e) e->ctx_size -+#define EVP_CIPHER_CTX_get_cipher_data(ctx) ctx->cipher_data -+ -+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); -+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); -+#define RSA_meth_get_finish(meth) meth->finish -+int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); -+int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); -+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)); -+void RSA_meth_free(RSA_METHOD *meth); -+ -+int RSA_bits(const RSA *r); -+int DSA_bits(const DSA *d); -+ -+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); -+ -+#endif /* OPENSSL_VERSION_NUMBER */ -+ -+#endif /* LIBCRYPTO_COMPAT_H */ -+ -diff -up openssh/Makefile.in.openssl openssh/Makefile.in ---- openssh/Makefile.in.openssl 2017-09-26 13:19:31.784249617 +0200 -+++ openssh/Makefile.in 2017-09-26 13:19:31.798249703 +0200 -@@ -101,7 +101,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ - kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ - platform-pledge.o platform-tracing.o platform-misc.o \ -- auditstub.o -+ auditstub.o libcrypto-compat.o - - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect2.o mux.o -diff -up openssh/monitor.c.openssl openssh/monitor.c ---- openssh/monitor.c.openssl 2017-09-26 13:19:31.789249648 +0200 -+++ openssh/monitor.c 2017-09-26 13:19:31.799249709 +0200 -@@ -631,9 +631,12 @@ mm_answer_moduli(int sock, Buffer *m) - return (0); - } else { - /* Send first bignum */ -+ const BIGNUM *p, *g; -+ -+ DH_get0_pqg(dh, &p, NULL, &g); - if ((r = sshbuf_put_u8(m, 1)) != 0 || -- (r = sshbuf_put_bignum2(m, dh->p)) != 0 || -- (r = sshbuf_put_bignum2(m, dh->g)) != 0) -+ (r = sshbuf_put_bignum2(m, p)) != 0 || -+ (r = sshbuf_put_bignum2(m, g)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - DH_free(dh); -diff -up openssh/openbsd-compat/openssl-compat.c.openssl openssh/openbsd-compat/openssl-compat.c ---- openssh/openbsd-compat/openssl-compat.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/openbsd-compat/openssl-compat.c 2017-09-26 13:19:31.799249709 +0200 -@@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, l - void - ssh_OpenSSL_add_all_algorithms(void) - { -+#if OPENSSL_VERSION_NUMBER < 0x10100000L - OpenSSL_add_all_algorithms(); - - /* Enable use of crypto hardware */ - ENGINE_load_builtin_engines(); -+#if OPENSSL_VERSION_NUMBER < 0x10001000L - ENGINE_register_all_complete(); -+#endif - OPENSSL_config(NULL); -+#else -+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS | -+ OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); -+#endif - } - #endif - -diff -up openssh/regress/unittests/sshkey/test_file.c.openssl openssh/regress/unittests/sshkey/test_file.c ---- openssh/regress/unittests/sshkey/test_file.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/regress/unittests/sshkey/test_file.c 2017-09-26 13:19:31.799249709 +0200 -@@ -46,6 +46,7 @@ sshkey_file_tests(void) - struct sshbuf *buf, *pw; - BIGNUM *a, *b, *c; - char *cp; -+ const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key; - - TEST_START("load passphrase"); - pw = load_text_file("pw"); -@@ -60,9 +61,11 @@ sshkey_file_tests(void) - a = load_bignum("rsa_1.param.n"); - b = load_bignum("rsa_1.param.p"); - c = load_bignum("rsa_1.param.q"); -- ASSERT_BIGNUM_EQ(k1->rsa->n, a); -- ASSERT_BIGNUM_EQ(k1->rsa->p, b); -- ASSERT_BIGNUM_EQ(k1->rsa->q, c); -+ RSA_get0_key(k1->rsa, &n, NULL, NULL); -+ RSA_get0_factors(k1->rsa, &p, &q); -+ ASSERT_BIGNUM_EQ(n, a); -+ ASSERT_BIGNUM_EQ(p, b); -+ ASSERT_BIGNUM_EQ(q, c); - BN_free(a); - BN_free(b); - BN_free(c); -@@ -151,9 +154,11 @@ sshkey_file_tests(void) - a = load_bignum("dsa_1.param.g"); - b = load_bignum("dsa_1.param.priv"); - c = load_bignum("dsa_1.param.pub"); -- ASSERT_BIGNUM_EQ(k1->dsa->g, a); -- ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); -- ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); -+ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); -+ DSA_get0_key(k1->dsa, &pub_key, &priv_key); -+ ASSERT_BIGNUM_EQ(g, a); -+ ASSERT_BIGNUM_EQ(priv_key, b); -+ ASSERT_BIGNUM_EQ(pub_key, c); - BN_free(a); - BN_free(b); - BN_free(c); -diff -up openssh/regress/unittests/sshkey/test_sshkey.c.openssl openssh/regress/unittests/sshkey/test_sshkey.c ---- openssh/regress/unittests/sshkey/test_sshkey.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/regress/unittests/sshkey/test_sshkey.c 2017-09-26 13:19:31.800249715 +0200 -@@ -197,9 +197,6 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_RSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); - sshkey_free(k1); - TEST_DONE(); - -@@ -207,8 +204,6 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_DSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); - sshkey_free(k1); - TEST_DONE(); - -@@ -234,9 +229,6 @@ sshkey_tests(void) - k1 = sshkey_new_private(KEY_RSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_NE(k1->rsa->p, NULL); - ASSERT_INT_EQ(sshkey_add_private(k1), 0); - sshkey_free(k1); - TEST_DONE(); -@@ -245,8 +237,6 @@ sshkey_tests(void) - k1 = sshkey_new_private(KEY_DSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_NE(k1->dsa->priv_key, NULL); - ASSERT_INT_EQ(sshkey_add_private(k1), 0); - sshkey_free(k1); - TEST_DONE(); -@@ -285,18 +275,13 @@ sshkey_tests(void) - ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); - ASSERT_PTR_NE(kr, NULL); - ASSERT_PTR_NE(kr->rsa, NULL); -- ASSERT_PTR_NE(kr->rsa->n, NULL); -- ASSERT_PTR_NE(kr->rsa->e, NULL); -- ASSERT_PTR_NE(kr->rsa->p, NULL); -- ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); -+ ASSERT_INT_EQ(RSA_bits(kr->rsa), 1024); - TEST_DONE(); - - TEST_START("generate KEY_DSA"); - ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); - ASSERT_PTR_NE(kd, NULL); - ASSERT_PTR_NE(kd->dsa, NULL); -- ASSERT_PTR_NE(kd->dsa->g, NULL); -- ASSERT_PTR_NE(kd->dsa->priv_key, NULL); - TEST_DONE(); - - #ifdef OPENSSL_HAS_ECC -@@ -323,9 +308,6 @@ sshkey_tests(void) - ASSERT_PTR_NE(kr, k1); - ASSERT_INT_EQ(k1->type, KEY_RSA); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); - TEST_DONE(); - - TEST_START("equal KEY_RSA/demoted KEY_RSA"); -@@ -339,8 +321,6 @@ sshkey_tests(void) - ASSERT_PTR_NE(kd, k1); - ASSERT_INT_EQ(k1->type, KEY_DSA); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); - TEST_DONE(); - - TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -up openssh/ssh.c.openssl openssh/ssh.c ---- openssh/ssh.c.openssl 2017-09-26 13:19:31.786249629 +0200 -+++ openssh/ssh.c 2017-09-26 13:19:31.800249715 +0200 -@@ -530,7 +530,9 @@ main(int ac, char **av) - sanitise_stdfd(); - - __progname = ssh_get_progname(av[0]); -+#if OPENSSL_VERSION_NUMBER < 0x10100000L - SSLeay_add_all_algorithms(); -+#endif - if (access("/etc/system-fips", F_OK) == 0) - if (! FIPSCHECK_verify(NULL, NULL)){ - if (FIPS_mode()) -diff -up openssh/sshd.c.openssl openssh/sshd.c ---- openssh/sshd.c.openssl 2017-09-26 13:19:31.792249666 +0200 -+++ openssh/sshd.c 2017-09-26 13:19:31.801249721 +0200 -@@ -1485,7 +1485,7 @@ main(int ac, char **av) - #endif - __progname = ssh_get_progname(av[0]); - -- SSLeay_add_all_algorithms(); -+ OpenSSL_add_all_algorithms(); - if (access("/etc/system-fips", F_OK) == 0) - if (! FIPSCHECK_verify(NULL, NULL)) { - openlog(__progname, LOG_PID, LOG_AUTHPRIV); -diff -up openssh/ssh-dss.c.openssl openssh/ssh-dss.c ---- openssh/ssh-dss.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/ssh-dss.c 2017-09-26 13:19:31.801249721 +0200 -@@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u - size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); - struct sshbuf *b = NULL; - int ret = SSH_ERR_INVALID_ARGUMENT; -+ const BIGNUM *r, *s; - - if (lenp != NULL) - *lenp = 0; -@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u - goto out; - } - -- rlen = BN_num_bytes(sig->r); -- slen = BN_num_bytes(sig->s); -+ DSA_SIG_get0(sig, &r, &s); -+ rlen = BN_num_bytes(r); -+ slen = BN_num_bytes(s); - if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { - ret = SSH_ERR_INTERNAL_ERROR; - goto out; - } - explicit_bzero(sigblob, SIGBLOB_LEN); -- BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); -- BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); -+ BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); -+ BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen); - - if ((b = sshbuf_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; -@@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key, - int ret = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL; - char *ktype = NULL; -+ BIGNUM *r = NULL, *s = NULL; - - if (key == NULL || key->dsa == NULL || - sshkey_type_plain(key->type) != KEY_DSA || -@@ -177,16 +180,19 @@ ssh_dss_verify(const struct sshkey *key, - - /* parse signature */ - if ((sig = DSA_SIG_new()) == NULL || -- (sig->r = BN_new()) == NULL || -- (sig->s = BN_new()) == NULL) { -+ (r = BN_new()) == NULL || -+ (s = BN_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || -- (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { -+ if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) || -+ (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL) || -+ (DSA_SIG_set0(sig, r, s) == 0)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ r = NULL; -+ s = NULL; - - /* sha1 the data */ - if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, -@@ -207,7 +213,9 @@ ssh_dss_verify(const struct sshkey *key, - - out: - explicit_bzero(digest, sizeof(digest)); -+ BN_free(r); -+ BN_free(s); - DSA_SIG_free(sig); - sshbuf_free(b); - free(ktype); - if (sigblob != NULL) { -diff -up openssh/ssh-ecdsa.c.openssl openssh/ssh-ecdsa.c ---- openssh/ssh-ecdsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/ssh-ecdsa.c 2017-09-26 13:19:31.801249721 +0200 -@@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, - size_t len, dlen; - struct sshbuf *b = NULL, *bb = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; -+ const BIGNUM *r, *s; - - if (lenp != NULL) - *lenp = 0; -@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || -- (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) -+ ECDSA_SIG_get0(sig, &r, &s); -+ if ((ret = sshbuf_put_bignum2(bb, r)) != 0 || -+ (ret = sshbuf_put_bignum2(bb, s)) != 0) - goto out; - if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || - (ret = sshbuf_put_stringb(b, bb)) != 0) -@@ -119,6 +121,7 @@ ssh_ecdsa_verify(const struct sshkey *ke - int ret = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL, *sigbuf = NULL; - char *ktype = NULL; -+ BIGNUM *r = NULL, *s = NULL; - - if (key == NULL || key->ecdsa == NULL || - sshkey_type_plain(key->type) != KEY_ECDSA || -@@ -147,15 +150,23 @@ ssh_ecdsa_verify(const struct sshkey *ke - } - - /* parse signature */ -- if ((sig = ECDSA_SIG_new()) == NULL) { -+ if ((sig = ECDSA_SIG_new()) == NULL || -+ (r = BN_new()) == NULL || -+ (s = BN_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || -- sshbuf_get_bignum2(sigbuf, sig->s) != 0) { -+ if (sshbuf_get_bignum2(sigbuf, r) != 0 || -+ sshbuf_get_bignum2(sigbuf, s) != 0) { - ret = SSH_ERR_INVALID_FORMAT; - goto out; - } -+ if (ECDSA_SIG_set0(sig, r, s) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ r = NULL; -+ s = NULL; - if (sshbuf_len(sigbuf) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; - goto out; -@@ -180,7 +191,9 @@ ssh_ecdsa_verify(const struct sshkey *ke - explicit_bzero(digest, sizeof(digest)); - sshbuf_free(sigbuf); - sshbuf_free(b); -+ BN_free(r); -+ BN_free(s); - ECDSA_SIG_free(sig); - free(ktype); - return ret; - } -diff -up openssh/sshkey.c.openssl openssh/sshkey.c ---- openssh/sshkey.c.openssl 2017-09-26 13:19:31.786249629 +0200 -+++ openssh/sshkey.c 2017-09-26 13:19:31.802249728 +0200 -@@ -267,10 +267,10 @@ sshkey_size(const struct sshkey *k) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: -- return BN_num_bits(k->rsa->n); -+ return RSA_bits(k->rsa); - case KEY_DSA: - case KEY_DSA_CERT: -- return BN_num_bits(k->dsa->p); -+ return DSA_bits(k->dsa); - case KEY_ECDSA: - case KEY_ECDSA_CERT: - return sshkey_curve_nid_to_bits(k->ecdsa_nid); -@@ -302,11 +302,17 @@ sshkey_is_private(const struct sshkey *k - switch (k->type) { - #ifdef WITH_OPENSSL - case KEY_RSA_CERT: -- case KEY_RSA: -- return k->rsa->d != NULL; -+ case KEY_RSA: { -+ const BIGNUM *d; -+ RSA_get0_key(k->rsa, NULL, NULL, &d); -+ return d != NULL; -+ } - case KEY_DSA_CERT: -- case KEY_DSA: -- return k->dsa->priv_key != NULL; -+ case KEY_DSA: { -+ const BIGNUM *priv_key; -+ DSA_get0_key(k->dsa, NULL, &priv_key); -+ return priv_key != NULL; -+ } - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA_CERT: - case KEY_ECDSA: -@@ -496,10 +501,7 @@ sshkey_new(int type) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: -- if ((rsa = RSA_new()) == NULL || -- (rsa->n = BN_new()) == NULL || -- (rsa->e = BN_new()) == NULL) { -- RSA_free(rsa); -+ if ((rsa = RSA_new()) == NULL) { - free(k); - return NULL; - } -@@ -508,12 +509,7 @@ sshkey_new(int type) - break; - case KEY_DSA: - case KEY_DSA_CERT: -- if ((dsa = DSA_new()) == NULL || -- (dsa->p = BN_new()) == NULL || -- (dsa->q = BN_new()) == NULL || -- (dsa->g = BN_new()) == NULL || -- (dsa->pub_key = BN_new()) == NULL) { -- DSA_free(dsa); -+ if ((dsa = DSA_new()) == NULL) { - free(k); - return NULL; - } -@@ -553,21 +548,10 @@ sshkey_add_private(struct sshkey *k) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: --#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) -- if (bn_maybe_alloc_failed(k->rsa->d) || -- bn_maybe_alloc_failed(k->rsa->iqmp) || -- bn_maybe_alloc_failed(k->rsa->q) || -- bn_maybe_alloc_failed(k->rsa->p) || -- bn_maybe_alloc_failed(k->rsa->dmq1) || -- bn_maybe_alloc_failed(k->rsa->dmp1)) -- return SSH_ERR_ALLOC_FAIL; - break; - case KEY_DSA: - case KEY_DSA_CERT: -- if (bn_maybe_alloc_failed(k->dsa->priv_key)) -- return SSH_ERR_ALLOC_FAIL; - break; --#undef bn_maybe_alloc_failed - case KEY_ECDSA: - case KEY_ECDSA_CERT: - /* Cannot do anything until we know the group */ -@@ -684,17 +668,31 @@ sshkey_equal_public(const struct sshkey - switch (a->type) { - #ifdef WITH_OPENSSL - case KEY_RSA_CERT: -- case KEY_RSA: -- return a->rsa != NULL && b->rsa != NULL && -- BN_cmp(a->rsa->e, b->rsa->e) == 0 && -- BN_cmp(a->rsa->n, b->rsa->n) == 0; -+ case KEY_RSA: { -+ const BIGNUM *a_e, *a_n, *b_e, *b_n; -+ -+ if (a->rsa == NULL || b->rsa == NULL) -+ return 0; -+ RSA_get0_key(a->rsa, &a_n, &a_e, NULL); -+ RSA_get0_key(b->rsa, &b_n, &b_e, NULL); -+ return BN_cmp(a_e, b_e) == 0 && BN_cmp(a_n, b_n) == 0; -+ } - case KEY_DSA_CERT: -- case KEY_DSA: -- return a->dsa != NULL && b->dsa != NULL && -- BN_cmp(a->dsa->p, b->dsa->p) == 0 && -- BN_cmp(a->dsa->q, b->dsa->q) == 0 && -- BN_cmp(a->dsa->g, b->dsa->g) == 0 && -- BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; -+ case KEY_DSA: { -+ const BIGNUM *a_p, *a_q, *a_g, *a_pub_key; -+ const BIGNUM *b_p, *b_q, *b_g, *b_pub_key; -+ -+ if (a->dsa == NULL || b->dsa == NULL) -+ return 0; -+ DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g); -+ DSA_get0_key(a->dsa, &a_pub_key, NULL); -+ DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g); -+ DSA_get0_key(b->dsa, &b_pub_key, NULL); -+ return BN_cmp(a_p, b_p) == 0 && -+ BN_cmp(a_q, b_q) == 0 && -+ BN_cmp(a_g, b_g) == 0 && -+ BN_cmp(a_pub_key, b_pub_key) == 0; -+ } - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA_CERT: - case KEY_ECDSA: -@@ -769,15 +767,21 @@ to_blob_buf(const struct sshkey *key, st - return ret; - break; - #ifdef WITH_OPENSSL -- case KEY_DSA: -- if (key->dsa == NULL) -- return SSH_ERR_INVALID_ARGUMENT; -- if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) -- return ret; -+ case KEY_DSA: { -+ const BIGNUM *p, *q, *g, *pub_key; -+ -+ if (key->dsa == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ -+ DSA_get0_pqg(key->dsa, &p, &q, &g); -+ DSA_get0_key(key->dsa, &pub_key, NULL); -+ if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -+ (ret = sshbuf_put_bignum2(b, p)) != 0 || -+ (ret = sshbuf_put_bignum2(b, q)) != 0 || -+ (ret = sshbuf_put_bignum2(b, g)) != 0 || -+ (ret = sshbuf_put_bignum2(b, pub_key)) != 0) -+ return ret; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -790,13 +794,18 @@ to_blob_buf(const struct sshkey *key, st - return ret; - break; - # endif -- case KEY_RSA: -- if (key->rsa == NULL) -- return SSH_ERR_INVALID_ARGUMENT; -- if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) -- return ret; -+ case KEY_RSA: { -+ const BIGNUM *e, *n; -+ -+ if (key->rsa == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ -+ RSA_get0_key(key->rsa, &n, &e, NULL); -+ if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -+ (ret = sshbuf_put_bignum2(b, e)) != 0 || -+ (ret = sshbuf_put_bignum2(b, n)) != 0) -+ return ret; -+ } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519: -@@ -1672,15 +1681,32 @@ sshkey_from_private(const struct sshkey - switch (k->type) { - #ifdef WITH_OPENSSL - case KEY_DSA: -- case KEY_DSA_CERT: -- if ((n = sshkey_new(k->type)) == NULL) -- return SSH_ERR_ALLOC_FAIL; -- if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || -- (BN_copy(n->dsa->q, k->dsa->q) == NULL) || -- (BN_copy(n->dsa->g, k->dsa->g) == NULL) || -- (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { -- sshkey_free(n); -- return SSH_ERR_ALLOC_FAIL; -+ case KEY_DSA_CERT: { -+ const BIGNUM *k_p, *k_q, *k_g, *k_pub_key; -+ BIGNUM *n_p = NULL, *n_q = NULL, *n_g = NULL, *n_pub_key = NULL; -+ -+ if ((n = sshkey_new(k->type)) == NULL) -+ return SSH_ERR_ALLOC_FAIL; -+ -+ DSA_get0_pqg(k->dsa, &k_p, &k_q, &k_g); -+ DSA_get0_key(k->dsa, &k_pub_key, NULL); -+ -+ if (((n_p = BN_dup(k_p)) == NULL) || -+ ((n_q = BN_dup(k_q)) == NULL) || -+ ((n_g = BN_dup(k_g)) == NULL) || -+ (DSA_set0_pqg(n->dsa, n_p, n_q, n_g) == 0)) { -+ sshkey_free(n); -+ BN_free(n_p); -+ BN_free(n_q); -+ BN_free(n_g); -+ return SSH_ERR_ALLOC_FAIL; -+ } -+ if (((n_pub_key = BN_dup(k_pub_key)) == NULL) || -+ (DSA_set0_key(n->dsa, n_pub_key, NULL) == 0)) { -+ sshkey_free(n); -+ BN_free(n_pub_key); -+ return SSH_ERR_ALLOC_FAIL; -+ } - } - break; - # ifdef OPENSSL_HAS_ECC -@@ -1702,13 +1728,22 @@ sshkey_from_private(const struct sshkey - break; - # endif /* OPENSSL_HAS_ECC */ - case KEY_RSA: -- case KEY_RSA_CERT: -- if ((n = sshkey_new(k->type)) == NULL) -- return SSH_ERR_ALLOC_FAIL; -- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || -- (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { -- sshkey_free(n); -- return SSH_ERR_ALLOC_FAIL; -+ case KEY_RSA_CERT: { -+ const BIGNUM *k_n, *k_e; -+ BIGNUM *n_n = NULL, *n_e = NULL; -+ -+ if ((n = sshkey_new(k->type)) == NULL) -+ return SSH_ERR_ALLOC_FAIL; -+ -+ RSA_get0_key(k->rsa, &k_n, &k_e, NULL); -+ if (((n_n = BN_dup(k_n)) == NULL) || -+ ((n_e = BN_dup(k_e)) == NULL) || -+ RSA_set0_key(n->rsa, n_n, n_e, NULL) == 0) { -+ sshkey_free(n); -+ BN_free(n_n); -+ BN_free(n_e); -+ return SSH_ERR_ALLOC_FAIL; -+ } - } - break; - #endif /* WITH_OPENSSL */ -@@ -1907,12 +1942,22 @@ sshkey_from_blob_internal(struct sshbuf - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || -- sshbuf_get_bignum2(b, key->rsa->n) != 0) { -- ret = SSH_ERR_INVALID_FORMAT; -- goto out; -+ { -+ BIGNUM *e, *n; -+ -+ e = BN_new(); -+ n = BN_new(); -+ if (e == NULL || n == NULL || -+ sshbuf_get_bignum2(b, e) != 0 || -+ sshbuf_get_bignum2(b, n) != 0 || -+ RSA_set0_key(key->rsa, n, e, NULL) == 0) { -+ BN_free(e); -+ BN_free(n); -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } - } -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - ret = SSH_ERR_KEY_LENGTH; - goto out; - } -@@ -1932,12 +1977,34 @@ sshkey_from_blob_internal(struct sshbuf - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || -- sshbuf_get_bignum2(b, key->dsa->q) != 0 || -- sshbuf_get_bignum2(b, key->dsa->g) != 0 || -- sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { -- ret = SSH_ERR_INVALID_FORMAT; -- goto out; -+ { -+ BIGNUM *p, *q, *g, *pub_key; -+ -+ p = BN_new(); -+ q = BN_new(); -+ g = BN_new(); -+ pub_key = BN_new(); -+ -+ if (p == NULL || q == NULL || g == NULL || -+ pub_key == NULL || -+ sshbuf_get_bignum2(b, p) != 0 || -+ sshbuf_get_bignum2(b, q) != 0 || -+ sshbuf_get_bignum2(b, g) != 0 || -+ sshbuf_get_bignum2(b, pub_key) != 0 || -+ DSA_set0_pqg(key->dsa, p, q, g) == 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(g); -+ BN_free(pub_key); -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) { -+ BN_free(pub_key); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } - } - #ifdef DEBUG_PK - DSA_print_fp(stderr, key->dsa, 8); -@@ -2171,26 +2238,53 @@ sshkey_demote(const struct sshkey *k, st - if ((ret = sshkey_cert_copy(k, pk)) != 0) - goto fail; - /* FALLTHROUGH */ -- case KEY_RSA: -- if ((pk->rsa = RSA_new()) == NULL || -- (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || -- (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { -- ret = SSH_ERR_ALLOC_FAIL; -- goto fail; -+ case KEY_RSA: { -+ const BIGNUM *k_e, *k_n; -+ BIGNUM *pk_e = NULL, *pk_n = NULL; -+ -+ RSA_get0_key(k->rsa, &k_n, &k_e, NULL); -+ if ((pk->rsa = RSA_new()) == NULL || -+ (pk_e = BN_dup(k_e)) == NULL || -+ (pk_n = BN_dup(k_n)) == NULL || -+ RSA_set0_key(pk->rsa, pk_n, pk_e, NULL) == 0) { -+ BN_free(pk_e); -+ BN_free(pk_n); -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto fail; - } -+ } - break; - case KEY_DSA_CERT: - if ((ret = sshkey_cert_copy(k, pk)) != 0) - goto fail; - /* FALLTHROUGH */ -- case KEY_DSA: -- if ((pk->dsa = DSA_new()) == NULL || -- (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || -- (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || -- (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || -- (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { -- ret = SSH_ERR_ALLOC_FAIL; -- goto fail; -+ case KEY_DSA: { -+ const BIGNUM *k_p, *k_q, *k_g, *k_pub_key; -+ BIGNUM *pk_p = NULL, *pk_q = NULL, *pk_g = NULL; -+ BIGNUM *pk_pub_key = NULL; -+ -+ DSA_get0_pqg(k->dsa, &k_p, &k_q, &k_g); -+ DSA_get0_key(k->dsa, &k_pub_key, NULL); -+ -+ if ((pk->dsa = DSA_new()) == NULL || -+ (pk_p = BN_dup(k_p)) == NULL || -+ (pk_q = BN_dup(k_q)) == NULL || -+ (pk_g = BN_dup(k_g)) == NULL || -+ (pk_pub_key = BN_dup(k_pub_key)) == NULL || -+ DSA_set0_pqg(pk->dsa, pk_p, pk_q, pk_g) == 0) { -+ BN_free(pk_p); -+ BN_free(pk_q); -+ BN_free(pk_g); -+ BN_free(pk_pub_key); -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto fail; -+ } -+ -+ if (DSA_set0_key(pk->dsa, pk_pub_key, NULL) == 0) { -+ BN_free(pk_pub_key); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto fail; -+ } - } - break; - case KEY_ECDSA_CERT: -@@ -2312,12 +2406,17 @@ sshkey_certify_custom(struct sshkey *k, - /* XXX this substantially duplicates to_blob(); refactor */ - switch (k->type) { - #ifdef WITH_OPENSSL -- case KEY_DSA_CERT: -- if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) -- goto out; -+ case KEY_DSA_CERT: { -+ const BIGNUM *p, *q, *g, *pub_key; -+ -+ DSA_get0_pqg(k->dsa, &p, &q, &g); -+ DSA_get0_key(k->dsa, &pub_key, NULL); -+ if ((ret = sshbuf_put_bignum2(cert, p)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, q)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, g)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) -+ goto out; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA_CERT: -@@ -2329,10 +2428,15 @@ sshkey_certify_custom(struct sshkey *k, - goto out; - break; - # endif /* OPENSSL_HAS_ECC */ -- case KEY_RSA_CERT: -- if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) -- goto out; -+ case KEY_RSA_CERT: { -+ const BIGNUM *e, *n; -+ -+ RSA_get0_key(k->rsa, &n, &e, NULL); -+ if (e == NULL || n == NULL || -+ (ret = sshbuf_put_bignum2(cert, e)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, n)) != 0) -+ goto out; -+ } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519_CERT: -@@ -2505,43 +2609,65 @@ sshkey_private_serialize(const struct ss - goto out; - switch (key->type) { - #ifdef WITH_OPENSSL -- case KEY_RSA: -- if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) -- goto out; -+ case KEY_RSA: { -+ const BIGNUM *n, *e, *d, *iqmp, *p, *q; -+ RSA_get0_key(key->rsa, &n, &e, &d); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ RSA_get0_factors(key->rsa, &p, &q); -+ if ((r = sshbuf_put_bignum2(b, n)) != 0 || -+ (r = sshbuf_put_bignum2(b, e)) != 0 || -+ (r = sshbuf_put_bignum2(b, d)) != 0 || -+ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0) -+ goto out; -+ } - break; - case KEY_RSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) -- goto out; -+ { -+ const BIGNUM *d, *iqmp, *p, *q; -+ -+ RSA_get0_key(key->rsa, NULL, NULL, &d); -+ RSA_get0_factors(key->rsa, &p, &q); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -+ (r = sshbuf_put_bignum2(b, d)) != 0 || -+ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0) -+ goto out; -+ } - break; -- case KEY_DSA: -- if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) -- goto out; -+ case KEY_DSA: { -+ const BIGNUM *p, *q, *g, *pub_key, *priv_key; -+ -+ DSA_get0_pqg(key->dsa, &p, &q, &g); -+ DSA_get0_key(key->dsa, &pub_key, &priv_key); -+ if ((r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0 || -+ (r = sshbuf_put_bignum2(b, g)) != 0 || -+ (r = sshbuf_put_bignum2(b, pub_key)) != 0 || -+ (r = sshbuf_put_bignum2(b, priv_key)) != 0) -+ goto out; -+ } - break; - case KEY_DSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) -- goto out; -+ { -+ const BIGNUM *priv_key; -+ -+ DSA_get0_key(key->dsa, NULL, &priv_key); -+ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -+ (r = sshbuf_put_bignum2(b, priv_key)) != 0) -+ goto out; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -2617,18 +2743,51 @@ sshkey_private_deserialize(struct sshbuf - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) -- goto out; -+ { -+ BIGNUM *p, *q, *g, *pub_key, *priv_key; -+ -+ p = BN_new(); -+ q = BN_new(); -+ g = BN_new(); -+ pub_key = BN_new(); -+ priv_key = BN_new(); -+ if (p == NULL || q == NULL || g == NULL || -+ pub_key == NULL || priv_key == NULL || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0 || -+ (r = sshbuf_get_bignum2(buf, g)) != 0 || -+ (r = sshbuf_get_bignum2(buf, pub_key)) != 0 || -+ (r = sshbuf_get_bignum2(buf, priv_key)) != 0 || -+ (r = ((DSA_set0_pqg(k->dsa, p, q, g) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(g); -+ BN_free(pub_key); -+ BN_free(priv_key); -+ goto out; -+ } -+ if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(pub_key); -+ BN_free(priv_key); -+ goto out; -+ } -+ } - break; -- case KEY_DSA_CERT: -- if ((r = sshkey_froms(buf, &k)) != 0 || -- (r = sshkey_add_private(k)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) -- goto out; -+ case KEY_DSA_CERT: { -+ BIGNUM *priv_key = BN_new(); -+ -+ if (priv_key == NULL || -+ (r = sshkey_froms(buf, &k)) != 0 || -+ (r = sshkey_add_private(k)) != 0 || -+ (r = sshbuf_get_bignum2(buf, priv_key)) != 0 || -+ (r = ((DSA_set0_key(k->dsa, NULL, priv_key) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { -+ BN_free(priv_key); -+ goto out; -+ } -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -2687,29 +2846,89 @@ sshkey_private_deserialize(struct sshbuf - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = ssh_rsa_generate_additional_parameters(k)) != 0) -- goto out; -- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ { -+ BIGNUM *n, *e, *d, *iqmp, *p, *q; -+ -+ n = BN_new(); -+ e = BN_new(); -+ d = BN_new(); -+ iqmp = BN_new(); -+ p = BN_new(); -+ q = BN_new(); -+ -+ if (n == NULL || e == NULL || d == NULL || -+ iqmp == NULL || p == NULL || q == NULL || -+ (r = sshbuf_get_bignum2(buf, n)) != 0 || -+ (r = sshbuf_get_bignum2(buf, e)) != 0 || -+ (r = sshbuf_get_bignum2(buf, d)) != 0 || -+ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0 || -+ (r = ((RSA_set0_key(k->rsa, n, e, d) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { -+ BN_free(n); -+ BN_free(e); -+ BN_free(d); -+ BN_free(iqmp); -+ BN_free(p); -+ BN_free(q); -+ goto out; -+ } -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(iqmp); -+ BN_free(p); -+ BN_free(q); -+ goto out; -+ } -+ if ((r = ssh_rsa_generate_additional_parameters(k, iqmp)) != 0) { -+ BN_free(iqmp); -+ goto out; -+ } -+ } -+ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } - break; -- case KEY_RSA_CERT: -- if ((r = sshkey_froms(buf, &k)) != 0 || -- (r = sshkey_add_private(k)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = ssh_rsa_generate_additional_parameters(k)) != 0) -- goto out; -- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ case KEY_RSA_CERT: { -+ BIGNUM *d, *iqmp, *p, *q; -+ -+ /* N and E are already set so make sure we will not overwrite them */ -+ d = BN_new(); -+ iqmp = BN_new(); -+ p = BN_new(); -+ q = BN_new(); -+ -+ if (d == NULL || iqmp == NULL || p == NULL || -+ q == NULL || -+ (r = sshkey_froms(buf, &k)) != 0 || -+ (r = sshkey_add_private(k)) != 0 || -+ (r = sshbuf_get_bignum2(buf, d)) != 0 || -+ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0 || -+ (r = ((RSA_set0_key(k->rsa, NULL, NULL, d) == 0) -+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) { -+ BN_free(d); -+ BN_free(iqmp); -+ BN_free(p); -+ BN_free(q); -+ goto out; -+ } -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(p); -+ BN_free(q); -+ goto out; -+ } -+ if (ssh_rsa_generate_additional_parameters(k, iqmp) != 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ free(iqmp); -+ goto out; -+ } -+ } -+ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } -@@ -3427,7 +3646,9 @@ translate_libcrypto_error(unsigned long - switch (pem_reason) { - case EVP_R_BAD_DECRYPT: - return SSH_ERR_KEY_WRONG_PASSPHRASE; -+#ifdef EVP_R_BN_DECODE_ERROR - case EVP_R_BN_DECODE_ERROR: -+#endif - case EVP_R_DECODE_ERROR: - #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR - case EVP_R_PRIVATE_KEY_DECODE_ERROR: -@@ -3492,7 +3713,7 @@ sshkey_parse_private_pem_fileblob(struct - r = convert_libcrypto_error(); - goto out; - } -- if (pk->type == EVP_PKEY_RSA && -+ if (EVP_PKEY_id(pk) == EVP_PKEY_RSA && - (type == KEY_UNSPEC || type == KEY_RSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; -@@ -3507,11 +3728,11 @@ sshkey_parse_private_pem_fileblob(struct - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } -- } else if (pk->type == EVP_PKEY_DSA && -+ } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA && - (type == KEY_UNSPEC || type == KEY_DSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; -@@ -3523,7 +3744,7 @@ sshkey_parse_private_pem_fileblob(struct - DSA_print_fp(stderr, prv->dsa, 8); - #endif - #ifdef OPENSSL_HAS_ECC -- } else if (pk->type == EVP_PKEY_EC && -+ } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC && - (type == KEY_UNSPEC || type == KEY_ECDSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; -diff -up openssh/ssh-keygen.c.openssl openssh/ssh-keygen.c ---- openssh/ssh-keygen.c.openssl 2017-09-26 13:19:31.787249636 +0200 -+++ openssh/ssh-keygen.c 2017-09-26 13:19:31.802249728 +0200 -@@ -501,40 +501,67 @@ do_convert_private_ssh2_from_blob(u_char - free(type); - - switch (key->type) { -- case KEY_DSA: -- buffer_get_bignum_bits(b, key->dsa->p); -- buffer_get_bignum_bits(b, key->dsa->g); -- buffer_get_bignum_bits(b, key->dsa->q); -- buffer_get_bignum_bits(b, key->dsa->pub_key); -- buffer_get_bignum_bits(b, key->dsa->priv_key); -+ case KEY_DSA: { -+ BIGNUM *p = NULL, *g = NULL, *q = NULL, *pub_key = NULL, *priv_key = NULL; -+ -+ if ((p = BN_new()) == NULL || -+ (g = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (pub_key = BN_new()) == NULL || -+ (priv_key = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ buffer_get_bignum_bits(b, p); -+ buffer_get_bignum_bits(b, g); -+ buffer_get_bignum_bits(b, q); -+ buffer_get_bignum_bits(b, pub_key); -+ buffer_get_bignum_bits(b, priv_key); -+ if (DSA_set0_pqg(key->dsa, p, q, g) == 0 || -+ DSA_set0_key(key->dsa, pub_key, priv_key) == 0) { -+ fatal("failed to set DSA key"); -+ } -+ } - break; -- case KEY_RSA: -- if ((r = sshbuf_get_u8(b, &e1)) != 0 || -- (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || -- (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) -- fatal("%s: buffer error: %s", __func__, ssh_err(r)); -- e = e1; -- debug("e %lx", e); -- if (e < 30) { -- e <<= 8; -- e += e2; -- debug("e %lx", e); -- e <<= 8; -- e += e3; -+ case KEY_RSA: { -+ BIGNUM *bn_e = NULL, *bn_d = NULL, *bn_n = NULL, *bn_iqmp = NULL, *bn_p = NULL, *bn_q = NULL; -+ -+ if ((bn_e = BN_new()) == NULL || -+ (bn_d = BN_new()) == NULL || -+ (bn_n = BN_new()) == NULL || -+ (bn_iqmp = BN_new()) == NULL || -+ (bn_p = BN_new()) == NULL || -+ (bn_q = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ -+ if ((r = sshbuf_get_u8(b, &e1)) != 0 || -+ (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || -+ (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ e = e1; - debug("e %lx", e); -+ if (e < 30) { -+ e <<= 8; -+ e += e2; -+ debug("e %lx", e); -+ e <<= 8; -+ e += e3; -+ debug("e %lx", e); -+ } -+ if (!BN_set_word(bn_e, e)) { -+ sshbuf_free(b); -+ sshkey_free(key); -+ return NULL; -+ } -+ buffer_get_bignum_bits(b, bn_d); -+ buffer_get_bignum_bits(b, bn_n); -+ buffer_get_bignum_bits(b, bn_iqmp); -+ buffer_get_bignum_bits(b, bn_q); -+ buffer_get_bignum_bits(b, bn_p); -+ if (RSA_set0_key(key->rsa, bn_n, bn_e, bn_d) == 0 || -+ RSA_set0_factors(key->rsa, bn_p, bn_q) == 0) -+ fatal("Failed to set RSA parameters"); -+ if ((r = ssh_rsa_generate_additional_parameters(key, bn_iqmp)) != 0) -+ fatal("generate RSA parameters failed: %s", ssh_err(r)); - } -- if (!BN_set_word(key->rsa->e, e)) { -- sshbuf_free(b); -- sshkey_free(key); -- return NULL; -- } -- buffer_get_bignum_bits(b, key->rsa->d); -- buffer_get_bignum_bits(b, key->rsa->n); -- buffer_get_bignum_bits(b, key->rsa->iqmp); -- buffer_get_bignum_bits(b, key->rsa->q); -- buffer_get_bignum_bits(b, key->rsa->p); -- if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) -- fatal("generate RSA parameters failed: %s", ssh_err(r)); - break; - } - rlen = sshbuf_len(b); -@@ -642,7 +669,7 @@ do_convert_from_pkcs8(struct sshkey **k, - identity_file); - } - fclose(fp); -- switch (EVP_PKEY_type(pubkey->type)) { -+ switch (EVP_PKEY_base_id(pubkey)) { - case EVP_PKEY_RSA: - if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); -@@ -666,7 +693,7 @@ do_convert_from_pkcs8(struct sshkey **k, - #endif - default: - fatal("%s: unsupported pubkey type %d", __func__, -- EVP_PKEY_type(pubkey->type)); -+ EVP_PKEY_base_id(pubkey)); - } - EVP_PKEY_free(pubkey); - return; -@@ -1798,6 +1825,7 @@ do_ca_sign(struct passwd *pw, int argc, - #ifdef ENABLE_PKCS11 - pkcs11_terminate(); - #endif -+ free(ca); - exit(0); - } - -diff -up openssh/sshkey.h.openssl openssh/sshkey.h ---- openssh/sshkey.h.openssl 2017-09-26 13:19:31.780249593 +0200 -+++ openssh/sshkey.h 2017-09-26 13:19:31.803249734 +0200 -@@ -199,7 +199,7 @@ int sshkey_parse_private_fileblob_type(s - const char *passphrase, struct sshkey **keyp, char **commentp); - - /* XXX should be internal, but used by ssh-keygen */ --int ssh_rsa_generate_additional_parameters(struct sshkey *); -+int ssh_rsa_generate_additional_parameters(struct sshkey *, BIGNUM *iqmp); - - /* stateful keys (e.g. XMSS) */ - #ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS -diff -up openssh/ssh-pkcs11-client.c.openssl openssh/ssh-pkcs11-client.c ---- openssh/ssh-pkcs11-client.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/ssh-pkcs11-client.c 2017-09-26 13:19:31.803249734 +0200 -@@ -143,12 +143,16 @@ pkcs11_rsa_private_encrypt(int flen, con - static int - wrap_rsa_key(RSA *rsa) - { -- static RSA_METHOD helper_rsa; -+ static RSA_METHOD *helper_rsa; - -- memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); -- helper_rsa.name = "ssh-pkcs11-helper"; -- helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; -- RSA_set_method(rsa, &helper_rsa); -+ if (helper_rsa == NULL) { -+ helper_rsa = RSA_meth_dup(RSA_get_default_method()); -+ if (helper_rsa == NULL) -+ error("RSA_meth_dup failed"); -+ RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper"); -+ RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt); -+ } -+ RSA_set_method(rsa, helper_rsa); - return (0); - } - -diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c ---- openssh/ssh-pkcs11.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/ssh-pkcs11.c 2017-09-26 13:19:31.803249734 +0200 -@@ -67,7 +67,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - CK_ULONG key_type; - int (*orig_finish)(RSA *rsa); -- RSA_METHOD rsa_method; -+ RSA_METHOD *rsa_method; - char *keyid; - int keyid_len; - char *label; -@@ -183,6 +183,7 @@ pkcs11_rsa_finish(RSA *rsa) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); - free(k11->label); -+ RSA_meth_free(k11->rsa_method); - free(k11); - } - return (rv); -@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); - k11->label[label_attrib->ulValueLen] = 0; - } -- k11->orig_finish = def->finish; -- memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); -- k11->rsa_method.name = "pkcs11"; -- k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; -- k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; -- k11->rsa_method.finish = pkcs11_rsa_finish; -- RSA_set_method(rsa, &k11->rsa_method); -+ k11->orig_finish = RSA_meth_get_finish(def); -+ if ((k11->rsa_method = RSA_meth_dup(def)) == NULL || -+ RSA_meth_set1_name(k11->rsa_method, "pkcs11") == 0 || -+ RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt) == 0 || -+ RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt) == 0 || -+ RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish) == 0) { -+ RSA_meth_free(k11->rsa_method); -+ k11->rsa_method = NULL; -+ pkcs11_provider_unref(k11->provider); -+ free(k11->keyid); -+ free(k11); -+ return (-1); -+ } -+ -+ RSA_set_method(rsa, k11->rsa_method); - RSA_set_app_data(rsa, k11); - return (0); - } -@@ -460,6 +468,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - CK_ULONG nfound; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f; -+ const BIGNUM *n, *e; - - f = p->module->function_list; - session = p->module->slotinfo[slotidx].session; -@@ -512,10 +521,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - if ((rsa = RSA_new()) == NULL) { - error("RSA_new failed"); - } else { -- rsa->n = BN_bin2bn(attribs[2].pValue, -+ BIGNUM *rsa_n, *rsa_e; -+ -+ rsa_n = BN_bin2bn(attribs[2].pValue, - attribs[2].ulValueLen, NULL); -- rsa->e = BN_bin2bn(attribs[3].pValue, -+ rsa_e = BN_bin2bn(attribs[3].pValue, - attribs[3].ulValueLen, NULL); -+ if (rsa_n == NULL || rsa_e == NULL) -+ error("BN_bin2bn failed"); -+ if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0) -+ error("RSA_set0_key failed"); - } - #ifdef ENABLE_PKCS11_ECDSA - } else if (attribs[2].type == CKA_EC_PARAMS ) { -@@ -920,19 +936,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } else if ((evp = X509_get_pubkey(x509)) == NULL) { - debug("X509_get_pubkey failed"); - } else { -- switch (evp->type) { -+ switch (EVP_PKEY_id(evp)) { - case EVP_PKEY_RSA: -- if (evp->pkey.rsa == NULL) -+ if (EVP_PKEY_get0_RSA(evp) == NULL) - debug("Missing RSA key"); -- else if ((rsa = RSAPublicKey_dup( -- evp->pkey.rsa)) == NULL) -+ else if ((rsa = RSAPublicKey_dup( -+ EVP_PKEY_get0_RSA(evp))) == NULL) - error("RSAPublicKey_dup failed"); - break; - case EVP_PKEY_EC: -- if (evp->pkey.ecdsa == NULL) -+ if (EVP_PKEY_get0_EC_KEY(evp) == NULL) - debug("Missing ECDSA key"); -- else if ((ecdsa = EC_KEY_dup( -- evp->pkey.ecdsa)) == NULL) -+ else if ((ecdsa = EC_KEY_dup( -+ EVP_PKEY_get0_EC_KEY(evp))) == NULL) - error("EC_KEY_dup failed"); - break; - default: -@@ -538,7 +551,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } - key = NULL; - if (rsa || ecdsa) { -- if (rsa && rsa->n && rsa->e && -+ if (rsa) -+ RSA_get0_key(rsa, &n, &e, NULL); -+ if (rsa && n && e && - pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); -diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c ---- openssh/ssh-rsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 -+++ openssh/ssh-rsa.c 2017-09-26 13:19:31.803249734 +0200 -@@ -78,38 +78,50 @@ rsa_hash_alg_nid(int type) - } - - int --ssh_rsa_generate_additional_parameters(struct sshkey *key) -+ssh_rsa_generate_additional_parameters(struct sshkey *key, BIGNUM *iqmp) - { - BIGNUM *aux = NULL; - BN_CTX *ctx = NULL; -- BIGNUM d; -+ BIGNUM *d = NULL; - int r; -+ const BIGNUM *p, *q, *rsa_d; -+ BIGNUM *dmp1 = NULL, *dmq1 = NULL; - - if (key == NULL || key->rsa == NULL || - sshkey_type_plain(key->type) != KEY_RSA) - return SSH_ERR_INVALID_ARGUMENT; - -- if ((ctx = BN_CTX_new()) == NULL) -- return SSH_ERR_ALLOC_FAIL; -- if ((aux = BN_new()) == NULL) { -+ RSA_get0_factors(key->rsa, &p, &q); -+ RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); -+ -+ if ((ctx = BN_CTX_new()) == NULL || -+ (aux = BN_new()) == NULL || -+ (d = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL || -+ (dmq1 = BN_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - BN_set_flags(aux, BN_FLG_CONSTTIME); - -- BN_init(&d); -- BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); -+ BN_with_flags(d, rsa_d, BN_FLG_CONSTTIME); - -- if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || -- (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || -- (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || -- (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { -+ if ((BN_sub(aux, q, BN_value_one()) == 0) || -+ (BN_mod(dmq1, d, aux, ctx) == 0) || -+ (BN_sub(aux, p, BN_value_one()) == 0) || -+ (BN_mod(dmp1, d, aux, ctx) == 0) || -+ (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ dmp1 = NULL; -+ dmq1 = NULL; - r = 0; - out: -+ BN_free(d); - BN_clear_free(aux); -+ BN_clear_free(dmp1); -+ BN_clear_free(dmq1); - BN_CTX_free(ctx); - return r; - } -@@ -136,7 +145,7 @@ ssh_rsa_sign(const struct sshkey *key, u - if (key == NULL || key->rsa == NULL || hash_alg == -1 || - sshkey_type_plain(key->type) != KEY_RSA) - return SSH_ERR_INVALID_ARGUMENT; -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - slen = RSA_size(key->rsa); - if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) -@@ -210,7 +219,7 @@ ssh_rsa_verify(const struct sshkey *key, - sshkey_type_plain(key->type) != KEY_RSA || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; -- if (BN_num_bits(key->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) ---- openssh-7.6p1/configure.ac.openssl 2017-10-04 15:47:48.440672023 +0200 -+++ openssh-7.6p1/configure.ac 2017-10-04 15:47:23.327531495 +0200 -@@ -2730,6 +2730,7 @@ - AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) - ;; - 100*) ;; # 1.0.x -+ 101*) ;; # 1.1.x is supported by this patch too - 200*) ;; # LibreSSL - *) - AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")]) diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index b761962..85a4b0f 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -20,8 +20,8 @@ index ca75cc7..6e7de31 100644 +#if defined(__NR_flock) && defined(__s390__) + SC_ALLOW(__NR_flock), +#endif - #ifdef __NR_geteuid - SC_ALLOW(__NR_geteuid), + #ifdef __NR_futex + SC_ALLOW(__NR_futex), #endif @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_gettimeofday diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index e184894..299d632 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -2048,12 +2048,12 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c + fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; - if ((r = sshkey_demote(sensitive_data.host_keys[i], - &tmp)) != 0) - fatal("could not demote host %s key: %s", - sshkey_type(sensitive_data.host_keys[i]), - ssh_err(r)); - sshkey_free(sensitive_data.host_keys[i]); + if ((r = sshkey_from_private( + sensitive_data.host_keys[i], &tmp)) != 0) + fatal("could not demote host %s key: %s", + sshkey_type(sensitive_data.host_keys[i]), + ssh_err(r)); + sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS @@ -2126,7 +2126,7 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c diff -up openssh-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c --- openssh-7.6p1/sshkey.c.audit 2017-10-04 17:18:32.758504660 +0200 +++ openssh-7.6p1/sshkey.c 2017-10-04 17:18:32.839505074 +0200 -@@ -295,6 +295,32 @@ sshkey_type_is_valid_ca(int type) +@@ -295,6 +295,38 @@ sshkey_type_is_valid_ca(int type) } int @@ -2135,11 +2135,17 @@ diff -up openssh-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c + switch (k->type) { +#ifdef WITH_OPENSSL + case KEY_RSA_CERT: -+ case KEY_RSA: -+ return k->rsa->d != NULL; ++ case KEY_RSA: { ++ const BIGNUM *d; ++ RSA_get0_key(k->rsa, NULL, NULL, &d); ++ return d != NULL; ++ } + case KEY_DSA_CERT: -+ case KEY_DSA: -+ return k->dsa->priv_key != NULL; ++ case KEY_DSA: { ++ const BIGNUM *priv_key; ++ DSA_get0_key(k->dsa, NULL, &priv_key); ++ return priv_key != NULL; ++ } +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch index 2e73d45..7f5f130 100644 --- a/openssh-7.6p1-pkcs11-ecdsa.patch +++ b/openssh-7.6p1-pkcs11-ecdsa.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-client.c ---- openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-02-16 13:25:59.426469253 +0100 -+++ openssh-7.6p1/ssh-pkcs11-client.c 2018-02-16 13:25:59.428469265 +0100 +diff -up openssh/ssh-pkcs11-client.c.pkcs11-ecdsa openssh/ssh-pkcs11-client.c +--- openssh/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-10-12 14:05:55.020656974 +0200 ++++ openssh/ssh-pkcs11-client.c 2018-10-12 14:05:55.023656999 +0200 @@ -31,6 +31,15 @@ #include @@ -15,9 +15,9 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 +#endif +#endif - #include "pathnames.h" - #include "xmalloc.h" -@@ -139,9 +147,9 @@ pkcs11_rsa_private_encrypt(int flen, con + #include "openbsd-compat/openssl-compat.h" + +@@ -155,9 +164,9 @@ pkcs11_rsa_private_encrypt(int flen, con return (ret); } @@ -27,9 +27,9 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 -wrap_key(RSA *rsa) +wrap_rsa_key(RSA *rsa) { - static RSA_METHOD helper_rsa; + static RSA_METHOD *helper_rsa; -@@ -152,6 +160,88 @@ wrap_key(RSA *rsa) +@@ -170,6 +179,88 @@ wrap_key(RSA *rsa) return (0); } @@ -118,7 +118,7 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 static int pkcs11_start_helper(void) { -@@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi +@@ -238,7 +329,15 @@ pkcs11_add_provider(char *name, char *pi __func__, ssh_err(r)); if ((r = sshkey_from_blob(blob, blen, &k)) != 0) fatal("%s: bad key: %s", __func__, ssh_err(r)); @@ -135,11 +135,11 @@ diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 (*keysp)[i] = k; free(blob); } -diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c ---- openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa 2018-02-16 13:25:59.427469259 +0100 -+++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 13:44:51.270554797 +0100 -@@ -32,6 +32,16 @@ - #include "openbsd-compat/sys-queue.h" +diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c +--- openssh/ssh-pkcs11.c.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200 ++++ openssh/ssh-pkcs11.c 2018-10-12 14:11:54.292636679 +0200 +@@ -33,6 +33,16 @@ + #include "openbsd-compat/openssl-compat.h" #include +#include @@ -155,15 +155,15 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c #define CRYPTOKI_COMPAT #include "pkcs11.h" -@@ -67,6 +76,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro +@@ -74,6 +84,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro struct pkcs11_key { struct pkcs11_provider *provider; CK_ULONG slotidx; + CK_ULONG key_type; int (*orig_finish)(RSA *rsa); - RSA_METHOD rsa_method; + RSA_METHOD *rsa_method; char *keyid; -@@ -75,6 +85,9 @@ struct pkcs11_key { +@@ -82,6 +93,9 @@ struct pkcs11_key { }; int pkcs11_interactive = 0; @@ -173,7 +173,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c /* * This can't be in the ssh-pkcs11-uri, becase we can not depend on -@@ -289,6 +302,40 @@ pkcs11_find(struct pkcs11_provider *p, C +@@ -345,6 +359,40 @@ pkcs11_find(struct pkcs11_provider *p, C return (ret); } @@ -214,7 +214,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c /* openssl callback doing the actual signing operation */ static int pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, -@@ -310,7 +357,6 @@ pkcs11_rsa_private_encrypt(int flen, con +@@ -366,7 +414,6 @@ pkcs11_rsa_private_encrypt(int flen, con {CKA_ID, NULL, 0}, {CKA_SIGN, NULL, sizeof(true_val) } }; @@ -222,7 +222,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c int rval = -1; key_filter[0].pValue = &private_key_class; -@@ -326,33 +372,8 @@ pkcs11_rsa_private_encrypt(int flen, con +@@ -383,33 +430,8 @@ pkcs11_rsa_private_encrypt(int flen, con } f = k11->provider->module->function_list; si = &k11->provider->module->slotinfo[k11->slotidx]; @@ -258,7 +258,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c } key_filter[1].pValue = k11->keyid; key_filter[1].ulValueLen = k11->keyid_len; -@@ -390,6 +411,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider * +@@ -447,6 +469,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider * const RSA_METHOD *def = RSA_get_default_method(); k11 = xcalloc(1, sizeof(*k11)); @@ -266,7 +266,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c k11->provider = provider; provider->refcount++; /* provider referenced by RSA key */ k11->slotidx = slotidx; -@@ -415,6 +437,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider * +@@ -477,6 +500,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider * return (0); } @@ -451,7 +451,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c /* remove trailing spaces */ static void rmspace(u_char *buf, size_t len) -@@ -482,11 +646,13 @@ static int +@@ -544,11 +745,13 @@ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) { @@ -466,7 +466,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c { CKA_ID, NULL, 0 }, { CKA_LABEL, NULL, 0 } }; -@@ -507,29 +673,60 @@ pkcs11_fetch_keys(struct pkcs11_provider +@@ -569,29 +772,60 @@ pkcs11_fetch_keys(struct pkcs11_provider { CKA_SUBJECT, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; @@ -533,9 +533,12 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c cert_attribs, keysp, nkeys) < 0) return (-1); return (0); -@@ -553,6 +746,11 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -624,8 +858,13 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], + struct sshkey ***keysp, int *nkeys) { - struct sshkey *key; +- struct sshkey *key; ++ struct sshkey *key = NULL; RSA *rsa; +#ifdef ENABLE_PKCS11_ECDSA + EC_KEY *ecdsa; @@ -545,7 +548,7 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c X509 *x509; EVP_PKEY *evp = NULL; int i; -@@ -608,6 +806,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -678,6 +917,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p * or ID, label, subject and value for certificates. */ rsa = NULL; @@ -555,9 +558,9 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); -@@ -620,6 +821,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - rsa->e = BN_bin2bn(attribs[3].pValue, - attribs[3].ulValueLen, NULL); +@@ -700,6 +942,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + BN_free(rsa_n); + BN_free(rsa_e); } +#ifdef ENABLE_PKCS11_ECDSA + } else if (attribs[2].type == CKA_EC_PARAMS ) { @@ -601,43 +604,61 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c } else { cp = attribs[3].pValue; if ((x509 = X509_new()) == NULL) { -@@ -639,13 +879,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -707,13 +988,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) + == NULL) { + error("d2i_X509 failed"); +- } else if ((evp = X509_get_pubkey(x509)) == NULL || +- EVP_PKEY_base_id(evp) != EVP_PKEY_RSA || +- EVP_PKEY_get0_RSA(evp) == NULL) { +- debug("X509_get_pubkey failed or no rsa"); +- } else if ((rsa = RSAPublicKey_dup( +- EVP_PKEY_get0_RSA(evp))) == NULL) { +- error("RSAPublicKey_dup"); ++ } else if ((evp = X509_get_pubkey(x509)) == NULL) { ++ debug("X509_get_pubkey failed"); ++ } else { ++ switch (EVP_PKEY_base_id(evp)) { ++ case EVP_PKEY_RSA: ++ if (EVP_PKEY_get0_RSA(evp) == NULL) ++ debug("Missing RSA key"); ++ else if ((rsa = RSAPublicKey_dup( ++ EVP_PKEY_get0_RSA(evp))) == NULL) ++ error("RSAPublicKey_dup failed"); ++ break; ++ case EVP_PKEY_EC: ++ if (EVP_PKEY_get0_EC_KEY(evp) == NULL) ++ debug("Missing ECDSA key"); ++ else if ((ecdsa = EC_KEY_dup( ++ EVP_PKEY_get0_EC_KEY(evp))) == NULL) ++ error("EC_KEY_dup failed"); ++ break; ++ default: ++ debug("not a RSA or ECDSA key"); ++ break; ++ } + } X509_free(x509); EVP_PKEY_free(evp); - } -- if (rsa && rsa->n && rsa->e && -- pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { -- if ((key = sshkey_new(KEY_UNSPEC)) == NULL) -- fatal("sshkey_new failed"); -- key->rsa = rsa; -- key->type = KEY_RSA; -- key->flags |= SSHKEY_FLAG_EXT; -+ key = NULL; -+ if (rsa || ecdsa) { -+ if (rsa && rsa->n && rsa->e && -+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { -+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) -+ fatal("sshkey_new failed"); -+ key->rsa = rsa; -+ key->type = KEY_RSA; -+ key->flags |= SSHKEY_FLAG_EXT; +@@ -725,6 +1021,17 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + key->rsa = rsa; + key->type = KEY_RSA; + key->flags |= SSHKEY_FLAG_EXT; +#ifdef ENABLE_PKCS11_ECDSA -+ } else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) { -+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) -+ fatal("sshkey_new failed"); -+ key->ecdsa = ecdsa; -+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); -+ key->type = KEY_ECDSA; -+ key->flags |= SSHKEY_FLAG_EXT; ++ } else if (ecdsa && ++ pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) { ++ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) ++ fatal("sshkey_new failed"); ++ key->ecdsa = ecdsa; ++ key->type = KEY_ECDSA; ++ key->flags |= SSHKEY_FLAG_EXT; +#endif /* ENABLE_PKCS11_ECDSA */ -+ } + } -+ -+ if(key) { ++ if (key) { if (pkcs11_key_included(keysp, nkeys, key)) { sshkey_free(key); } else { -@@ -658,6 +913,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -737,6 +1044,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p } } else if (rsa) { RSA_free(rsa); @@ -648,9 +669,9 @@ diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c } for (i = 0; i < nattribs; i++) free(attribs[i].pValue); -diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-helper.c ---- openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/ssh-pkcs11-helper.c 2018-02-16 13:25:59.428469265 +0100 +diff -up openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh/ssh-pkcs11-helper.c +--- openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-pkcs11-helper.c 2018-10-12 14:05:55.023656999 +0200 @@ -24,6 +24,17 @@ #include "openbsd-compat/sys-queue.h" @@ -669,7 +690,7 @@ diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 #include #include #include -@@ -80,7 +90,7 @@ del_keys_by_name(char *name) +@@ -77,7 +88,7 @@ del_keys_by_name(char *name) if (!strcmp(ki->providername, name)) { TAILQ_REMOVE(&pkcs11_keylist, ki, next); free(ki->providername); @@ -678,7 +699,7 @@ diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 free(ki); } } -@@ -164,6 +174,20 @@ process_del(void) +@@ -172,6 +183,20 @@ process_del(void) sshbuf_free(msg); } @@ -699,7 +720,7 @@ diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 static void process_sign(void) { -@@ -180,14 +204,38 @@ process_sign(void) +@@ -192,14 +217,38 @@ process_sign(void) else { if ((found = lookup_key(key)) != NULL) { #ifdef WITH_OPENSSL @@ -746,9 +767,9 @@ diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11 } #endif /* WITH_OPENSSL */ } -diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h ---- openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa 2018-02-16 13:25:59.429469272 +0100 -+++ openssh-7.6p1/ssh-pkcs11.h 2018-02-16 13:45:29.623800048 +0100 +diff -up openssh/ssh-pkcs11.h.pkcs11-ecdsa openssh/ssh-pkcs11.h +--- openssh/ssh-pkcs11.h.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200 ++++ openssh/ssh-pkcs11.h 2018-10-12 14:05:55.023656999 +0200 @@ -20,6 +20,7 @@ int pkcs11_init(int); void pkcs11_terminate(void); @@ -757,45 +778,3 @@ diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); int pkcs11_del_provider(char *); int pkcs11_uri_write(const struct sshkey *, FILE *); - - - -diff -up openssh-7.6p1/ssh-pkcs11.c.old openssh-7.6p1/ssh-pkcs11.c ---- openssh-7.6p1/ssh-pkcs11.c.old 2018-02-16 16:43:08.861520255 +0100 -+++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 16:56:35.312601451 +0100 -@@ -917,13 +917,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) - == NULL) { - error("d2i_X509 failed"); -- } else if ((evp = X509_get_pubkey(x509)) == NULL || -- evp->type != EVP_PKEY_RSA || -- evp->pkey.rsa == NULL) { -- debug("X509_get_pubkey failed or no rsa"); -- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) -- == NULL) { -- error("RSAPublicKey_dup"); -+ } else if ((evp = X509_get_pubkey(x509)) == NULL) { -+ debug("X509_get_pubkey failed"); -+ } else { -+ switch (evp->type) { -+ case EVP_PKEY_RSA: -+ if (evp->pkey.rsa == NULL) -+ debug("Missing RSA key"); -+ else if ((rsa = RSAPublicKey_dup( -+ evp->pkey.rsa)) == NULL) -+ error("RSAPublicKey_dup failed"); -+ break; -+ case EVP_PKEY_EC: -+ if (evp->pkey.ecdsa == NULL) -+ debug("Missing ECDSA key"); -+ else if ((ecdsa = EC_KEY_dup( -+ evp->pkey.ecdsa)) == NULL) -+ error("EC_KEY_dup failed"); -+ break; -+ default: -+ debug("not a RSA or ECDSA key"); -+ break; -+ } - } - X509_free(x509); - EVP_PKEY_free(evp); diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch index 6fd463e..3343730 100644 --- a/openssh-7.6p1-pkcs11-uri.patch +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -1,92 +1,7 @@ -diff --git a/Makefile.in b/Makefile.in -index ac959c1f..f8ed1781 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ - kexgssc.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -248,6 +248,8 @@ clean: regressclean - rm -f regress/unittests/match/test_match$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - (cd openbsd-compat && $(MAKE) clean) -@@ -276,6 +278,8 @@ distclean: regressclean - rm -f regress/unittests/match/test_match - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8 -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz - (cd openbsd-compat && $(MAKE) distclean) -@@ -437,6 +441,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/kex - $(MKDIR_P) `pwd`/regress/unittests/match - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/kexfuzz - [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -455,6 +460,11 @@ regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \ - $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+regress/soft-pkcs11.so: $(srcdir)/regress/soft-pkcs11.c $(REGRESSLIBS) -+ $(CC) $(CFLAGS) $(CPPFLAGS) -fpic -c $(srcdir)/regress/soft-pkcs11.c \ -+ -o $(srcdir)/regress/soft-pkcs11.o -+ $(CC) -shared -o $@ $(srcdir)/regress/soft-pkcs11.o -+ - regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \ - $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -556,6 +566,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ - MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o - -@@ -566,6 +586,7 @@ regress/misc/kexfuzz/kexfuzz$(EXEEXT): ${MISC_KEX_FUZZ_OBJS} libssh.a - regress-binaries: regress/modpipe$(EXEEXT) \ - regress/setuid-allowed$(EXEEXT) \ - regress/netcat$(EXEEXT) \ -+ regress/soft-pkcs11.so \ - regress/check-perm$(EXEEXT) \ - regress/mkdtemp$(EXEEXT) \ - regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ -@@ -575,6 +596,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ - regress/unittests/kex/test_kex$(EXEEXT) \ - regress/unittests/match/test_match$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - regress/misc/kexfuzz/kexfuzz$(EXEEXT) - - tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) -diff --git a/authfd.c b/authfd.c -index 1eff7ba9..35153f47 100644 ---- a/authfd.c -+++ b/authfd.c -@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identitylist *idl) +diff -up openssh/authfd.c.pkcs11-uri openssh/authfd.c +--- openssh/authfd.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/authfd.c 2018-10-12 13:52:55.450191401 +0200 +@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identit if (idl->comments != NULL) free(idl->comments[i]); } @@ -95,11 +10,10 @@ index 1eff7ba9..35153f47 100644 free(idl); } -diff --git a/configure.ac b/configure.ac -index d7bcaf01..171a8597 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1895,12 +1895,14 @@ AC_LINK_IFELSE( +diff -up openssh/configure.ac.pkcs11-uri openssh/configure.ac +--- openssh/configure.ac.pkcs11-uri 2018-10-12 13:52:55.430191235 +0200 ++++ openssh/configure.ac 2018-10-12 13:52:55.451191409 +0200 +@@ -1987,12 +1987,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -114,7 +28,7 @@ index d7bcaf01..171a8597 100644 fi ] ) -@@ -1916,6 +1918,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then +@@ -2008,6 +2010,40 @@ if test "x$openssl" = "xyes" && test "x$ ) fi @@ -155,7 +69,7 @@ index d7bcaf01..171a8597 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5226,6 +5262,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" +@@ -5458,6 +5494,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" @@ -163,36 +77,92 @@ index d7bcaf01..171a8597 100644 echo "" -diff --git a/regress/Makefile b/regress/Makefile -index d15898ad..9c15afa4 100644 ---- a/regress/Makefile -+++ b/regress/Makefile -@@ -108,9 +110,11 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ - known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ - modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log \ -- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ -+ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ -+ rsa-agent-cert.pub rsa.pub \ - rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ -- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ -+ soft-pkcs11.so soft-pkcs11.o pkcs11*.crt pkcs11*.key \ -+ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ - scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ - sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ - ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ -@@ -225,6 +229,7 @@ unit: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ -diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index db3018b8..4991d0bc 100644 ---- a/regress/agent-pkcs11.sh -+++ b/regress/agent-pkcs11.sh +diff -up openssh/Makefile.in.pkcs11-uri openssh/Makefile.in +--- openssh/Makefile.in.pkcs11-uri 2018-10-12 13:52:55.366190704 +0200 ++++ openssh/Makefile.in 2018-10-12 13:52:55.450191401 +0200 +@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -270,6 +270,8 @@ clean: regressclean + rm -f regress/unittests/match/test_match$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) clean) +@@ -300,6 +302,8 @@ distclean: regressclean + rm -f regress/unittests/match/test_match + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) distclean) +@@ -484,6 +488,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/kex + $(MKDIR_P) `pwd`/regress/unittests/match + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/kexfuzz + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -502,6 +507,11 @@ regress/netcat$(EXEEXT): $(srcdir)/regre + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++regress/soft-pkcs11.so: $(srcdir)/regress/soft-pkcs11.c $(REGRESSLIBS) ++ $(CC) $(CFLAGS) $(CPPFLAGS) -fpic -c $(srcdir)/regress/soft-pkcs11.c \ ++ -o $(srcdir)/regress/soft-pkcs11.o ++ $(CC) -shared -o $@ $(srcdir)/regress/soft-pkcs11.o ++ + regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +@@ -607,6 +617,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ + MISC_KEX_FUZZ_OBJS=\ + regress/misc/kexfuzz/kexfuzz.o + +@@ -617,6 +637,7 @@ regress/misc/kexfuzz/kexfuzz$(EXEEXT): $ + regress-binaries: regress/modpipe$(EXEEXT) \ + regress/setuid-allowed$(EXEEXT) \ + regress/netcat$(EXEEXT) \ ++ regress/soft-pkcs11.so \ + regress/check-perm$(EXEEXT) \ + regress/mkdtemp$(EXEEXT) \ + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ +@@ -627,6 +648,7 @@ regress-binaries: regress/modpipe$(EXEEX + regress/unittests/kex/test_kex$(EXEEXT) \ + regress/unittests/match/test_match$(EXEEXT) \ + regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + regress/misc/kexfuzz/kexfuzz$(EXEEXT) + + tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) +diff -up openssh/regress/agent-pkcs11.sh.pkcs11-uri openssh/regress/agent-pkcs11.sh +--- openssh/regress/agent-pkcs11.sh.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/regress/agent-pkcs11.sh 2018-10-12 13:52:55.451191409 +0200 @@ -4,10 +4,17 @@ tid="pkcs11 agent test" @@ -230,12 +200,10 @@ index db3018b8..4991d0bc 100644 r=$? if [ $r -ne 0 ]; then fail "ssh-add -e failed: exit code $r" -diff --git a/regress/locl.h b/regress/locl.h -new file mode 100644 -index 00000000..afefe27d ---- /dev/null -+++ b/regress/locl.h -@@ -0,0 +1,79 @@ +diff -up openssh/regress/locl.h.pkcs11-uri openssh/regress/locl.h +--- openssh/regress/locl.h.pkcs11-uri 2018-10-12 13:52:55.451191409 +0200 ++++ openssh/regress/locl.h 2018-10-12 13:52:55.451191409 +0200 +@@ -0,0 +1,78 @@ +/* + * Copyright (c) 2004, Stockholms universitet + * (Stockholm University, Stockholm Sweden) @@ -280,7 +248,6 @@ index 00000000..afefe27d +#include +#include +#include -+#include "../libcrypto-compat.h" + +#include +#include @@ -315,11 +282,34 @@ index 00000000..afefe27d + } \ + } \ +} -diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh -new file mode 100644 -index 00000000..cf98e379 ---- /dev/null -+++ b/regress/pkcs11.sh +diff -up openssh/regress/Makefile.pkcs11-uri openssh/regress/Makefile +--- openssh/regress/Makefile.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/regress/Makefile 2018-10-12 13:52:55.451191409 +0200 +@@ -109,9 +109,11 @@ CLEANFILES= *.core actual agent-key.* au + known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ + modpipe netcat no_identity_config \ + pidfile putty.rsa2 ready regress.log \ +- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ ++ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ ++ rsa-agent-cert.pub rsa.pub \ + rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ +- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ ++ soft-pkcs11.so soft-pkcs11.o pkcs11*.crt pkcs11*.key \ ++ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ + sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ + ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ +@@ -226,6 +228,7 @@ unit: + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ +diff -up openssh/regress/pkcs11.sh.pkcs11-uri openssh/regress/pkcs11.sh +--- openssh/regress/pkcs11.sh.pkcs11-uri 2018-10-12 13:52:55.451191409 +0200 ++++ openssh/regress/pkcs11.sh 2018-10-12 13:52:55.451191409 +0200 @@ -0,0 +1,300 @@ +# +# Copyright (c) 2017 Red Hat @@ -621,11 +611,9 @@ index 00000000..cf98e379 +fi + +rm -rf $OBJ/.tokens $OBJ/token_keys -diff --git a/regress/soft-pkcs11.c b/regress/soft-pkcs11.c -new file mode 100644 -index 00000000..8b4981bd ---- /dev/null -+++ b/regress/soft-pkcs11.c +diff -up openssh/regress/soft-pkcs11.c.pkcs11-uri openssh/regress/soft-pkcs11.c +--- openssh/regress/soft-pkcs11.c.pkcs11-uri 2018-10-12 13:52:55.452191417 +0200 ++++ openssh/regress/soft-pkcs11.c 2018-10-12 13:52:55.452191417 +0200 @@ -0,0 +1,2058 @@ +/* + * Copyright (c) 2004-2006, Stockholms universitet @@ -2685,10 +2673,9 @@ index 00000000..8b4981bd + (void *)func_not_supported, /* C_CancelFunction */ + (void *)func_not_supported /* C_WaitForSlotEvent */ +}; -diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e464b085..a0e5a37c 100644 ---- a/regress/unittests/Makefile -+++ b/regress/unittests/Makefile +diff -up openssh/regress/unittests/Makefile.pkcs11-uri openssh/regress/unittests/Makefile +--- openssh/regress/unittests/Makefile.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/regress/unittests/Makefile 2018-10-12 13:52:55.453191425 +0200 @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes @@ -2697,11 +2684,9 @@ index e464b085..a0e5a37c 100644 +SUBDIR+=pkcs11 authopt .include -diff --git a/regress/unittests/pkcs11/Makefile b/regress/unittests/pkcs11/Makefile -new file mode 100644 -index 00000000..481b13d0 ---- /dev/null -+++ b/regress/unittests/pkcs11/Makefile +diff -up openssh/regress/unittests/pkcs11/Makefile.pkcs11-uri openssh/regress/unittests/pkcs11/Makefile +--- openssh/regress/unittests/pkcs11/Makefile.pkcs11-uri 2018-10-12 13:52:55.453191425 +0200 ++++ openssh/regress/unittests/pkcs11/Makefile 2018-10-12 13:52:55.453191425 +0200 @@ -0,0 +1,9 @@ + +PROG=test_pkcs11 @@ -2712,11 +2697,9 @@ index 00000000..481b13d0 + env ${TEST_ENV} ./${PROG} + +.include -diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c -new file mode 100644 -index 00000000..e83aca54 ---- /dev/null -+++ b/regress/unittests/pkcs11/tests.c +diff -up openssh/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh/regress/unittests/pkcs11/tests.c +--- openssh/regress/unittests/pkcs11/tests.c.pkcs11-uri 2018-10-12 13:52:55.453191425 +0200 ++++ openssh/regress/unittests/pkcs11/tests.c 2018-10-12 13:52:55.453191425 +0200 @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2017 Red Hat @@ -2884,8 +2867,8 @@ index 00000000..e83aca54 + compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); + /* MUST NOT contain duplicate attributes of the same name */ + check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); -+ /* Unrecognized attribute in path SHOULD be error */ -+ check_parse_rv("pkcs11:key_name=SSH", EMPTY_URI, -1); ++ /* Unrecognized attribute in path are ignored with log message */ ++ check_parse("pkcs11:key_name=SSH", EMPTY_URI); + /* Unrecognized attribute in query SHOULD be ignored */ + check_parse("pkcs11:?key_name=SSH", EMPTY_URI); +} @@ -3048,10 +3031,9 @@ index 00000000..e83aca54 + test_parse_invalid(); + test_generate_valid(); +} -diff --git a/ssh-add.c b/ssh-add.c -index adcc4599..e4fd5623 100644 ---- a/ssh-add.c -+++ b/ssh-add.c +diff -up openssh/ssh-add.c.pkcs11-uri openssh/ssh-add.c +--- openssh/ssh-add.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-add.c 2018-10-12 13:52:55.454191434 +0200 @@ -64,6 +64,7 @@ #include "misc.h" #include "ssherr.h" @@ -3060,15 +3042,15 @@ index adcc4599..e4fd5623 100644 /* argv0 */ extern char *__progname; -@@ -188,6 +189,24 @@ delete_all(int agent_fd) +@@ -188,6 +189,24 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *); ++static int update_card(int, int, const char *, int); + +int -+update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri) ++update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) +{ + struct pkcs11_uri *uri; + @@ -3078,14 +3060,14 @@ index adcc4599..e4fd5623 100644 + fatal("Failed to parse PKCS#11 URI"); + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag); +} +#endif + static int add_file(int agent_fd, const char *filename, int key_only, int qflag) { -@@ -480,6 +499,13 @@ lock_agent(int agent_fd, int lock) +@@ -495,6 +514,13 @@ lock_agent(int agent_fd, int lock) static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) { @@ -3093,16 +3075,15 @@ index adcc4599..e4fd5623 100644 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && + strncmp(file, PKCS11_URI_SCHEME, + strlen(PKCS11_URI_SCHEME)) == 0) { -+ return update_pkcs11_uri(agent_fd, !deleting, file); ++ return update_pkcs11_uri(agent_fd, !deleting, file, qflag); + } +#endif if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -diff --git a/ssh-agent.c b/ssh-agent.c -index 2a4578b0..f6c86240 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c +diff -up openssh/ssh-agent.c.pkcs11-uri openssh/ssh-agent.c +--- openssh/ssh-agent.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-agent.c 2018-10-12 13:52:55.454191434 +0200 @@ -546,10 +546,72 @@ no_identities(SocketEntry *e) } @@ -3177,7 +3158,7 @@ index 2a4578b0..f6c86240 100644 int r, i, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; -@@ -585,28 +645,23 @@ process_add_smartcard_key(SocketEntry *e) +@@ -585,28 +647,23 @@ process_add_smartcard_key(SocketEntry *e goto send; } } @@ -3214,7 +3195,7 @@ index 2a4578b0..f6c86240 100644 id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&idtab->idlist, id, next); -@@ -620,6 +675,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -620,6 +677,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -3222,7 +3203,7 @@ index 2a4578b0..f6c86240 100644 free(keys); send_status(e, success); } -@@ -627,7 +683,7 @@ send: +@@ -627,7 +685,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -3231,7 +3212,7 @@ index 2a4578b0..f6c86240 100644 int r, success = 0; Identity *id, *nxt; -@@ -638,30 +694,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -638,30 +696,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -3268,11 +3249,173 @@ index 2a4578b0..f6c86240 100644 send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index d1ffc30c..00e38049 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -820,6 +820,7 @@ do_download(struct passwd *pw) +diff -up openssh/ssh_config.5.pkcs11-uri openssh/ssh_config.5 +--- openssh/ssh_config.5.pkcs11-uri 2018-10-12 13:52:55.437191293 +0200 ++++ openssh/ssh_config.5 2018-10-12 13:52:55.459191475 +0200 +@@ -991,6 +991,19 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query argument ++.Cm module-path ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +diff -up openssh/ssh.c.pkcs11-uri openssh/ssh.c +--- openssh/ssh.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh.c 2018-10-12 13:52:55.458191467 +0200 +@@ -769,6 +769,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) < 0) + fprintf(stderr, "Warning: Identity file %s " +@@ -1975,6 +1983,45 @@ ssh_session2(struct ssh *ssh, struct pas + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(struct passwd *pw) +@@ -1989,10 +2036,6 @@ load_public_identity_files(struct passwd + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2005,32 +2048,46 @@ load_public_identity_files(struct passwd + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = +- xstrdup(options.pkcs11_provider); /* XXX */ +- n_ids++; +- } +- free(keys); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = percent_expand(cp, "d", pw->pw_dir, + "u", pw->pw_name, "l", thishost, "h", host, + "r", options.user, (char *)NULL); +diff -up openssh/ssh-keygen.c.pkcs11-uri openssh/ssh-keygen.c +--- openssh/ssh-keygen.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-keygen.c 2018-10-12 13:52:55.455191442 +0200 +@@ -825,6 +825,7 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -3280,11 +3423,10 @@ index d1ffc30c..00e38049 100644 fprintf(stdout, "\n"); } sshkey_free(keys[i]); -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index a023f5f4..882e8381 100644 ---- a/ssh-pkcs11-client.c -+++ b/ssh-pkcs11-client.c -@@ -117,6 +117,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, +diff -up openssh/ssh-pkcs11-client.c.pkcs11-uri openssh/ssh-pkcs11-client.c +--- openssh/ssh-pkcs11-client.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-pkcs11-client.c 2018-10-12 13:52:55.455191442 +0200 +@@ -126,6 +126,7 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); key.type = KEY_RSA; key.rsa = rsa; @@ -3292,7 +3434,7 @@ index a023f5f4..882e8381 100644 if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); return -1; -@@ -195,6 +196,8 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) +@@ -210,6 +211,8 @@ pkcs11_add_provider(char *name, char *pi u_int nkeys, i; struct sshbuf *msg; @@ -3301,7 +3443,7 @@ index a023f5f4..882e8381 100644 if (fd < 0 && pkcs11_start_helper() < 0) return (-1); -@@ -208,6 +211,7 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp) +@@ -226,6 +229,7 @@ pkcs11_add_provider(char *name, char *pi if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); @@ -3309,11 +3451,861 @@ index a023f5f4..882e8381 100644 for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c -new file mode 100644 -index 00000000..da15c164 ---- /dev/null -+++ b/ssh-pkcs11-uri.c +diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c +--- openssh/ssh-pkcs11.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-pkcs11.c 2018-10-12 13:54:35.755023297 +0200 +@@ -49,8 +49,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -59,6 +59,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -71,10 +78,46 @@ struct pkcs11_key { + RSA_METHOD *rsa_method; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ if (key->type != KEY_RSA || ++ (k11 = RSA_get_app_data(key->rsa)) == NULL) ++ return -1; ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + int + pkcs11_init(int interactive) + { +@@ -90,26 +133,63 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug("pkcs11_provider_finalize: %p refcount %d valid %d", +- p, p->refcount, p->valid); +- if (!p->valid) ++ debug("%s: %p refcount %d valid %d", __func__, ++ m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug("%s: %p refcount %d", __func__, m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error("%s: %p still valid", __func__, m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared libarary, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug("%s: %p refcount %d valid %d", __func__, ++ p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -119,12 +199,11 @@ pkcs11_provider_finalize(struct pkcs11_p + static void + pkcs11_provider_unref(struct pkcs11_provider *p) + { +- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); ++ debug("%s: %p refcount %d", __func__, p, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error("pkcs11_provider_unref: %p still valid", p); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); ++ free(p->name); + free(p); + } + } +@@ -142,6 +221,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -156,19 +249,52 @@ pkcs11_provider_lookup(char *provider_id + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) + { ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) ++{ + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3("%s(%s): called", __func__, provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + /* openssl callback for freeing an RSA key */ +@@ -185,6 +311,7 @@ pkcs11_rsa_finish(RSA *rsa) + pkcs11_provider_unref(k11->provider); + RSA_meth_free(k11->rsa_method); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + return (rv); +@@ -201,8 +328,8 @@ pkcs11_find(struct pkcs11_provider *p, C + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -249,12 +376,13 @@ pkcs11_rsa_private_encrypt(int flen, con + error("RSA_get_app_data failed for rsa %p", rsa); + return (-1); + } +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || !k11->provider->module ++ || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider for rsa %p", rsa); + return (-1); + } +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (!pkcs11_interactive) { + error("need pin entry%s", (si->token.flags & +@@ -313,7 +441,7 @@ pkcs11_rsa_private_decrypt(int flen, con + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + const RSA_METHOD *def = RSA_get_default_method(); +@@ -328,6 +456,11 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } + k11->rsa_method = RSA_meth_dup(def); + if (k11->rsa_method == NULL) + fatal("%s: RSA_meth_dup failed", __func__); +@@ -371,16 +504,16 @@ pkcs11_open_session(struct pkcs11_provid + CK_SESSION_HANDLE session; + int login_required; + +- f = p->function_list; +- login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; ++ f = p->module->function_list; ++ login_required = p->module->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; + if (pin && login_required && !strlen(pin)) { + error("pin required"); + return (-1); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) + != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin) { +@@ -392,9 +525,9 @@ pkcs11_open_session(struct pkcs11_provid + error("C_CloseSession failed: %lu", rv); + return (-1); + } +- p->slotinfo[slotidx].logged_in = 1; ++ p->module->slotinfo[slotidx].logged_in = 1; + } +- p->slotinfo[slotidx].session = session; ++ p->module->slotinfo[slotidx].session = session; + return (0); + } + +@@ -404,38 +537,62 @@ pkcs11_open_session(struct pkcs11_provid + * keysp points to an (possibly empty) array with *nkeys keys. + */ + static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, +- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) ++ CK_ATTRIBUTE [], size_t, CK_ATTRIBUTE [3], struct sshkey ***, int *) + __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); + + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, int *nkeys) ++ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) + { ++ size_t filter_size = 1; + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; + CK_ATTRIBUTE pubkey_filter[] = { +- { CKA_CLASS, NULL, sizeof(pubkey_class) } ++ { CKA_CLASS, NULL, sizeof(pubkey_class) }, ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 } + }; + CK_ATTRIBUTE cert_filter[] = { +- { CKA_CLASS, NULL, sizeof(cert_class) } ++ { CKA_CLASS, NULL, sizeof(cert_class) }, ++ { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 } + }; + CK_ATTRIBUTE pubkey_attribs[] = { + { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 } + }; + CK_ATTRIBUTE cert_attribs[] = { + { CKA_ID, NULL, 0 }, ++ { CKA_LABEL, NULL, 0 }, + { CKA_SUBJECT, NULL, 0 }, + { CKA_VALUE, NULL, 0 } + }; + pubkey_filter[0].pValue = &pubkey_class; + cert_filter[0].pValue = &cert_class; + +- if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, +- keysp, nkeys) < 0 || +- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, +- keysp, nkeys) < 0) ++ if (uri->id != NULL) { ++ pubkey_filter[filter_size].pValue = uri->id; ++ pubkey_filter[filter_size].ulValueLen = uri->id_len; ++ cert_filter[filter_size].pValue = uri->id; ++ cert_filter[filter_size].ulValueLen = uri->id_len; ++ filter_size++; ++ } ++ if (uri->object != NULL) { ++ pubkey_filter[filter_size].pValue = uri->object; ++ pubkey_filter[filter_size].ulValueLen = strlen(uri->object); ++ pubkey_filter[filter_size].type = CKA_LABEL; ++ cert_filter[filter_size].pValue = uri->object; ++ cert_filter[filter_size].ulValueLen = strlen(uri->object); ++ cert_filter[filter_size].type = CKA_LABEL; ++ filter_size++; ++ } ++ ++ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, ++ pubkey_attribs, keysp, nkeys) < 0 || ++ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, ++ cert_attribs, keysp, nkeys) < 0) + return (-1); + return (0); + } +@@ -462,14 +619,15 @@ have_rsa_key(const RSA *rsa) + + static int + pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, +- CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], ++ CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], + struct sshkey ***keysp, int *nkeys) + { + struct sshkey *key; + RSA *rsa; + X509 *x509; +- EVP_PKEY *evp; ++ EVP_PKEY *evp = NULL; + int i; ++ int nattribs = 4; + const u_char *cp; + CK_RV rv; + CK_OBJECT_HANDLE obj; +@@ -477,16 +635,15 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + /* setup a filter the looks for public keys */ +- if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { ++ if ((rv = f->C_FindObjectsInit(session, filter, filter_size)) != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + return (-1); + } + while (1) { +- /* XXX 3 attributes in attribs[] */ +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < nattribs; i++) { + attribs[i].pValue = NULL; + attribs[i].ulValueLen = 0; + } +@@ -494,22 +651,22 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + || nfound == 0) + break; + /* found a key, so figure out size of the attributes */ +- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) ++ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + continue; + } + /* +- * Allow CKA_ID (always first attribute) to be empty, but +- * ensure that none of the others are zero length. ++ * Allow CKA_ID (always first attribute) and CKA_LABEL (second) ++ * to be empty, but ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (attribs[1].ulValueLen == 0 || +- attribs[2].ulValueLen == 0) { ++ if (attribs[2].ulValueLen == 0 || ++ attribs[3].ulValueLen == 0) { + continue; + } + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) { ++ for (i = 0; i < nattribs; i++) { + if (attribs[i].ulValueLen > 0) { + attribs[i].pValue = xmalloc( + attribs[i].ulValueLen); +@@ -517,23 +674,23 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } + + /* +- * retrieve ID, modulus and public exponent of RSA key, +- * or ID, subject and value for certificates. ++ * retrieve ID, label, modulus and public exponent of RSA key, ++ * or ID, label, subject and value for certificates. + */ + rsa = NULL; +- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) ++ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); +- } else if (attribs[1].type == CKA_MODULUS ) { ++ } else if (attribs[2].type == CKA_MODULUS ) { + if ((rsa = RSA_new()) == NULL) { + error("RSA_new failed"); + } else { + BIGNUM *rsa_n, *rsa_e; + +- rsa_n = BN_bin2bn(attribs[1].pValue, +- attribs[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(attribs[2].pValue, ++ rsa_n = BN_bin2bn(attribs[2].pValue, + attribs[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(attribs[3].pValue, ++ attribs[3].ulValueLen, NULL); + if (rsa_n != NULL && rsa_e != NULL) { + if (!RSA_set0_key(rsa, + rsa_n, rsa_e, NULL)) +@@ -544,10 +701,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + BN_free(rsa_e); + } + } else { +- cp = attribs[2].pValue; ++ cp = attribs[3].pValue; + if ((x509 = X509_new()) == NULL) { + error("X509_new failed"); +- } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) ++ } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) + == NULL) { + error("d2i_X509 failed"); + } else if ((evp = X509_get_pubkey(x509)) == NULL || +@@ -559,9 +716,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + error("RSAPublicKey_dup"); + } + X509_free(x509); ++ EVP_PKEY_free(evp); + } + if (rsa && have_rsa_key(rsa) && +- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { ++ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + key->rsa = rsa; +@@ -580,7 +738,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + } else if (rsa) { + RSA_free(rsa); + } +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattribs; i++) + free(attribs[i].pValue); + } + if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) +@@ -592,126 +750,239 @@ pkcs11_fetch_keys_filter(struct pkcs11_p + int + pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) + { +- int nkeys, need_finalize = 0; +- struct pkcs11_provider *p = NULL; ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_add_provider_by_uri(uri, pin, keyp); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++struct pkcs11_provider * ++pkcs11_provider_initialize(struct pkcs11_uri *uri) ++{ ++ int need_finalize = 0; + void *handle = NULL; + CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); + CK_RV rv; + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_provider *p; ++ struct pkcs11_module *m; + +- *keyp = NULL; +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug("%s: provider already registered: %s", +- __func__, provider_id); ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error("%s: No module path provided", __func__); + goto fail; ++#endif ++ } else ++ provider_module = strdup(uri->module_path); ++ ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); ++ ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug("%s: provider module already initialized: %s", ++ __func__, provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ return p; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-libarary */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ m->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); ++ goto fail; ++ } ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug("%s: Skipping provider %s not matching library_manufacturer", ++ __func__, m->info.manufacturerID); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { ++ if (m->nslots == 0) { + debug("%s: provider %s returned no slots", __func__, +- provider_id); ++ provider_module); + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->valid = 1; + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (unsigned long)i, rv); ++ "failed: %lu", provider_module, (unsigned long)i, rv); + continue; + } + if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2("%s: ignoring uninitialised token in " +- "provider %s slot %lu", __func__, +- provider_id, (unsigned long)i); + continue; + } + rmspace(token->label, sizeof(token->label)); + rmspace(token->manufacturerID, sizeof(token->manufacturerID)); + rmspace(token->model, sizeof(token->model)); + rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ return p; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ free(p); ++ if (handle) ++ dlclose(handle); ++ return NULL; ++} ++ ++int ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, struct sshkey ***keyp) ++{ ++ int nkeys; ++ struct pkcs11_provider *p = NULL; ++ CK_TOKEN_INFO *token; ++ CK_ULONG i; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug("%s: called, provider_uri = %s", __func__, provider_uri); ++ ++ *keyp = NULL; ++ if ((p = pkcs11_provider_initialize(uri)) == NULL) { ++ debug("%s: failed to initialize provider: %s", ++ __func__, provider_uri); ++ goto fail; ++ } ++ ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2("%s: ignoring uninitialised token in " ++ "provider %s slot %lu", __func__, ++ provider_uri, (unsigned long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2("%s: ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", __func__, ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2("%s: ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", __func__, ++ token->manufacturerID, (unsigned long)i); ++ continue; ++ } + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); +- /* open session, login with pin and retrieve public keys */ +- if (pkcs11_open_session(p, i, pin) == 0) +- pkcs11_fetch_keys(p, i, keyp, &nkeys); ++ /* open session if not yet opened, login with pin ++ * and retrieve public keys */ ++ if ((p->module->slotinfo[i].session != 0) || ++ pkcs11_open_session(p, i, pin) == 0) ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); + } + if (nkeys > 0) { +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ ++ free(provider_uri); + return (nkeys); + } +- debug("%s: provider %s returned no keys", __func__, provider_id); ++ debug("%s: provider %s returned no keys", __func__, provider_uri); + /* don't add the provider, since it does not have any keys */ + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); ++ free(provider_uri); + return (-1); + } + +diff -up openssh/ssh-pkcs11.h.pkcs11-uri openssh/ssh-pkcs11.h +--- openssh/ssh-pkcs11.h.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 ++++ openssh/ssh-pkcs11.h 2018-10-12 13:52:55.457191459 +0200 +@@ -14,10 +14,15 @@ + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ ++ ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + + #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) + #undef ENABLE_PKCS11 +diff -up openssh/ssh-pkcs11-uri.c.pkcs11-uri openssh/ssh-pkcs11-uri.c +--- openssh/ssh-pkcs11-uri.c.pkcs11-uri 2018-10-12 13:52:55.456191450 +0200 ++++ openssh/ssh-pkcs11-uri.c 2018-10-12 13:52:55.455191442 +0200 @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3710,11 +4702,9 @@ index 00000000..da15c164 +} + +#endif /* ENABLE_PKCS11 */ -diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h -new file mode 100644 -index 00000000..609c4df1 ---- /dev/null -+++ b/ssh-pkcs11-uri.h +diff -up openssh/ssh-pkcs11-uri.h.pkcs11-uri openssh/ssh-pkcs11-uri.h +--- openssh/ssh-pkcs11-uri.h.pkcs11-uri 2018-10-12 13:52:55.456191450 +0200 ++++ openssh/ssh-pkcs11-uri.h 2018-10-12 13:52:55.456191450 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3757,1015 +4747,3 @@ index 00000000..609c4df1 +struct pkcs11_uri *pkcs11_uri_init(); +char * pkcs11_uri_get(struct pkcs11_uri *uri); + -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 88c9d6e2..a29b4451 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -48,8 +48,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -58,6 +58,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -70,10 +77,46 @@ struct pkcs11_key { - RSA_METHOD rsa_method; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ if (key->type != KEY_RSA || -+ (k11 = RSA_get_app_data(key->rsa)) == NULL) -+ return -1; -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - int - pkcs11_init(int interactive) - { -@@ -89,26 +132,63 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); -- if (!p->valid) -+ debug("%s: %p refcount %d valid %d", __func__, -+ m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug("%s: %p refcount %d", __func__, m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error("%s: %p still valid", __func__, m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared libarary, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug("%s: %p refcount %d valid %d", __func__, -+ p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -118,12 +198,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) - static void - pkcs11_provider_unref(struct pkcs11_provider *p) - { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug("%s: %p refcount %d", __func__, p, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); -+ free(p->name); - free(p); - } - } -@@ -141,6 +220,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -155,19 +248,52 @@ pkcs11_provider_lookup(char *provider_id) - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) -+{ -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) - { - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3("%s(%s): called", __func__, provider_uri); -+ -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - /* openssl callback for freeing an RSA key */ -@@ -183,6 +309,7 @@ pkcs11_rsa_finish(RSA *rsa) - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); -+ free(k11->label); - free(k11); - } - return (rv); -@@ -199,8 +327,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -247,12 +375,13 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - error("RSA_get_app_data failed for rsa %p", rsa); - return (-1); - } -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || !k11->provider->module -+ || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider for rsa %p", rsa); - return (-1); - } -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (!pkcs11_interactive) { - error("need pin entry%s", (si->token.flags & -@@ -311,7 +440,7 @@ pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - /* redirect private key operations for rsa key to pkcs11 token */ - static int - pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - const RSA_METHOD *def = RSA_get_default_method(); -@@ -326,6 +455,11 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } - k11->orig_finish = def->finish; - memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); - k11->rsa_method.name = "pkcs11"; -@@ -372,16 +506,16 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) - CK_SESSION_HANDLE session; - int login_required; - -- f = p->function_list; -- login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; -+ f = p->module->function_list; -+ login_required = p->module->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; - if (pin && login_required && !strlen(pin)) { - error("pin required"); - return (-1); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) - != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin) { -@@ -393,9 +527,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) - error("C_CloseSession failed: %lu", rv); - return (-1); - } -- p->slotinfo[slotidx].logged_in = 1; -+ p->module->slotinfo[slotidx].logged_in = 1; - } -- p->slotinfo[slotidx].session = session; -+ p->module->slotinfo[slotidx].session = session; - return (0); - } - -@@ -405,38 +539,62 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) - * keysp points to an (possibly empty) array with *nkeys keys. - */ - static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, -- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) -+ CK_ATTRIBUTE [], size_t, CK_ATTRIBUTE [3], struct sshkey ***, int *) - __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); - - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, int *nkeys) -+ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) - { -+ size_t filter_size = 1; - CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; - CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; - CK_ATTRIBUTE pubkey_filter[] = { -- { CKA_CLASS, NULL, sizeof(pubkey_class) } -+ { CKA_CLASS, NULL, sizeof(pubkey_class) }, -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 } - }; - CK_ATTRIBUTE cert_filter[] = { -- { CKA_CLASS, NULL, sizeof(cert_class) } -+ { CKA_CLASS, NULL, sizeof(cert_class) }, -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 } - }; - CK_ATTRIBUTE pubkey_attribs[] = { - { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 } - }; - CK_ATTRIBUTE cert_attribs[] = { - { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - pubkey_filter[0].pValue = &pubkey_class; - cert_filter[0].pValue = &cert_class; - -- if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, -- keysp, nkeys) < 0 || -- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, -- keysp, nkeys) < 0) -+ if (uri->id != NULL) { -+ pubkey_filter[filter_size].pValue = uri->id; -+ pubkey_filter[filter_size].ulValueLen = uri->id_len; -+ cert_filter[filter_size].pValue = uri->id; -+ cert_filter[filter_size].ulValueLen = uri->id_len; -+ filter_size++; -+ } -+ if (uri->object != NULL) { -+ pubkey_filter[filter_size].pValue = uri->object; -+ pubkey_filter[filter_size].ulValueLen = strlen(uri->object); -+ pubkey_filter[filter_size].type = CKA_LABEL; -+ cert_filter[filter_size].pValue = uri->object; -+ cert_filter[filter_size].ulValueLen = strlen(uri->object); -+ cert_filter[filter_size].type = CKA_LABEL; -+ filter_size++; -+ } -+ -+ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, -+ pubkey_attribs, keysp, nkeys) < 0 || -+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, -+ cert_attribs, keysp, nkeys) < 0) - return (-1); - return (0); - } -@@ -454,14 +612,15 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) - - static int - pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, -- CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], -+ CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], - struct sshkey ***keysp, int *nkeys) - { - struct sshkey *key; - RSA *rsa; - X509 *x509; -- EVP_PKEY *evp; -+ EVP_PKEY *evp = NULL; - int i; -+ int nattribs = 4; - const u_char *cp; - CK_RV rv; - CK_OBJECT_HANDLE obj; -@@ -470,16 +629,15 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - /* setup a filter the looks for public keys */ -- if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { -+ if ((rv = f->C_FindObjectsInit(session, filter, filter_size)) != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - return (-1); - } - while (1) { -- /* XXX 3 attributes in attribs[] */ -- for (i = 0; i < 3; i++) { -+ for (i = 0; i < nattribs; i++) { - attribs[i].pValue = NULL; - attribs[i].ulValueLen = 0; - } -@@ -487,22 +645,22 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - || nfound == 0) - break; - /* found a key, so figure out size of the attributes */ -- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) -+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) - != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - continue; - } - /* -- * Allow CKA_ID (always first attribute) to be empty, but -- * ensure that none of the others are zero length. -+ * Allow CKA_ID (always first attribute) and CKA_LABEL (second) -+ * to be empty, but ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (attribs[1].ulValueLen == 0 || -- attribs[2].ulValueLen == 0) { -+ if (attribs[2].ulValueLen == 0 || -+ attribs[3].ulValueLen == 0) { - continue; - } - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) { -+ for (i = 0; i < nattribs; i++) { - if (attribs[i].ulValueLen > 0) { - attribs[i].pValue = xmalloc( - attribs[i].ulValueLen); -@@ -510,27 +668,27 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - } - - /* -- * retrieve ID, modulus and public exponent of RSA key, -- * or ID, subject and value for certificates. -+ * retrieve ID, label, modulus and public exponent of RSA key, -+ * or ID, label, subject and value for certificates. - */ - rsa = NULL; -- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) -+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) - != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); -- } else if (attribs[1].type == CKA_MODULUS ) { -+ } else if (attribs[2].type == CKA_MODULUS ) { - if ((rsa = RSA_new()) == NULL) { - error("RSA_new failed"); - } else { -- rsa->n = BN_bin2bn(attribs[1].pValue, -- attribs[1].ulValueLen, NULL); -- rsa->e = BN_bin2bn(attribs[2].pValue, -+ rsa->n = BN_bin2bn(attribs[2].pValue, - attribs[2].ulValueLen, NULL); -+ rsa->e = BN_bin2bn(attribs[3].pValue, -+ attribs[3].ulValueLen, NULL); - } - } else { -- cp = attribs[2].pValue; -+ cp = attribs[3].pValue; - if ((x509 = X509_new()) == NULL) { - error("X509_new failed"); -- } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) -+ } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) - == NULL) { - error("d2i_X509 failed"); - } else if ((evp = X509_get_pubkey(x509)) == NULL || -@@ -546,9 +704,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - error("RSAPublicKey_dup"); - } - X509_free(x509); -+ EVP_PKEY_free(evp); - } - if (rsa && rsa->n && rsa->e && -- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { -+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); - key->rsa = rsa; -@@ -569,7 +728,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - } else if (rsa) { - RSA_free(rsa); - } -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattribs; i++) - free(attribs[i].pValue); - } - if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) -@@ -581,126 +740,239 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, - int - pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) - { -- int nkeys, need_finalize = 0; -- struct pkcs11_provider *p = NULL; -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_add_provider_by_uri(uri, pin, keyp); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+struct pkcs11_provider * -+pkcs11_provider_initialize(struct pkcs11_uri *uri) -+{ -+ int need_finalize = 0; - void *handle = NULL; - CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); - CK_RV rv; - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -+ char *provider_module = NULL; -+ struct pkcs11_provider *p; -+ struct pkcs11_module *m; - -- *keyp = NULL; -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug("%s: provider already registered: %s", -- __func__, provider_id); -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error("%s: No module path provided", __func__); - goto fail; -+#endif -+ } else -+ provider_module = strdup(uri->module_path); -+ -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); -+ -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug("%s: provider module already initialized: %s", -+ __func__, provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ return p; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } -+ - /* open shared pkcs11-libarary */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } -- p = xcalloc(1, sizeof(*p)); -- p->name = xstrdup(provider_id); -- p->handle = handle; -+ m->handle = handle; - /* setup the pkcs11 callbacks */ - if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug("%s: Skipping provider %s not matching library_manufacturer", -+ __func__, m->info.manufacturerID); -+ goto fail; -+ } -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -+ if (m->nslots == 0) { - debug("%s: provider %s returned no slots", __func__, -- provider_id); -+ provider_module); - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->valid = 1; - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ -+ for (i = 0; i < m->nslots; i++) { -+ token = &m->slotinfo[i].token; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (unsigned long)i, rv); -+ "failed: %lu", provider_module, (unsigned long)i, rv); - continue; - } - if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -- debug2("%s: ignoring uninitialised token in " -- "provider %s slot %lu", __func__, -- provider_id, (unsigned long)i); - continue; - } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ return p; -+ -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ free(p); -+ if (handle) -+ dlclose(handle); -+ return NULL; -+} -+ -+int -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, struct sshkey ***keyp) -+{ -+ int nkeys; -+ struct pkcs11_provider *p = NULL; -+ CK_TOKEN_INFO *token; -+ CK_ULONG i; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); -+ -+ *keyp = NULL; -+ if ((p = pkcs11_provider_initialize(uri)) == NULL) { -+ debug("%s: failed to initialize provider: %s", -+ __func__, provider_uri); -+ goto fail; -+ } -+ -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; -+ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -+ debug2("%s: ignoring uninitialised token in " -+ "provider %s slot %lu", __func__, -+ provider_uri, (unsigned long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2("%s: ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", __func__, -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2("%s: ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", __func__, -+ token->manufacturerID, (unsigned long)i); -+ continue; -+ } - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); -- /* open session, login with pin and retrieve public keys */ -- if (pkcs11_open_session(p, i, pin) == 0) -- pkcs11_fetch_keys(p, i, keyp, &nkeys); -+ /* open session if not yet opened, login with pin -+ * and retrieve public keys */ -+ if ((p->module->slotinfo[i].session != 0) || -+ pkcs11_open_session(p, i, pin) == 0) -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); - } - if (nkeys > 0) { -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -+ free(provider_uri); - return (nkeys); - } -- debug("%s: provider %s returned no keys", __func__, provider_id); -+ debug("%s: provider %s returned no keys", __func__, provider_uri); - /* don't add the provider, since it does not have any keys */ - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); -+ free(provider_uri); - return (-1); - } - -diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index 0ced74f2..c63a88f6 100644 ---- a/ssh-pkcs11.h -+++ b/ssh-pkcs11.h -@@ -14,10 +14,15 @@ - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -+ -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - - #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) - #undef ENABLE_PKCS11 -diff --git a/ssh.c b/ssh.c -index d3619fe2..180eb2e0 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -769,6 +769,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) < 0) - fprintf(stderr, "Warning: Identity file %s " -@@ -1999,6 +2007,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(struct passwd *pw) -@@ -2011,10 +2058,6 @@ load_public_identity_files(struct passwd *pw) - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2023,32 +2066,46 @@ load_public_identity_files(struct passwd *pw) - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = -- xstrdup(options.pkcs11_provider); /* XXX */ -- n_ids++; -- } -- free(keys); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); -+ -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = percent_expand(cp, "d", pw->pw_dir, - "u", pw->pw_name, "l", thishost, "h", host, - "r", options.user, (char *)NULL); -diff --git a/ssh_config.5 b/ssh_config.5 -index 71705cab..e0266609 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -919,6 +919,19 @@ may also be used in conjunction with - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query argument -+.Cm module-path -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 084c903..6450b5f 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -102,12 +102,14 @@ diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c --- openssh-7.7p1/entropy.c.fips 2018-08-08 10:08:40.698718928 +0200 +++ openssh-7.7p1/entropy.c 2018-08-08 10:08:40.822719973 +0200 -@@ -217,6 +217,9 @@ seed_rng(void) +@@ -217,6 +217,11 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + /* clean the PRNG status when exiting the program */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + atexit(RAND_cleanup); ++#endif + #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { @@ -377,16 +379,16 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h + "hmac-sha1" +#endif + - #else /* WITH_OPENSSL */ - - #define KEX_SERVER_KEX \ + /* Not a KEX value, but here so all the algorithm defaults are together */ + #define SSH_ALLOWED_CA_SIGALGS \ + "ecdsa-sha2-nistp256," \ diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c --- openssh-7.7p1/readconf.c.fips 2018-08-08 10:08:40.769719527 +0200 +++ openssh-7.7p1/readconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -2081,17 +2081,18 @@ fill_default_options(Options * options) - all_mac = mac_alg_list(','); +@@ -2081,18 +2081,19 @@ fill_default_options(Options * options) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); -#define ASSEMBLE(what, defaults, all) \ +#define ASSEMBLE(what, defaults, fips_defaults, all) \ do { \ @@ -401,11 +403,13 @@ diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c - ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); - ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); - ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); +- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); + ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); + ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); + ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); + ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); ++ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig); #undef ASSEMBLE free(all_cipher); free(all_mac); @@ -425,10 +429,10 @@ diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-secco diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c --- openssh-7.7p1/servconf.c.fips 2018-08-08 10:08:40.778719603 +0200 +++ openssh-7.7p1/servconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -196,17 +196,18 @@ option_clear_or_none(const char *o) - all_mac = mac_alg_list(','); +@@ -196,18 +196,19 @@ option_clear_or_none(const char *o) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); -#define ASSEMBLE(what, defaults, all) \ +#define ASSEMBLE(what, defaults, fips_defaults, all) \ do { \ @@ -443,12 +447,14 @@ diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c - ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); - ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); - ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); +- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); + ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); + ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); + ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); + ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); ++ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig); #undef ASSEMBLE free(all_cipher); free(all_mac); @@ -464,11 +470,13 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -579,6 +581,14 @@ main(int ac, char **av) +@@ -579,6 +581,16 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); -+ SSLeay_add_all_algorithms(); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ SSLeay_add_all_algorithms(); ++#endif + if (access("/etc/system-fips", F_OK) == 0) + if (! FIPSCHECK_verify(NULL, NULL)){ + if (FIPS_mode()) @@ -520,7 +528,7 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); -@@ -290,21 +293,26 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -290,23 +293,28 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -528,7 +536,9 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c - * client to the key exchange algorithm proposal */ - orig = options.kex_algorithms; - -- if (options.gss_trust_dns) +- if (options.gss_server_identity) +- gss_host = options.gss_server_identity; +- else if (options.gss_trust_dns) - gss_host = (char *)get_canonical_hostname(active_state, 1); - else - gss_host = host; @@ -547,7 +557,9 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c + * client to the key exchange algorithm proposal */ + orig = options.kex_algorithms; + -+ if (options.gss_trust_dns) ++ if (options.gss_server_identity) ++ gss_host = options.gss_server_identity; ++ else if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(active_state, 1); + else + gss_host = host; @@ -605,7 +617,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c #endif __progname = ssh_get_progname(av[0]); -+ SSLeay_add_all_algorithms(); ++ OpenSSL_add_all_algorithms(); + if (access("/etc/system-fips", F_OK) == 0) + if (! FIPSCHECK_verify(NULL, NULL)) { + openlog(__progname, LOG_PID, LOG_AUTHPRIV); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 7acc58a..6ab5e2c 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -113,7 +113,7 @@ index a5a81ed2..63f877f2 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -237,36 +287,186 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -237,36 +287,188 @@ krb5_cleanup_proc(Authctxt *authctxt) } } @@ -195,7 +195,7 @@ index a5a81ed2..63f877f2 100644 + continue; + } else { + p_o = strchr(p_n, '}') + 1; -+ p_o = '\0'; ++ *p_o = '\0'; + debug("%s: unsupported token %s in %s", __func__, p_n, template); + /* unknown token, fallback to the default */ + goto cleanup; @@ -248,7 +248,7 @@ index a5a81ed2..63f877f2 100644 + if (need_environment) + *need_environment = 0; + ret = ssh_krb5_get_cctemplate(ctx, &ccname); -+ if (ret || !ccname || options.kerberos_unique_ticket) { ++ if (ret || !ccname || options.kerberos_unique_ccache) { + /* Otherwise, go with the old method */ + if (ccname) + free(ccname); @@ -307,6 +307,7 @@ index a5a81ed2..63f877f2 100644 + if (krb5_cc_support_switch(ctx, type)) { + debug3("%s: calling cc_new_unique(%s)", __func__, ccname); + ret = krb5_cc_new_unique(ctx, type, NULL, ccache); ++ free(type); + if (ret) + return ret; + @@ -317,6 +318,7 @@ index a5a81ed2..63f877f2 100644 + * it is already unique from above or the type does not support + * collections + */ ++ free(type); + debug3("%s: calling cc_resolve(%s)", __func__, ccname); + return (krb5_cc_resolve(ctx, ccname, ccache)); + } @@ -492,7 +494,7 @@ index cb578658..a6e01df2 100644 options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; -+ options->kerberos_unique_ticket = -1; ++ options->kerberos_unique_ccache = -1; options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; @@ -500,8 +502,8 @@ index cb578658..a6e01df2 100644 options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; -+ if (options->kerberos_unique_ticket == -1) -+ options->kerberos_unique_ticket = 0; ++ if (options->kerberos_unique_ccache == -1) ++ options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) @@ -510,7 +512,7 @@ index cb578658..a6e01df2 100644 sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sChallengeResponseAuthentication, -+ sKerberosGetAFSToken, sKerberosUniqueTicket, ++ sKerberosGetAFSToken, sKerberosUniqueCCache, + sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, @@ -519,13 +521,13 @@ index cb578658..a6e01df2 100644 #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif -+ { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL }, ++ { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, #else { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -533,8 +535,8 @@ index cb578658..a6e01df2 100644 intptr = &options->kerberos_get_afs_token; goto parse_flag; -+ case sKerberosUniqueTicket: -+ intptr = &options->kerberos_unique_ticket; ++ case sKerberosUniqueCCache: ++ intptr = &options->kerberos_unique_ccache; + goto parse_flag; + case sGssAuthentication: @@ -544,7 +546,7 @@ index cb578658..a6e01df2 100644 # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif -+ dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket); ++ dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); @@ -556,7 +558,7 @@ index db8362c6..4fa42d64 100644 * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ -+ int kerberos_unique_ticket; /* If true, the aquired ticket will ++ int kerberos_unique_ccache; /* If true, the acquired ticket will + * be stored in per-session ccache */ int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ @@ -631,16 +633,18 @@ diff --git a/sshd_config.5 b/sshd_config.5 index c0683d4a..2349f477 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -860,6 +860,12 @@ 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 . -+.It Cm KerberosUniqueTicket -+Specifies whether to store the aquired tickets in the per-session credential -+cache or whether to use per-user credential cache, which might overwrite -+tickets aquired in different sessions of the same user. -+The default is -+.Cm no . ++.It Cm KerberosUniqueCCache ++Specifies whether to store the acquired tickets in the per-session credential ++cache under /tmp/ or whether to use per-user credential cache as configured in ++.Pa /etc/krb5.conf . ++The default value ++.Cm no ++can lead to overwriting previous tickets by subseqent connections to the same ++user account. .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. diff --git a/openssh-7.8p1-gsskex.patch b/openssh-7.8p1-gsskex.patch index 6a350c7..2903b69 100644 --- a/openssh-7.8p1-gsskex.patch +++ b/openssh-7.8p1-gsskex.patch @@ -188,7 +188,7 @@ diff -up openssh/configure.ac.gsskex openssh/configure.ac diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c --- openssh/gss-genr.c.gsskex 2018-08-20 07:57:29.000000000 +0200 +++ openssh/gss-genr.c 2018-08-22 13:18:47.444383602 +0200 -@@ -35,18 +35,177 @@ +@@ -35,18 +35,179 @@ #include #include #include @@ -256,7 +256,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + u_char digest[EVP_MAX_MD_SIZE]; + char deroid[2]; + const EVP_MD *evp_md = EVP_md5(); -+ EVP_MD_CTX md; ++ EVP_MD_CTX *md; + + if (gss_enc2oid != NULL) { + for (i = 0; gss_enc2oid[i].encoded != NULL; i++) @@ -270,6 +270,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + if ((buf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + ++ md = EVP_MD_CTX_new(); + oidpos = 0; + for (i = 0; i < gss_supported->count; i++) { + if (gss_supported->elements[i].length < 128 && @@ -278,12 +279,12 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + deroid[0] = SSH_GSS_OIDTYPE; + deroid[1] = gss_supported->elements[i].length; + -+ EVP_DigestInit(&md, evp_md); -+ EVP_DigestUpdate(&md, deroid, 2); -+ EVP_DigestUpdate(&md, ++ EVP_DigestInit(md, evp_md); ++ EVP_DigestUpdate(md, deroid, 2); ++ EVP_DigestUpdate(md, + gss_supported->elements[i].elements, + gss_supported->elements[i].length); -+ EVP_DigestFinal(&md, digest, NULL); ++ EVP_DigestFinal(md, digest, NULL); + + encoded = xmalloc(EVP_MD_size(evp_md) * 2); + enclen = __b64_ntop(digest, EVP_MD_size(evp_md), @@ -311,6 +312,7 @@ diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c + oidpos++; + } + } ++ EVP_MD_CTX_free(md); + gss_enc2oid[oidpos].oid = NULL; + gss_enc2oid[oidpos].encoded = NULL; + @@ -988,7 +990,7 @@ diff -up openssh/kex.c.gsskex openssh/kex.c diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c --- openssh/kexgssc.c.gsskex 2018-08-22 11:47:33.311216457 +0200 +++ openssh/kexgssc.c 2018-08-22 11:47:33.311216457 +0200 -@@ -0,0 +1,338 @@ +@@ -0,0 +1,341 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1049,6 +1051,7 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + BIGNUM *shared_secret = NULL; + BIGNUM *p = NULL; + BIGNUM *g = NULL; ++ const BIGNUM *pub_key, *p1, *g1; + u_char *kbuf; + u_char *serverhostkey = NULL; + u_char *empty = ""; @@ -1110,8 +1113,9 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); + } + -+ /* Step 1 - e is dh->pub_key */ ++ /* Step 1 - e is pub_key */ + dh_gen_key(dh, ssh->kex->we_need * 8); ++ DH_get0_key(dh, &pub_key, NULL); + + /* This is f, we initialise it now to make life easier */ + dh_server_pub = BN_new(); @@ -1159,7 +1163,7 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + packet_start(SSH2_MSG_KEXGSS_INIT); + packet_put_string(send_tok.value, + send_tok.length); -+ packet_put_bignum2(dh->pub_key); ++ packet_put_bignum2((BIGNUM *)pub_key); + first = 0; + } else { + packet_start(SSH2_MSG_KEXGSS_CONTINUE); @@ -1266,13 +1270,14 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, -+ dh->pub_key, /* e */ ++ pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ + hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: ++ DH_get0_pqg(dh, &p1, NULL, &g1); + kexgex_hash( + ssh->kex->hash_alg, + ssh->kex->client_version_string, @@ -1281,8 +1286,8 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + min, nbits, max, -+ dh->p, dh->g, -+ dh->pub_key, ++ p, g, ++ pub_key, + dh_server_pub, + shared_secret, + hash, &hashlen @@ -1330,7 +1335,7 @@ diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c --- openssh/kexgsss.c.gsskex 2018-08-22 11:47:33.311216457 +0200 +++ openssh/kexgsss.c 2018-08-22 11:47:33.311216457 +0200 -@@ -0,0 +1,297 @@ +@@ -0,0 +1,300 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1410,6 +1415,7 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + char *mechs; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t hashlen; ++ const BIGNUM *p, *g, *pub_key; + + /* Initialise GSSAPI */ + @@ -1455,9 +1461,10 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + if (dh == NULL) + packet_disconnect("Protocol error: no matching group found"); + ++ DH_get0_pqg(dh, &p, NULL, &g); + packet_start(SSH2_MSG_KEXGSS_GROUP); -+ packet_put_bignum2(dh->p); -+ packet_put_bignum2(dh->g); ++ packet_put_bignum2((BIGNUM *)p); ++ packet_put_bignum2((BIGNUM *)g); + packet_send(); + + packet_write_wait(); @@ -1549,6 +1556,7 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + memset(kbuf, 0, klen); + free(kbuf); + ++ DH_get0_key(dh, &pub_key, NULL); + hashlen = sizeof(hash); + switch (ssh->kex->kex_type) { + case KEX_GSS_GRP1_SHA1: @@ -1558,7 +1566,7 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + NULL, 0, /* Change this if we start sending host keys */ -+ dh_client_pub, dh->pub_key, shared_secret, ++ dh_client_pub, pub_key, shared_secret, + hash, &hashlen + ); + break; @@ -1570,9 +1578,9 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), + NULL, 0, + cmin, nbits, cmax, -+ dh->p, dh->g, ++ p, g, + dh_client_pub, -+ dh->pub_key, ++ pub_key, + shared_secret, + hash, &hashlen + ); @@ -1596,7 +1604,7 @@ diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c + fatal("Couldn't get MIC"); + + packet_start(SSH2_MSG_KEXGSS_COMPLETE); -+ packet_put_bignum2(dh->pub_key); ++ packet_put_bignum2(pub_key); + packet_put_string(msg_tok.value,msg_tok.length); + + if (send_tok.length != 0) { @@ -1928,7 +1936,7 @@ diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c + + sshbuf_free(m); + -+ return(major); ++ return (major); +} + +int @@ -2423,7 +2431,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c /* * SSH2 key exchange */ -@@ -162,9 +280,34 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -162,9 +280,36 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2441,7 +2449,9 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + * client to the key exchange algorithm proposal */ + orig = options.kex_algorithms; + -+ if (options.gss_trust_dns) ++ if (options.gss_server_identity) ++ gss_host = options.gss_server_identity; ++ else if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(active_state, 1); + else + gss_host = host; @@ -2617,16 +2627,6 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c diff -up openssh/sshd.c.gsskex openssh/sshd.c --- openssh/sshd.c.gsskex 2018-08-22 11:47:33.299216360 +0200 +++ openssh/sshd.c 2018-08-22 13:34:28.455975954 +0200 -@@ -537,8 +537,7 @@ privsep_preauth_child(void) - - #ifdef GSSAPI - /* Cache supported mechanism OIDs for later use */ -- if (options.gss_authentication) -- ssh_gssapi_prepare_supported_oids(); -+ ssh_gssapi_prepare_supported_oids(); - #endif - - reseed_prngs(); @@ -887,8 +887,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %u hostkeys", __func__, nkeys); diff --git a/openssh-7.8p1-gsissh.patch b/openssh-7.9p1-gsissh.patch similarity index 88% rename from openssh-7.8p1-gsissh.patch rename to openssh-7.9p1-gsissh.patch index 7e0d6dc..29e5ddf 100644 --- a/openssh-7.8p1-gsissh.patch +++ b/openssh-7.9p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-7.8p1.orig/auth2.c openssh-7.8p1/auth2.c ---- openssh-7.8p1.orig/auth2.c 2018-10-24 14:09:16.619775688 +0200 -+++ openssh-7.8p1/auth2.c 2018-10-24 14:09:54.219377927 +0200 +diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c +--- openssh-7.9p1.orig/auth2.c 2018-10-23 23:08:05.762762297 +0200 ++++ openssh-7.9p1/auth2.c 2018-10-23 23:09:11.656055302 +0200 @@ -270,7 +270,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -99,9 +99,9 @@ diff -Nur openssh-7.8p1.orig/auth2.c openssh-7.8p1/auth2.c "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c ---- openssh-7.8p1.orig/auth2-gss.c 2018-10-24 14:09:16.410777899 +0200 -+++ openssh-7.8p1/auth2-gss.c 2018-10-24 17:39:13.477216029 +0200 +diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c +--- openssh-7.9p1.orig/auth2-gss.c 2018-10-23 23:08:05.758762340 +0200 ++++ openssh-7.9p1/auth2-gss.c 2018-10-24 17:39:01.494342784 +0200 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -136,14 +136,14 @@ diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, - &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -- authctxt->pw)); +- authctxt->pw, 1)); + &gssbuf, &mic))) || + !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, + &gssbuf2, &mic)))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1 /* gssapi-keyex */)); ++ authctxt->pw, 1)); + } + } @@ -234,11 +234,11 @@ diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c fatal("%s: %s", __func__, ssh_err(r)); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -- authctxt->pw)); +- authctxt->pw, 1)); + /* user should be set if valid but we double-check here */ + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1 /* gssapi-keyex */)); ++ authctxt->pw, 1)); + } if ((!use_privsep || mm_is_monitor()) && @@ -249,7 +249,7 @@ diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = -- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); +- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0)); - else + gssapi_set_username(authctxt); + @@ -257,7 +257,7 @@ diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0 /* !gssapi-keyex */)); ++ authctxt->pw, 0)); + } + } else { logit("GSSAPI MIC check failed"); @@ -289,9 +289,9 @@ diff -Nur openssh-7.8p1.orig/auth2-gss.c openssh-7.8p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c ---- openssh-7.8p1.orig/auth.c 2018-10-24 14:09:16.621775667 +0200 -+++ openssh-7.8p1/auth.c 2018-10-24 14:09:54.220377916 +0200 +diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c +--- openssh-7.9p1.orig/auth.c 2018-10-23 23:08:05.763762286 +0200 ++++ openssh-7.9p1/auth.c 2018-10-23 23:09:11.658055281 +0200 @@ -76,6 +76,9 @@ #include "compat.h" #include "channels.h" @@ -302,7 +302,7 @@ diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c /* import */ extern ServerOptions options; extern int use_privsep; -@@ -339,7 +342,8 @@ +@@ -343,7 +346,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -312,7 +312,7 @@ diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -365,6 +369,23 @@ +@@ -369,6 +373,23 @@ if (authenticated == 0 && !authctxt->postponed && !partial) audit_event(audit_classify_auth(method)); #endif @@ -336,7 +336,7 @@ diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c } -@@ -577,6 +598,10 @@ +@@ -581,6 +602,10 @@ #endif pw = getpwnam(user); @@ -347,7 +347,7 @@ diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -596,7 +621,8 @@ +@@ -600,7 +625,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -357,9 +357,9 @@ diff -Nur openssh-7.8p1.orig/auth.c openssh-7.8p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.8p1.orig/auth.h openssh-7.8p1/auth.h ---- openssh-7.8p1.orig/auth.h 2018-10-24 14:09:16.622775656 +0200 -+++ openssh-7.8p1/auth.h 2018-10-24 14:09:54.220377916 +0200 +diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h +--- openssh-7.9p1.orig/auth.h 2018-10-23 23:08:05.763762286 +0200 ++++ openssh-7.9p1/auth.h 2018-10-23 23:09:11.658055281 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -369,9 +369,9 @@ diff -Nur openssh-7.8p1.orig/auth.h openssh-7.8p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-7.8p1.orig/auth-pam.c openssh-7.8p1/auth-pam.c ---- openssh-7.8p1.orig/auth-pam.c 2018-10-24 14:09:16.677775074 +0200 -+++ openssh-7.8p1/auth-pam.c 2018-10-24 14:09:54.221377906 +0200 +diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c +--- openssh-7.9p1.orig/auth-pam.c 2018-10-23 23:08:05.624763778 +0200 ++++ openssh-7.9p1/auth-pam.c 2018-10-23 23:09:11.659055270 +0200 @@ -288,6 +288,55 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -514,9 +514,9 @@ diff -Nur openssh-7.8p1.orig/auth-pam.c openssh-7.8p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.8p1.orig/auth-pam.h openssh-7.8p1/auth-pam.h ---- openssh-7.8p1.orig/auth-pam.h 2018-10-24 14:09:16.320778851 +0200 -+++ openssh-7.8p1/auth-pam.h 2018-10-24 14:09:54.221377906 +0200 +diff -Nur openssh-7.9p1.orig/auth-pam.h openssh-7.9p1/auth-pam.h +--- openssh-7.9p1.orig/auth-pam.h 2018-10-23 23:08:05.625763767 +0200 ++++ openssh-7.9p1/auth-pam.h 2018-10-23 23:09:11.659055270 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -524,9 +524,9 @@ diff -Nur openssh-7.8p1.orig/auth-pam.h openssh-7.8p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.8p1.orig/canohost.c openssh-7.8p1/canohost.c ---- openssh-7.8p1.orig/canohost.c 2018-08-23 07:41:42.000000000 +0200 -+++ openssh-7.8p1/canohost.c 2018-10-24 14:09:54.221377906 +0200 +diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c +--- openssh-7.9p1.orig/canohost.c 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/canohost.c 2018-10-23 23:09:11.660055260 +0200 @@ -17,6 +17,7 @@ #include #include @@ -569,9 +569,9 @@ diff -Nur openssh-7.8p1.orig/canohost.c openssh-7.8p1/canohost.c + } + } +} -diff -Nur openssh-7.8p1.orig/canohost.h openssh-7.8p1/canohost.h ---- openssh-7.8p1.orig/canohost.h 2018-08-23 07:41:42.000000000 +0200 -+++ openssh-7.8p1/canohost.h 2018-10-24 14:09:54.221377906 +0200 +diff -Nur openssh-7.9p1.orig/canohost.h openssh-7.9p1/canohost.h +--- openssh-7.9p1.orig/canohost.h 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/canohost.h 2018-10-23 23:09:11.660055260 +0200 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -579,10 +579,10 @@ diff -Nur openssh-7.8p1.orig/canohost.h openssh-7.8p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.8p1.orig/configure.ac openssh-7.8p1/configure.ac ---- openssh-7.8p1.orig/configure.ac 2018-10-24 14:09:16.709774736 +0200 -+++ openssh-7.8p1/configure.ac 2018-10-24 14:09:54.223377885 +0200 -@@ -4504,6 +4504,14 @@ +diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac +--- openssh-7.9p1.orig/configure.ac 2018-10-23 23:08:05.747762458 +0200 ++++ openssh-7.9p1/configure.ac 2018-10-23 23:09:11.661055249 +0200 +@@ -4631,6 +4631,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -597,7 +597,7 @@ diff -Nur openssh-7.8p1.orig/configure.ac openssh-7.8p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4543,6 +4551,50 @@ +@@ -4670,6 +4678,50 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -648,9 +648,9 @@ diff -Nur openssh-7.8p1.orig/configure.ac openssh-7.8p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.8p1.orig/gss-genr.c openssh-7.8p1/gss-genr.c ---- openssh-7.8p1.orig/gss-genr.c 2018-10-24 14:09:16.682775021 +0200 -+++ openssh-7.8p1/gss-genr.c 2018-10-24 14:09:54.223377885 +0200 +diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c +--- openssh-7.9p1.orig/gss-genr.c 2018-10-23 23:08:05.738762555 +0200 ++++ openssh-7.9p1/gss-genr.c 2018-10-23 23:09:11.662055238 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -659,7 +659,7 @@ diff -Nur openssh-7.8p1.orig/gss-genr.c openssh-7.8p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -396,9 +397,18 @@ +@@ -395,9 +396,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -679,7 +679,7 @@ diff -Nur openssh-7.8p1.orig/gss-genr.c openssh-7.8p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -406,6 +416,7 @@ +@@ -405,6 +415,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -687,9 +687,9 @@ diff -Nur openssh-7.8p1.orig/gss-genr.c openssh-7.8p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c ---- openssh-7.8p1.orig/gss-serv.c 2018-10-24 14:09:16.511776830 +0200 -+++ openssh-7.8p1/gss-serv.c 2018-10-24 14:09:54.224377874 +0200 +diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c +--- openssh-7.9p1.orig/gss-serv.c 2018-10-23 23:08:05.758762340 +0200 ++++ openssh-7.9p1/gss-serv.c 2018-10-23 23:20:40.923607619 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -888,16 +888,9 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c return (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -442,16 +505,19 @@ - } +@@ -449,11 +512,13 @@ - /* Privileged */ -+/* gssapi_keyex arg added for Globus usage */ - int --ssh_gssapi_userok(char *user, struct passwd *pw) -+ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex) - { - OM_uint32 lmin; + (void) kex; /* used in privilege separation */ - if (gssapi_client.exportedname.length == 0 || - gssapi_client.exportedname.value == NULL) { @@ -912,7 +905,7 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -462,6 +528,7 @@ +@@ -464,6 +529,7 @@ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); @@ -920,7 +913,7 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c explicit_bzero(&gssapi_client, sizeof(ssh_gssapi_client)); return 0; -@@ -471,6 +538,24 @@ +@@ -473,6 +539,24 @@ return (0); } @@ -945,7 +938,7 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -497,9 +582,11 @@ +@@ -499,9 +583,11 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -958,7 +951,7 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c gssapi_client.store.envvar == NULL) return; -@@ -525,6 +612,18 @@ +@@ -527,6 +613,18 @@ if (ret) return; @@ -977,7 +970,7 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -565,4 +664,13 @@ +@@ -567,4 +665,13 @@ return (char *)gssapi_client.displayname.value; } @@ -991,9 +984,9 @@ diff -Nur openssh-7.8p1.orig/gss-serv.c openssh-7.8p1/gss-serv.c +} + #endif -diff -Nur openssh-7.8p1.orig/gss-serv-gsi.c openssh-7.8p1/gss-serv-gsi.c ---- openssh-7.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.8p1/gss-serv-gsi.c 2018-10-24 14:09:54.224377874 +0200 +diff -Nur openssh-7.9p1.orig/gss-serv-gsi.c openssh-7.9p1/gss-serv-gsi.c +--- openssh-7.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.9p1/gss-serv-gsi.c 2018-10-23 23:09:11.664055217 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1323,9 +1316,9 @@ diff -Nur openssh-7.8p1.orig/gss-serv-gsi.c openssh-7.8p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.8p1.orig/gss-serv-krb5.c openssh-7.8p1/gss-serv-krb5.c ---- openssh-7.8p1.orig/gss-serv-krb5.c 2018-10-24 14:09:16.497776978 +0200 -+++ openssh-7.8p1/gss-serv-krb5.c 2018-10-24 14:09:54.224377874 +0200 +diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c +--- openssh-7.9p1.orig/gss-serv-krb5.c 2018-10-23 23:08:05.707762887 +0200 ++++ openssh-7.9p1/gss-serv-krb5.c 2018-10-23 23:09:11.664055217 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1379,9 +1372,9 @@ diff -Nur openssh-7.8p1.orig/gss-serv-krb5.c openssh-7.8p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.8p1.orig/kexgsss.c openssh-7.8p1/kexgsss.c ---- openssh-7.8p1.orig/kexgsss.c 2018-10-24 14:09:16.685774989 +0200 -+++ openssh-7.8p1/kexgsss.c 2018-10-24 14:09:54.225377863 +0200 +diff -Nur openssh-7.9p1.orig/kexgsss.c openssh-7.9p1/kexgsss.c +--- openssh-7.9p1.orig/kexgsss.c 2018-10-23 23:08:05.734762597 +0200 ++++ openssh-7.9p1/kexgsss.c 2018-10-23 23:09:11.665055206 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1441,9 +1434,9 @@ diff -Nur openssh-7.8p1.orig/kexgsss.c openssh-7.8p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.8p1.orig/LICENSE.globus_usage openssh-7.8p1/LICENSE.globus_usage ---- openssh-7.8p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.8p1/LICENSE.globus_usage 2018-10-24 14:09:54.225377863 +0200 +diff -Nur openssh-7.9p1.orig/LICENSE.globus_usage openssh-7.9p1/LICENSE.globus_usage +--- openssh-7.9p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.9p1/LICENSE.globus_usage 2018-10-23 23:09:11.665055206 +0200 @@ -0,0 +1,18 @@ +/* + * Portions of the Usage Metrics suport code are derived from the @@ -1463,9 +1456,9 @@ diff -Nur openssh-7.8p1.orig/LICENSE.globus_usage openssh-7.8p1/LICENSE.globus_u + * See the License for the specific language governing permissions and + * limitations under the License. + */ -diff -Nur openssh-7.8p1.orig/Makefile.in openssh-7.8p1/Makefile.in ---- openssh-7.8p1.orig/Makefile.in 2018-10-24 14:09:16.688774958 +0200 -+++ openssh-7.8p1/Makefile.in 2018-10-24 14:09:54.225377863 +0200 +diff -Nur openssh-7.9p1.orig/Makefile.in openssh-7.9p1/Makefile.in +--- openssh-7.9p1.orig/Makefile.in 2018-10-23 23:08:05.776762147 +0200 ++++ openssh-7.9p1/Makefile.in 2018-10-23 23:09:11.666055195 +0200 @@ -124,8 +124,10 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1477,10 +1470,10 @@ diff -Nur openssh-7.8p1.orig/Makefile.in openssh-7.8p1/Makefile.in sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o uidswap.o -diff -Nur openssh-7.8p1.orig/misc.c openssh-7.8p1/misc.c ---- openssh-7.8p1.orig/misc.c 2018-10-24 14:09:16.494777010 +0200 -+++ openssh-7.8p1/misc.c 2018-10-24 14:09:54.226377853 +0200 -@@ -237,11 +237,14 @@ +diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c +--- openssh-7.9p1.orig/misc.c 2018-10-23 23:08:05.705762909 +0200 ++++ openssh-7.9p1/misc.c 2018-10-23 23:09:11.666055195 +0200 +@@ -238,11 +238,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1496,7 +1489,7 @@ diff -Nur openssh-7.8p1.orig/misc.c openssh-7.8p1/misc.c int wspace = 0; if (*s == NULL) -@@ -249,6 +252,21 @@ +@@ -250,6 +253,21 @@ old = *s; @@ -1518,7 +1511,7 @@ diff -Nur openssh-7.8p1.orig/misc.c openssh-7.8p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -324,6 +342,20 @@ +@@ -325,6 +343,20 @@ return copy; } @@ -1539,10 +1532,10 @@ diff -Nur openssh-7.8p1.orig/misc.c openssh-7.8p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.8p1.orig/misc.h openssh-7.8p1/misc.h ---- openssh-7.8p1.orig/misc.h 2018-10-24 14:09:16.494777010 +0200 -+++ openssh-7.8p1/misc.h 2018-10-24 14:09:54.226377853 +0200 -@@ -82,6 +82,7 @@ +diff -Nur openssh-7.9p1.orig/misc.h openssh-7.9p1/misc.h +--- openssh-7.9p1.orig/misc.h 2018-10-23 23:08:05.705762909 +0200 ++++ openssh-7.9p1/misc.h 2018-10-23 23:09:11.667055184 +0200 +@@ -83,6 +83,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1550,10 +1543,10 @@ diff -Nur openssh-7.8p1.orig/misc.h openssh-7.8p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c ---- openssh-7.8p1.orig/monitor.c 2018-10-24 14:09:16.689774947 +0200 -+++ openssh-7.8p1/monitor.c 2018-10-24 14:09:54.226377853 +0200 -@@ -150,6 +150,9 @@ +diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c +--- openssh-7.9p1.orig/monitor.c 2018-10-23 23:08:05.782762082 +0200 ++++ openssh-7.9p1/monitor.c 2018-10-23 23:09:11.668055174 +0200 +@@ -152,6 +152,9 @@ int mm_answer_gss_userok(int, struct sshbuf *); int mm_answer_gss_checkmic(int, struct sshbuf *); int mm_answer_gss_sign(int, struct sshbuf *); @@ -1563,7 +1556,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c int mm_answer_gss_updatecreds(int, struct sshbuf *); #endif -@@ -200,7 +203,7 @@ +@@ -202,7 +205,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1572,7 +1565,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -208,7 +211,7 @@ +@@ -210,7 +213,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1581,7 +1574,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -232,8 +235,11 @@ +@@ -234,8 +237,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1594,7 +1587,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c #endif {0, 0, NULL} }; -@@ -243,6 +249,8 @@ +@@ -245,6 +251,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1603,7 +1596,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -324,6 +332,8 @@ +@@ -326,6 +334,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1612,7 +1605,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -442,6 +452,8 @@ +@@ -444,6 +454,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1621,7 +1614,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -763,15 +775,18 @@ +@@ -764,15 +776,18 @@ debug3("%s", __func__); @@ -1643,38 +1636,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2010,13 +2025,17 @@ - mm_answer_gss_userok(int sock, struct sshbuf *m) - { - int r, authenticated; -+ int gssapi_keyex; - const char *displayname; - - if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - -+ if ((r = sshbuf_get_u32(m, &gssapi_keyex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ - authenticated = authctxt->valid && -- ssh_gssapi_userok(authctxt->user, authctxt->pw); -+ ssh_gssapi_userok(authctxt->user, authctxt->pw, gssapi_keyex); - - sshbuf_reset(m); - if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -2025,7 +2044,10 @@ - debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - -- auth_method = "gssapi-with-mic"; -+ if (gssapi_keyex) -+ auth_method = "gssapi-keyex"; -+ else -+ auth_method = "gssapi-with-mic"; - - if ((displayname = ssh_gssapi_displayname()) != NULL) - auth2_record_info(authctxt, "%s", displayname); -@@ -2034,6 +2056,79 @@ +@@ -2042,6 +2057,79 @@ return (authenticated); } @@ -1754,7 +1716,7 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c int mm_answer_gss_sign(int socket, struct sshbuf *m) { -@@ -2085,12 +2180,14 @@ +@@ -2093,12 +2181,14 @@ ssh_gssapi_ccache store; int ok, r; @@ -1770,9 +1732,9 @@ diff -Nur openssh-7.8p1.orig/monitor.c openssh-7.8p1/monitor.c free(store.envvar); free(store.envval); -diff -Nur openssh-7.8p1.orig/monitor.h openssh-7.8p1/monitor.h ---- openssh-7.8p1.orig/monitor.h 2018-10-24 14:09:16.630775571 +0200 -+++ openssh-7.8p1/monitor.h 2018-10-24 14:09:54.227377842 +0200 +diff -Nur openssh-7.9p1.orig/monitor.h openssh-7.9p1/monitor.h +--- openssh-7.9p1.orig/monitor.h 2018-10-23 23:08:05.766762254 +0200 ++++ openssh-7.9p1/monitor.h 2018-10-23 23:09:11.669055163 +0200 @@ -73,8 +73,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1786,27 +1748,10 @@ diff -Nur openssh-7.8p1.orig/monitor.h openssh-7.8p1/monitor.h }; struct monitor { -diff -Nur openssh-7.8p1.orig/monitor_wrap.c openssh-7.8p1/monitor_wrap.c ---- openssh-7.8p1.orig/monitor_wrap.c 2018-10-24 14:09:16.665775201 +0200 -+++ openssh-7.8p1/monitor_wrap.c 2018-10-24 14:33:40.976350751 +0200 -@@ -1045,13 +1045,15 @@ - } - - int --mm_ssh_gssapi_userok(char *user, struct passwd *pw) -+mm_ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex) - { - struct sshbuf *m; - int r, authenticated = 0; - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); -+ if ((r = sshbuf_put_u32(m, gssapi_keyex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); - mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1065,6 +1067,94 @@ +diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c +--- openssh-7.9p1.orig/monitor_wrap.c 2018-10-23 23:08:05.783762072 +0200 ++++ openssh-7.9p1/monitor_wrap.c 2018-10-24 15:25:13.876838426 +0200 +@@ -1067,6 +1067,94 @@ return (authenticated); } @@ -1901,7 +1846,7 @@ diff -Nur openssh-7.8p1.orig/monitor_wrap.c openssh-7.8p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -@@ -1098,7 +1188,8 @@ +@@ -1100,7 +1188,8 @@ if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -1911,15 +1856,11 @@ diff -Nur openssh-7.8p1.orig/monitor_wrap.c openssh-7.8p1/monitor_wrap.c (r = sshbuf_put_cstring(m, store->envval ? store->envval : "")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); -diff -Nur openssh-7.8p1.orig/monitor_wrap.h openssh-7.8p1/monitor_wrap.h ---- openssh-7.8p1.orig/monitor_wrap.h 2018-10-24 14:09:16.647775391 +0200 -+++ openssh-7.8p1/monitor_wrap.h 2018-10-24 14:09:54.242377684 +0200 -@@ -65,9 +65,13 @@ - OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); - OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, - gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); --int mm_ssh_gssapi_userok(char *user, struct passwd *); -+int mm_ssh_gssapi_userok(char *user, struct passwd *, int gssapi_keyex); +diff -Nur openssh-7.9p1.orig/monitor_wrap.h openssh-7.9p1/monitor_wrap.h +--- openssh-7.9p1.orig/monitor_wrap.h 2018-10-23 23:08:05.771762201 +0200 ++++ openssh-7.9p1/monitor_wrap.h 2018-10-23 23:35:33.766952547 +0200 +@@ -68,6 +68,10 @@ + int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); +int mm_ssh_gssapi_localname(char **user); @@ -1929,10 +1870,10 @@ diff -Nur openssh-7.8p1.orig/monitor_wrap.h openssh-7.8p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.8p1.orig/readconf.c openssh-7.8p1/readconf.c ---- openssh-7.8p1.orig/readconf.c 2018-10-24 14:09:16.656775296 +0200 -+++ openssh-7.8p1/readconf.c 2018-10-24 14:09:54.246377641 +0200 -@@ -2013,13 +2013,13 @@ +diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c +--- openssh-7.9p1.orig/readconf.c 2018-10-23 23:08:05.776762147 +0200 ++++ openssh-7.9p1/readconf.c 2018-10-23 23:09:11.671055142 +0200 +@@ -2039,13 +2039,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1950,10 +1891,10 @@ diff -Nur openssh-7.8p1.orig/readconf.c openssh-7.8p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.8p1.orig/readconf.h openssh-7.8p1/readconf.h ---- openssh-7.8p1.orig/readconf.h 2018-10-24 14:09:16.522776714 +0200 -+++ openssh-7.8p1/readconf.h 2018-10-24 14:09:54.247377631 +0200 -@@ -77,6 +77,8 @@ +diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h +--- openssh-7.9p1.orig/readconf.h 2018-10-23 23:08:05.717762780 +0200 ++++ openssh-7.9p1/readconf.h 2018-10-23 23:09:11.671055142 +0200 +@@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1962,9 +1903,9 @@ diff -Nur openssh-7.8p1.orig/readconf.h openssh-7.8p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c ---- openssh-7.8p1.orig/servconf.c 2018-10-24 14:09:16.672775127 +0200 -+++ openssh-7.8p1/servconf.c 2018-10-24 14:09:54.247377631 +0200 +diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c +--- openssh-7.9p1.orig/servconf.c 2018-10-23 23:08:05.784762061 +0200 ++++ openssh-7.9p1/servconf.c 2018-10-23 23:09:11.672055131 +0200 @@ -84,6 +84,7 @@ /* Portable-specific options */ @@ -1975,7 +1916,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c options->num_ports = 0; @@ -127,9 +128,11 @@ options->kerberos_get_afs_token = -1; - options->kerberos_unique_ticket = -1; + options->kerberos_unique_ccache = -1; options->gss_authentication=-1; + options->gss_deleg_creds = -1; options->gss_keyex = -1; @@ -1985,7 +1926,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -177,6 +180,8 @@ +@@ -178,6 +181,8 @@ options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; @@ -1994,7 +1935,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; -@@ -269,6 +274,8 @@ +@@ -273,6 +278,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -2003,9 +1944,9 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -346,13 +353,17 @@ - if (options->kerberos_unique_ticket == -1) - options->kerberos_unique_ticket = 0; +@@ -350,13 +357,17 @@ + if (options->kerberos_unique_ccache == -1) + options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) - options->gss_authentication = 0; + options->gss_authentication = 1; @@ -2023,7 +1964,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -487,7 +498,7 @@ +@@ -491,7 +502,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -2032,7 +1973,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -509,10 +520,14 @@ +@@ -513,10 +524,14 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -2047,7 +1988,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -538,8 +553,10 @@ +@@ -542,8 +557,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -2058,7 +1999,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -587,7 +604,14 @@ +@@ -591,7 +608,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -2073,7 +2014,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -595,7 +619,10 @@ +@@ -599,7 +623,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -2084,7 +2025,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -666,6 +693,8 @@ +@@ -670,6 +697,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -2093,7 +2034,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1296,6 +1325,10 @@ +@@ -1301,6 +1330,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2104,7 +2045,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1510,6 +1543,10 @@ +@@ -1519,6 +1552,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2115,7 +2056,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1518,6 +1555,10 @@ +@@ -1527,6 +1564,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2126,7 +2067,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1538,6 +1579,12 @@ +@@ -1547,6 +1588,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2139,7 +2080,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2051,6 +2098,35 @@ +@@ -2060,6 +2107,35 @@ *charptr = xstrdup(arg); break; @@ -2175,7 +2116,7 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; -@@ -2345,6 +2421,7 @@ +@@ -2354,6 +2430,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2183,10 +2124,10 @@ diff -Nur openssh-7.8p1.orig/servconf.c openssh-7.8p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.8p1.orig/servconf.h openssh-7.8p1/servconf.h ---- openssh-7.8p1.orig/servconf.h 2018-10-24 14:09:16.535776576 +0200 -+++ openssh-7.8p1/servconf.h 2018-10-24 14:09:54.248377620 +0200 -@@ -129,9 +129,12 @@ +diff -Nur openssh-7.9p1.orig/servconf.h openssh-7.9p1/servconf.h +--- openssh-7.9p1.orig/servconf.h 2018-10-23 23:08:05.725762694 +0200 ++++ openssh-7.9p1/servconf.h 2018-10-23 23:09:11.673055120 +0200 +@@ -130,9 +130,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2199,7 +2140,7 @@ diff -Nur openssh-7.8p1.orig/servconf.h openssh-7.8p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -191,6 +194,7 @@ +@@ -192,6 +195,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2207,7 +2148,7 @@ diff -Nur openssh-7.8p1.orig/servconf.h openssh-7.8p1/servconf.h int permit_tun; -@@ -200,6 +204,10 @@ +@@ -201,6 +205,10 @@ u_int num_permitted_listens; char *chroot_directory; @@ -2218,10 +2159,10 @@ diff -Nur openssh-7.8p1.orig/servconf.h openssh-7.8p1/servconf.h char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; -diff -Nur openssh-7.8p1.orig/ssh.1 openssh-7.8p1/ssh.1 ---- openssh-7.8p1.orig/ssh.1 2018-10-24 14:09:16.525776682 +0200 -+++ openssh-7.8p1/ssh.1 2018-10-24 14:09:54.249377610 +0200 -@@ -1423,6 +1423,18 @@ +diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 +--- openssh-7.9p1.orig/ssh.1 2018-10-23 23:08:05.719762758 +0200 ++++ openssh-7.9p1/ssh.1 2018-10-23 23:09:11.674055109 +0200 +@@ -1433,6 +1433,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2240,9 +2181,9 @@ diff -Nur openssh-7.8p1.orig/ssh.1 openssh-7.8p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.8p1.orig/ssh.c openssh-7.8p1/ssh.c ---- openssh-7.8p1.orig/ssh.c 2018-10-24 14:09:16.690774937 +0200 -+++ openssh-7.8p1/ssh.c 2018-10-24 14:09:54.249377610 +0200 +diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c +--- openssh-7.9p1.orig/ssh.c 2018-10-23 23:08:05.778762125 +0200 ++++ openssh-7.9p1/ssh.c 2018-10-23 23:09:11.674055109 +0200 @@ -541,6 +541,32 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2276,7 +2217,7 @@ diff -Nur openssh-7.8p1.orig/ssh.c openssh-7.8p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1283,8 +1309,12 @@ +@@ -1289,8 +1315,12 @@ logit("FIPS mode initialized"); } @@ -2290,9 +2231,9 @@ diff -Nur openssh-7.8p1.orig/ssh.c openssh-7.8p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) -diff -Nur openssh-7.8p1.orig/ssh_config openssh-7.8p1/ssh_config ---- openssh-7.8p1.orig/ssh_config 2018-10-24 14:09:16.427777719 +0200 -+++ openssh-7.8p1/ssh_config 2018-10-24 14:09:54.249377610 +0200 +diff -Nur openssh-7.9p1.orig/ssh_config openssh-7.9p1/ssh_config +--- openssh-7.9p1.orig/ssh_config 2018-10-23 23:08:05.675763231 +0200 ++++ openssh-7.9p1/ssh_config 2018-10-23 23:09:11.675055099 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2308,9 +2249,9 @@ diff -Nur openssh-7.8p1.orig/ssh_config openssh-7.8p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 ---- openssh-7.8p1.orig/ssh_config.5 2018-10-24 14:09:16.599775899 +0200 -+++ openssh-7.8p1/ssh_config.5 2018-10-24 14:09:54.250377599 +0200 +diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 +--- openssh-7.9p1.orig/ssh_config.5 2018-10-23 23:08:05.750762426 +0200 ++++ openssh-7.9p1/ssh_config.5 2018-10-23 23:09:11.675055099 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2324,7 +2265,7 @@ diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -717,7 +723,7 @@ +@@ -735,7 +741,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2333,7 +2274,7 @@ diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -725,12 +731,12 @@ +@@ -743,12 +749,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2348,7 +2289,7 @@ diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -762,7 +768,7 @@ +@@ -780,7 +786,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2357,7 +2298,7 @@ diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1227,7 +1233,7 @@ +@@ -1249,7 +1255,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2366,10 +2307,10 @@ diff -Nur openssh-7.8p1.orig/ssh_config.5 openssh-7.8p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c ---- openssh-7.8p1.orig/sshconnect2.c 2018-10-24 14:09:16.658775275 +0200 -+++ openssh-7.8p1/sshconnect2.c 2018-10-24 14:09:54.257377525 +0200 -@@ -863,6 +863,11 @@ +diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c +--- openssh-7.9p1.orig/sshconnect2.c 2018-10-23 23:08:05.778762125 +0200 ++++ openssh-7.9p1/sshconnect2.c 2018-10-23 23:09:11.676055088 +0200 +@@ -894,6 +894,11 @@ int r, ok = 0; const char *gss_host = NULL; @@ -2381,7 +2322,7 @@ diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c if (options.gss_server_identity) gss_host = options.gss_server_identity; else if (options.gss_trust_dns) { -@@ -956,7 +961,8 @@ +@@ -987,7 +992,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2391,7 +2332,7 @@ diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1126,6 +1132,20 @@ +@@ -1157,6 +1163,20 @@ return r; } @@ -2412,7 +2353,7 @@ diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c int userauth_gsskeyex(Authctxt *authctxt) { -@@ -1146,6 +1166,11 @@ +@@ -1177,6 +1197,11 @@ if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -2424,7 +2365,7 @@ diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -@@ -1158,7 +1183,13 @@ +@@ -1189,7 +1214,13 @@ } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -2438,9 +2379,9 @@ diff -Nur openssh-7.8p1.orig/sshconnect2.c openssh-7.8p1/sshconnect2.c packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.8p1.orig/sshd.8 openssh-7.8p1/sshd.8 ---- openssh-7.8p1.orig/sshd.8 2018-10-24 14:09:16.457777401 +0200 -+++ openssh-7.8p1/sshd.8 2018-10-24 14:09:54.258377514 +0200 +diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 +--- openssh-7.9p1.orig/sshd.8 2018-10-23 23:08:05.689763080 +0200 ++++ openssh-7.9p1/sshd.8 2018-10-23 23:09:11.677055077 +0200 @@ -788,6 +788,44 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2486,9 +2427,9 @@ diff -Nur openssh-7.8p1.orig/sshd.8 openssh-7.8p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.8p1.orig/sshd.c openssh-7.8p1/sshd.c ---- openssh-7.8p1.orig/sshd.c 2018-10-24 14:09:16.691774926 +0200 -+++ openssh-7.8p1/sshd.c 2018-10-24 14:09:54.259377504 +0200 +diff -Nur openssh-7.9p1.orig/sshd.c openssh-7.9p1/sshd.c +--- openssh-7.9p1.orig/sshd.c 2018-10-23 23:08:05.785762050 +0200 ++++ openssh-7.9p1/sshd.c 2018-10-23 23:09:11.677055077 +0200 @@ -130,6 +130,7 @@ #include "auth-options.h" #include "version.h" @@ -2520,9 +2461,9 @@ diff -Nur openssh-7.8p1.orig/sshd.c openssh-7.8p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.8p1.orig/sshd_config openssh-7.8p1/sshd_config ---- openssh-7.8p1.orig/sshd_config 2018-10-24 14:09:16.509776851 +0200 -+++ openssh-7.8p1/sshd_config 2018-10-24 14:09:54.259377504 +0200 +diff -Nur openssh-7.9p1.orig/sshd_config openssh-7.9p1/sshd_config +--- openssh-7.9p1.orig/sshd_config 2018-10-23 23:08:05.714762812 +0200 ++++ openssh-7.9p1/sshd_config 2018-10-23 23:09:11.678055066 +0200 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2559,10 +2500,10 @@ diff -Nur openssh-7.8p1.orig/sshd_config openssh-7.8p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 ---- openssh-7.8p1.orig/sshd_config.5 2018-10-24 14:09:16.562776291 +0200 -+++ openssh-7.8p1/sshd_config.5 2018-10-24 14:09:54.259377504 +0200 -@@ -576,6 +576,15 @@ +diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 +--- openssh-7.9p1.orig/sshd_config.5 2018-10-23 23:08:05.736762576 +0200 ++++ openssh-7.9p1/sshd_config.5 2018-10-23 23:09:11.678055066 +0200 +@@ -587,6 +587,15 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. @@ -2578,7 +2519,7 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -633,15 +642,34 @@ +@@ -644,15 +653,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2614,7 +2555,7 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -652,7 +680,7 @@ +@@ -663,7 +691,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2623,7 +2564,7 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -691,7 +719,6 @@ +@@ -702,7 +730,6 @@ .Pp The default is .Dq gss-gex-sha1-,gss-group14-sha1- . @@ -2631,7 +2572,7 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a list of comma-separated patterns. -@@ -1627,6 +1654,103 @@ +@@ -1640,6 +1667,103 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . @@ -2735,7 +2676,7 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm UseDNS Specifies whether .Xr sshd 8 -@@ -1668,6 +1792,12 @@ +@@ -1681,6 +1805,12 @@ as a non-root user. The default is .Cm no . @@ -2748,9 +2689,9 @@ diff -Nur openssh-7.8p1.orig/sshd_config.5 openssh-7.8p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.8p1.orig/ssh-globus-usage.c openssh-7.8p1/ssh-globus-usage.c ---- openssh-7.8p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.8p1/ssh-globus-usage.c 2018-10-24 14:09:54.260377493 +0200 +diff -Nur openssh-7.9p1.orig/ssh-globus-usage.c openssh-7.9p1/ssh-globus-usage.c +--- openssh-7.9p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.9p1/ssh-globus-usage.c 2018-10-23 23:09:11.679055056 +0200 @@ -0,0 +1,396 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3148,9 +3089,9 @@ diff -Nur openssh-7.8p1.orig/ssh-globus-usage.c openssh-7.8p1/ssh-globus-usage.c + +#endif /* HAVE_GLOBUS_USAGE */ +} -diff -Nur openssh-7.8p1.orig/ssh-globus-usage.h openssh-7.8p1/ssh-globus-usage.h ---- openssh-7.8p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.8p1/ssh-globus-usage.h 2018-10-24 14:09:54.260377493 +0200 +diff -Nur openssh-7.9p1.orig/ssh-globus-usage.h openssh-7.9p1/ssh-globus-usage.h +--- openssh-7.9p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.9p1/ssh-globus-usage.h 2018-10-23 23:09:11.679055056 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 The Board of Trustees of the University @@ -3200,9 +3141,9 @@ diff -Nur openssh-7.8p1.orig/ssh-globus-usage.h openssh-7.8p1/ssh-globus-usage.h + const char *userdn); + +#endif /* __SSH_GLOBUS_USAGE_H */ -diff -Nur openssh-7.8p1.orig/ssh-gss.h openssh-7.8p1/ssh-gss.h ---- openssh-7.8p1.orig/ssh-gss.h 2018-10-24 14:09:16.560776312 +0200 -+++ openssh-7.8p1/ssh-gss.h 2018-10-24 14:09:54.260377493 +0200 +diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h +--- openssh-7.9p1.orig/ssh-gss.h 2018-10-23 23:08:05.759762329 +0200 ++++ openssh-7.9p1/ssh-gss.h 2018-10-23 23:09:11.679055056 +0200 @@ -85,6 +85,7 @@ KEX_GSS_GRP14_SHA1_ID @@ -3246,15 +3187,6 @@ diff -Nur openssh-7.8p1.orig/ssh-gss.h openssh-7.8p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -165,7 +171,7 @@ - int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, - const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); --int ssh_gssapi_userok(char *name, struct passwd *); -+int ssh_gssapi_userok(char *name, struct passwd *, int gssapi_keyex); - 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); @@ -178,6 +184,7 @@ int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); @@ -3263,12 +3195,12 @@ diff -Nur openssh-7.8p1.orig/ssh-gss.h openssh-7.8p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -Nur openssh-7.8p1.orig/version.h openssh-7.8p1/version.h ---- openssh-7.8p1.orig/version.h 2018-08-23 07:41:42.000000000 +0200 -+++ openssh-7.8p1/version.h 2018-10-24 14:09:54.260377493 +0200 +diff -Nur openssh-7.9p1.orig/version.h openssh-7.9p1/version.h +--- openssh-7.9p1.orig/version.h 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/version.h 2018-10-23 23:09:11.680055045 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_7.8" + #define SSH_VERSION "OpenSSH_7.9" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-7.9p1-gsskex-method.patch b/openssh-7.9p1-gsskex-method.patch new file mode 100644 index 0000000..b06620d --- /dev/null +++ b/openssh-7.9p1-gsskex-method.patch @@ -0,0 +1,150 @@ +From bc74944ce7a2eabd228d47051f277ce108914c96 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 16 Oct 2018 16:44:40 +0200 +Subject: [PATCH] Unbreak authentication using gssapi-keyex (#1625366) + +--- + auth2-gss.c | 6 +++--- + gss-serv.c | 4 +++- + monitor.c | 13 ++++++++++--- + monitor_wrap.c | 4 +++- + monitor_wrap.h | 2 +- + ssh-gss.h | 2 +- + 6 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/auth2-gss.c b/auth2-gss.c +index 3f2ad21d..a61ac089 100644 +--- a/auth2-gss.c ++++ b/auth2-gss.c +@@ -84,7 +84,7 @@ userauth_gsskeyex(Authctxt *authctxt) + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, + &gssbuf, &mic)))) + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, +- authctxt->pw)); ++ authctxt->pw, 1)); + + sshbuf_free(b); + free(mic.value); +@@ -299,7 +299,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) + fatal("%s: %s", __func__, ssh_err(r)); + + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, +- authctxt->pw)); ++ authctxt->pw, 1)); + + if ((!use_privsep || mm_is_monitor()) && + (displayname = ssh_gssapi_displayname()) != NULL) +@@ -347,7 +347,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) + + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) + authenticated = +- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); ++ PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0)); + else + logit("GSSAPI MIC check failed"); + +diff --git a/gss-serv.c b/gss-serv.c +index 786ac95c..87de2baa 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -493,10 +493,12 @@ verify_authentication_indicators(Gssctxt *gssctxt) + + /* Privileged */ + int +-ssh_gssapi_userok(char *user, struct passwd *pw) ++ssh_gssapi_userok(char *user, struct passwd *pw, int kex) + { + OM_uint32 lmin; + ++ (void) kex; /* used in privilege separation */ ++ + if (gssapi_client.exportedname.length == 0 || + gssapi_client.exportedname.value == NULL) { + debug("No suitable client data"); +diff --git a/monitor.c b/monitor.c +index 9bbe8cc4..7b1903af 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -1877,14 +1877,17 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m) + int + mm_answer_gss_userok(int sock, struct sshbuf *m) + { +- int r, authenticated; ++ int r, authenticated, kex; + const char *displayname; + + if (!options.gss_authentication && !options.gss_keyex) + fatal("%s: GSSAPI authentication not enabled", __func__); + ++ if ((r = sshbuf_get_u32(m, &kex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ + authenticated = authctxt->valid && +- ssh_gssapi_userok(authctxt->user, authctxt->pw); ++ ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); + + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, authenticated)) != 0) +@@ -1893,7 +1896,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); + +- auth_method = "gssapi-with-mic"; ++ if (kex) { ++ auth_method = "gssapi-keyex"; ++ } else { ++ auth_method = "gssapi-with-mic"; ++ } + + if ((displayname = ssh_gssapi_displayname()) != NULL) + auth2_record_info(authctxt, "%s", displayname); +diff --git a/monitor_wrap.c b/monitor_wrap.c +index fb52a530..508d926d 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -984,13 +984,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) + } + + int +-mm_ssh_gssapi_userok(char *user, struct passwd *pw) ++mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex) + { + struct sshbuf *m; + int r, authenticated = 0; + + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, kex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); + mm_request_receive_expect(pmonitor->m_recvfd, +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 494760dd..5eba5ecc 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -60,7 +60,7 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, + OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); + OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); +-int mm_ssh_gssapi_userok(char *user, struct passwd *); ++int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); + OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); + int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); +diff --git a/ssh-gss.h b/ssh-gss.h +index 39b6ce69..98262837 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -162,7 +162,7 @@ gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); + int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, + const char *); + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +-int ssh_gssapi_userok(char *name, struct passwd *); ++int ssh_gssapi_userok(char *name, struct passwd *, int kex); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-- +2.17.2 + diff --git a/sources b/sources index c629991..48349e8 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-7.8p1.tar.gz) = 8e5b0c8682a9243e4e8b7c374ec989dccd1a752eb6f84e593b67141e8b23dcc8b9a7322b1f7525d18e2ce8830a767d0d9793f997486339db201a57986b910705 -SHA512 (openssh-7.8p1.tar.gz.asc) = 3a7bef84df3c07aa78965a11a6bbd6ca6e5d1e9265ac08871b3e5d304646be651b74f5302a195e86a56e6a83b19d79292e5599c9a9cf6f003a513d4354e8ad2f +SHA512 (openssh-7.9p1.tar.gz) = 0412c9c429c9287f0794023951469c8e6ec833cdb55821bfa0300dd90d0879ff60484f620cffd93372641ab69bf0b032c2d700ccc680950892725fb631b7708e +SHA512 (openssh-7.9p1.tar.gz.asc) = 881db1b541813136fabd9adb9f5430c4f0fae372c06c99cb049feb8526a573275fe80c129c89511dd4e65f73f41e29364fefaaf8b7c78835224691c488d5da32 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From f0dc592cfc2c112ba6cc69b4ba859126a41bbc20 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 14 Nov 2018 13:19:09 +0100 Subject: [PATCH 063/146] Based on openssh-7.9p1-2.fc29 --- gsi-openssh.spec | 9 +++- openssh-6.7p1-ldap.patch | 8 +++- openssh-7.0p1-gssKexAlgorithms.patch | 17 +++++-- openssh-7.7p1-gssapi-new-unique.patch | 2 +- openssh-7.7p1-redhat.patch | 2 +- openssh-7.8p1-gsskex.patch | 68 +++++++++++++-------------- openssh-7.9p1-disable-sha1.patch | 62 ++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 43 deletions(-) create mode 100644 openssh-7.9p1-disable-sha1.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 8e80526..6e846e7 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -165,6 +165,9 @@ Patch951: openssh-7.6p1-pkcs11-uri.patch Patch952: openssh-7.6p1-pkcs11-ecdsa.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch +# Allow to disable RSA signatures with SHA-1 in server +# https://bugzilla.mindrot.org/show_bug.cgi?id=2746 +Patch954: openssh-7.9p1-disable-sha1.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -324,6 +327,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch952 -p1 -b .pkcs11-ecdsa %patch953 -p1 -b .scp-ipv6 %patch808 -p1 -b .gsskex-method +%patch954 -p1 -b .disable-sha1 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -535,6 +539,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Nov 14 2018 Mattias Ellert - 7.9p1-2 +- Based on openssh-7.9p1-2.fc29 + * Tue Oct 23 2018 Mattias Ellert - 7.9p1-1 - Based on openssh-7.9p1-1.fc29 diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index ee44fdb..a8770e0 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -331,7 +331,7 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac + [ac_cv_ldap_set_rebind_proc=3], + [ac_cv_ldap_set_rebind_proc=2]) + AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) -+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) ++ AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) + ) + LIBS="$saved_LIBS" + fi @@ -646,7 +646,7 @@ diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c --- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100 +++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,494 @@ +@@ -0,0 +1,499 @@ +/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. @@ -708,7 +708,11 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c + +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +static int ++#if LDAP_API_VERSION > 3000 ++_rebind_proc (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params) ++#else +_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) ++#endif +{ + struct timeval timeout; + int rc; diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 1497049..099c72d 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -223,10 +223,19 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-7.0p1/readconf.h.gsskexalg openssh-7.0p1/readconf.h ---- openssh-7.0p1/readconf.h.gsskexalg 2015-08-19 12:28:38.026518955 +0200 -+++ openssh-7.0p1/readconf.h 2015-08-19 12:28:38.079518836 +0200 -@@ -51,6 +51,7 @@ typedef struct { +@@ -2651,6 +2671,8 @@ dump_client_config(Options *o, const cha + dump_cfg_string(oGssClientIdentity, o->gss_client_identity); + dump_cfg_string(oGssServerIdentity, o->gss_client_identity); + dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); ++ dump_cfg_string(oKexAlgorithms, o->gss_kex_algorithms ? ++ o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX); + #endif /* GSSAPI */ + dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); + dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); +diff -up openssh-7.9p1/readconf.h.gsskexalg openssh-7.9p1/readconf.h +--- openssh-7.9p1/readconf.h.gsskexalg 2018-11-14 09:20:06.616350574 +0100 ++++ openssh-7.9p1/readconf.h 2018-11-14 09:20:06.647350828 +0100 +@@ -46,6 +46,7 @@ typedef struct { int gss_renewal_rekey; /* Credential renewal forces rekey */ char *gss_client_identity; /* Principal to initiate GSSAPI with */ char *gss_server_identity; /* GSSAPI target principal */ diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 6ab5e2c..11ab6ee 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -84,7 +84,7 @@ index a5a81ed2..63f877f2 100644 + /* There is at least one other ccache in collection + * we can switch to */ + krb5_cc_switch(ctx, ccache); -+ } else { ++ } else if (authctxt->krb5_ccname != NULL) { + /* Clean up the collection too */ + strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10); + krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1; diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 99a4411..933796a 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -142,7 +142,7 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config #PermitTTY yes -#PrintMotd yes + -+# It is recommended to use pam_motd in /etc/pam.d/ssh instead of PrintMotd, ++# 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/openssh-7.8p1-gsskex.patch b/openssh-7.8p1-gsskex.patch index 2903b69..cba36dc 100644 --- a/openssh-7.8p1-gsskex.patch +++ b/openssh-7.8p1-gsskex.patch @@ -2069,9 +2069,22 @@ diff -up openssh/readconf.c.gsskex openssh/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh/readconf.h.gsskex openssh/readconf.h ---- openssh/readconf.h.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/readconf.h 2018-08-22 11:47:33.314216481 +0200 +@@ -2603,7 +2645,12 @@ dump_client_config(Options *o, const cha + dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); + #ifdef GSSAPI + dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); ++ dump_cfg_fmtint(oGssKeyEx, o->gss_keyex); + dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); ++ dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns); ++ dump_cfg_string(oGssClientIdentity, o->gss_client_identity); ++ dump_cfg_string(oGssServerIdentity, o->gss_client_identity); ++ dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); + #endif /* GSSAPI */ + dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); + dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); +diff -up openssh-7.9p1/readconf.h.gsskex openssh-7.9p1/readconf.h +--- openssh-7.9p1/readconf.h.gsskex 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/readconf.h 2018-11-14 09:14:06.277379857 +0100 @@ -40,7 +40,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2468,7 +2481,7 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -194,6 +337,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -194,6 +339,16 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2479,14 +2492,13 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], + "%s,null", orig); -+ free(gss); + } +#endif + if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, options.rekey_interval); -@@ -214,11 +368,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -214,16 +369,46 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2518,7 +2530,22 @@ diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); /* remove ext-info from the KEX proposals for rekeying */ -@@ -314,6 +488,7 @@ int input_gssapi_token(int type, u_int32 + myproposal[PROPOSAL_KEX_ALGS] = + compat_kex_proposal(options.kex_algorithms); ++#ifdef GSSAPI ++ /* repair myproposal after it was crumpled by the */ ++ /* ext-info removal above */ ++ if (gss) { ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ free(gss); ++ } ++#endif + if ((r = kex_prop2buf(kex->my, myproposal)) != 0) + fatal("kex_prop2buf: %s", ssh_err(r)); + +@@ -314,6 +499,7 @@ int input_gssapi_token(int type, u_int32 int input_gssapi_hash(int type, u_int32_t, struct ssh *); int input_gssapi_error(int, u_int32_t, struct ssh *); int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -2875,31 +2902,4 @@ diff -up openssh/sshkey.h.gsskex openssh/sshkey.h + KEY_NULL, KEY_UNSPEC }; - ---- openssh/sshconnect2.c.orig 2017-01-04 19:47:10.000000000 +0100 -+++ openssh/sshconnect2.c 2017-01-05 04:13:08.977425272 +0100 -@@ -344,7 +344,6 @@ - orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], - "%s,null", orig); -- free(gss); - } - #endif - -@@ -398,6 +397,16 @@ - /* remove ext-info from the KEX proposals for rekeying */ - myproposal[PROPOSAL_KEX_ALGS] = - compat_kex_proposal(options.kex_algorithms); -+#ifdef GSSAPI -+ /* repair myproposal after it was crumpled by the */ -+ /* ext-info removal above */ -+ if (gss) { -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ free(gss); -+ } -+#endif - if ((r = kex_prop2buf(kex->my, myproposal)) != 0) - fatal("kex_prop2buf: %s", ssh_err(r)); diff --git a/openssh-7.9p1-disable-sha1.patch b/openssh-7.9p1-disable-sha1.patch new file mode 100644 index 0000000..c157b3c --- /dev/null +++ b/openssh-7.9p1-disable-sha1.patch @@ -0,0 +1,62 @@ +diff --git a/monitor.c b/monitor.c +index 12b33e7..a1c3c97 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -875,6 +875,34 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m) + } + #endif + ++/* ++ * Check that the key type appears in the supplied pattern list, ignoring ++ * mismastches in the signature algorithm. (Signature algorithm checks are ++ * performed in the unprivileged authentication code). ++ * Returns 1 on success, 0 otherwise. ++ */ ++static int ++key_base_type_match(const struct sshkey *key, const char *list) ++{ ++ char *s, *l, *ol = xstrdup(list); ++ int found = 0; ++ ++ l = ol; ++ for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) { ++ if (sshkey_type_from_name(s) == key->type) { ++ found = 1; ++ break; ++ } ++ } ++ if (!found) { ++ debug("key type %s does not appear in list %s", ++ sshkey_ssh_name(key), list); ++ } ++ ++ free(ol); ++ return found; ++} ++ + int + mm_answer_keyallowed(int sock, struct sshbuf *m) + { +@@ -909,8 +937,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) + break; + if (auth2_key_already_used(authctxt, key)) + break; +- if (match_pattern_list(sshkey_ssh_name(key), +- options.pubkey_key_types, 0) != 1) ++ if (!key_base_type_match(key, ++ options.pubkey_key_types)) + break; + allowed = user_key_allowed(ssh, authctxt->pw, key, + pubkey_auth_attempt, &opts); +@@ -921,8 +949,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) + break; + if (auth2_key_already_used(authctxt, key)) + break; +- if (match_pattern_list(sshkey_ssh_name(key), +- options.hostbased_key_types, 0) != 1) ++ if (!key_base_type_match(key, ++ options.hostbased_key_types)) + break; + allowed = hostbased_key_allowed(authctxt->pw, + cuser, chost, key); + From b3988fbe6691412c618bdbc11fb4ed45d0a7f5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 14 Jan 2019 19:03:17 +0100 Subject: [PATCH 064/146] Rebuilt for libcrypt.so.2 (#1666033) --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 6e846e7..30c9a97 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -539,6 +539,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Jan 14 2019 Björn Esser - 7.9p1-2.1 +- Rebuilt for libcrypt.so.2 (#1666033) + * Wed Nov 14 2018 Mattias Ellert - 7.9p1-2 - Based on openssh-7.9p1-2.fc29 From 460eae6bd421fd55d5b07d5db451ab02a9a8f8e6 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 15 Jan 2019 16:01:10 +0100 Subject: [PATCH 065/146] Based on openssh-7.9p1-3.fc29 --- gsi-openssh.spec | 18 +- openssh-7.0p1-gssKexAlgorithms.patch | 2 +- openssh-7.6p1-pkcs11-ecdsa.patch | 7 +- openssh-7.9p1-CVE-2018-20685.patch | 28 +++ openssh-7.9p1-backports.patch | 186 ++++++++++++++++ openssh-7.9p1-gsissh.patch | 14 +- openssh-7.9p1-match-final.patch | 306 +++++++++++++++++++++++++++ 7 files changed, 551 insertions(+), 10 deletions(-) create mode 100644 openssh-7.9p1-CVE-2018-20685.patch create mode 100644 openssh-7.9p1-backports.patch create mode 100644 openssh-7.9p1-match-final.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 30c9a97..4adcf2c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -168,6 +168,13 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # Allow to disable RSA signatures with SHA-1 in server # https://bugzilla.mindrot.org/show_bug.cgi?id=2746 Patch954: openssh-7.9p1-disable-sha1.patch +# Backport Match final so the crypto-policies do not break canonicalization (#1630166) +# https://bugzilla.mindrot.org/show_bug.cgi?id=2906 +Patch955: openssh-7.9p1-match-final.patch +# Backport more after-release fixes (#1665611) +Patch956: openssh-7.9p1-backports.patch +# Backport patch for CVE-2018-20685 (#1665786) +Patch957: openssh-7.9p1-CVE-2018-20685.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -328,6 +335,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch953 -p1 -b .scp-ipv6 %patch808 -p1 -b .gsskex-method %patch954 -p1 -b .disable-sha1 +%patch955 -p1 -b .match-final +%patch956 -p1 -b .backports +%patch957 -p1 -b .CVE-2018-20685 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -340,6 +350,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in 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} . @@ -539,6 +550,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Jan 15 2019 Mattias Ellert - 7.9p1-3 +- Based on openssh-7.9p1-3.fc29 + * Mon Jan 14 2019 Björn Esser - 7.9p1-2.1 - Rebuilt for libcrypt.so.2 (#1666033) diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 099c72d..8bd2d4e 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -227,7 +227,7 @@ diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c dump_cfg_string(oGssClientIdentity, o->gss_client_identity); dump_cfg_string(oGssServerIdentity, o->gss_client_identity); dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); -+ dump_cfg_string(oKexAlgorithms, o->gss_kex_algorithms ? ++ dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ? + o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX); #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch index 7f5f130..d356a90 100644 --- a/openssh-7.6p1-pkcs11-ecdsa.patch +++ b/openssh-7.6p1-pkcs11-ecdsa.patch @@ -124,10 +124,10 @@ diff -up openssh/ssh-pkcs11-client.c.pkcs11-ecdsa openssh/ssh-pkcs11-client.c fatal("%s: bad key: %s", __func__, ssh_err(r)); - wrap_key(k->rsa); + if(k->type == KEY_RSA) { -+ wrap_rsa_key(k->rsa); ++ wrap_rsa_key(k->rsa); +#ifdef ENABLE_PKCS11_ECDSA + } else if(k->type == KEY_ECDSA) { -+ wrap_ecdsa_key(k->ecdsa); ++ wrap_ecdsa_key(k->ecdsa); +#endif /* ENABLE_PKCS11_ECDSA */ + } else { + /* Unsupported type */ @@ -640,7 +640,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c } X509_free(x509); EVP_PKEY_free(evp); -@@ -725,6 +1021,17 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -725,6 +1021,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_p key->rsa = rsa; key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; @@ -650,6 +650,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + key->ecdsa = ecdsa; ++ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key->ecdsa); + key->type = KEY_ECDSA; + key->flags |= SSHKEY_FLAG_EXT; +#endif /* ENABLE_PKCS11_ECDSA */ diff --git a/openssh-7.9p1-CVE-2018-20685.patch b/openssh-7.9p1-CVE-2018-20685.patch new file mode 100644 index 0000000..db7a4f8 --- /dev/null +++ b/openssh-7.9p1-CVE-2018-20685.patch @@ -0,0 +1,28 @@ +From 6010c0303a422a9c5fa8860c061bf7105eb7f8b2 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Fri, 16 Nov 2018 03:03:10 +0000 +Subject: [PATCH] upstream: disallow empty incoming filename or ones that refer + to the + +current directory; based on report/patch from Harry Sintonen + +OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9 +--- + scp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/scp.c b/scp.c +index 60682c687..4f3fdcd3d 100644 +--- a/scp.c ++++ b/scp.c +@@ -1106,7 +1106,8 @@ sink(int argc, char **argv) + SCREWUP("size out of range"); + size = (off_t)ull; + +- if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { ++ if (*cp == '\0' || strchr(cp, '/') != NULL || ++ strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { + run_err("error: unexpected filename: %s", cp); + exit(1); + } + diff --git a/openssh-7.9p1-backports.patch b/openssh-7.9p1-backports.patch new file mode 100644 index 0000000..d89138b --- /dev/null +++ b/openssh-7.9p1-backports.patch @@ -0,0 +1,186 @@ +From 631165f6c43d230df9174423aeb19fcf09a67ef4 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Mon, 22 Oct 2018 11:22:50 +1100 +Subject: [PATCH 1/7] fix compile for openssl 1.0.x w/ --with-ssl-engine + +bz#2921, patch from cotequeiroz +--- + openbsd-compat/openssl-compat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c +index 8b4a3627..590b66d1 100644 +--- a/openbsd-compat/openssl-compat.c ++++ b/openbsd-compat/openssl-compat.c +@@ -76,7 +76,7 @@ ssh_OpenSSL_add_all_algorithms(void) + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); + +-#if OPENSSL_VERSION_NUMBER < 0x10001000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + OPENSSL_config(NULL); + #else + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | +-- +2.20.1 + + +From 55d7cdda4dc4e8284ccd276f73440be400250a1e Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Mon, 22 Oct 2018 20:05:18 +1100 +Subject: [PATCH 2/7] Include openssl compatibility. + +Patch from rosenp at gmail.com via openssh-unix-dev. +--- + ssh-keysign.c | 1 + + ssh_api.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/ssh-keysign.c b/ssh-keysign.c +index 744ecb4f..bcd1508c 100644 +--- a/ssh-keysign.c ++++ b/ssh-keysign.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include "openbsd-compat/openssl-compat.h" + #endif + + #include "xmalloc.h" +diff --git a/ssh_api.c b/ssh_api.c +index c84b4e71..e727c0d6 100644 +--- a/ssh_api.c ++++ b/ssh_api.c +@@ -29,6 +29,8 @@ + #include "ssherr.h" + #include "sshbuf.h" + ++#include "openbsd-compat/openssl-compat.h" ++ + #include + + int _ssh_exchange_banner(struct ssh *); +-- +2.20.1 + + +From 22092e375125dc602227afb8b2d3b285203e77c1 Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Mon, 5 Nov 2018 17:31:24 +1100 +Subject: [PATCH 3/7] Fix pasto for HAVE_EVP_CIPHER_CTX_SET_IV. + +Prevents unnecessary redefinition. Patch from mforney at mforney.org. +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 7379ab35..1041bf25 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2850,7 +2850,7 @@ if test "x$openssl" = "xyes" ; then + [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1], + [Define if libcrypto has EVP_CIPHER_CTX_get_iv])]) + AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto], +- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1], ++ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_SET_IV], [1], + [Define if libcrypto has EVP_CIPHER_CTX_set_iv])]) + + AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto], +-- +2.20.1 + + +From 904d478f07deabb401f741f88c67ab2e07f742bd Mon Sep 17 00:00:00 2001 +From: Darren Tucker +Date: Sun, 11 Nov 2018 15:54:54 +1100 +Subject: [PATCH 4/7] Remove hardcoded service name in cygwin setup. + +bz#2922, patch from Christian.Lupien at USherbrooke.ca, sanity check +by vinschen at redhat.com. +--- + contrib/cygwin/ssh-host-config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config +index 261020af..e9f038db 100644 +--- a/contrib/cygwin/ssh-host-config ++++ b/contrib/cygwin/ssh-host-config +@@ -307,7 +307,7 @@ check_service_files_ownership() { + + if [ -z "${run_service_as}" ] + then +- accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | ++ accnt_name=$(/usr/bin/cygrunsrv -VQ "${service_name}" | + /usr/bin/sed -ne 's/^Account *: *//gp') + if [ "${accnt_name}" = "LocalSystem" ] + then +-- +2.20.1 + + +From 4608a60cb4893a25490fd88ffdaaae6256381ae3 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Fri, 23 Nov 2018 10:45:20 +1100 +Subject: [PATCH 6/7] fix configure test for OpenSSL version + +square brackets in case statements may be eaten by autoconf. + +Report and fix from Filipp Gunbin; tweaked by naddy@ +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 1041bf25..9920ede5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2616,7 +2616,7 @@ if test "x$openssl" = "xyes" ; then + AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) + ;; + 100*) ;; # 1.0.x +- 101000[0123456]*) ++ 101000[[0123456]]*) + # https://github.com/openssl/openssl/pull/4613 + AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")]) + ;; +-- +2.20.1 + + +From f429c1b2ef631f2855e51a790cf71761d752bbca Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Thu, 27 Dec 2018 23:02:11 +0000 +Subject: [PATCH 7/7] upstream: Request RSA-SHA2 signatures for + +rsa-sha2-{256|512}-cert-v01@openssh.com cert algorithms; ok markus@ + +OpenBSD-Commit-ID: afc6f7ca216ccd821656d1c911d2a3deed685033 +--- + authfd.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/authfd.c b/authfd.c +index ecdd869a..62cbf8c1 100644 +--- a/authfd.c ++++ b/authfd.c +@@ -327,10 +327,12 @@ ssh_free_identitylist(struct ssh_identitylist *idl) + static u_int + agent_encode_alg(const struct sshkey *key, const char *alg) + { +- if (alg != NULL && key->type == KEY_RSA) { +- if (strcmp(alg, "rsa-sha2-256") == 0) ++ if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) { ++ if (strcmp(alg, "rsa-sha2-256") == 0 || ++ strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0) + return SSH_AGENT_RSA_SHA2_256; +- else if (strcmp(alg, "rsa-sha2-512") == 0) ++ if (strcmp(alg, "rsa-sha2-512") == 0 || ++ strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0) + return SSH_AGENT_RSA_SHA2_512; + } + return 0; +-- +2.20.1 + diff --git a/openssh-7.9p1-gsissh.patch b/openssh-7.9p1-gsissh.patch index 29e5ddf..0e83984 100644 --- a/openssh-7.9p1-gsissh.patch +++ b/openssh-7.9p1-gsissh.patch @@ -2184,7 +2184,7 @@ diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c --- openssh-7.9p1.orig/ssh.c 2018-10-23 23:08:05.778762125 +0200 +++ openssh-7.9p1/ssh.c 2018-10-23 23:09:11.674055109 +0200 -@@ -541,6 +541,32 @@ +@@ -541,6 +541,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2200,18 +2200,24 @@ diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif +#if defined(KRB5) + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, &options, 1); ++ (void)read_config_file(buf, pw, host, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif +#endif r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, diff --git a/openssh-7.9p1-match-final.patch b/openssh-7.9p1-match-final.patch new file mode 100644 index 0000000..4c28fcf --- /dev/null +++ b/openssh-7.9p1-match-final.patch @@ -0,0 +1,306 @@ +commit 9e34e0c59ab04514f9de9934a772283f7f372afe +Author: djm@openbsd.org +Date: Fri Nov 23 05:08:07 2018 +0000 + + upstream: add a ssh_config "Match final" predicate + + Matches in same pass as "Match canonical" but doesn't require + hostname canonicalisation be enabled. bz#2906 ok markus + + OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa + +diff --git a/readconf.c b/readconf.c +index 7850f2f5..7331ef5a 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -133,10 +133,11 @@ + + static int read_config_file_depth(const char *filename, struct passwd *pw, + const char *host, const char *original_host, Options *options, +- int flags, int *activep, int depth); ++ int flags, int *activep, int *want_final_pass, int depth); + static int process_config_line_depth(Options *options, struct passwd *pw, + const char *host, const char *original_host, char *line, +- const char *filename, int linenum, int *activep, int flags, int depth); ++ const char *filename, int linenum, int *activep, int flags, ++ int *want_final_pass, int depth); + + /* Keyword tokens. */ + +@@ -539,8 +540,8 @@ execute_in_shell(const char *cmd) + */ + static int + match_cfg_line(Options *options, char **condition, struct passwd *pw, +- const char *host_arg, const char *original_host, int post_canon, +- const char *filename, int linenum) ++ const char *host_arg, const char *original_host, int final_pass, ++ int *want_final_pass, const char *filename, int linenum) + { + char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; + const char *ruser; +@@ -554,7 +555,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, + */ + port = options->port <= 0 ? default_ssh_port() : options->port; + ruser = options->user == NULL ? pw->pw_name : options->user; +- if (post_canon) { ++ if (final_pass) { + host = xstrdup(options->hostname); + } else if (options->hostname != NULL) { + /* NB. Please keep in sync with ssh.c:main() */ +@@ -586,8 +587,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, + goto out; + } + attributes++; +- if (strcasecmp(attrib, "canonical") == 0) { +- r = !!post_canon; /* force bitmask member to boolean */ ++ if (strcasecmp(attrib, "canonical") == 0 || ++ strcasecmp(attrib, "final") == 0) { ++ /* ++ * If the config requests "Match final" then remember ++ * this so we can perform a second pass later. ++ */ ++ if (strcasecmp(attrib, "final") == 0 && ++ want_final_pass != NULL) ++ *want_final_pass = 1; ++ r = !!final_pass; /* force bitmask member to boolean */ + if (r == (negate ? 1 : 0)) + this_result = result = 0; + debug3("%.200s line %d: %smatched '%s'", +@@ -824,14 +833,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host, + int linenum, int *activep, int flags) + { + return process_config_line_depth(options, pw, host, original_host, +- line, filename, linenum, activep, flags, 0); ++ line, filename, linenum, activep, flags, NULL, 0); + } + + #define WHITESPACE " \t\r\n" + static int + process_config_line_depth(Options *options, struct passwd *pw, const char *host, + const char *original_host, char *line, const char *filename, +- int linenum, int *activep, int flags, int depth) ++ int linenum, int *activep, int flags, int *want_final_pass, int depth) + { + char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; + char **cpptr, fwdarg[256]; +@@ -1339,7 +1348,8 @@ parse_keytypes: + fatal("Host directive not supported as a command-line " + "option"); + value = match_cfg_line(options, &s, pw, host, original_host, +- flags & SSHCONF_POSTCANON, filename, linenum); ++ flags & SSHCONF_FINAL, want_final_pass, ++ filename, linenum); + if (value < 0) + fatal("%.200s line %d: Bad Match condition", filename, + linenum); +@@ -1548,7 +1558,7 @@ parse_keytypes: + pw, host, original_host, options, + flags | SSHCONF_CHECKPERM | + (oactive ? 0 : SSHCONF_NEVERMATCH), +- activep, depth + 1); ++ activep, want_final_pass, depth + 1); + if (r != 1 && errno != ENOENT) { + fatal("Can't open user config file " + "%.100s: %.100s", gl.gl_pathv[i], +@@ -1751,19 +1761,20 @@ parse_keytypes: + */ + int + read_config_file(const char *filename, struct passwd *pw, const char *host, +- const char *original_host, Options *options, int flags) ++ const char *original_host, Options *options, int flags, ++ int *want_final_pass) + { + int active = 1; + + return read_config_file_depth(filename, pw, host, original_host, +- options, flags, &active, 0); ++ options, flags, &active, want_final_pass, 0); + } + + #define READCONF_MAX_DEPTH 16 + static int + read_config_file_depth(const char *filename, struct passwd *pw, + const char *host, const char *original_host, Options *options, +- int flags, int *activep, int depth) ++ int flags, int *activep, int *want_final_pass, int depth) + { + FILE *f; + char *line = NULL; +@@ -1798,7 +1809,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, + /* Update line number counter. */ + linenum++; + if (process_config_line_depth(options, pw, host, original_host, +- line, filename, linenum, activep, flags, depth) != 0) ++ line, filename, linenum, activep, flags, want_final_pass, ++ depth) != 0) + bad_options++; + } + free(line); +diff --git a/readconf.h b/readconf.h +index fc7e3825..8e36bf32 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -185,7 +185,7 @@ typedef struct { + + #define SSHCONF_CHECKPERM 1 /* check permissions on config file */ + #define SSHCONF_USERCONF 2 /* user provided config file not system */ +-#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ ++#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */ + #define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ + + #define SSH_UPDATE_HOSTKEYS_NO 0 +@@ -203,7 +203,7 @@ void fill_default_options_for_canonicalization(Options *); + int process_config_line(Options *, struct passwd *, const char *, + const char *, char *, const char *, int, int *, int); + int read_config_file(const char *, struct passwd *, const char *, +- const char *, Options *, int); ++ const char *, Options *, int, int *); + int parse_forward(struct Forward *, const char *, int, int); + int parse_jump(const char *, Options *, int); + int parse_ssh_uri(const char *, char **, char **, int *); +diff --git a/ssh-keysign.c b/ssh-keysign.c +index 8f487b8c..7ea5ad0e 100644 +--- a/ssh-keysign.c ++++ b/ssh-keysign.c +@@ -208,7 +208,8 @@ main(int argc, char **argv) + + /* verify that ssh-keysign is enabled by the admin */ + initialize_options(&options); +- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0); ++ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", ++ &options, 0, NULL); + fill_default_options(&options); + if (options.enable_ssh_keysign != 1) + fatal("ssh-keysign not enabled in %s", +diff --git a/ssh.c b/ssh.c +index 1ac903d1..c6cb7847 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -527,7 +527,8 @@ check_load(int r, const char *path, const char *message) + * file if the user specifies a config file on the command line. + */ + static void +-process_config_files(const char *host_name, struct passwd *pw, int post_canon) ++process_config_files(const char *host_name, struct passwd *pw, int final_pass, ++ int *want_final_pass) + { + char buf[PATH_MAX]; + int r; +@@ -535,7 +536,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) + if (config != NULL) { + if (strcasecmp(config, "none") != 0 && + !read_config_file(config, pw, host, host_name, &options, +- SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) ++ SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), ++ want_final_pass)) + fatal("Can't open user config file %.100s: " + "%.100s", config, strerror(errno)); + } else { +@@ -544,12 +546,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) + if (r > 0 && (size_t)r < sizeof(buf)) + (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | +- (post_canon ? SSHCONF_POSTCANON : 0)); ++ (final_pass ? SSHCONF_FINAL : 0), want_final_pass); + + /* Read systemwide configuration file after user config. */ + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, + host, host_name, &options, +- post_canon ? SSHCONF_POSTCANON : 0); ++ final_pass ? SSHCONF_FINAL : 0, want_final_pass); + } + } + +@@ -581,7 +583,7 @@ main(int ac, char **av) + { + struct ssh *ssh = NULL; + int i, r, opt, exit_status, use_syslog, direct, timeout_ms; +- int was_addr, config_test = 0, opt_terminated = 0; ++ int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; + char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; + char cname[NI_MAXHOST]; + struct stat st; +@@ -1089,7 +1091,9 @@ main(int ac, char **av) + ); + + /* Parse the configuration files */ +- process_config_files(host_arg, pw, 0); ++ process_config_files(host_arg, pw, 0, &want_final_pass); ++ if (want_final_pass) ++ debug("configuration requests final Match pass"); + + /* Hostname canonicalisation needs a few options filled. */ + fill_default_options_for_canonicalization(&options); +@@ -1146,12 +1150,17 @@ main(int ac, char **av) + * If canonicalisation is enabled then re-parse the configuration + * files as new stanzas may match. + */ +- if (options.canonicalize_hostname != 0) { +- debug("Re-reading configuration after hostname " +- "canonicalisation"); ++ if (options.canonicalize_hostname != 0 && !want_final_pass) { ++ debug("hostname canonicalisation enabled, " ++ "will re-parse configuration"); ++ want_final_pass = 1; ++ } ++ ++ if (want_final_pass) { ++ debug("re-parsing configuration"); + free(options.hostname); + options.hostname = xstrdup(host); +- process_config_files(host_arg, pw, 1); ++ process_config_files(host_arg, pw, 1, NULL); + /* + * Address resolution happens early with canonicalisation + * enabled and the port number may have changed since, so +diff --git a/ssh_config.5 b/ssh_config.5 +index 4d5b01d3..58a5fa1c 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -139,6 +139,7 @@ or the single token + which always matches. + The available criteria keywords are: + .Cm canonical , ++.Cm final , + .Cm exec , + .Cm host , + .Cm originalhost , +@@ -148,12 +149,15 @@ and + The + .Cm all + criteria must appear alone or immediately after +-.Cm canonical . ++.Cm canonical ++or ++.Cm final . + Other criteria may be combined arbitrarily. + All criteria but + .Cm all +-and + .Cm canonical ++and ++.Cm final + require an argument. + Criteria may be negated by prepending an exclamation mark + .Pq Sq !\& . +@@ -166,6 +170,20 @@ after hostname canonicalization (see the + option.) + This may be useful to specify conditions that work with canonical host + names only. ++.Pp ++The ++.Cm final ++keyword requests that the configuration be re-parsed (regardless of whether ++.Cm CanonicalizeHostname ++is enabled), and matches only during this final pass. ++If ++.Cm CanonicalizeHostname ++is enabled, then ++.Cm canonical ++and ++.Cm final ++match during the same pass. ++.Pp + The + .Cm exec + keyword executes the specified command under the user's shell. From bd3d327c9ae3c99f5c88e73cb683836fb55fc4c9 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 28 Jan 2019 20:17:47 +0100 Subject: [PATCH 066/146] Remove obsolete Group tag References: https://fedoraproject.org/wiki/Changes/Remove_Group_Tag --- gsi-openssh.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 4adcf2c..1a50400 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -181,7 +181,6 @@ Patch957: openssh-7.9p1-CVE-2018-20685.patch Patch98: openssh-7.9p1-gsissh.patch License: BSD -Group: Applications/Internet Requires: /sbin/nologin Obsoletes: %{name}-clients-fips, %{name}-server-fips @@ -229,7 +228,6 @@ BuildRequires: gnupg2 Summary: SSH client applications with GSI authentication Provides: gsissh-clients = %{version}-%{release} Obsoletes: gsissh-clients < 5.8p2-2 -Group: Applications/Internet Requires: %{name} = %{version}-%{release} Requires: fipscheck-lib%{_isa} >= 1.3.0 Requires: crypto-policies >= 20180306-1 @@ -238,7 +236,6 @@ Requires: crypto-policies >= 20180306-1 Summary: SSH server daemon with GSI authentication Provides: gsissh-server = %{version}-%{release} Obsoletes: gsissh-server < 5.8p2-2 -Group: System Environment/Daemons Requires: %{name} = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 From f09e89f05d85766280afabbb40f731930b361e19 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 1 Feb 2019 01:40:10 +0000 Subject: [PATCH 067/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 1a50400..c3edb56 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -547,6 +547,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Feb 01 2019 Fedora Release Engineering - 7.9p1-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + * Tue Jan 15 2019 Mattias Ellert - 7.9p1-3 - Based on openssh-7.9p1-3.fc29 From ae75c3d4f7c1860d9fccbcfddcb8cc354e2e5342 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 7 Feb 2019 14:21:29 +0100 Subject: [PATCH 068/146] Based on openssh-7.9p1-4.fc29 --- gsi-openssh.spec | 16 ++++++++-- openssh-7.7p1-redhat.patch | 18 ++++++----- openssh-7.9p1-log-sftp-only-connections.patch | 11 +++++++ openssh-7.9p1-ssh-copy-id.patch | 31 +++++++++++++++++++ 4 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 openssh-7.9p1-log-sftp-only-connections.patch create mode 100644 openssh-7.9p1-ssh-copy-id.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index c3edb56..3470c62 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -175,6 +175,13 @@ Patch955: openssh-7.9p1-match-final.patch Patch956: openssh-7.9p1-backports.patch # Backport patch for CVE-2018-20685 (#1665786) Patch957: openssh-7.9p1-CVE-2018-20685.patch +# ssh-copy-id is unmaintained: Aggreagete patches +# - do not return 0 if the write fails (full disk) +# - shellcheck reports (upstream #2902) +Patch958: openssh-7.9p1-ssh-copy-id.patch +# log when a client requests an interactive session and only sftp is allowed +# https://bugzilla.mindrot.org/show_bug.cgi?id=2960 +Patch959: openssh-7.9p1-log-sftp-only-connections.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -335,6 +342,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch955 -p1 -b .match-final %patch956 -p1 -b .backports %patch957 -p1 -b .CVE-2018-20685 +%patch958 -p1 -b .ssh-copy-id +%patch959 -p1 -b .log-sftp-only %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -547,6 +556,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Feb 07 2019 Mattias Ellert - 7.9p1-4 +- Based on openssh-7.9p1-4.fc29 + * Fri Feb 01 2019 Fedora Release Engineering - 7.9p1-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 933796a..6fd9daf 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -12,15 +12,13 @@ diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat --- openssh-7.7p1/ssh_config_redhat.redhat 2018-07-03 10:44:06.522245125 +0200 +++ openssh-7.7p1/ssh_config_redhat 2018-07-03 10:44:06.522245125 +0200 -@@ -0,0 +1,20 @@ -+# Follow system-wide Crypto Policy, if defined: -+Include /etc/crypto-policies/back-ends/openssh.config +@@ -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 ++ # Follow system-wide Crypto Policy, if defined: ++ Include /etc/crypto-policies/back-ends/openssh.config + -+# Uncomment this if you want to use .local domain -+# Host *.local -+# CheckHostIP no -+ -+Host * + GSSAPIAuthentication yes + +# If this option is set to yes then remote X11 clients will have full access @@ -33,6 +31,10 @@ diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat + 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 ++# CheckHostIP no diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0 --- openssh-7.7p1/sshd_config.0.redhat 2018-04-02 07:39:27.000000000 +0200 +++ openssh-7.7p1/sshd_config.0 2018-07-03 10:44:06.523245133 +0200 diff --git a/openssh-7.9p1-log-sftp-only-connections.patch b/openssh-7.9p1-log-sftp-only-connections.patch new file mode 100644 index 0000000..3b3613d --- /dev/null +++ b/openssh-7.9p1-log-sftp-only-connections.patch @@ -0,0 +1,11 @@ +diff --git a/session.c b/session.c +--- a/session.c ++++ b/session.c +@@ -1859,6 +1859,7 @@ do_child(Session *s, const char *command) + + if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { + printf("This service allows sftp connections only.\n"); ++ logit("The session allows sftp connections only"); + fflush(NULL); + exit(1); + } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { diff --git a/openssh-7.9p1-ssh-copy-id.patch b/openssh-7.9p1-ssh-copy-id.patch new file mode 100644 index 0000000..d47880a --- /dev/null +++ b/openssh-7.9p1-ssh-copy-id.patch @@ -0,0 +1,31 @@ +diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id +--- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/contrib/ssh-copy-id 2019-01-23 20:49:30.513393667 +0100 +@@ -112,7 +112,8 @@ do + usage + } + +- OPT= OPTARG= ++ OPT= ++ OPTARG= + # implement something like getopt to avoid Solaris pain + case "$1" in + -i?*|-o?*|-p?*) +@@ -261,7 +262,7 @@ populate_new_ids() { + fi + if [ -z "$NEW_IDS" ] ; then + printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 +- printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 ++ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2 + exit 0 + fi + printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 +@@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in + # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; + # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ +- ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ ++ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ + || exit 1 + ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) + ;; From 515c95fb14f0a258c90e6760d2ee5ccf41dbf28e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 8 Feb 2019 22:18:53 +0100 Subject: [PATCH 069/146] CVE-2019-7639 --- gsi-openssh.spec | 5 ++++- openssh-7.9p1-gsissh.patch | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 3470c62..090409a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -556,6 +556,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Feb 08 2019 Mattias Ellert - 7.9p1-5 +- CVE-2019-7639 + * Thu Feb 07 2019 Mattias Ellert - 7.9p1-4 - Based on openssh-7.9p1-4.fc29 diff --git a/openssh-7.9p1-gsissh.patch b/openssh-7.9p1-gsissh.patch index 0e83984..031f154 100644 --- a/openssh-7.9p1-gsissh.patch +++ b/openssh-7.9p1-gsissh.patch @@ -372,7 +372,7 @@ diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c --- openssh-7.9p1.orig/auth-pam.c 2018-10-23 23:08:05.624763778 +0200 +++ openssh-7.9p1/auth-pam.c 2018-10-23 23:09:11.659055270 +0200 -@@ -288,6 +288,55 @@ +@@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -396,6 +396,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c +void +sshpam_check_userchanged(void) +{ ++ int sshpam_err; + struct passwd *pw; + const char *user; + From a7d5063016644d6adfcdece9565c426f521e7bd9 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 27 Feb 2019 08:59:43 +0100 Subject: [PATCH 070/146] Remove usage statistics collection support --- gsi-openssh.spec | 8 +- openssh-7.9p1-gsissh.patch | 1000 ++++-------------------------------- 2 files changed, 119 insertions(+), 889 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 090409a..e75071b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 5 +%global openssh_rel 6 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -213,7 +213,6 @@ BuildRequires: krb5-devel BuildRequires: globus-gss-assist-devel >= 8 BuildRequires: globus-gssapi-gsi-devel >= 12.12 BuildRequires: globus-common-devel >= 14 -BuildRequires: globus-usage-devel >= 3 %endif %if %{libedit} @@ -512,7 +511,7 @@ getent passwd sshd >/dev/null || \ %systemd_postun_with_restart gsisshd.service %files -%license LICENCE LICENSE.globus_usage +%license LICENCE %doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli @@ -556,6 +555,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Feb 27 2019 Mattias Ellert - 7.9p1-6 +- Remove usage statistics collection support + * Fri Feb 08 2019 Mattias Ellert - 7.9p1-5 - CVE-2019-7639 diff --git a/openssh-7.9p1-gsissh.patch b/openssh-7.9p1-gsissh.patch index 031f154..666fb14 100644 --- a/openssh-7.9p1-gsissh.patch +++ b/openssh-7.9p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c ---- openssh-7.9p1.orig/auth2.c 2018-10-23 23:08:05.762762297 +0200 -+++ openssh-7.9p1/auth2.c 2018-10-23 23:09:11.656055302 +0200 +--- openssh-7.9p1.orig/auth2.c 2019-02-27 08:08:38.955515147 +0100 ++++ openssh-7.9p1/auth2.c 2019-02-27 08:09:31.745945233 +0100 @@ -270,7 +270,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); @@ -100,8 +100,8 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c ---- openssh-7.9p1.orig/auth2-gss.c 2018-10-23 23:08:05.758762340 +0200 -+++ openssh-7.9p1/auth2-gss.c 2018-10-24 17:39:01.494342784 +0200 +--- openssh-7.9p1.orig/auth2-gss.c 2019-02-27 08:08:38.915515578 +0100 ++++ openssh-7.9p1/auth2-gss.c 2019-02-27 08:09:31.783944823 +0100 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -290,19 +290,9 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c ---- openssh-7.9p1.orig/auth.c 2018-10-23 23:08:05.763762286 +0200 -+++ openssh-7.9p1/auth.c 2018-10-23 23:09:11.658055281 +0200 -@@ -76,6 +76,9 @@ - #include "compat.h" - #include "channels.h" - -+#include "version.h" -+#include "ssh-globus-usage.h" -+ - /* import */ - extern ServerOptions options; - extern int use_privsep; -@@ -343,7 +346,8 @@ +--- openssh-7.9p1.orig/auth.c 2019-02-27 08:08:38.957515125 +0100 ++++ openssh-7.9p1/auth.c 2019-02-27 08:09:31.784944812 +0100 +@@ -343,7 +343,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -312,31 +302,7 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -369,6 +373,23 @@ - if (authenticated == 0 && !authctxt->postponed && !partial) - audit_event(audit_classify_auth(method)); - #endif -+ if (authenticated) { -+ char *userdn = NULL; -+ char *mech_name = NULL; -+#ifdef GSSAPI -+ ssh_gssapi_get_client_info(&userdn, &mech_name); -+#endif -+ debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)", -+ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), -+ method, mech_name?mech_name:"NULL", ssh_remote_ipaddr(ssh), -+ (authctxt->user && authctxt->user[0])? -+ authctxt->user : "unknown", -+ userdn?userdn:"NULL"); -+ ssh_globus_send_usage_metrics(SSH_RELEASE, -+ SSLeay_version(SSLEAY_VERSION), -+ method, mech_name, ssh_remote_ipaddr(ssh), -+ authctxt->user, userdn); -+ } - } - - -@@ -581,6 +602,10 @@ +@@ -581,6 +582,10 @@ #endif pw = getpwnam(user); @@ -347,7 +313,7 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -600,7 +625,8 @@ +@@ -600,7 +605,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -358,8 +324,8 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c record_failed_login(user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h ---- openssh-7.9p1.orig/auth.h 2018-10-23 23:08:05.763762286 +0200 -+++ openssh-7.9p1/auth.h 2018-10-23 23:09:11.658055281 +0200 +--- openssh-7.9p1.orig/auth.h 2019-02-27 08:08:38.957515125 +0100 ++++ openssh-7.9p1/auth.h 2019-02-27 08:09:31.784944812 +0100 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -370,8 +336,8 @@ diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c ---- openssh-7.9p1.orig/auth-pam.c 2018-10-23 23:08:05.624763778 +0200 -+++ openssh-7.9p1/auth-pam.c 2018-10-23 23:09:11.659055270 +0200 +--- openssh-7.9p1.orig/auth-pam.c 2019-02-27 08:08:38.523519810 +0100 ++++ openssh-7.9p1/auth-pam.c 2019-02-27 08:11:41.378545748 +0100 @@ -288,6 +288,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -429,7 +395,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -319,7 +368,7 @@ +@@ -319,7 +369,7 @@ static void import_environments(struct sshbuf *b) { @@ -438,7 +404,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c u_int n, i, num_env; int r; -@@ -335,6 +384,19 @@ +@@ -335,6 +385,19 @@ if ((r = sshbuf_get_u32(b, &n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshpam_password_change_required(n != 0); @@ -458,7 +424,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -507,6 +569,13 @@ +@@ -507,6 +570,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -472,7 +438,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -527,6 +596,13 @@ +@@ -527,6 +597,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -486,7 +452,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -1024,6 +1100,18 @@ +@@ -1024,6 +1101,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -505,7 +471,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1314,6 +1402,9 @@ +@@ -1314,6 +1403,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -516,8 +482,8 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-7.9p1.orig/auth-pam.h openssh-7.9p1/auth-pam.h ---- openssh-7.9p1.orig/auth-pam.h 2018-10-23 23:08:05.625763767 +0200 -+++ openssh-7.9p1/auth-pam.h 2018-10-23 23:09:11.659055270 +0200 +--- openssh-7.9p1.orig/auth-pam.h 2019-02-27 08:08:38.523519810 +0100 ++++ openssh-7.9p1/auth-pam.h 2019-02-27 08:09:31.784944812 +0100 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -527,7 +493,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.h openssh-7.9p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c --- openssh-7.9p1.orig/canohost.c 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/canohost.c 2018-10-23 23:09:11.660055260 +0200 ++++ openssh-7.9p1/canohost.c 2019-02-27 08:09:31.803944607 +0100 @@ -17,6 +17,7 @@ #include #include @@ -572,7 +538,7 @@ diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c +} diff -Nur openssh-7.9p1.orig/canohost.h openssh-7.9p1/canohost.h --- openssh-7.9p1.orig/canohost.h 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/canohost.h 2018-10-23 23:09:11.660055260 +0200 ++++ openssh-7.9p1/canohost.h 2019-02-27 08:09:31.803944607 +0100 @@ -23,4 +23,6 @@ #endif /* _CANOHOST_H */ @@ -581,8 +547,8 @@ diff -Nur openssh-7.9p1.orig/canohost.h openssh-7.9p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac ---- openssh-7.9p1.orig/configure.ac 2018-10-23 23:08:05.747762458 +0200 -+++ openssh-7.9p1/configure.ac 2018-10-23 23:09:11.661055249 +0200 +--- openssh-7.9p1.orig/configure.ac 2019-02-27 08:08:38.942515287 +0100 ++++ openssh-7.9p1/configure.ac 2019-02-27 08:09:31.806944574 +0100 @@ -4631,6 +4631,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -598,7 +564,7 @@ diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4670,6 +4678,50 @@ +@@ -4670,6 +4678,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -624,34 +590,24 @@ diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac + GSSAPI="GSI" + fi + -+ LIBS="$LIBS `pkg-config --libs globus-gss-assist globus-gssapi-gsi globus-common`" -+ CPPFLAGS="$CPPFLAGS `pkg-config --cflags globus-gss-assist globus-gssapi-gsi globus-common`" ++ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) ++ if test "x$PKGCONFIG" != "xno"; then ++ LIBS="$LIBS `$PKGCONFIG --libs globus-gss-assist globus-gssapi-gsi globus-common`" ++ CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags globus-gss-assist globus-gssapi-gsi globus-common`" ++ fi + + AC_DEFINE(GSSAPI) + AC_DEFINE(HAVE_GSSAPI_H) + + AC_CHECK_FUNCS(globus_gss_assist_map_and_authorize) -+ -+ dnl -+ dnl Check for globus_usage_stats_send -+ dnl -+ AC_SEARCH_LIBS(globus_usage_stats_send, -+ globus_usage, -+ AC_DEFINE([HAVE_GLOBUS_USAGE], 1, [Have Globus Usage])) -+ dnl -+ dnl Check for globus_usage_stats_send_array -+ dnl -+ AC_SEARCH_LIBS(globus_usage_stats_send_array, -+ globus_usage, -+ AC_DEFINE([HAVE_GLOBUS_USAGE_SEND_ARRAY], 1, [Have Globus Usage send_array])) +fi + # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c ---- openssh-7.9p1.orig/gss-genr.c 2018-10-23 23:08:05.738762555 +0200 -+++ openssh-7.9p1/gss-genr.c 2018-10-23 23:09:11.662055238 +0200 +--- openssh-7.9p1.orig/gss-genr.c 2019-02-27 08:08:38.859516183 +0100 ++++ openssh-7.9p1/gss-genr.c 2019-02-27 08:09:31.806944574 +0100 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -689,8 +645,8 @@ diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c return (ctx->major); } diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c ---- openssh-7.9p1.orig/gss-serv.c 2018-10-23 23:08:05.758762340 +0200 -+++ openssh-7.9p1/gss-serv.c 2018-10-23 23:20:40.923607619 +0200 +--- openssh-7.9p1.orig/gss-serv.c 2019-02-27 08:08:38.915515578 +0100 ++++ openssh-7.9p1/gss-serv.c 2019-02-27 08:09:31.807944563 +0100 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -971,23 +927,9 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -@@ -567,4 +665,13 @@ - return (char *)gssapi_client.displayname.value; - } - -+/* added for Globus usage */ -+void -+ssh_gssapi_get_client_info(char **userdn, char **mech) { -+ *userdn = gssapi_client.displayname.value; -+ -+ if (gssapi_client.mech) -+ *mech = gssapi_client.mech->name; -+} -+ - #endif diff -Nur openssh-7.9p1.orig/gss-serv-gsi.c openssh-7.9p1/gss-serv-gsi.c --- openssh-7.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.9p1/gss-serv-gsi.c 2018-10-23 23:09:11.664055217 +0200 ++++ openssh-7.9p1/gss-serv-gsi.c 2019-02-27 08:09:31.807944563 +0100 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1318,8 +1260,8 @@ diff -Nur openssh-7.9p1.orig/gss-serv-gsi.c openssh-7.9p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c ---- openssh-7.9p1.orig/gss-serv-krb5.c 2018-10-23 23:08:05.707762887 +0200 -+++ openssh-7.9p1/gss-serv-krb5.c 2018-10-23 23:09:11.664055217 +0200 +--- openssh-7.9p1.orig/gss-serv-krb5.c 2019-02-27 08:08:38.787516960 +0100 ++++ openssh-7.9p1/gss-serv-krb5.c 2019-02-27 08:09:31.807944563 +0100 @@ -379,6 +379,34 @@ return found_principal; } @@ -1374,8 +1316,8 @@ diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-7.9p1.orig/kexgsss.c openssh-7.9p1/kexgsss.c ---- openssh-7.9p1.orig/kexgsss.c 2018-10-23 23:08:05.734762597 +0200 -+++ openssh-7.9p1/kexgsss.c 2018-10-23 23:09:11.665055206 +0200 +--- openssh-7.9p1.orig/kexgsss.c 2019-02-27 08:08:38.852516259 +0100 ++++ openssh-7.9p1/kexgsss.c 2019-02-27 08:09:31.808944553 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1435,45 +1377,20 @@ diff -Nur openssh-7.9p1.orig/kexgsss.c openssh-7.9p1/kexgsss.c + } +} #endif /* GSSAPI */ -diff -Nur openssh-7.9p1.orig/LICENSE.globus_usage openssh-7.9p1/LICENSE.globus_usage ---- openssh-7.9p1.orig/LICENSE.globus_usage 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.9p1/LICENSE.globus_usage 2018-10-23 23:09:11.665055206 +0200 -@@ -0,0 +1,18 @@ -+/* -+ * Portions of the Usage Metrics suport code are derived from the -+ * Globus project's GridFTP subject to the following license. -+ * -+ * Copyright 2010 University of Chicago -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ diff -Nur openssh-7.9p1.orig/Makefile.in openssh-7.9p1/Makefile.in ---- openssh-7.9p1.orig/Makefile.in 2018-10-23 23:08:05.776762147 +0200 -+++ openssh-7.9p1/Makefile.in 2018-10-23 23:09:11.666055195 +0200 -@@ -124,8 +124,10 @@ +--- openssh-7.9p1.orig/Makefile.in 2019-02-27 08:08:39.000514661 +0100 ++++ openssh-7.9p1/Makefile.in 2019-02-27 08:09:31.808944553 +0100 +@@ -124,6 +124,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ -+ ssh-globus-usage.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o uidswap.o diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c ---- openssh-7.9p1.orig/misc.c 2018-10-23 23:08:05.705762909 +0200 -+++ openssh-7.9p1/misc.c 2018-10-23 23:09:11.666055195 +0200 +--- openssh-7.9p1.orig/misc.c 2019-02-27 08:08:38.783517003 +0100 ++++ openssh-7.9p1/misc.c 2019-02-27 08:09:31.808944553 +0100 @@ -238,11 +238,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1534,8 +1451,8 @@ diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-7.9p1.orig/misc.h openssh-7.9p1/misc.h ---- openssh-7.9p1.orig/misc.h 2018-10-23 23:08:05.705762909 +0200 -+++ openssh-7.9p1/misc.h 2018-10-23 23:09:11.667055184 +0200 +--- openssh-7.9p1.orig/misc.h 2019-02-27 08:08:38.783517003 +0100 ++++ openssh-7.9p1/misc.h 2019-02-27 08:09:31.808944553 +0100 @@ -83,6 +83,7 @@ void sock_set_v6only(int); @@ -1545,8 +1462,8 @@ diff -Nur openssh-7.9p1.orig/misc.h openssh-7.9p1/misc.h typedef struct arglist arglist; diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c ---- openssh-7.9p1.orig/monitor.c 2018-10-23 23:08:05.782762082 +0200 -+++ openssh-7.9p1/monitor.c 2018-10-23 23:09:11.668055174 +0200 +--- openssh-7.9p1.orig/monitor.c 2019-02-27 08:08:39.014514510 +0100 ++++ openssh-7.9p1/monitor.c 2019-02-27 08:09:31.809944542 +0100 @@ -152,6 +152,9 @@ int mm_answer_gss_userok(int, struct sshbuf *); int mm_answer_gss_checkmic(int, struct sshbuf *); @@ -1637,7 +1554,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2042,6 +2057,79 @@ +@@ -2070,6 +2085,79 @@ return (authenticated); } @@ -1717,7 +1634,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c int mm_answer_gss_sign(int socket, struct sshbuf *m) { -@@ -2093,12 +2181,14 @@ +@@ -2121,12 +2209,14 @@ ssh_gssapi_ccache store; int ok, r; @@ -1734,8 +1651,8 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c free(store.envval); diff -Nur openssh-7.9p1.orig/monitor.h openssh-7.9p1/monitor.h ---- openssh-7.9p1.orig/monitor.h 2018-10-23 23:08:05.766762254 +0200 -+++ openssh-7.9p1/monitor.h 2018-10-23 23:09:11.669055163 +0200 +--- openssh-7.9p1.orig/monitor.h 2019-02-27 08:08:38.969514995 +0100 ++++ openssh-7.9p1/monitor.h 2019-02-27 08:09:31.809944542 +0100 @@ -73,8 +73,10 @@ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, @@ -1750,8 +1667,8 @@ diff -Nur openssh-7.9p1.orig/monitor.h openssh-7.9p1/monitor.h struct monitor { diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c ---- openssh-7.9p1.orig/monitor_wrap.c 2018-10-23 23:08:05.783762072 +0200 -+++ openssh-7.9p1/monitor_wrap.c 2018-10-24 15:25:13.876838426 +0200 +--- openssh-7.9p1.orig/monitor_wrap.c 2019-02-27 08:08:39.015514499 +0100 ++++ openssh-7.9p1/monitor_wrap.c 2019-02-27 08:09:31.810944531 +0100 @@ -1067,6 +1067,94 @@ return (authenticated); } @@ -1858,8 +1775,8 @@ diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c fatal("%s: buffer error: %s", __func__, ssh_err(r)); diff -Nur openssh-7.9p1.orig/monitor_wrap.h openssh-7.9p1/monitor_wrap.h ---- openssh-7.9p1.orig/monitor_wrap.h 2018-10-23 23:08:05.771762201 +0200 -+++ openssh-7.9p1/monitor_wrap.h 2018-10-23 23:35:33.766952547 +0200 +--- openssh-7.9p1.orig/monitor_wrap.h 2019-02-27 08:08:38.984514834 +0100 ++++ openssh-7.9p1/monitor_wrap.h 2019-02-27 08:09:31.810944531 +0100 @@ -68,6 +68,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1872,9 +1789,9 @@ diff -Nur openssh-7.9p1.orig/monitor_wrap.h openssh-7.9p1/monitor_wrap.h #endif diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c ---- openssh-7.9p1.orig/readconf.c 2018-10-23 23:08:05.776762147 +0200 -+++ openssh-7.9p1/readconf.c 2018-10-23 23:09:11.671055142 +0200 -@@ -2039,13 +2039,13 @@ +--- openssh-7.9p1.orig/readconf.c 2019-02-27 08:08:39.002514639 +0100 ++++ openssh-7.9p1/readconf.c 2019-02-27 08:09:31.810944531 +0100 +@@ -2051,13 +2051,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1893,8 +1810,8 @@ diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h ---- openssh-7.9p1.orig/readconf.h 2018-10-23 23:08:05.717762780 +0200 -+++ openssh-7.9p1/readconf.h 2018-10-23 23:09:11.671055142 +0200 +--- openssh-7.9p1.orig/readconf.h 2019-02-27 08:08:38.927515449 +0100 ++++ openssh-7.9p1/readconf.h 2019-02-27 08:09:31.811944520 +0100 @@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1905,8 +1822,8 @@ diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c ---- openssh-7.9p1.orig/servconf.c 2018-10-23 23:08:05.784762061 +0200 -+++ openssh-7.9p1/servconf.c 2018-10-23 23:09:11.672055131 +0200 +--- openssh-7.9p1.orig/servconf.c 2019-02-27 08:08:39.017514477 +0100 ++++ openssh-7.9p1/servconf.c 2019-02-27 08:09:31.812944509 +0100 @@ -84,6 +84,7 @@ /* Portable-specific options */ @@ -1927,16 +1844,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -178,6 +181,8 @@ - options->chroot_directory = NULL; - options->authorized_keys_command = NULL; - options->authorized_keys_command_user = NULL; -+ options->disable_usage_stats = 1; -+ options->usage_stats_targets = NULL; - options->revoked_keys_file = NULL; - options->trusted_user_ca_keys = NULL; - options->authorized_principals_file = NULL; -@@ -273,6 +278,8 @@ +@@ -273,6 +276,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1945,7 +1853,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -350,13 +357,17 @@ +@@ -350,13 +355,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1965,7 +1873,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -491,7 +502,7 @@ +@@ -491,7 +500,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1974,7 +1882,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -513,10 +524,14 @@ +@@ -513,6 +522,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1984,12 +1892,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, -+ sDisUsageStats, sUsageStatsTarg, - sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, -@@ -542,8 +557,10 @@ +@@ -542,8 +554,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -2000,7 +1903,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -591,7 +608,14 @@ +@@ -591,7 +605,14 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -2015,7 +1918,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -599,7 +623,10 @@ +@@ -599,7 +620,10 @@ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -2026,16 +1929,16 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -670,6 +697,8 @@ +@@ -670,6 +694,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, -+ { "disableusagestats", sDisUsageStats, SSHCFG_GLOBAL}, -+ { "usagestatstargets", sUsageStatsTarg, SSHCFG_GLOBAL}, ++ { "disableusagestats", sUnsupported, SSHCFG_GLOBAL}, ++ { "usagestatstargets", sUnsupported, SSHCFG_GLOBAL}, { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1301,6 +1330,10 @@ +@@ -1301,6 +1327,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -2046,7 +1949,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1519,6 +1552,10 @@ +@@ -1519,6 +1549,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -2057,7 +1960,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1527,6 +1564,10 @@ +@@ -1527,6 +1561,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2068,7 +1971,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1547,6 +1588,12 @@ +@@ -1547,6 +1585,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2081,43 +1984,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2060,6 +2107,35 @@ - *charptr = xstrdup(arg); - break; - -+ case sDisUsageStats: -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: missing value.", -+ filename, linenum); -+ if (!strcasecmp(arg, "true") || -+ !strcasecmp(arg, "enabled") || -+ !strcasecmp(arg, "yes") || -+ !strcasecmp(arg, "on") || -+ !strcasecmp(arg, "1")) -+ options->disable_usage_stats = 1; -+ else if (!strcasecmp(arg, "false") || -+ !strcasecmp(arg, "disabled") || -+ !strcasecmp(arg, "no") || -+ !strcasecmp(arg, "off") || -+ !strcasecmp(arg, "0")) -+ options->disable_usage_stats = 0; -+ else -+ fatal("Incorrect value for disable_usage_stats"); -+ break; -+ -+ case sUsageStatsTarg: -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: missing value.", -+ filename, linenum); -+ options->usage_stats_targets = xstrdup(arg); -+ break; -+ - case sTrustedUserCAKeys: - charptr = &options->trusted_user_ca_keys; - goto parse_filename; -@@ -2354,6 +2430,7 @@ +@@ -2354,6 +2398,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2126,8 +1993,8 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); diff -Nur openssh-7.9p1.orig/servconf.h openssh-7.9p1/servconf.h ---- openssh-7.9p1.orig/servconf.h 2018-10-23 23:08:05.725762694 +0200 -+++ openssh-7.9p1/servconf.h 2018-10-23 23:09:11.673055120 +0200 +--- openssh-7.9p1.orig/servconf.h 2019-02-27 08:08:38.830516496 +0100 ++++ openssh-7.9p1/servconf.h 2019-02-27 08:09:31.812944509 +0100 @@ -130,9 +130,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2149,20 +2016,9 @@ diff -Nur openssh-7.9p1.orig/servconf.h openssh-7.9p1/servconf.h int permit_tun; -@@ -201,6 +205,10 @@ - u_int num_permitted_listens; - - char *chroot_directory; -+ -+ int disable_usage_stats; -+ char *usage_stats_targets; -+ - char *revoked_keys_file; - char *trusted_user_ca_keys; - char *authorized_keys_command; diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 ---- openssh-7.9p1.orig/ssh.1 2018-10-23 23:08:05.719762758 +0200 -+++ openssh-7.9p1/ssh.1 2018-10-23 23:09:11.674055109 +0200 +--- openssh-7.9p1.orig/ssh.1 2019-02-27 08:08:38.819516615 +0100 ++++ openssh-7.9p1/ssh.1 2019-02-27 08:09:31.812944509 +0100 @@ -1433,6 +1433,18 @@ on to new connections). .It Ev USER @@ -2183,9 +2039,9 @@ diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 .Pp Additionally, diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c ---- openssh-7.9p1.orig/ssh.c 2018-10-23 23:08:05.778762125 +0200 -+++ openssh-7.9p1/ssh.c 2018-10-23 23:09:11.674055109 +0200 -@@ -541,6 +541,38 @@ +--- openssh-7.9p1.orig/ssh.c 2019-02-27 08:08:39.004514618 +0100 ++++ openssh-7.9p1/ssh.c 2019-02-27 08:15:38.242004315 +0100 +@@ -543,6 +543,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2224,7 +2080,7 @@ diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1289,8 +1315,12 @@ +@@ -1298,8 +1330,12 @@ logit("FIPS mode initialized"); } @@ -2239,8 +2095,8 @@ diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) diff -Nur openssh-7.9p1.orig/ssh_config openssh-7.9p1/ssh_config ---- openssh-7.9p1.orig/ssh_config 2018-10-23 23:08:05.675763231 +0200 -+++ openssh-7.9p1/ssh_config 2018-10-23 23:09:11.675055099 +0200 +--- openssh-7.9p1.orig/ssh_config 2019-02-27 08:08:38.702517878 +0100 ++++ openssh-7.9p1/ssh_config 2019-02-27 08:09:31.813944499 +0100 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2257,8 +2113,8 @@ diff -Nur openssh-7.9p1.orig/ssh_config openssh-7.9p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 ---- openssh-7.9p1.orig/ssh_config.5 2018-10-23 23:08:05.750762426 +0200 -+++ openssh-7.9p1/ssh_config.5 2018-10-23 23:09:11.675055099 +0200 +--- openssh-7.9p1.orig/ssh_config.5 2019-02-27 08:08:38.933515384 +0100 ++++ openssh-7.9p1/ssh_config.5 2019-02-27 08:09:31.814944488 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2272,7 +2128,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -735,7 +741,7 @@ +@@ -753,7 +759,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2281,7 +2137,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -743,12 +749,12 @@ +@@ -761,12 +767,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2296,7 +2152,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -780,7 +786,7 @@ +@@ -798,7 +804,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2305,7 +2161,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1249,7 +1255,7 @@ +@@ -1267,7 +1273,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2315,8 +2171,8 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c ---- openssh-7.9p1.orig/sshconnect2.c 2018-10-23 23:08:05.778762125 +0200 -+++ openssh-7.9p1/sshconnect2.c 2018-10-23 23:09:11.676055088 +0200 +--- openssh-7.9p1.orig/sshconnect2.c 2019-02-27 08:08:39.005514607 +0100 ++++ openssh-7.9p1/sshconnect2.c 2019-02-27 08:09:31.815944477 +0100 @@ -894,6 +894,11 @@ int r, ok = 0; const char *gss_host = NULL; @@ -2387,9 +2243,9 @@ diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c packet_put_cstring(authctxt->method->name); packet_put_string(mic.value, mic.length); diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 ---- openssh-7.9p1.orig/sshd.8 2018-10-23 23:08:05.689763080 +0200 -+++ openssh-7.9p1/sshd.8 2018-10-23 23:09:11.677055077 +0200 -@@ -788,6 +788,44 @@ +--- openssh-7.9p1.orig/sshd.8 2019-02-27 08:08:38.739517478 +0100 ++++ openssh-7.9p1/sshd.8 2019-02-27 08:09:31.815944477 +0100 +@@ -788,6 +788,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2397,21 +2253,6 @@ diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 +.Nm +will normally set the following environment variables: +.Bl -tag -width "SSH_ORIGINAL_COMMAND" -+.It Ev GLOBUS_USAGE_OPTOUT -+Setting this environment variable to "1" will disable the reporting -+of usage metrics. Usage metrics can also be disabled using the -+.Cm DisableUsageStats -+setting in -+.Xr sshd_config 5 . -+.It Ev GLOBUS_USAGE_TARGETS -+If -+.Cm UsageStatsTargets -+is not specified in -+.Xr sshd_config 5 , -+a comma-separated list of targets (without any tags specified) if -+specified in the environment variable -+.Ev GLOBUS_USAGE_TARGETS -+will be used. +.It Ev GRIDMAP +Applies to GSI authentication/authorization. Specifies the location of the +gridmapfile. If not specified, the gridmap file is assumed to be available at @@ -2435,31 +2276,9 @@ diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-7.9p1.orig/sshd.c openssh-7.9p1/sshd.c ---- openssh-7.9p1.orig/sshd.c 2018-10-23 23:08:05.785762050 +0200 -+++ openssh-7.9p1/sshd.c 2018-10-23 23:09:11.677055077 +0200 -@@ -130,6 +130,7 @@ - #include "auth-options.h" - #include "version.h" - #include "ssherr.h" -+#include "ssh-globus-usage.h" - - /* Re-exec fds */ - #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -@@ -1797,6 +1798,13 @@ - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - -+#ifdef HAVE_GLOBUS_USAGE -+ if (ssh_usage_stats_init(options.disable_usage_stats, -+ options.usage_stats_targets) != GLOBUS_SUCCESS) { -+ error("Error initializing Globus Usage Metrics, but continuing ..."); -+ } -+#endif /* HAVE_GLOBUS_USAGE */ -+ - /* challenge-response is implemented via keyboard interactive */ - if (options.challenge_response_authentication) - options.kbd_interactive_authentication = 1; -@@ -2305,7 +2313,7 @@ +--- openssh-7.9p1.orig/sshd.c 2019-02-27 08:08:39.020514445 +0100 ++++ openssh-7.9p1/sshd.c 2019-02-27 08:09:31.815944477 +0100 +@@ -2305,7 +2305,7 @@ #endif #ifdef GSSAPI @@ -2469,8 +2288,8 @@ diff -Nur openssh-7.9p1.orig/sshd.c openssh-7.9p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-7.9p1.orig/sshd_config openssh-7.9p1/sshd_config ---- openssh-7.9p1.orig/sshd_config 2018-10-23 23:08:05.714762812 +0200 -+++ openssh-7.9p1/sshd_config 2018-10-23 23:09:11.678055066 +0200 +--- openssh-7.9p1.orig/sshd_config 2019-02-27 08:08:38.802516798 +0100 ++++ openssh-7.9p1/sshd_config 2019-02-27 08:09:31.816944466 +0100 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2496,37 +2315,10 @@ diff -Nur openssh-7.9p1.orig/sshd_config openssh-7.9p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -@@ -141,6 +146,10 @@ - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - -+# Usage Metrics -+#UsageStatsTargets usage-stats.example.edu:4810 -+#DisableUsageStats yes -+ - # Example of overriding settings on a per-user basis - #Match User anoncvs - # X11Forwarding no diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 ---- openssh-7.9p1.orig/sshd_config.5 2018-10-23 23:08:05.736762576 +0200 -+++ openssh-7.9p1/sshd_config.5 2018-10-23 23:09:11.678055066 +0200 -@@ -587,6 +587,15 @@ - TCP and StreamLocal. - This option overrides all other forwarding-related options and may - simplify restricted configurations. -+.It Cm DisableUsageStats -+This keyword can be followed by one of the keywords "true", "enabled", "yes", -+"on" or "1" to disable reporting of usage metrics. Or it can be set to "false", -+"disabled", "no", "off", "0" to enable reporting of usage metrics. Setting the -+.Cm GLOBUS_USAGE_OPTOUT -+environment variable to "1" will also disable the reporting of usage metrics. -+Disabling reporting of usage metrics will cause the -+.Cm UsageStatsTargets -+setting to be ignored. - .It Cm ExposeAuthInfo - Writes a temporary file containing a list of authentication methods and - public credentials (e.g. keys) used to authenticate the user. -@@ -644,15 +653,34 @@ +--- openssh-7.9p1.orig/sshd_config.5 2019-02-27 08:08:38.858516194 +0100 ++++ openssh-7.9p1/sshd_config.5 2019-02-27 08:09:31.816944466 +0100 +@@ -644,15 +644,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2562,7 +2354,7 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -663,7 +691,7 @@ +@@ -663,7 +682,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2571,7 +2363,7 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -702,7 +730,6 @@ +@@ -702,7 +721,6 @@ .Pp The default is .Dq gss-gex-sha1-,gss-group14-sha1- . @@ -2579,111 +2371,7 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a list of comma-separated patterns. -@@ -1640,6 +1667,103 @@ - .Cm TrustedUserCAKeys . - For more details on certificates, see the CERTIFICATES section in - .Xr ssh-keygen 1 . -+.It Cm UsageStatsTargets -+This option can be used to specify the target collector hosts to which usage -+metrics should be reported. This setting will be ignored if -+.Cm DisableUsageStats -+is enabled. Multiple targets can be specified separated by comma(s), but no -+space(s). Each target specification is of the format -+.Pa host:port[!tags]. -+Tags control what data elements are reported. The following list specifies -+the tags for the corresponding data elements. -+.Pp -+.Bl -item -offset indent -compact -+.It -+.Cm V -+.Sm off -+- OpenSSH version, reported by default. -+.Sm on -+.It -+.Cm v -+.Sm off -+- SSL version, reported by default. -+.Sm on -+.It -+.Cm M -+.Sm off -+- User authentication method used such as "gssapi-keyex", "gssapi-with-mic", etc. Reported by default. -+.Sm on -+.It -+.Cm m -+.Sm off -+- User authentication mechanism used such as "GSI", "Kerberos", etc. Reported by default. -+.Sm on -+.It -+.Cm I -+.Sm off -+- Client IP address. Not reported by default. -+.Sm on -+.It -+.Cm u -+.Sm off -+- User name. Not reported by default. -+.Sm on -+.It -+.Cm U -+.Sm off -+- User DN. Not reported by default. -+.Sm on -+.Pp -+In addition to the above selected information, the following data are -+reported to ALL the specified/default target collectors. There's no way to -+exclude these from being reported other than by disabling the reporting of -+usage metrics altogether: -+.Pp -+.It -+.Cm Component code -+.Sm off -+- 12 for GSI OpenSSH -+.Sm on -+.It -+.Cm Component Data Format version -+.Sm off -+- 0 currently -+.Sm on -+.It -+.Cm IP Address -+.Sm off -+- IP address of reporting server -+.Sm on -+.It -+.Cm Timestamp -+.It -+.Cm Hostname -+.Sm off -+- Host name of reporting server -+.Sm on -+.Pp -+If no tags are specified in a host spec, or the special string -+.Cm default -+is specified, the tags -+.Cm VvMm -+are assumed. A site could choose to allow a -+different set of data to be reported by specifying a different tag set. The -+last 3 tags -+.Cm I , -+.Cm u -+and -+.Cm U -+above are more meant for a local collector that a -+site might like to deploy since they could be construed as private information. -+The special string -+.Cm all -+denotes all tags. -+.El -+.Pp -+Usage Metrics reporting is disabled unless -+.Cm UsageStatsTargets -+is specified. -+.Pp - .It Cm UseDNS - Specifies whether - .Xr sshd 8 -@@ -1681,6 +1805,12 @@ +@@ -1681,6 +1699,12 @@ as a non-root user. The default is .Cm no . @@ -2696,461 +2384,9 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.9p1.orig/ssh-globus-usage.c openssh-7.9p1/ssh-globus-usage.c ---- openssh-7.9p1.orig/ssh-globus-usage.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.9p1/ssh-globus-usage.c 2018-10-23 23:09:11.679055056 +0200 -@@ -0,0 +1,396 @@ -+/* -+ * Copyright 2009 The Board of Trustees of the University -+ * of Illinois. See the LICENSE file for detailed license information. -+ * -+ * Portions, specifically log_usage_stats(), ssh_usage_stats_init(), -+ * ssh_usage_stats_close(), ssh_usage_ent_s, ssh_usage_tag_e and -+ * TAG #defines were based on those from Usage Metrics portions of: -+ * gridftp/server/source/globus_i_gfs_log.c -+ * -+ * Copyright 1999-2006 University of Chicago -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#include "includes.h" -+ -+#ifdef HAVE_GLOBUS_USAGE -+ -+#include -+#include -+ -+#include "log.h" -+#include "ssh-globus-usage.h" -+ -+static globus_list_t *usage_handle_list = NULL; -+ -+#define SSH_GLOBUS_USAGE_ID 12 -+#define SSH_GLOBUS_USAGE_VER 0 -+ -+#define SSH_GLOBUS_DEFAULT_TAGLIST "VvMm" -+#define SSH_GLOBUS_ALL_TAGLIST "VvMmIuU" -+#define SSH_GLOBUS_TAGCOUNT 25 -+ -+typedef enum ssh_usage_tag_e -+{ -+ SSH_GLOBUS_USAGE_SSH_VER = 'V', -+ SSH_GLOBUS_USAGE_SSL_VER = 'v', -+ SSH_GLOBUS_USAGE_METHOD = 'M', -+ SSH_GLOBUS_USAGE_MECHANISM = 'm', -+ SSH_GLOBUS_USAGE_CLIENTIP = 'I', -+ SSH_GLOBUS_USAGE_USERNAME = 'u', -+ SSH_GLOBUS_USAGE_USERDN = 'U' -+ /* !! ADD to ALL_TAGLIST above and to globus_usage_stats_send() -+ invocation below when adding here */ -+} ssh_usage_tag_t; -+ -+typedef struct ssh_usage_ent_s -+{ -+ globus_usage_stats_handle_t handle; -+ char * target; -+ char * taglist; -+} ssh_usage_ent_t; -+ -+ -+globus_result_t -+ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets) -+{ -+ globus_result_t result; -+ char * target_str = NULL; -+ char * ptr = ptr; -+ char * target = NULL; -+ char * entry = NULL; -+ globus_list_t * list = NULL; -+ ssh_usage_ent_t * usage_ent = NULL; -+ -+ if (disable_usage_stats || !usage_stats_targets) -+ return GLOBUS_SUCCESS; -+ -+ result = globus_module_activate(GLOBUS_USAGE_MODULE); -+ if (result != GLOBUS_SUCCESS) -+ { -+ error("ERROR: couldn't activate USAGE STATS module"); -+ return result; -+ } -+ -+ target_str = strdup(usage_stats_targets); -+ if (target_str == NULL) -+ { -+ error("ERROR: strdup failure for target_str"); -+ goto error; -+ } -+ debug("Processing usage_stats_target (%s)\n", target_str); -+ -+ if(target_str && (strchr(target_str, ',') || strchr(target_str, '!'))) -+ { -+ target = target_str; -+ -+ do { -+ usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t)); -+ if (usage_ent == NULL) -+ { -+ error("ERROR: couldn't allocate for ssh_usage_ent_t"); -+ goto error; -+ } -+ -+ if ((ptr = strchr(target, ',')) != NULL) -+ *ptr = '\0'; -+ -+ entry = strdup(target); -+ if (entry == NULL) -+ { -+ error("ERROR: strdup failure for target"); -+ goto error; -+ } -+ -+ if (ptr) -+ target = ptr + 1; -+ else -+ target = NULL; -+ -+ if((ptr = strchr(entry, '!')) != NULL) -+ { -+ *ptr = '\0'; -+ usage_ent->taglist = strdup(ptr + 1); -+ if (usage_ent->taglist == NULL) -+ { -+ error("ERROR: strdup failure for taglist"); -+ goto error; -+ } -+ if(strlen(usage_ent->taglist) > SSH_GLOBUS_TAGCOUNT) -+ { -+ usage_ent->taglist[SSH_GLOBUS_TAGCOUNT + 1] = '\0'; -+ } -+ } -+ else -+ { -+ usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); -+ if (usage_ent->taglist == NULL) -+ { -+ error("ERROR: couldn't allocate for taglist"); -+ goto error; -+ } -+ } -+ -+ if(strcasecmp(usage_ent->taglist, "default") == 0) -+ { -+ free(usage_ent->taglist); -+ usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); -+ if (usage_ent->taglist == NULL) -+ { -+ error("ERROR: couldn't allocate for taglist"); -+ goto error; -+ } -+ } -+ else if(strcasecmp(usage_ent->taglist, "all") == 0) -+ { -+ free(usage_ent->taglist); -+ usage_ent->taglist = strdup(SSH_GLOBUS_ALL_TAGLIST); -+ if (usage_ent->taglist == NULL) -+ { -+ error("ERROR: couldn't allocate for taglist"); -+ goto error; -+ } -+ } -+ -+ usage_ent->target = entry; -+ -+ globus_list_insert(&usage_handle_list, usage_ent); -+ } -+ while(target != NULL); -+ -+ free(target_str); -+ } -+ else -+ { -+ usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t)); -+ if (usage_ent == NULL) -+ { -+ error("ERROR: couldn't allocate for usage_ent"); -+ goto error; -+ } -+ -+ usage_ent->target = target_str; -+ usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); -+ if (usage_ent->taglist == NULL) -+ { -+ error("ERROR: couldn't allocate for taglist"); -+ goto error; -+ } -+ -+ globus_list_insert(&usage_handle_list, usage_ent); -+ } -+ -+ result = GLOBUS_SUCCESS; -+ for(list = usage_handle_list; -+ !globus_list_empty(list); -+ list = globus_list_rest(list)) -+ { -+ usage_ent = (ssh_usage_ent_t *) globus_list_first(list); -+ -+ usage_ent->handle = NULL; -+ if (globus_usage_stats_handle_init( -+ &usage_ent->handle, -+ SSH_GLOBUS_USAGE_ID, -+ SSH_GLOBUS_USAGE_VER, -+ usage_ent->target) != GLOBUS_SUCCESS) -+ { -+ error("USAGE-STATS: Error initializing (%s) (%s)", -+ usage_ent->target?:"NULL", -+ usage_ent->taglist?:"NULL"); -+ result = GLOBUS_FAILURE; -+ } else -+ debug("USAGE-STATS: Initialized (%s) (%s)", usage_ent->target?:"NULL", -+ usage_ent->taglist?:"NULL"); -+ -+ } -+ -+ return result; -+ -+error: -+ if (target_str) -+ { -+ free(target_str); -+ target_str = NULL; -+ } -+ if (entry) -+ { -+ free(target_str); -+ target_str = NULL; -+ } -+ return GLOBUS_FAILURE; -+} -+ -+void -+ssh_usage_stats_close(int disable_usage_stats) -+{ -+ globus_list_t *list; -+ -+ if (disable_usage_stats) -+ return; -+ -+ list = usage_handle_list; -+ -+ while(!globus_list_empty(list)) -+ { -+ ssh_usage_ent_t *usage_ent; -+ -+ usage_ent = (ssh_usage_ent_t *) -+ globus_list_remove(&list, list); -+ -+ if(usage_ent) -+ { -+ if(usage_ent->handle) -+ { -+ globus_usage_stats_handle_destroy(usage_ent->handle); -+ } -+ if(usage_ent->target) -+ { -+ free(usage_ent->target); -+ } -+ if(usage_ent->taglist) -+ { -+ free(usage_ent->taglist); -+ } -+ free(usage_ent); -+ } -+ } -+ usage_handle_list = NULL; -+} -+ -+static void -+log_usage_stats(const char *ssh_release, const char *ssl_release, -+ const char *method, const char *mechanism, -+ const char *clientip, -+ const char *username, const char *userdn) -+{ -+ globus_result_t result; -+ globus_list_t * list; -+ ssh_usage_ent_t * usage_ent; -+ char * keys[SSH_GLOBUS_TAGCOUNT]; -+ char * values[SSH_GLOBUS_TAGCOUNT]; -+ char * ptr; -+ char * key; -+ char * value; -+ int i = 0; -+ char * save_taglist = NULL; -+ -+ for(list = usage_handle_list; -+ !globus_list_empty(list); -+ list = globus_list_rest(list)) -+ { -+ usage_ent = (ssh_usage_ent_t *) globus_list_first(list); -+ -+ if(!usage_ent || usage_ent->handle == NULL) -+ continue; -+ -+ if(save_taglist == NULL || -+ strcmp(save_taglist, usage_ent->taglist) != 0) -+ { -+ save_taglist = usage_ent->taglist; -+ -+ ptr = usage_ent->taglist; -+ i = 0; -+ while(ptr && *ptr) -+ { -+ switch(*ptr) -+ { -+ case SSH_GLOBUS_USAGE_SSH_VER: -+ key = "SSH_VER"; -+ value = (char *) ssh_release; -+ break; -+ -+ case SSH_GLOBUS_USAGE_SSL_VER: -+ key = "SSL_VER"; -+ value = (char *) ssl_release; -+ break; -+ -+ case SSH_GLOBUS_USAGE_METHOD: -+ key = "METHOD"; -+ value = (char *) method; -+ break; -+ -+ case SSH_GLOBUS_USAGE_MECHANISM: -+ key = "MECH"; -+ value = (char *) mechanism?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_CLIENTIP: -+ key = "CLIENTIP"; -+ value = (char *) clientip?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_USERNAME: -+ key = "USER"; -+ value = (char *) username?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_USERDN: -+ key = "USERDN"; -+ value = (char *) userdn?:""; -+ break; -+ -+ default: -+ key = NULL; -+ value = NULL; -+ break; -+ } -+ -+ if(key != NULL && value != NULL) -+ { -+ keys[i] = key; -+ values[i] = value; -+ i++; -+ } -+ -+ ptr++; -+ } -+ } -+ -+#ifdef HAVE_GLOBUS_USAGE_SEND_ARRAY -+ result = globus_usage_stats_send_array( -+ usage_ent->handle, i, keys, values); -+#else -+ if (i) -+ result = globus_usage_stats_send( -+ usage_ent->handle, i, -+ i>0?keys[0]:NULL, i>0?values[0]:NULL, -+ i>1?keys[1]:NULL, i>1?values[1]:NULL, -+ i>2?keys[2]:NULL, i>2?values[2]:NULL, -+ i>3?keys[3]:NULL, i>3?values[3]:NULL, -+ i>4?keys[4]:NULL, i>4?values[4]:NULL, -+ i>5?keys[5]:NULL, i>5?values[5]:NULL, -+ i>6?keys[6]:NULL, i>6?values[6]:NULL); -+#endif /* HAVE_GLOBUS_USAGE_SEND_ARRAY */ -+ } -+ -+ return; -+} -+#endif /* HAVE_GLOBUS_USAGE */ -+ -+void -+ssh_globus_send_usage_metrics(const char *ssh_release, -+ const char *ssl_release, -+ const char *method, -+ const char *mechanism, -+ const char *client_ip, -+ const char *username, -+ const char *userdn) -+{ -+#ifdef HAVE_GLOBUS_USAGE -+ -+ log_usage_stats(ssh_release, ssl_release, method, mechanism, -+ client_ip, username, userdn); -+ -+#endif /* HAVE_GLOBUS_USAGE */ -+} -diff -Nur openssh-7.9p1.orig/ssh-globus-usage.h openssh-7.9p1/ssh-globus-usage.h ---- openssh-7.9p1.orig/ssh-globus-usage.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.9p1/ssh-globus-usage.h 2018-10-23 23:09:11.679055056 +0200 -@@ -0,0 +1,48 @@ -+/* -+ * Copyright 2009 The Board of Trustees of the University -+ * of Illinois. See the LICENSE file for detailed license information. -+ * -+ * Portions, specifically ssh_usage_stats_init(), ssh_usage_stats_close() -+ * were based on those from: gridftp/server/source/globus_i_gfs_log.h -+ * Copyright 1999-2006 University of Chicago -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef __SSH_GLOBUS_USAGE_H -+#define __SSH_GLOBUS_USAGE_H -+ -+#include "includes.h" -+ -+#ifdef HAVE_GLOBUS_USAGE -+ -+#include "globus_usage.h" -+ -+globus_result_t -+ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets); -+ -+void -+ssh_usage_stats_close(int disable_usage_stats); -+ -+#endif /* HAVE_GLOBUS_USAGE */ -+ -+void -+ssh_globus_send_usage_metrics(const char *ssh_release, -+ const char *ssl_release, -+ const char *method, -+ const char *mechanism, -+ const char *client_ip, -+ const char *username, -+ const char *userdn); -+ -+#endif /* __SSH_GLOBUS_USAGE_H */ diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h ---- openssh-7.9p1.orig/ssh-gss.h 2018-10-23 23:08:05.759762329 +0200 -+++ openssh-7.9p1/ssh-gss.h 2018-10-23 23:09:11.679055056 +0200 +--- openssh-7.9p1.orig/ssh-gss.h 2019-02-27 08:08:38.917515557 +0100 ++++ openssh-7.9p1/ssh-gss.h 2019-02-27 08:09:31.816944466 +0100 @@ -85,6 +85,7 @@ KEX_GSS_GRP14_SHA1_ID @@ -3194,17 +2430,9 @@ diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -@@ -178,6 +184,7 @@ - int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); - - void ssh_gssapi_rekey_creds(void); -+void ssh_gssapi_get_client_info(char **userdn, char **mech); - #endif /* GSSAPI */ - - #endif /* _SSH_GSS_H */ diff -Nur openssh-7.9p1.orig/version.h openssh-7.9p1/version.h --- openssh-7.9p1.orig/version.h 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/version.h 2018-10-23 23:09:11.680055045 +0200 ++++ openssh-7.9p1/version.h 2019-02-27 08:09:31.816944466 +0100 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_7.9" From f25f21397449fb93e8d9a532048a07869184a48a Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 22 Mar 2019 11:28:50 +0100 Subject: [PATCH 071/146] Based on openssh-7.9p1-5.fc29 --- gsi-openssh.spec | 8 +- openssh-6.6.1p1-selinux-contexts.patch | 88 +++++---- openssh-6.6p1-privsep-selinux.patch | 6 +- openssh-7.1p2-audit-race-condition.patch | 4 +- openssh-7.6p1-audit.patch | 2 +- openssh-7.6p1-pkcs11-ecdsa.patch | 17 +- openssh-7.6p1-pkcs11-uri.patch | 15 +- openssh-7.7p1-fips.patch | 234 +++++++++++++++-------- openssh-7.7p1-gssapi-new-unique.patch | 112 +++++------ openssh-7.8p1-gsskex.patch | 2 +- openssh-7.9p1-gsissh.patch | 6 +- openssh-7.9p1-updated-cached-pw.patch | 23 +++ 12 files changed, 329 insertions(+), 188 deletions(-) create mode 100644 openssh-7.9p1-updated-cached-pw.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e75071b..7d86075 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 7.9p1 -%global openssh_rel 6 +%global openssh_rel 7 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -182,6 +182,8 @@ Patch958: openssh-7.9p1-ssh-copy-id.patch # log when a client requests an interactive session and only sftp is allowed # https://bugzilla.mindrot.org/show_bug.cgi?id=2960 Patch959: openssh-7.9p1-log-sftp-only-connections.patch +# Update cached passwd structure after PAM authentication (#1674541) +Patch960: openssh-7.9p1-updated-cached-pw.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -343,6 +345,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch957 -p1 -b .CVE-2018-20685 %patch958 -p1 -b .ssh-copy-id %patch959 -p1 -b .log-sftp-only +%patch960 -p1 -b .update-pw %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -555,6 +558,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Mar 22 2019 Mattias Ellert - 7.9p1-7 +- Based on openssh-7.9p1-5.fc29 + * Wed Feb 27 2019 Mattias Ellert - 7.9p1-6 - Remove usage statistics collection support diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index f26f343..3a7193e 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -19,7 +19,7 @@ index 8f32464..18a2ca4 100644 if (!sshd_selinux_enabled()) return; -@@ -461,6 +462,58 @@ sshd_selinux_copy_context(void) +@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void) } } @@ -30,46 +30,60 @@ index 8f32464..18a2ca4 100644 + char line[1024], *preauth_context = NULL, *cp, *arg; + const char *contexts_path; + FILE *contexts_file; ++ struct stat sb; + + contexts_path = selinux_openssh_contexts_path(); -+ if (contexts_path != NULL) { -+ if ((contexts_file = fopen(contexts_path, "r")) != NULL) { -+ struct stat sb; -+ -+ if (fstat(fileno(contexts_file), &sb) == 0 && ((sb.st_uid == 0) && ((sb.st_mode & 022) == 0))) { -+ while (fgets(line, sizeof(line), contexts_file)) { -+ /* Strip trailing whitespace */ -+ for (len = strlen(line) - 1; len > 0; len--) { -+ if (strchr(" \t\r\n", line[len]) == NULL) -+ break; -+ line[len] = '\0'; -+ } -+ -+ if (line[0] == '\0') -+ continue; -+ -+ cp = line; -+ arg = strdelim(&cp); -+ if (arg && *arg == '\0') -+ arg = strdelim(&cp); -+ -+ if (arg && strcmp(arg, "privsep_preauth") == 0) { -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') { -+ debug("%s: privsep_preauth is empty", __func__); -+ fclose(contexts_file); -+ return; -+ } -+ preauth_context = xstrdup(arg); -+ } -+ } -+ } -+ fclose(contexts_file); -+ } ++ if (contexts_path == NULL) { ++ debug3("%s: Failed to get the path to SELinux context", __func__); ++ return; + } + -+ if (preauth_context == NULL) -+ preauth_context = xstrdup("sshd_net_t"); ++ if ((contexts_file = fopen(contexts_path, "r")) == NULL) { ++ 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("%s: SELinux context file needs to be owned by root" ++ " and not writable by anyone else", __func__); ++ fclose(contexts_file); ++ return; ++ } ++ ++ while (fgets(line, sizeof(line), contexts_file)) { ++ /* Strip trailing whitespace */ ++ for (len = strlen(line) - 1; len > 0; len--) { ++ if (strchr(" \t\r\n", line[len]) == NULL) ++ break; ++ line[len] = '\0'; ++ } ++ ++ if (line[0] == '\0') ++ continue; ++ ++ cp = line; ++ arg = strdelim(&cp); ++ if (arg && *arg == '\0') ++ arg = strdelim(&cp); ++ ++ if (arg && strcmp(arg, "privsep_preauth") == 0) { ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') { ++ debug("%s: privsep_preauth is empty", __func__); ++ fclose(contexts_file); ++ return; ++ } ++ preauth_context = xstrdup(arg); ++ } ++ } ++ fclose(contexts_file); ++ ++ if (preauth_context == NULL) { ++ debug("%s: Unable to find 'privsep_preauth' option in" ++ " SELinux context file", __func__); ++ return; ++ } + + ssh_selinux_change_context(preauth_context); + free(preauth_context); diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 1365506..3d4c287 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- + return; + + if (getexeccon((security_context_t *)&ctx) != 0) { -+ logit("%s: getcon failed with %s", __func__, strerror (errno)); ++ 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)); ++ fatal("%s: setexeccon failed with %s", __func__, strerror(errno)); + if (setcon(ctx) != 0) -+ fatal("%s: setcon failed with %s", __func__, strerror (errno)); ++ fatal("%s: setcon failed with %s", __func__, strerror(errno)); + freecon(ctx); + } +} diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 9a0d917..c4536ff 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -172,8 +172,8 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group @@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command - struct passwd *pw = s->pw; - int r = 0; + pw = s->pw; + } - /* remove hostkey from the child's memory */ - destroy_sensitive_data(1); diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 299d632..feb170f 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1806,7 +1806,7 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); @@ -1499,8 +1511,11 @@ do_child(struct ssh *ssh, Session *s, co - int r = 0; + } /* remove hostkey from the child's memory */ - destroy_sensitive_data(); diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch index d356a90..68fe97b 100644 --- a/openssh-7.6p1-pkcs11-ecdsa.patch +++ b/openssh-7.6p1-pkcs11-ecdsa.patch @@ -466,7 +466,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c { CKA_ID, NULL, 0 }, { CKA_LABEL, NULL, 0 } }; -@@ -569,29 +772,60 @@ pkcs11_fetch_keys(struct pkcs11_provider +@@ -569,37 +772,72 @@ pkcs11_fetch_keys(struct pkcs11_provider { CKA_SUBJECT, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; @@ -532,7 +532,20 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c + pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1, cert_attribs, keysp, nkeys) < 0) return (-1); - return (0); + if (*nkeys == 0) { + /* Try once more without the label filter */ + filter_size--; + if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, + pubkey_attribs, keysp, nkeys) < 0 || +- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, ++#ifdef ENABLE_PKCS11_ECDSA ++ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size, ++ ecdsa_attribs, keysp, nkeys) < 0|| ++#endif /* ENABLE_PKCS11_ECDSA */ ++ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1, + cert_attribs, keysp, nkeys) < 0) + return (-1); + } @@ -624,8 +858,13 @@ pkcs11_fetch_keys_filter(struct pkcs11_p CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], struct sshkey ***keysp, int *nkeys) diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch index 3343730..708f016 100644 --- a/openssh-7.6p1-pkcs11-uri.patch +++ b/openssh-7.6p1-pkcs11-uri.patch @@ -3785,7 +3785,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c return (0); } -@@ -404,38 +537,62 @@ pkcs11_open_session(struct pkcs11_provid +@@ -404,39 +537,72 @@ pkcs11_open_session(struct pkcs11_provid * keysp points to an (possibly empty) array with *nkeys keys. */ static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, @@ -3854,8 +3854,18 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c + pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, + cert_attribs, keysp, nkeys) < 0) return (-1); ++ if (*nkeys == 0) { ++ /* Try once more without the label filter */ ++ filter_size--; ++ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, ++ pubkey_attribs, keysp, nkeys) < 0 || ++ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, ++ cert_attribs, keysp, nkeys) < 0) ++ return (-1); ++ } return (0); } + @@ -462,14 +619,15 @@ have_rsa_key(const RSA *rsa) static int @@ -3989,7 +3999,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c free(attribs[i].pValue); } if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) -@@ -592,126 +750,239 @@ pkcs11_fetch_keys_filter(struct pkcs11_p +@@ -592,126 +750,240 @@ pkcs11_fetch_keys_filter(struct pkcs11_p int pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { @@ -4276,6 +4286,7 @@ diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c - free(p->slotlist); - free(p->slotinfo); - free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_unref(p); } - if (handle) diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 6450b5f..89867b1 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c ---- openssh-7.7p1/cipher.c.fips 2018-08-08 10:08:40.814719906 +0200 -+++ openssh-7.7p1/cipher.c 2018-08-08 10:08:40.821719965 +0200 +diff -up openssh-7.9p1/cipher.c.fips openssh-7.9p1/cipher.c +--- openssh-7.9p1/cipher.c.fips 2019-03-11 17:06:37.614877975 +0100 ++++ openssh-7.9p1/cipher.c 2019-03-11 17:06:37.620878031 +0100 @@ -39,6 +39,8 @@ #include @@ -10,7 +10,7 @@ diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c #include #include #include -@@ -90,6 +92,33 @@ static const struct sshcipher ciphers[] +@@ -92,6 +94,33 @@ static const struct sshcipher ciphers[] { NULL, 0, 0, 0, 0, 0, NULL } }; @@ -44,7 +44,7 @@ diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c /*--*/ /* Returns a comma-separated list of supported ciphers. */ -@@ -100,7 +129,7 @@ cipher_alg_list(char sep, int auth_only) +@@ -102,7 +131,7 @@ cipher_alg_list(char sep, int auth_only) size_t nlen, rlen = 0; const struct sshcipher *c; @@ -53,7 +53,7 @@ diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) -@@ -172,7 +201,7 @@ const struct sshcipher * +@@ -174,7 +203,7 @@ const struct sshcipher * cipher_by_name(const char *name) { const struct sshcipher *c; @@ -62,9 +62,9 @@ diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c if (strcmp(c->name, name) == 0) return c; return NULL; -diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c ---- openssh-7.7p1/cipher-ctr.c.fips 2018-08-08 10:08:40.709719021 +0200 -+++ openssh-7.7p1/cipher-ctr.c 2018-08-08 10:08:40.821719965 +0200 +diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c +--- openssh-7.9p1/cipher-ctr.c.fips 2019-03-11 17:06:37.519877082 +0100 ++++ openssh-7.9p1/cipher-ctr.c 2019-03-11 17:06:37.620878031 +0100 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -75,10 +75,10 @@ diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c ---- openssh-7.7p1/clientloop.c.fips 2018-08-08 10:08:40.769719527 +0200 -+++ openssh-7.7p1/clientloop.c 2018-08-08 10:08:40.822719973 +0200 -@@ -1978,7 +1978,8 @@ key_accepted_by_hostkeyalgs(const struct +diff -up openssh-7.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c +--- openssh-7.9p1/clientloop.c.fips 2019-03-11 17:06:37.523877120 +0100 ++++ openssh-7.9p1/clientloop.c 2019-03-11 17:06:37.620878031 +0100 +@@ -2014,7 +2014,8 @@ key_accepted_by_hostkeyalgs(const struct { const char *ktype = sshkey_ssh_name(key); const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? @@ -88,10 +88,73 @@ diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c if (key == NULL || key->type == KEY_UNSPEC) return 0; -diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h ---- openssh-7.7p1/dh.h.fips 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/dh.h 2018-08-08 10:08:40.822719973 +0200 -@@ -51,6 +51,7 @@ u_int dh_estimate(int); +diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c +--- openssh-7.9p1/dh.c.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/dh.c 2019-03-11 17:08:11.769763057 +0100 +@@ -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-7.9p1/dh.h.fips openssh-7.9p1/dh.h +--- openssh-7.9p1/dh.h.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/dh.h 2019-03-11 17:08:18.718828381 +0100 +@@ -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); + +@@ -51,6 +52,7 @@ u_int dh_estimate(int); * Miniumum increased in light of DH precomputation attacks. */ #define DH_GRP_MIN 2048 @@ -99,10 +162,10 @@ diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h #define DH_GRP_MAX 8192 /* -diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c ---- openssh-7.7p1/entropy.c.fips 2018-08-08 10:08:40.698718928 +0200 -+++ openssh-7.7p1/entropy.c 2018-08-08 10:08:40.822719973 +0200 -@@ -217,6 +217,11 @@ seed_rng(void) +diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c +--- openssh-7.9p1/entropy.c.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/entropy.c 2019-03-11 17:06:37.621878041 +0100 +@@ -223,6 +223,11 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -114,9 +177,9 @@ diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); -diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c ---- openssh-7.7p1/kex.c.fips 2018-08-08 10:08:40.815719915 +0200 -+++ openssh-7.7p1/kex.c 2018-08-08 10:11:24.109081924 +0200 +diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c +--- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100 ++++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL #include @@ -182,9 +245,9 @@ diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c free(s); return 0; } -diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c ---- openssh-7.7p1/kexgexc.c.fips 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/kexgexc.c 2018-08-08 10:08:40.822719973 +0200 +diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c +--- openssh-7.9p1/kexgexc.c.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/kexgexc.c 2019-03-11 17:06:37.621878041 +0100 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -193,7 +256,7 @@ diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c #include #include -@@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh) +@@ -65,7 +66,7 @@ kexgex_client(struct ssh *ssh) nbits = dh_estimate(kex->dh_need * 8); @@ -202,10 +265,21 @@ diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) -diff -up openssh-7.7p1/kexgexs.c.fips openssh-7.7p1/kexgexs.c ---- openssh-7.7p1/kexgexs.c.fips 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/kexgexs.c 2018-08-08 10:08:40.823719982 +0200 -@@ -82,9 +82,9 @@ input_kex_dh_gex_request(int type, u_int +@@ -118,6 +119,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-7.9p1/kexgexs.c.fips openssh-7.9p1/kexgexs.c +--- openssh-7.9p1/kexgexs.c.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/kexgexs.c 2019-03-11 17:06:37.621878041 +0100 +@@ -85,9 +85,9 @@ input_kex_dh_gex_request(int type, u_int kex->nbits = nbits; kex->min = min; kex->max = max; @@ -217,9 +291,9 @@ diff -up openssh-7.7p1/kexgexs.c.fips openssh-7.7p1/kexgexs.c nbits = MINIMUM(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || -diff -up openssh-7.7p1/mac.c.fips openssh-7.7p1/mac.c ---- openssh-7.7p1/mac.c.fips 2018-08-08 10:08:40.815719915 +0200 -+++ openssh-7.7p1/mac.c 2018-08-08 10:11:56.915352642 +0200 +diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c +--- openssh-7.9p1/mac.c.fips 2019-03-11 17:06:37.614877975 +0100 ++++ openssh-7.9p1/mac.c 2019-03-11 17:06:37.621878041 +0100 @@ -27,6 +27,8 @@ #include @@ -281,9 +355,9 @@ diff -up openssh-7.7p1/mac.c.fips openssh-7.7p1/mac.c if (strcmp(name, m->name) != 0) continue; if (mac != NULL) -diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in ---- openssh-7.7p1/Makefile.in.fips 2018-08-08 10:08:40.815719915 +0200 -+++ openssh-7.7p1/Makefile.in 2018-08-08 10:08:40.823719982 +0200 +diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in +--- openssh-7.9p1/Makefile.in.fips 2019-03-11 17:06:37.615877984 +0100 ++++ openssh-7.9p1/Makefile.in 2019-03-11 17:06:37.621878041 +0100 @@ -179,25 +179,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -325,10 +399,10 @@ diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h ---- openssh-7.7p1/myproposal.h.fips 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/myproposal.h 2018-08-08 10:08:40.823719982 +0200 -@@ -114,6 +114,14 @@ +diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h +--- openssh-7.9p1/myproposal.h.fips 2018-10-17 02:01:20.000000000 +0200 ++++ openssh-7.9p1/myproposal.h 2019-03-11 17:06:37.621878041 +0100 +@@ -116,6 +116,14 @@ "rsa-sha2-256," \ "ssh-rsa" @@ -343,7 +417,7 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h /* the actual algorithms */ #define KEX_SERVER_ENCRYPT \ -@@ -137,6 +145,38 @@ +@@ -139,6 +147,38 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -382,10 +456,10 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ "ecdsa-sha2-nistp256," \ -diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c ---- openssh-7.7p1/readconf.c.fips 2018-08-08 10:08:40.769719527 +0200 -+++ openssh-7.7p1/readconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -2081,18 +2081,19 @@ fill_default_options(Options * options) +diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c +--- openssh-7.9p1/readconf.c.fips 2019-03-11 17:06:37.601877853 +0100 ++++ openssh-7.9p1/readconf.c 2019-03-11 17:06:37.622878050 +0100 +@@ -2178,18 +2178,19 @@ fill_default_options(Options * options) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -413,9 +487,9 @@ diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c #undef ASSEMBLE free(all_cipher); free(all_mac); -diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-seccomp-filter.c ---- openssh-7.7p1/sandbox-seccomp-filter.c.fips 2018-08-08 10:08:40.794719737 +0200 -+++ openssh-7.7p1/sandbox-seccomp-filter.c 2018-08-08 10:08:40.824719990 +0200 +diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-seccomp-filter.c +--- openssh-7.9p1/sandbox-seccomp-filter.c.fips 2019-03-11 17:06:37.586877712 +0100 ++++ openssh-7.9p1/sandbox-seccomp-filter.c 2019-03-11 17:06:37.622878050 +0100 @@ -137,6 +137,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), @@ -426,10 +500,10 @@ diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c ---- openssh-7.7p1/servconf.c.fips 2018-08-08 10:08:40.778719603 +0200 -+++ openssh-7.7p1/servconf.c 2018-08-08 10:08:40.824719990 +0200 -@@ -196,18 +196,19 @@ option_clear_or_none(const char *o) +diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c +--- openssh-7.9p1/servconf.c.fips 2019-03-11 17:06:37.568877543 +0100 ++++ openssh-7.9p1/servconf.c 2019-03-11 17:06:37.622878050 +0100 +@@ -209,18 +209,19 @@ assemble_algorithms(ServerOptions *o) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -458,9 +532,9 @@ diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c #undef ASSEMBLE free(all_cipher); free(all_mac); -diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c ---- openssh-7.7p1/ssh.c.fips 2018-08-08 10:08:40.811719881 +0200 -+++ openssh-7.7p1/ssh.c 2018-08-08 10:08:40.825719999 +0200 +diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c +--- openssh-7.9p1/ssh.c.fips 2019-03-11 17:06:37.602877862 +0100 ++++ openssh-7.9p1/ssh.c 2019-03-11 17:06:37.623878060 +0100 @@ -76,6 +76,8 @@ #include #include @@ -470,7 +544,7 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -579,6 +581,16 @@ main(int ac, char **av) +@@ -600,6 +602,16 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -487,7 +561,7 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -1045,7 +1055,6 @@ main(int ac, char **av) +@@ -1047,7 +1059,6 @@ main(int ac, char **av) host_arg = xstrdup(host); #ifdef WITH_OPENSSL @@ -495,7 +569,7 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c ERR_load_crypto_strings(); #endif -@@ -1268,6 +1277,10 @@ main(int ac, char **av) +@@ -1283,6 +1294,10 @@ main(int ac, char **av) seed_rng(); @@ -506,9 +580,9 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c ---- openssh-7.7p1/sshconnect2.c.fips 2018-08-08 10:08:40.786719670 +0200 -+++ openssh-7.7p1/sshconnect2.c 2018-08-08 10:08:40.825719999 +0200 +diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c +--- openssh-7.9p1/sshconnect2.c.fips 2019-03-11 17:06:37.580877655 +0100 ++++ openssh-7.9p1/sshconnect2.c 2019-03-11 17:06:37.623878060 +0100 @@ -44,6 +44,8 @@ #include #endif @@ -574,10 +648,10 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c } } #endif -@@ -322,14 +330,16 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -326,14 +334,16 @@ ssh_kex2(char *host, struct sockaddr *ho if (options.hostkeyalgorithms != NULL) { all_key = sshkey_alg_list(0, 0, 1, ','); - if (kex_assemble_names(&options.hostkeyalgorithms, + if (kex_assemble_names(&options.hostkeyalgorithms, - KEX_DEFAULT_PK_ALG, all_key) != 0) + (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), + all_key) != 0) @@ -593,9 +667,9 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( -diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c ---- openssh-7.7p1/sshd.c.fips 2018-08-08 10:08:40.818719940 +0200 -+++ openssh-7.7p1/sshd.c 2018-08-08 10:08:40.826720007 +0200 +diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c +--- openssh-7.9p1/sshd.c.fips 2019-03-11 17:06:37.617878003 +0100 ++++ openssh-7.9p1/sshd.c 2019-03-11 17:06:37.624878069 +0100 @@ -66,6 +66,7 @@ #include #include @@ -613,7 +687,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1534,6 +1537,18 @@ main(int ac, char **av) +@@ -1581,6 +1584,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -632,7 +706,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1675,7 +1690,7 @@ main(int ac, char **av) +@@ -1722,7 +1737,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); @@ -641,7 +715,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c OpenSSL_add_all_algorithms(); #endif -@@ -1979,6 +1994,10 @@ main(int ac, char **av) +@@ -2036,6 +2051,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); @@ -652,7 +726,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2359,10 +2378,14 @@ do_ssh2_kex(void) +@@ -2412,10 +2431,14 @@ do_ssh2_kex(void) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -671,9 +745,9 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c ---- openssh-7.7p1/sshkey.c.fips 2018-08-08 10:08:40.818719940 +0200 -+++ openssh-7.7p1/sshkey.c 2018-08-08 10:08:40.826720007 +0200 +diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c +--- openssh-7.9p1/sshkey.c.fips 2019-03-11 17:06:37.617878003 +0100 ++++ openssh-7.9p1/sshkey.c 2019-03-11 17:06:37.624878069 +0100 @@ -34,6 +34,7 @@ #include #include @@ -690,7 +764,7 @@ diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c #include "xmss_fast.h" -@@ -1526,6 +1528,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1514,6 +1516,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -699,10 +773,10 @@ diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c ---- openssh-7.7p1/ssh-keygen.c.fips 2018-08-08 10:08:40.801719797 +0200 -+++ openssh-7.7p1/ssh-keygen.c 2018-08-08 10:08:40.827720016 +0200 -@@ -229,6 +229,12 @@ type_bits_valid(int type, const char *na +diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c +--- openssh-7.9p1/ssh-keygen.c.fips 2019-03-11 17:06:37.590877750 +0100 ++++ openssh-7.9p1/ssh-keygen.c 2019-03-11 17:06:37.625878079 +0100 +@@ -230,6 +230,12 @@ type_bits_valid(int type, const char *na OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (*bitsp > maxbits) fatal("key bits exceeds maximum %d", maxbits); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 11ab6ee..3f46ac1 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -113,29 +113,12 @@ index a5a81ed2..63f877f2 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -237,36 +287,188 @@ 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, ...) { @@ -200,9 +183,8 @@ index a5a81ed2..63f877f2 100644 + /* unknown token, fallback to the default */ + goto cleanup; + } - } - -- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { ++ } ++ + if (ssh_asprintf_append(&r, "%s", p_o) == -1) + goto cleanup; + @@ -216,7 +198,10 @@ index a5a81ed2..63f877f2 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; @@ -241,9 +226,22 @@ index a5a81ed2..63f877f2 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; -+ + +- 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; @@ -258,7 +256,8 @@ index a5a81ed2..63f877f2 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; @@ -345,11 +344,10 @@ index 29491df9..fdab5040 100644 +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); #endif #endif -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 795992d9..0623a107 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -114,7 +114,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, 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 */ @@ -358,12 +356,9 @@ index 795992d9..0623a107 100644 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; -@@ -121,16 +121,17 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - krb5_error_code problem; - krb5_principal princ; +@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl OM_uint32 maj_status, min_status; -- const char *new_ccname, *new_cctype; -+ int len; + const char *new_ccname, *new_cctype; const char *errmsg; + int set_env = 0; @@ -379,7 +374,7 @@ index 795992d9..0623a107 100644 #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE -@@ -144,14 +145,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); @@ -398,7 +393,7 @@ index 795992d9..0623a107 100644 } #endif /* #ifdef HEIMDAL */ -@@ -160,7 +161,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); @@ -407,7 +402,7 @@ index 795992d9..0623a107 100644 } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { -@@ -169,7 +170,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); @@ -416,7 +411,7 @@ index 795992d9..0623a107 100644 } krb5_free_principal(krb_context, princ); -@@ -178,37 +179,27 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -331,29 +332,19 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); @@ -424,8 +419,8 @@ index 795992d9..0623a107 100644 + return 0; } -- new_cctype = krb5_cc_get_type(krb_context, ccache); -- new_ccname = krb5_cc_get_name(krb_context, ccache); + new_cctype = krb5_cc_get_type(krb_context, ccache); + new_ccname = krb5_cc_get_name(krb_context, ccache); - - client->store.envvar = "KRB5CCNAME"; -#ifdef USE_CCAPI @@ -433,21 +428,17 @@ index 795992d9..0623a107 100644 -#else - if (new_ccname[0] == ':') - new_ccname++; -- xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); + xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); - if (strcmp(new_cctype, "DIR") == 0) { - char *p; - p = strrchr(client->store.envval, '/'); - if (p) - *p = '\0'; -- } --#endif ++ + if (set_env) { -+ const char *filename = krb5_cc_get_name(krb_context, ccache); + client->store.envvar = "KRB5CCNAME"; -+ len = strlen(filename) + 6; -+ client->store.envval = xmalloc(len); -+ snprintf(client->store.envval, len, "FILE:%s", filename); -+ } + } +-#endif #ifdef USE_PAM - if (options.use_pam) @@ -455,7 +446,7 @@ index 795992d9..0623a107 100644 do_pam_putenv(client->store.envvar, client->store.envval); #endif - krb5_cc_close(krb_context, ccache); +@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->store.data = krb_context; @@ -486,11 +477,20 @@ index 6cae720e..16e55cbc 100644 } /* This allows GSSAPI methods to do things to the childs environment based -diff --git a/servconf.c b/servconf.c -index cb578658..a6e01df2 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options) +@@ -496,8 +498,7 @@ ssh_gssapi_rekey_creds() { + char *envstr; + #endif + +- if (gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); +diff -up openssh-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; diff --git a/openssh-7.8p1-gsskex.patch b/openssh-7.8p1-gsskex.patch index cba36dc..ce35d90 100644 --- a/openssh-7.8p1-gsskex.patch +++ b/openssh-7.8p1-gsskex.patch @@ -693,7 +693,7 @@ diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c + debug("%s: krb5_cc_resolve(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ debug("%s: krb5_cc_destroy(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else { + krb5_free_context(gssapi_client.store.data); diff --git a/openssh-7.9p1-gsissh.patch b/openssh-7.9p1-gsissh.patch index 666fb14..9686bd8 100644 --- a/openssh-7.9p1-gsissh.patch +++ b/openssh-7.9p1-gsissh.patch @@ -902,12 +902,12 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c + char **p; char **pw; #endif -- if (gssapi_client.store.envval == NULL && +- if (gssapi_client.store.envval == NULL) + if (gssapi_client.store.filename == NULL && -+ gssapi_client.store.envval == NULL && - gssapi_client.store.envvar == NULL) ++ gssapi_client.store.envval == NULL) return; + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); @@ -527,6 +613,18 @@ if (ret) return; diff --git a/openssh-7.9p1-updated-cached-pw.patch b/openssh-7.9p1-updated-cached-pw.patch new file mode 100644 index 0000000..7f24ce4 --- /dev/null +++ b/openssh-7.9p1-updated-cached-pw.patch @@ -0,0 +1,23 @@ +diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.update-pw 2019-03-04 14:10:57.287054645 +0100 ++++ openssh-7.4p1/session.c 2019-03-04 14:12:39.259997218 +0100 +@@ -1522,9 +1522,18 @@ do_child(Session *s, const char *command + char **env; + char *argv[ARGV_MAX]; + const char *shell, *shell0; +- struct passwd *pw = s->pw; ++ struct passwd *pw = NULL; + int r = 0; + ++ /* Update the users passwd structure after successful login */ ++ pw = getpwuid(s->pw->pw_uid); ++ if (pw != NULL) { ++ free(s->pw); ++ s->pw = pw; ++ } else { ++ pw = s->pw; ++ } ++ + /* remove hostkey from the child's memory */ + destroy_sensitive_data(); + packet_clear_keys(); From aa3c245244b8eb4fc98afc0a9ff4052052419992 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 5 May 2019 18:06:52 +0200 Subject: [PATCH 072/146] Based on openssh-8.0p1-1.fc30 --- gsi-openssh.spec | 60 +- openssh-6.1p1-gssapi-canohost.patch | 21 - openssh-6.2p1-vendor.patch | 142 - openssh-6.6.1p1-log-in-chroot.patch | 4 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 14 +- openssh-6.6p1-kuserok.patch | 8 +- openssh-6.7p1-coverity.patch | 16 +- openssh-6.7p1-kdf-cavs.patch | 16 +- openssh-6.8p1-sshdT-output.patch | 15 - openssh-7.0p1-gssKexAlgorithms.patch | 431 -- openssh-7.1p1-gssapi-documentation.patch | 52 - openssh-7.1p2-audit-race-condition.patch | 32 +- openssh-7.2p2-k5login_directory.patch | 13 +- openssh-7.5p1-gssapi-kex-with-ec.patch | 1377 ----- openssh-7.6p1-audit.patch | 926 ++-- openssh-7.6p1-cleanup-selinux.patch | 82 +- openssh-7.6p1-pkcs11-ecdsa.patch | 794 --- openssh-7.6p1-pkcs11-uri.patch | 4760 ----------------- openssh-7.7p1-fips.patch | 237 +- openssh-7.7p1-gssapi-new-unique.patch | 20 +- openssh-7.8p1-UsePAM-warning.patch | 4 +- openssh-7.8p1-gsskex.patch | 2905 ---------- openssh-7.8p1-ip-port-config-parser.patch | 72 - openssh-7.8p1-role-mls.patch | 36 +- openssh-7.9p1-CVE-2018-20685.patch | 28 - openssh-7.9p1-backports.patch | 186 - openssh-7.9p1-disable-sha1.patch | 62 - openssh-7.9p1-gsskex-method.patch | 150 - openssh-7.9p1-log-sftp-only-connections.patch | 11 - openssh-7.9p1-match-final.patch | 306 -- openssh-7.9p1-updated-cached-pw.patch | 8 +- ...gsissh.patch => openssh-8.0p1-gsissh.patch | 691 ++- openssh-8.0p1-gssapi-keyex.patch | 3924 ++++++++++++++ openssh-8.0p1-pkcs11-uri.patch | 3068 +++++++++++ 34 files changed, 8114 insertions(+), 12357 deletions(-) delete mode 100644 openssh-6.1p1-gssapi-canohost.patch delete mode 100644 openssh-6.2p1-vendor.patch delete mode 100644 openssh-7.0p1-gssKexAlgorithms.patch delete mode 100644 openssh-7.1p1-gssapi-documentation.patch delete mode 100644 openssh-7.5p1-gssapi-kex-with-ec.patch delete mode 100644 openssh-7.6p1-pkcs11-ecdsa.patch delete mode 100644 openssh-7.6p1-pkcs11-uri.patch delete mode 100644 openssh-7.8p1-gsskex.patch delete mode 100644 openssh-7.8p1-ip-port-config-parser.patch delete mode 100644 openssh-7.9p1-CVE-2018-20685.patch delete mode 100644 openssh-7.9p1-backports.patch delete mode 100644 openssh-7.9p1-disable-sha1.patch delete mode 100644 openssh-7.9p1-gsskex-method.patch delete mode 100644 openssh-7.9p1-log-sftp-only-connections.patch delete mode 100644 openssh-7.9p1-match-final.patch rename openssh-7.9p1-gsissh.patch => openssh-8.0p1-gsissh.patch (80%) create mode 100644 openssh-8.0p1-gssapi-keyex.patch create mode 100644 openssh-8.0p1-pkcs11-uri.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 7d86075..f157605 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 7.9p1 -%global openssh_rel 7 +%global openssh_ver 8.0p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -96,8 +96,6 @@ Patch702: openssh-5.1p1-askpass-progress.patch Patch703: openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) Patch707: openssh-7.7p1-redhat.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) -Patch709: openssh-6.2p1-vendor.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 @@ -107,28 +105,20 @@ Patch713: openssh-6.6p1-ctr-cavstest.patch # add SSH KDF CAVS test driver Patch714: openssh-6.7p1-kdf-cavs.patch -#http://www.sxw.org.uk/computing/patches/openssh.html -#changed cache storage type - #848228 -Patch800: openssh-7.8p1-gsskex.patch +# GSSAPI Key Exchange (RFC 4462 + draft-ietf-curdle-gss-keyex-sha2-08) +# 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 -# Documentation about GSSAPI -# from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655 -Patch803: openssh-7.1p1-gssapi-documentation.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 -# Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02 -Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch -# Do not break when using AuthenticationMethods with gssapi-keyex auth method (#1625366) -Patch808: openssh-7.9p1-gsskex-method.patch -Patch900: openssh-6.1p1-gssapi-canohost.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 Patch901: openssh-6.6p1-kuserok.patch # Use tty allocation for a remote scp (#985650) @@ -139,16 +129,12 @@ Patch916: openssh-6.6.1p1-selinux-contexts.patch 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 -# Config parser shouldn't accept ip/port syntax (#1130733) -Patch920: openssh-7.8p1-ip-port-config-parser.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 # Restore compatible default (#89216) Patch929: openssh-6.9p1-permit-root-login.patch -# Add GSSAPIKexAlgorithms option for server and client application -Patch932: openssh-7.0p1-gssKexAlgorithms.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch # Move MAX_DISPLAYS to a configuration option (#1341302) @@ -160,34 +146,19 @@ 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) -Patch951: openssh-7.6p1-pkcs11-uri.patch -# PKCS#11 ECDSA keys (upstream #2474, 8th iteration) -Patch952: openssh-7.6p1-pkcs11-ecdsa.patch +Patch951: openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch -# Allow to disable RSA signatures with SHA-1 in server -# https://bugzilla.mindrot.org/show_bug.cgi?id=2746 -Patch954: openssh-7.9p1-disable-sha1.patch -# Backport Match final so the crypto-policies do not break canonicalization (#1630166) -# https://bugzilla.mindrot.org/show_bug.cgi?id=2906 -Patch955: openssh-7.9p1-match-final.patch -# Backport more after-release fixes (#1665611) -Patch956: openssh-7.9p1-backports.patch -# Backport patch for CVE-2018-20685 (#1665786) -Patch957: openssh-7.9p1-CVE-2018-20685.patch # ssh-copy-id is unmaintained: Aggreagete patches # - do not return 0 if the write fails (full disk) # - shellcheck reports (upstream #2902) Patch958: openssh-7.9p1-ssh-copy-id.patch -# log when a client requests an interactive session and only sftp is allowed -# https://bugzilla.mindrot.org/show_bug.cgi?id=2960 -Patch959: openssh-7.9p1-log-sftp-only-connections.patch # Update cached passwd structure after PAM authentication (#1674541) Patch960: openssh-7.9p1-updated-cached-pw.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-7.9p1-gsissh.patch +Patch98: openssh-8.0p1-gsissh.patch License: BSD Requires: /sbin/nologin @@ -305,7 +276,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch702 -p1 -b .progress %patch703 -p1 -b .grab-info %patch707 -p1 -b .redhat -%patch709 -p1 -b .vendor %patch711 -p1 -b .log-usepam-no %patch712 -p1 -b .evp-ctr %patch713 -p1 -b .ctr-cavs @@ -313,38 +283,26 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch800 -p1 -b .gsskex %patch801 -p1 -b .force_krb -%patch803 -p1 -b .gss-docs %patch804 -p1 -b .ccache_name %patch805 -p1 -b .k5login -%patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok %patch906 -p1 -b .fromto-remote %patch916 -p1 -b .contexts %patch918 -p1 -b .log-in-chroot %patch919 -p1 -b .scp -%patch920 -p1 -b .config %patch802 -p1 -b .GSSAPIEnablek5users %patch922 -p1 -b .sshdt %patch926 -p1 -b .sftp-force-mode %patch929 -p1 -b .root-login -%patch932 -p1 -b .gsskexalg %patch939 -p1 -b .s390-dev %patch944 -p1 -b .x11max %patch948 -p1 -b .systemd -%patch807 -p1 -b .gsskex-ec %patch949 -p1 -b .refactor %patch950 -p1 -b .sandbox %patch951 -p1 -b .pkcs11-uri -%patch952 -p1 -b .pkcs11-ecdsa %patch953 -p1 -b .scp-ipv6 -%patch808 -p1 -b .gsskex-method -%patch954 -p1 -b .disable-sha1 -%patch955 -p1 -b .match-final -%patch956 -p1 -b .backports -%patch957 -p1 -b .CVE-2018-20685 %patch958 -p1 -b .ssh-copy-id -%patch959 -p1 -b .log-sftp-only %patch960 -p1 -b .update-pw %patch200 -p1 -b .audit @@ -401,7 +359,6 @@ fi --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 \ - --enable-vendor-patchlevel="FC-%{openssh_ver}-%{openssh_rel}" \ --disable-strip \ --without-zlib-version-check \ --with-ssl-engine \ @@ -558,6 +515,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri May 3 2019 Mattias Ellert - 8.0p1-1 +- Based on openssh-8.0p1-1.fc30 + * Fri Mar 22 2019 Mattias Ellert - 7.9p1-7 - Based on openssh-7.9p1-5.fc29 diff --git a/openssh-6.1p1-gssapi-canohost.patch b/openssh-6.1p1-gssapi-canohost.patch deleted file mode 100644 index 3e6c9cc..0000000 --- a/openssh-6.1p1-gssapi-canohost.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c ---- openssh-6.1p1/sshconnect2.c.canohost 2012-10-30 10:52:59.593301692 +0100 -+++ openssh-6.1p1/sshconnect2.c 2012-10-30 11:01:12.870301632 +0100 -@@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt) - static u_int mech = 0; - OM_uint32 min; - int r, ok = 0; -- const char *gss_host; -+ const char *gss_host = NULL; - - if (options.gss_server_identity) - gss_host = options.gss_server_identity; -- else if (options.gss_trust_dns) -+ else if (options.gss_trust_dns) { - gss_host = get_canonical_hostname(active_state, 1); -+ if (strcmp(gss_host, "UNKNOWN") == 0) -+ gss_host = authctxt->host; -+ } - else - gss_host = authctxt->host; - diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch deleted file mode 100644 index 1af5e9d..0000000 --- a/openssh-6.2p1-vendor.patch +++ /dev/null @@ -1,142 +0,0 @@ -diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac ---- openssh-7.4p1/configure.ac.vendor 2016-12-23 13:34:51.681253844 +0100 -+++ openssh-7.4p1/configure.ac 2016-12-23 13:34:51.694253847 +0100 -@@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog], - fi - ] - ) -+AC_ARG_ENABLE(vendor-patchlevel, -+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level], -+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL="$enableval"], -+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL=none]) - - dnl lastlog, [uw]tmpx? detection - dnl NOTE: set the paths in the platform section to avoid the -@@ -5194,6 +5200,7 @@ echo " Translate v4 in v6 hack - echo " BSD Auth support: $BSD_AUTH_MSG" - echo " Random number source: $RAND_MSG" - echo " Privsep sandbox style: $SANDBOX_STYLE" -+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" - - echo "" - -diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.vendor 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 13:36:07.555268628 +0100 -@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions - options->max_authtries = -1; - options->max_sessions = -1; - options->banner = NULL; -+ options->show_patchlevel = -1; - options->use_dns = -1; - options->client_alive_interval = -1; - options->client_alive_count_max = -1; -@@ -325,6 +326,8 @@ fill_default_server_options(ServerOption - options->ip_qos_bulk = IPTOS_DSCP_CS1; - if (options->version_addendum == NULL) - options->version_addendum = xstrdup(""); -+ if (options->show_patchlevel == -1) -+ options->show_patchlevel = 0; - if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) - options->fwd_opts.streamlocal_bind_mask = 0177; - if (options->fwd_opts.streamlocal_bind_unlink == -1) -@@ -402,7 +405,7 @@ typedef enum { - sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, - sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, -- sBanner, sUseDNS, sHostbasedAuthentication, -+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, - sHostKeyAlgorithms, - sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, -@@ -528,6 +531,7 @@ static struct { - { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, - { "maxsessions", sMaxSessions, SSHCFG_ALL }, - { "banner", sBanner, SSHCFG_ALL }, -+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL }, - { "usedns", sUseDNS, SSHCFG_GLOBAL }, - { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, - { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions - intptr = &options->disable_forwarding; - goto parse_flag; - -+ case sShowPatchLevel: -+ intptr = &options->show_patchlevel; -+ goto parse_flag; -+ - case sAllowUsers: - while ((arg = strdelim(&cp)) && *arg != '\0') { - if (match_user(NULL, NULL, NULL, arg) == -1) -@@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); - dump_cfg_fmtint(sCompression, o->compression); - dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); -+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); -diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.vendor 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 13:34:51.694253847 +0100 -@@ -149,6 +149,7 @@ typedef struct { - int max_authtries; - int max_sessions; - char *banner; /* SSH-2 banner message */ -+ int show_patchlevel; /* Show vendor patch level to clients */ - int use_dns; - int client_alive_interval; /* - * poke the client this often to -diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100 -@@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as - .Cm AcceptEnv - or - .Cm PermitUserEnvironment . -+.It Cm ShowPatchLevel -+Specifies whether -+.Nm sshd -+will display the patch level of the binary in the identification string. -+The patch level is set at compile-time. -+The default is -+.Dq no . - .It Cm StreamLocalBindMask - Sets the octal file creation mode mask - .Pq umask -diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.vendor 2016-12-23 13:34:51.690253846 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 13:34:51.695253847 +0100 -@@ -105,6 +105,7 @@ X11Forwarding yes - #Compression delayed - #ClientAliveInterval 0 - #ClientAliveCountMax 3 -+#ShowPatchLevel no - #UseDNS no - #PidFile /var/run/sshd.pid - #MaxStartups 10:30:100 -diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.vendor 2016-12-23 13:34:51.682253844 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 13:38:32.434296856 +0100 -@@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh - char remote_version[256]; /* Must be at least as big as buf. */ - - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", -- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, -+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, -+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - *options.version_addendum == '\0' ? "" : " ", - options.version_addendum); - -@@ -1650,7 +1651,8 @@ main(int ac, char **av) - exit(1); - } - -- debug("sshd version %s, %s", SSH_VERSION, -+ debug("sshd version %s, %s", -+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - #ifdef WITH_OPENSSL - SSLeay_version(SSLEAY_VERSION) - #else diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 7f822ab..b009d99 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -46,7 +46,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c + pmonitor->m_state = "preauth"; + - authctxt = _authctxt; + authctxt = (Authctxt *)ssh->authctxt; memset(authctxt, 0, sizeof(*authctxt)); ssh->authctxt = authctxt; @@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p @@ -113,7 +113,7 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h +void monitor_reinit(struct monitor *, const char *); struct Authctxt; - void monitor_child_preauth(struct Authctxt *, struct monitor *); + 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 diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index c33bdac..d943f41 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -22,15 +22,15 @@ 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_strict_acceptor = -1; 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->challenge_response_authentication = -1; @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption - options->gss_store_rekey = 0; + #endif if (options->use_kuserok == -1) options->use_kuserok = 1; + if (options->enable_k5users == -1) @@ -44,20 +44,22 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, + sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -497,12 +500,14 @@ static struct { - { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, +@@ -497,14 +500,16 @@ static struct { { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, + { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, + { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, + { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, + { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 4b681ff..56a6950 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -176,17 +176,17 @@ 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_cleanup_creds = -1; 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->challenge_response_authentication = -1; @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption - options->gss_strict_acceptor = 1; - if (options->gss_store_rekey == -1) - options->gss_store_rekey = 0; + if (options->gss_kex_algorithms == NULL) + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); + #endif + if (options->use_kuserok == -1) + options->use_kuserok = 1; if (options->password_authentication == -1) diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 0d238dd..15d489d 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -20,7 +20,7 @@ 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(pmonitor); + mm_get_keystate(ssh, pmonitor); /* Drain any buffered messages from the child */ - while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) @@ -124,14 +124,14 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c } @@ -518,7 +518,7 @@ server_request_tun(void) + debug("%s: invalid tun", __func__); + goto done; } - - tun = packet_get_int(); - if (auth_opts->force_tun_device != -1) { + if (auth_opts->force_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) + if (tun != SSH_TUNID_ANY && + auth_opts->force_tun_device != (int)tun) goto done; - tun = auth_opts->force_tun_device; 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 @@ -163,7 +163,7 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 @@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt) - privsep_preauth_child(); + privsep_preauth_child(ssh); setproctitle("%s", "[net]"); - if (box != NULL) + if (box != NULL) { @@ -174,8 +174,8 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c return 0; } @@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so - if (num_listen_socks < 0) - break; + explicit_bzero(rnd, sizeof(rnd)); + } } + + if (fdset != NULL) diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index 181267c..a5beb8c 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in 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,377 @@ +@@ -0,0 +1,387 @@ +/* + * Copyright (C) 2015, Stephan Mueller + * @@ -208,6 +208,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c +{ + int ret = 0; + struct kex kex; ++ struct sshbuf *Kb = NULL; + BIGNUM *Kbn = NULL; + int mode = 0; + struct newkeys *ctoskeys; @@ -222,10 +223,17 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c + Kbn = BN_new(); + BN_bin2bn(test->K, test->Klen, Kbn); + if (!Kbn) { -+ printf("cannot convert K into BIGNUM\n"); ++ 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; @@ -285,7 +293,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c + goto out; + } + ssh->kex = &kex; -+ kex_derive_keys_bn(ssh, test->H, test->Hlen, Kbn); ++ kex_derive_keys(ssh, test->H, test->Hlen, Kb); + + ctoskeys = kex.newkeys[0]; + stockeys = kex.newkeys[1]; @@ -321,6 +329,8 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c +out: + if (Kbn) + BN_free(Kbn); ++ if (Kb) ++ sshbuf_free(Kb); + if (ssh) + ssh_packet_close(ssh); + return ret; diff --git a/openssh-6.8p1-sshdT-output.patch b/openssh-6.8p1-sshdT-output.patch index 7a843e7..ac9169a 100644 --- a/openssh-6.8p1-sshdT-output.patch +++ b/openssh-6.8p1-sshdT-output.patch @@ -10,18 +10,3 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); -diff -up openssh/ssh.1.sshdt openssh/ssh.1 ---- openssh/ssh.1.sshdt 2015-06-24 11:42:19.565102807 +0200 -+++ openssh/ssh.1 2015-06-24 11:42:29.042078701 +0200 -@@ -441,7 +441,11 @@ For full details of the options listed b - .It GatewayPorts - .It GlobalKnownHostsFile - .It GSSAPIAuthentication -+.It GSSAPIKeyExchange -+.It GSSAPIClientIdentity - .It GSSAPIDelegateCredentials -+.It GSSAPIRenewalForcesRekey -+.It GSSAPITrustDNS - .It HashKnownHosts - .It Host - .It HostbasedAuthentication diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch deleted file mode 100644 index 8bd2d4e..0000000 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ /dev/null @@ -1,431 +0,0 @@ -diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c ---- openssh-7.0p1/gss-genr.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 -+++ openssh-7.0p1/gss-genr.c 2015-08-19 12:28:38.078518839 +0200 -@@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() { - */ - - char * --ssh_gssapi_client_mechanisms(const char *host, const char *client) { -+ssh_gssapi_client_mechanisms(const char *host, const char *client, -+ const char *kex) { - gss_OID_set gss_supported; - OM_uint32 min_status; - -@@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char - return NULL; - - return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, -- host, client)); -+ host, client, kex)); - } - - char * - ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, -- const char *host, const char *client) { -+ const char *host, const char *client, const char *kex) { - struct sshbuf *buf; - size_t i; - int oidpos, enclen, r; -@@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - char deroid[2]; - const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX *md; -+ char *s, *cp, *p; - - if (gss_enc2oid != NULL) { - for (i = 0; gss_enc2oid[i].encoded != NULL; i++) -@@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - - md = EVP_MD_CTX_new(); - oidpos = 0; -+ s = cp = xstrdup(kex); - for (i = 0; i < gss_supported->count; i++) { - if (gss_supported->elements[i].length < 128 && - (*check)(NULL, &(gss_supported->elements[i]), host, client)) { -@@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - enclen = __b64_ntop(digest, EVP_MD_size(evp_md), - encoded, EVP_MD_size(evp_md) * 2); - -- if (oidpos != 0) -- if ((r = sshbuf_put_u8(buf, ',')) != 0) -- fatal("%s: buffer error: %s", __func__, ssh_err(r)); -- -- if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID, -- sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 || -- (r = sshbuf_put(buf, encoded, enclen)) != 0 || -- (r = sshbuf_put_u8(buf, ',')) != 0 || -- (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, -- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 || -- (r = sshbuf_put(buf, encoded, enclen)) != 0 || -- (r = sshbuf_put_u8(buf, ',')) != 0 || -- (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID, -- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 || -- (r = sshbuf_put(buf, encoded, enclen)) != 0) -- fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ cp = strncpy(s, kex, strlen(kex)); -+ for ((p = strsep(&cp, ",")); p && *p != '\0'; -+ (p = strsep(&cp, ","))) { -+ if (sshbuf_len(buf) != 0) -+ if ((r = sshbuf_put_u8(buf, ',')) != 0) -+ fatal("%s: buffer error: %s", -+ __func__, ssh_err(r)); -+ if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || -+ (r = sshbuf_put(buf, encoded, enclen)) != 0) -+ fatal("%s: buffer error: %s", -+ __func__, ssh_err(r)); -+ } - - gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); - gss_enc2oid[oidpos].encoded = encoded; - oidpos++; - } - } -+ free(s); - EVP_MD_CTX_free(md); - gss_enc2oid[oidpos].oid = NULL; - gss_enc2oid[oidpos].encoded = NULL; -diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c ---- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 -+++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200 -@@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() { - if (supported_oids == NULL) - ssh_gssapi_prepare_supported_oids(); - return (ssh_gssapi_kex_mechs(supported_oids, -- &ssh_gssapi_server_check_mech, NULL, NULL)); -+ &ssh_gssapi_server_check_mech, NULL, NULL, -+ options.gss_kex_algorithms)); - } - - /* Unprivileged */ -diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200 -+++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200 -@@ -50,6 +50,7 @@ - #include "misc.h" - #include "dispatch.h" - #include "monitor.h" -+#include "xmalloc.h" - - #include "ssherr.h" - #include "sshbuf.h" -@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char - return r; - } - -+/* Validate GSS KEX method name list */ -+int -+gss_kex_names_valid(const char *names) -+{ -+ char *s, *cp, *p; -+ -+ if (names == NULL || *names == '\0') -+ return 0; -+ s = cp = xstrdup(names); -+ for ((p = strsep(&cp, ",")); p && *p != '\0'; -+ (p = strsep(&cp, ","))) { -+ if (strncmp(p, "gss-", 4) != 0 -+ || kex_alg_by_name(p) == NULL) { -+ error("Unsupported KEX algorithm \"%.100s\"", p); -+ free(s); -+ return 0; -+ } -+ } -+ debug3("gss kex names ok: [%s]", names); -+ free(s); -+ return 1; -+} -+ - /* put algorithm proposal into buffer */ - int - kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) -diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h ---- openssh-7.0p1/kex.h.gsskexalg 2015-08-19 12:28:38.078518839 +0200 -+++ openssh-7.0p1/kex.h 2015-08-19 12:30:52.404218958 +0200 -@@ -173,6 +173,7 @@ int kex_names_valid(const char *); - char *kex_alg_list(char); - char *kex_names_cat(const char *, const char *); - int kex_assemble_names(char **, const char *, const char *); -+int gss_kex_names_valid(const char *); - - int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); - int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); -diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c ---- openssh-7.0p1/readconf.c.gsskexalg 2015-08-19 12:28:38.026518955 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-19 12:31:28.333138747 +0200 -@@ -61,6 +61,7 @@ - #include "uidswap.h" - #include "myproposal.h" - #include "digest.h" -+#include "ssh-gss.h" - - /* Format of the configuration file: - -@@ -148,7 +149,7 @@ typedef enum { - oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, - oAddressFamily, oGssAuthentication, oGssDelegateCreds, - oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, -- oGssServerIdentity, -+ oGssServerIdentity, oGssKexAlgorithms, - oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, - oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, - oHashKnownHosts, -@@ -200,6 +201,7 @@ static struct { - { "gssapiclientidentity", oGssClientIdentity }, - { "gssapiserveridentity", oGssServerIdentity }, - { "gssapirenewalforcesrekey", oGssRenewalRekey }, -+ { "gssapikexalgorithms", oGssKexAlgorithms }, - # else - { "gssapiauthentication", oUnsupported }, - { "gssapikeyexchange", oUnsupported }, -@@ -207,6 +209,7 @@ static struct { - { "gssapitrustdns", oUnsupported }, - { "gssapiclientidentity", oUnsupported }, - { "gssapirenewalforcesrekey", oUnsupported }, -+ { "gssapikexalgorithms", oUnsupported }, - #endif - #ifdef ENABLE_PKCS11 - { "smartcarddevice", oPKCS11Provider }, -@@ -929,6 +932,18 @@ parse_time: - intptr = &options->gss_renewal_rekey; - goto parse_flag; - -+ case oGssKexAlgorithms: -+ arg = strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", -+ filename, linenum); -+ if (!gss_kex_names_valid(arg)) -+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", -+ filename, linenum, arg ? arg : ""); -+ if (*activep && options->gss_kex_algorithms == NULL) -+ options->gss_kex_algorithms = xstrdup(arg); -+ break; -+ - case oBatchMode: - intptr = &options->batch_mode; - goto parse_flag; -@@ -1638,6 +1653,7 @@ initialize_options(Options * options) - options->gss_renewal_rekey = -1; - options->gss_client_identity = NULL; - options->gss_server_identity = NULL; -+ options->gss_kex_algorithms = NULL; - options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->kbd_interactive_devices = NULL; -@@ -1773,6 +1789,10 @@ fill_default_options(Options * options) - options->gss_trust_dns = 0; - if (options->gss_renewal_rekey == -1) - options->gss_renewal_rekey = 0; -+#ifdef GSSAPI -+ if (options->gss_kex_algorithms == NULL) -+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); -+#endif - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) -@@ -2651,6 +2671,8 @@ dump_client_config(Options *o, const cha - dump_cfg_string(oGssClientIdentity, o->gss_client_identity); - dump_cfg_string(oGssServerIdentity, o->gss_client_identity); - dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); -+ dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ? -+ o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX); - #endif /* GSSAPI */ - dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); - dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff -up openssh-7.9p1/readconf.h.gsskexalg openssh-7.9p1/readconf.h ---- openssh-7.9p1/readconf.h.gsskexalg 2018-11-14 09:20:06.616350574 +0100 -+++ openssh-7.9p1/readconf.h 2018-11-14 09:20:06.647350828 +0100 -@@ -46,6 +46,7 @@ typedef struct { - int gss_renewal_rekey; /* Credential renewal forces rekey */ - char *gss_client_identity; /* Principal to initiate GSSAPI with */ - char *gss_server_identity; /* GSSAPI target principal */ -+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ - int password_authentication; /* Try password - * authentication. */ - int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.gsskexalg 2015-08-19 12:28:38.074518847 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-19 12:33:13.599902732 +0200 -@@ -57,6 +57,7 @@ - #include "auth.h" - #include "myproposal.h" - #include "digest.h" -+#include "ssh-gss.h" - - static void add_listen_addr(ServerOptions *, const char *, - const char *, int); -@@ -121,6 +122,7 @@ initialize_server_options(ServerOptions - options->gss_cleanup_creds = -1; - options->gss_strict_acceptor = -1; - options->gss_store_rekey = -1; -+ options->gss_kex_algorithms = NULL; - options->use_kuserok = -1; - options->enable_k5users = -1; - options->password_authentication = -1; -@@ -288,6 +290,10 @@ fill_default_server_options(ServerOption - options->gss_strict_acceptor = 1; - if (options->gss_store_rekey == -1) - options->gss_store_rekey = 0; -+#ifdef GSSAPI -+ if (options->gss_kex_algorithms == NULL) -+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); -+#endif - if (options->use_kuserok == -1) - options->use_kuserok = 1; - if (options->enable_k5users == -1) -@@ -427,7 +431,7 @@ typedef enum { - sHostKeyAlgorithms, - sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, -- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel, - sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, - sHostCertificate, -@@ -506,6 +510,7 @@ static struct { - { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, - { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, - { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, -+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, - #else - { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, - { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -513,6 +518,7 @@ static struct { - { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, - { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, - { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, -+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, - #endif - { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, - { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions - intptr = &options->gss_store_rekey; - goto parse_flag; - -+ case sGssKexAlgorithms: -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", -+ filename, linenum); -+ if (!gss_kex_names_valid(arg)) -+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", -+ filename, linenum, arg ? arg : ""); -+ if (*activep && options->gss_kex_algorithms == NULL) -+ options->gss_kex_algorithms = xstrdup(arg); -+ break; -+ - case sPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; -@@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); - dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); - dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); -+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); - #endif - dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); - dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h ---- openssh-7.0p1/servconf.h.gsskexalg 2015-08-19 12:28:38.080518834 +0200 -+++ openssh-7.0p1/servconf.h 2015-08-19 12:34:46.328693944 +0200 -@@ -122,6 +122,7 @@ typedef struct { - int gss_cleanup_creds; /* If true, destroy cred cache on logout */ - int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ - int gss_store_rekey; -+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ - int password_authentication; /* If true, permit password - * authentication. */ - int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1 ---- openssh-7.0p1/ssh.1.gsskexalg 2015-08-19 12:28:38.081518832 +0200 -+++ openssh-7.0p1/ssh.1 2015-08-19 12:35:31.741591692 +0200 -@@ -496,6 +496,7 @@ For full details of the options listed b - .It GSSAPIDelegateCredentials - .It GSSAPIRenewalForcesRekey - .It GSSAPITrustDNS -+.It GSSAPIKexAlgorithms - .It HashKnownHosts - .It Host - .It HostbasedAuthentication -diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5 ---- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200 -+++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200 -@@ -786,6 +786,18 @@ command line will be passed untouched to - command line will be passed untouched to the GSSAPI library. - The default is - .Dq no . -+.It Cm GSSAPIKexAlgorithms -+The list of key exchange algorithms that are offered for GSSAPI -+key exchange. Possible values are -+.Bd -literal -offset 3n -+gss-gex-sha1-, -+gss-group1-sha1-, -+gss-group14-sha1- -+.Ed -+.Pp -+The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HashKnownHosts - Indicates that - .Xr ssh 1 -diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1/sshconnect2.c.gsskexalg 2015-08-19 12:28:38.045518912 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:28:38.081518832 +0200 -@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho - else - gss_host = host; - -- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); -+ gss = ssh_gssapi_client_mechanisms(gss_host, -+ options.gss_client_identity, options.gss_kex_algorithms); - if (gss) { - debug("Offering GSSAPI proposal: %s", gss); - xasprintf(&options.kex_algorithms, ---- openssh-7.1p1/sshd_config.5.gsskexalg 2015-12-10 15:32:48.105418092 +0100 -+++ openssh-7.1p1/sshd_config.5 2015-12-10 15:33:47.771279548 +0100 -@@ -663,6 +663,18 @@ or updated credentials from a compatible - For this to work - .Cm GSSAPIKeyExchange - needs to be enabled in the server and also used by the client. -+.It Cm GSSAPIKexAlgorithms -+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- -+.Ed -+.Pp -+The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. -diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h ---- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200 -+++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200 -@@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds; - #define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" - #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" - -+#define GSS_KEX_DEFAULT_KEX \ -+ KEX_GSS_GEX_SHA1_ID "," \ -+ KEX_GSS_GRP14_SHA1_ID -+ - typedef struct { - char *envvar; - char *envval; -@@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct - /* In the server */ - typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, - const char *); --char *ssh_gssapi_client_mechanisms(const char *, const char *); -+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); - char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, -- const char *); -+ const char *, const char *); - gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); - int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, - const char *); diff --git a/openssh-7.1p1-gssapi-documentation.patch b/openssh-7.1p1-gssapi-documentation.patch deleted file mode 100644 index db689d4..0000000 --- a/openssh-7.1p1-gssapi-documentation.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff -up openssh-7.4p1/ssh_config.5.gss-docs openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1/ssh_config.5.gss-docs 2016-12-23 14:28:34.051714486 +0100 -+++ openssh-7.4p1/ssh_config.5 2016-12-23 14:34:24.568522417 +0100 -@@ -765,10 +765,19 @@ The default is - If set to - .Dq yes - then renewal of the client's GSSAPI credentials will force the rekeying of the --ssh connection. With a compatible server, this can delegate the renewed -+ssh connection. With a compatible server, this will delegate the renewed - credentials to a session on the server. -+.Pp -+Checks are made to ensure that credentials are only propagated when the new -+credentials match the old ones on the originating client and where the -+receiving server still has the old set in its cache. -+.Pp - The default is - .Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. - .It Cm GSSAPIServerIdentity - If set, specifies the GSSAPI server identity that ssh should expect when - connecting to the server. The default is unset, which means that the -@@ -776,9 +785,11 @@ expected GSSAPI server identity will be - hostname. - .It Cm GSSAPITrustDns - Set to --.Dq yes to indicate that the DNS is trusted to securely canonicalize -+.Dq yes -+to indicate that the DNS is trusted to securely canonicalize - the name of the host being connected to. If --.Dq no, the hostname entered on the -+.Dq no , -+the hostname entered on the - command line will be passed untouched to the GSSAPI library. - The default is - .Dq no . -diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.gss-docs 2016-12-23 14:28:34.043714490 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 14:28:34.051714486 +0100 -@@ -652,6 +652,10 @@ Controls whether the user's GSSAPI crede - successful connection rekeying. This option can be used to accepted renewed - or updated credentials from a compatible client. The default is - .Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index c4536ff..9c9a680 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -56,9 +56,9 @@ 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(int, char *, char *, char *, char *, pid_t, uid_t); - void mm_audit_session_key_free_body(int, pid_t, uid_t); - void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); + 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); +int mm_forward_audit_messages(int); +void mm_set_monitor_pipe(int); #endif @@ -82,7 +82,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c return 1; } -+void child_destory_sensitive_data(); ++void child_destory_sensitive_data(struct ssh *ssh); + #define USE_PIPES 1 /* @@ -91,7 +91,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c close(err[0]); #endif -+ child_destory_sensitive_data(); ++ child_destory_sensitive_data(ssh); + /* Do processing for the child (exec command etc). */ do_child(ssh, s, command); @@ -101,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c close(ttyfd); + /* Do this early, so we will not block large MOTDs */ -+ child_destory_sensitive_data(); ++ child_destory_sensitive_data(ssh); + /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA @@ -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(s->command)); + s->command_handle = PRIVSEP(audit_run_command(ssh, s->command)); + if (pipe(paudit) < 0) + fatal("pipe: %s", strerror(errno)); #endif @@ -141,7 +141,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c } +void -+child_destory_sensitive_data() ++child_destory_sensitive_data(struct ssh *ssh) +{ +#ifdef SSH_AUDIT_EVENTS + int pparent = paudit[1]; @@ -152,15 +152,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c +#endif + + /* remove hostkey from the child's memory */ -+ destroy_sensitive_data(use_privsep); ++ 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 + * which we can't do using one-way pipe. + */ -+ packet_destroy_all(0, 1); ++ packet_destroy_all(ssh, 0, 1); + /* XXX this will clean the rest but should not audit anymore */ -+ /* packet_clear_keys(); */ ++ /* packet_clear_keys(ssh); */ + +#ifdef SSH_AUDIT_EVENTS + /* Notify parent that we are done */ @@ -172,15 +172,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group @@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command - pw = s->pw; - } + + sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove hostkey from the child's memory */ -- destroy_sensitive_data(1); -- packet_clear_keys(); +- 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. */ -- packet_destroy_all(0, 1); +- packet_destroy_all(ssh, 0, 1); - /* Force a password change */ if (s->authctxt->force_pwchange) { diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 09369aa..600117f 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -2,10 +2,11 @@ diff --git a/auth-krb5.c b/auth-krb5.c index 2b02a04..19b9364 100644 --- a/auth-krb5.c +++ b/auth-krb5.c -@@ -375,6 +375,22 @@ cleanup: - return -1; +@@ -375,5 +375,21 @@ cleanup: + return (krb5_cc_resolve(ctx, ccname, ccache)); + } } - ++ +/* + * Reads k5login_directory option from the krb5.conf + */ @@ -21,10 +22,8 @@ index 2b02a04..19b9364 100644 + return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL, + k5login_directory); +} -+ - krb5_error_code - ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { - profile_t p; + #endif /* !HEIMDAL */ + #endif /* KRB5 */ diff --git a/auth.h b/auth.h index f9d191c..c432d2f 100644 --- a/auth.h diff --git a/openssh-7.5p1-gssapi-kex-with-ec.patch b/openssh-7.5p1-gssapi-kex-with-ec.patch deleted file mode 100644 index 5f2763a..0000000 --- a/openssh-7.5p1-gssapi-kex-with-ec.patch +++ /dev/null @@ -1,1377 +0,0 @@ -From 6ff8f667f792052fd47689c3e421fcd6ddca1cd0 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 25 Aug 2017 19:15:48 +0200 -Subject: [PATCH 1/3] GSSAPI Key exchange methods with DH and SHA2 - ---- - gss-genr.c | 10 ++++++++++ - kex.c | 2 ++ - kex.h | 2 ++ - kexgssc.c | 6 ++++++ - kexgsss.c | 6 ++++++ - monitor.c | 2 ++ - regress/kextype.sh | 4 +++- - regress/rekey.sh | 8 ++++++-- - ssh-gss.h | 2 ++ - ssh_config.5 | 4 +++- - sshconnect2.c | 2 ++ - sshd.c | 2 ++ - sshd_config.5 | 4 +++- - 13 files changed, 49 insertions(+), 5 deletions(-) - -diff --git a/gss-genr.c b/gss-genr.c -index dc63682d..c6eff3d7 100644 ---- a/gss-genr.c -+++ b/gss-genr.c -@@ -183,6 +183,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { - return GSS_C_NO_OID; - name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; - break; -+ case KEX_GSS_GRP14_SHA256: -+ if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1; -+ break; -+ case KEX_GSS_GRP16_SHA512: -+ if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1; -+ break; - case KEX_GSS_GEX_SHA1: - if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) - return GSS_C_NO_OID; -diff --git a/kex.c b/kex.c -index 63e028fa..e798fecb 100644 ---- a/kex.c -+++ b/kex.c -@@ -112,6 +112,8 @@ static const struct kexalg kexalgs[] = { - { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, - #endif - { NULL, -1, -1, -1}, - }; -diff --git a/kex.h b/kex.h -index 8a2b37c5..f27958ae 100644 ---- a/kex.h -+++ b/kex.h -@@ -102,6 +102,8 @@ enum kex_exchange { - #ifdef GSSAPI - KEX_GSS_GRP1_SHA1, - KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GRP14_SHA256, -+ KEX_GSS_GRP16_SHA512, - KEX_GSS_GEX_SHA1, - #endif - KEX_MAX -diff --git a/kexgssc.c b/kexgssc.c -index 132df8b5..ed23f06d 100644 ---- a/kexgssc.c -+++ b/kexgssc.c -@@ -88,8 +88,12 @@ kexgss_client(struct ssh *ssh) { - dh = dh_new_group1(); - break; - case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: - dh = dh_new_group14(); - break; -+ case KEX_GSS_GRP16_SHA512: -+ dh = dh_new_group16(); -+ break; - case KEX_GSS_GEX_SHA1: - debug("Doing group exchange\n"); - nbits = dh_estimate(ssh->kex->we_need * 8); -@@ -272,6 +276,8 @@ kexgss_client(struct ssh *ssh) { - switch (ssh->kex->kex_type) { - case KEX_GSS_GRP1_SHA1: - case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: - kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, - ssh->kex->server_version_string, - sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), -diff --git a/kexgsss.c b/kexgsss.c -index 82a715cc..b7da8823 100644 ---- a/kexgsss.c -+++ b/kexgsss.c -@@ -104,8 +104,12 @@ kexgss_server(struct ssh *ssh) - dh = dh_new_group1(); - break; - case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: - dh = dh_new_group14(); - break; -+ case KEX_GSS_GRP16_SHA512: -+ dh = dh_new_group16(); -+ break; - case KEX_GSS_GEX_SHA1: - debug("Doing group exchange"); - packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); -@@ -223,6 +227,8 @@ kexgss_server(struct ssh *ssh) - switch (ssh->kex->kex_type) { - case KEX_GSS_GRP1_SHA1: - case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: - kex_dh_hash(ssh->kex->hash_alg, - ssh->kex->client_version_string, ssh->kex->server_version_string, - sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), -diff --git a/monitor.c b/monitor.c -index 17046936..d6bc7ac7 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -1648,6 +1648,8 @@ monitor_apply_keystate(struct monitor *pmonitor) - if (options.gss_keyex) { - kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; - kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; - } - #endif -diff --git a/regress/kextype.sh b/regress/kextype.sh -index 780362ca..45f4f16d 100644 ---- a/regress/kextype.sh -+++ b/regress/kextype.sh -@@ -14,7 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy - - tries="1 2 3 4" - for k in `${SSH} -Q kex`; do -- if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o $k = "gss-group14-sha1-" ]; then -+ if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ -+ $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ -+ $k = "gss-group16-sha512-" ]; then - continue - fi - verbose "kex $k" -diff --git a/regress/rekey.sh b/regress/rekey.sh -index 9fbe9b38..a2921bef 100644 ---- a/regress/rekey.sh -+++ b/regress/rekey.sh -@@ -38,7 +38,9 @@ increase_datafile_size 300 - - opts="" - for i in `${SSH} -Q kex`; do -- if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o $i = "gss-group14-sha1-" ]; then -+ if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ -+ $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ -+ $i = "gss-group16-sha512-" ]; then - continue - fi - opts="$opts KexAlgorithms=$i" -@@ -59,7 +61,9 @@ done - if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then - for c in `${SSH} -Q cipher-auth`; do - for kex in `${SSH} -Q kex`; do -- if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o $kex = "gss-group14-sha1-" ]; then -+ if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ -+ $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ -+ $kex = "gss-group16-sha512-" ]; then - continue - fi - verbose "client rekey $c $kex" -diff --git a/ssh-gss.h b/ssh-gss.h -index 6b6adb2b..7bf8d75e 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -70,6 +70,8 @@ - #define SSH2_MSG_KEXGSS_GROUP 41 - #define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" - #define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" -+#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" -+#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" - #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" - - #define GSS_KEX_DEFAULT_KEX \ -diff --git a/ssh_config.5 b/ssh_config.5 -index 6b24649e..3d6da510 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -760,7 +760,9 @@ key exchange. Possible values are - .Bd -literal -offset 3n - gss-gex-sha1-, - gss-group1-sha1-, --gss-group14-sha1- -+gss-group14-sha1-, -+gss-group14-sha256-, -+gss-group16-sha512- - .Ed - .Pp - The default is -diff --git a/sshconnect2.c b/sshconnect2.c -index 8db98293..5d6b8be0 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -253,6 +253,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - if (options.gss_keyex) { - kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; - kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; - } - #endif -diff --git a/sshd.c b/sshd.c -index 895df26f..e4c879a2 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2244,6 +2244,8 @@ do_ssh2_kex(void) - if (options.gss_keyex) { - kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; - kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; - } - #endif -diff --git a/sshd_config.5 b/sshd_config.5 -index bf81f6af..0793418b 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -675,7 +675,9 @@ key exchange. Possible values are - .Bd -literal -offset 3n - gss-gex-sha1-, - gss-group1-sha1-, --gss-group14-sha1- -+gss-group14-sha1-, -+gss-group14-sha256-, -+gss-group16-sha512- - .Ed - .Pp - The default is --- -2.13.5 - - -From 7d56144903fc625c33da7fabf103f4f6bba4d43a Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 29 Aug 2017 15:32:14 +0200 -Subject: [PATCH 2/3] GSSAPI Key exchange using ECDH and SHA2 - ---- - gss-genr.c | 10 ++ - kex.c | 3 + - kex.h | 4 + - kexgssc.c | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - kexgsss.c | 333 +++++++++++++++++++++++++++++++++++++++++++++ - monitor.c | 5 +- - regress/kextype.sh | 1 + - regress/rekey.sh | 2 + - ssh-gss.h | 2 + - ssh_config.5 | 4 +- - sshconnect2.c | 2 + - sshd.c | 2 + - sshd_config.5 | 4 +- - 13 files changed, 754 insertions(+), 10 deletions(-) - -diff --git a/gss-genr.c b/gss-genr.c -index c6eff3d7..22040244 100644 ---- a/gss-genr.c -+++ b/gss-genr.c -@@ -198,6 +198,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { - return GSS_C_NO_OID; - name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; - break; -+ case KEX_GSS_NISTP256_SHA256: -+ if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1; -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1; -+ break; - default: - return GSS_C_NO_OID; - } -diff --git a/kex.c b/kex.c -index e798fecb..bdeeada9 100644 ---- a/kex.c -+++ b/kex.c -@@ -114,6 +114,9 @@ static const struct kexalg kexalgs[] = { - { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - #endif - { NULL, -1, -1, -1}, - }; -diff --git a/kex.h b/kex.h -index f27958ae..7def8561 100644 ---- a/kex.h -+++ b/kex.h -@@ -105,6 +105,8 @@ enum kex_exchange { - KEX_GSS_GRP14_SHA256, - KEX_GSS_GRP16_SHA512, - KEX_GSS_GEX_SHA1, -+ KEX_GSS_NISTP256_SHA256, -+ KEX_GSS_C25519_SHA256, - #endif - KEX_MAX - }; -@@ -211,6 +213,8 @@ int kexecdh_server(struct ssh *); - int kexc25519_client(struct ssh *); - int kexc25519_server(struct ssh *); - #ifdef GSSAPI -+int kexecgss_client(struct ssh *); -+int kexecgss_server(struct ssh *); - int kexgss_client(struct ssh *); - int kexgss_server(struct ssh *); - #endif -diff --git a/kexgssc.c b/kexgssc.c -index ed23f06d..bdb3109a 100644 ---- a/kexgssc.c -+++ b/kexgssc.c -@@ -43,6 +43,7 @@ - #include "packet.h" - #include "dh.h" - #include "digest.h" -+#include "ssherr.h" - - #include "ssh-gss.h" - -@@ -52,7 +53,7 @@ kexgss_client(struct ssh *ssh) { - gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; - Gssctxt *ctxt; - OM_uint32 maj_status, min_status, ret_flags; -- u_int klen, kout, slen = 0, strlen; -+ u_int klen, kout, slen = 0, packet_len; - DH *dh; - BIGNUM *dh_server_pub = NULL; - BIGNUM *shared_secret = NULL; -@@ -201,20 +202,20 @@ kexgss_client(struct ssh *ssh) { - debug("Received GSSAPI_CONTINUE"); - if (maj_status == GSS_S_COMPLETE) - fatal("GSSAPI Continue received from server when complete"); -- recv_tok.value = packet_get_string(&strlen); -- recv_tok.length = strlen; -+ recv_tok.value = packet_get_string(&packet_len); -+ recv_tok.length = packet_len; - break; - case SSH2_MSG_KEXGSS_COMPLETE: - debug("Received GSSAPI_COMPLETE"); - packet_get_bignum2(dh_server_pub); -- msg_tok.value = packet_get_string(&strlen); -- msg_tok.length = strlen; -+ msg_tok.value = packet_get_string(&packet_len); -+ msg_tok.length = packet_len; - - /* Is there a token included? */ - if (packet_get_char()) { - recv_tok.value= -- packet_get_string(&strlen); -- recv_tok.length = strlen; -+ packet_get_string(&packet_len); -+ recv_tok.length = packet_len; - /* If we're already complete - protocol error */ - if (maj_status == GSS_S_COMPLETE) - packet_disconnect("Protocol error: received token when complete"); -@@ -344,4 +345,382 @@ kexgss_client(struct ssh *ssh) { - return kex_send_newkeys(ssh); - } - -+int -+kexecgss_client(struct ssh *ssh) { -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; -+ Gssctxt *ctxt; -+ OM_uint32 maj_status, min_status, ret_flags; -+ u_int klen = 0, slen = 0, packet_len; -+ u_char *server_pub = NULL; -+ u_int server_pub_len = 0; -+ BIGNUM *shared_secret = NULL; -+ u_char *kbuf = NULL; -+ u_char *serverhostkey = NULL; -+ u_char *empty = ""; -+ char *msg; -+ char *lang; -+ int type = 0; -+ int first = 1; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ const EC_GROUP *group = NULL; -+ const EC_POINT *public_key; -+ struct sshbuf *Q_C = NULL; -+ struct kex *kex = ssh->kex; -+ EC_POINT *server_public = NULL; -+ struct sshbuf *c25519_shared_secret = NULL; -+ int r; -+ -+ /* Initialise our GSSAPI world */ -+ ssh_gssapi_build_ctx(&ctxt); -+ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) -+ == GSS_C_NO_OID) -+ fatal("Couldn't identify host exchange"); -+ -+ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) -+ fatal("Couldn't import hostname"); -+ -+ if (kex->gss_client && -+ ssh_gssapi_client_identity(ctxt, kex->gss_client)) -+ fatal("Couldn't acquire client credentials"); -+ -+ if ((Q_C = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if ((kex->ec_client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (EC_KEY_generate_key(kex->ec_client_key) != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ group = EC_KEY_get0_group(kex->ec_client_key); -+ public_key = EC_KEY_get0_public_key(kex->ec_client_key); -+#ifdef DEBUG_KEXECDH -+ fputs("client private key:\n", stderr); -+ sshkey_dump_ec_key(kex->ec_client_key); -+#endif -+ -+ sshbuf_put_ec(Q_C, public_key, group); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey); -+#ifdef DEBUG_KEXECDH -+ dump_digest("client private key:", kex->c25519_client_key, -+ sizeof(kex->c25519_client_key)); -+#endif -+ -+ if ((r = sshbuf_put_string(Q_C, kex->c25519_client_pubkey, -+ sizeof(kex->c25519_client_pubkey))) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ token_ptr = GSS_C_NO_BUFFER; -+ -+ do { -+ /* Step 2 - call GSS_Init_sec_context() */ -+ debug("Calling gss_init_sec_context"); -+ -+ maj_status = ssh_gssapi_init_ctx(ctxt, -+ kex->gss_deleg_creds, token_ptr, &send_tok, -+ &ret_flags); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length != 0) { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ } -+ fatal("gss_init_context failed"); -+ } -+ -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ free(recv_tok.value); -+ -+ if (maj_status == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); -+ -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } -+ -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (first) { -+ const u_char * ptr; -+ size_t len; -+ -+ packet_start(SSH2_MSG_KEXGSS_INIT); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ sshbuf_get_string_direct(Q_C, &ptr, &len); -+ packet_put_string(ptr, len); -+ first = 0; -+ } else { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ } -+ packet_send(); -+ gss_release_buffer(&min_status, &send_tok); -+ -+ /* If we've sent them data, they should reply */ -+ do { -+ type = packet_read(); -+ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ debug("Received KEXGSS_HOSTKEY"); -+ if (serverhostkey) -+ fatal("Server host key received more than once"); -+ serverhostkey = -+ packet_get_string(&slen); -+ } -+ } while (type == SSH2_MSG_KEXGSS_HOSTKEY); -+ -+ switch (type) { -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ debug("Received GSSAPI_CONTINUE"); -+ if (maj_status == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ recv_tok.value = packet_get_string(&packet_len); -+ recv_tok.length = packet_len; -+ break; -+ case SSH2_MSG_KEXGSS_COMPLETE: -+ debug("Received GSSAPI_COMPLETE"); -+ server_pub = packet_get_string(&server_pub_len); -+ msg_tok.value = packet_get_string(&packet_len); -+ msg_tok.length = packet_len; -+ -+ /* Is there a token included? */ -+ if (packet_get_char()) { -+ recv_tok.value= -+ packet_get_string(&packet_len); -+ recv_tok.length = packet_len; -+ /* If we're already complete - protocol error */ -+ if (maj_status == GSS_S_COMPLETE) -+ packet_disconnect("Protocol error: received token when complete"); -+ } else { -+ /* No token included */ -+ if (maj_status != GSS_S_COMPLETE) -+ packet_disconnect("Protocol error: did not receive final token"); -+ } -+ break; -+ case SSH2_MSG_KEXGSS_ERROR: -+ debug("Received Error"); -+ maj_status = packet_get_int(); -+ min_status = packet_get_int(); -+ msg = packet_get_string(NULL); -+ lang = packet_get_string(NULL); -+ fatal("GSSAPI Error: \n%.400s",msg); -+ default: -+ packet_disconnect("Protocol error: didn't expect packet type %d", -+ type); -+ } -+ token_ptr = &recv_tok; -+ } else { -+ /* No data, and not complete */ -+ if (maj_status != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ /* -+ * We _must_ have received a COMPLETE message in reply from the -+ * server, which will have set dh_server_pub and msg_tok -+ */ -+ -+ if (type != SSH2_MSG_KEXGSS_COMPLETE) -+ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -+ -+ /* 7. C verifies that the key Q_S is valid */ -+ /* 8. C computes shared secret */ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if (server_pub_len != 65) -+ fatal("The received NIST-P256 key did not match" -+ "expected length (expected 65, got %d)", server_pub_len); -+ -+ if (server_pub[0] != POINT_CONVERSION_UNCOMPRESSED) -+ fatal("The received NIST-P256 key does not have first octet 0x04"); -+ -+ if ((server_public = EC_POINT_new(group)) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (!EC_POINT_oct2point(group, server_public, server_pub, -+ server_pub_len, NULL)) -+ fatal("Can not decode received NIST-P256 client key"); -+#ifdef DEBUG_KEXECDH -+ fputs("server public key:\n", stderr); -+ sshkey_dump_ec_point(group, server_public); -+#endif -+ -+ if (sshkey_ec_validate_public(group, server_public) != 0) { -+ sshpkt_disconnect(ssh, "invalid client public key"); -+ r = SSH_ERR_MESSAGE_INCOMPLETE; -+ goto out; -+ } -+ -+ if (!EC_POINT_is_on_curve(group, server_public, NULL)) -+ fatal("Received NIST-P256 client key is not on curve"); -+ -+ /* Calculate shared_secret */ -+ klen = (EC_GROUP_get_degree(group) + 7) / 8; -+ if ((kbuf = malloc(klen)) == NULL || -+ (shared_secret = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (ECDH_compute_key(kbuf, klen, server_public, -+ kex->ec_client_key, NULL) != (int)klen || -+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+#ifdef DEBUG_KEXECDH -+ dump_digest("shared secret", kbuf, klen); -+#endif -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if (server_pub_len != 32) -+ fatal("The received curve25519 key did not match" -+ "expected length (expected 32, got %d)", server_pub_len); -+ -+ if (server_pub[server_pub_len-1] & 0x80) -+ fatal("The received key has MSB of last octet set!"); -+#ifdef DEBUG_KEXECDH -+ dump_digest("server public key:", server_pub, CURVE25519_SIZE); -+#endif -+ -+ /* generate shared secret */ -+ if ((c25519_shared_secret = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if ((r = kexc25519_shared_key(kex->c25519_client_key, -+ server_pub, c25519_shared_secret)) < 0) -+ goto out; -+ -+ /* if all octets of the shared secret are zero octets, -+ * is already checked in kexc25519_shared_key() */ -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ hashlen = sizeof(hash); -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ kex_ecdh_hash( -+ kex->hash_alg, -+ group, -+ kex->client_version_string, -+ kex->server_version_string, -+ sshbuf_ptr(kex->my), sshbuf_len(kex->my), -+ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), -+ (serverhostkey ? serverhostkey : empty), slen, -+ EC_KEY_get0_public_key(kex->ec_client_key), -+ server_public, -+ shared_secret, -+ hash, &hashlen -+ ); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ kex_c25519_hash( -+ kex->hash_alg, -+ kex->client_version_string, kex->server_version_string, -+ sshbuf_ptr(kex->my), sshbuf_len(kex->my), -+ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), -+ (serverhostkey ? serverhostkey : empty), slen, -+ kex->c25519_client_pubkey, server_pub, -+ sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), -+ hash, &hashlen -+ ); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ /* Verify that the hash matches the MIC we just got. */ -+ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) -+ packet_disconnect("Hash's MIC didn't verify"); -+ -+ free(msg_tok.value); -+ -+ /* save session id */ -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); -+ } -+ -+ if (kex->gss_deleg_creds) -+ ssh_gssapi_credentials_updated(ctxt); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ /* Finally derive the keys and send them */ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0) -+ goto out; -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0) -+ goto out; -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ r = kex_send_newkeys(ssh); -+out: -+ free(serverhostkey); -+ explicit_bzero(hash, sizeof(hash)); -+ sshbuf_free(Q_C); -+ if (server_pub) -+ free(server_pub); -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if (kex->ec_client_key) { -+ EC_KEY_free(kex->ec_client_key); -+ kex->ec_client_key = NULL; -+ } -+ if (server_public) -+ EC_POINT_clear_free(server_public); -+ if (kbuf) { -+ explicit_bzero(kbuf, klen); -+ free(kbuf); -+ } -+ if (shared_secret) -+ BN_clear_free(shared_secret); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); -+ sshbuf_free(c25519_shared_secret); -+ break; -+ } -+ return r; -+} - #endif /* GSSAPI */ -diff --git a/kexgsss.c b/kexgsss.c -index b7da8823..a7c42803 100644 ---- a/kexgsss.c -+++ b/kexgsss.c -@@ -46,6 +46,7 @@ - #include "servconf.h" - #include "ssh-gss.h" - #include "digest.h" -+#include "ssherr.h" - - extern ServerOptions options; - -@@ -303,4 +304,338 @@ kexgss_server(struct ssh *ssh) - ssh_gssapi_rekey_creds(); - return 0; - } -+ -+int -+kexecgss_server(struct ssh *ssh) -+{ -+ OM_uint32 maj_status, min_status; -+ -+ /* -+ * Some GSSAPI implementations use the input value of ret_flags (an -+ * output variable) as a means of triggering mechanism specific -+ * features. Initializing it to zero avoids inadvertently -+ * activating this non-standard behaviour. -+ */ -+ -+ OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf, recv_tok, msg_tok; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ Gssctxt *ctxt = NULL; -+ u_int slen, klen = 0; -+ u_char *kbuf = NULL; -+ BIGNUM *shared_secret = NULL; -+ int type = 0; -+ gss_OID oid; -+ char *mechs; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ u_char *client_pub = NULL; -+ u_int client_pub_len = 0; -+ const EC_GROUP *group = NULL; -+ EC_POINT *client_public = NULL; -+ EC_KEY *server_key = NULL; -+ const EC_POINT *public_key; -+ u_char c25519_server_key[CURVE25519_SIZE]; -+ u_char c25519_server_pubkey[CURVE25519_SIZE]; -+ struct sshbuf *c25519_shared_secret = NULL; -+ struct sshbuf *Q_S; -+ struct kex *kex = ssh->kex; -+ int r; -+ -+ /* Initialise GSSAPI */ -+ -+ /* If we're rekeying, privsep means that some of the private structures -+ * in the GSSAPI code are no longer available. This kludges them back -+ * into life -+ */ -+ if (!ssh_gssapi_oid_table_ok()) -+ if ((mechs = ssh_gssapi_server_mechanisms())) -+ free(mechs); -+ -+ debug2("%s: Identifying %s", __func__, kex->name); -+ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); -+ if (oid == GSS_C_NO_OID) -+ fatal("Unknown gssapi mechanism"); -+ -+ debug2("%s: Acquiring credentials", __func__); -+ -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) -+ fatal("Unable to acquire credentials for the server"); -+ -+ if ((Q_S = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ /* 5. S generates an ephemeral key pair (do the allocations early) */ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ 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) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ group = EC_KEY_get0_group(server_key); -+ public_key = EC_KEY_get0_public_key(server_key); -+ -+ sshbuf_put_ec(Q_S, public_key, group); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ kexc25519_keygen(c25519_server_key, c25519_server_pubkey); -+#ifdef DEBUG_KEXECDH -+ dump_digest("server private key:", c25519_server_key, -+ sizeof(c25519_server_key)); -+#endif -+ if ((r = sshbuf_put_string(Q_S, c25519_server_pubkey, -+ sizeof(c25519_server_pubkey))) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ do { -+ debug("Wait SSH2_MSG_GSSAPI_INIT"); -+ type = packet_read(); -+ switch(type) { -+ case SSH2_MSG_KEXGSS_INIT: -+ if (client_pub != NULL) -+ fatal("Received KEXGSS_INIT after initialising"); -+ recv_tok.value = packet_get_string(&slen); -+ recv_tok.length = slen; -+ -+ client_pub = packet_get_string(&client_pub_len); -+ -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ break; -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ recv_tok.value = packet_get_string(&slen); -+ recv_tok.length = slen; -+ break; -+ default: -+ packet_disconnect( -+ "Protocol error: didn't expect packet type %d", -+ type); -+ } -+ -+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags)); -+ -+ free(recv_tok.value); -+ -+ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -+ fatal("Zero length token output when incomplete"); -+ -+ if (client_pub == NULL) -+ fatal("No client public key"); -+ -+ if (maj_status & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, send_tok.length); -+ packet_send(); -+ gss_release_buffer(&min_status, &send_tok); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length > 0) { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, send_tok.length); -+ packet_send(); -+ } -+ fatal("accept_ctx died"); -+ } -+ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual Authentication flag wasn't set"); -+ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity flag wasn't set"); -+ -+ /* 3. S verifies that the (client) key is valid */ -+ /* calculate shared secret */ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if (client_pub_len != 65) -+ fatal("The received NIST-P256 key did not match" -+ "expected length (expected 65, got %d)", client_pub_len); -+ -+ if (client_pub[0] != POINT_CONVERSION_UNCOMPRESSED) -+ fatal("The received NIST-P256 key does not have first octet 0x04"); -+ -+ if ((client_public = EC_POINT_new(group)) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (!EC_POINT_oct2point(group, client_public, client_pub, -+ client_pub_len, NULL)) -+ fatal("Can not decode received NIST-P256 client key"); -+ -+ if (sshkey_ec_validate_public(group, client_public) != 0) { -+ sshpkt_disconnect(ssh, "invalid client public key"); -+ r = SSH_ERR_MESSAGE_INCOMPLETE; -+ goto out; -+ } -+ -+ if (!EC_POINT_is_on_curve(group, client_public, NULL)) -+ fatal("Received NIST-P256 client key is not on curve"); -+ -+ /* Calculate shared_secret */ -+ klen = (EC_GROUP_get_degree(group) + 7) / 8; -+ if ((kbuf = malloc(klen)) == NULL || -+ (shared_secret = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (ECDH_compute_key(kbuf, klen, client_public, -+ server_key, NULL) != (int)klen || -+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if (client_pub_len != 32) -+ fatal("The received curve25519 key did not match" -+ "expected length (expected 32, got %d)", client_pub_len); -+ -+ if (client_pub[client_pub_len-1] & 0x80) -+ fatal("The received key has MSB of last octet set!"); -+ -+ /* generate shared secret */ -+ if ((c25519_shared_secret = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if ((r = kexc25519_shared_key(c25519_server_key, -+ client_pub, c25519_shared_secret)) < 0) -+ goto out; -+ -+ /* if all octets of the shared secret are zero octets, -+ * is already checked in kexc25519_shared_key() */ -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ hashlen = sizeof(hash); -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ kex_ecdh_hash( -+ kex->hash_alg, -+ group, -+ kex->client_version_string, -+ kex->server_version_string, -+ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), -+ sshbuf_ptr(kex->my), sshbuf_len(kex->my), -+ NULL, 0, -+ client_public, -+ EC_KEY_get0_public_key(server_key), -+ shared_secret, -+ hash, &hashlen -+ ); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ kex_c25519_hash( -+ kex->hash_alg, -+ kex->client_version_string, kex->server_version_string, -+ sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), -+ sshbuf_ptr(kex->my), sshbuf_len(kex->my), -+ NULL, 0, -+ client_pub, c25519_server_pubkey, -+ sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret), -+ hash, &hashlen -+ ); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); -+ } -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) -+ fatal("Couldn't get MIC"); -+ -+ packet_start(SSH2_MSG_KEXGSS_COMPLETE); -+ { -+ const u_char *ptr; -+ size_t len; -+ if ((r = sshbuf_get_string_direct(Q_S, &ptr, &len)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ packet_put_string(ptr, len); -+ } -+ packet_put_string(msg_tok.value, msg_tok.length); -+ -+ if (send_tok.length != 0) { -+ packet_put_char(1); /* true */ -+ packet_put_string(send_tok.value, send_tok.length); -+ } else { -+ packet_put_char(0); /* false */ -+ } -+ packet_send(); -+ -+ gss_release_buffer(&min_status, &send_tok); -+ gss_release_buffer(&min_status, &msg_tok); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ /* Finally derive the keys and send them */ -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0) -+ goto out; -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0) -+ goto out; -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); -+ } -+ if ((r = kex_send_newkeys(ssh)) != 0) -+ goto out; -+ -+ /* If this was a rekey, then save out any delegated credentials we -+ * just exchanged. */ -+ if (options.gss_store_rekey) -+ ssh_gssapi_rekey_creds(); -+out: -+ explicit_bzero(hash, sizeof(hash)); -+ if (Q_S) -+ sshbuf_free(Q_S); -+ if (client_pub) -+ free(client_pub); -+ switch (kex->kex_type) { -+ case KEX_GSS_NISTP256_SHA256: -+ if (server_key) -+ EC_KEY_free(server_key); -+ if (kbuf) { -+ explicit_bzero(kbuf, klen); -+ free(kbuf); -+ } -+ if (shared_secret) -+ BN_clear_free(shared_secret); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ explicit_bzero(c25519_server_key, sizeof(c25519_server_key)); -+ sshbuf_free(c25519_shared_secret); -+ break; -+ } -+ return r; -+} - #endif /* GSSAPI */ -diff --git a/monitor.c b/monitor.c -index d6bc7ac7..b11616c8 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -1651,6 +1651,8 @@ monitor_apply_keystate(struct monitor *pmonitor) - kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; - kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server; - } - #endif - kex->load_host_public_key=&get_hostkey_public_by_type; -@@ -1867,7 +1869,8 @@ mm_answer_gss_sign(int socket, Buffer *m) - - if ((r = sshbuf_get_string(m, (u_char **)&data.value, &data.length)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -- if (data.length != 20) -+ /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ -+ if (data.length != 20 && data.length != 32 && data.length != 64) - fatal("%s: data length incorrect: %d", __func__, - (int) data.length); - -diff --git a/regress/kextype.sh b/regress/kextype.sh -index 45f4f16d..d5b4a713 100644 ---- a/regress/kextype.sh -+++ b/regress/kextype.sh -@@ -15,6 +15,7 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy - tries="1 2 3 4" - for k in `${SSH} -Q kex`; do - if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ -+ $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \ - $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ - $k = "gss-group16-sha512-" ]; then - continue -diff --git a/regress/rekey.sh b/regress/rekey.sh -index a2921bef..b118c6c8 100644 ---- a/regress/rekey.sh -+++ b/regress/rekey.sh -@@ -39,6 +39,7 @@ increase_datafile_size 300 - opts="" - for i in `${SSH} -Q kex`; do - if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ -+ $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \ - $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ - $i = "gss-group16-sha512-" ]; then - continue -@@ -62,6 +63,7 @@ if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then - for c in `${SSH} -Q cipher-auth`; do - for kex in `${SSH} -Q kex`; do - if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ -+ $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \ - $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ - $kex = "gss-group16-sha512-" ]; then - continue -diff --git a/ssh-gss.h b/ssh-gss.h -index 7bf8d75e..1f73721d 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -73,6 +73,8 @@ - #define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" - #define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" - #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" -+#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" -+#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" - - #define GSS_KEX_DEFAULT_KEX \ - KEX_GSS_GEX_SHA1_ID "," \ -diff --git a/ssh_config.5 b/ssh_config.5 -index 3d6da510..1dc29bf1 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -762,7 +762,9 @@ gss-gex-sha1-, - gss-group1-sha1-, - gss-group14-sha1-, - gss-group14-sha256-, --gss-group16-sha512- -+gss-group16-sha512-, -+gss-nistp256-sha256-, -+gss-curve25519-sha256- - .Ed - .Pp - The default is -diff --git a/sshconnect2.c b/sshconnect2.c -index 5d6b8be0..280ae5a6 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -256,6 +256,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) - kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; - kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_client; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_client; - } - #endif - kex->kex[KEX_C25519_SHA256] = kexc25519_client; -diff --git a/sshd.c b/sshd.c -index e4c879a2..a35735d8 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2247,6 +2247,8 @@ do_ssh2_kex(void) - kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; - kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; - kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server; - } - #endif - kex->server = 1; -diff --git a/sshd_config.5 b/sshd_config.5 -index 0793418b..888316bf 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -677,7 +677,9 @@ gss-gex-sha1-, - gss-group1-sha1-, - gss-group14-sha1-, - gss-group14-sha256-, --gss-group16-sha512- -+gss-group16-sha512-, -+gss-nistp256-sha256-, -+gss-curve25519-sha256- - .Ed - .Pp - The default is --- -2.13.5 - - -From 0431695660d5eb1dd1169d42a1624c75a92aa5d2 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 30 Aug 2017 15:30:51 +0200 -Subject: [PATCH 3/3] Simplify rough edges of GSSAPI Kex - ---- - gss-genr.c | 53 +++++++++++++++++------------------------------------ - regress/kextype.sh | 10 ++++------ - regress/rekey.sh | 20 ++++++++------------ - 3 files changed, 29 insertions(+), 54 deletions(-) - -diff --git a/gss-genr.c b/gss-genr.c -index 22040244..c671be31 100644 ---- a/gss-genr.c -+++ b/gss-genr.c -@@ -171,47 +171,28 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, - gss_OID - ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { - int i = 0; -- -- switch (kex_type) { -- case KEX_GSS_GRP1_SHA1: -- if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; -- break; -- case KEX_GSS_GRP14_SHA1: -- if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; -- break; -- case KEX_GSS_GRP14_SHA256: -- if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1; -- break; -- case KEX_GSS_GRP16_SHA512: -- if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1; -- break; -- case KEX_GSS_GEX_SHA1: -- if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; -- break; -- case KEX_GSS_NISTP256_SHA256: -- if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1; -- break; -- case KEX_GSS_C25519_SHA256: -- if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID)) -- return GSS_C_NO_OID; -- name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1; -+ -+#define SKIP_KEX_NAME(type) \ -+ case type: \ -+ if (strlen(name) < sizeof(type##_ID)) \ -+ return GSS_C_NO_OID; \ -+ name += sizeof(type##_ID) - 1; \ - break; -+ -+ switch (kex_type) { -+ SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1) -+ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1) -+ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256) -+ SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512) -+ SKIP_KEX_NAME(KEX_GSS_GEX_SHA1) -+ SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256) -+ SKIP_KEX_NAME(KEX_GSS_C25519_SHA256) - default: - return GSS_C_NO_OID; - } - -+#undef SKIP_KEX_NAME -+ - while (gss_enc2oid[i].encoded != NULL && - strcmp(name, gss_enc2oid[i].encoded) != 0) - i++; -diff --git a/regress/kextype.sh b/regress/kextype.sh -index d5b4a713..6b4af28a 100644 ---- a/regress/kextype.sh -+++ b/regress/kextype.sh -@@ -14,12 +14,10 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy - - tries="1 2 3 4" - for k in `${SSH} -Q kex`; do -- if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \ -- $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \ -- $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \ -- $k = "gss-group16-sha512-" ]; then -- continue -- fi -+ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) -+ case $k in -+ gss-* ) continue ;; -+ esac - verbose "kex $k" - for i in $tries; do - ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff --git a/regress/rekey.sh b/regress/rekey.sh -index b118c6c8..d6a8742f 100644 ---- a/regress/rekey.sh -+++ b/regress/rekey.sh -@@ -38,12 +38,10 @@ increase_datafile_size 300 - - opts="" - for i in `${SSH} -Q kex`; do -- if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \ -- $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \ -- $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \ -- $i = "gss-group16-sha512-" ]; then -- continue -- fi -+ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) -+ case $i in -+ gss-* ) continue ;; -+ esac - opts="$opts KexAlgorithms=$i" - done - for i in `${SSH} -Q cipher`; do -@@ -62,12 +60,10 @@ done - if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then - for c in `${SSH} -Q cipher-auth`; do - for kex in `${SSH} -Q kex`; do -- if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \ -- $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \ -- $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \ -- $kex = "gss-group16-sha512-" ]; then -- continue -- fi -+ # ignore GSSAPI key exchange mechanisms (all of them start with gss-) -+ case $kex in -+ gss-* ) continue ;; -+ esac - verbose "client rekey $c $kex" - ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c - done --- -2.13.5 - diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index feb170f..01e509e 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,83 +1,80 @@ -diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c ---- openssh-7.6p1/audit-bsm.c.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/audit-bsm.c 2017-10-04 17:18:32.834505048 +0200 -@@ -373,10 +373,23 @@ audit_connection_from(const char *host, +diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c +--- openssh/audit-bsm.c.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/audit-bsm.c 2019-04-03 17:02:20.713886041 +0200 +@@ -372,13 +372,26 @@ audit_connection_from(const char *host, #endif } --void +int - audit_run_command(const char *command) - { - /* not implemented */ ++audit_run_command(struct ssh *ssh, const char *command) ++{ ++ /* not implemented */ + return 0; +} + -+void -+audit_end_command(int handle, const char *command) -+{ -+ /* not implemented */ -+} -+ -+void -+audit_count_session_open(void) -+{ -+ /* not necessary */ + void +-audit_run_command(const char *command) ++audit_end_command(struct ssh *ssh, int handle, const char *command) + { + /* not implemented */ } void -@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li ++audit_count_session_open(void) ++{ ++ /* not necessary */ ++} ++ ++void + audit_session_open(struct logininfo *li) + { + /* not implemented */ +@@ -390,6 +403,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } +int -+audit_keyusage(int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) +{ + /* not implemented */ +} + void - audit_event(ssh_audit_event_t event) + audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -452,4 +471,34 @@ audit_event(ssh_audit_event_t event) +@@ -451,4 +470,28 @@ audit_event(struct ssh *ssh, ssh_audit_e debug("%s: unhandled event %d", __func__, event); } } + +void -+audit_unsupported_body(int what) ++audit_unsupported_body(struct ssh *ssh, int what) +{ + /* not implemented */ +} + +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) +{ + /* not implemented */ +} + +void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++audit_session_key_free_body(struct ssh * ssh, int ctos, pid_t pid, uid_t uid) +{ + /* not implemented */ +} + +void -+audit_destroy_sensitive_data(const char *fp) -+{ -+ /* not implemented */ -+} -+ -+void -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) +{ + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c ---- openssh-7.6p1/audit.c.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/audit.c 2017-10-04 17:18:32.834505048 +0200 -@@ -34,6 +35,12 @@ +diff -up openssh/audit.c.audit openssh/audit.c +--- openssh/audit.c.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/audit.c 2019-04-03 17:02:20.713886041 +0200 +@@ -34,6 +34,12 @@ #include "log.h" #include "hostfile.h" #include "auth.h" @@ -119,38 +116,38 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c } +void -+audit_key(int host_user, int *rv, const struct sshkey *key) ++audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) +{ + char *fp; + + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (audit_keyusage(host_user, fp, (*rv == 0)) == 0) ++ if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) + *rv = -SSH_ERR_INTERNAL_ERROR; + free(fp); +} + +void -+audit_unsupported(int what) ++audit_unsupported(struct ssh *ssh, int what) +{ -+ PRIVSEP(audit_unsupported_body(what)); ++ PRIVSEP(audit_unsupported_body(ssh, what)); +} + +void -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) ++audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) +{ -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); ++ PRIVSEP(audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid())); +} + +void -+audit_session_key_free(int ctos) ++audit_session_key_free(struct ssh *ssh, int ctos) +{ -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); ++ PRIVSEP(audit_session_key_free_body(ssh, ctos, getpid(), getuid())); +} + # ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. -@@ -138,6 +173,17 @@ audit_event(ssh_audit_event_t event) +@@ -138,6 +171,17 @@ audit_event(struct ssh *ssh, ssh_audit_e } /* @@ -168,7 +165,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c * Called when a user session is started. Argument is the tty allocated to * the session, or NULL if no tty was allocated. * -@@ -172,13 +218,82 @@ audit_session_close(struct logininfo *li +@@ -172,13 +216,82 @@ audit_session_close(struct logininfo *li /* * This will be called when a user runs a non-interactive command. Note that * it may be called multiple times for a single connection since SSH2 allows @@ -177,8 +174,9 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * audit_end_command. */ -void +-audit_run_command(const char *command) +int - audit_run_command(const char *command) ++audit_run_command(struct ssh *ssh, const char *command) { debug("audit run command euid %d user %s command '%.200s'", geteuid(), audit_username(), command); @@ -192,7 +190,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * the corresponding audit_run_command. + */ +void -+audit_end_command(int handle, const char *command) ++audit_end_command(struct ssh *ssh, int handle, const char *command) +{ + debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); @@ -204,7 +202,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. + */ +int -+audit_keyusage(int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) +{ + debug("audit %s key usage euid %d user %s fingerprint %s, result %d", + host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), @@ -215,7 +213,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * This will be called when the protocol negotiation fails. + */ +void -+audit_unsupported_body(int what) ++audit_unsupported_body(struct ssh *ssh, int what) +{ + debug("audit unsupported protocol euid %d type %d", geteuid(), what); +} @@ -224,7 +222,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * This will be called on succesfull protocol negotiation. + */ +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, + uid_t uid) +{ + debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", @@ -236,7 +234,7 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * This will be called on succesfull session key discard + */ +void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++audit_session_key_free_body(struct ssh *, int ctos, pid_t pid, uid_t uid) +{ + debug("audit session key discard euid %u direction %d from pid %ld uid %u", + (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); @@ -246,25 +244,25 @@ diff -up openssh-7.6p1/audit.c.audit openssh-7.6p1/audit.c + * This will be called on destroy private part of the server key + */ +void -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) +{ + debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", + geteuid(), fp, (long)pid, (unsigned)uid); } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h ---- openssh-7.6p1/audit.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/audit.h 2017-10-04 17:18:32.834505048 +0200 +diff -up openssh/audit.h.audit openssh/audit.h +--- openssh/audit.h.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/audit.h 2019-04-03 17:02:20.713886041 +0200 @@ -26,6 +26,7 @@ # define _SSH_AUDIT_H #include "loginrec.h" +#include "sshkey.h" - enum ssh_audit_event_type { - SSH_LOGIN_EXCEED_MAXTRIES, -@@ -43,13 +44,32 @@ enum ssh_audit_event_type { + struct ssh; + +@@ -45,13 +46,32 @@ enum ssh_audit_event_type { SSH_CONNECTION_ABANDON, /* closed without completing auth */ SSH_AUDIT_UNKNOWN }; @@ -279,28 +277,28 @@ diff -up openssh-7.6p1/audit.h.audit openssh-7.6p1/audit.h +int listening_for_clients(void); + void audit_connection_from(const char *, int); - void audit_event(ssh_audit_event_t); + void audit_event(struct ssh *, ssh_audit_event_t); +void audit_count_session_open(void); void audit_session_open(struct logininfo *); void audit_session_close(struct logininfo *); -void audit_run_command(const char *); -+int audit_run_command(const char *); -+void audit_end_command(int, const char *); ++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(int, char *, int); -+void audit_key(int, int *, const struct sshkey *); -+void audit_unsupported(int); -+void audit_kex(int, char *, char *, char *, char *); -+void audit_unsupported_body(int); -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); -+void audit_session_key_free(int ctos); -+void audit_session_key_free_body(int ctos, pid_t, uid_t); -+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); ++int audit_keyusage(struct ssh *, int, 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 *); ++void audit_unsupported_body(struct ssh *, int); ++void audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(struct ssh *, int ctos); ++void audit_session_key_free_body(struct ssh *, int ctos, pid_t, uid_t); ++void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); #endif /* _SSH_AUDIT_H */ -diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c ---- openssh-7.6p1/audit-linux.c.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/audit-linux.c 2017-10-04 17:18:32.835505053 +0200 +diff -up openssh/audit-linux.c.audit openssh/audit-linux.c +--- openssh/audit-linux.c.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/audit-linux.c 2019-04-03 17:02:20.713886041 +0200 @@ -33,27 +33,40 @@ #include "log.h" @@ -414,7 +412,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +} + +int -+audit_keyusage(int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) +{ + char buf[AUDIT_LOG_SIZE]; + int audit_fd, rc, saved_errno; @@ -429,12 +427,12 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + } + 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(active_state), NULL, rv); ++ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; + snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp); + rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL, -+ ssh_remote_ipaddr(active_state), NULL, rv); ++ ssh_remote_ipaddr(ssh), NULL, rv); +out: + saved_errno = errno; + audit_close(audit_fd); @@ -448,34 +446,34 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c /* Below is the sshd audit API code */ void -@@ -76,24 +177,55 @@ audit_connection_from(const char *host, +@@ -76,49 +176,210 @@ audit_connection_from(const char *host, /* not implemented */ } --void +int - audit_run_command(const char *command) - { -- /* not implemented */ ++audit_run_command(struct ssh *ssh, const char *command) ++{ + if (!user_login_count++) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ ssh_remote_ipaddr(active_state), ++ ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_LOGIN); + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ ssh_remote_ipaddr(active_state), ++ ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_START); + return 0; +} + -+void -+audit_end_command(int handle, const char *command) -+{ + void +-audit_run_command(const char *command) ++audit_end_command(struct ssh *ssh, int handle, const char *command) + { +- /* not implemented */ + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ ssh_remote_ipaddr(active_state), ++ 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, -+ ssh_remote_ipaddr(active_state), ++ ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_LOGOUT); +} + @@ -510,9 +508,8 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c } void -@@ -102,25 +231,155 @@ audit_event(ssh_audit_event_t event) - struct ssh *ssh = active_state; /* XXX */ - + audit_event(struct ssh *ssh, ssh_audit_event_t event) + { switch(event) { - case SSH_AUTH_SUCCESS: - case SSH_CONNECTION_CLOSE: @@ -563,7 +560,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c } + +void -+audit_unsupported_body(int what) ++audit_unsupported_body(struct ssh *ssh, int what) +{ +#ifdef AUDIT_CRYPTO_SESSION + char buf[AUDIT_LOG_SIZE]; @@ -572,15 +569,15 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + int audit_fd; + + snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ", -+ name[what], ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), -+ ssh_local_port(active_state)); ++ name[what], ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ++ ssh_local_port(ssh)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) + /* no problem, the next instruction will be fatal() */ + return; + audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 0); ++ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 0); + audit_close(audit_fd); +#endif +} @@ -588,7 +585,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +const static char *direction[] = { "from-server", "from-client", "both" }; + +void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, + char *pfs, pid_t pid, uid_t uid) +{ +#ifdef AUDIT_CRYPTO_SESSION @@ -600,7 +597,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", + direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, + (intmax_t)pid, (intmax_t)uid, -+ ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ssh_local_port(active_state)); ++ ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ssh_local_port(ssh)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) { @@ -611,7 +608,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + fatal("cannot open audit"); /* Must prevent login */ + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 1); ++ buf, 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 */ + if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) @@ -620,7 +617,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +} + +void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ + char buf[AUDIT_LOG_SIZE]; + int audit_fd, audit_ok; @@ -628,9 +625,9 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + + snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", + direction[ctos], (intmax_t)pid, (intmax_t)uid, -+ ssh_remote_port(active_state), -+ (s = get_local_ipaddr(packet_get_connection_in())), -+ ssh_local_port(active_state)); ++ ssh_remote_port(ssh), ++ (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ++ ssh_local_port(ssh)); + free(s); + audit_fd = audit_open(); + if (audit_fd < 0) { @@ -640,7 +637,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + return; + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, ssh_remote_ipaddr(active_state), NULL, 1); ++ buf, 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 */ + if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) @@ -648,7 +645,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +} + +void -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) +{ + char buf[AUDIT_LOG_SIZE]; + int audit_fd, audit_ok; @@ -664,7 +661,7 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.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(active_state), ++ 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 */ @@ -672,10 +669,10 @@ diff -up openssh-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-7.6p1/auditstub.c.audit openssh-7.6p1/auditstub.c ---- openssh-7.6p1/auditstub.c.audit 2017-10-04 17:18:32.835505053 +0200 -+++ openssh-7.6p1/auditstub.c 2017-10-04 17:18:32.835505053 +0200 -@@ -0,0 +1,50 @@ +diff -up openssh/auditstub.c.audit openssh/auditstub.c +--- openssh/auditstub.c.audit 2019-04-03 17:02:20.714886050 +0200 ++++ openssh/auditstub.c 2019-04-03 17:02:20.714886050 +0200 +@@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + +/* @@ -707,95 +704,97 @@ diff -up openssh-7.6p1/auditstub.c.audit openssh-7.6p1/auditstub.c + +#include + ++struct ssh; ++ +void -+audit_unsupported(int n) ++audit_unsupported(struct ssh *ssh, int n) +{ +} + +void -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) ++audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) +{ +} + +void -+audit_session_key_free(int ctos) ++audit_session_key_free(struct ssh *ssh, int ctos) +{ +} + +void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-7.6p1/auth2.c.audit openssh-7.6p1/auth2.c ---- openssh-7.6p1/auth2.c.audit 2017-10-04 17:18:32.746504598 +0200 -+++ openssh-7.6p1/auth2.c 2017-10-04 17:18:32.835505053 +0200 -@@ -255,9 +255,6 @@ input_userauth_request(int type, u_int32 +diff -up openssh/auth2.c.audit openssh/auth2.c +--- openssh/auth2.c.audit 2019-04-03 17:02:20.651885453 +0200 ++++ openssh/auth2.c 2019-04-03 17:02:20.714886050 +0200 +@@ -303,9 +303,6 @@ input_userauth_request(int type, u_int32 } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS -- PRIVSEP(audit_event(SSH_INVALID_USER)); +- PRIVSEP(audit_event(ssh, SSH_INVALID_USER)); -#endif } #ifdef USE_PAM if (options.use_pam) -diff -up openssh-7.6p1/auth2-hostbased.c.audit openssh-7.6p1/auth2-hostbased.c ---- openssh-7.6p1/auth2-hostbased.c.audit 2017-10-04 17:18:32.683504276 +0200 -+++ openssh-7.6p1/auth2-hostbased.c 2017-10-04 17:18:32.835505053 +0200 -@@ -152,7 +152,7 @@ userauth_hostbased(struct ssh *ssh) - /* test for allowed key and correct signature */ +diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c +--- openssh/auth2-hostbased.c.audit 2019-04-03 17:02:20.612885083 +0200 ++++ openssh/auth2-hostbased.c 2019-04-03 17:02:20.714886050 +0200 +@@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh) authenticated = 0; - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && + if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, + chost, key)) && - PRIVSEP(sshkey_verify(key, sig, slen, -+ PRIVSEP(hostbased_key_verify(key, sig, slen, ++ PRIVSEP(hostbased_key_verify(ssh, key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0) authenticated = 1; -@@ -169,6 +169,19 @@ done: +@@ -175,6 +175,19 @@ done: return authenticated; } +int -+hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, -+ const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++hostbased_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, ++ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + int rv; + + rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); +#ifdef SSH_AUDIT_EVENTS -+ audit_key(0, &rv, key); ++ audit_key(ssh, 0, &rv, key); +#endif + return rv; +} + /* return 1 if given hostkey is allowed */ int - hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, -diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c ---- openssh-7.6p1/auth2-pubkey.c.audit 2017-10-04 17:18:32.828505018 +0200 -+++ openssh-7.6p1/auth2-pubkey.c 2017-10-04 17:18:32.835505053 +0200 -@@ -206,7 +206,7 @@ userauth_pubkey(struct ssh *ssh) + hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, +diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.audit 2019-04-03 17:02:20.691885832 +0200 ++++ openssh/auth2-pubkey.c 2019-04-03 17:02:20.714886050 +0200 +@@ -219,7 +219,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(key, sig, slen, ++ PRIVSEP(user_key_verify(ssh, key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat)) == 0) { -@@ -250,6 +250,19 @@ done: +@@ -278,6 +278,19 @@ done: return authenticated; } +int -+user_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, -+ const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++user_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, ++ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + int rv; + + rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); +#ifdef SSH_AUDIT_EVENTS -+ audit_key(1, &rv, key); ++ audit_key(ssh, 1, &rv, key); +#endif + return rv; +} @@ -803,52 +802,52 @@ diff -up openssh-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { -diff -up openssh-7.6p1/auth.c.audit openssh-7.6p1/auth.c ---- openssh-7.6p1/auth.c.audit 2017-10-04 17:18:32.746504598 +0200 -+++ openssh-7.6p1/auth.c 2017-10-04 17:18:32.835505053 +0200 -@@ -360,7 +360,7 @@ auth_log(Authctxt *authctxt, int authent +diff -up openssh/auth.c.audit openssh/auth.c +--- openssh/auth.c.audit 2019-04-03 17:02:20.691885832 +0200 ++++ openssh/auth.c 2019-04-03 17:02:20.714886050 +0200 +@@ -366,7 +366,7 @@ auth_log(struct ssh *ssh, int authentica # endif #endif #ifdef SSH_AUDIT_EVENTS - if (authenticated == 0 && !authctxt->postponed) + if (authenticated == 0 && !authctxt->postponed && !partial) - audit_event(audit_classify_auth(method)); + audit_event(ssh, audit_classify_auth(method)); #endif } -@@ -599,9 +599,6 @@ getpwnamallow(const char *user) - record_failed_login(user, +@@ -592,9 +592,6 @@ getpwnamallow(struct ssh *ssh, const cha + record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif -#ifdef SSH_AUDIT_EVENTS -- audit_event(SSH_INVALID_USER); +- audit_event(ssh, SSH_INVALID_USER); -#endif /* SSH_AUDIT_EVENTS */ return (NULL); } - if (!allowed_user(pw)) -diff -up openssh-7.6p1/auth.h.audit openssh-7.6p1/auth.h ---- openssh-7.6p1/auth.h.audit 2017-10-04 17:18:32.768504711 +0200 -+++ openssh-7.6p1/auth.h 2017-10-04 17:18:32.836505059 +0200 -@@ -198,6 +198,8 @@ struct passwd * getpwnamallow(const char + if (!allowed_user(ssh, pw)) +diff -up openssh/auth.h.audit openssh/auth.h +--- openssh/auth.h.audit 2019-04-03 17:02:20.692885842 +0200 ++++ openssh/auth.h 2019-04-03 17:02:20.714886050 +0200 +@@ -195,6 +195,8 @@ struct passwd * getpwnamallow(struct ssh char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); -+int user_key_verify(const struct sshkey *, const u_char *, size_t, ++int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, + const u_char *, size_t, const char *, u_int); FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -217,6 +218,8 @@ struct sshkey *get_hostkey_private_by_ty +@@ -214,6 +216,8 @@ struct sshkey *get_hostkey_private_by_ty int get_hostkey_index(struct sshkey *, int, struct ssh *); - int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, - size_t *, const u_char *, size_t, const char *, u_int); -+int hostbased_key_verify(const struct sshkey *, const u_char *, size_t, + int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, + u_char **, size_t *, const u_char *, size_t, const char *); ++int hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, + const u_char *, size_t, const char *, u_int); /* Key / cert options linkage to auth layer */ const struct sshauthopt *auth_options(struct ssh *); -diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c ---- openssh-7.6p1/cipher.c.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/cipher.c 2017-10-04 17:18:32.836505059 +0200 +diff -up openssh/cipher.c.audit openssh/cipher.c +--- openssh/cipher.c.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/cipher.c 2019-04-03 17:02:20.714886050 +0200 @@ -61,25 +61,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -875,7 +874,7 @@ diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -409,7 +409,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -410,7 +391,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) { @@ -884,9 +883,9 @@ diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); -diff -up openssh-7.6p1/cipher.h.audit openssh-7.6p1/cipher.h ---- openssh-7.6p1/cipher.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/cipher.h 2017-10-04 17:18:32.836505059 +0200 +diff -up openssh/cipher.h.audit openssh/cipher.h +--- openssh/cipher.h.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/cipher.h 2019-04-03 17:02:20.714886050 +0200 @@ -45,7 +45,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -914,10 +913,10 @@ diff -up openssh-7.6p1/cipher.h.audit openssh-7.6p1/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh-7.6p1/kex.c.audit openssh-7.6p1/kex.c ---- openssh-7.6p1/kex.c.audit 2017-10-04 17:18:32.822504987 +0200 -+++ openssh-7.6p1/kex.c 2017-10-04 17:18:32.836505059 +0200 -@@ -54,6 +54,7 @@ +diff -up openssh/kex.c.audit openssh/kex.c +--- openssh/kex.c.audit 2019-04-03 17:02:20.652885462 +0200 ++++ openssh/kex.c 2019-04-03 17:02:20.715886060 +0200 +@@ -60,6 +60,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -925,64 +924,91 @@ diff -up openssh-7.6p1/kex.c.audit openssh-7.6p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -692,8 +693,12 @@ choose_enc(struct sshenc *enc, char *cli +@@ -758,12 +759,16 @@ kex_start_rekex(struct ssh *ssh) + } + + static int +-choose_enc(struct sshenc *enc, char *client, char *server) ++choose_enc(struct ssh *ssh, struct sshenc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(SSH_AUDIT_UNSUPPORTED_CIPHER); ++ audit_unsupported(ssh, SSH_AUDIT_UNSUPPORTED_CIPHER); +#endif return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) { free(name); return SSH_ERR_INTERNAL_ERROR; -@@ -713,8 +718,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(SSH_AUDIT_UNSUPPORTED_MAC); ++ audit_unsupported(ssh, SSH_AUDIT_UNSUPPORTED_MAC); +#endif return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) { free(name); return SSH_ERR_INTERNAL_ERROR; -@@ -733,8 +742,12 @@ choose_comp(struct sshcomp *comp, char * +@@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma + } + + static int +-choose_comp(struct sshcomp *comp, char *client, char *server) ++choose_comp(struct ssh *ssh, struct sshcomp *comp, char *client, char *server) { char *name = match_list(client, server, NULL); - if (name == NULL) + if (name == NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_unsupported(SSH_AUDIT_UNSUPPORTED_COMPRESSION); ++ audit_unsupported(ssh, SSH_AUDIT_UNSUPPORTED_COMPRESSION); +#endif return SSH_ERR_NO_COMPRESS_ALG_MATCH; + } if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { -@@ -904,6 +917,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -933,7 +946,7 @@ kex_choose_conf(struct ssh *ssh) + nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; + nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; + ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; +- if ((r = choose_enc(&newkeys->enc, cprop[nenc], ++ if ((r = choose_enc(ssh, &newkeys->enc, cprop[nenc], + sprop[nenc])) != 0) { + kex->failed_choice = peer[nenc]; + peer[nenc] = NULL; +@@ -948,7 +961,7 @@ kex_choose_conf(struct ssh *ssh) + peer[nmac] = NULL; + goto out; + } +- if ((r = choose_comp(&newkeys->comp, cprop[ncomp], ++ if ((r = choose_comp(ssh, &newkeys->comp, cprop[ncomp], + sprop[ncomp])) != 0) { + kex->failed_choice = peer[ncomp]; + peer[ncomp] = NULL; +@@ -971,6 +984,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); + debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); +#ifdef SSH_AUDIT_EVENTS -+ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); ++ audit_kex(ssh, mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); +#endif } /* XXX need runden? */ kex->we_need = need; -@@ -1037,3 +1054,33 @@ dump_digest(char *msg, u_char *digest, i - sshbuf_dump_data(digest, len, stderr); +@@ -1129,6 +1146,36 @@ dump_digest(const char *msg, const u_cha } #endif -+ + +static void +enc_destroy(struct sshenc *enc) +{ @@ -1012,22 +1038,26 @@ diff -up openssh-7.6p1/kex.c.audit openssh-7.6p1/kex.c + mac_destroy(&newkeys->mac); + memset(&newkeys->comp, 0, sizeof(newkeys->comp)); +} -diff -up openssh-7.6p1/kex.h.audit openssh-7.6p1/kex.h ---- openssh-7.6p1/kex.h.audit 2017-10-04 17:18:32.822504987 +0200 -+++ openssh-7.6p1/kex.h 2017-10-04 17:18:32.836505059 +0200 -@@ -219,6 +219,8 @@ int kexgss_client(struct ssh *); ++ + /* + * Send a plaintext error message to the peer, suffixed by \r\n. + * Only used during banner exchange, and there only for the server. +diff -up openssh/kex.h.audit openssh/kex.h +--- openssh/kex.h.audit 2019-04-03 17:02:20.652885462 +0200 ++++ openssh/kex.h 2019-04-03 17:02:20.715886060 +0200 +@@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif +void newkeys_destroy(struct newkeys *newkeys); + - int kex_dh_hash(int, const char *, const char *, - const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, - const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -diff -up openssh-7.6p1/mac.c.audit openssh-7.6p1/mac.c ---- openssh-7.6p1/mac.c.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/mac.c 2017-10-04 17:18:32.836505059 +0200 -@@ -242,6 +242,20 @@ mac_clear(struct sshmac *mac) + int kex_dh_keypair(struct kex *); + int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, + struct sshbuf **); +diff -up openssh/mac.c.audit openssh/mac.c +--- openssh/mac.c.audit 2019-04-03 17:02:20.652885462 +0200 ++++ openssh/mac.c 2019-04-03 17:02:20.715886060 +0200 +@@ -243,6 +243,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1048,9 +1078,9 @@ diff -up openssh-7.6p1/mac.c.audit openssh-7.6p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-7.6p1/mac.h.audit openssh-7.6p1/mac.h ---- openssh-7.6p1/mac.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/mac.h 2017-10-04 17:18:32.837505064 +0200 +diff -up openssh/mac.h.audit openssh/mac.h +--- openssh/mac.h.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/mac.h 2019-04-03 17:02:20.715886060 +0200 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1058,23 +1088,23 @@ diff -up openssh-7.6p1/mac.h.audit openssh-7.6p1/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-7.6p1/Makefile.in.audit openssh-7.6p1/Makefile.in ---- openssh-7.6p1/Makefile.in.audit 2017-10-04 17:18:32.749504614 +0200 -+++ openssh-7.6p1/Makefile.in 2017-10-04 17:18:32.837505064 +0200 -@@ -100,7 +100,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ - kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ +diff -up openssh/Makefile.in.audit openssh/Makefile.in +--- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 ++++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 +@@ -109,7 +109,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kexgexc.o kexgexs.o \ + sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexgssc.o \ - platform-pledge.o platform-tracing.o platform-misc.o + platform-pledge.o platform-tracing.o platform-misc.o \ + auditstub.o + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect2.o mux.o -diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c ---- openssh-7.6p1/monitor.c.audit 2017-10-04 17:18:32.824504997 +0200 -+++ openssh-7.6p1/monitor.c 2017-10-04 17:18:32.837505064 +0200 -@@ -102,6 +102,7 @@ +diff -up openssh/monitor.c.audit openssh/monitor.c +--- openssh/monitor.c.audit 2019-04-03 17:02:20.674885671 +0200 ++++ openssh/monitor.c 2019-04-03 17:03:17.201421405 +0200 +@@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" #include "authfd.h" @@ -1082,28 +1112,28 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #include "match.h" #include "ssherr.h" -@@ -117,6 +118,8 @@ extern Buffer auth_debug; +@@ -107,6 +108,8 @@ extern u_char session_id[]; extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ -+extern void destroy_sensitive_data(int); ++extern void destroy_sensitive_data(struct ssh *, int); + /* State exported from the child */ static struct sshbuf *child_state; -@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe +@@ -157,6 +160,11 @@ int mm_answer_gss_updatecreds(struct ssh #ifdef SSH_AUDIT_EVENTS - int mm_answer_audit_event(int, struct sshbuf *); - int mm_answer_audit_command(int, struct sshbuf *); -+int mm_answer_audit_end_command(int, struct sshbuf *); -+int mm_answer_audit_unsupported_body(int, struct sshbuf *); -+int mm_answer_audit_kex_body(int, struct sshbuf *); -+int mm_answer_audit_session_key_free_body(int, struct sshbuf *); -+int mm_answer_audit_server_key_free(int, struct sshbuf *); + int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); + int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); ++int mm_answer_audit_end_command(struct ssh *, int, struct sshbuf *); ++int mm_answer_audit_unsupported_body(struct ssh *, int, struct sshbuf *); ++int mm_answer_audit_kex_body(struct ssh *, int, struct sshbuf *); ++int mm_answer_audit_session_key_free_body(struct ssh *, int, struct sshbuf *); ++int mm_answer_audit_server_key_free(struct ssh *, int, struct sshbuf *); #endif - static int monitor_read_log(struct monitor *); -@@ -222,6 +230,10 @@ struct mon_table mon_dispatch_proto20[] + static Authctxt *authctxt; +@@ -215,6 +223,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1114,7 +1144,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -260,6 +272,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20 #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1126,7 +1156,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -1396,8 +1413,10 @@ mm_answer_keyverify(int sock, struct ssh +@@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int char *sigalg; size_t signaturelen, datalen, bloblen; int r, ret, valid_data = 0, encoded_ret; @@ -1138,7 +1168,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1405,6 +1424,8 @@ mm_answer_keyverify(int sock, struct ssh +@@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); @@ -1147,18 +1177,18 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1414,21 +1435,24 @@ mm_answer_keyverify(int sock, struct ssh +@@ -1470,21 +1491,24 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: valid_data = monitor_valid_userblob(data, datalen); auth_method = "publickey"; -+ ret = user_key_verify(key, signature, signaturelen, data, -+ datalen, sigalg, active_state->compat); ++ ret = user_key_verify(ssh, key, signature, signaturelen, data, ++ datalen, sigalg, ssh->compat); break; case MM_HOSTKEY: valid_data = monitor_valid_hostbasedblob(data, datalen, hostbased_cuser, hostbased_chost); -+ ret = hostbased_key_verify(key, signature, signaturelen, data, -+ datalen, sigalg, active_state->compat); ++ ret = hostbased_key_verify(ssh, key, signature, signaturelen, data, ++ datalen, sigalg, ssh->compat); auth_method = "hostbased"; break; default: @@ -1170,33 +1200,59 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c fatal("%s: bad signature data blob", __func__); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, -- sigalg, active_state->compat); +- sigalg, ssh->compat); debug3("%s: %s %p signature %s", __func__, auth_method, key, (ret == 0) ? "verified" : "unverified"); auth2_record_key(authctxt, ret == 0, key); -@@ -1485,6 +1509,12 @@ mm_session_close(Session *s) +@@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session + } + + static void +-mm_session_close(Session *s) ++mm_session_close(struct ssh *ssh, Session *s) + { + debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); + if (s->ttyfd != -1) { debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } +#ifdef SSH_AUDIT_EVENTS + if (s->command != NULL) { + debug3("%s: command %d", __func__, s->command_handle); -+ session_end_command2(s); ++ session_end_command2(ssh, s); + } +#endif session_unused(s->self); } -@@ -1588,6 +1618,8 @@ mm_answer_term(int sock, Buffer *req) +@@ -1609,7 +1639,7 @@ mm_answer_pty(struct ssh *ssh, int sock, + + error: + if (s != NULL) +- mm_session_close(s); ++ mm_session_close(ssh, s); + if ((r = sshbuf_put_u32(m, 0)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + mm_request_send(sock, MONITOR_ANS_PTY, m); +@@ -1628,7 +1658,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i + if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if ((s = session_by_tty(tty)) != NULL) +- mm_session_close(s); ++ mm_session_close(ssh, s); + sshbuf_reset(m); + free(tty); + return (0); +@@ -1650,6 +1680,8 @@ mm_answer_term(struct ssh *ssh, int sock sshpam_cleanup(); #endif -+ destroy_sensitive_data(0); ++ destroy_sensitive_data(ssh, 0); + while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1630,12 +1662,47 @@ mm_answer_audit_command(int socket, Buff +@@ -1696,12 +1728,47 @@ mm_answer_audit_command(struct ssh *ssh, { char *cmd; int r; @@ -1213,7 +1269,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + fatal("%s: error allocating a session", __func__); + s->command = cmd; +#ifdef SSH_AUDIT_EVENTS -+ s->command_handle = audit_run_command(cmd); ++ s->command_handle = audit_run_command(ssh, cmd); +#endif + + sshbuf_reset(m); @@ -1225,7 +1281,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +} + +int -+mm_answer_audit_end_command(int socket, struct sshbuf *m) ++mm_answer_audit_end_command(struct ssh *ssh, int socket, struct sshbuf *m) +{ + int handle, r; + size_t len; @@ -1241,19 +1297,19 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + if (s == NULL || s->ttyfd != -1 || s->command == NULL || + strcmp(s->command, cmd) != 0) + fatal("%s: invalid handle", __func__); -+ mm_session_close(s); ++ mm_session_close(ssh, s); free(cmd); return (0); } -@@ -1702,6 +1768,7 @@ monitor_apply_keystate(struct monitor *p +@@ -1767,6 +1834,7 @@ monitor_apply_keystate(struct ssh *ssh, void - mm_get_keystate(struct monitor *pmonitor) + mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { + struct sshbuf *m; debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) -@@ -1709,6 +1776,19 @@ mm_get_keystate(struct monitor *pmonitor +@@ -1774,6 +1842,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); @@ -1262,7 +1318,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + m = sshbuf_new(); + mm_request_receive_expect(pmonitor->m_sendfd, + MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, m); ++ mm_answer_audit_session_key_free_body(ssh, pmonitor->m_sendfd, m); + sshbuf_free(m); +#endif + @@ -1273,20 +1329,20 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c } -@@ -1976,3 +2056,102 @@ mm_answer_gss_updatecreds(int socket, Bu +@@ -2066,3 +2147,102 @@ mm_answer_gss_updatecreds(struct ssh *ss #endif /* GSSAPI */ +#ifdef SSH_AUDIT_EVENTS +int -+mm_answer_audit_unsupported_body(int sock, struct sshbuf *m) ++mm_answer_audit_unsupported_body(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int what, r; + + if ((r = sshbuf_get_u32(m, &what)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + -+ audit_unsupported_body(what); ++ audit_unsupported_body(ssh, what); + + sshbuf_reset(m); + @@ -1295,7 +1351,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +} + +int -+mm_answer_audit_kex_body(int sock, struct sshbuf *m) ++mm_answer_audit_kex_body(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int ctos, r; + char *cipher, *mac, *compress, *pfs; @@ -1315,7 +1371,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (pid_t) tmp; + -+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); ++ audit_kex_body(ssh, ctos, cipher, mac, compress, pfs, pid, uid); + + free(cipher); + free(mac); @@ -1328,7 +1384,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +} + +int -+mm_answer_audit_session_key_free_body(int sock, struct sshbuf *m) ++mm_answer_audit_session_key_free_body(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int ctos, r; + u_int64_t tmp; @@ -1343,7 +1399,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (uid_t) tmp; + -+ audit_session_key_free_body(ctos, pid, uid); ++ audit_session_key_free_body(ssh, ctos, pid, uid); + + sshbuf_reset(m); + @@ -1352,7 +1408,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +} + +int -+mm_answer_audit_server_key_free(int sock, struct sshbuf *m) ++mm_answer_audit_server_key_free(struct ssh *ssh, int sock, struct sshbuf *m) +{ + size_t len, r; + char *fp; @@ -1368,7 +1424,7 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (uid_t) tmp; + -+ audit_destroy_sensitive_data(fp, pid, uid); ++ audit_destroy_sensitive_data(ssh, fp, pid, uid); + + free(fp); + sshbuf_reset(m); @@ -1376,10 +1432,10 @@ diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.6p1/monitor.h.audit openssh-7.6p1/monitor.h ---- openssh-7.6p1/monitor.h.audit 2017-10-04 17:18:32.781504777 +0200 -+++ openssh-7.6p1/monitor.h 2017-10-04 17:18:32.837505064 +0200 -@@ -69,7 +69,13 @@ enum monitor_reqtype { +diff -up openssh/monitor.h.audit openssh/monitor.h +--- openssh/monitor.h.audit 2019-04-03 17:02:20.674885671 +0200 ++++ openssh/monitor.h 2019-04-03 17:02:20.715886060 +0200 +@@ -65,7 +65,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, @@ -1390,14 +1446,14 @@ diff -up openssh-7.6p1/monitor.h.audit openssh-7.6p1/monitor.h + MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, + MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, + MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124 ++ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, - }; - -diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c ---- openssh-7.6p1/monitor_wrap.c.audit 2017-10-04 17:18:32.750504619 +0200 -+++ openssh-7.6p1/monitor_wrap.c 2017-10-04 17:18:32.838505069 +0200 -@@ -463,7 +463,7 @@ mm_key_allowed(enum mm_keytype type, con + MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, + MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, +diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.audit 2019-04-03 17:02:20.653885472 +0200 ++++ openssh/monitor_wrap.c 2019-04-03 17:02:20.716886069 +0200 +@@ -513,7 +513,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1406,7 +1462,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat) { struct sshbuf *m; -@@ -478,7 +478,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -1416,34 +1472,35 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -497,6 +498,20 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -547,6 +548,20 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } +int -+mm_hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++mm_hostbased_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, size_t siglen, + const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, pkalg, compat); +} + +int -+mm_user_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++mm_user_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, size_t siglen, + const u_char *data, size_t datalen, const char *pkalg, u_int compat) +{ + return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, pkalg, compat); +} + void - mm_send_keystate(struct monitor *monitor) + mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -874,11 +889,12 @@ mm_audit_event(ssh_audit_event_t event) +@@ -900,11 +915,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi sshbuf_free(m); } -void +-mm_audit_run_command(const char *command) +int - mm_audit_run_command(const char *command) ++mm_audit_run_command(struct ssh *ssh, const char *command) { struct sshbuf *m; int r; @@ -1451,7 +1508,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -885,6 +901,30 @@ mm_audit_run_command(const char *command +@@ -914,6 +930,30 @@ mm_audit_run_command(const char *command fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); @@ -1465,7 +1522,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +} + +void -+mm_audit_end_command(int handle, const char *command) ++mm_audit_end_command(struct ssh *ssh, int handle, const char *command) +{ + int r; + struct sshbuf *m; @@ -1482,13 +1539,13 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1020,3 +1056,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc - return (ok); +@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc } + #endif /* GSSAPI */ +#ifdef SSH_AUDIT_EVENTS +void -+mm_audit_unsupported_body(int what) ++mm_audit_unsupported_body(struct ssh *ssh, int what) +{ + int r; + struct sshbuf *m; @@ -1506,7 +1563,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +} + +void -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, ++mm_audit_kex_body(struct ssh *ssh, int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, + uid_t uid) +{ + int r; @@ -1531,7 +1588,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +} + +void -+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++mm_audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ + int r; + struct sshbuf *m; @@ -1550,7 +1607,7 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +} + +void -+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) +{ + int r; + struct sshbuf *m; @@ -1566,38 +1623,38 @@ diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.6p1/monitor_wrap.h.audit openssh-7.6p1/monitor_wrap.h ---- openssh-7.6p1/monitor_wrap.h.audit 2017-10-04 17:18:32.750504619 +0200 -+++ openssh-7.6p1/monitor_wrap.h 2017-10-04 17:18:32.838505069 +0200 -@@ -53,7 +53,9 @@ int mm_key_allowed(enum mm_keytype, cons +diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.audit 2019-04-03 17:02:20.653885472 +0200 ++++ openssh/monitor_wrap.h 2019-04-03 17:02:20.716886069 +0200 +@@ -57,7 +57,9 @@ int mm_user_key_allowed(struct ssh *, st struct sshauthopt **); - int mm_hostbased_key_allowed(struct passwd *, const char *, + int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); -int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, -+int mm_hostbased_key_verify(const struct sshkey *, const u_char *, size_t, ++int mm_hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, + const u_char *, size_t, const char *, u_int); -+int mm_user_key_verify(const struct sshkey *, const u_char *, size_t, ++int mm_user_key_verify(struct ssh*, const struct sshkey *, const u_char *, size_t, const u_char *, size_t, const char *, u_int); #ifdef GSSAPI -@@ -78,7 +80,12 @@ void mm_sshpam_free_ctx(void *); +@@ -82,7 +84,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" - void mm_audit_event(ssh_audit_event_t); + void mm_audit_event(struct ssh *, ssh_audit_event_t); -void mm_audit_run_command(const char *); -+int mm_audit_run_command(const char *); -+void mm_audit_end_command(int, const char *); -+void mm_audit_unsupported_body(int); -+void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); -+void mm_audit_session_key_free_body(int, pid_t, uid_t); -+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); ++int mm_audit_run_command(struct ssh *ssh, const char *); ++void mm_audit_end_command(struct ssh *ssh, int, const char *); ++void mm_audit_unsupported_body(struct ssh *, int); ++void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); ++void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t); ++void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); #endif struct Session; -diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c ---- openssh-7.6p1/packet.c.audit 2017-10-04 17:18:32.672504220 +0200 -+++ openssh-7.6p1/packet.c 2017-10-04 17:25:48.141741390 +0200 -@@ -67,6 +67,7 @@ +diff -up openssh/packet.c.audit openssh/packet.c +--- openssh/packet.c.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/packet.c 2019-04-03 17:02:20.716886069 +0200 +@@ -77,6 +77,7 @@ #include #include "xmalloc.h" @@ -1605,7 +1662,7 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c #include "crc32.h" #include "compat.h" #include "ssh2.h" -@@ -502,6 +503,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1619,7 +1676,7 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -566,22 +574,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -587,22 +595,19 @@ ssh_packet_close_internal(struct ssh *ss { struct session_state *state = ssh->state; u_int mode; @@ -1642,18 +1699,18 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c + state->output = NULL; sshbuf_free(state->outgoing_packet); + state->outgoing_packet = NULL; - sshbuf_free(state->incoming_packet); + sshbuf_free(state->incoming_packet); + state->incoming_packet = NULL; for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -615,8 +616,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -636,8 +641,18 @@ ssh_packet_close_internal(struct ssh *ss } cipher_free(state->send_context); cipher_free(state->receive_context); + if (had_keys && state->server_side) { + /* Assuming this is called only from privsep child */ -+ audit_session_key_free(MODE_MAX); ++ audit_session_key_free(ssh, MODE_MAX); + } state->send_context = state->receive_context = NULL; if (do_close) { @@ -1666,15 +1723,15 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -854,6 +863,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - (unsigned long long)state->p_read.blocks, +@@ -864,6 +879,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); -+ audit_session_key_free(mode); - cipher_free(*ccp); - *ccp = NULL; kex_free_newkeys(state->newkeys[mode]); -@@ -2135,6 +2145,72 @@ ssh_packet_get_output(struct ssh *ssh) ++ audit_session_key_free(ssh, mode); + state->newkeys[mode] = NULL; + } + /* note that both bytes and the seqnr are not reset */ +@@ -2167,6 +2183,71 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1728,18 +1785,17 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c +} + +void -+packet_destroy_all(int audit_it, int privsep) ++packet_destroy_all(struct ssh *ssh, int audit_it, int privsep) +{ + if (audit_it) -+ audit_it = (active_state != NULL && packet_state_has_keys(active_state->state)); -+ if (active_state != NULL) -+ packet_destroy_state(active_state->state); ++ audit_it = packet_state_has_keys(ssh->state); ++ packet_destroy_state(ssh->state); + if (audit_it) { +#ifdef SSH_AUDIT_EVENTS + if (privsep) -+ audit_session_key_free(MODE_MAX); ++ audit_session_key_free(ssh, MODE_MAX); + else -+ audit_session_key_free_body(MODE_MAX, getpid(), getuid()); ++ audit_session_key_free_body(ssh, MODE_MAX, getpid(), getuid()); +#endif + } +} @@ -1747,28 +1803,28 @@ diff -up openssh-7.6p1/packet.c.audit openssh-7.6p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-7.6p1/packet.h.audit openssh-7.6p1/packet.h ---- openssh-7.6p1/packet.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/packet.h 2017-10-04 17:18:32.838505069 +0200 -@@ -217,4 +217,5 @@ extern struct ssh *active_state; +diff -up openssh/packet.h.audit openssh/packet.h +--- openssh/packet.h.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/packet.h 2019-04-03 17:02:20.716886069 +0200 +@@ -217,4 +217,5 @@ const u_char *sshpkt_ptr(struct ssh *, s # undef EC_POINT #endif -+void packet_destroy_all(int, int); ++void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c ---- openssh-7.6p1/session.c.audit 2017-10-04 17:18:32.812504936 +0200 -+++ openssh-7.6p1/session.c 2017-10-04 17:18:32.839505074 +0200 -@@ -138,7 +138,7 @@ extern char *__progname; +diff -up openssh/session.c.audit openssh/session.c +--- openssh/session.c.audit 2019-04-03 17:02:20.712886031 +0200 ++++ openssh/session.c 2019-04-03 17:02:20.716886069 +0200 +@@ -136,7 +136,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; -extern void destroy_sensitive_data(void); -+extern void destroy_sensitive_data(int); ++extern void destroy_sensitive_data(struct ssh *, int); extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; - char *tun_fwd_ifnames; /* serverloop.c */ -@@ -605,6 +605,14 @@ do_exec_pty(struct ssh *ssh, Session *s, + extern char *tun_fwd_ifnames; /* serverloop.c */ +@@ -648,6 +648,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1782,8 +1838,8 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c + /* Enter interactive session. */ s->ptymaster = ptymaster; - packet_set_interactive(1, -@@ -724,15 +732,19 @@ do_exec(struct ssh *ssh, Session *s, con + ssh_packet_set_interactive(ssh, 1, +@@ -740,15 +748,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1801,24 +1857,24 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c + s->command = xstrdup(shell); } + if (s->command != NULL && s->ptyfd == -1) -+ s->command_handle = PRIVSEP(audit_run_command(s->command)); ++ s->command_handle = PRIVSEP(audit_run_command(ssh, s->command)); #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1499,8 +1511,11 @@ do_child(struct ssh *ssh, Session *s, co - } +@@ -1556,8 +1568,11 @@ do_child(struct ssh *ssh, Session *s, co + sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ - destroy_sensitive_data(); -+ destroy_sensitive_data(1); - packet_clear_keys(); ++ 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. */ -+ packet_destroy_all(0, 1); ++ packet_destroy_all(ssh, 0, 1); /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1714,6 +1729,9 @@ session_unused(int id) +@@ -1769,6 +1784,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1828,7 +1884,7 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1796,6 +1814,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1851,6 +1869,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1848,17 +1904,17 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c session_by_tty(char *tty) { int i; -@@ -2307,6 +2338,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2461,6 +2492,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } +#ifdef SSH_AUDIT_EVENTS +void -+session_end_command2(Session *s) ++session_end_command2(struct ssh *ssh, Session *s) +{ + if (s->command != NULL) { + if (s->command_handle != -1) -+ audit_end_command(s->command_handle, s->command); ++ audit_end_command(ssh, s->command_handle, s->command); + free(s->command); + s->command = NULL; + s->command_handle = -1; @@ -1866,11 +1922,11 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c +} + +static void -+session_end_command(Session *s) ++session_end_command(struct ssh *ssh, Session *s) +{ + if (s->command != NULL) { + if (s->command_handle != -1) -+ PRIVSEP(audit_end_command(s->command_handle, s->command)); ++ PRIVSEP(audit_end_command(ssh, s->command_handle, s->command)); + free(s->command); + s->command = NULL; + s->command_handle = -1; @@ -1881,34 +1937,51 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2320,6 +2377,10 @@ session_close(struct ssh *ssh, Session * +@@ -2474,6 +2531,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); +#ifdef SSH_AUDIT_EVENTS + if (s->command) -+ session_end_command(s); ++ session_end_command(ssh, s); +#endif free(s->term); free(s->display); free(s->x11_chanids); -@@ -2528,6 +2589,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2549,14 +2610,14 @@ session_close_by_channel(struct ssh *ssh + } + + void +-session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *)) ++session_destroy_all(struct ssh *ssh, void (*closefunc)(struct ssh *ssh, Session *)) + { + int i; + for (i = 0; i < sessions_nalloc; i++) { + Session *s = &sessions[i]; + if (s->used) { + if (closefunc != NULL) +- closefunc(s); ++ closefunc(ssh, s); + else + session_close(ssh, s); + } +@@ -2683,6 +2744,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } +static void -+do_cleanup_one_session(Session *s) ++do_cleanup_one_session(struct ssh *ssh, Session *s) +{ + session_pty_cleanup2(s); +#ifdef SSH_AUDIT_EVENTS -+ session_end_command2(s); ++ session_end_command2(ssh, s); +#endif +} + void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2585,7 +2655,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2746,7 +2816,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -1917,10 +1990,10 @@ diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-7.6p1/session.h.audit openssh-7.6p1/session.h ---- openssh-7.6p1/session.h.audit 2017-10-02 21:34:26.000000000 +0200 -+++ openssh-7.6p1/session.h 2017-10-04 17:18:32.839505074 +0200 -@@ -60,6 +60,12 @@ struct Session { +diff -up openssh/session.h.audit openssh/session.h +--- openssh/session.h.audit 2019-03-27 23:26:14.000000000 +0100 ++++ openssh/session.h 2019-04-03 17:02:20.717886079 +0200 +@@ -61,6 +61,12 @@ struct Session { char *name; char *val; } *env; @@ -1933,20 +2006,23 @@ diff -up openssh-7.6p1/session.h.audit openssh-7.6p1/session.h }; void do_authenticated(struct ssh *, Authctxt *); -@@ -72,8 +78,10 @@ void session_close_by_pid(struct ssh *s +@@ -71,10 +77,12 @@ void session_unused(int); + int session_input_channel_req(struct ssh *, Channel *, const char *); + void session_close_by_pid(struct ssh *ssh, pid_t, int); void session_close_by_channel(struct ssh *, int, void *); - void session_destroy_all(struct ssh *, void (*)(Session *)); +-void session_destroy_all(struct ssh *, void (*)(Session *)); ++void session_destroy_all(struct ssh *, void (*)(struct ssh*, Session *)); void session_pty_cleanup2(Session *); -+void session_end_command2(Session *); ++void session_end_command2(struct ssh *ssh, Session *); Session *session_new(void); +Session *session_by_id(int); Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c ---- openssh-7.6p1/sshd.c.audit 2017-10-04 17:18:32.830505028 +0200 -+++ openssh-7.6p1/sshd.c 2017-10-04 17:18:32.839505074 +0200 +diff -up openssh/sshd.c.audit openssh/sshd.c +--- openssh/sshd.c.audit 2019-04-03 17:02:20.692885842 +0200 ++++ openssh/sshd.c 2019-04-03 17:02:20.717886079 +0200 @@ -122,6 +122,7 @@ #include "ssh-gss.h" #endif @@ -1955,16 +2031,18 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -248,7 +249,7 @@ Buffer loginmsg; +@@ -261,8 +262,8 @@ struct sshbuf *loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -+void destroy_sensitive_data(int); - void demote_sensitive_data(void); - static void do_ssh2_kex(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 *); -@@ -265,6 +266,15 @@ close_listen_socks(void) + /* +@@ -278,6 +279,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -1980,8 +2058,8 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c static void close_startup_pipes(void) { -@@ -475,18 +485,45 @@ sshd_exchange_identification(struct ssh - } +@@ -380,18 +390,45 @@ grace_alarm_handler(int sig) + ssh_remote_port(the_active_state)); } -/* Destroy the host and server keys. They will no longer be needed. */ @@ -1991,7 +2069,7 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c + */ void -destroy_sensitive_data(void) -+destroy_sensitive_data(int privsep) ++destroy_sensitive_data(struct ssh *ssh, int privsep) { u_int i; +#ifdef SSH_AUDIT_EVENTS @@ -2014,10 +2092,10 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS + if (privsep) -+ PRIVSEP(audit_destroy_sensitive_data(fp, ++ PRIVSEP(audit_destroy_sensitive_data(ssh, fp, + pid, uid)); + else -+ audit_destroy_sensitive_data(fp, ++ audit_destroy_sensitive_data(ssh, fp, + pid, uid); +#endif + free(fp); @@ -2029,7 +2107,13 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -499,16 +536,34 @@ demote_sensitive_data(void) +@@ -400,14 +437,26 @@ destroy_sensitive_data(void) + + /* Demote private to public keys for network child */ + void +-demote_sensitive_data(void) ++demote_sensitive_data(struct ssh *ssh) + { struct sshkey *tmp; u_int i; int r; @@ -2051,20 +2135,38 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c if ((r = sshkey_from_private( sensitive_data.host_keys[i], &tmp)) != 0) fatal("could not demote host %s key: %s", - sshkey_type(sensitive_data.host_keys[i]), +@@ -415,6 +464,12 @@ demote_sensitive_data(void) ssh_err(r)); sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_destroy_sensitive_data(fp, pid, uid); ++ audit_destroy_sensitive_data(ssh, fp, pid, uid); +#endif + free(fp); + } } /* Certs do not need demotion */ } -@@ -587,7 +642,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -442,7 +497,7 @@ reseed_prngs(void) + } + + static void +-privsep_preauth_child(void) ++privsep_preauth_child(struct ssh *ssh) + { + gid_t gidset[1]; + +@@ -457,7 +512,7 @@ privsep_preauth_child(void) + reseed_prngs(); + + /* Demote the private keys to public keys. */ +- demote_sensitive_data(); ++ demote_sensitive_data(ssh); + + #ifdef WITH_SELINUX + sshd_selinux_change_privsep_preauth_context(); +@@ -496,7 +551,7 @@ privsep_preauth(struct ssh *ssh) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2073,28 +2175,64 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -1162,6 +1217,7 @@ server_accept_loop(int *sock_in, int *so +@@ -542,7 +597,7 @@ privsep_preauth(struct ssh *ssh) + /* Arrange for logging to be sent to the monitor */ + set_log_handler(mm_log_handler, pmonitor); + +- privsep_preauth_child(); ++ privsep_preauth_child(ssh); + setproctitle("%s", "[net]"); + if (box != NULL) + ssh_sandbox_child(box); +@@ -594,7 +649,7 @@ privsep_postauth(struct ssh *ssh, Authct + set_log_handler(mm_log_handler, pmonitor); + + /* Demote the private keys to public keys. */ +- demote_sensitive_data(); ++ demote_sensitive_data(ssh); + + reseed_prngs(); + +@@ -1057,7 +1112,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) + { + fd_set *fdset; + int i, j, ret, maxfd; +@@ -1112,6 +1167,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); -+ destroy_sensitive_data(0); ++ destroy_sensitive_data(ssh, 0); close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2165,6 +2221,9 @@ main(int ac, char **av) +@@ -1978,7 +2034,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); + } + +@@ -2222,6 +2278,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ -+ packet_destroy_all(1, 1); -+ destroy_sensitive_data(1); ++ packet_destroy_all(ssh, 1, 1); ++ destroy_sensitive_data(ssh, 1); + - packet_get_bytes(&ibytes, &obytes); + ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2344,6 +2403,15 @@ void +@@ -2401,6 +2460,15 @@ do_ssh2_kex(struct ssh *ssh) + void cleanup_exit(int i) { - struct ssh *ssh = active_state; /* XXX */ + static int in_cleanup = 0; + int is_privsep_child; + @@ -2104,29 +2242,31 @@ diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c + if (in_cleanup) + _exit(i); + in_cleanup = 1; - - if (the_authctxt) { - do_cleanup(ssh, the_authctxt); -@@ -2356,9 +2424,14 @@ cleanup_exit(int i) + if (the_active_state != NULL && the_authctxt != NULL) { + do_cleanup(the_active_state, the_authctxt); + if (use_privsep && privsep_is_preauth && +@@ -2414,9 +2482,16 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } + is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; -+ if (sensitive_data.host_keys != NULL) -+ destroy_sensitive_data(is_privsep_child); -+ packet_destroy_all(1, is_privsep_child); ++ 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); #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ -- if (!use_privsep || mm_is_monitor()) -+ if ((the_authctxt == NULL || !the_authctxt->authenticated) && +- if (the_active_state != NULL && (!use_privsep || mm_is_monitor())) ++ if (the_active_state != NULL && ++ (the_authctxt == NULL || !the_authctxt->authenticated) && + (!use_privsep || mm_is_monitor())) - audit_event(SSH_CONNECTION_ABANDON); + audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c ---- openssh-7.6p1/sshkey.c.audit 2017-10-04 17:18:32.758504660 +0200 -+++ openssh-7.6p1/sshkey.c 2017-10-04 17:18:32.839505074 +0200 -@@ -295,6 +295,38 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh/sshkey.c.audit openssh/sshkey.c +--- openssh/sshkey.c.audit 2019-04-03 17:02:20.657885510 +0200 ++++ openssh/sshkey.c 2019-04-03 17:02:20.718886088 +0200 +@@ -331,6 +331,38 @@ sshkey_type_is_valid_ca(int type) } int @@ -2165,10 +2305,10 @@ diff -up openssh-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh-7.6p1/sshkey.h.audit openssh-7.6p1/sshkey.h ---- openssh-7.6p1/sshkey.h.audit 2017-10-04 17:18:32.758504660 +0200 -+++ openssh-7.6p1/sshkey.h 2017-10-04 17:18:32.840505079 +0200 -@@ -133,6 +133,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh/sshkey.h.audit openssh/sshkey.h +--- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 ++++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 +@@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 3b5001a..08cd349 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -1,6 +1,6 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.refactor 2017-09-27 13:10:19.556830609 +0200 -+++ openssh/auth2-pubkey.c 2017-09-27 13:10:19.677831274 +0200 +--- 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; @@ -11,7 +11,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c static char * format_key(const struct sshkey *key) -@@ -432,7 +435,8 @@ match_principals_command(struct passwd * +@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command, ac, av, &f, @@ -21,7 +21,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c goto out; uid_swapped = 1; -@@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd +@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, ac, av, &f, @@ -32,9 +32,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c uid_swapped = 1; diff -up openssh/auth.c.refactor openssh/auth.c ---- openssh/auth.c.refactor 2017-09-27 13:10:19.640831071 +0200 -+++ openssh/auth.c 2017-09-27 13:10:19.678831279 +0200 -@@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv) +--- 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, @@ -44,7 +44,7 @@ diff -up openssh/auth.c.refactor openssh/auth.c { FILE *f = NULL; struct stat st; -@@ -1551,7 +1552,7 @@ subprocess(const char *tag, struct passw +@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw } #ifdef WITH_SELINUX @@ -54,9 +54,9 @@ diff -up openssh/auth.c.refactor openssh/auth.c strerror(errno)); _exit(127); diff -up openssh/auth.h.refactor openssh/auth.h ---- openssh/auth.h.refactor 2017-09-25 01:48:10.000000000 +0200 -+++ openssh/auth.h 2017-09-27 13:10:19.678831279 +0200 -@@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *, +--- 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 *, @@ -66,8 +66,8 @@ diff -up openssh/auth.h.refactor openssh/auth.h 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 2017-09-27 13:10:19.634831038 +0200 -+++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +0200 +--- 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); @@ -80,9 +80,9 @@ diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/por #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 2017-09-27 13:10:19.634831038 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2017-09-27 13:12:06.811420371 +0200 -@@ -48,11 +48,6 @@ +--- 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 #endif @@ -94,7 +94,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa /* Wrapper around is_selinux_enabled() to log its return value once only */ int sshd_selinux_enabled(void) -@@ -222,7 +217,8 @@ get_user_context(const char *sename, con +@@ -223,7 +218,8 @@ get_user_context(const char *sename, con } static void @@ -104,7 +104,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { *role = NULL; *level = NULL; -@@ -240,8 +236,8 @@ ssh_selinux_get_role_level(char **role, +@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role, /* Return the default security context for the given username */ static int @@ -115,7 +115,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { char *sename, *lvl; char *role; -@@ -249,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, int r = 0; context_t con = NULL; @@ -124,7 +124,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa #ifdef HAVE_GETSEUSERBYNAME if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -@@ -271,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, if (r == 0) { /* If launched from xinetd, we must use current level */ @@ -133,7 +133,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa security_context_t sshdsc=NULL; if (getcon_raw(&sshdsc) < 0) -@@ -332,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -143,7 +143,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { const char *reqlvl; char *role; -@@ -341,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it +@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it debug3("%s: setting execution context", __func__); @@ -157,7 +157,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa use_current = "1"; } else { use_current = ""; -@@ -361,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it +@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it } static int @@ -170,7 +170,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa } static int -@@ -373,25 +371,28 @@ do_setenv(char *name, const char *value) +@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value) } int @@ -204,7 +204,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa switch (security_getenforce()) { case -1: fatal("%s: security_getenforce() failed", __func__); -@@ -409,7 +410,7 @@ sshd_selinux_setup_exec_context(char *pw +@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw debug3("%s: setting execution context", __func__); @@ -214,9 +214,9 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa r = setexeccon(user_ctx); if (r < 0) { diff -up openssh/platform.c.refactor openssh/platform.c ---- openssh/platform.c.refactor 2017-09-27 13:10:19.574830708 +0200 -+++ openssh/platform.c 2017-09-27 13:11:45.475303050 +0200 -@@ -33,6 +33,9 @@ +--- 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; @@ -226,7 +226,7 @@ diff -up openssh/platform.c.refactor openssh/platform.c void platform_pre_listen(void) -@@ -184,7 +187,9 @@ platform_setusercontext_post_groups(stru +@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -238,9 +238,27 @@ diff -up openssh/platform.c.refactor openssh/platform.c } diff -up openssh/sshd.c.refactor openssh/sshd.c ---- openssh/sshd.c.refactor 2017-09-27 13:10:19.674831257 +0200 -+++ openssh/sshd.c 2017-09-27 13:12:01.635391909 +0200 -@@ -2135,7 +2135,9 @@ main(int ac, char **av) +--- 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 diff --git a/openssh-7.6p1-pkcs11-ecdsa.patch b/openssh-7.6p1-pkcs11-ecdsa.patch deleted file mode 100644 index 68fe97b..0000000 --- a/openssh-7.6p1-pkcs11-ecdsa.patch +++ /dev/null @@ -1,794 +0,0 @@ -diff -up openssh/ssh-pkcs11-client.c.pkcs11-ecdsa openssh/ssh-pkcs11-client.c ---- openssh/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-10-12 14:05:55.020656974 +0200 -+++ openssh/ssh-pkcs11-client.c 2018-10-12 14:05:55.023656999 +0200 -@@ -31,6 +31,15 @@ - #include - - #include -+#ifdef OPENSSL_HAS_ECC -+#include -+#if ((defined(LIBRESSL_VERSION_NUMBER) && \ -+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ -+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ -+ (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+#define ENABLE_PKCS11_ECDSA 1 -+#endif -+#endif - - #include "openbsd-compat/openssl-compat.h" - -@@ -155,9 +164,9 @@ pkcs11_rsa_private_encrypt(int flen, con - return (ret); - } - --/* redirect the private key encrypt operation to the ssh-pkcs11-helper */ -+/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */ - static int --wrap_key(RSA *rsa) -+wrap_rsa_key(RSA *rsa) - { - static RSA_METHOD *helper_rsa; - -@@ -170,6 +179,88 @@ wrap_key(RSA *rsa) - return (0); - } - -+#ifdef ENABLE_PKCS11_ECDSA -+static ECDSA_SIG * -+pkcs11_ecdsa_private_sign(const unsigned char *from, int flen, -+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa) -+{ -+ struct sshkey *key = NULL; -+ u_char *blob, *signature = NULL; -+ size_t blen, slen = 0; -+ struct sshbuf *msg = NULL; -+ ECDSA_SIG *ret = NULL; -+ BIGNUM *r = NULL, *s = NULL; -+ int rv; -+ -+ if ((key = sshkey_new(KEY_ECDSA)) == NULL) -+ fatal("%s: sshkey_new failed", __func__); -+ key->ecdsa = ecdsa; -+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); -+ if (sshkey_to_blob(key, &blob, &blen) == 0) -+ goto out; -+ if ((msg = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ if ((rv = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || -+ (rv = sshbuf_put_string(msg, blob, blen)) != 0 || -+ (rv = sshbuf_put_string(msg, from, flen)) != 0 || -+ (rv = sshbuf_put_u32(msg, 0)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(rv)); -+ free(blob); -+ send_msg(msg); -+ sshbuf_reset(msg); -+ -+ if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) { -+ if ((rv = sshbuf_get_string(msg, &signature, &slen)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(rv)); -+ if (slen <= (size_t)ECDSA_size(ecdsa)) { -+ int nlen = slen / 2; -+ ret = ECDSA_SIG_new(); -+ r = BN_new(); -+ s = BN_new(); -+ BN_bin2bn(&signature[0], nlen, r); -+ BN_bin2bn(&signature[nlen], nlen, s); -+ ECDSA_SIG_set0(ret, r, s); -+ } -+ free(signature); -+ } -+out: -+ sshkey_free(key); -+ sshbuf_free(msg); -+ return (ret); -+} -+ -+/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */ -+static int -+wrap_ecdsa_key(EC_KEY *ecdsa) { -+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+ static EC_KEY_METHOD *helper_ecdsa = NULL; -+ if (helper_ecdsa == NULL) { -+ const EC_KEY_METHOD *def = EC_KEY_get_default_method(); -+ helper_ecdsa = EC_KEY_METHOD_new(def); -+ EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign); -+ } -+ EC_KEY_set_method(ecdsa, helper_ecdsa); -+#else -+ static ECDSA_METHOD *helper_ecdsa = NULL; -+ if(helper_ecdsa == NULL) { -+ const ECDSA_METHOD *def = ECDSA_get_default_method(); -+# ifdef ECDSA_F_ECDSA_METHOD_NEW -+ helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def); -+ ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa"); -+ ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign); -+# else -+ helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa)); -+ memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa)); -+ helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa"; -+ helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign; -+# endif -+ } -+ ECDSA_set_method(ecdsa, helper_ecdsa); -+#endif -+ return (0); -+} -+#endif -+ - static int - pkcs11_start_helper(void) - { -@@ -238,7 +329,15 @@ pkcs11_add_provider(char *name, char *pi - __func__, ssh_err(r)); - if ((r = sshkey_from_blob(blob, blen, &k)) != 0) - fatal("%s: bad key: %s", __func__, ssh_err(r)); -- wrap_key(k->rsa); -+ if(k->type == KEY_RSA) { -+ wrap_rsa_key(k->rsa); -+#ifdef ENABLE_PKCS11_ECDSA -+ } else if(k->type == KEY_ECDSA) { -+ wrap_ecdsa_key(k->ecdsa); -+#endif /* ENABLE_PKCS11_ECDSA */ -+ } else { -+ /* Unsupported type */ -+ } - (*keysp)[i] = k; - free(blob); - } -diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c ---- openssh/ssh-pkcs11.c.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200 -+++ openssh/ssh-pkcs11.c 2018-10-12 14:11:54.292636679 +0200 -@@ -33,6 +33,16 @@ - #include "openbsd-compat/openssl-compat.h" - - #include -+#include -+#ifdef OPENSSL_HAS_ECC -+#include -+#if ((defined(LIBRESSL_VERSION_NUMBER) && \ -+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ -+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ -+ (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+#define ENABLE_PKCS11_ECDSA 1 -+#endif -+#endif - - #define CRYPTOKI_COMPAT - #include "pkcs11.h" -@@ -74,6 +84,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro - struct pkcs11_key { - struct pkcs11_provider *provider; - CK_ULONG slotidx; -+ CK_ULONG key_type; - int (*orig_finish)(RSA *rsa); - RSA_METHOD *rsa_method; - char *keyid; -@@ -82,6 +93,9 @@ struct pkcs11_key { - }; - - int pkcs11_interactive = 0; -+#ifdef ENABLE_PKCS11_ECDSA -+static int pkcs11_key_idx = -1; -+#endif /* ENABLE_PKCS11_ECDSA */ - - /* - * This can't be in the ssh-pkcs11-uri, becase we can not depend on -@@ -345,6 +359,40 @@ pkcs11_find(struct pkcs11_provider *p, C - return (ret); - } - -+int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) { -+ char *pin = NULL, prompt[1024]; -+ CK_RV rv; -+ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { -+ if (!pkcs11_interactive) { -+ error("need pin entry%s", (si->token.flags & -+ CKF_PROTECTED_AUTHENTICATION_PATH) ? -+ " on reader keypad" : ""); -+ return (-1); -+ } -+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) -+ verbose("Deferring PIN entry to reader keypad."); -+ else { -+ snprintf(prompt, sizeof(prompt), -+ "Enter PIN for '%s': ", si->token.label); -+ pin = read_passphrase(prompt, RP_ALLOW_EOF); -+ if (pin == NULL) -+ return (-1); /* bail out */ -+ } -+ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, -+ (pin != NULL) ? strlen(pin) : 0); -+ if (pin != NULL) { -+ explicit_bzero(pin, strlen(pin)); -+ free(pin); -+ } -+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { -+ error("C_Login failed: %lu", rv); -+ return (-1); -+ } -+ si->logged_in = 1; -+ } -+ return 0; -+} -+ - /* openssl callback doing the actual signing operation */ - static int - pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, -@@ -366,7 +414,6 @@ pkcs11_rsa_private_encrypt(int flen, con - {CKA_ID, NULL, 0}, - {CKA_SIGN, NULL, sizeof(true_val) } - }; -- char *pin = NULL, prompt[1024]; - int rval = -1; - - key_filter[0].pValue = &private_key_class; -@@ -383,33 +430,8 @@ pkcs11_rsa_private_encrypt(int flen, con - } - f = k11->provider->module->function_list; - si = &k11->provider->module->slotinfo[k11->slotidx]; -- if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { -- if (!pkcs11_interactive) { -- error("need pin entry%s", (si->token.flags & -- CKF_PROTECTED_AUTHENTICATION_PATH) ? -- " on reader keypad" : ""); -- return (-1); -- } -- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) -- verbose("Deferring PIN entry to reader keypad."); -- else { -- snprintf(prompt, sizeof(prompt), -- "Enter PIN for '%s': ", si->token.label); -- pin = read_passphrase(prompt, RP_ALLOW_EOF); -- if (pin == NULL) -- return (-1); /* bail out */ -- } -- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, -- (pin != NULL) ? strlen(pin) : 0); -- if (pin != NULL) { -- explicit_bzero(pin, strlen(pin)); -- free(pin); -- } -- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { -- error("C_Login failed: %lu", rv); -- return (-1); -- } -- si->logged_in = 1; -+ if(pkcs11_login(k11, f, si)) { -+ return (-1); - } - key_filter[1].pValue = k11->keyid; - key_filter[1].ulValueLen = k11->keyid_len; -@@ -447,6 +469,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - const RSA_METHOD *def = RSA_get_default_method(); - - k11 = xcalloc(1, sizeof(*k11)); -+ k11->key_type = CKK_RSA; - k11->provider = provider; - provider->refcount++; /* provider referenced by RSA key */ - k11->slotidx = slotidx; -@@ -477,6 +500,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - return (0); - } - -+#ifdef ENABLE_PKCS11_ECDSA -+static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len, -+ const BIGNUM *inv, const BIGNUM *rp, -+ EC_KEY *ecdsa) { -+ struct pkcs11_key *k11; -+ struct pkcs11_slotinfo *si; -+ CK_FUNCTION_LIST *f; -+ CK_OBJECT_HANDLE obj; -+ CK_ULONG tlen = 0; -+ CK_RV rv; -+ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; -+ CK_BBOOL true_val = CK_TRUE; -+ CK_MECHANISM mech = { -+ CKM_ECDSA, NULL_PTR, 0 -+ }; -+ CK_ATTRIBUTE key_filter[] = { -+ {CKA_CLASS, NULL, sizeof(private_key_class) }, -+ {CKA_ID, NULL, 0}, -+ {CKA_SIGN, NULL, sizeof(true_val) } -+ }; -+ ECDSA_SIG *rval = NULL; -+ key_filter[0].pValue = &private_key_class; -+ key_filter[2].pValue = &true_val; -+ -+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+ if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) { -+ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa); -+ #else -+ if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) { -+ error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa); -+ #endif -+ return NULL; -+ } -+ if (!k11->provider || !k11->provider->valid) { -+ error("no pkcs11 (valid) provider for ecdsa %p", ecdsa); -+ return NULL; -+ } -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; -+ if(pkcs11_login(k11, f, si)) { -+ return NULL; -+ } -+ key_filter[1].pValue = k11->keyid; -+ key_filter[1].ulValueLen = k11->keyid_len; -+ /* try to find object w/CKA_SIGN first, retry w/o */ -+ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 && -+ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) { -+ error("cannot find private key"); -+ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { -+ error("C_SignInit failed: %lu", rv); -+ } else { -+ CK_BYTE_PTR buf = NULL; -+ BIGNUM *r = NULL, *s = NULL; -+ int nlen; -+ /* Make a call to C_Sign to find out the size of the signature */ -+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen); -+ if (rv != CKR_OK) { -+ error("C_Sign failed: %lu", rv); -+ return NULL; -+ } -+ if ((buf = xmalloc(tlen)) == NULL) { -+ error("failure to allocate signature buffer"); -+ return NULL; -+ } -+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen); -+ if (rv != CKR_OK) { -+ error("C_Sign failed: %lu", rv); -+ } -+ -+ if ((rval = ECDSA_SIG_new()) == NULL || -+ (r = BN_new()) == NULL || -+ (s = BN_new()) == NULL) { -+ error("failure to allocate ECDSA signature"); -+ } else { -+ /* -+ * ECDSA signature is 2 large integers of same size returned -+ * concatenated by PKCS#11, we separate them to create an -+ * ECDSA_SIG for OpenSSL. -+ */ -+ nlen = tlen / 2; -+ BN_bin2bn(&buf[0], nlen, r); -+ BN_bin2bn(&buf[nlen], nlen, s); -+ ECDSA_SIG_set0(rval, r, s); -+ } -+ free(buf); -+ } -+ return (rval); -+} -+ -+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) { -+ static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL; -+ if(pkcs11_key_idx == -1) { -+ pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0); -+ } -+ if (pkcs11_ecdsa_method == NULL) { -+ const EC_KEY_METHOD *def = EC_KEY_get_default_method(); -+ pkcs11_ecdsa_method = EC_KEY_METHOD_new(def); -+ EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign); -+ } -+#else -+static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) { -+ static ECDSA_METHOD *pkcs11_ecdsa_method = NULL; -+ if(pkcs11_key_idx == -1) { -+ pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0); -+ } -+ if(pkcs11_ecdsa_method == NULL) { -+ const ECDSA_METHOD *def = ECDSA_get_default_method(); -+ #ifdef ECDSA_F_ECDSA_METHOD_NEW -+ pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def); -+ ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11"); -+ ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign); -+ #else -+ pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method)); -+ memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method)); -+ pkcs11_ecdsa_method->name = "pkcs11"; -+ pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign; -+ #endif -+ } -+#endif -+ return pkcs11_ecdsa_method; -+} -+ -+static int -+pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa) -+{ -+ struct pkcs11_key *k11; -+ k11 = xcalloc(1, sizeof(*k11)); -+ k11->key_type = CKK_EC; -+ k11->provider = provider; -+ provider->refcount++; /* provider referenced by ECDSA key */ -+ k11->slotidx = slotidx; -+ /* identify key object on smartcard */ -+ k11->keyid_len = keyid_attrib->ulValueLen; -+ if (k11->keyid_len > 0) { -+ k11->keyid = xmalloc(k11->keyid_len); -+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); -+ } -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+ EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method()); -+ EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11); -+ #else -+ ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method()); -+ ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11); -+ #endif -+ return (0); -+} -+#endif /* ENABLE_PKCS11_ECDSA */ -+ -+int pkcs11_del_key(struct sshkey *key) { -+#ifdef ENABLE_PKCS11_ECDSA -+ if(key->type == KEY_ECDSA) { -+ struct pkcs11_key *k11 = (struct pkcs11_key *) -+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+ EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx); -+ #else -+ ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx); -+ #endif -+ if (k11 == NULL) { -+ error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa); -+ } else { -+ if (k11->provider) -+ pkcs11_provider_unref(k11->provider); -+ free(k11->keyid); -+ free(k11); -+ } -+ } -+#endif /* ENABLE_PKCS11_ECDSA */ -+ sshkey_free(key); -+ return (0); -+} -+ - /* remove trailing spaces */ - static void - rmspace(u_char *buf, size_t len) -@@ -544,11 +745,13 @@ static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) - { -- size_t filter_size = 1; -+ size_t filter_size = 2; -+ CK_KEY_TYPE pubkey_type = CKK_RSA; - CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; - CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; - CK_ATTRIBUTE pubkey_filter[] = { - { CKA_CLASS, NULL, sizeof(pubkey_class) }, -+ { CKA_KEY_TYPE, NULL, sizeof(pubkey_type) }, - { CKA_ID, NULL, 0 }, - { CKA_LABEL, NULL, 0 } - }; -@@ -569,37 +772,72 @@ pkcs11_fetch_keys(struct pkcs11_provider - { CKA_SUBJECT, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; -+#ifdef ENABLE_PKCS11_ECDSA -+ CK_KEY_TYPE ecdsa_type = CKK_EC; -+ CK_ATTRIBUTE ecdsa_filter[] = { -+ { CKA_CLASS, NULL, sizeof(pubkey_class) }, -+ { CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) }, -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 } -+ }; -+ CK_ATTRIBUTE ecdsa_attribs[] = { -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 }, -+ { CKA_EC_PARAMS, NULL, 0 }, -+ { CKA_EC_POINT, NULL, 0 } -+ }; -+ ecdsa_filter[0].pValue = &pubkey_class; -+ ecdsa_filter[1].pValue = &ecdsa_type; -+#endif /* ENABLE_PKCS11_ECDSA */ - pubkey_filter[0].pValue = &pubkey_class; -+ pubkey_filter[1].pValue = &pubkey_type; - cert_filter[0].pValue = &cert_class; - - if (uri->id != NULL) { - pubkey_filter[filter_size].pValue = uri->id; - pubkey_filter[filter_size].ulValueLen = uri->id_len; -- cert_filter[filter_size].pValue = uri->id; -- cert_filter[filter_size].ulValueLen = uri->id_len; -+#ifdef ENABLE_PKCS11_ECDSA -+ ecdsa_filter[filter_size].pValue = uri->id; -+ ecdsa_filter[filter_size].ulValueLen = uri->id_len; -+#endif /* ENABLE_PKCS11_ECDSA */ -+ cert_filter[filter_size-1].pValue = uri->id; -+ cert_filter[filter_size-1].ulValueLen = uri->id_len; - filter_size++; - } - if (uri->object != NULL) { - pubkey_filter[filter_size].pValue = uri->object; - pubkey_filter[filter_size].ulValueLen = strlen(uri->object); - pubkey_filter[filter_size].type = CKA_LABEL; -- cert_filter[filter_size].pValue = uri->object; -- cert_filter[filter_size].ulValueLen = strlen(uri->object); -- cert_filter[filter_size].type = CKA_LABEL; -+#ifdef ENABLE_PKCS11_ECDSA -+ ecdsa_filter[filter_size].pValue = uri->object; -+ ecdsa_filter[filter_size].ulValueLen = strlen(uri->object); -+ ecdsa_filter[filter_size].type = CKA_LABEL; -+#endif /* ENABLE_PKCS11_ECDSA */ -+ cert_filter[filter_size-1].pValue = uri->object; -+ cert_filter[filter_size-1].ulValueLen = strlen(uri->object); -+ cert_filter[filter_size-1].type = CKA_LABEL; - filter_size++; - } - - if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, - pubkey_attribs, keysp, nkeys) < 0 || -- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, -+#ifdef ENABLE_PKCS11_ECDSA -+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size, -+ ecdsa_attribs, keysp, nkeys) < 0|| -+#endif /* ENABLE_PKCS11_ECDSA */ -+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1, - cert_attribs, keysp, nkeys) < 0) - return (-1); - if (*nkeys == 0) { - /* Try once more without the label filter */ - filter_size--; - if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, - pubkey_attribs, keysp, nkeys) < 0 || -- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, -+#ifdef ENABLE_PKCS11_ECDSA -+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size, -+ ecdsa_attribs, keysp, nkeys) < 0|| -+#endif /* ENABLE_PKCS11_ECDSA */ -+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1, - cert_attribs, keysp, nkeys) < 0) - return (-1); - } -@@ -624,8 +858,13 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], - struct sshkey ***keysp, int *nkeys) - { -- struct sshkey *key; -+ struct sshkey *key = NULL; - RSA *rsa; -+#ifdef ENABLE_PKCS11_ECDSA -+ EC_KEY *ecdsa; -+#else -+ void *ecdsa; -+#endif /* ENABLE_PKCS11_ECDSA */ - X509 *x509; - EVP_PKEY *evp = NULL; - int i; -@@ -678,6 +917,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - * or ID, label, subject and value for certificates. - */ - rsa = NULL; -+#ifdef ENABLE_PKCS11_ECDSA -+ ecdsa = NULL; -+#endif /* ENABLE_PKCS11_ECDSA */ - if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) - != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); -@@ -700,6 +942,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - BN_free(rsa_n); - BN_free(rsa_e); - } -+#ifdef ENABLE_PKCS11_ECDSA -+ } else if (attribs[2].type == CKA_EC_PARAMS ) { -+ if ((ecdsa = EC_KEY_new()) == NULL) { -+ error("EC_KEY_new failed"); -+ } else { -+ const unsigned char *ptr1 = attribs[2].pValue; -+ const unsigned char *ptr2 = attribs[3].pValue; -+ CK_ULONG len1 = attribs[2].ulValueLen; -+ CK_ULONG len2 = attribs[3].ulValueLen; -+ ASN1_OCTET_STRING *point = NULL; -+ -+ /* -+ * CKA_EC_PARAMS contains the curve parameters of the key -+ * either referenced as an OID or directly with all values. -+ * CKA_EC_POINT contains the point (public key) on the curve. -+ * The point is should be returned inside a DER-encoded -+ * ASN.1 OCTET STRING value (but some implementation). -+ */ -+ if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) { -+ /* Pointing to OCTET STRING content */ -+ ptr2 = point->data; -+ len2 = point->length; -+ } else { -+ /* No OCTET STRING */ -+ ptr2 = attribs[3].pValue; -+ } -+ -+ if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) || -+ (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) { -+ EC_KEY_free(ecdsa); -+ ecdsa = NULL; -+ error("EC public key parsing failed"); -+ } -+ -+ if(point) { -+ ASN1_OCTET_STRING_free(point); -+ } -+ } -+#endif /* ENABLE_PKCS11_ECDSA */ - } else { - cp = attribs[3].pValue; - if ((x509 = X509_new()) == NULL) { -@@ -707,13 +988,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) - == NULL) { - error("d2i_X509 failed"); -- } else if ((evp = X509_get_pubkey(x509)) == NULL || -- EVP_PKEY_base_id(evp) != EVP_PKEY_RSA || -- EVP_PKEY_get0_RSA(evp) == NULL) { -- debug("X509_get_pubkey failed or no rsa"); -- } else if ((rsa = RSAPublicKey_dup( -- EVP_PKEY_get0_RSA(evp))) == NULL) { -- error("RSAPublicKey_dup"); -+ } else if ((evp = X509_get_pubkey(x509)) == NULL) { -+ debug("X509_get_pubkey failed"); -+ } else { -+ switch (EVP_PKEY_base_id(evp)) { -+ case EVP_PKEY_RSA: -+ if (EVP_PKEY_get0_RSA(evp) == NULL) -+ debug("Missing RSA key"); -+ else if ((rsa = RSAPublicKey_dup( -+ EVP_PKEY_get0_RSA(evp))) == NULL) -+ error("RSAPublicKey_dup failed"); -+ break; -+ case EVP_PKEY_EC: -+ if (EVP_PKEY_get0_EC_KEY(evp) == NULL) -+ debug("Missing ECDSA key"); -+ else if ((ecdsa = EC_KEY_dup( -+ EVP_PKEY_get0_EC_KEY(evp))) == NULL) -+ error("EC_KEY_dup failed"); -+ break; -+ default: -+ debug("not a RSA or ECDSA key"); -+ break; -+ } - } - X509_free(x509); - EVP_PKEY_free(evp); -@@ -725,6 +1021,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - key->rsa = rsa; - key->type = KEY_RSA; - key->flags |= SSHKEY_FLAG_EXT; -+#ifdef ENABLE_PKCS11_ECDSA -+ } else if (ecdsa && -+ pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) { -+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL) -+ fatal("sshkey_new failed"); -+ key->ecdsa = ecdsa; -+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key->ecdsa); -+ key->type = KEY_ECDSA; -+ key->flags |= SSHKEY_FLAG_EXT; -+#endif /* ENABLE_PKCS11_ECDSA */ -+ } -+ if (key) { - if (pkcs11_key_included(keysp, nkeys, key)) { - sshkey_free(key); - } else { -@@ -737,6 +1044,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } - } else if (rsa) { - RSA_free(rsa); -+#ifdef ENABLE_PKCS11_ECDSA -+ } else if (ecdsa) { -+ EC_KEY_free(ecdsa); -+#endif /* ENABLE_PKCS11_ECDSA */ - } - for (i = 0; i < nattribs; i++) - free(attribs[i].pValue); -diff -up openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh/ssh-pkcs11-helper.c ---- openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-pkcs11-helper.c 2018-10-12 14:05:55.023656999 +0200 -@@ -24,6 +24,17 @@ - - #include "openbsd-compat/sys-queue.h" - -+#include -+#ifdef OPENSSL_HAS_ECC -+#include -+#if ((defined(LIBRESSL_VERSION_NUMBER) && \ -+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ -+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \ -+ (OPENSSL_VERSION_NUMBER >= 0x00010100L) -+#define ENABLE_PKCS11_ECDSA 1 -+#endif -+#endif -+ - #include - #include - #include -@@ -77,7 +88,7 @@ del_keys_by_name(char *name) - if (!strcmp(ki->providername, name)) { - TAILQ_REMOVE(&pkcs11_keylist, ki, next); - free(ki->providername); -- sshkey_free(ki->key); -+ pkcs11_del_key(ki->key); - free(ki); - } - } -@@ -172,6 +183,20 @@ process_del(void) - sshbuf_free(msg); - } - -+#ifdef ENABLE_PKCS11_ECDSA -+static u_int EC_KEY_order_size(EC_KEY *key) -+{ -+ const EC_GROUP *group = EC_KEY_get0_group(key); -+ BIGNUM *order = BN_new(); -+ u_int nbytes = 0; -+ if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) { -+ nbytes = BN_num_bytes(order); -+ } -+ BN_clear_free(order); -+ return nbytes; -+} -+#endif /* ENABLE_PKCS11_ECDSA */ -+ - static void - process_sign(void) - { -@@ -192,14 +217,38 @@ process_sign(void) - else { - if ((found = lookup_key(key)) != NULL) { - #ifdef WITH_OPENSSL -- int ret; -- -- slen = RSA_size(key->rsa); -- signature = xmalloc(slen); -- if ((ret = RSA_private_encrypt(dlen, data, signature, -- found->rsa, RSA_PKCS1_PADDING)) != -1) { -- slen = ret; -- ok = 0; -+ if(found->type == KEY_RSA) { -+ int ret; -+ slen = RSA_size(key->rsa); -+ signature = xmalloc(slen); -+ if ((ret = RSA_private_encrypt(dlen, data, signature, -+ found->rsa, RSA_PKCS1_PADDING)) != -1) { -+ slen = ret; -+ ok = 0; -+ } -+#ifdef ENABLE_PKCS11_ECDSA -+ } else if(found->type == KEY_ECDSA) { -+ ECDSA_SIG *sig; -+ const BIGNUM *r = NULL, *s = NULL; -+ if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) { -+ /* PKCS11 2.3.1 recommends both r and s to have the order size for -+ backward compatiblity */ -+ ECDSA_SIG_get0(sig, &r, &s); -+ u_int o_len = EC_KEY_order_size(found->ecdsa); -+ u_int r_len = BN_num_bytes(r); -+ u_int s_len = BN_num_bytes(s); -+ if (o_len > 0 && r_len <= o_len && s_len <= o_len) { -+ signature = xcalloc(2, o_len); -+ BN_bn2bin(r, signature + o_len - r_len); -+ BN_bn2bin(s, signature + (2 * o_len) - s_len); -+ slen = 2 * o_len; -+ ok = 0; -+ } -+ ECDSA_SIG_free(sig); -+ } -+#endif /* ENABLE_PKCS11_ECDSA */ -+ } else { -+ /* Unsupported type */ - } - #endif /* WITH_OPENSSL */ - } -diff -up openssh/ssh-pkcs11.h.pkcs11-ecdsa openssh/ssh-pkcs11.h ---- openssh/ssh-pkcs11.h.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200 -+++ openssh/ssh-pkcs11.h 2018-10-12 14:05:55.023656999 +0200 -@@ -20,6 +20,7 @@ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***); -+int pkcs11_del_key(struct sshkey *); - int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); - int pkcs11_del_provider(char *); - int pkcs11_uri_write(const struct sshkey *, FILE *); diff --git a/openssh-7.6p1-pkcs11-uri.patch b/openssh-7.6p1-pkcs11-uri.patch deleted file mode 100644 index 708f016..0000000 --- a/openssh-7.6p1-pkcs11-uri.patch +++ /dev/null @@ -1,4760 +0,0 @@ -diff -up openssh/authfd.c.pkcs11-uri openssh/authfd.c ---- openssh/authfd.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/authfd.c 2018-10-12 13:52:55.450191401 +0200 -@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identit - if (idl->comments != NULL) - free(idl->comments[i]); - } -+ free(idl->keys); -+ free(idl->comments); - free(idl); - } - -diff -up openssh/configure.ac.pkcs11-uri openssh/configure.ac ---- openssh/configure.ac.pkcs11-uri 2018-10-12 13:52:55.430191235 +0200 -+++ openssh/configure.ac 2018-10-12 13:52:55.451191409 +0200 -@@ -1987,12 +1987,14 @@ AC_LINK_IFELSE( - [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) - ]) - -+SCARD_MSG="yes" - disable_pkcs11= - AC_ARG_ENABLE([pkcs11], - [ --disable-pkcs11 disable PKCS#11 support code [no]], - [ - if test "x$enableval" = "xno" ; then - disable_pkcs11=1 -+ SCARD_MSG="no" - fi - ] - ) -@@ -2008,6 +2010,40 @@ if test "x$openssl" = "xyes" && test "x$ - ) - fi - -+# Check whether we have a p11-kit, we got default provider on command line -+DEFAULT_PKCS11_PROVIDER_MSG="no" -+AC_ARG_WITH([default-pkcs11-provider], -+ [ --with-default-pkcs11-provider[[=PATH]] Use default pkcs11 provider (p11-kit detected by default)], -+ [ if test "x$withval" != "xno" && test "x$disable_pkcs11" = "x"; then -+ if test "x$withval" = "xyes" ; then -+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) -+ if test "x$PKGCONFIG" != "xno"; then -+ AC_MSG_CHECKING([if $PKGCONFIG knows about p11-kit]) -+ if "$PKGCONFIG" "p11-kit-1"; then -+ AC_MSG_RESULT([yes]) -+ use_pkgconfig_for_p11kit=yes -+ else -+ AC_MSG_RESULT([no]) -+ fi -+ fi -+ else -+ PKCS11_PATH="${withval}" -+ fi -+ if test "x$use_pkgconfig_for_p11kit" = "xyes"; then -+ PKCS11_PATH=`$PKGCONFIG --variable=proxy_module p11-kit-1` -+ fi -+ AC_CHECK_FILE("$PKCS11_PATH", -+ [ AC_DEFINE_UNQUOTED([PKCS11_DEFAULT_PROVIDER], ["$PKCS11_PATH"], [Path to default PKCS#11 provider (p11-kit proxy)]) -+ DEFAULT_PKCS11_PROVIDER_MSG="$PKCS11_PATH" -+ ], -+ [ AC_MSG_ERROR([Requested PKCS11 provided not found]) ] -+ ) -+ else -+ AC_MSG_WARN([Needs PKCS11 support to enable default pkcs11 provider]) -+ fi ] -+) -+ -+ - # IRIX has a const char return value for gai_strerror() - AC_CHECK_FUNCS([gai_strerror], [ - AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5458,6 +5494,7 @@ echo " BSD Auth support - echo " Random number source: $RAND_MSG" - echo " Privsep sandbox style: $SANDBOX_STYLE" - echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" -+echo " Default PKCS#11 provider: $DEFAULT_PKCS11_PROVIDER_MSG" - - echo "" - -diff -up openssh/Makefile.in.pkcs11-uri openssh/Makefile.in ---- openssh/Makefile.in.pkcs11-uri 2018-10-12 13:52:55.366190704 +0200 -+++ openssh/Makefile.in 2018-10-12 13:52:55.450191401 +0200 -@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ - kexgssc.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -270,6 +270,8 @@ clean: regressclean - rm -f regress/unittests/match/test_match$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - (cd openbsd-compat && $(MAKE) clean) -@@ -300,6 +302,8 @@ distclean: regressclean - rm -f regress/unittests/match/test_match - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8 -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - (cd openbsd-compat && $(MAKE) distclean) -@@ -484,6 +488,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/kex - $(MKDIR_P) `pwd`/regress/unittests/match - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/kexfuzz - [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -502,6 +507,11 @@ regress/netcat$(EXEEXT): $(srcdir)/regre - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \ - $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+regress/soft-pkcs11.so: $(srcdir)/regress/soft-pkcs11.c $(REGRESSLIBS) -+ $(CC) $(CFLAGS) $(CPPFLAGS) -fpic -c $(srcdir)/regress/soft-pkcs11.c \ -+ -o $(srcdir)/regress/soft-pkcs11.o -+ $(CC) -shared -o $@ $(srcdir)/regress/soft-pkcs11.o -+ - regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \ - $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -607,6 +617,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ - MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o - -@@ -617,6 +637,7 @@ regress/misc/kexfuzz/kexfuzz$(EXEEXT): $ - regress-binaries: regress/modpipe$(EXEEXT) \ - regress/setuid-allowed$(EXEEXT) \ - regress/netcat$(EXEEXT) \ -+ regress/soft-pkcs11.so \ - regress/check-perm$(EXEEXT) \ - regress/mkdtemp$(EXEEXT) \ - regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ -@@ -627,6 +648,7 @@ regress-binaries: regress/modpipe$(EXEEX - regress/unittests/kex/test_kex$(EXEEXT) \ - regress/unittests/match/test_match$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - regress/misc/kexfuzz/kexfuzz$(EXEEXT) - - tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) -diff -up openssh/regress/agent-pkcs11.sh.pkcs11-uri openssh/regress/agent-pkcs11.sh ---- openssh/regress/agent-pkcs11.sh.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/regress/agent-pkcs11.sh 2018-10-12 13:52:55.451191409 +0200 -@@ -4,10 +4,17 @@ - tid="pkcs11 agent test" - - TEST_SSH_PIN="" --TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 -+TEST_SSH_PKCS11=$OBJ/soft-pkcs11.so - - test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" - -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ - # setup environment for soft-pkcs11 token - SOFTPKCS11RC=$OBJ/pkcs11.info - export SOFTPKCS11RC -@@ -23,7 +30,7 @@ notty() { - } - - trace "start agent" --eval `${SSHAGENT} -s` > /dev/null -+eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null - r=$? - if [ $r -ne 0 ]; then - fail "could not start ssh-agent: exit code $r" -@@ -60,7 +67,7 @@ else - fi - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff -up openssh/regress/locl.h.pkcs11-uri openssh/regress/locl.h ---- openssh/regress/locl.h.pkcs11-uri 2018-10-12 13:52:55.451191409 +0200 -+++ openssh/regress/locl.h 2018-10-12 13:52:55.451191409 +0200 -@@ -0,0 +1,78 @@ -+/* -+ * Copyright (c) 2004, Stockholms universitet -+ * (Stockholm University, Stockholm Sweden) -+ * All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * -+ * 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. Neither the name of the university nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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 ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* $Id: locl.h,v 1.5 2005/08/28 15:30:31 lha Exp $ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+ -+#include "../pkcs11.h" -+ -+#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \ -+{ \ -+ unsigned char *p; \ -+ (BL) = i2d_##T((S), NULL); \ -+ if ((BL) <= 0) { \ -+ (R) = EINVAL; \ -+ } else { \ -+ (B) = malloc((BL)); \ -+ if ((B) == NULL) { \ -+ (R) = ENOMEM; \ -+ } else { \ -+ p = (B); \ -+ (R) = 0; \ -+ (BL) = i2d_##T((S), &p); \ -+ if ((BL) <= 0) { \ -+ free((B)); \ -+ (R) = EINVAL; \ -+ } \ -+ } \ -+ } \ -+} -diff -up openssh/regress/Makefile.pkcs11-uri openssh/regress/Makefile ---- openssh/regress/Makefile.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/regress/Makefile 2018-10-12 13:52:55.451191409 +0200 -@@ -109,9 +109,11 @@ CLEANFILES= *.core actual agent-key.* au - known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ - modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log \ -- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ -+ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ -+ rsa-agent-cert.pub rsa.pub \ - rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ -- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ -+ soft-pkcs11.so soft-pkcs11.o pkcs11*.crt pkcs11*.key \ -+ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ - scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ - sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ - ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ -@@ -226,6 +228,7 @@ unit: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ -diff -up openssh/regress/pkcs11.sh.pkcs11-uri openssh/regress/pkcs11.sh ---- openssh/regress/pkcs11.sh.pkcs11-uri 2018-10-12 13:52:55.451191409 +0200 -+++ openssh/regress/pkcs11.sh 2018-10-12 13:52:55.451191409 +0200 -@@ -0,0 +1,300 @@ -+# -+# Copyright (c) 2017 Red Hat -+# -+# Authors: Jakub Jelen -+# -+# Permission to use, copy, modify, and distribute this software for any -+# purpose with or without fee is hereby granted, provided that the above -+# copyright notice and this permission notice appear in all copies. -+# -+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ -+tid="pkcs11 tests with soft token" -+ -+TEST_SSH_PIN="" -+TEST_SSH_PKCS11=$OBJ/soft-pkcs11.so -+ -+test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" -+ -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ -+# setup environment for soft-pkcs11 token -+SOFTPKCS11RC=$OBJ/pkcs11.info -+rm -f $SOFTPKCS11RC -+export SOFTPKCS11RC -+# prevent ssh-agent from calling ssh-askpass -+SSH_ASKPASS=/usr/bin/true -+export SSH_ASKPASS -+unset DISPLAY -+ -+# start command w/o tty, so ssh accepts pin from stdin (from agent-pkcs11.sh) -+notty() { -+ perl -e 'use POSIX; POSIX::setsid(); -+ if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" -+} -+ -+create_key() { -+ ID=$1 -+ LABEL=$2 -+ rm -f $OBJ/pkcs11-${ID}.key $OBJ/pkcs11-${ID}.crt -+ openssl genrsa -out $OBJ/pkcs11-${ID}.key 2048 > /dev/null 2>&1 -+ chmod 600 $OBJ/pkcs11-${ID}.key -+ openssl req -key $OBJ/pkcs11-${ID}.key -new -x509 \ -+ -out $OBJ/pkcs11-${ID}.crt -text -subj '/CN=pkcs11 test' >/dev/null -+ printf "${ID}\t${LABEL}\t$OBJ/pkcs11-${ID}.crt\t$OBJ/pkcs11-${ID}.key\n" \ -+ >> $SOFTPKCS11RC -+} -+ -+trace "Create a key pairs on soft token" -+ID1="02" -+ID2="04" -+create_key "$ID1" "SSH RSA Key" -+create_key "$ID2" "SSH RSA Key 2" -+ -+trace "List the keys in the ssh-keygen with PKCS#11 URIs" -+${SSHKEYGEN} -D ${TEST_SSH_PKCS11} > $OBJ/token_keys -+if [ $? -ne 0 ]; then -+ fail "keygen fails to enumerate keys on PKCS#11 token" -+fi -+grep "pkcs11:" $OBJ/token_keys > /dev/null -+if [ $? -ne 0 ]; then -+ fail "The keys from ssh-keygen do not contain PKCS#11 URI as a comment" -+fi -+tail -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER -+ -+ -+trace "Simple connect with ssh (without PKCS#11 URI)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -I ${TEST_SSH_PKCS11} \ -+ -F $OBJ/ssh_proxy somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with pkcs11 failed (exit code $r)" -+fi -+ -+ -+trace "Connect with PKCS#11 URI" -+trace " (second key should succeed)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" -+fi -+ -+trace " (first key should fail)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" -+fi -+ -+trace "Connect with various filtering options in PKCS#11 URI" -+trace " (by object label, second key should succeed)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:object=SSH%20RSA%20Key%202?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" -+fi -+ -+trace " (by object label, first key should fail)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:object=SSH%20RSA%20Key?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" -+fi -+ -+trace " (by token label, second key should succeed)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID2};token=SoftToken%20(token)?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" -+fi -+ -+trace " (by wrong token label, should fail)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:token=SoftToken?module-path=${TEST_SSH_PKCS11}" somehost exit 5 -+r=$? -+if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" -+fi -+ -+ -+ -+ -+trace "Test PKCS#11 URI specification in configuration files" -+echo "IdentityFile \"pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}\"" \ -+ >> $OBJ/ssh_proxy -+trace " (second key should succeed)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI in config failed (exit code $r)" -+fi -+ -+trace " (first key should fail)" -+head -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+r=$? -+if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI in config succeeded (should fail)" -+fi -+sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy -+ -+trace "Test PKCS#11 URI specification in configuration files with bogus spaces" -+echo "IdentityFile \" pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} \"" \ -+ >> $OBJ/ssh_proxy -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI with bogus spaces in config failed" \ -+ "(exit code $r)" -+fi -+sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy -+ -+ -+trace "Combination of PKCS11Provider and PKCS11URI on commandline" -+trace " (first key should succeed)" -+echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID1}" -I ${TEST_SSH_PKCS11} somehost exit 5 -+r=$? -+if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI and provider combination" \ -+ "failed (exit code $r)" -+fi -+ -+trace "Regress: Missing provider in PKCS11URI option" -+${SSH} -F $OBJ/ssh_proxy \ -+ -o IdentityFile=\"pkcs11:token=segfault\" somehost exit 5 -+r=$? -+if [ $r -eq 139 ]; then -+ fail "ssh connect with missing provider_id from configuration option" \ -+ "crashed (exit code $r)" -+fi -+ -+ -+trace "SSH Agent can work with PKCS#11 URI" -+trace "start the agent" -+eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null -+ -+r=$? -+if [ $r -ne 0 ]; then -+ fail "could not start ssh-agent: exit code $r" -+else -+ trace "add whole provider to agent" -+ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add failed with whole provider: exit code $r" -+ fi -+ -+ trace " pkcs11 list via agent (all keys)" -+ ${SSHADD} -l > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add -l failed with whole provider: exit code $r" -+ fi -+ -+ trace " pkcs11 connect via agent (all keys)" -+ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+ r=$? -+ if [ $r -ne 5 ]; then -+ fail "ssh connect failed with whole provider (exit code $r)" -+ fi -+ -+ trace " remove pkcs11 keys (all keys)" -+ ${SSHADD} -d "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with whole provider: exit code $r" -+ fi -+ -+ trace "add only first key to the agent" -+ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add failed with first key: exit code $r" -+ fi -+ -+ trace " pkcs11 connect via agent (first key)" -+ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+ r=$? -+ if [ $r -ne 5 ]; then -+ fail "ssh connect failed with first key (exit code $r)" -+ fi -+ -+ trace " remove first pkcs11 key" -+ ${SSHADD} -d "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" \ -+ > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with first key: exit code $r" -+ fi -+ -+ trace "add only second key to the agent" -+ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add failed with second key: exit code $r" -+ fi -+ -+ trace " pkcs11 connect via agent (second key should fail)" -+ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+ r=$? -+ if [ $r -eq 5 ]; then -+ fail "ssh connect passed without key (should fail)" -+ fi -+ -+ trace "add also the first key to the agent" -+ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add failed with first key: exit code $r" -+ fi -+ -+ trace " remove second pkcs11 key" -+ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ -+ > /dev/null 2>&1 -+ r=$? -+ if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with second key: exit code $r" -+ fi -+ -+ trace " remove already-removed pkcs11 key should fail" -+ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ -+ > /dev/null 2>&1 -+ r=$? -+ if [ $r -eq 0 ]; then -+ fail "ssh-add -d passed with non-existing key (should fail)" -+ fi -+ -+ trace " pkcs11 connect via agent (the first key should be still usable)" -+ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 -+ r=$? -+ if [ $r -ne 5 ]; then -+ fail "ssh connect failed with first key (after removing second): exit code $r" -+ fi -+ -+ trace "kill agent" -+ ${SSHAGENT} -k > /dev/null -+fi -+ -+rm -rf $OBJ/.tokens $OBJ/token_keys -diff -up openssh/regress/soft-pkcs11.c.pkcs11-uri openssh/regress/soft-pkcs11.c ---- openssh/regress/soft-pkcs11.c.pkcs11-uri 2018-10-12 13:52:55.452191417 +0200 -+++ openssh/regress/soft-pkcs11.c 2018-10-12 13:52:55.452191417 +0200 -@@ -0,0 +1,2058 @@ -+/* -+ * Copyright (c) 2004-2006, Stockholms universitet -+ * (Stockholm University, Stockholm Sweden) -+ * All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * -+ * 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. Neither the name of the university nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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 ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "locl.h" -+ -+/* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */ -+ -+#define OBJECT_ID_MASK 0xfff -+#define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK) -+#define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle) -+ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ #define RSA_PKCS1_SSLeay RSA_PKCS1_OpenSSL -+#endif -+ -+struct st_attr { -+ CK_ATTRIBUTE attribute; -+ int secret; -+}; -+ -+struct st_object { -+ CK_OBJECT_HANDLE object_handle; -+ struct st_attr *attrs; -+ int num_attributes; -+ enum { -+ STO_T_CERTIFICATE, -+ STO_T_PRIVATE_KEY, -+ STO_T_PUBLIC_KEY -+ } type; -+ union { -+ X509 *cert; -+ EVP_PKEY *public_key; -+ struct { -+ const char *file; -+ EVP_PKEY *key; -+ X509 *cert; -+ } private_key; -+ } u; -+}; -+ -+static struct soft_token { -+ CK_VOID_PTR application; -+ CK_NOTIFY notify; -+ struct { -+ struct st_object **objs; -+ int num_objs; -+ } object; -+ struct { -+ int hardware_slot; -+ int app_error_fatal; -+ int login_done; -+ } flags; -+ int open_sessions; -+ struct session_state { -+ CK_SESSION_HANDLE session_handle; -+ -+ struct { -+ CK_ATTRIBUTE *attributes; -+ CK_ULONG num_attributes; -+ int next_object; -+ } find; -+ -+ int encrypt_object; -+ CK_MECHANISM_PTR encrypt_mechanism; -+ int decrypt_object; -+ CK_MECHANISM_PTR decrypt_mechanism; -+ int sign_object; -+ CK_MECHANISM_PTR sign_mechanism; -+ int verify_object; -+ CK_MECHANISM_PTR verify_mechanism; -+ int digest_object; -+ } state[10]; -+#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0])) -+ FILE *logfile; -+} soft_token; -+ -+static void -+application_error(const char *fmt, ...) -+{ -+ va_list ap; -+ va_start(ap, fmt); -+ vprintf(fmt, ap); -+ va_end(ap); -+ if (soft_token.flags.app_error_fatal) -+ abort(); -+} -+ -+static void -+st_logf(const char *fmt, ...) -+{ -+ va_list ap; -+ if (soft_token.logfile == NULL) -+ return; -+ va_start(ap, fmt); -+ vfprintf(soft_token.logfile, fmt, ap); -+ va_end(ap); -+ fflush(soft_token.logfile); -+} -+ -+static void -+snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...) -+{ -+ int len; -+ va_list ap; -+ len = vsnprintf(str, size, fmt, ap); -+ va_end(ap); -+ if (len < 0 || len > (int) size) -+ return; -+ while(len < (int) size) -+ str[len++] = fillchar; -+} -+ -+#ifndef TEST_APP -+#define printf error_use_st_logf -+#endif -+ -+#define VERIFY_SESSION_HANDLE(s, state) \ -+{ \ -+ CK_RV ret; \ -+ ret = verify_session_handle(s, state); \ -+ if (ret != CKR_OK) { \ -+ /* return CKR_OK */; \ -+ } \ -+} -+ -+static CK_RV -+verify_session_handle(CK_SESSION_HANDLE hSession, -+ struct session_state **state) -+{ -+ size_t i; -+ -+ for (i = 0; i < MAX_NUM_SESSION; i++){ -+ if (soft_token.state[i].session_handle == hSession) -+ break; -+ } -+ if (i == MAX_NUM_SESSION) { -+ application_error("use of invalid handle: 0x%08lx\n", -+ (unsigned long)hSession); -+ return CKR_SESSION_HANDLE_INVALID; -+ } -+ if (state) -+ *state = &soft_token.state[i]; -+ return CKR_OK; -+} -+ -+static CK_RV -+object_handle_to_object(CK_OBJECT_HANDLE handle, -+ struct st_object **object) -+{ -+ int i = HANDLE_OBJECT_ID(handle); -+ -+ *object = NULL; -+ if (i >= soft_token.object.num_objs) -+ return CKR_ARGUMENTS_BAD; -+ if (soft_token.object.objs[i] == NULL) -+ return CKR_ARGUMENTS_BAD; -+ if (soft_token.object.objs[i]->object_handle != handle) -+ return CKR_ARGUMENTS_BAD; -+ *object = soft_token.object.objs[i]; -+ return CKR_OK; -+} -+ -+static int -+attributes_match(const struct st_object *obj, -+ const CK_ATTRIBUTE *attributes, -+ CK_ULONG num_attributes) -+{ -+ CK_ULONG i; -+ int j; -+ st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj)); -+ -+ for (i = 0; i < num_attributes; i++) { -+ int match = 0; -+ for (j = 0; j < obj->num_attributes; j++) { -+ if (attributes[i].type == obj->attrs[j].attribute.type && -+ attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen && -+ memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue, -+ attributes[i].ulValueLen) == 0) { -+ match = 1; -+ break; -+ } -+ } -+ if (match == 0) { -+ st_logf("type %d attribute have no match\n", attributes[i].type); -+ return 0; -+ } -+ } -+ st_logf("attribute matches\n"); -+ return 1; -+} -+ -+static void -+print_attributes(const CK_ATTRIBUTE *attributes, -+ CK_ULONG num_attributes) -+{ -+ CK_ULONG i; -+ -+ st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes); -+ -+ for (i = 0; i < num_attributes; i++) { -+ st_logf(" type: "); -+ switch (attributes[i].type) { -+ case CKA_TOKEN: { -+ CK_BBOOL *ck_true; -+ if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) { -+ application_error("token attribute wrong length\n"); -+ break; -+ } -+ ck_true = attributes[i].pValue; -+ st_logf("token: %s", *ck_true ? "TRUE" : "FALSE"); -+ break; -+ } -+ case CKA_CLASS: { -+ CK_OBJECT_CLASS *class; -+ if (attributes[i].ulValueLen != sizeof(CK_ULONG)) { -+ application_error("class attribute wrong length\n"); -+ break; -+ } -+ class = attributes[i].pValue; -+ st_logf("class "); -+ switch (*class) { -+ case CKO_CERTIFICATE: -+ st_logf("certificate"); -+ break; -+ case CKO_PUBLIC_KEY: -+ st_logf("public key"); -+ break; -+ case CKO_PRIVATE_KEY: -+ st_logf("private key"); -+ break; -+ case CKO_SECRET_KEY: -+ st_logf("secret key"); -+ break; -+ case CKO_DOMAIN_PARAMETERS: -+ st_logf("domain parameters"); -+ break; -+ default: -+ st_logf("[class %lx]", (long unsigned)*class); -+ break; -+ } -+ break; -+ } -+ case CKA_PRIVATE: -+ st_logf("private"); -+ break; -+ case CKA_LABEL: -+ st_logf("label"); -+ break; -+ case CKA_APPLICATION: -+ st_logf("application"); -+ break; -+ case CKA_VALUE: -+ st_logf("value"); -+ break; -+ case CKA_ID: -+ st_logf("id"); -+ break; -+ default: -+ st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type); -+ break; -+ } -+ st_logf("\n"); -+ } -+} -+ -+static struct st_object * -+add_st_object(void) -+{ -+ struct st_object *o, **objs; -+ int i; -+ -+ o = malloc(sizeof(*o)); -+ if (o == NULL) -+ return NULL; -+ memset(o, 0, sizeof(*o)); -+ o->attrs = NULL; -+ o->num_attributes = 0; -+ -+ for (i = 0; i < soft_token.object.num_objs; i++) { -+ if (soft_token.object.objs == NULL) { -+ soft_token.object.objs[i] = o; -+ break; -+ } -+ } -+ if (i == soft_token.object.num_objs) { -+ objs = realloc(soft_token.object.objs, -+ (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0])); -+ if (objs == NULL) { -+ free(o); -+ return NULL; -+ } -+ soft_token.object.objs = objs; -+ soft_token.object.objs[soft_token.object.num_objs++] = o; -+ } -+ soft_token.object.objs[i]->object_handle = -+ (random() & (~OBJECT_ID_MASK)) | i; -+ -+ return o; -+} -+ -+static CK_RV -+add_object_attribute(struct st_object *o, -+ int secret, -+ CK_ATTRIBUTE_TYPE type, -+ CK_VOID_PTR pValue, -+ CK_ULONG ulValueLen) -+{ -+ struct st_attr *a; -+ int i; -+ -+ i = o->num_attributes; -+ a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0])); -+ if (a == NULL) -+ return CKR_DEVICE_MEMORY; -+ o->attrs = a; -+ o->attrs[i].secret = secret; -+ o->attrs[i].attribute.type = type; -+ o->attrs[i].attribute.pValue = malloc(ulValueLen); -+ if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0) -+ return CKR_DEVICE_MEMORY; -+ memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen); -+ o->attrs[i].attribute.ulValueLen = ulValueLen; -+ o->num_attributes++; -+ -+ return CKR_OK; -+} -+ -+static CK_RV -+add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) -+{ -+ switch (key_type) { -+ case CKK_RSA: { -+ CK_BYTE *modulus = NULL; -+ size_t modulus_len = 0; -+ CK_ULONG modulus_bits = 0; -+ CK_BYTE *exponent = NULL; -+ size_t exponent_len = 0; -+ RSA* rsa = NULL; -+ const BIGNUM *n = NULL, *e = NULL; -+ -+ rsa = EVP_PKEY_get0_RSA(key); -+ RSA_get0_key(rsa, &n, &e, NULL); -+ -+ modulus_bits = BN_num_bits(n); -+ -+ modulus_len = BN_num_bytes(n); -+ modulus = malloc(modulus_len); -+ BN_bn2bin(n, modulus); -+ -+ exponent_len = BN_num_bytes(e); -+ exponent = malloc(exponent_len); -+ BN_bn2bin(e, exponent); -+ -+ add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); -+ add_object_attribute(o, 0, CKA_MODULUS_BITS, -+ &modulus_bits, sizeof(modulus_bits)); -+ add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, -+ exponent, exponent_len); -+ -+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); -+ -+ free(modulus); -+ free(exponent); -+ } -+ default: -+ /* XXX */ -+ break; -+ } -+ return CKR_OK; -+} -+ -+ -+static int -+pem_callback(char *buf, int num, int w, void *key) -+{ -+ return -1; -+} -+ -+ -+static CK_RV -+add_certificate(char *label, -+ const char *cert_file, -+ const char *private_key_file, -+ char *id, -+ int anchor) -+{ -+ struct st_object *o = NULL; -+ CK_BBOOL bool_true = CK_TRUE; -+ CK_BBOOL bool_false = CK_FALSE; -+ CK_OBJECT_CLASS c; -+ CK_CERTIFICATE_TYPE cert_type = CKC_X_509; -+ CK_KEY_TYPE key_type; -+ CK_MECHANISM_TYPE mech_type; -+ void *cert_data = NULL; -+ size_t cert_length; -+ void *subject_data = NULL; -+ size_t subject_length; -+ void *issuer_data = NULL; -+ size_t issuer_length; -+ void *serial_data = NULL; -+ size_t serial_length; -+ CK_RV ret = CKR_GENERAL_ERROR; -+ X509 *cert; -+ EVP_PKEY *public_key; -+ -+ size_t id_len = strlen(id); -+ -+ { -+ FILE *f; -+ -+ f = fopen(cert_file, "r"); -+ if (f == NULL) { -+ st_logf("failed to open file %s\n", cert_file); -+ return CKR_GENERAL_ERROR; -+ } -+ -+ cert = PEM_read_X509(f, NULL, NULL, NULL); -+ fclose(f); -+ if (cert == NULL) { -+ st_logf("failed reading PEM cert\n"); -+ return CKR_GENERAL_ERROR; -+ } -+ -+ OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret); -+ if (ret) -+ goto out; -+ -+ OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length, -+ X509_get_issuer_name(cert), ret); -+ if (ret) -+ goto out; -+ -+ OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length, -+ X509_get_subject_name(cert), ret); -+ if (ret) -+ goto out; -+ -+ OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length, -+ X509_get_serialNumber(cert), ret); -+ if (ret) -+ goto out; -+ -+ } -+ -+ st_logf("done parsing, adding to internal structure\n"); -+ -+ o = add_st_object(); -+ if (o == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ o->type = STO_T_CERTIFICATE; -+ o->u.cert = cert; -+ public_key = X509_get_pubkey(o->u.cert); -+ -+ switch (EVP_PKEY_base_id(public_key)) { -+ case EVP_PKEY_RSA: -+ key_type = CKK_RSA; -+ break; -+ case EVP_PKEY_DSA: -+ key_type = CKK_DSA; -+ break; -+ default: -+ /* XXX */ -+ break; -+ } -+ -+ c = CKO_CERTIFICATE; -+ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); -+ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); -+ -+ add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); -+ add_object_attribute(o, 0, CKA_ID, id, id_len); -+ -+ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); -+ add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length); -+ add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length); -+ add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length); -+ if (anchor) -+ add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); -+ else -+ add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); -+ -+ st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); -+ -+ o = add_st_object(); -+ if (o == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ o->type = STO_T_PUBLIC_KEY; -+ o->u.public_key = public_key; -+ -+ c = CKO_PUBLIC_KEY; -+ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); -+ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); -+ -+ add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); -+ add_object_attribute(o, 0, CKA_ID, id, id_len); -+ add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ -+ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ -+ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); -+ mech_type = CKM_RSA_X_509; -+ add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); -+ -+ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); -+ add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); -+ -+ add_pubkey_info(o, key_type, public_key); -+ -+ st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); -+ -+ if (private_key_file) { -+ CK_FLAGS flags; -+ FILE *f; -+ -+ o = add_st_object(); -+ if (o == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ o->type = STO_T_PRIVATE_KEY; -+ o->u.private_key.file = strdup(private_key_file); -+ o->u.private_key.key = NULL; -+ -+ o->u.private_key.cert = cert; -+ -+ c = CKO_PRIVATE_KEY; -+ add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); -+ add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); -+ -+ add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); -+ add_object_attribute(o, 0, CKA_ID, id, id_len); -+ add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ -+ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ -+ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); -+ mech_type = CKM_RSA_X_509; -+ add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); -+ -+ add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); -+ add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); -+ flags = 0; -+ add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); -+ -+ add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); -+ add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); -+ add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); -+ -+ add_pubkey_info(o, key_type, public_key); -+ -+ f = fopen(private_key_file, "r"); -+ if (f == NULL) { -+ st_logf("failed to open private key\n"); -+ return CKR_GENERAL_ERROR; -+ } -+ -+ o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL); -+ fclose(f); -+ if (o->u.private_key.key == NULL) { -+ st_logf("failed to read private key a startup\n"); -+ /* don't bother with this failure for now, -+ fix it at C_Login time */; -+ } else { -+ /* XXX verify keytype */ -+ -+ if (key_type == CKK_RSA) { -+ RSA *rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); -+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); -+ } -+ -+ if (X509_check_private_key(cert, o->u.private_key.key) != 1) { -+ EVP_PKEY_free(o->u.private_key.key); -+ o->u.private_key.key = NULL; -+ st_logf("private key doesn't verify\n"); -+ } else { -+ st_logf("private key usable\n"); -+ soft_token.flags.login_done = 1; -+ } -+ } -+ } -+ -+ ret = CKR_OK; -+ out: -+ if (ret != CKR_OK) { -+ st_logf("something went wrong when adding cert!\n"); -+ -+ /* XXX wack o */; -+ } -+ free(cert_data); -+ free(serial_data); -+ free(issuer_data); -+ free(subject_data); -+ -+ return ret; -+} -+ -+static void -+find_object_final(struct session_state *state) -+{ -+ if (state->find.attributes) { -+ CK_ULONG i; -+ -+ for (i = 0; i < state->find.num_attributes; i++) { -+ if (state->find.attributes[i].pValue) -+ free(state->find.attributes[i].pValue); -+ } -+ free(state->find.attributes); -+ state->find.attributes = NULL; -+ state->find.num_attributes = 0; -+ state->find.next_object = -1; -+ } -+} -+ -+static void -+reset_crypto_state(struct session_state *state) -+{ -+ state->encrypt_object = -1; -+ if (state->encrypt_mechanism) -+ free(state->encrypt_mechanism); -+ state->encrypt_mechanism = NULL_PTR; -+ state->decrypt_object = -1; -+ if (state->decrypt_mechanism) -+ free(state->decrypt_mechanism); -+ state->decrypt_mechanism = NULL_PTR; -+ state->sign_object = -1; -+ if (state->sign_mechanism) -+ free(state->sign_mechanism); -+ state->sign_mechanism = NULL_PTR; -+ state->verify_object = -1; -+ if (state->verify_mechanism) -+ free(state->verify_mechanism); -+ state->verify_mechanism = NULL_PTR; -+ state->digest_object = -1; -+} -+ -+static void -+close_session(struct session_state *state) -+{ -+ if (state->find.attributes) { -+ application_error("application didn't do C_FindObjectsFinal\n"); -+ find_object_final(state); -+ } -+ -+ state->session_handle = CK_INVALID_HANDLE; -+ soft_token.application = NULL_PTR; -+ soft_token.notify = NULL_PTR; -+ reset_crypto_state(state); -+} -+ -+static const char * -+has_session(void) -+{ -+ return soft_token.open_sessions > 0 ? "yes" : "no"; -+} -+ -+static void -+read_conf_file(const char *fn) -+{ -+ char buf[1024], *cert, *key, *id, *label, *s, *p; -+ int anchor; -+ FILE *f; -+ -+ f = fopen(fn, "r"); -+ if (f == NULL) { -+ st_logf("can't open configuration file %s\n", fn); -+ return; -+ } -+ -+ while(fgets(buf, sizeof(buf), f) != NULL) { -+ buf[strcspn(buf, "\n")] = '\0'; -+ -+ anchor = 0; -+ -+ st_logf("line: %s\n", buf); -+ -+ p = buf; -+ while (isspace(*p)) -+ p++; -+ if (*p == '#') -+ continue; -+ while (isspace(*p)) -+ p++; -+ -+ s = NULL; -+ id = strtok_r(p, "\t", &s); -+ if (id == NULL) -+ continue; -+ label = strtok_r(NULL, "\t", &s); -+ if (label == NULL) -+ continue; -+ cert = strtok_r(NULL, "\t", &s); -+ if (cert == NULL) -+ continue; -+ key = strtok_r(NULL, "\t", &s); -+ -+ /* XXX */ -+ if (strcmp(id, "anchor") == 0) { -+ id = "\x00\x00"; -+ anchor = 1; -+ } -+ -+ st_logf("adding: %s\n", label); -+ -+ add_certificate(label, cert, key, id, anchor); -+ } -+} -+ -+static CK_RV -+func_not_supported(void) -+{ -+ st_logf("function not supported\n"); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_Initialize(CK_VOID_PTR a) -+{ -+ CK_C_INITIALIZE_ARGS_PTR args = a; -+ st_logf("Initialize\n"); -+ size_t i; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ srandom(getpid() ^ time(NULL)); -+ -+ for (i = 0; i < MAX_NUM_SESSION; i++) { -+ soft_token.state[i].session_handle = CK_INVALID_HANDLE; -+ soft_token.state[i].find.attributes = NULL; -+ soft_token.state[i].find.num_attributes = 0; -+ soft_token.state[i].find.next_object = -1; -+ reset_crypto_state(&soft_token.state[i]); -+ } -+ -+ soft_token.flags.hardware_slot = 1; -+ soft_token.flags.app_error_fatal = 0; -+ soft_token.flags.login_done = 0; -+ -+ soft_token.object.objs = NULL; -+ soft_token.object.num_objs = 0; -+ -+ soft_token.logfile = NULL; -+#if 1 -+// soft_token.logfile = stdout; -+#endif -+#if 0 -+ soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a"); -+#endif -+ -+ if (a != NULL_PTR) { -+ st_logf("\tCreateMutex:\t%p\n", args->CreateMutex); -+ st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex); -+ st_logf("\tLockMutext\t%p\n", args->LockMutex); -+ st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex); -+ st_logf("\tFlags\t%04x\n", (unsigned int)args->flags); -+ } -+ -+ { -+ char *fn = NULL, *home = NULL; -+ -+ if (getuid() == geteuid()) { -+ fn = getenv("SOFTPKCS11RC"); -+ if (fn) -+ fn = strdup(fn); -+ home = getenv("HOME"); -+ } -+ if (fn == NULL && home == NULL) { -+ struct passwd *pw = getpwuid(getuid()); -+ if(pw != NULL) -+ home = pw->pw_dir; -+ } -+ if (fn == NULL) { -+ if (home) -+ asprintf(&fn, "%s/.soft-token.rc", home); -+ else -+ fn = strdup("/etc/soft-token.rc"); -+ } -+ -+ read_conf_file(fn); -+ free(fn); -+ } -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_Finalize(CK_VOID_PTR args) -+{ -+ size_t i; -+ -+ st_logf("Finalize\n"); -+ -+ for (i = 0; i < MAX_NUM_SESSION; i++) { -+ if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) { -+ application_error("application finalized without " -+ "closing session\n"); -+ close_session(&soft_token.state[i]); -+ } -+ } -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetInfo(CK_INFO_PTR args) -+{ -+ st_logf("GetInfo\n"); -+ -+ memset(args, 17, sizeof(*args)); -+ args->cryptokiVersion.major = 2; -+ args->cryptokiVersion.minor = 10; -+ snprintf_fill((char *)args->manufacturerID, -+ sizeof(args->manufacturerID), -+ ' ', -+ "SoftToken"); -+ snprintf_fill((char *)args->libraryDescription, -+ sizeof(args->libraryDescription), ' ', -+ "SoftToken"); -+ args->libraryVersion.major = 1; -+ args->libraryVersion.minor = 8; -+ -+ return CKR_OK; -+} -+ -+extern CK_FUNCTION_LIST funcs; -+ -+CK_RV -+C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) -+{ -+ *ppFunctionList = &funcs; -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetSlotList(CK_BBOOL tokenPresent, -+ CK_SLOT_ID_PTR pSlotList, -+ CK_ULONG_PTR pulCount) -+{ -+ st_logf("GetSlotList: %s\n", -+ tokenPresent ? "tokenPresent" : "token not Present"); -+ if (pSlotList) -+ pSlotList[0] = 1; -+ *pulCount = 1; -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetSlotInfo(CK_SLOT_ID slotID, -+ CK_SLOT_INFO_PTR pInfo) -+{ -+ st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session()); -+ -+ memset(pInfo, 18, sizeof(*pInfo)); -+ -+ if (slotID != 1) -+ return CKR_ARGUMENTS_BAD; -+ -+ snprintf_fill((char *)pInfo->slotDescription, -+ sizeof(pInfo->slotDescription), -+ ' ', -+ "SoftToken (slot)"); -+ snprintf_fill((char *)pInfo->manufacturerID, -+ sizeof(pInfo->manufacturerID), -+ ' ', -+ "SoftToken (slot)"); -+ pInfo->flags = CKF_TOKEN_PRESENT; -+ if (soft_token.flags.hardware_slot) -+ pInfo->flags |= CKF_HW_SLOT; -+ pInfo->hardwareVersion.major = 1; -+ pInfo->hardwareVersion.minor = 0; -+ pInfo->firmwareVersion.major = 1; -+ pInfo->firmwareVersion.minor = 0; -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetTokenInfo(CK_SLOT_ID slotID, -+ CK_TOKEN_INFO_PTR pInfo) -+{ -+ st_logf("GetTokenInfo: %s\n", has_session()); -+ -+ memset(pInfo, 19, sizeof(*pInfo)); -+ -+ snprintf_fill((char *)pInfo->label, -+ sizeof(pInfo->label), -+ ' ', -+ "SoftToken (token)"); -+ snprintf_fill((char *)pInfo->manufacturerID, -+ sizeof(pInfo->manufacturerID), -+ ' ', -+ "SoftToken (token)"); -+ snprintf_fill((char *)pInfo->model, -+ sizeof(pInfo->model), -+ ' ', -+ "SoftToken (token)"); -+ snprintf_fill((char *)pInfo->serialNumber, -+ sizeof(pInfo->serialNumber), -+ ' ', -+ "4711"); -+ pInfo->flags = -+ CKF_TOKEN_INITIALIZED | -+ CKF_USER_PIN_INITIALIZED; -+ -+ if (soft_token.flags.login_done == 0) -+ pInfo->flags |= CKF_LOGIN_REQUIRED; -+ -+ /* CFK_RNG | -+ CKF_RESTORE_KEY_NOT_NEEDED | -+ */ -+ pInfo->ulMaxSessionCount = MAX_NUM_SESSION; -+ pInfo->ulSessionCount = soft_token.open_sessions; -+ pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION; -+ pInfo->ulRwSessionCount = soft_token.open_sessions; -+ pInfo->ulMaxPinLen = 1024; -+ pInfo->ulMinPinLen = 0; -+ pInfo->ulTotalPublicMemory = 4711; -+ pInfo->ulFreePublicMemory = 4712; -+ pInfo->ulTotalPrivateMemory = 4713; -+ pInfo->ulFreePrivateMemory = 4714; -+ pInfo->hardwareVersion.major = 2; -+ pInfo->hardwareVersion.minor = 0; -+ pInfo->firmwareVersion.major = 2; -+ pInfo->firmwareVersion.minor = 0; -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetMechanismList(CK_SLOT_ID slotID, -+ CK_MECHANISM_TYPE_PTR pMechanismList, -+ CK_ULONG_PTR pulCount) -+{ -+ st_logf("GetMechanismList\n"); -+ -+ *pulCount = 2; -+ if (pMechanismList == NULL_PTR) -+ return CKR_OK; -+ pMechanismList[0] = CKM_RSA_X_509; -+ pMechanismList[1] = CKM_RSA_PKCS; -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetMechanismInfo(CK_SLOT_ID slotID, -+ CK_MECHANISM_TYPE type, -+ CK_MECHANISM_INFO_PTR pInfo) -+{ -+ st_logf("GetMechanismInfo: slot %d type: %d\n", -+ (int)slotID, (int)type); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_InitToken(CK_SLOT_ID slotID, -+ CK_UTF8CHAR_PTR pPin, -+ CK_ULONG ulPinLen, -+ CK_UTF8CHAR_PTR pLabel) -+{ -+ st_logf("InitToken: slot %d\n", (int)slotID); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_OpenSession(CK_SLOT_ID slotID, -+ CK_FLAGS flags, -+ CK_VOID_PTR pApplication, -+ CK_NOTIFY Notify, -+ CK_SESSION_HANDLE_PTR phSession) -+{ -+ size_t i; -+ -+ st_logf("OpenSession: slot: %d\n", (int)slotID); -+ -+ if (soft_token.open_sessions == MAX_NUM_SESSION) -+ return CKR_SESSION_COUNT; -+ -+ soft_token.application = pApplication; -+ soft_token.notify = Notify; -+ -+ for (i = 0; i < MAX_NUM_SESSION; i++) -+ if (soft_token.state[i].session_handle == CK_INVALID_HANDLE) -+ break; -+ if (i == MAX_NUM_SESSION) -+ abort(); -+ -+ soft_token.open_sessions++; -+ -+ soft_token.state[i].session_handle = -+ (CK_SESSION_HANDLE)(random() & 0xfffff); -+ *phSession = soft_token.state[i].session_handle; -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_CloseSession(CK_SESSION_HANDLE hSession) -+{ -+ struct session_state *state; -+ st_logf("CloseSession\n"); -+ -+ if (verify_session_handle(hSession, &state) != CKR_OK) -+ application_error("closed session not open"); -+ else -+ close_session(state); -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_CloseAllSessions(CK_SLOT_ID slotID) -+{ -+ size_t i; -+ -+ st_logf("CloseAllSessions\n"); -+ -+ for (i = 0; i < MAX_NUM_SESSION; i++) -+ if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) -+ close_session(&soft_token.state[i]); -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_GetSessionInfo(CK_SESSION_HANDLE hSession, -+ CK_SESSION_INFO_PTR pInfo) -+{ -+ st_logf("GetSessionInfo\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ -+ memset(pInfo, 20, sizeof(*pInfo)); -+ -+ pInfo->slotID = 1; -+ if (soft_token.flags.login_done) -+ pInfo->state = CKS_RO_USER_FUNCTIONS; -+ else -+ pInfo->state = CKS_RO_PUBLIC_SESSION; -+ pInfo->flags = CKF_SERIAL_SESSION; -+ pInfo->ulDeviceError = 0; -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_Login(CK_SESSION_HANDLE hSession, -+ CK_USER_TYPE userType, -+ CK_UTF8CHAR_PTR pPin, -+ CK_ULONG ulPinLen) -+{ -+ char *pin = NULL; -+ int i; -+ -+ st_logf("Login\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ -+ if (pPin != NULL_PTR) { -+ asprintf(&pin, "%.*s", (int)ulPinLen, pPin); -+ st_logf("type: %d password: %s\n", (int)userType, pin); -+ } -+ -+ for (i = 0; i < soft_token.object.num_objs; i++) { -+ struct st_object *o = soft_token.object.objs[i]; -+ FILE *f; -+ -+ if (o->type != STO_T_PRIVATE_KEY) -+ continue; -+ -+ if (o->u.private_key.key) -+ continue; -+ -+ f = fopen(o->u.private_key.file, "r"); -+ if (f == NULL) { -+ st_logf("can't open private file: %s\n", o->u.private_key.file); -+ continue; -+ } -+ -+ o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin); -+ fclose(f); -+ if (o->u.private_key.key == NULL) { -+ st_logf("failed to read key: %s error: %s\n", -+ o->u.private_key.file, -+ ERR_error_string(ERR_get_error(), NULL)); -+ /* just ignore failure */; -+ continue; -+ } -+ -+ /* XXX check keytype */ -+ RSA *rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); -+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); -+ -+ if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) { -+ EVP_PKEY_free(o->u.private_key.key); -+ o->u.private_key.key = NULL; -+ st_logf("private key %s doesn't verify\n", o->u.private_key.file); -+ continue; -+ } -+ -+ soft_token.flags.login_done = 1; -+ } -+ free(pin); -+ -+ return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT; -+} -+ -+CK_RV -+C_Logout(CK_SESSION_HANDLE hSession) -+{ -+ st_logf("Logout\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_GetObjectSize(CK_SESSION_HANDLE hSession, -+ CK_OBJECT_HANDLE hObject, -+ CK_ULONG_PTR pulSize) -+{ -+ st_logf("GetObjectSize\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_GetAttributeValue(CK_SESSION_HANDLE hSession, -+ CK_OBJECT_HANDLE hObject, -+ CK_ATTRIBUTE_PTR pTemplate, -+ CK_ULONG ulCount) -+{ -+ struct session_state *state; -+ struct st_object *obj; -+ CK_ULONG i; -+ CK_RV ret; -+ int j; -+ -+ st_logf("GetAttributeValue: %lx\n", -+ (unsigned long)HANDLE_OBJECT_ID(hObject)); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) { -+ st_logf("object not found: %lx\n", -+ (unsigned long)HANDLE_OBJECT_ID(hObject)); -+ return ret; -+ } -+ -+ ret = CKR_OK; -+ for (i = 0; i < ulCount; i++) { -+ st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type); -+ for (j = 0; j < obj->num_attributes; j++) { -+ if (obj->attrs[j].secret) { -+ pTemplate[i].ulValueLen = (CK_ULONG)-1; -+ break; -+ } -+ if (pTemplate[i].type == obj->attrs[j].attribute.type) { -+ if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) { -+ if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen) -+ memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue, -+ obj->attrs[j].attribute.ulValueLen); -+ } -+ pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen; -+ break; -+ } -+ } -+ if (j == obj->num_attributes) { -+ st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type); -+ pTemplate[i].ulValueLen = (CK_ULONG)-1; -+ ret = CKR_ATTRIBUTE_TYPE_INVALID; -+ } -+ -+ } -+ return ret; -+} -+ -+CK_RV -+C_FindObjectsInit(CK_SESSION_HANDLE hSession, -+ CK_ATTRIBUTE_PTR pTemplate, -+ CK_ULONG ulCount) -+{ -+ struct session_state *state; -+ -+ st_logf("FindObjectsInit\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->find.next_object != -1) { -+ application_error("application didn't do C_FindObjectsFinal\n"); -+ find_object_final(state); -+ } -+ if (ulCount) { -+ CK_ULONG i; -+ -+ print_attributes(pTemplate, ulCount); -+ -+ state->find.attributes = -+ calloc(1, ulCount * sizeof(state->find.attributes[0])); -+ if (state->find.attributes == NULL) -+ return CKR_DEVICE_MEMORY; -+ for (i = 0; i < ulCount; i++) { -+ state->find.attributes[i].pValue = -+ malloc(pTemplate[i].ulValueLen); -+ if (state->find.attributes[i].pValue == NULL) { -+ find_object_final(state); -+ return CKR_DEVICE_MEMORY; -+ } -+ memcpy(state->find.attributes[i].pValue, -+ pTemplate[i].pValue, pTemplate[i].ulValueLen); -+ state->find.attributes[i].type = pTemplate[i].type; -+ state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen; -+ } -+ state->find.num_attributes = ulCount; -+ state->find.next_object = 0; -+ } else { -+ st_logf("find all objects\n"); -+ state->find.attributes = NULL; -+ state->find.num_attributes = 0; -+ state->find.next_object = 0; -+ } -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_FindObjects(CK_SESSION_HANDLE hSession, -+ CK_OBJECT_HANDLE_PTR phObject, -+ CK_ULONG ulMaxObjectCount, -+ CK_ULONG_PTR pulObjectCount) -+{ -+ struct session_state *state; -+ int i; -+ -+ st_logf("FindObjects\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->find.next_object == -1) { -+ application_error("application didn't do C_FindObjectsInit\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ if (ulMaxObjectCount == 0) { -+ application_error("application asked for 0 objects\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ *pulObjectCount = 0; -+ for (i = state->find.next_object; i < soft_token.object.num_objs; i++) { -+ st_logf("FindObjects: %d\n", i); -+ state->find.next_object = i + 1; -+ if (attributes_match(soft_token.object.objs[i], -+ state->find.attributes, -+ state->find.num_attributes)) { -+ *phObject++ = soft_token.object.objs[i]->object_handle; -+ ulMaxObjectCount--; -+ (*pulObjectCount)++; -+ if (ulMaxObjectCount == 0) -+ break; -+ } -+ } -+ return CKR_OK; -+} -+ -+CK_RV -+C_FindObjectsFinal(CK_SESSION_HANDLE hSession) -+{ -+ struct session_state *state; -+ -+ st_logf("FindObjectsFinal\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ find_object_final(state); -+ return CKR_OK; -+} -+ -+static CK_RV -+commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len, -+ const CK_MECHANISM_TYPE *mechs, int mechs_len, -+ const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, -+ struct st_object **o) -+{ -+ CK_RV ret; -+ int i; -+ -+ *o = NULL; -+ if ((ret = object_handle_to_object(hKey, o)) != CKR_OK) -+ return ret; -+ -+ ret = attributes_match(*o, attr_match, attr_match_len); -+ if (!ret) { -+ application_error("called commonInit on key that doesn't " -+ "support required attr"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ -+ for (i = 0; i < mechs_len; i++) -+ if (mechs[i] == pMechanism->mechanism) -+ break; -+ if (i == mechs_len) { -+ application_error("called mech (%08lx) not supported\n", -+ pMechanism->mechanism); -+ return CKR_ARGUMENTS_BAD; -+ } -+ return CKR_OK; -+} -+ -+ -+static CK_RV -+dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism) -+{ -+ CK_MECHANISM_PTR p; -+ -+ p = malloc(sizeof(*p)); -+ if (p == NULL) -+ return CKR_DEVICE_MEMORY; -+ -+ if (*dup) -+ free(*dup); -+ *dup = p; -+ memcpy(p, pMechanism, sizeof(*p)); -+ -+ return CKR_OK; -+} -+ -+ -+CK_RV -+C_EncryptInit(CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey) -+{ -+ struct session_state *state; -+ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; -+ CK_BBOOL bool_true = CK_TRUE; -+ CK_ATTRIBUTE attr[] = { -+ { CKA_ENCRYPT, &bool_true, sizeof(bool_true) } -+ }; -+ struct st_object *o; -+ CK_RV ret; -+ -+ st_logf("EncryptInit\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), -+ mechs, sizeof(mechs)/sizeof(mechs[0]), -+ pMechanism, hKey, &o); -+ if (ret) -+ return ret; -+ -+ ret = dup_mechanism(&state->encrypt_mechanism, pMechanism); -+ if (ret == CKR_OK) -+ state->encrypt_object = OBJECT_ID(o); -+ -+ return ret; -+} -+ -+CK_RV -+C_Encrypt(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pEncryptedData, -+ CK_ULONG_PTR pulEncryptedDataLen) -+{ -+ struct session_state *state; -+ struct st_object *o; -+ void *buffer = NULL; -+ CK_RV ret; -+ RSA *rsa; -+ int padding, len, buffer_len, padding_len; -+ -+ st_logf("Encrypt\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->encrypt_object == -1) -+ return CKR_ARGUMENTS_BAD; -+ -+ o = soft_token.object.objs[state->encrypt_object]; -+ -+ if (o->u.public_key == NULL) { -+ st_logf("public key NULL\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ -+ rsa = EVP_PKEY_get0_RSA(o->u.public_key); -+ if (rsa == NULL) -+ return CKR_ARGUMENTS_BAD; -+ -+ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ -+ -+ buffer_len = RSA_size(rsa); -+ -+ buffer = malloc(buffer_len); -+ if (buffer == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ -+ ret = CKR_OK; -+ switch(state->encrypt_mechanism->mechanism) { -+ case CKM_RSA_PKCS: -+ padding = RSA_PKCS1_PADDING; -+ padding_len = RSA_PKCS1_PADDING_SIZE; -+ break; -+ case CKM_RSA_X_509: -+ padding = RSA_NO_PADDING; -+ padding_len = 0; -+ break; -+ default: -+ ret = CKR_FUNCTION_NOT_SUPPORTED; -+ goto out; -+ } -+ -+ if (buffer_len + padding_len < (long) ulDataLen) { -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pulEncryptedDataLen == NULL) { -+ st_logf("pulEncryptedDataLen NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pData == NULL_PTR) { -+ st_logf("data NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding); -+ if (len <= 0) { -+ ret = CKR_DEVICE_ERROR; -+ goto out; -+ } -+ if (len > buffer_len) -+ abort(); -+ -+ if (pEncryptedData != NULL_PTR) -+ memcpy(pEncryptedData, buffer, len); -+ *pulEncryptedDataLen = len; -+ -+ out: -+ if (buffer) { -+ memset(buffer, 0, buffer_len); -+ free(buffer); -+ } -+ return ret; -+} -+ -+CK_RV -+C_EncryptUpdate(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pPart, -+ CK_ULONG ulPartLen, -+ CK_BYTE_PTR pEncryptedPart, -+ CK_ULONG_PTR pulEncryptedPartLen) -+{ -+ st_logf("EncryptUpdate\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+ -+CK_RV -+C_EncryptFinal(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pLastEncryptedPart, -+ CK_ULONG_PTR pulLastEncryptedPartLen) -+{ -+ st_logf("EncryptFinal\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+ -+/* C_DecryptInit initializes a decryption operation. */ -+CK_RV -+C_DecryptInit(CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey) -+{ -+ struct session_state *state; -+ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; -+ CK_BBOOL bool_true = CK_TRUE; -+ CK_ATTRIBUTE attr[] = { -+ { CKA_DECRYPT, &bool_true, sizeof(bool_true) } -+ }; -+ struct st_object *o; -+ CK_RV ret; -+ -+ st_logf("DecryptInit\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), -+ mechs, sizeof(mechs)/sizeof(mechs[0]), -+ pMechanism, hKey, &o); -+ if (ret) -+ return ret; -+ -+ ret = dup_mechanism(&state->decrypt_mechanism, pMechanism); -+ if (ret == CKR_OK) -+ state->decrypt_object = OBJECT_ID(o); -+ -+ return CKR_OK; -+} -+ -+ -+CK_RV -+C_Decrypt(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pEncryptedData, -+ CK_ULONG ulEncryptedDataLen, -+ CK_BYTE_PTR pData, -+ CK_ULONG_PTR pulDataLen) -+{ -+ struct session_state *state; -+ struct st_object *o; -+ void *buffer = NULL; -+ CK_RV ret; -+ RSA *rsa; -+ int padding, len, buffer_len, padding_len; -+ -+ st_logf("Decrypt\n"); -+ -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->decrypt_object == -1) -+ return CKR_ARGUMENTS_BAD; -+ -+ o = soft_token.object.objs[state->decrypt_object]; -+ -+ if (o->u.private_key.key == NULL) { -+ st_logf("private key NULL\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ -+ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); -+ if (rsa == NULL) -+ return CKR_ARGUMENTS_BAD; -+ -+ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ -+ -+ buffer_len = RSA_size(rsa); -+ -+ buffer = malloc(buffer_len); -+ if (buffer == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ -+ ret = CKR_OK; -+ switch(state->decrypt_mechanism->mechanism) { -+ case CKM_RSA_PKCS: -+ padding = RSA_PKCS1_PADDING; -+ padding_len = RSA_PKCS1_PADDING_SIZE; -+ break; -+ case CKM_RSA_X_509: -+ padding = RSA_NO_PADDING; -+ padding_len = 0; -+ break; -+ default: -+ ret = CKR_FUNCTION_NOT_SUPPORTED; -+ goto out; -+ } -+ -+ if (buffer_len + padding_len < (long) ulEncryptedDataLen) { -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pulDataLen == NULL) { -+ st_logf("pulDataLen NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pEncryptedData == NULL_PTR) { -+ st_logf("data NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer, -+ rsa, padding); -+ if (len <= 0) { -+ ret = CKR_DEVICE_ERROR; -+ goto out; -+ } -+ if (len > buffer_len) -+ abort(); -+ -+ if (pData != NULL_PTR) -+ memcpy(pData, buffer, len); -+ *pulDataLen = len; -+ -+ out: -+ if (buffer) { -+ memset(buffer, 0, buffer_len); -+ free(buffer); -+ } -+ return ret; -+} -+ -+ -+CK_RV -+C_DecryptUpdate(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pEncryptedPart, -+ CK_ULONG ulEncryptedPartLen, -+ CK_BYTE_PTR pPart, -+ CK_ULONG_PTR pulPartLen) -+ -+{ -+ st_logf("DecryptUpdate\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+ -+CK_RV -+C_DecryptFinal(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pLastPart, -+ CK_ULONG_PTR pulLastPartLen) -+{ -+ st_logf("DecryptFinal\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_DigestInit(CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism) -+{ -+ st_logf("DigestInit\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_SignInit(CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey) -+{ -+ struct session_state *state; -+ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; -+ CK_BBOOL bool_true = CK_TRUE; -+ CK_ATTRIBUTE attr[] = { -+ { CKA_SIGN, &bool_true, sizeof(bool_true) } -+ }; -+ struct st_object *o; -+ CK_RV ret; -+ -+ st_logf("SignInit\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), -+ mechs, sizeof(mechs)/sizeof(mechs[0]), -+ pMechanism, hKey, &o); -+ if (ret) -+ return ret; -+ -+ ret = dup_mechanism(&state->sign_mechanism, pMechanism); -+ if (ret == CKR_OK) -+ state->sign_object = OBJECT_ID(o); -+ -+ return CKR_OK; -+} -+ -+CK_RV -+C_Sign(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG_PTR pulSignatureLen) -+{ -+ struct session_state *state; -+ struct st_object *o; -+ void *buffer = NULL; -+ CK_RV ret; -+ RSA *rsa; -+ int padding, len, buffer_len; -+ size_t padding_len; -+ -+ st_logf("Sign\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->sign_object == -1) -+ return CKR_ARGUMENTS_BAD; -+ -+ o = soft_token.object.objs[state->sign_object]; -+ -+ if (o->u.private_key.key == NULL) { -+ st_logf("private key NULL\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ -+ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); -+ if (rsa == NULL) -+ return CKR_ARGUMENTS_BAD; -+ -+ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ -+ -+ buffer_len = RSA_size(rsa); -+ -+ buffer = malloc(buffer_len); -+ if (buffer == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ -+ switch(state->sign_mechanism->mechanism) { -+ case CKM_RSA_PKCS: -+ padding = RSA_PKCS1_PADDING; -+ padding_len = RSA_PKCS1_PADDING_SIZE; -+ break; -+ case CKM_RSA_X_509: -+ padding = RSA_NO_PADDING; -+ padding_len = 0; -+ break; -+ default: -+ ret = CKR_FUNCTION_NOT_SUPPORTED; -+ goto out; -+ } -+ -+ if ((size_t) buffer_len < ulDataLen + padding_len) { -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pulSignatureLen == NULL) { -+ st_logf("signature len NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pData == NULL_PTR) { -+ st_logf("data NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding); -+ st_logf("private encrypt done\n"); -+ if (len <= 0) { -+ ret = CKR_DEVICE_ERROR; -+ goto out; -+ } -+ if (len > buffer_len) -+ abort(); -+ -+ if (pSignature != NULL_PTR) -+ memcpy(pSignature, buffer, len); -+ *pulSignatureLen = len; -+ -+ ret = CKR_OK; -+ -+ out: -+ if (buffer) { -+ memset(buffer, 0, buffer_len); -+ free(buffer); -+ } -+ return ret; -+} -+ -+CK_RV -+C_SignUpdate(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pPart, -+ CK_ULONG ulPartLen) -+{ -+ st_logf("SignUpdate\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+ -+CK_RV -+C_SignFinal(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG_PTR pulSignatureLen) -+{ -+ st_logf("SignUpdate\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_VerifyInit(CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey) -+{ -+ struct session_state *state; -+ CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 }; -+ CK_BBOOL bool_true = CK_TRUE; -+ CK_ATTRIBUTE attr[] = { -+ { CKA_VERIFY, &bool_true, sizeof(bool_true) } -+ }; -+ struct st_object *o; -+ CK_RV ret; -+ -+ st_logf("VerifyInit\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]), -+ mechs, sizeof(mechs)/sizeof(mechs[0]), -+ pMechanism, hKey, &o); -+ if (ret) -+ return ret; -+ -+ ret = dup_mechanism(&state->verify_mechanism, pMechanism); -+ if (ret == CKR_OK) -+ state->verify_object = OBJECT_ID(o); -+ -+ return ret; -+} -+ -+CK_RV -+C_Verify(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG ulSignatureLen) -+{ -+ struct session_state *state; -+ struct st_object *o; -+ void *buffer = NULL; -+ CK_RV ret; -+ RSA *rsa; -+ int padding, len, buffer_len; -+ -+ st_logf("Verify\n"); -+ VERIFY_SESSION_HANDLE(hSession, &state); -+ -+ if (state->verify_object == -1) -+ return CKR_ARGUMENTS_BAD; -+ -+ o = soft_token.object.objs[state->verify_object]; -+ -+ if (o->u.public_key == NULL) { -+ st_logf("public key NULL\n"); -+ return CKR_ARGUMENTS_BAD; -+ } -+ -+ rsa = EVP_PKEY_get0_RSA(o->u.public_key); -+ if (rsa == NULL) -+ return CKR_ARGUMENTS_BAD; -+ -+ RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ -+ -+ buffer_len = RSA_size(rsa); -+ -+ buffer = malloc(buffer_len); -+ if (buffer == NULL) { -+ ret = CKR_DEVICE_MEMORY; -+ goto out; -+ } -+ -+ ret = CKR_OK; -+ switch(state->verify_mechanism->mechanism) { -+ case CKM_RSA_PKCS: -+ padding = RSA_PKCS1_PADDING; -+ break; -+ case CKM_RSA_X_509: -+ padding = RSA_NO_PADDING; -+ break; -+ default: -+ ret = CKR_FUNCTION_NOT_SUPPORTED; -+ goto out; -+ } -+ -+ if (buffer_len < (long) ulDataLen) { -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pSignature == NULL) { -+ st_logf("signature NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ if (pData == NULL_PTR) { -+ st_logf("data NULL\n"); -+ ret = CKR_ARGUMENTS_BAD; -+ goto out; -+ } -+ -+ len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding); -+ st_logf("private encrypt done\n"); -+ if (len <= 0) { -+ ret = CKR_DEVICE_ERROR; -+ goto out; -+ } -+ if (len > buffer_len) -+ abort(); -+ -+ if ((size_t) len != ulSignatureLen) { -+ ret = CKR_GENERAL_ERROR; -+ goto out; -+ } -+ -+ if (memcmp(pSignature, buffer, len) != 0) { -+ ret = CKR_GENERAL_ERROR; -+ goto out; -+ } -+ -+ out: -+ if (buffer) { -+ memset(buffer, 0, buffer_len); -+ free(buffer); -+ } -+ return ret; -+} -+ -+ -+CK_RV -+C_VerifyUpdate(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pPart, -+ CK_ULONG ulPartLen) -+{ -+ st_logf("VerifyUpdate\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_VerifyFinal(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG ulSignatureLen) -+{ -+ st_logf("VerifyFinal\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+CK_RV -+C_GenerateRandom(CK_SESSION_HANDLE hSession, -+ CK_BYTE_PTR RandomData, -+ CK_ULONG ulRandomLen) -+{ -+ st_logf("GenerateRandom\n"); -+ VERIFY_SESSION_HANDLE(hSession, NULL); -+ return CKR_FUNCTION_NOT_SUPPORTED; -+} -+ -+ -+CK_FUNCTION_LIST funcs = { -+ { 2, 11 }, -+ C_Initialize, -+ C_Finalize, -+ C_GetInfo, -+ C_GetFunctionList, -+ C_GetSlotList, -+ C_GetSlotInfo, -+ C_GetTokenInfo, -+ C_GetMechanismList, -+ C_GetMechanismInfo, -+ C_InitToken, -+ (void *)func_not_supported, /* C_InitPIN */ -+ (void *)func_not_supported, /* C_SetPIN */ -+ C_OpenSession, -+ C_CloseSession, -+ C_CloseAllSessions, -+ C_GetSessionInfo, -+ (void *)func_not_supported, /* C_GetOperationState */ -+ (void *)func_not_supported, /* C_SetOperationState */ -+ C_Login, -+ C_Logout, -+ (void *)func_not_supported, /* C_CreateObject */ -+ (void *)func_not_supported, /* C_CopyObject */ -+ (void *)func_not_supported, /* C_DestroyObject */ -+ (void *)func_not_supported, /* C_GetObjectSize */ -+ C_GetAttributeValue, -+ (void *)func_not_supported, /* C_SetAttributeValue */ -+ C_FindObjectsInit, -+ C_FindObjects, -+ C_FindObjectsFinal, -+ C_EncryptInit, -+ C_Encrypt, -+ C_EncryptUpdate, -+ C_EncryptFinal, -+ C_DecryptInit, -+ C_Decrypt, -+ C_DecryptUpdate, -+ C_DecryptFinal, -+ C_DigestInit, -+ (void *)func_not_supported, /* C_Digest */ -+ (void *)func_not_supported, /* C_DigestUpdate */ -+ (void *)func_not_supported, /* C_DigestKey */ -+ (void *)func_not_supported, /* C_DigestFinal */ -+ C_SignInit, -+ C_Sign, -+ C_SignUpdate, -+ C_SignFinal, -+ (void *)func_not_supported, /* C_SignRecoverInit */ -+ (void *)func_not_supported, /* C_SignRecover */ -+ C_VerifyInit, -+ C_Verify, -+ C_VerifyUpdate, -+ C_VerifyFinal, -+ (void *)func_not_supported, /* C_VerifyRecoverInit */ -+ (void *)func_not_supported, /* C_VerifyRecover */ -+ (void *)func_not_supported, /* C_DigestEncryptUpdate */ -+ (void *)func_not_supported, /* C_DecryptDigestUpdate */ -+ (void *)func_not_supported, /* C_SignEncryptUpdate */ -+ (void *)func_not_supported, /* C_DecryptVerifyUpdate */ -+ (void *)func_not_supported, /* C_GenerateKey */ -+ (void *)func_not_supported, /* C_GenerateKeyPair */ -+ (void *)func_not_supported, /* C_WrapKey */ -+ (void *)func_not_supported, /* C_UnwrapKey */ -+ (void *)func_not_supported, /* C_DeriveKey */ -+ (void *)func_not_supported, /* C_SeedRandom */ -+ C_GenerateRandom, -+ (void *)func_not_supported, /* C_GetFunctionStatus */ -+ (void *)func_not_supported, /* C_CancelFunction */ -+ (void *)func_not_supported /* C_WaitForSlotEvent */ -+}; -diff -up openssh/regress/unittests/Makefile.pkcs11-uri openssh/regress/unittests/Makefile ---- openssh/regress/unittests/Makefile.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/regress/unittests/Makefile 2018-10-12 13:52:55.453191425 +0200 -@@ -2,6 +2,6 @@ - - REGRESS_FAIL_EARLY?= yes - SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion --SUBDIR+=authopt -+SUBDIR+=pkcs11 authopt - - .include -diff -up openssh/regress/unittests/pkcs11/Makefile.pkcs11-uri openssh/regress/unittests/pkcs11/Makefile ---- openssh/regress/unittests/pkcs11/Makefile.pkcs11-uri 2018-10-12 13:52:55.453191425 +0200 -+++ openssh/regress/unittests/pkcs11/Makefile 2018-10-12 13:52:55.453191425 +0200 -@@ -0,0 +1,9 @@ -+ -+PROG=test_pkcs11 -+SRCS=tests.c -+REGRESS_TARGETS=run-regress-${PROG} -+ -+run-regress-${PROG}: ${PROG} -+ env ${TEST_ENV} ./${PROG} -+ -+.include -diff -up openssh/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh/regress/unittests/pkcs11/tests.c ---- openssh/regress/unittests/pkcs11/tests.c.pkcs11-uri 2018-10-12 13:52:55.453191425 +0200 -+++ openssh/regress/unittests/pkcs11/tests.c 2018-10-12 13:52:55.453191425 +0200 -@@ -0,0 +1,330 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "includes.h" -+ -+#include -+#include -+ -+#include "../test_helper/test_helper.h" -+ -+#include "sshbuf.h" -+#include "ssh-pkcs11-uri.h" -+ -+#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL) -+ -+/* prototypes are not public -- specify them here internally for tests */ -+struct sshbuf *percent_encode(const char *, size_t, char *); -+int percent_decode(char *, char **); -+ -+void -+compare_uri(struct pkcs11_uri *a, struct pkcs11_uri *b) -+{ -+ ASSERT_PTR_NE(a, NULL); -+ ASSERT_PTR_NE(b, NULL); -+ ASSERT_SIZE_T_EQ(a->id_len, b->id_len); -+ ASSERT_MEM_EQ(a->id, b->id, a->id_len); -+ if (b->object != NULL) -+ ASSERT_STRING_EQ(a->object, b->object); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->object, b->object); -+ if (b->module_path != NULL) -+ ASSERT_STRING_EQ(a->module_path, b->module_path); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->module_path, b->module_path); -+ if (b->token != NULL) -+ ASSERT_STRING_EQ(a->token, b->token); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->token, b->token); -+ if (b->manuf != NULL) -+ ASSERT_STRING_EQ(a->manuf, b->manuf); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->manuf, b->manuf); -+ if (b->lib_manuf != NULL) -+ ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); -+} -+ -+void -+check_parse_rv(char *uri, struct pkcs11_uri *expect, int expect_rv) -+{ -+ char *buf = NULL, *str; -+ struct pkcs11_uri *pkcs11uri = NULL; -+ int rv; -+ -+ if (expect_rv == 0) -+ str = "Valid"; -+ else -+ str = "Invalid"; -+ asprintf(&buf, "%s PKCS#11 URI parsing: %s", str, uri); -+ TEST_START(buf); -+ free(buf); -+ pkcs11uri = pkcs11_uri_init(); -+ rv = pkcs11_uri_parse(uri, pkcs11uri); -+ ASSERT_INT_EQ(rv, expect_rv); -+ if (rv == 0) /* in case of failure result is undefined */ -+ compare_uri(pkcs11uri, expect); -+ pkcs11_uri_cleanup(pkcs11uri); -+ free(expect); -+ TEST_DONE(); -+} -+ -+void -+check_parse(char *uri, struct pkcs11_uri *expect) -+{ -+ check_parse_rv(uri, expect, 0); -+} -+ -+struct pkcs11_uri * -+compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, -+ char *manuf, char *module_path, char *object) -+{ -+ struct pkcs11_uri *uri = pkcs11_uri_init(); -+ if (id_len > 0) { -+ uri->id_len = id_len; -+ uri->id = id; -+ } -+ uri->module_path = module_path; -+ uri->token = token; -+ uri->lib_manuf = lib_manuf; -+ uri->manuf = manuf; -+ uri->object = object; -+ return uri; -+} -+ -+static void -+test_parse_valid(void) -+{ -+ /* path arguments */ -+ check_parse("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL)); -+ check_parse("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL)); -+ check_parse("pkcs11:token=SSH%20Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); -+ check_parse("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL)); -+ check_parse("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL)); -+ check_parse("pkcs11:object=SIGN%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key")); -+ /* query arguments */ -+ check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); -+ -+ /* combinations */ -+ /* ID SHOULD be percent encoded */ -+ check_parse("pkcs11:token=SSH%20Key;id=0", -+ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL)); -+ check_parse( -+ "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, "CAC", -+ "/usr/lib64/p11-kit-proxy.so", NULL)); -+ check_parse( -+ "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, -+ "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key")); -+ -+ /* empty path component matches everything */ -+ check_parse("pkcs11:", EMPTY_URI); -+ -+ /* empty string is a valid to match against (and different from NULL) */ -+ check_parse("pkcs11:token=", -+ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL)); -+ /* Percent character needs to be percent-encoded */ -+ check_parse("pkcs11:token=%25", -+ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL)); -+} -+ -+static void -+test_parse_invalid(void) -+{ -+ /* Invalid percent encoding */ -+ check_parse_rv("pkcs11:id=%0", EMPTY_URI, -1); -+ /* Invalid percent encoding */ -+ check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); -+ /* Space MUST be percent encoded -- XXX not enforced yet */ -+ check_parse("pkcs11:token=SSH Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); -+ /* MUST NOT contain duplicate attributes of the same name */ -+ check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); -+ /* Unrecognized attribute in path are ignored with log message */ -+ check_parse("pkcs11:key_name=SSH", EMPTY_URI); -+ /* Unrecognized attribute in query SHOULD be ignored */ -+ check_parse("pkcs11:?key_name=SSH", EMPTY_URI); -+} -+ -+void -+check_gen(char *expect, struct pkcs11_uri *uri) -+{ -+ char *buf = NULL, *uri_str; -+ -+ asprintf(&buf, "Valid PKCS#11 URI generation: %s", expect); -+ TEST_START(buf); -+ free(buf); -+ uri_str = pkcs11_uri_get(uri); -+ ASSERT_PTR_NE(uri_str, NULL); -+ ASSERT_STRING_EQ(uri_str, expect); -+ free(uri_str); -+ TEST_DONE(); -+} -+ -+static void -+test_generate_valid(void) -+{ -+ /* path arguments */ -+ check_gen("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL)); -+ check_gen("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL)); -+ check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL)); -+ /* library-manufacturer is not implmented now */ -+ /*check_gen("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL));*/ -+ check_gen("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL)); -+ check_gen("pkcs11:object=RSA%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key")); -+ /* query arguments */ -+ check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); -+ -+ /* combinations */ -+ check_gen("pkcs11:id=%02;token=SSH%20Keys", -+ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL)); -+ check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL)); -+ check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key")); -+ -+ /* empty path component matches everything */ -+ check_gen("pkcs11:", EMPTY_URI); -+ -+} -+ -+void -+check_encode(char *source, size_t len, char *whitelist, char *expect) -+{ -+ char *buf = NULL; -+ struct sshbuf *b; -+ -+ asprintf(&buf, "percent_encode: expected %s", expect); -+ TEST_START(buf); -+ free(buf); -+ -+ b = percent_encode(source, len, whitelist); -+ ASSERT_STRING_EQ(sshbuf_ptr(b), expect); -+ sshbuf_free(b); -+ TEST_DONE(); -+} -+ -+static void -+test_percent_encode_multibyte(void) -+{ -+ /* SHOULD be encoded as octets according to the UTF-8 character encoding */ -+ -+ /* multi-byte characters are "for free" */ -+ check_encode("$", 1, "", "%24"); -+ check_encode("¢", 2, "", "%C2%A2"); -+ check_encode("€", 3, "", "%E2%82%AC"); -+ check_encode("𐍈", 4, "", "%F0%90%8D%88"); -+ -+ /* CK_UTF8CHAR is unsigned char (1 byte) */ -+ /* labels SHOULD be normalized to NFC [UAX15] */ -+ -+} -+ -+static void -+test_percent_encode(void) -+{ -+ /* Without whitelist encodes everything (for CKA_ID) */ -+ check_encode("A*", 2, "", "%41%2A"); -+ check_encode("\x00", 1, "", "%00"); -+ check_encode("\x7F", 1, "", "%7F"); -+ check_encode("\x80", 1, "", "%80"); -+ check_encode("\xff", 1, "", "%FF"); -+ -+ /* Default whitelist encodes anything but safe letters */ -+ check_encode("test" "\x00" "0alpha", 11, PKCS11_URI_WHITELIST, -+ "test%000alpha"); -+ check_encode(" ", 1, PKCS11_URI_WHITELIST, -+ "%20"); /* Space MUST be percent encoded */ -+ check_encode("/", 1, PKCS11_URI_WHITELIST, -+ "%2F"); /* '/' delimiter MUST be percent encoded (in the path) */ -+ check_encode("?", 1, PKCS11_URI_WHITELIST, -+ "%3F"); /* delimiter '?' MUST be percent encoded (in the path) */ -+ check_encode("#", 1, PKCS11_URI_WHITELIST, -+ "%23"); /* '#' MUST be always percent encoded */ -+ check_encode("key=value;separator?query&#anch", 35, PKCS11_URI_WHITELIST, -+ "key%3Dvalue%3Bseparator%3Fquery%26amp%3B%23anch"); -+ -+ /* Components in query can have '/' unencoded (useful for paths) */ -+ check_encode("/path/to.file", 13, PKCS11_URI_WHITELIST "/", -+ "/path/to.file"); -+} -+ -+void -+check_decode(char *source, char *expect, int expect_len) -+{ -+ char *buf = NULL, *out = NULL; -+ int rv; -+ -+ asprintf(&buf, "percent_decode: %s", source); -+ TEST_START(buf); -+ free(buf); -+ -+ rv = percent_decode(source, &out); -+ ASSERT_INT_EQ(rv, expect_len); -+ if (rv >= 0) -+ ASSERT_MEM_EQ(out, expect, expect_len); -+ free(out); -+ TEST_DONE(); -+} -+ -+static void -+test_percent_decode(void) -+{ -+ /* simple valid cases */ -+ check_decode("%00", "\x00", 1); -+ check_decode("%FF", "\xFF", 1); -+ -+ /* normal strings shold be kept intact */ -+ check_decode("strings are left", "strings are left", 16); -+ check_decode("10%25 of trees", "10% of trees", 12); -+ -+ /* make sure no more than 2 bytes are parsed */ -+ check_decode("%222", "\x22" "2", 2); -+ -+ /* invalid expects failure */ -+ check_decode("%0", "", -1); -+ check_decode("%Z", "", -1); -+ check_decode("%FG", "", -1); -+} -+ -+void -+tests(void) -+{ -+ test_percent_encode(); -+ test_percent_encode_multibyte(); -+ test_percent_decode(); -+ test_parse_valid(); -+ test_parse_invalid(); -+ test_generate_valid(); -+} -diff -up openssh/ssh-add.c.pkcs11-uri openssh/ssh-add.c ---- openssh/ssh-add.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-add.c 2018-10-12 13:52:55.454191434 +0200 -@@ -64,6 +64,7 @@ - #include "misc.h" - #include "ssherr.h" - #include "digest.h" -+#include "ssh-pkcs11-uri.h" - - /* argv0 */ - extern char *__progname; -@@ -188,6 +189,24 @@ delete_all(int agent_fd, int qflag) - return ret; - } - -+#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int); -+ -+int -+update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) -+{ -+ struct pkcs11_uri *uri; -+ -+ /* dry-run parse to make sure the URI is valid and to report errors */ -+ uri = pkcs11_uri_init(); -+ if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ pkcs11_uri_cleanup(uri); -+ -+ return update_card(agent_fd, adding, pkcs11_uri, qflag); -+} -+#endif -+ - static int - add_file(int agent_fd, const char *filename, int key_only, int qflag) - { -@@ -495,6 +514,13 @@ lock_agent(int agent_fd, int lock) - static int - do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) - { -+#ifdef ENABLE_PKCS11 -+ if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(file, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ return update_pkcs11_uri(agent_fd, !deleting, file, qflag); -+ } -+#endif - if (deleting) { - if (delete_file(agent_fd, file, key_only, qflag) == -1) - return -1; -diff -up openssh/ssh-agent.c.pkcs11-uri openssh/ssh-agent.c ---- openssh/ssh-agent.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-agent.c 2018-10-12 13:52:55.454191434 +0200 -@@ -546,10 +546,72 @@ no_identities(SocketEntry *e) - } - - #ifdef ENABLE_PKCS11 -+static char * -+sanitize_pkcs11_provider(const char *provider) -+{ -+ struct pkcs11_uri *uri = NULL; -+ char *sane_uri, *module_path = NULL; /* default path */ -+ char canonical_provider[PATH_MAX]; -+ -+ if (provider == NULL) -+ return NULL; -+ -+ if (strlen(provider) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ /* PKCS#11 URI */ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) { -+ error("Failed to init PCKS#11 URI"); -+ return NULL; -+ } -+ -+ if (pkcs11_uri_parse(provider, uri) != 0) { -+ error("Failed to parse PKCS#11 URI"); -+ return NULL; -+ } -+ /* validate also provider from URI */ -+ if (uri->module_path) -+ module_path = strdup(uri->module_path); -+ } else -+ module_path = strdup(provider); /* simple path */ -+ -+ if (module_path != NULL) { /* do not validate default NULL path in URI */ -+ if (realpath(module_path, canonical_provider) == NULL) { -+ verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", -+ module_path, strerror(errno)); -+ free(module_path); -+ pkcs11_uri_cleanup(uri); -+ return NULL; -+ } -+ free(module_path); -+ if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { -+ verbose("refusing PKCS#11 provider \"%.100s\": " -+ "not whitelisted", canonical_provider); -+ pkcs11_uri_cleanup(uri); -+ return NULL; -+ } -+ -+ /* copy verified and sanitized provider path back to the uri */ -+ if (uri) { -+ free(uri->module_path); -+ uri->module_path = xstrdup(canonical_provider); -+ } -+ } -+ -+ if (uri) { -+ sane_uri = pkcs11_uri_get(uri); -+ pkcs11_uri_cleanup(uri); -+ return sane_uri; -+ } else { -+ return xstrdup(canonical_provider); /* simple path */ -+ } -+} -+ - static void - process_add_smartcard_key(SocketEntry *e) - { -- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; -+ char *provider = NULL, *pin = NULL, *sane_uri = NULL; - int r, i, count = 0, success = 0, confirm = 0; - u_int seconds; - time_t death = 0; -@@ -585,28 +647,23 @@ process_add_smartcard_key(SocketEntry *e - goto send; - } - } -- if (realpath(provider, canonical_provider) == NULL) { -- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", -- provider, strerror(errno)); -- goto send; -- } -- if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { -- verbose("refusing PKCS#11 add of \"%.100s\": " -- "provider not whitelisted", canonical_provider); -+ -+ sane_uri = sanitize_pkcs11_provider(provider); -+ if (sane_uri == NULL) - goto send; -- } -- debug("%s: add %.100s", __func__, canonical_provider); -+ - if (lifetime && !death) - death = monotime() + lifetime; - -- count = pkcs11_add_provider(canonical_provider, pin, &keys); -+ debug("%s: add %.100s", __func__, sane_uri); -+ count = pkcs11_add_provider(sane_uri, pin, &keys); - for (i = 0; i < count; i++) { - k = keys[i]; - if (lookup_identity(k) == NULL) { - id = xcalloc(1, sizeof(Identity)); - id->key = k; -- id->provider = xstrdup(canonical_provider); -- id->comment = xstrdup(canonical_provider); /* XXX */ -+ id->provider = xstrdup(sane_uri); -+ id->comment = xstrdup(sane_uri); - id->death = death; - id->confirm = confirm; - TAILQ_INSERT_TAIL(&idtab->idlist, id, next); -@@ -620,6 +677,7 @@ process_add_smartcard_key(SocketEntry *e - send: - free(pin); - free(provider); -+ free(sane_uri); - free(keys); - send_status(e, success); - } -@@ -627,7 +685,7 @@ send: - static void - process_remove_smartcard_key(SocketEntry *e) - { -- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; -+ char *provider = NULL, *pin = NULL, *sane_uri = NULL; - int r, success = 0; - Identity *id, *nxt; - -@@ -638,30 +696,29 @@ process_remove_smartcard_key(SocketEntry - } - free(pin); - -- if (realpath(provider, canonical_provider) == NULL) { -- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", -- provider, strerror(errno)); -+ sane_uri = sanitize_pkcs11_provider(provider); -+ if (sane_uri == NULL) - goto send; -- } - -- debug("%s: remove %.100s", __func__, canonical_provider); -+ debug("%s: remove %.100s", __func__, sane_uri); - for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { - nxt = TAILQ_NEXT(id, next); - /* Skip file--based keys */ - if (id->provider == NULL) - continue; -- if (!strcmp(canonical_provider, id->provider)) { -+ if (!strcmp(sane_uri, id->provider)) { - TAILQ_REMOVE(&idtab->idlist, id, next); - free_identity(id); - idtab->nentries--; - } - } -- if (pkcs11_del_provider(canonical_provider) == 0) -+ if (pkcs11_del_provider(sane_uri) == 0) - success = 1; - else - error("%s: pkcs11_del_provider failed", __func__); - send: - free(provider); -+ free(sane_uri); - send_status(e, success); - } - #endif /* ENABLE_PKCS11 */ -diff -up openssh/ssh_config.5.pkcs11-uri openssh/ssh_config.5 ---- openssh/ssh_config.5.pkcs11-uri 2018-10-12 13:52:55.437191293 +0200 -+++ openssh/ssh_config.5 2018-10-12 13:52:55.459191475 +0200 -@@ -991,6 +991,19 @@ may also be used in conjunction with - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query argument -+.Cm module-path -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. -diff -up openssh/ssh.c.pkcs11-uri openssh/ssh.c ---- openssh/ssh.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh.c 2018-10-12 13:52:55.458191467 +0200 -@@ -769,6 +769,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) < 0) - fprintf(stderr, "Warning: Identity file %s " -@@ -1975,6 +1983,45 @@ ssh_session2(struct ssh *ssh, struct pas - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(struct passwd *pw) -@@ -1989,10 +2036,6 @@ load_public_identity_files(struct passwd - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2005,32 +2048,46 @@ load_public_identity_files(struct passwd - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = -- xstrdup(options.pkcs11_provider); /* XXX */ -- n_ids++; -- } -- free(keys); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); -+ -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = percent_expand(cp, "d", pw->pw_dir, - "u", pw->pw_name, "l", thishost, "h", host, - "r", options.user, (char *)NULL); -diff -up openssh/ssh-keygen.c.pkcs11-uri openssh/ssh-keygen.c ---- openssh/ssh-keygen.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-keygen.c 2018-10-12 13:52:55.455191442 +0200 -@@ -825,6 +825,7 @@ do_download(struct passwd *pw) - free(fp); - } else { - (void) sshkey_write(keys[i], stdout); /* XXX check */ -+ (void) pkcs11_uri_write(keys[i], stdout); - fprintf(stdout, "\n"); - } - sshkey_free(keys[i]); -diff -up openssh/ssh-pkcs11-client.c.pkcs11-uri openssh/ssh-pkcs11-client.c ---- openssh/ssh-pkcs11-client.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-pkcs11-client.c 2018-10-12 13:52:55.455191442 +0200 -@@ -126,6 +126,7 @@ pkcs11_rsa_private_encrypt(int flen, con - return (-1); - key.type = KEY_RSA; - key.rsa = rsa; -+ key.ecdsa_nid = 0; - if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { - error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); - return -1; -@@ -210,6 +211,8 @@ pkcs11_add_provider(char *name, char *pi - u_int nkeys, i; - struct sshbuf *msg; - -+ debug("%s: called, name = %s", __func__, name); -+ - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); - -@@ -226,6 +229,7 @@ pkcs11_add_provider(char *name, char *pi - if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); -+ debug("%s: nkeys = %u", __func__, nkeys); - for (i = 0; i < nkeys; i++) { - /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh/ssh-pkcs11.c.pkcs11-uri openssh/ssh-pkcs11.c ---- openssh/ssh-pkcs11.c.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-pkcs11.c 2018-10-12 13:54:35.755023297 +0200 -@@ -49,8 +49,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -59,6 +59,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -71,10 +78,46 @@ struct pkcs11_key { - RSA_METHOD *rsa_method; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ if (key->type != KEY_RSA || -+ (k11 = RSA_get_app_data(key->rsa)) == NULL) -+ return -1; -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - int - pkcs11_init(int interactive) - { -@@ -90,26 +133,63 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); -- if (!p->valid) -+ debug("%s: %p refcount %d valid %d", __func__, -+ m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug("%s: %p refcount %d", __func__, m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error("%s: %p still valid", __func__, m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared libarary, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug("%s: %p refcount %d valid %d", __func__, -+ p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -119,12 +199,11 @@ pkcs11_provider_finalize(struct pkcs11_p - static void - pkcs11_provider_unref(struct pkcs11_provider *p) - { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug("%s: %p refcount %d", __func__, p, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); -+ free(p->name); - free(p); - } - } -@@ -142,6 +221,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -156,19 +249,52 @@ pkcs11_provider_lookup(char *provider_id - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) - { -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) -+{ - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3("%s(%s): called", __func__, provider_uri); -+ -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - /* openssl callback for freeing an RSA key */ -@@ -185,6 +311,7 @@ pkcs11_rsa_finish(RSA *rsa) - pkcs11_provider_unref(k11->provider); - RSA_meth_free(k11->rsa_method); - free(k11->keyid); -+ free(k11->label); - free(k11); - } - return (rv); -@@ -201,8 +328,8 @@ pkcs11_find(struct pkcs11_provider *p, C - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -249,12 +376,13 @@ pkcs11_rsa_private_encrypt(int flen, con - error("RSA_get_app_data failed for rsa %p", rsa); - return (-1); - } -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || !k11->provider->module -+ || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider for rsa %p", rsa); - return (-1); - } -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (!pkcs11_interactive) { - error("need pin entry%s", (si->token.flags & -@@ -313,7 +441,7 @@ pkcs11_rsa_private_decrypt(int flen, con - /* redirect private key operations for rsa key to pkcs11 token */ - static int - pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - const RSA_METHOD *def = RSA_get_default_method(); -@@ -328,6 +456,11 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } - k11->rsa_method = RSA_meth_dup(def); - if (k11->rsa_method == NULL) - fatal("%s: RSA_meth_dup failed", __func__); -@@ -371,16 +504,16 @@ pkcs11_open_session(struct pkcs11_provid - CK_SESSION_HANDLE session; - int login_required; - -- f = p->function_list; -- login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; -+ f = p->module->function_list; -+ login_required = p->module->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; - if (pin && login_required && !strlen(pin)) { - error("pin required"); - return (-1); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) - != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin) { -@@ -392,9 +525,9 @@ pkcs11_open_session(struct pkcs11_provid - error("C_CloseSession failed: %lu", rv); - return (-1); - } -- p->slotinfo[slotidx].logged_in = 1; -+ p->module->slotinfo[slotidx].logged_in = 1; - } -- p->slotinfo[slotidx].session = session; -+ p->module->slotinfo[slotidx].session = session; - return (0); - } - -@@ -404,39 +537,72 @@ pkcs11_open_session(struct pkcs11_provid - * keysp points to an (possibly empty) array with *nkeys keys. - */ - static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, -- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) -+ CK_ATTRIBUTE [], size_t, CK_ATTRIBUTE [3], struct sshkey ***, int *) - __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); - - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, int *nkeys) -+ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) - { -+ size_t filter_size = 1; - CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; - CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; - CK_ATTRIBUTE pubkey_filter[] = { -- { CKA_CLASS, NULL, sizeof(pubkey_class) } -+ { CKA_CLASS, NULL, sizeof(pubkey_class) }, -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 } - }; - CK_ATTRIBUTE cert_filter[] = { -- { CKA_CLASS, NULL, sizeof(cert_class) } -+ { CKA_CLASS, NULL, sizeof(cert_class) }, -+ { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 } - }; - CK_ATTRIBUTE pubkey_attribs[] = { - { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 } - }; - CK_ATTRIBUTE cert_attribs[] = { - { CKA_ID, NULL, 0 }, -+ { CKA_LABEL, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - pubkey_filter[0].pValue = &pubkey_class; - cert_filter[0].pValue = &cert_class; - -- if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, -- keysp, nkeys) < 0 || -- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, -- keysp, nkeys) < 0) -+ if (uri->id != NULL) { -+ pubkey_filter[filter_size].pValue = uri->id; -+ pubkey_filter[filter_size].ulValueLen = uri->id_len; -+ cert_filter[filter_size].pValue = uri->id; -+ cert_filter[filter_size].ulValueLen = uri->id_len; -+ filter_size++; -+ } -+ if (uri->object != NULL) { -+ pubkey_filter[filter_size].pValue = uri->object; -+ pubkey_filter[filter_size].ulValueLen = strlen(uri->object); -+ pubkey_filter[filter_size].type = CKA_LABEL; -+ cert_filter[filter_size].pValue = uri->object; -+ cert_filter[filter_size].ulValueLen = strlen(uri->object); -+ cert_filter[filter_size].type = CKA_LABEL; -+ filter_size++; -+ } -+ -+ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, -+ pubkey_attribs, keysp, nkeys) < 0 || -+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, -+ cert_attribs, keysp, nkeys) < 0) - return (-1); -+ if (*nkeys == 0) { -+ /* Try once more without the label filter */ -+ filter_size--; -+ if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, -+ pubkey_attribs, keysp, nkeys) < 0 || -+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size, -+ cert_attribs, keysp, nkeys) < 0) -+ return (-1); -+ } - return (0); - } - -@@ -462,14 +619,15 @@ have_rsa_key(const RSA *rsa) - - static int - pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, -- CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], -+ CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4], - struct sshkey ***keysp, int *nkeys) - { - struct sshkey *key; - RSA *rsa; - X509 *x509; -- EVP_PKEY *evp; -+ EVP_PKEY *evp = NULL; - int i; -+ int nattribs = 4; - const u_char *cp; - CK_RV rv; - CK_OBJECT_HANDLE obj; -@@ -477,16 +635,15 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - /* setup a filter the looks for public keys */ -- if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { -+ if ((rv = f->C_FindObjectsInit(session, filter, filter_size)) != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - return (-1); - } - while (1) { -- /* XXX 3 attributes in attribs[] */ -- for (i = 0; i < 3; i++) { -+ for (i = 0; i < nattribs; i++) { - attribs[i].pValue = NULL; - attribs[i].ulValueLen = 0; - } -@@ -494,22 +651,22 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - || nfound == 0) - break; - /* found a key, so figure out size of the attributes */ -- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) -+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) - != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - continue; - } - /* -- * Allow CKA_ID (always first attribute) to be empty, but -- * ensure that none of the others are zero length. -+ * Allow CKA_ID (always first attribute) and CKA_LABEL (second) -+ * to be empty, but ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (attribs[1].ulValueLen == 0 || -- attribs[2].ulValueLen == 0) { -+ if (attribs[2].ulValueLen == 0 || -+ attribs[3].ulValueLen == 0) { - continue; - } - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) { -+ for (i = 0; i < nattribs; i++) { - if (attribs[i].ulValueLen > 0) { - attribs[i].pValue = xmalloc( - attribs[i].ulValueLen); -@@ -517,23 +674,23 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } - - /* -- * retrieve ID, modulus and public exponent of RSA key, -- * or ID, subject and value for certificates. -+ * retrieve ID, label, modulus and public exponent of RSA key, -+ * or ID, label, subject and value for certificates. - */ - rsa = NULL; -- if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) -+ if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) - != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); -- } else if (attribs[1].type == CKA_MODULUS ) { -+ } else if (attribs[2].type == CKA_MODULUS ) { - if ((rsa = RSA_new()) == NULL) { - error("RSA_new failed"); - } else { - BIGNUM *rsa_n, *rsa_e; - -- rsa_n = BN_bin2bn(attribs[1].pValue, -- attribs[1].ulValueLen, NULL); -- rsa_e = BN_bin2bn(attribs[2].pValue, -+ rsa_n = BN_bin2bn(attribs[2].pValue, - attribs[2].ulValueLen, NULL); -+ rsa_e = BN_bin2bn(attribs[3].pValue, -+ attribs[3].ulValueLen, NULL); - if (rsa_n != NULL && rsa_e != NULL) { - if (!RSA_set0_key(rsa, - rsa_n, rsa_e, NULL)) -@@ -544,10 +701,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - BN_free(rsa_e); - } - } else { -- cp = attribs[2].pValue; -+ cp = attribs[3].pValue; - if ((x509 = X509_new()) == NULL) { - error("X509_new failed"); -- } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) -+ } else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) - == NULL) { - error("d2i_X509 failed"); - } else if ((evp = X509_get_pubkey(x509)) == NULL || -@@ -559,9 +716,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - error("RSAPublicKey_dup"); - } - X509_free(x509); -+ EVP_PKEY_free(evp); - } - if (rsa && have_rsa_key(rsa) && -- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { -+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) { - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); - key->rsa = rsa; -@@ -580,7 +738,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } else if (rsa) { - RSA_free(rsa); - } -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattribs; i++) - free(attribs[i].pValue); - } - if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) -@@ -592,126 +750,240 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - int - pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) - { -- int nkeys, need_finalize = 0; -- struct pkcs11_provider *p = NULL; -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_add_provider_by_uri(uri, pin, keyp); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+struct pkcs11_provider * -+pkcs11_provider_initialize(struct pkcs11_uri *uri) -+{ -+ int need_finalize = 0; - void *handle = NULL; - CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); - CK_RV rv; - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -+ char *provider_module = NULL; -+ struct pkcs11_provider *p; -+ struct pkcs11_module *m; - -- *keyp = NULL; -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug("%s: provider already registered: %s", -- __func__, provider_id); -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error("%s: No module path provided", __func__); - goto fail; -+#endif -+ } else -+ provider_module = strdup(uri->module_path); -+ -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); -+ -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug("%s: provider module already initialized: %s", -+ __func__, provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ return p; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } -+ - /* open shared pkcs11-libarary */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } -- p = xcalloc(1, sizeof(*p)); -- p->name = xstrdup(provider_id); -- p->handle = handle; -+ m->handle = handle; - /* setup the pkcs11 callbacks */ - if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); -+ goto fail; -+ } -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug("%s: Skipping provider %s not matching library_manufacturer", -+ __func__, m->info.manufacturerID); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -+ if (m->nslots == 0) { - debug("%s: provider %s returned no slots", __func__, -- provider_id); -+ provider_module); - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->valid = 1; - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ -+ for (i = 0; i < m->nslots; i++) { -+ token = &m->slotinfo[i].token; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (unsigned long)i, rv); -+ "failed: %lu", provider_module, (unsigned long)i, rv); - continue; - } - if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -- debug2("%s: ignoring uninitialised token in " -- "provider %s slot %lu", __func__, -- provider_id, (unsigned long)i); - continue; - } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ return p; -+ -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ free(p); -+ if (handle) -+ dlclose(handle); -+ return NULL; -+} -+ -+int -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, struct sshkey ***keyp) -+{ -+ int nkeys; -+ struct pkcs11_provider *p = NULL; -+ CK_TOKEN_INFO *token; -+ CK_ULONG i; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); -+ -+ *keyp = NULL; -+ if ((p = pkcs11_provider_initialize(uri)) == NULL) { -+ debug("%s: failed to initialize provider: %s", -+ __func__, provider_uri); -+ goto fail; -+ } -+ -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; -+ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -+ debug2("%s: ignoring uninitialised token in " -+ "provider %s slot %lu", __func__, -+ provider_uri, (unsigned long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2("%s: ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", __func__, -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2("%s: ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", __func__, -+ token->manufacturerID, (unsigned long)i); -+ continue; -+ } - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); -- /* open session, login with pin and retrieve public keys */ -- if (pkcs11_open_session(p, i, pin) == 0) -- pkcs11_fetch_keys(p, i, keyp, &nkeys); -+ /* open session if not yet opened, login with pin -+ * and retrieve public keys */ -+ if ((p->module->slotinfo[i].session != 0) || -+ pkcs11_open_session(p, i, pin) == 0) -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); - } - if (nkeys > 0) { -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -+ free(provider_uri); - return (nkeys); - } -- debug("%s: provider %s returned no keys", __func__, provider_id); -+ debug("%s: provider %s returned no keys", __func__, provider_uri); - /* don't add the provider, since it does not have any keys */ - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); -+ free(provider_uri); - return (-1); - } - -diff -up openssh/ssh-pkcs11.h.pkcs11-uri openssh/ssh-pkcs11.h ---- openssh/ssh-pkcs11.h.pkcs11-uri 2018-10-11 02:56:36.000000000 +0200 -+++ openssh/ssh-pkcs11.h 2018-10-12 13:52:55.457191459 +0200 -@@ -14,10 +14,15 @@ - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -+ -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - - #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) - #undef ENABLE_PKCS11 -diff -up openssh/ssh-pkcs11-uri.c.pkcs11-uri openssh/ssh-pkcs11-uri.c ---- openssh/ssh-pkcs11-uri.c.pkcs11-uri 2018-10-12 13:52:55.456191450 +0200 -+++ openssh/ssh-pkcs11-uri.c 2018-10-12 13:52:55.455191442 +0200 -@@ -0,0 +1,395 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "includes.h" -+ -+#ifdef ENABLE_PKCS11 -+ -+#include -+#include -+ -+#include "sshkey.h" -+#include "sshbuf.h" -+#include "log.h" -+ -+#define CRYPTOKI_COMPAT -+#include "pkcs11.h" -+ -+#include "ssh-pkcs11-uri.h" -+ -+#define PKCS11_URI_PATH_SEPARATOR ";" -+#define PKCS11_URI_QUERY_SEPARATOR "&" -+#define PKCS11_URI_VALUE_SEPARATOR "=" -+#define PKCS11_URI_ID "id" -+#define PKCS11_URI_TOKEN "token" -+#define PKCS11_URI_OBJECT "object" -+#define PKCS11_URI_LIB_MANUF "library-manufacturer" -+#define PKCS11_URI_MANUF "manufacturer" -+#define PKCS11_URI_MODULE_PATH "module-path" -+ -+/* Keyword tokens. */ -+typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pBadOption -+} pkcs11uriOpCodes; -+ -+/* Textual representation of the tokens. */ -+static struct { -+ const char *name; -+ pkcs11uriOpCodes opcode; -+} keywords[] = { -+ { PKCS11_URI_ID, pId }, -+ { PKCS11_URI_TOKEN, pToken }, -+ { PKCS11_URI_OBJECT, pObject }, -+ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, -+ { PKCS11_URI_MANUF, pManufacturer }, -+ { PKCS11_URI_MODULE_PATH, pModulePath }, -+ { NULL, pBadOption } -+}; -+ -+static pkcs11uriOpCodes -+parse_token(const char *cp) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name; i++) -+ if (strncasecmp(cp, keywords[i].name, -+ strlen(keywords[i].name)) == 0) -+ return keywords[i].opcode; -+ -+ return pBadOption; -+} -+ -+int -+percent_decode(char *data, char **outp) -+{ -+ char tmp[3]; -+ char *out, *tmp_end; -+ char *p = data; -+ long value; -+ size_t outlen = 0; -+ -+ out = malloc(strlen(data)+1); /* upper bound */ -+ if (out == NULL) -+ return -1; -+ while (*p != '\0') { -+ switch (*p) { -+ case '%': -+ p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[0] = *p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[1] = *p++; -+ tmp[2] = '\0'; -+ tmp_end = NULL; -+ value = strtol(tmp, &tmp_end, 16); -+ if (tmp_end != tmp+2) -+ goto fail; -+ else -+ out[outlen++] = (char) value; -+ break; -+ default: -+ out[outlen++] = *p++; -+ break; -+ } -+ } -+ -+ /* zero terminate */ -+ out[outlen] = '\0'; -+ *outp = out; -+ return outlen; -+fail: -+ free(out); -+ return -1; -+} -+ -+struct sshbuf * -+percent_encode(const char *data, size_t length, const char *whitelist) -+{ -+ struct sshbuf *b = NULL; -+ char tmp[4], *cp; -+ size_t i; -+ -+ if ((b = sshbuf_new()) == NULL) -+ return NULL; -+ for (i = 0; i < length; i++) { -+ cp = strchr(whitelist, data[i]); -+ /* if c is specified as '\0' pointer to terminator is returned !! */ -+ if (cp != NULL && *cp != '\0') { -+ if (sshbuf_put(b, &data[i], 1) != 0) -+ goto err; -+ } else -+ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 -+ || sshbuf_put(b, tmp, 3) != 0) -+ goto err; -+ } -+ if (sshbuf_put(b, "\0", 1) == 0) -+ return b; -+err: -+ sshbuf_free(b); -+ return NULL; -+} -+ -+char * -+pkcs11_uri_append(char *part, const char *separator, const char *key, -+ struct sshbuf *value) -+{ -+ char *new_part; -+ size_t size = 0; -+ -+ if (value == NULL) -+ return NULL; -+ -+ size = asprintf(&new_part, -+ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", -+ (part != NULL ? part : ""), -+ (part != NULL ? separator : ""), -+ key, sshbuf_ptr(value)); -+ sshbuf_free(value); -+ free(part); -+ -+ if (size <= 0) -+ return NULL; -+ return new_part; -+} -+ -+char * -+pkcs11_uri_get(struct pkcs11_uri *uri) -+{ -+ size_t size = 0; -+ char *p = NULL, *path = NULL, *query = NULL; -+ -+ /* compose a percent-encoded ID */ -+ if (uri->id_len > 0) { -+ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_ID, key_id); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write object label */ -+ if (uri->object) { -+ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_OBJECT, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write token label */ -+ if (uri->token) { -+ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_TOKEN, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write manufacturer */ -+ if (uri->manuf) { -+ struct sshbuf *manuf = percent_encode(uri->manuf, -+ strlen(uri->manuf), PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_MANUF, manuf); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write module_path */ -+ if (uri->module_path) { -+ struct sshbuf *module = percent_encode(uri->module_path, -+ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); -+ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, -+ PKCS11_URI_MODULE_PATH, module); -+ if (query == NULL) -+ goto err; -+ } -+ -+ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", -+ path != NULL ? path : "", -+ query != NULL ? "?" : "", -+ query != NULL ? query : ""); -+err: -+ free(query); -+ free(path); -+ if (size <= 0) -+ return NULL; -+ return p; -+} -+ -+struct pkcs11_uri * -+pkcs11_uri_init() -+{ -+ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); -+ return d; -+} -+ -+void -+pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) -+{ -+ free(pkcs11->id); -+ free(pkcs11->module_path); -+ free(pkcs11->token); -+ free(pkcs11->object); -+ free(pkcs11->lib_manuf); -+ free(pkcs11->manuf); -+ free(pkcs11); -+} -+ -+int -+pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) -+{ -+ char *saveptr1, *saveptr2, *str1, *str2, *tok; -+ int rv = 0, len; -+ char *p = NULL; -+ -+ size_t scheme_len = strlen(PKCS11_URI_SCHEME); -+ if (strlen(uri) < scheme_len || /* empty URI matches everything */ -+ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { -+ error("%s: The '%s' does not look like PKCS#11 URI", -+ __func__, uri); -+ return -1; -+ } -+ -+ if (pkcs11 == NULL) { -+ error("%s: Bad arguments. The pkcs11 can't be null", __func__); -+ return -1; -+ } -+ -+ /* skip URI schema name */ -+ p = strdup(uri); -+ str1 = p; -+ -+ /* everything before ? */ -+ tok = strtok_r(str1, "?", &saveptr1); -+ if (tok == NULL) { -+ free(p); -+ error("%s: pk11-path expected, got EOF", __func__); -+ return -1; -+ } -+ -+ /* skip URI schema name: -+ * the scheme ensures that there is at least something before "?" -+ * allowing empty pk11-path. Resulting token at worst pointing to -+ * \0 byte */ -+ tok = tok + scheme_len; -+ -+ /* parse pk11-path */ -+ for (str2 = tok; ; str2 = NULL) { -+ char **charptr; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ -+ char *arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ -+ switch (opcode) { -+ case pId: -+ /* CKA_ID */ -+ if (pkcs11->id != NULL) { -+ verbose("%s: The id already set in the PKCS#11 URI", -+ __func__); -+ rv = -1; -+ } -+ len = percent_decode(arg, &pkcs11->id); -+ if (len <= 0) { -+ verbose("%s: Failed to percent-decode CKA_ID: %s", -+ __func__, arg); -+ rv = -1; -+ } else -+ pkcs11->id_len = len; -+ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", -+ __func__, arg); -+ break; -+ case pToken: -+ /* CK_TOKEN_INFO -> label */ -+ charptr = &pkcs11->token; -+ parse_string: -+ if (*charptr != NULL) { -+ verbose("%s: The %s already set in the PKCS#11 URI", -+ keywords[opcode].name, __func__); -+ rv = -1; -+ } -+ percent_decode(arg, charptr); -+ debug3("%s: Setting %s = %s from PKCS#11 URI", -+ __func__, keywords[opcode].name, *charptr); -+ break; -+ -+ case pObject: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->object; -+ goto parse_string; -+ -+ case pManufacturer: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->manuf; -+ goto parse_string; -+ -+ case pLibraryManufacturer: -+ /* CK_INFO -> manufacturerID */ -+ charptr = &pkcs11->lib_manuf; -+ goto parse_string; -+ -+ case pBadOption: -+ default: -+ /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose("%s: Unknown part of path in PKCS#11 URI: %s", -+ __func__, tok); -+ } -+ } -+ -+ tok = strtok_r(NULL, "?", &saveptr1); -+ if (tok == NULL) { -+ free(p); -+ return rv; -+ } -+ /* parse pk11-query (optional) */ -+ for (str2 = tok; ; str2 = NULL) { -+ size_t key_len = strlen(PKCS11_URI_MODULE_PATH) + 1; -+ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ if (strncasecmp(tok, PKCS11_URI_MODULE_PATH -+ PKCS11_URI_VALUE_SEPARATOR, key_len) == 0) { -+ /* module-path is PKCS11Provider */ -+ if (pkcs11->module_path != NULL) { -+ verbose("%s: Multiple module-path attributes are" -+ "not supported the PKCS#11 URI", __func__); -+ rv = -1; -+ } -+ percent_decode(tok + key_len, &pkcs11->module_path); -+ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", -+ __func__, pkcs11->module_path); -+ /* } else if ( pin-value ) { */ -+ } else { -+ /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose("%s: Unknown part of query in PKCS#11 URI: %s", -+ __func__, tok); -+ } -+ } -+ free(p); -+ return rv; -+} -+ -+#endif /* ENABLE_PKCS11 */ -diff -up openssh/ssh-pkcs11-uri.h.pkcs11-uri openssh/ssh-pkcs11-uri.h ---- openssh/ssh-pkcs11-uri.h.pkcs11-uri 2018-10-12 13:52:55.456191450 +0200 -+++ openssh/ssh-pkcs11-uri.h 2018-10-12 13:52:55.456191450 +0200 -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#define PKCS11_URI_SCHEME "pkcs11:" -+#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ -+ "0123456789_-.()" -+ -+struct pkcs11_uri { -+ /* path */ -+ char *id; -+ size_t id_len; -+ char *token; -+ char *object; -+ char *lib_manuf; -+ char *manuf; -+ /* query */ -+ char *module_path; -+}; -+ -+struct pkcs11_uri *pkcs11_uri_init(); -+void pkcs11_uri_cleanup(struct pkcs11_uri *); -+int pkcs11_uri_parse(const char *, struct pkcs11_uri *); -+struct pkcs11_uri *pkcs11_uri_init(); -+char * pkcs11_uri_get(struct pkcs11_uri *uri); -+ diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 89867b1..14cf5c3 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -5,7 +5,7 @@ diff -up openssh-7.9p1/cipher.c.fips openssh-7.9p1/cipher.c #include -+#include ++#include + #include #include @@ -154,20 +154,12 @@ diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h u_int dh_estimate(int); -@@ -51,6 +52,7 @@ u_int dh_estimate(int); - * Miniumum increased in light of DH precomputation attacks. - */ - #define DH_GRP_MIN 2048 -+#define DH_GRP_MIN_FIPS 2048 - #define DH_GRP_MAX 8192 - - /* diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c --- openssh-7.9p1/entropy.c.fips 2018-10-17 02:01:20.000000000 +0200 +++ openssh-7.9p1/entropy.c 2019-03-11 17:06:37.621878041 +0100 @@ -223,6 +223,11 @@ seed_rng(void) - fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, + OpenSSL_version_num()); + /* clean the PRNG status when exiting the program */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -175,21 +167,13 @@ diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c +#endif + #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { + if (RAND_status() == 1) debug3("RNG is ready, skipping seeding"); diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c --- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100 +++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100 -@@ -35,6 +35,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - #endif - - #include "ssh2.h" @@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = { - { NULL, -1, -1, -1}, + { NULL, -1, -1, -1 }, }; +static const struct kexalg kexalgs_fips[] = { @@ -209,22 +193,22 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c + SSH_DIGEST_SHA512 }, +# endif +#endif -+ { NULL, -1, -1, -1}, ++ { NULL, -1, -1, -1 }, +}; + + static char * + kex_alg_list_internal(char sep, const struct kexalg *algs) + { +@@ -129,7 +150,7 @@ kex_alg_list(char sep) char * kex_alg_list(char sep) { -@@ -129,7 +150,7 @@ kex_alg_list(char sep) - size_t nlen, rlen = 0; - const struct kexalg *k; +- return kex_alg_list_internal(sep, kexalgs); ++ return kex_alg_list_internal(sep, (FIPS_mode() ? kexalgs_fips : kexalgs)); + } -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -149,7 +170,7 @@ kex_alg_by_name(const char *name) + char * +@@ -149,11 +170,11 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -232,7 +216,13 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c + for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; - #ifdef GSSAPI + } +- for (k = gss_kexalgs; k->name != NULL; k++) { ++ for (k = (FIPS_mode() ? NULL : gss_kexalgs); k->name != NULL; k++) { + if (strncmp(k->name, name, strlen(k->name)) == 0) + return k; + } + return NULL; @@ -175,7 +196,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { @@ -252,19 +242,10 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c #ifdef WITH_OPENSSL -+#include ++#include #include #include -@@ -65,7 +66,7 @@ kexgex_client(struct ssh *ssh) - - nbits = dh_estimate(kex->dh_need * 8); - -- kex->min = DH_GRP_MIN; -+ kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; - kex->max = DH_GRP_MAX; - kex->nbits = nbits; - if (datafellows & SSH_BUG_DHGEX_LARGE) @@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32 r = SSH_ERR_ALLOC_FAIL; goto out; @@ -276,21 +257,6 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-7.9p1/kexgexs.c.fips openssh-7.9p1/kexgexs.c ---- openssh-7.9p1/kexgexs.c.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/kexgexs.c 2019-03-11 17:06:37.621878041 +0100 -@@ -85,9 +85,9 @@ input_kex_dh_gex_request(int type, u_int - kex->nbits = nbits; - kex->min = min; - kex->max = max; -- min = MAXIMUM(DH_GRP_MIN, min); -+ min = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); - max = MINIMUM(DH_GRP_MAX, max); -- nbits = MAXIMUM(DH_GRP_MIN, nbits); -+ nbits = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); - nbits = MINIMUM(DH_GRP_MAX, nbits); - - if (kex->max < kex->min || kex->nbits < kex->min || diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c --- openssh-7.9p1/mac.c.fips 2019-03-11 17:06:37.614877975 +0100 +++ openssh-7.9p1/mac.c 2019-03-11 17:06:37.621878041 +0100 @@ -298,11 +264,11 @@ diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c #include -+#include ++#include + #include #include - + #include @@ -54,7 +56,7 @@ struct macalg { int etm; /* Encrypt-then-MAC */ }; @@ -384,7 +350,7 @@ diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in - $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o - $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) @@ -472,15 +438,15 @@ diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c + all)) != 0) \ fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ } while (0) -- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); -- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); -- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); +- ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher); +- ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac); +- ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex); - ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); - ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); - ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); -+ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); -+ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); -+ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); ++ ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); ++ ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac); ++ ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); + ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); + ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig); @@ -539,7 +505,7 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c #include #include #endif -+#include ++#include +#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" @@ -561,14 +527,6 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -1047,7 +1059,6 @@ main(int ac, char **av) - host_arg = xstrdup(host); - - #ifdef WITH_OPENSSL -- OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - #endif - @@ -1283,6 +1294,10 @@ main(int ac, char **av) seed_rng(); @@ -577,9 +535,9 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c + logit("FIPS mode initialized"); + } + - if (options.user == NULL) - options.user = xstrdup(pw->pw_name); - + /* + * Discard other fds that are hanging around. These can cause problem + * with backgrounded ssh processes started by ControlPersist. diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c --- openssh-7.9p1/sshconnect2.c.fips 2019-03-11 17:06:37.580877655 +0100 +++ openssh-7.9p1/sshconnect2.c 2019-03-11 17:06:37.623878060 +0100 @@ -587,12 +545,12 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c #include #endif -+#include ++#include + #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -235,7 +237,8 @@ order_hostkeyalgs(char *host, struct soc +@@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc for (i = 0; i < options.num_system_hostfiles; i++) load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); @@ -602,53 +560,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); -@@ -290,23 +293,28 @@ ssh_kex2(char *host, struct sockaddr *ho - - #ifdef GSSAPI - if (options.gss_keyex) { -- /* Add the GSSAPI mechanisms currently supported on this -- * client to the key exchange algorithm proposal */ -- orig = options.kex_algorithms; -- -- if (options.gss_server_identity) -- gss_host = options.gss_server_identity; -- else if (options.gss_trust_dns) -- gss_host = (char *)get_canonical_hostname(active_state, 1); -- else -- gss_host = 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(&options.kex_algorithms, -- "%s,%s", gss, 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 = options.kex_algorithms; -+ -+ if (options.gss_server_identity) -+ gss_host = options.gss_server_identity; -+ else if (options.gss_trust_dns) -+ gss_host = (char *)get_canonical_hostname(active_state, 1); -+ else -+ gss_host = 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(&options.kex_algorithms, -+ "%s,%s", gss, orig); -+ } - } - } - #endif -@@ -326,14 +334,16 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho if (options.hostkeyalgorithms != NULL) { all_key = sshkey_alg_list(0, 0, 1, ','); if (kex_assemble_names(&options.hostkeyalgorithms, @@ -667,6 +579,64 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( +@@ -201,29 +201,34 @@ ssh_kex2(char *host, struct sockaddr *ho + + #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); +- 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); ++ 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-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c --- openssh-7.9p1/sshd.c.fips 2019-03-11 17:06:37.617878003 +0100 +++ openssh-7.9p1/sshd.c 2019-03-11 17:06:37.624878069 +0100 @@ -682,7 +652,7 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c #include #include #include -+#include ++#include +#include #include "openbsd-compat/openssl-compat.h" #endif @@ -706,15 +676,6 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1722,7 +1737,7 @@ main(int ac, char **av) - else - closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); - --#ifdef WITH_OPENSSL -+#if 0 /* FIPS */ - OpenSSL_add_all_algorithms(); - #endif - @@ -2036,6 +2051,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); @@ -752,7 +713,7 @@ diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c #include #include #include -+#include ++#include #endif #include "crypto_api.h" diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 3f46ac1..2eea250 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -411,7 +411,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c } krb5_free_principal(krb_context, princ); -@@ -331,29 +332,19 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -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); @@ -425,6 +425,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c - client->store.envvar = "KRB5CCNAME"; -#ifdef USE_CCAPI - xasprintf(&client->store.envval, "API:%s", new_ccname); +- client->store.filename = NULL; -#else - if (new_ccname[0] == ':') - new_ccname++; @@ -438,6 +439,8 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c + if (set_env) { + client->store.envvar = "KRB5CCNAME"; } + if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) + client->store.filename = xstrdup(new_ccname); -#endif #ifdef USE_PAM @@ -477,15 +480,16 @@ index 6cae720e..16e55cbc 100644 } /* This allows GSSAPI methods to do things to the childs environment based -@@ -496,8 +498,7 @@ ssh_gssapi_rekey_creds() { +@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() { char *envstr; #endif -- if (gssapi_client.store.envval == NULL && +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && - gssapi_client.store.envvar == NULL) + if (gssapi_client.store.envval == NULL) return; - + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); diff -up openssh-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 @@ -590,14 +594,6 @@ diff --git a/ssh-gss.h b/ssh-gss.h index 6593e422..245178af 100644 --- a/ssh-gss.h +++ b/ssh-gss.h -@@ -62,7 +62,6 @@ - #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" - - typedef struct { -- char *filename; - char *envvar; - char *envval; - struct passwd *owner; @@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct { int (*dochild) (ssh_gssapi_client *); int (*userok) (ssh_gssapi_client *, char *); diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index da39361..ef2c737 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -9,9 +9,9 @@ diff --git a/sshd.c b/sshd.c + if (! options.use_pam) + logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); + - seed_rng(); - /* 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 diff --git a/openssh-7.8p1-gsskex.patch b/openssh-7.8p1-gsskex.patch deleted file mode 100644 index ce35d90..0000000 --- a/openssh-7.8p1-gsskex.patch +++ /dev/null @@ -1,2905 +0,0 @@ -diff -up openssh/auth2.c.gsskex openssh/auth2.c ---- openssh/auth2.c.gsskex 2018-08-22 11:47:33.260216045 +0200 -+++ openssh/auth2.c 2018-08-22 11:47:33.307216424 +0200 -@@ -74,6 +74,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif - -@@ -81,6 +82,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - &method_passwd, -diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c ---- openssh/auth2-gss.c.gsskex 2018-08-22 11:47:33.260216045 +0200 -+++ openssh/auth2-gss.c 2018-08-22 13:00:48.722680124 +0200 -@@ -31,6 +31,7 @@ - #include - - #include -+#include - - #include "xmalloc.h" - #include "sshkey.h" -@@ -54,6 +55,44 @@ static int input_gssapi_mic(int type, u_ - 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 *); - -+/* -+ * The 'gssapi_keyex' userauth mechanism. -+ */ -+static int -+userauth_gsskeyex(struct ssh *ssh) -+{ -+ Authctxt *authctxt = ssh->authctxt; -+ int authenticated = 0; -+ struct sshbuf *b = NULL; -+ gss_buffer_desc mic, gssbuf; -+ u_int len; -+ -+ mic.value = packet_get_string(&len); -+ mic.length = len; -+ -+ packet_check_eom(); -+ -+ if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ -+ ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, -+ "gssapi-keyex"); -+ -+ gssbuf.value = sshbuf_mutable_ptr(b); -+ 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)); -+ -+ sshbuf_free(b); -+ free(mic.value); -+ -+ return (authenticated); -+} -+ - /* - * 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 +296,8 @@ input_gssapi_exchange_complete(int type, - if ((r = sshpkt_get_end(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw)); - - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) -@@ -313,7 +350,8 @@ input_gssapi_mic(int type, u_int32_t ple - 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)); - else - logit("GSSAPI MIC check failed"); - -@@ -335,6 +373,12 @@ input_gssapi_mic(int type, u_int32_t ple - return 0; - } - -+Authmethod method_gsskeyex = { -+ "gssapi-keyex", -+ userauth_gsskeyex, -+ &options.gss_authentication -+}; -+ - Authmethod method_gssapi = { - "gssapi-with-mic", - userauth_gssapi, -diff -up openssh/auth.c.gsskex openssh/auth.c ---- openssh/auth.c.gsskex 2018-08-22 11:47:33.274216158 +0200 -+++ openssh/auth.c 2018-08-22 11:47:33.308216432 +0200 -@@ -395,6 +395,7 @@ auth_root_allowed(struct ssh *ssh, const - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -+ strcmp(method, "gssapi-keyex") == 0 || - strcmp(method, "gssapi-with-mic") == 0) - return 1; - break; -diff -up openssh/clientloop.c.gsskex openssh/clientloop.c ---- openssh/clientloop.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/clientloop.c 2018-08-22 11:47:33.309216441 +0200 -@@ -112,6 +112,10 @@ - #include "ssherr.h" - #include "hostfile.h" - -+#ifdef GSSAPI -+#include "ssh-gss.h" -+#endif -+ - /* import options */ - extern Options options; - -@@ -1357,9 +1361,18 @@ client_loop(struct ssh *ssh, int have_pt - break; - - /* Do channel operations unless rekeying in progress. */ -- if (!ssh_packet_is_rekeying(ssh)) -+ if (!ssh_packet_is_rekeying(ssh)) { - channel_after_select(ssh, readset, writeset); - -+#ifdef GSSAPI -+ if (options.gss_renewal_rekey && -+ ssh_gssapi_credentials_updated(NULL)) { -+ debug("credentials updated - forcing rekey"); -+ need_rekeying = 1; -+ } -+#endif -+ } -+ - /* Buffer input from the connection. */ - client_process_net_input(readset); - -diff -up openssh/configure.ac.gsskex openssh/configure.ac ---- openssh/configure.ac.gsskex 2018-08-22 11:47:33.296216335 +0200 -+++ openssh/configure.ac 2018-08-22 11:47:33.309216441 +0200 -@@ -673,6 +673,30 @@ main() { if (NSVersionOfRunTimeLibrary(" - [Use tunnel device compatibility to OpenBSD]) - AC_DEFINE([SSH_TUN_PREPEND_AF], [1], - [Prepend the address family to IP tunnel traffic]) -+ AC_MSG_CHECKING(if we have the Security Authorization Session API) -+ AC_TRY_COMPILE([#include ], -+ [SessionCreate(0, 0);], -+ [ac_cv_use_security_session_api="yes" -+ AC_DEFINE(USE_SECURITY_SESSION_API, 1, -+ [platform has the Security Authorization Session API]) -+ LIBS="$LIBS -framework Security" -+ AC_MSG_RESULT(yes)], -+ [ac_cv_use_security_session_api="no" -+ AC_MSG_RESULT(no)]) -+ AC_MSG_CHECKING(if we have an in-memory credentials cache) -+ AC_TRY_COMPILE( -+ [#include ], -+ [cc_context_t c; -+ (void) cc_initialize (&c, 0, NULL, NULL);], -+ [AC_DEFINE(USE_CCAPI, 1, -+ [platform uses an in-memory credentials cache]) -+ LIBS="$LIBS -framework Security" -+ AC_MSG_RESULT(yes) -+ if test "x$ac_cv_use_security_session_api" = "xno"; then -+ AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***) -+ fi], -+ [AC_MSG_RESULT(no)] -+ ) - m4_pattern_allow([AU_IPv]) - AC_CHECK_DECL([AU_IPv4], [], - AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c ---- openssh/gss-genr.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/gss-genr.c 2018-08-22 13:18:47.444383602 +0200 -@@ -35,18 +35,179 @@ - #include - #include - #include -+#include - - #include "xmalloc.h" - #include "ssherr.h" - #include "sshbuf.h" - #include "log.h" - #include "ssh2.h" -+#include "cipher.h" -+#include "sshkey.h" -+#include "kex.h" - - #include "ssh-gss.h" - - extern u_char *session_id2; - extern u_int session_id2_len; - -+typedef struct { -+ char *encoded; -+ gss_OID oid; -+} ssh_gss_kex_mapping; -+ -+/* -+ * XXX - It would be nice to find a more elegant way of handling the -+ * XXX passing of the key exchange context to the userauth routines -+ */ -+ -+Gssctxt *gss_kex_context = NULL; -+ -+static ssh_gss_kex_mapping *gss_enc2oid = NULL; -+ -+int -+ssh_gssapi_oid_table_ok() { -+ return (gss_enc2oid != NULL); -+} -+ -+/* -+ * Return a list of the gss-group1-sha1 mechanisms supported by this program -+ * -+ * We test mechanisms to ensure that we can use them, to avoid starting -+ * a key exchange with a bad mechanism -+ */ -+ -+char * -+ssh_gssapi_client_mechanisms(const char *host, const char *client) { -+ gss_OID_set gss_supported; -+ OM_uint32 min_status; -+ -+ if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) -+ return NULL; -+ -+ return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, -+ host, client)); -+} -+ -+char * -+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, -+ const char *host, const char *client) { -+ struct sshbuf *buf; -+ size_t i; -+ int oidpos, enclen, r; -+ char *mechs, *encoded; -+ u_char digest[EVP_MAX_MD_SIZE]; -+ char deroid[2]; -+ const EVP_MD *evp_md = EVP_md5(); -+ EVP_MD_CTX *md; -+ -+ if (gss_enc2oid != NULL) { -+ for (i = 0; gss_enc2oid[i].encoded != NULL; i++) -+ free(gss_enc2oid[i].encoded); -+ free(gss_enc2oid); -+ } -+ -+ gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * -+ (gss_supported->count + 1)); -+ -+ if ((buf = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ -+ md = EVP_MD_CTX_new(); -+ oidpos = 0; -+ for (i = 0; i < gss_supported->count; i++) { -+ if (gss_supported->elements[i].length < 128 && -+ (*check)(NULL, &(gss_supported->elements[i]), host, client)) { -+ -+ deroid[0] = SSH_GSS_OIDTYPE; -+ deroid[1] = gss_supported->elements[i].length; -+ -+ EVP_DigestInit(md, evp_md); -+ EVP_DigestUpdate(md, deroid, 2); -+ EVP_DigestUpdate(md, -+ gss_supported->elements[i].elements, -+ gss_supported->elements[i].length); -+ EVP_DigestFinal(md, digest, NULL); -+ -+ encoded = xmalloc(EVP_MD_size(evp_md) * 2); -+ enclen = __b64_ntop(digest, EVP_MD_size(evp_md), -+ encoded, EVP_MD_size(evp_md) * 2); -+ -+ if (oidpos != 0) -+ if ((r = sshbuf_put_u8(buf, ',')) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID, -+ sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 || -+ (r = sshbuf_put(buf, encoded, enclen)) != 0 || -+ (r = sshbuf_put_u8(buf, ',')) != 0 || -+ (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, -+ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 || -+ (r = sshbuf_put(buf, encoded, enclen)) != 0 || -+ (r = sshbuf_put_u8(buf, ',')) != 0 || -+ (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID, -+ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 || -+ (r = sshbuf_put(buf, encoded, enclen)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); -+ gss_enc2oid[oidpos].encoded = encoded; -+ oidpos++; -+ } -+ } -+ EVP_MD_CTX_free(md); -+ gss_enc2oid[oidpos].oid = NULL; -+ gss_enc2oid[oidpos].encoded = NULL; -+ -+ if ((r = sshbuf_put_u8(buf, '\0')) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ mechs = xmalloc(sshbuf_len(buf)); -+ sshbuf_get(buf, mechs, sshbuf_len(buf)); -+ sshbuf_free(buf); -+ -+ if (strlen(mechs) == 0) { -+ free(mechs); -+ mechs = NULL; -+ } -+ -+ return (mechs); -+} -+ -+gss_OID -+ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { -+ int i = 0; -+ -+ switch (kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; -+ break; -+ case KEX_GSS_GRP14_SHA1: -+ if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; -+ break; -+ case KEX_GSS_GEX_SHA1: -+ if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) -+ return GSS_C_NO_OID; -+ name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; -+ break; -+ default: -+ return GSS_C_NO_OID; -+ } -+ -+ while (gss_enc2oid[i].encoded != NULL && -+ strcmp(name, gss_enc2oid[i].encoded) != 0) -+ i++; -+ -+ if (gss_enc2oid[i].oid != NULL && ctx != NULL) -+ ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid); -+ -+ return gss_enc2oid[i].oid; -+} -+ - /* sshbuf_get for gss_buffer_desc */ - int - ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -218,7 +373,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de - } - - ctx->major = gss_init_sec_context(&ctx->minor, -- GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, -+ ctx->client_creds, &ctx->context, ctx->name, ctx->oid, - GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, - 0, NULL, recv_tok, NULL, send_tok, flags, NULL); - -@@ -248,8 +403,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con - } - - OM_uint32 -+ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) -+{ -+ gss_buffer_desc gssbuf; -+ gss_name_t gssname; -+ OM_uint32 status; -+ gss_OID_set oidset; -+ -+ gssbuf.value = (void *) name; -+ gssbuf.length = strlen(gssbuf.value); -+ -+ gss_create_empty_oid_set(&status, &oidset); -+ gss_add_oid_set_member(&status, ctx->oid, &oidset); -+ -+ ctx->major = gss_import_name(&ctx->minor, &gssbuf, -+ GSS_C_NT_USER_NAME, &gssname); -+ -+ if (!ctx->major) -+ ctx->major = gss_acquire_cred(&ctx->minor, -+ gssname, 0, oidset, GSS_C_INITIATE, -+ &ctx->client_creds, NULL, NULL); -+ -+ gss_release_name(&status, &gssname); -+ gss_release_oid_set(&status, &oidset); -+ -+ if (ctx->major) -+ ssh_gssapi_error(ctx); -+ -+ return(ctx->major); -+} -+ -+OM_uint32 - ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) - { -+ if (ctx == NULL) -+ return -1; -+ - if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, - GSS_C_QOP_DEFAULT, buffer, hash))) - ssh_gssapi_error(ctx); -@@ -257,6 +446,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer - return (ctx->major); - } - -+/* Priviledged when used by server */ -+OM_uint32 -+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) -+{ -+ if (ctx == NULL) -+ return -1; -+ -+ ctx->major = gss_verify_mic(&ctx->minor, ctx->context, -+ gssbuf, gssmic, NULL); -+ -+ return (ctx->major); -+} -+ - void - ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, - const char *context) -@@ -273,11 +475,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co - } - - int --ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) -+ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, -+ const char *client) - { - gss_buffer_desc token = GSS_C_EMPTY_BUFFER; - OM_uint32 major, minor; - gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; -+ Gssctxt *intctx = NULL; -+ -+ if (ctx == NULL) -+ ctx = &intctx; - - /* RFC 4462 says we MUST NOT do SPNEGO */ - if (oid->length == spnego_oid.length && -@@ -287,6 +494,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx - ssh_gssapi_build_ctx(ctx); - ssh_gssapi_set_oid(*ctx, oid); - major = ssh_gssapi_import_name(*ctx, host); -+ -+ if (!GSS_ERROR(major) && client) -+ major = ssh_gssapi_client_identity(*ctx, client); -+ - if (!GSS_ERROR(major)) { - major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, - NULL); -@@ -296,10 +507,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx - GSS_C_NO_BUFFER); - } - -- if (GSS_ERROR(major)) -+ if (GSS_ERROR(major) || intctx != NULL) - ssh_gssapi_delete_ctx(ctx); - - return (!GSS_ERROR(major)); - } - -+int -+ssh_gssapi_credentials_updated(Gssctxt *ctxt) { -+ static gss_name_t saved_name = GSS_C_NO_NAME; -+ static OM_uint32 saved_lifetime = 0; -+ static gss_OID saved_mech = GSS_C_NO_OID; -+ static gss_name_t name; -+ static OM_uint32 last_call = 0; -+ OM_uint32 lifetime, now, major, minor; -+ int equal; -+ -+ now = time(NULL); -+ -+ if (ctxt) { -+ debug("Rekey has happened - updating saved versions"); -+ -+ if (saved_name != GSS_C_NO_NAME) -+ gss_release_name(&minor, &saved_name); -+ -+ major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, -+ &saved_name, &saved_lifetime, NULL, NULL); -+ -+ if (!GSS_ERROR(major)) { -+ saved_mech = ctxt->oid; -+ saved_lifetime+= now; -+ } else { -+ /* Handle the error */ -+ } -+ return 0; -+ } -+ -+ if (now - last_call < 10) -+ return 0; -+ -+ last_call = now; -+ -+ if (saved_mech == GSS_C_NO_OID) -+ return 0; -+ -+ major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, -+ &name, &lifetime, NULL, NULL); -+ if (major == GSS_S_CREDENTIALS_EXPIRED) -+ return 0; -+ else if (GSS_ERROR(major)) -+ return 0; -+ -+ major = gss_compare_name(&minor, saved_name, name, &equal); -+ gss_release_name(&minor, &name); -+ if (GSS_ERROR(major)) -+ return 0; -+ -+ if (equal && (saved_lifetime < lifetime + now - 10)) -+ return 1; -+ -+ return 0; -+} -+ - #endif /* GSSAPI */ -diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c ---- openssh/gss-serv.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/gss-serv.c 2018-08-22 11:47:33.310216448 +0200 -@@ -44,17 +44,19 @@ - #include "session.h" - #include "misc.h" - #include "servconf.h" -+#include "uidswap.h" - - #include "ssh-gss.h" -+#include "monitor_wrap.h" - - extern ServerOptions options; - - static ssh_gssapi_client gssapi_client = -- { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, -- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; -+ { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, -+ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL}, 0, 0}; - - ssh_gssapi_mech gssapi_null_mech = -- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; -+ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; - - #ifdef KRB5 - extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -141,6 +143,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss - } - - /* Unprivileged */ -+char * -+ssh_gssapi_server_mechanisms() { -+ if (supported_oids == NULL) -+ ssh_gssapi_prepare_supported_oids(); -+ return (ssh_gssapi_kex_mechs(supported_oids, -+ &ssh_gssapi_server_check_mech, NULL, NULL)); -+} -+ -+/* Unprivileged */ -+int -+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, -+ const char *dummy) { -+ Gssctxt *ctx = NULL; -+ int res; -+ -+ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); -+ ssh_gssapi_delete_ctx(&ctx); -+ -+ return (res); -+} -+ -+/* Unprivileged */ - void - ssh_gssapi_supported_oids(gss_OID_set *oidset) - { -@@ -150,7 +174,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o - gss_OID_set supported; - - gss_create_empty_oid_set(&min_status, oidset); -- gss_indicate_mechs(&min_status, &supported); -+ -+ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) -+ return; - - while (supported_mechs[i]->name != NULL) { - if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -276,8 +302,48 @@ OM_uint32 - ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - { - int i = 0; -+ int equal = 0; -+ gss_name_t new_name = GSS_C_NO_NAME; -+ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; -+ -+ if (options.gss_store_rekey && client->used && ctx->client_creds) { -+ if (client->mech->oid.length != ctx->oid->length || -+ (memcmp(client->mech->oid.elements, -+ ctx->oid->elements, ctx->oid->length) !=0)) { -+ debug("Rekeyed credentials have different mechanism"); -+ return GSS_S_COMPLETE; -+ } -+ -+ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &new_name, -+ NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ -+ ctx->major = gss_compare_name(&ctx->minor, client->name, -+ new_name, &equal); -+ -+ if (GSS_ERROR(ctx->major)) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ -+ if (!equal) { -+ debug("Rekeyed credentials have different name"); -+ return GSS_S_COMPLETE; -+ } -+ -+ debug("Marking rekeyed credentials for export"); - -- gss_buffer_desc ename; -+ gss_release_name(&ctx->minor, &client->name); -+ gss_release_cred(&ctx->minor, &client->creds); -+ client->name = new_name; -+ client->creds = ctx->client_creds; -+ ctx->client_creds = GSS_C_NO_CREDENTIAL; -+ client->updated = 1; -+ return GSS_S_COMPLETE; -+ } - - client->mech = NULL; - -@@ -292,6 +358,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - if (client->mech == NULL) - return GSS_S_FAILURE; - -+ if (ctx->client_creds && -+ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ - if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, - &client->displayname, NULL))) { - ssh_gssapi_error(ctx); -@@ -309,6 +382,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - return (ctx->major); - } - -+ gss_release_buffer(&ctx->minor, &ename); -+ - /* We can't copy this structure, so we just move the pointer to it */ - client->creds = ctx->client_creds; - ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -319,11 +394,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g - void - ssh_gssapi_cleanup_creds(void) - { -- if (gssapi_client.store.filename != NULL) { -- /* Unlink probably isn't sufficient */ -- debug("removing gssapi cred file\"%s\"", -- gssapi_client.store.filename); -- unlink(gssapi_client.store.filename); -+ krb5_ccache ccache = NULL; -+ krb5_error_code problem; -+ -+ if (gssapi_client.store.data != NULL) { -+ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug("%s: krb5_cc_destroy(): %.100s", __func__, -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else { -+ krb5_free_context(gssapi_client.store.data); -+ gssapi_client.store.data = NULL; -+ } - } - } - -@@ -356,7 +440,7 @@ ssh_gssapi_do_child(char ***envp, u_int - - /* Privileged */ - int --ssh_gssapi_userok(char *user) -+ssh_gssapi_userok(char *user, struct passwd *pw) - { - OM_uint32 lmin; - -@@ -366,9 +450,11 @@ ssh_gssapi_userok(char *user) - return 0; - } - if (gssapi_client.mech && gssapi_client.mech->userok) -- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) -+ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { -+ gssapi_client.used = 1; -+ gssapi_client.store.owner = pw; - return 1; -- else { -+ } else { - /* Destroy delegated credentials if userok fails */ - gss_release_buffer(&lmin, &gssapi_client.displayname); - gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -382,14 +468,89 @@ ssh_gssapi_userok(char *user) - return (0); - } - --/* Privileged */ --OM_uint32 --ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) -+/* These bits are only used for rekeying. The unpriviledged child is running -+ * as the user, the monitor is root. -+ * -+ * In the child, we want to : -+ * *) Ask the monitor to store our credentials into the store we specify -+ * *) If it succeeds, maybe do a PAM update -+ */ -+ -+/* Stuff for PAM */ -+ -+#ifdef USE_PAM -+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, -+ struct pam_response **resp, void *data) - { -- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, -- gssbuf, gssmic, NULL); -+ return (PAM_CONV_ERR); -+} -+#endif - -- return (ctx->major); -+void -+ssh_gssapi_rekey_creds() { -+ int ok; -+ int ret; -+#ifdef USE_PAM -+ pam_handle_t *pamh = NULL; -+ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; -+ char *envstr; -+#endif -+ -+ if (gssapi_client.store.envval == NULL && -+ gssapi_client.store.envvar == NULL) -+ return; -+ -+ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -+ -+ if (!ok) -+ return; -+ -+ debug("Rekeyed credentials stored successfully"); -+ -+ /* Actually managing to play with the ssh pam stack from here will -+ * be next to impossible. In any case, we may want different options -+ * 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) -+ return; -+ -+ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, -+ gssapi_client.store.envval); -+ -+ ret = pam_putenv(pamh, envstr); -+ if (!ret) -+ pam_setcred(pamh, PAM_REINITIALIZE_CRED); -+ pam_end(pamh, PAM_SUCCESS); -+#endif -+} -+ -+int -+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { -+ int ok = 0; -+ -+ /* Check we've got credentials to store */ -+ if (!gssapi_client.updated) -+ return 0; -+ -+ gssapi_client.updated = 0; -+ -+ temporarily_use_uid(gssapi_client.store.owner); -+ if (gssapi_client.mech && gssapi_client.mech->updatecreds) -+ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); -+ else -+ debug("No update function for this mechanism"); -+ -+ restore_uid(); -+ -+ return ok; - } - - /* Privileged */ -diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c ---- openssh/gss-serv-krb5.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/gss-serv-krb5.c 2018-08-22 11:47:33.311216457 +0200 -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - krb5_error_code problem; - krb5_principal princ; - OM_uint32 maj_status, min_status; -- int len; -+ const char *new_ccname, *new_cctype; - const char *errmsg; - - if (client->creds == NULL) { -@@ -180,11 +180,23 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - return; - } - -- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); -+ new_cctype = krb5_cc_get_type(krb_context, ccache); -+ new_ccname = krb5_cc_get_name(krb_context, ccache); -+ - client->store.envvar = "KRB5CCNAME"; -- len = strlen(client->store.filename) + 6; -- client->store.envval = xmalloc(len); -- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); -+#ifdef USE_CCAPI -+ xasprintf(&client->store.envval, "API:%s", new_ccname); -+#else -+ if (new_ccname[0] == ':') -+ new_ccname++; -+ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); -+ if (strcmp(new_cctype, "DIR") == 0) { -+ char *p; -+ p = strrchr(client->store.envval, '/'); -+ if (p) -+ *p = '\0'; -+ } -+#endif - - #ifdef USE_PAM - if (options.use_pam) -@@ -193,9 +205,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - - krb5_cc_close(krb_context, ccache); - -+ client->store.data = krb_context; -+ - return; - } - -+int -+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, -+ ssh_gssapi_client *client) -+{ -+ krb5_ccache ccache = NULL; -+ krb5_principal principal = NULL; -+ char *name = NULL; -+ krb5_error_code problem; -+ OM_uint32 maj_status, min_status; -+ -+ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { -+ logit("krb5_cc_resolve(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ return 0; -+ } -+ -+ /* Find out who the principal in this cache is */ -+ if ((problem = krb5_cc_get_principal(krb_context, ccache, -+ &principal))) { -+ logit("krb5_cc_get_principal(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { -+ logit("krb5_unparse_name(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ -+ if (strcmp(name,client->exportedname.value)!=0) { -+ debug("Name in local credentials cache differs. Not storing"); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ krb5_free_unparsed_name(krb_context, name); -+ return 0; -+ } -+ krb5_free_unparsed_name(krb_context, name); -+ -+ /* Name matches, so lets get on with it! */ -+ -+ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { -+ logit("krb5_cc_initialize(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ krb5_free_principal(krb_context, principal); -+ -+ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, -+ ccache))) { -+ logit("gss_krb5_copy_ccache() failed. Sorry!"); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ return 1; -+} -+ - ssh_gssapi_mech gssapi_kerberos_mech = { - "toWM5Slw5Ew8Mqkay+al2g==", - "Kerberos", -@@ -203,7 +282,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { - NULL, - &ssh_gssapi_krb5_userok, - NULL, -- &ssh_gssapi_krb5_storecreds -+ &ssh_gssapi_krb5_storecreds, -+ &ssh_gssapi_krb5_updatecreds - }; - - #endif /* KRB5 */ -diff -up openssh/kex.c.gsskex openssh/kex.c ---- openssh/kex.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/kex.c 2018-08-22 11:47:33.311216457 +0200 -@@ -54,6 +54,10 @@ - #include "sshbuf.h" - #include "digest.h" - -+#ifdef GSSAPI -+#include "ssh-gss.h" -+#endif -+ - /* prototype */ - static int kex_choose_conf(struct ssh *); - static int kex_input_newkeys(int, u_int32_t, struct ssh *); -@@ -103,6 +107,11 @@ static const struct kexalg kexalgs[] = { - { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ -+#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+#endif - { NULL, -1, -1, -1}, - }; - -@@ -136,6 +145,12 @@ kex_alg_by_name(const char *name) - for (k = kexalgs; k->name != NULL; k++) { - if (strcmp(k->name, name) == 0) - return k; -+#ifdef GSSAPI -+ if (strncmp(name, "gss-", 4) == 0) { -+ if (strncmp(k->name, name, strlen(k->name)) == 0) -+ return k; -+ } -+#endif - } - return NULL; - } -diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c ---- openssh/kexgssc.c.gsskex 2018-08-22 11:47:33.311216457 +0200 -+++ openssh/kexgssc.c 2018-08-22 11:47:33.311216457 +0200 -@@ -0,0 +1,341 @@ -+/* -+ * 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 -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "includes.h" -+ -+#ifdef GSSAPI -+ -+#include "includes.h" -+ -+#include -+#include -+ -+#include -+ -+#include "xmalloc.h" -+#include "sshbuf.h" -+#include "ssh2.h" -+#include "sshkey.h" -+#include "cipher.h" -+#include "kex.h" -+#include "log.h" -+#include "packet.h" -+#include "dh.h" -+#include "digest.h" -+ -+#include "ssh-gss.h" -+ -+int -+kexgss_client(struct ssh *ssh) { -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; -+ Gssctxt *ctxt; -+ OM_uint32 maj_status, min_status, ret_flags; -+ u_int klen, kout, slen = 0, strlen; -+ DH *dh; -+ BIGNUM *dh_server_pub = NULL; -+ BIGNUM *shared_secret = NULL; -+ BIGNUM *p = NULL; -+ BIGNUM *g = NULL; -+ const BIGNUM *pub_key, *p1, *g1; -+ u_char *kbuf; -+ u_char *serverhostkey = NULL; -+ u_char *empty = ""; -+ char *msg; -+ char *lang; -+ int type = 0; -+ int first = 1; -+ int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ -+ /* Initialise our GSSAPI world */ -+ ssh_gssapi_build_ctx(&ctxt); -+ if (ssh_gssapi_id_kex(ctxt, ssh->kex->name, ssh->kex->kex_type) -+ == GSS_C_NO_OID) -+ fatal("Couldn't identify host exchange"); -+ -+ if (ssh_gssapi_import_name(ctxt, ssh->kex->gss_host)) -+ fatal("Couldn't import hostname"); -+ -+ if (ssh->kex->gss_client && -+ ssh_gssapi_client_identity(ctxt, ssh->kex->gss_client)) -+ fatal("Couldn't acquire client credentials"); -+ -+ switch (ssh->kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ dh = dh_new_group1(); -+ break; -+ case KEX_GSS_GRP14_SHA1: -+ dh = dh_new_group14(); -+ break; -+ case KEX_GSS_GEX_SHA1: -+ debug("Doing group exchange\n"); -+ nbits = dh_estimate(ssh->kex->we_need * 8); -+ packet_start(SSH2_MSG_KEXGSS_GROUPREQ); -+ packet_put_int(min); -+ packet_put_int(nbits); -+ packet_put_int(max); -+ -+ packet_send(); -+ -+ packet_read_expect(SSH2_MSG_KEXGSS_GROUP); -+ -+ if ((p = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum2(p); -+ if ((g = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum2(g); -+ packet_check_eom(); -+ -+ if (BN_num_bits(p) < min || BN_num_bits(p) > max) -+ fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", -+ min, BN_num_bits(p), max); -+ -+ dh = dh_new_group(g, p); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); -+ } -+ -+ /* Step 1 - e is pub_key */ -+ dh_gen_key(dh, ssh->kex->we_need * 8); -+ DH_get0_key(dh, &pub_key, NULL); -+ -+ /* This is f, we initialise it now to make life easier */ -+ dh_server_pub = BN_new(); -+ if (dh_server_pub == NULL) -+ fatal("dh_server_pub == NULL"); -+ -+ token_ptr = GSS_C_NO_BUFFER; -+ -+ do { -+ debug("Calling gss_init_sec_context"); -+ -+ maj_status = ssh_gssapi_init_ctx(ctxt, -+ ssh->kex->gss_deleg_creds, token_ptr, &send_tok, -+ &ret_flags); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length != 0) { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ } -+ fatal("gss_init_context failed"); -+ } -+ -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ free(recv_tok.value); -+ -+ if (maj_status == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); -+ -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } -+ -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (first) { -+ packet_start(SSH2_MSG_KEXGSS_INIT); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ packet_put_bignum2((BIGNUM *)pub_key); -+ first = 0; -+ } else { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, -+ send_tok.length); -+ } -+ packet_send(); -+ gss_release_buffer(&min_status, &send_tok); -+ -+ /* If we've sent them data, they should reply */ -+ do { -+ type = packet_read(); -+ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ debug("Received KEXGSS_HOSTKEY"); -+ if (serverhostkey) -+ fatal("Server host key received more than once"); -+ serverhostkey = -+ packet_get_string(&slen); -+ } -+ } while (type == SSH2_MSG_KEXGSS_HOSTKEY); -+ -+ switch (type) { -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ debug("Received GSSAPI_CONTINUE"); -+ if (maj_status == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ recv_tok.value = packet_get_string(&strlen); -+ recv_tok.length = strlen; -+ break; -+ case SSH2_MSG_KEXGSS_COMPLETE: -+ debug("Received GSSAPI_COMPLETE"); -+ packet_get_bignum2(dh_server_pub); -+ msg_tok.value = packet_get_string(&strlen); -+ msg_tok.length = strlen; -+ -+ /* Is there a token included? */ -+ if (packet_get_char()) { -+ recv_tok.value= -+ packet_get_string(&strlen); -+ recv_tok.length = strlen; -+ /* If we're already complete - protocol error */ -+ if (maj_status == GSS_S_COMPLETE) -+ packet_disconnect("Protocol error: received token when complete"); -+ } else { -+ /* No token included */ -+ if (maj_status != GSS_S_COMPLETE) -+ packet_disconnect("Protocol error: did not receive final token"); -+ } -+ break; -+ case SSH2_MSG_KEXGSS_ERROR: -+ debug("Received Error"); -+ maj_status = packet_get_int(); -+ min_status = packet_get_int(); -+ msg = packet_get_string(NULL); -+ lang = packet_get_string(NULL); -+ fatal("GSSAPI Error: \n%.400s",msg); -+ default: -+ packet_disconnect("Protocol error: didn't expect packet type %d", -+ type); -+ } -+ token_ptr = &recv_tok; -+ } else { -+ /* No data, and not complete */ -+ if (maj_status != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ /* -+ * We _must_ have received a COMPLETE message in reply from the -+ * server, which will have set dh_server_pub and msg_tok -+ */ -+ -+ if (type != SSH2_MSG_KEXGSS_COMPLETE) -+ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -+ -+ /* Check f in range [1, p-1] */ -+ if (!dh_pub_is_valid(dh, dh_server_pub)) -+ packet_disconnect("bad server public DH value"); -+ -+ /* compute K=f^x mod p */ -+ klen = DH_size(dh); -+ kbuf = xmalloc(klen); -+ kout = DH_compute_key(kbuf, dh_server_pub, dh); -+ if ((int)kout < 0) -+ fatal("DH_compute_key: failed"); -+ -+ shared_secret = BN_new(); -+ if (shared_secret == NULL) -+ fatal("kexgss_client: BN_new failed"); -+ -+ if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) -+ fatal("kexdh_client: BN_bin2bn failed"); -+ -+ memset(kbuf, 0, klen); -+ free(kbuf); -+ -+ hashlen = sizeof(hash); -+ switch (ssh->kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, -+ ssh->kex->server_version_string, -+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), -+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), -+ (serverhostkey ? serverhostkey : empty), slen, -+ pub_key, /* e */ -+ dh_server_pub, /* f */ -+ shared_secret, /* K */ -+ hash, &hashlen -+ ); -+ break; -+ case KEX_GSS_GEX_SHA1: -+ DH_get0_pqg(dh, &p1, NULL, &g1); -+ kexgex_hash( -+ ssh->kex->hash_alg, -+ ssh->kex->client_version_string, -+ ssh->kex->server_version_string, -+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), -+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), -+ (serverhostkey ? serverhostkey : empty), slen, -+ min, nbits, max, -+ p, g, -+ pub_key, -+ dh_server_pub, -+ shared_secret, -+ hash, &hashlen -+ ); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); -+ } -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ /* Verify that the hash matches the MIC we just got. */ -+ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) -+ packet_disconnect("Hash's MIC didn't verify"); -+ -+ free(msg_tok.value); -+ -+ DH_free(dh); -+ if (serverhostkey) -+ free(serverhostkey); -+ BN_clear_free(dh_server_pub); -+ -+ /* save session id */ -+ if (ssh->kex->session_id == NULL) { -+ ssh->kex->session_id_len = hashlen; -+ ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); -+ memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); -+ } -+ -+ if (ssh->kex->gss_deleg_creds) -+ ssh_gssapi_credentials_updated(ctxt); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); -+ BN_clear_free(shared_secret); -+ return kex_send_newkeys(ssh); -+} -+ -+#endif /* GSSAPI */ -diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c ---- openssh/kexgsss.c.gsskex 2018-08-22 11:47:33.311216457 +0200 -+++ openssh/kexgsss.c 2018-08-22 11:47:33.311216457 +0200 -@@ -0,0 +1,300 @@ -+/* -+ * 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 -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "includes.h" -+ -+#ifdef GSSAPI -+ -+#include -+ -+#include -+#include -+ -+#include "xmalloc.h" -+#include "sshbuf.h" -+#include "ssh2.h" -+#include "sshkey.h" -+#include "cipher.h" -+#include "kex.h" -+#include "log.h" -+#include "packet.h" -+#include "dh.h" -+#include "ssh-gss.h" -+#include "monitor_wrap.h" -+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ -+#include "servconf.h" -+#include "ssh-gss.h" -+#include "digest.h" -+ -+extern ServerOptions options; -+ -+int -+kexgss_server(struct ssh *ssh) -+{ -+ OM_uint32 maj_status, min_status; -+ -+ /* -+ * Some GSSAPI implementations use the input value of ret_flags (an -+ * output variable) as a means of triggering mechanism specific -+ * features. Initializing it to zero avoids inadvertently -+ * activating this non-standard behaviour. -+ */ -+ -+ OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf, recv_tok, msg_tok; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ Gssctxt *ctxt = NULL; -+ u_int slen, klen, kout; -+ u_char *kbuf; -+ DH *dh; -+ int min = -1, max = -1, nbits = -1; -+ int cmin = -1, cmax = -1; /* client proposal */ -+ BIGNUM *shared_secret = NULL; -+ BIGNUM *dh_client_pub = NULL; -+ int type = 0; -+ gss_OID oid; -+ char *mechs; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ const BIGNUM *p, *g, *pub_key; -+ -+ /* Initialise GSSAPI */ -+ -+ /* If we're rekeying, privsep means that some of the private structures -+ * in the GSSAPI code are no longer available. This kludges them back -+ * into life -+ */ -+ if (!ssh_gssapi_oid_table_ok()) -+ if ((mechs = ssh_gssapi_server_mechanisms())) -+ free(mechs); -+ -+ debug2("%s: Identifying %s", __func__, ssh->kex->name); -+ oid = ssh_gssapi_id_kex(NULL, ssh->kex->name, ssh->kex->kex_type); -+ if (oid == GSS_C_NO_OID) -+ fatal("Unknown gssapi mechanism"); -+ -+ debug2("%s: Acquiring credentials", __func__); -+ -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) -+ fatal("Unable to acquire credentials for the server"); -+ -+ switch (ssh->kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ dh = dh_new_group1(); -+ break; -+ case KEX_GSS_GRP14_SHA1: -+ dh = dh_new_group14(); -+ break; -+ case KEX_GSS_GEX_SHA1: -+ debug("Doing group exchange"); -+ packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); -+ /* store client proposal to provide valid signature */ -+ cmin = packet_get_int(); -+ nbits = packet_get_int(); -+ cmax = packet_get_int(); -+ min = MAX(DH_GRP_MIN, cmin); -+ max = MIN(DH_GRP_MAX, cmax); -+ packet_check_eom(); -+ if (max < min || nbits < min || max < nbits) -+ fatal("GSS_GEX, bad parameters: %d !< %d !< %d", -+ min, nbits, max); -+ dh = PRIVSEP(choose_dh(min, nbits, max)); -+ if (dh == NULL) -+ packet_disconnect("Protocol error: no matching group found"); -+ -+ DH_get0_pqg(dh, &p, NULL, &g); -+ packet_start(SSH2_MSG_KEXGSS_GROUP); -+ packet_put_bignum2((BIGNUM *)p); -+ packet_put_bignum2((BIGNUM *)g); -+ packet_send(); -+ -+ packet_write_wait(); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); -+ } -+ -+ dh_gen_key(dh, ssh->kex->we_need * 8); -+ -+ do { -+ debug("Wait SSH2_MSG_GSSAPI_INIT"); -+ type = packet_read(); -+ switch(type) { -+ case SSH2_MSG_KEXGSS_INIT: -+ if (dh_client_pub != NULL) -+ fatal("Received KEXGSS_INIT after initialising"); -+ recv_tok.value = packet_get_string(&slen); -+ recv_tok.length = slen; -+ -+ if ((dh_client_pub = BN_new()) == NULL) -+ fatal("dh_client_pub == NULL"); -+ -+ packet_get_bignum2(dh_client_pub); -+ -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ break; -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ recv_tok.value = packet_get_string(&slen); -+ recv_tok.length = slen; -+ break; -+ default: -+ packet_disconnect( -+ "Protocol error: didn't expect packet type %d", -+ type); -+ } -+ -+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags)); -+ -+ free(recv_tok.value); -+ -+ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -+ fatal("Zero length token output when incomplete"); -+ -+ if (dh_client_pub == NULL) -+ fatal("No client public key"); -+ -+ if (maj_status & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, send_tok.length); -+ packet_send(); -+ gss_release_buffer(&min_status, &send_tok); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length > 0) { -+ packet_start(SSH2_MSG_KEXGSS_CONTINUE); -+ packet_put_string(send_tok.value, send_tok.length); -+ packet_send(); -+ } -+ fatal("accept_ctx died"); -+ } -+ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual Authentication flag wasn't set"); -+ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity flag wasn't set"); -+ -+ if (!dh_pub_is_valid(dh, dh_client_pub)) -+ packet_disconnect("bad client public DH value"); -+ -+ klen = DH_size(dh); -+ kbuf = xmalloc(klen); -+ kout = DH_compute_key(kbuf, dh_client_pub, dh); -+ if ((int)kout < 0) -+ fatal("DH_compute_key: failed"); -+ -+ shared_secret = BN_new(); -+ if (shared_secret == NULL) -+ fatal("kexgss_server: BN_new failed"); -+ -+ if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) -+ fatal("kexgss_server: BN_bin2bn failed"); -+ -+ memset(kbuf, 0, klen); -+ free(kbuf); -+ -+ DH_get0_key(dh, &pub_key, NULL); -+ hashlen = sizeof(hash); -+ switch (ssh->kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ kex_dh_hash(ssh->kex->hash_alg, -+ ssh->kex->client_version_string, ssh->kex->server_version_string, -+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), -+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), -+ NULL, 0, /* Change this if we start sending host keys */ -+ dh_client_pub, pub_key, shared_secret, -+ hash, &hashlen -+ ); -+ break; -+ case KEX_GSS_GEX_SHA1: -+ kexgex_hash( -+ ssh->kex->hash_alg, -+ ssh->kex->client_version_string, ssh->kex->server_version_string, -+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), -+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), -+ NULL, 0, -+ cmin, nbits, cmax, -+ p, g, -+ dh_client_pub, -+ pub_key, -+ shared_secret, -+ hash, &hashlen -+ ); -+ break; -+ default: -+ fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); -+ } -+ -+ BN_clear_free(dh_client_pub); -+ -+ if (ssh->kex->session_id == NULL) { -+ ssh->kex->session_id_len = hashlen; -+ ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); -+ memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); -+ } -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) -+ fatal("Couldn't get MIC"); -+ -+ packet_start(SSH2_MSG_KEXGSS_COMPLETE); -+ packet_put_bignum2(pub_key); -+ packet_put_string(msg_tok.value,msg_tok.length); -+ -+ if (send_tok.length != 0) { -+ packet_put_char(1); /* true */ -+ packet_put_string(send_tok.value, send_tok.length); -+ } else { -+ packet_put_char(0); /* false */ -+ } -+ packet_send(); -+ -+ gss_release_buffer(&min_status, &send_tok); -+ gss_release_buffer(&min_status, &msg_tok); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ DH_free(dh); -+ -+ kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); -+ BN_clear_free(shared_secret); -+ kex_send_newkeys(ssh); -+ -+ /* If this was a rekey, then save out any delegated credentials we -+ * just exchanged. */ -+ if (options.gss_store_rekey) -+ ssh_gssapi_rekey_creds(); -+ return 0; -+} -+#endif /* GSSAPI */ -diff -up openssh/kex.h.gsskex openssh/kex.h ---- openssh/kex.h.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/kex.h 2018-08-22 11:47:33.311216457 +0200 -@@ -100,6 +100,11 @@ enum kex_exchange { - KEX_DH_GEX_SHA256, - KEX_ECDH_SHA2, - KEX_C25519_SHA256, -+#ifdef GSSAPI -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GEX_SHA1, -+#endif - KEX_MAX - }; - -@@ -148,6 +153,12 @@ struct kex { - u_int flags; - int hash_alg; - int ec_nid; -+#ifdef GSSAPI -+ int gss_deleg_creds; -+ int gss_trust_dns; -+ char *gss_host; -+ char *gss_client; -+#endif - char *client_version_string; - char *server_version_string; - char *failed_choice; -@@ -197,6 +208,10 @@ int kexecdh_client(struct ssh *); - int kexecdh_server(struct ssh *); - int kexc25519_client(struct ssh *); - int kexc25519_server(struct ssh *); -+#ifdef GSSAPI -+int kexgss_client(struct ssh *); -+int kexgss_server(struct ssh *); -+#endif - - int kex_dh_hash(int, const char *, const char *, - const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh/Makefile.in.gsskex openssh/Makefile.in ---- openssh/Makefile.in.gsskex 2018-08-22 11:47:33.312216465 +0200 -+++ openssh/Makefile.in 2018-08-22 13:19:54.955928277 +0200 -@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - readpass.o ttymodes.o xmalloc.o addrmatch.o \ - atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ -+ kexgssc.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ -@@ -121,7 +122,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.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 \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -up openssh/monitor.c.gsskex openssh/monitor.c ---- openssh/monitor.c.gsskex 2018-08-22 11:47:33.263216069 +0200 -+++ openssh/monitor.c 2018-08-22 13:22:19.589095240 +0200 -@@ -146,6 +146,8 @@ int mm_answer_gss_setup_ctx(int, struct - int mm_answer_gss_accept_ctx(int, struct sshbuf *); - int mm_answer_gss_userok(int, struct sshbuf *); - int mm_answer_gss_checkmic(int, struct sshbuf *); -+int mm_answer_gss_sign(int, struct sshbuf *); -+int mm_answer_gss_updatecreds(int, struct sshbuf *); - #endif - - #ifdef SSH_AUDIT_EVENTS -@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, - {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, - {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, -+ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, - #endif - {0, 0, NULL} - }; - - struct mon_table mon_dispatch_postauth20[] = { -+#ifdef GSSAPI -+ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, -+ {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, -+ {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, -+ {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, -+#endif - #ifdef WITH_OPENSSL - {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, - #endif -@@ -293,6 +302,10 @@ monitor_child_preauth(Authctxt *_authctx - /* Permit requests for moduli and signatures */ - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); -+#ifdef GSSAPI -+ /* and for the GSSAPI key exchange */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); -+#endif - - /* The first few requests do not require asynchronous access */ - while (!authenticated) { -@@ -405,6 +418,10 @@ monitor_child_postauth(struct monitor *p - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -+#ifdef GSSAPI -+ /* and for the GSSAPI key exchange */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); -+#endif - - if (auth_opts->permit_pty_flag) { - monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1695,6 +1712,13 @@ monitor_apply_keystate(struct monitor *p - # endif - #endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kexc25519_server; -+#ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; -+ } -+#endif - kex->load_host_public_key=&get_hostkey_public_by_type; - kex->load_host_private_key=&get_hostkey_private_by_type; - kex->host_key_index=&get_hostkey_index; -@@ -1785,7 +1809,7 @@ mm_answer_gss_setup_ctx(int sock, struct - u_char *p; - int r; - -- if (!options.gss_authentication) -+ if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - - if ((r = sshbuf_get_string(m, &p, &len)) != 0) -@@ -1818,7 +1842,7 @@ mm_answer_gss_accept_ctx(int sock, struc - OM_uint32 flags = 0; /* GSI needs this */ - int r; - -- if (!options.gss_authentication) -+ if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - - if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) -@@ -1839,6 +1863,7 @@ mm_answer_gss_accept_ctx(int sock, struc - monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); - monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); - } - return (0); - } -@@ -1850,7 +1875,7 @@ mm_answer_gss_checkmic(int sock, struct - OM_uint32 ret; - int r; - -- if (!options.gss_authentication) -+ if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - - if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || -@@ -1880,10 +1905,11 @@ mm_answer_gss_userok(int sock, struct ss - int r, authenticated; - const char *displayname; - -- if (!options.gss_authentication) -+ if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - -- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); -+ authenticated = authctxt->valid && -+ ssh_gssapi_userok(authctxt->user, authctxt->pw); - - sshbuf_reset(m); - if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1900,5 +1926,74 @@ mm_answer_gss_userok(int sock, struct ss - /* Monitor loop will terminate if authenticated */ - return (authenticated); - } -+ -+int -+mm_answer_gss_sign(int socket, struct sshbuf *m) -+{ -+ gss_buffer_desc data; -+ gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; -+ OM_uint32 major, minor; -+ int r; -+ -+ if (!options.gss_authentication && !options.gss_keyex) -+ fatal("In GSSAPI monitor when GSSAPI is disabled"); -+ -+ if ((r = sshbuf_get_string(m, (u_char **)&data.value, &data.length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ if (data.length != 20) -+ fatal("%s: data length incorrect: %d", __func__, -+ (int) data.length); -+ -+ /* Save the session ID on the first time around */ -+ if (session_id2_len == 0) { -+ session_id2_len = data.length; -+ session_id2 = xmalloc(session_id2_len); -+ memcpy(session_id2, data.value, session_id2_len); -+ } -+ major = ssh_gssapi_sign(gsscontext, &data, &hash); -+ -+ free(data.value); -+ -+ sshbuf_reset(m); -+ if ((r = sshbuf_put_u32(m, major)) != 0 || -+ (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); -+ -+ gss_release_buffer(&minor, &hash); -+ -+ /* Turn on getpwnam permissions */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); -+ -+ /* And credential updating, for when rekeying */ -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); -+ -+ return (0); -+} -+ -+int -+mm_answer_gss_updatecreds(int socket, struct sshbuf *m) { -+ ssh_gssapi_ccache store; -+ int ok, r; -+ -+ if ((r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || -+ (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ ok = ssh_gssapi_update_creds(&store); -+ -+ free(store.envvar); -+ free(store.envval); -+ -+ sshbuf_reset(m); -+ if ((r = sshbuf_put_u32(m, ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); -+ -+ return(0); -+} -+ - #endif /* GSSAPI */ - -diff -up openssh/monitor.h.gsskex openssh/monitor.h ---- openssh/monitor.h.gsskex 2018-08-22 11:47:33.263216069 +0200 -+++ openssh/monitor.h 2018-08-22 11:47:33.313216473 +0200 -@@ -58,6 +58,8 @@ enum monitor_reqtype { - #ifdef WITH_SELINUX - MONITOR_REQ_AUTHROLE = 80, - #endif -+ MONITOR_REQ_GSSSIGN = 82, MONITOR_ANS_GSSSIGN = 83, -+ MONITOR_REQ_GSSUPCREDS = 84, MONITOR_ANS_GSSUPCREDS = 85, - - MONITOR_REQ_PAM_START = 100, - MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.gsskex 2018-08-22 11:47:33.313216473 +0200 -+++ openssh/monitor_wrap.c 2018-08-22 13:27:38.665669643 +0200 -@@ -1004,7 +1004,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss - } - - int --mm_ssh_gssapi_userok(char *user) -+mm_ssh_gssapi_userok(char *user, struct passwd *pw) - { - struct sshbuf *m; - int r, authenticated = 0; -@@ -1023,4 +1023,52 @@ mm_ssh_gssapi_userok(char *user) - debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); - return (authenticated); - } -+ -+OM_uint32 -+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) -+{ -+ struct sshbuf *m; -+ OM_uint32 major; -+ int r; -+ -+ if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); -+ -+ if ((r = sshbuf_get_u32(m, &major)) != 0 || -+ (r = sshbuf_get_string(m, (u_char **)&hash->value, &hash->length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ sshbuf_free(m); -+ -+ return (major); -+} -+ -+int -+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) -+{ -+ struct sshbuf *m; -+ int ok, r; -+ -+ if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ -+ if ((r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || -+ (r = sshbuf_put_cstring(m, store->envval ? store->envval : "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); -+ -+ if ((r = sshbuf_get_u32(m, &ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ -+ sshbuf_free(m); -+ -+ return (ok); -+} - #endif /* GSSAPI */ -diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.gsskex 2018-08-22 11:47:33.263216069 +0200 -+++ openssh/monitor_wrap.h 2018-08-22 11:47:33.313216473 +0200 -@@ -63,8 +63,10 @@ int mm_sshkey_verify(const struct sshkey - OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); - OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, - gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); --int mm_ssh_gssapi_userok(char *user); -+int mm_ssh_gssapi_userok(char *user, struct passwd *); - OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); -+OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); -+int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); - #endif - - #ifdef USE_PAM -diff -up openssh/readconf.c.gsskex openssh/readconf.c ---- openssh/readconf.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/readconf.c 2018-08-22 13:28:17.487982869 +0200 -@@ -161,6 +161,8 @@ typedef enum { - oClearAllForwardings, oNoHostAuthenticationForLocalhost, - oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, - oAddressFamily, oGssAuthentication, oGssDelegateCreds, -+ oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, -+ oGssServerIdentity, - oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, - oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, - oHashKnownHosts, -@@ -201,10 +203,19 @@ static struct { - /* Sometimes-unsupported options */ - #if defined(GSSAPI) - { "gssapiauthentication", oGssAuthentication }, -+ { "gssapikeyexchange", oGssKeyEx }, - { "gssapidelegatecredentials", oGssDelegateCreds }, -+ { "gssapitrustdns", oGssTrustDns }, -+ { "gssapiclientidentity", oGssClientIdentity }, -+ { "gssapiserveridentity", oGssServerIdentity }, -+ { "gssapirenewalforcesrekey", oGssRenewalRekey }, - # else - { "gssapiauthentication", oUnsupported }, -+ { "gssapikeyexchange", oUnsupported }, - { "gssapidelegatecredentials", oUnsupported }, -+ { "gssapitrustdns", oUnsupported }, -+ { "gssapiclientidentity", oUnsupported }, -+ { "gssapirenewalforcesrekey", oUnsupported }, - #endif - #ifdef ENABLE_PKCS11 - { "smartcarddevice", oPKCS11Provider }, -@@ -973,10 +984,30 @@ parse_time: - intptr = &options->gss_authentication; - goto parse_flag; - -+ case oGssKeyEx: -+ intptr = &options->gss_keyex; -+ goto parse_flag; -+ - case oGssDelegateCreds: - intptr = &options->gss_deleg_creds; - goto parse_flag; - -+ case oGssTrustDns: -+ intptr = &options->gss_trust_dns; -+ goto parse_flag; -+ -+ case oGssClientIdentity: -+ charptr = &options->gss_client_identity; -+ goto parse_string; -+ -+ case oGssServerIdentity: -+ charptr = &options->gss_server_identity; -+ goto parse_string; -+ -+ case oGssRenewalRekey: -+ intptr = &options->gss_renewal_rekey; -+ goto parse_flag; -+ - case oBatchMode: - intptr = &options->batch_mode; - goto parse_flag; -@@ -1817,7 +1848,12 @@ initialize_options(Options * options) - options->pubkey_authentication = -1; - options->challenge_response_authentication = -1; - options->gss_authentication = -1; -+ options->gss_keyex = -1; - options->gss_deleg_creds = -1; -+ options->gss_trust_dns = -1; -+ options->gss_renewal_rekey = -1; -+ options->gss_client_identity = NULL; -+ options->gss_server_identity = NULL; - options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->kbd_interactive_devices = NULL; -@@ -1962,8 +1998,14 @@ fill_default_options(Options * options) - options->challenge_response_authentication = 1; - if (options->gss_authentication == -1) - options->gss_authentication = 0; -+ if (options->gss_keyex == -1) -+ options->gss_keyex = 0; - if (options->gss_deleg_creds == -1) - options->gss_deleg_creds = 0; -+ if (options->gss_trust_dns == -1) -+ options->gss_trust_dns = 0; -+ if (options->gss_renewal_rekey == -1) -+ options->gss_renewal_rekey = 0; - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) -@@ -2603,7 +2645,12 @@ dump_client_config(Options *o, const cha - dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); - #ifdef GSSAPI - dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); -+ dump_cfg_fmtint(oGssKeyEx, o->gss_keyex); - dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); -+ dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns); -+ dump_cfg_string(oGssClientIdentity, o->gss_client_identity); -+ dump_cfg_string(oGssServerIdentity, o->gss_client_identity); -+ dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); - #endif /* GSSAPI */ - dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); - dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff -up openssh-7.9p1/readconf.h.gsskex openssh-7.9p1/readconf.h ---- openssh-7.9p1/readconf.h.gsskex 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/readconf.h 2018-11-14 09:14:06.277379857 +0100 -@@ -40,7 +40,12 @@ typedef struct { - int challenge_response_authentication; - /* Try S/Key or TIS, authentication. */ - int gss_authentication; /* Try GSS authentication */ -+ int gss_keyex; /* Try GSS key exchange */ - int gss_deleg_creds; /* Delegate GSS credentials */ -+ int gss_trust_dns; /* Trust DNS for GSS canonicalization */ -+ int gss_renewal_rekey; /* Credential renewal forces rekey */ -+ char *gss_client_identity; /* Principal to initiate GSSAPI with */ -+ char *gss_server_identity; /* GSSAPI target principal */ - int password_authentication; /* Try password - * authentication. */ - int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh ---- openssh/regress/cert-hostkey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/regress/cert-hostkey.sh 2018-08-22 11:47:33.314216481 +0200 -@@ -66,7 +66,7 @@ touch $OBJ/host_revoked_plain - touch $OBJ/host_revoked_cert - cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca - --PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` -+PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` - - if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then - PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh ---- openssh/regress/cert-userkey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/regress/cert-userkey.sh 2018-08-22 11:47:33.314216481 +0200 -@@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us - cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak - cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak - --PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` -+PLAIN_TYPES=`$SSH -Q key-plain | grep -v null | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` - EXTRA_TYPES="" - - if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then -diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh ---- openssh/regress/kextype.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/regress/kextype.sh 2018-08-22 11:47:33.315216489 +0200 -@@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh - - tries="1 2 3 4" - for k in `${SSH} -Q kex`; do -+ if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o $k = "gss-group14-sha1-" ]; then -+ continue -+ fi - verbose "kex $k" - for i in $tries; do - ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh ---- openssh/regress/rekey.sh.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/regress/rekey.sh 2018-08-22 11:47:33.315216489 +0200 -@@ -38,6 +38,9 @@ increase_datafile_size 300 - - opts="" - for i in `${SSH} -Q kex`; do -+ if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o $i = "gss-group14-sha1-" ]; then -+ continue -+ fi - opts="$opts KexAlgorithms=$i" - done - for i in `${SSH} -Q cipher`; do -@@ -56,6 +59,9 @@ done - if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then - for c in `${SSH} -Q cipher-auth`; do - for kex in `${SSH} -Q kex`; do -+ if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o $kex = "gss-group14-sha1-" ]; then -+ continue -+ fi - verbose "client rekey $c $kex" - ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c - done -diff -up openssh/servconf.c.gsskex openssh/servconf.c ---- openssh/servconf.c.gsskex 2018-08-22 11:47:33.296216335 +0200 -+++ openssh/servconf.c 2018-08-22 13:28:41.905179879 +0200 -@@ -124,8 +124,10 @@ initialize_server_options(ServerOptions - options->kerberos_ticket_cleanup = -1; - options->kerberos_get_afs_token = -1; - options->gss_authentication=-1; -+ options->gss_keyex = -1; - options->gss_cleanup_creds = -1; - options->gss_strict_acceptor = -1; -+ options->gss_store_rekey = -1; - options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; -@@ -334,10 +336,14 @@ fill_default_server_options(ServerOption - options->kerberos_get_afs_token = 0; - if (options->gss_authentication == -1) - options->gss_authentication = 0; -+ if (options->gss_keyex == -1) -+ options->gss_keyex = 0; - if (options->gss_cleanup_creds == -1) - options->gss_cleanup_creds = 1; - if (options->gss_strict_acceptor == -1) - options->gss_strict_acceptor = 1; -+ if (options->gss_store_rekey == -1) -+ options->gss_store_rekey = 0; - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) -@@ -484,7 +490,7 @@ typedef enum { - sHostKeyAlgorithms, - sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, -- sAcceptEnv, sSetEnv, sPermitTunnel, -+ sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, - sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, - sHostCertificate, -@@ -559,11 +565,17 @@ static struct { - { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, - { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, - { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, -+ { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, -+ { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, - #else - { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, - { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, - { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, -+ { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, -+ { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, -+ { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, - { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, - { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, - { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1463,6 +1475,10 @@ process_server_config_line(ServerOptions - intptr = &options->gss_authentication; - goto parse_flag; - -+ case sGssKeyEx: -+ intptr = &options->gss_keyex; -+ goto parse_flag; -+ - case sGssCleanupCreds: - intptr = &options->gss_cleanup_creds; - goto parse_flag; -@@ -1471,6 +1487,10 @@ process_server_config_line(ServerOptions - intptr = &options->gss_strict_acceptor; - goto parse_flag; - -+ case sGssStoreRekey: -+ intptr = &options->gss_store_rekey; -+ goto parse_flag; -+ - case sPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; -@@ -2560,6 +2580,9 @@ dump_config(ServerOptions *o) - #ifdef GSSAPI - dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); - dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); -+ dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); -+ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); -+ dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); - #endif - dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); - dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh/servconf.h.gsskex openssh/servconf.h ---- openssh/servconf.h.gsskex 2018-08-22 11:47:33.296216335 +0200 -+++ openssh/servconf.h 2018-08-22 11:47:33.316216497 +0200 -@@ -124,8 +124,10 @@ typedef struct { - int kerberos_get_afs_token; /* If true, try to get AFS token if - * authenticated with Kerberos. */ - int gss_authentication; /* If true, permit GSSAPI authentication */ -+ int gss_keyex; /* If true, permit GSSAPI key exchange */ - int gss_cleanup_creds; /* If true, destroy cred cache on logout */ - int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ -+ int gss_store_rekey; - int password_authentication; /* If true, permit password - * authentication. */ - int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 ---- openssh/ssh_config.5.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/ssh_config.5 2018-08-22 11:47:33.316216497 +0200 -@@ -718,10 +718,40 @@ The default is - Specifies whether user authentication based on GSSAPI is allowed. - The default is - .Cm no . -+.It Cm GSSAPIClientIdentity -+If set, specifies the GSSAPI client identity that ssh should use when -+connecting to the server. The default is unset, which means that the default -+identity will be used. - .It Cm GSSAPIDelegateCredentials - Forward (delegate) credentials to the server. - The default is - .Cm no . -+.It Cm GSSAPIKeyExchange -+Specifies whether key exchange based on GSSAPI may be used. When using -+GSSAPI key exchange the server need not have a host key. -+The default is -+.Dq no . -+.It Cm GSSAPIRenewalForcesRekey -+If set to -+.Dq yes -+then renewal of the client's GSSAPI credentials will force the rekeying of the -+ssh connection. With a compatible server, this can delegate the renewed -+credentials to a session on the server. -+The default is -+.Dq no . -+.It Cm GSSAPIServerIdentity -+If set, specifies the GSSAPI server identity that ssh should expect when -+connecting to the server. The default is unset, which means that the -+expected GSSAPI server identity will be determined from the target -+hostname. -+.It Cm GSSAPITrustDns -+Set to -+.Dq yes to indicate that the DNS is trusted to securely canonicalize -+the name of the host being connected to. If -+.Dq no, the hostname entered on the -+command line will be passed untouched to the GSSAPI library. -+The default is -+.Dq no . - .It Cm HashKnownHosts - Indicates that - .Xr ssh 1 -diff -up openssh/ssh_config.gsskex openssh/ssh_config ---- openssh/ssh_config.gsskex 2018-08-22 11:47:33.289216279 +0200 -+++ openssh/ssh_config 2018-08-22 11:47:33.316216497 +0200 -@@ -24,6 +24,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP yes - # AddressFamily any -diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c ---- openssh/sshconnect2.c.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/sshconnect2.c 2018-08-22 13:33:01.674275795 +0200 -@@ -82,6 +82,124 @@ extern char *client_version_string; - extern char *server_version_string; - extern Options options; - -+/* XXX from auth.h -- refactoring move these useful functions away of client context*/ -+ -+/* -+ * 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 legacy rhosts-style authentication. -+ * XXX is RhostsRSAAuthentication vulnerable to these? -+ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) -+ */ -+ -+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) < 0) { -+ debug("getpeername failed: %.100s", strerror(errno)); -+ return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); -+ } -+ return strdup(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. -+ */ -+ -+const char * -+get_canonical_hostname(struct ssh *ssh, int use_dns) -+{ -+ static char *dnsname; -+ -+ if (!use_dns) -+ return ssh_remote_ipaddr(ssh); -+ else if (dnsname != NULL) -+ return dnsname; -+ else { -+ dnsname = remote_hostname(ssh); -+ return dnsname; -+ } -+} -+ -+ -+ - /* - * SSH2 key exchange - */ -@@ -162,9 +280,36 @@ ssh_kex2(char *host, struct sockaddr *ho - struct kex *kex; - int r; - -+#ifdef GSSAPI -+ char *orig = NULL, *gss = NULL; -+ char *gss_host = NULL; -+#endif -+ - xxx_host = host; - xxx_hostaddr = hostaddr; - -+#ifdef GSSAPI -+ if (options.gss_keyex) { -+ /* Add the GSSAPI mechanisms currently supported on this -+ * client to the key exchange algorithm proposal */ -+ orig = options.kex_algorithms; -+ -+ if (options.gss_server_identity) -+ gss_host = options.gss_server_identity; -+ else if (options.gss_trust_dns) -+ gss_host = (char *)get_canonical_hostname(active_state, 1); -+ else -+ gss_host = host; -+ -+ gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); -+ if (gss) { -+ debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&options.kex_algorithms, -+ "%s,%s", gss, orig); -+ } -+ } -+#endif -+ - if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) - fatal("%s: kex_names_cat", __func__); - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -194,6 +339,16 @@ ssh_kex2(char *host, struct sockaddr *ho - order_hostkeyalgs(host, hostaddr, port)); - } - -+#ifdef GSSAPI -+ /* If we've got GSSAPI algorithms, then we also support the -+ * 'null' hostkey, as a last resort */ -+ if (options.gss_keyex && gss) { -+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "%s,null", orig); -+ } -+#endif -+ - if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits(options.rekey_limit, - options.rekey_interval); -@@ -214,16 +369,46 @@ ssh_kex2(char *host, struct sockaddr *ho - kex->kex[KEX_ECDH_SHA2] = kexecdh_client; - # endif - #endif -+#ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; -+ } -+#endif - kex->kex[KEX_C25519_SHA256] = kexc25519_client; - kex->client_version_string=client_version_string; - kex->server_version_string=server_version_string; - kex->verify_host_key=&verify_host_key_callback; - -+#ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->gss_deleg_creds = options.gss_deleg_creds; -+ kex->gss_trust_dns = options.gss_trust_dns; -+ kex->gss_client = options.gss_client_identity; -+ if (options.gss_server_identity) { -+ kex->gss_host = options.gss_server_identity; -+ } else { -+ kex->gss_host = gss_host; -+ } -+ } -+#endif -+ - ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); - - /* remove ext-info from the KEX proposals for rekeying */ - myproposal[PROPOSAL_KEX_ALGS] = - compat_kex_proposal(options.kex_algorithms); -+#ifdef GSSAPI -+ /* repair myproposal after it was crumpled by the */ -+ /* ext-info removal above */ -+ if (gss) { -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ free(gss); -+ } -+#endif - if ((r = kex_prop2buf(kex->my, myproposal)) != 0) - fatal("kex_prop2buf: %s", ssh_err(r)); - -@@ -314,6 +499,7 @@ int input_gssapi_token(int type, u_int32 - int input_gssapi_hash(int type, u_int32_t, struct ssh *); - int input_gssapi_error(int, u_int32_t, struct ssh *); - int input_gssapi_errtok(int, u_int32_t, struct ssh *); -+int userauth_gsskeyex(Authctxt *authctxt); - #endif - - void userauth(Authctxt *, char *); -@@ -330,6 +505,11 @@ static char *authmethods_get(void); - - Authmethod authmethods[] = { - #ifdef GSSAPI -+ {"gssapi-keyex", -+ userauth_gsskeyex, -+ NULL, -+ &options.gss_authentication, -+ NULL}, - {"gssapi-with-mic", - userauth_gssapi, - NULL, -@@ -657,19 +837,31 @@ userauth_gssapi(Authctxt *authctxt) - static u_int mech = 0; - OM_uint32 min; - int r, ok = 0; -+ const char *gss_host; -+ -+ if (options.gss_server_identity) -+ gss_host = options.gss_server_identity; -+ else if (options.gss_trust_dns) -+ gss_host = get_canonical_hostname(active_state, 1); -+ else -+ gss_host = authctxt->host; - - /* Try one GSSAPI method at a time, rather than sending them all at - * once. */ - - if (gss_supported == NULL) -- gss_indicate_mechs(&min, &gss_supported); -+ if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) { -+ gss_supported = NULL; -+ return 0; -+ } - - /* Check to see if the mechanism is usable before we offer it */ - while (mech < gss_supported->count && !ok) { - /* My DER encoding requires length<128 */ - if (gss_supported->elements[mech].length < 128 && - ssh_gssapi_check_mechanism(&gssctxt, -- &gss_supported->elements[mech], authctxt->host)) { -+ &gss_supported->elements[mech], gss_host, -+ options.gss_client_identity)) { - ok = 1; /* Mechanism works */ - } else { - mech++; -@@ -906,6 +1098,51 @@ input_gssapi_error(int type, u_int32_t p - free(lang); - return r; - } -+ -+int -+userauth_gsskeyex(Authctxt *authctxt) -+{ -+ struct sshbuf *b = NULL; -+ gss_buffer_desc gssbuf; -+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ms; -+ -+ static int attempt = 0; -+ if (attempt++ >= 1) -+ return (0); -+ -+ if (gss_kex_context == NULL) { -+ debug("No valid Key exchange context"); -+ return (0); -+ } -+ -+ if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); -+ -+ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex"); -+ -+ gssbuf.value = sshbuf_mutable_ptr(b); -+ gssbuf.length = sshbuf_len(b); -+ -+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { -+ sshbuf_free(b); -+ return (0); -+ } -+ -+ packet_start(SSH2_MSG_USERAUTH_REQUEST); -+ packet_put_cstring(authctxt->server_user); -+ packet_put_cstring(authctxt->service); -+ packet_put_cstring(authctxt->method->name); -+ packet_put_string(mic.value, mic.length); -+ packet_send(); -+ -+ sshbuf_free(b); -+ gss_release_buffer(&ms, &mic); -+ -+ return (1); -+} -+ - #endif /* GSSAPI */ - - int -diff -up openssh/sshd.c.gsskex openssh/sshd.c ---- openssh/sshd.c.gsskex 2018-08-22 11:47:33.299216360 +0200 -+++ openssh/sshd.c 2018-08-22 13:34:28.455975954 +0200 -@@ -887,8 +887,9 @@ notify_hostkeys(struct ssh *ssh) - } - debug3("%s: sent %u hostkeys", __func__, nkeys); - if (nkeys == 0) -- fatal("%s: no hostkeys", __func__); -- packet_send(); -+ debug3("%s: no hostkeys", __func__); -+ else -+ packet_send(); - sshbuf_free(buf); - } - -@@ -1841,7 +1842,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); - } -@@ -2321,6 +2323,48 @@ do_ssh2_kex(void) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - list_hostkey_types()); - -+#ifdef GSSAPI -+ { -+ char *orig; -+ char *gss = NULL; -+ char *newstr = NULL; -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ /* -+ * If we don't have a host key, then there's no point advertising -+ * the other key exchange algorithms -+ */ -+ -+ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) -+ orig = NULL; -+ -+ if (options.gss_keyex) -+ gss = ssh_gssapi_server_mechanisms(); -+ else -+ gss = NULL; -+ -+ if (gss && orig) -+ xasprintf(&newstr, "%s,%s", gss, orig); -+ else if (gss) -+ newstr = gss; -+ else if (orig) -+ newstr = orig; -+ -+ /* -+ * If we've got GSSAPI mechanisms, then we've got the 'null' host -+ * key alg, but we can't tell people about it unless its the only -+ * host key algorithm we support -+ */ -+ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; -+ -+ if (newstr) -+ myproposal[PROPOSAL_KEX_ALGS] = newstr; -+ else -+ fatal("No supported key exchange algorithms"); -+ } -+#endif -+ - /* start key exchange */ - if ((r = kex_setup(active_state, myproposal)) != 0) - fatal("kex_setup: %s", ssh_err(r)); -@@ -2338,6 +2382,13 @@ do_ssh2_kex(void) - # endif - #endif - kex->kex[KEX_C25519_SHA256] = kexc25519_server; -+#ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; -+ } -+#endif - kex->server = 1; - kex->client_version_string=client_version_string; - kex->server_version_string=server_version_string; -diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 ---- openssh/sshd_config.5.gsskex 2018-08-22 11:47:33.297216344 +0200 -+++ openssh/sshd_config.5 2018-08-22 13:35:05.531275099 +0200 -@@ -642,6 +642,11 @@ Specifies whether to automatically destr - on logout. - The default is - .Cm yes . -+.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. -+The default is -+.Dq no . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. -@@ -656,6 +661,11 @@ machine's default store. - This facility is provided to assist with operation on multi homed machines. - The default is - .Cm yes . -+.It Cm GSSAPIStoreCredentialsOnRekey -+Controls whether the user's GSSAPI credentials should be updated following a -+successful connection rekeying. This option can be used to accepted renewed -+or updated credentials from a compatible client. The default is -+.Dq no . - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. -diff -up openssh/sshd_config.gsskex openssh/sshd_config ---- openssh/sshd_config.gsskex 2018-08-22 11:47:33.299216360 +0200 -+++ openssh/sshd_config 2018-08-22 11:47:33.318216513 +0200 -@@ -85,6 +85,8 @@ ChallengeResponseAuthentication no - # GSSAPI options - GSSAPIAuthentication yes - GSSAPICleanupCredentials no -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h ---- openssh/ssh-gss.h.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/ssh-gss.h 2018-08-22 13:36:44.773075793 +0200 -@@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 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,22 @@ - - #define SSH_GSS_OIDTYPE 0x06 - -+#define SSH2_MSG_KEXGSS_INIT 30 -+#define SSH2_MSG_KEXGSS_CONTINUE 31 -+#define SSH2_MSG_KEXGSS_COMPLETE 32 -+#define SSH2_MSG_KEXGSS_HOSTKEY 33 -+#define SSH2_MSG_KEXGSS_ERROR 34 -+#define SSH2_MSG_KEXGSS_GROUPREQ 40 -+#define SSH2_MSG_KEXGSS_GROUP 41 -+#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" -+#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" -+#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" -+ - typedef struct { - char *filename; - char *envvar; - char *envval; -+ struct passwd *owner; - void *data; - } ssh_gssapi_ccache; - -@@ -72,8 +84,11 @@ typedef struct { - gss_buffer_desc displayname; - gss_buffer_desc exportedname; - gss_cred_id_t creds; -+ gss_name_t name; - struct ssh_gssapi_mech_struct *mech; - ssh_gssapi_ccache store; -+ int used; -+ int updated; - } ssh_gssapi_client; - - typedef struct ssh_gssapi_mech_struct { -@@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); - void (*storecreds) (ssh_gssapi_client *); -+ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - - typedef struct { -@@ -94,10 +110,11 @@ typedef struct { - gss_OID oid; /* client */ - gss_cred_id_t creds; /* server */ - gss_name_t client; /* server */ -- gss_cred_id_t client_creds; /* server */ -+ gss_cred_id_t client_creds; /* both */ - } Gssctxt; - - extern ssh_gssapi_mech *supported_mechs[]; -+extern Gssctxt *gss_kex_context; - - int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); - void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -123,17 +140,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); - OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_buildmic(struct sshbuf *, const char *, - const char *, const char *); --int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); -+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); -+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); -+int ssh_gssapi_credentials_updated(Gssctxt *); - - /* In the server */ -+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, -+ const char *); -+char *ssh_gssapi_client_mechanisms(const char *, const char *); -+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, -+ const char *); -+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); -+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, -+ const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); --int ssh_gssapi_userok(char *name); -+int ssh_gssapi_userok(char *name, struct passwd *); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); - void ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - -+char *ssh_gssapi_server_mechanisms(void); -+int ssh_gssapi_oid_table_ok(); -+ -+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); -+ -+void ssh_gssapi_rekey_creds(void); - #endif /* GSSAPI */ - - #endif /* _SSH_GSS_H */ -diff -up openssh/sshkey.c.gsskex openssh/sshkey.c ---- openssh/sshkey.c.gsskex 2018-08-22 11:47:33.319216521 +0200 -+++ openssh/sshkey.c 2018-08-22 13:37:18.979351804 +0200 -@@ -140,6 +140,7 @@ static const struct keytype keytypes[] = - # endif /* OPENSSL_HAS_NISTP521 */ - # endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ -+ { "null", "null", NULL, KEY_NULL, 0, 0, 1 }, - { NULL, NULL, NULL, -1, -1, 0, 0 } - }; - -diff -up openssh/sshkey.h.gsskex openssh/sshkey.h ---- openssh/sshkey.h.gsskex 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/sshkey.h 2018-08-22 11:47:33.320216529 +0200 -@@ -63,6 +63,7 @@ enum sshkey_types { - KEY_ED25519_CERT, - KEY_XMSS, - KEY_XMSS_CERT, -+ KEY_NULL, - KEY_UNSPEC - }; - diff --git a/openssh-7.8p1-ip-port-config-parser.patch b/openssh-7.8p1-ip-port-config-parser.patch deleted file mode 100644 index 6ca0cf5..0000000 --- a/openssh-7.8p1-ip-port-config-parser.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff -up openssh/misc.c.config openssh/misc.c ---- openssh/misc.c.config 2018-08-22 13:58:54.922807799 +0200 -+++ openssh/misc.c 2018-08-22 13:58:55.000808428 +0200 -@@ -485,7 +485,7 @@ put_host_port(const char *host, u_short - * The delimiter char, if present, is stored in delim. - * If this is the last field, *cp is set to NULL. - */ --static char * -+char * - hpdelim2(char **cp, char *delim) - { - char *s, *old; -diff -up openssh/misc.h.config openssh/misc.h ---- openssh/misc.h.config 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/misc.h 2018-08-22 13:58:55.001808436 +0200 -@@ -54,6 +54,7 @@ int set_rdomain(int, const char *); - int a2port(const char *); - int a2tun(const char *, int *); - char *put_host_port(const char *, u_short); -+char *hpdelim2(char **, char *); - char *hpdelim(char **); - char *cleanhostname(char *); - char *colon(char *); -diff -up openssh/servconf.c.config openssh/servconf.c ---- openssh/servconf.c.config 2018-08-22 13:58:54.989808340 +0200 -+++ openssh/servconf.c 2018-08-22 14:18:49.235443937 +0200 -@@ -886,7 +886,7 @@ process_permitopen_list(struct ssh *ssh, - { - u_int i; - int port; -- char *host, *arg, *oarg; -+ char *host, *arg, *oarg, ch; - int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; - const char *what = lookup_opcode_name(opcode); - -@@ -904,8 +904,8 @@ process_permitopen_list(struct ssh *ssh, - /* Otherwise treat it as a list of permitted host:port */ - for (i = 0; i < num_opens; i++) { - oarg = arg = xstrdup(opens[i]); -- host = hpdelim(&arg); -- if (host == NULL) -+ host = hpdelim2(&arg, &ch); -+ if (host == NULL || ch == '/') - fatal("%s: missing host in %s", __func__, what); - host = cleanhostname(host); - if (arg == NULL || ((port = permitopen_port(arg)) < 0)) -@@ -1323,8 +1323,10 @@ process_server_config_line(ServerOptions - port = 0; - p = arg; - } else { -- p = hpdelim(&arg); -- if (p == NULL) -+ char ch; -+ arg2 = NULL; -+ p = hpdelim2(&arg, &ch); -+ if (p == NULL || ch == '/') - fatal("%s line %d: bad address:port usage", - filename, linenum); - p = cleanhostname(p); -@@ -1965,9 +1967,10 @@ process_server_config_line(ServerOptions - */ - xasprintf(&arg2, "*:%s", arg); - } else { -+ char ch; - arg2 = xstrdup(arg); -- p = hpdelim(&arg); -- if (p == NULL) { -+ p = hpdelim2(&arg, &ch); -+ if (p == NULL || ch == '/') { - fatal("%s line %d: missing host in %s", - filename, linenum, - lookup_opcode_name(opcode)); diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 4c58d71..84ba9b3 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -4,11 +4,11 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c @@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; - char *user, *service, *method, *style = NULL; + char *user = NULL, *service = NULL, *method = NULL, *style = NULL; +#ifdef WITH_SELINUX + char *role = NULL; +#endif - int authenticated = 0; + int r, authenticated = 0; double tstart = monotime_double(); @@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32 @@ -37,9 +37,9 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c + mm_inform_authrole(role); +#endif + } - userauth_banner(); + userauth_banner(ssh); if (auth2_setup_methods_lists(authctxt) != 0) - packet_disconnect("no authentication methods enabled"); + 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 @@ -57,7 +57,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c mic.length = len; - ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, +#ifdef WITH_SELINUX -+ if (authctxt->role && (strlen(authctxt->role) > 0)) ++ if (authctxt->role && authctxt->role[0] != 0) + xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); + else +#endif @@ -197,15 +197,15 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c --- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200 @@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *) - int mm_answer_pwnamallow(int, struct sshbuf *); - int mm_answer_auth2_read_banner(int, struct sshbuf *); - int mm_answer_authserv(int, struct sshbuf *); + int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); + int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); + int mm_answer_authserv(struct ssh *, int, struct sshbuf *); +#ifdef WITH_SELINUX -+int mm_answer_authrole(int, struct sshbuf *); ++int mm_answer_authrole(struct ssh *, int, struct sshbuf *); +#endif - int mm_answer_authpassword(int, struct sshbuf *); - int mm_answer_bsdauthquery(int, struct sshbuf *); - int mm_answer_bsdauthrespond(int, struct sshbuf *); + 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 *); @@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, @@ -227,12 +227,12 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c #ifdef USE_PAM @@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb - return (0); + return found; } +#ifdef WITH_SELINUX +int -+mm_answer_authrole(int sock, struct sshbuf *m) ++mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int r; + monitor_permit_authentications(1); @@ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c +#endif + int - mm_answer_authpassword(int sock, struct sshbuf *m) + mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i { @@ -338,13 +338,13 @@ 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); - int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, - const char *, u_int compat); + int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, + const u_char *, size_t, const char *, u_int compat); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); +#endif - struct passwd *mm_getpwnamallow(const char *); + struct passwd *mm_getpwnamallow(struct ssh *, const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in diff --git a/openssh-7.9p1-CVE-2018-20685.patch b/openssh-7.9p1-CVE-2018-20685.patch deleted file mode 100644 index db7a4f8..0000000 --- a/openssh-7.9p1-CVE-2018-20685.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6010c0303a422a9c5fa8860c061bf7105eb7f8b2 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 16 Nov 2018 03:03:10 +0000 -Subject: [PATCH] upstream: disallow empty incoming filename or ones that refer - to the - -current directory; based on report/patch from Harry Sintonen - -OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9 ---- - scp.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/scp.c b/scp.c -index 60682c687..4f3fdcd3d 100644 ---- a/scp.c -+++ b/scp.c -@@ -1106,7 +1106,8 @@ sink(int argc, char **argv) - SCREWUP("size out of range"); - size = (off_t)ull; - -- if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { -+ if (*cp == '\0' || strchr(cp, '/') != NULL || -+ strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { - run_err("error: unexpected filename: %s", cp); - exit(1); - } - diff --git a/openssh-7.9p1-backports.patch b/openssh-7.9p1-backports.patch deleted file mode 100644 index d89138b..0000000 --- a/openssh-7.9p1-backports.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 631165f6c43d230df9174423aeb19fcf09a67ef4 Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Mon, 22 Oct 2018 11:22:50 +1100 -Subject: [PATCH 1/7] fix compile for openssl 1.0.x w/ --with-ssl-engine - -bz#2921, patch from cotequeiroz ---- - openbsd-compat/openssl-compat.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c -index 8b4a3627..590b66d1 100644 ---- a/openbsd-compat/openssl-compat.c -+++ b/openbsd-compat/openssl-compat.c -@@ -76,7 +76,7 @@ ssh_OpenSSL_add_all_algorithms(void) - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - --#if OPENSSL_VERSION_NUMBER < 0x10001000L -+#if OPENSSL_VERSION_NUMBER < 0x10100000L - OPENSSL_config(NULL); - #else - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | --- -2.20.1 - - -From 55d7cdda4dc4e8284ccd276f73440be400250a1e Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Mon, 22 Oct 2018 20:05:18 +1100 -Subject: [PATCH 2/7] Include openssl compatibility. - -Patch from rosenp at gmail.com via openssh-unix-dev. ---- - ssh-keysign.c | 1 + - ssh_api.c | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/ssh-keysign.c b/ssh-keysign.c -index 744ecb4f..bcd1508c 100644 ---- a/ssh-keysign.c -+++ b/ssh-keysign.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include "openbsd-compat/openssl-compat.h" - #endif - - #include "xmalloc.h" -diff --git a/ssh_api.c b/ssh_api.c -index c84b4e71..e727c0d6 100644 ---- a/ssh_api.c -+++ b/ssh_api.c -@@ -29,6 +29,8 @@ - #include "ssherr.h" - #include "sshbuf.h" - -+#include "openbsd-compat/openssl-compat.h" -+ - #include - - int _ssh_exchange_banner(struct ssh *); --- -2.20.1 - - -From 22092e375125dc602227afb8b2d3b285203e77c1 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Mon, 5 Nov 2018 17:31:24 +1100 -Subject: [PATCH 3/7] Fix pasto for HAVE_EVP_CIPHER_CTX_SET_IV. - -Prevents unnecessary redefinition. Patch from mforney at mforney.org. ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 7379ab35..1041bf25 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2850,7 +2850,7 @@ if test "x$openssl" = "xyes" ; then - [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1], - [Define if libcrypto has EVP_CIPHER_CTX_get_iv])]) - AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto], -- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1], -+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_SET_IV], [1], - [Define if libcrypto has EVP_CIPHER_CTX_set_iv])]) - - AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto], --- -2.20.1 - - -From 904d478f07deabb401f741f88c67ab2e07f742bd Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Sun, 11 Nov 2018 15:54:54 +1100 -Subject: [PATCH 4/7] Remove hardcoded service name in cygwin setup. - -bz#2922, patch from Christian.Lupien at USherbrooke.ca, sanity check -by vinschen at redhat.com. ---- - contrib/cygwin/ssh-host-config | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config -index 261020af..e9f038db 100644 ---- a/contrib/cygwin/ssh-host-config -+++ b/contrib/cygwin/ssh-host-config -@@ -307,7 +307,7 @@ check_service_files_ownership() { - - if [ -z "${run_service_as}" ] - then -- accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | -+ accnt_name=$(/usr/bin/cygrunsrv -VQ "${service_name}" | - /usr/bin/sed -ne 's/^Account *: *//gp') - if [ "${accnt_name}" = "LocalSystem" ] - then --- -2.20.1 - - -From 4608a60cb4893a25490fd88ffdaaae6256381ae3 Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Fri, 23 Nov 2018 10:45:20 +1100 -Subject: [PATCH 6/7] fix configure test for OpenSSL version - -square brackets in case statements may be eaten by autoconf. - -Report and fix from Filipp Gunbin; tweaked by naddy@ ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 1041bf25..9920ede5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2616,7 +2616,7 @@ if test "x$openssl" = "xyes" ; then - AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) - ;; - 100*) ;; # 1.0.x -- 101000[0123456]*) -+ 101000[[0123456]]*) - # https://github.com/openssl/openssl/pull/4613 - AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")]) - ;; --- -2.20.1 - - -From f429c1b2ef631f2855e51a790cf71761d752bbca Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Thu, 27 Dec 2018 23:02:11 +0000 -Subject: [PATCH 7/7] upstream: Request RSA-SHA2 signatures for - -rsa-sha2-{256|512}-cert-v01@openssh.com cert algorithms; ok markus@ - -OpenBSD-Commit-ID: afc6f7ca216ccd821656d1c911d2a3deed685033 ---- - authfd.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/authfd.c b/authfd.c -index ecdd869a..62cbf8c1 100644 ---- a/authfd.c -+++ b/authfd.c -@@ -327,10 +327,12 @@ ssh_free_identitylist(struct ssh_identitylist *idl) - static u_int - agent_encode_alg(const struct sshkey *key, const char *alg) - { -- if (alg != NULL && key->type == KEY_RSA) { -- if (strcmp(alg, "rsa-sha2-256") == 0) -+ if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) { -+ if (strcmp(alg, "rsa-sha2-256") == 0 || -+ strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0) - return SSH_AGENT_RSA_SHA2_256; -- else if (strcmp(alg, "rsa-sha2-512") == 0) -+ if (strcmp(alg, "rsa-sha2-512") == 0 || -+ strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0) - return SSH_AGENT_RSA_SHA2_512; - } - return 0; --- -2.20.1 - diff --git a/openssh-7.9p1-disable-sha1.patch b/openssh-7.9p1-disable-sha1.patch deleted file mode 100644 index c157b3c..0000000 --- a/openssh-7.9p1-disable-sha1.patch +++ /dev/null @@ -1,62 +0,0 @@ -diff --git a/monitor.c b/monitor.c -index 12b33e7..a1c3c97 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -875,6 +875,34 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m) - } - #endif - -+/* -+ * Check that the key type appears in the supplied pattern list, ignoring -+ * mismastches in the signature algorithm. (Signature algorithm checks are -+ * performed in the unprivileged authentication code). -+ * Returns 1 on success, 0 otherwise. -+ */ -+static int -+key_base_type_match(const struct sshkey *key, const char *list) -+{ -+ char *s, *l, *ol = xstrdup(list); -+ int found = 0; -+ -+ l = ol; -+ for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) { -+ if (sshkey_type_from_name(s) == key->type) { -+ found = 1; -+ break; -+ } -+ } -+ if (!found) { -+ debug("key type %s does not appear in list %s", -+ sshkey_ssh_name(key), list); -+ } -+ -+ free(ol); -+ return found; -+} -+ - int - mm_answer_keyallowed(int sock, struct sshbuf *m) - { -@@ -909,8 +937,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) - break; - if (auth2_key_already_used(authctxt, key)) - break; -- if (match_pattern_list(sshkey_ssh_name(key), -- options.pubkey_key_types, 0) != 1) -+ if (!key_base_type_match(key, -+ options.pubkey_key_types)) - break; - allowed = user_key_allowed(ssh, authctxt->pw, key, - pubkey_auth_attempt, &opts); -@@ -921,8 +949,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) - break; - if (auth2_key_already_used(authctxt, key)) - break; -- if (match_pattern_list(sshkey_ssh_name(key), -- options.hostbased_key_types, 0) != 1) -+ if (!key_base_type_match(key, -+ options.hostbased_key_types)) - break; - allowed = hostbased_key_allowed(authctxt->pw, - cuser, chost, key); - diff --git a/openssh-7.9p1-gsskex-method.patch b/openssh-7.9p1-gsskex-method.patch deleted file mode 100644 index b06620d..0000000 --- a/openssh-7.9p1-gsskex-method.patch +++ /dev/null @@ -1,150 +0,0 @@ -From bc74944ce7a2eabd228d47051f277ce108914c96 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 16 Oct 2018 16:44:40 +0200 -Subject: [PATCH] Unbreak authentication using gssapi-keyex (#1625366) - ---- - auth2-gss.c | 6 +++--- - gss-serv.c | 4 +++- - monitor.c | 13 ++++++++++--- - monitor_wrap.c | 4 +++- - monitor_wrap.h | 2 +- - ssh-gss.h | 2 +- - 6 files changed, 21 insertions(+), 10 deletions(-) - -diff --git a/auth2-gss.c b/auth2-gss.c -index 3f2ad21d..a61ac089 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -84,7 +84,7 @@ userauth_gsskeyex(Authctxt *authctxt) - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, - &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -- authctxt->pw)); -+ authctxt->pw, 1)); - - sshbuf_free(b); - free(mic.value); -@@ -299,7 +299,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) - fatal("%s: %s", __func__, ssh_err(r)); - - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -- authctxt->pw)); -+ authctxt->pw, 1)); - - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) -@@ -347,7 +347,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) - - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = -- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); -+ PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0)); - else - logit("GSSAPI MIC check failed"); - -diff --git a/gss-serv.c b/gss-serv.c -index 786ac95c..87de2baa 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -493,10 +493,12 @@ verify_authentication_indicators(Gssctxt *gssctxt) - - /* Privileged */ - int --ssh_gssapi_userok(char *user, struct passwd *pw) -+ssh_gssapi_userok(char *user, struct passwd *pw, int kex) - { - OM_uint32 lmin; - -+ (void) kex; /* used in privilege separation */ -+ - if (gssapi_client.exportedname.length == 0 || - gssapi_client.exportedname.value == NULL) { - debug("No suitable client data"); -diff --git a/monitor.c b/monitor.c -index 9bbe8cc4..7b1903af 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -1877,14 +1877,17 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m) - int - mm_answer_gss_userok(int sock, struct sshbuf *m) - { -- int r, authenticated; -+ int r, authenticated, kex; - const char *displayname; - - if (!options.gss_authentication && !options.gss_keyex) - fatal("%s: GSSAPI authentication not enabled", __func__); - -+ if ((r = sshbuf_get_u32(m, &kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ - authenticated = authctxt->valid && -- ssh_gssapi_userok(authctxt->user, authctxt->pw); -+ ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); - - sshbuf_reset(m); - if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1893,7 +1896,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) - debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - -- auth_method = "gssapi-with-mic"; -+ if (kex) { -+ auth_method = "gssapi-keyex"; -+ } else { -+ auth_method = "gssapi-with-mic"; -+ } - - if ((displayname = ssh_gssapi_displayname()) != NULL) - auth2_record_info(authctxt, "%s", displayname); -diff --git a/monitor_wrap.c b/monitor_wrap.c -index fb52a530..508d926d 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -984,13 +984,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) - } - - int --mm_ssh_gssapi_userok(char *user, struct passwd *pw) -+mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex) - { - struct sshbuf *m; - int r, authenticated = 0; - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); -+ if ((r = sshbuf_put_u32(m, kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); - mm_request_receive_expect(pmonitor->m_recvfd, -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 494760dd..5eba5ecc 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -60,7 +60,7 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, - OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); - OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, - gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); --int mm_ssh_gssapi_userok(char *user, struct passwd *); -+int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); - OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); - int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); -diff --git a/ssh-gss.h b/ssh-gss.h -index 39b6ce69..98262837 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -162,7 +162,7 @@ gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); - int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, - const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); --int ssh_gssapi_userok(char *name, struct passwd *); -+int ssh_gssapi_userok(char *name, struct passwd *, int kex); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --- -2.17.2 - diff --git a/openssh-7.9p1-log-sftp-only-connections.patch b/openssh-7.9p1-log-sftp-only-connections.patch deleted file mode 100644 index 3b3613d..0000000 --- a/openssh-7.9p1-log-sftp-only-connections.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff --git a/session.c b/session.c ---- a/session.c -+++ b/session.c -@@ -1859,6 +1859,7 @@ do_child(Session *s, const char *command) - - if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { - printf("This service allows sftp connections only.\n"); -+ logit("The session allows sftp connections only"); - fflush(NULL); - exit(1); - } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { diff --git a/openssh-7.9p1-match-final.patch b/openssh-7.9p1-match-final.patch deleted file mode 100644 index 4c28fcf..0000000 --- a/openssh-7.9p1-match-final.patch +++ /dev/null @@ -1,306 +0,0 @@ -commit 9e34e0c59ab04514f9de9934a772283f7f372afe -Author: djm@openbsd.org -Date: Fri Nov 23 05:08:07 2018 +0000 - - upstream: add a ssh_config "Match final" predicate - - Matches in same pass as "Match canonical" but doesn't require - hostname canonicalisation be enabled. bz#2906 ok markus - - OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa - -diff --git a/readconf.c b/readconf.c -index 7850f2f5..7331ef5a 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -133,10 +133,11 @@ - - static int read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, -- int flags, int *activep, int depth); -+ int flags, int *activep, int *want_final_pass, int depth); - static int process_config_line_depth(Options *options, struct passwd *pw, - const char *host, const char *original_host, char *line, -- const char *filename, int linenum, int *activep, int flags, int depth); -+ const char *filename, int linenum, int *activep, int flags, -+ int *want_final_pass, int depth); - - /* Keyword tokens. */ - -@@ -539,8 +540,8 @@ execute_in_shell(const char *cmd) - */ - static int - match_cfg_line(Options *options, char **condition, struct passwd *pw, -- const char *host_arg, const char *original_host, int post_canon, -- const char *filename, int linenum) -+ const char *host_arg, const char *original_host, int final_pass, -+ int *want_final_pass, const char *filename, int linenum) - { - char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; - const char *ruser; -@@ -554,7 +555,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, - */ - port = options->port <= 0 ? default_ssh_port() : options->port; - ruser = options->user == NULL ? pw->pw_name : options->user; -- if (post_canon) { -+ if (final_pass) { - host = xstrdup(options->hostname); - } else if (options->hostname != NULL) { - /* NB. Please keep in sync with ssh.c:main() */ -@@ -586,8 +587,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, - goto out; - } - attributes++; -- if (strcasecmp(attrib, "canonical") == 0) { -- r = !!post_canon; /* force bitmask member to boolean */ -+ if (strcasecmp(attrib, "canonical") == 0 || -+ strcasecmp(attrib, "final") == 0) { -+ /* -+ * If the config requests "Match final" then remember -+ * this so we can perform a second pass later. -+ */ -+ if (strcasecmp(attrib, "final") == 0 && -+ want_final_pass != NULL) -+ *want_final_pass = 1; -+ r = !!final_pass; /* force bitmask member to boolean */ - if (r == (negate ? 1 : 0)) - this_result = result = 0; - debug3("%.200s line %d: %smatched '%s'", -@@ -824,14 +833,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host, - int linenum, int *activep, int flags) - { - return process_config_line_depth(options, pw, host, original_host, -- line, filename, linenum, activep, flags, 0); -+ line, filename, linenum, activep, flags, NULL, 0); - } - - #define WHITESPACE " \t\r\n" - static int - process_config_line_depth(Options *options, struct passwd *pw, const char *host, - const char *original_host, char *line, const char *filename, -- int linenum, int *activep, int flags, int depth) -+ int linenum, int *activep, int flags, int *want_final_pass, int depth) - { - char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; - char **cpptr, fwdarg[256]; -@@ -1339,7 +1348,8 @@ parse_keytypes: - fatal("Host directive not supported as a command-line " - "option"); - value = match_cfg_line(options, &s, pw, host, original_host, -- flags & SSHCONF_POSTCANON, filename, linenum); -+ flags & SSHCONF_FINAL, want_final_pass, -+ filename, linenum); - if (value < 0) - fatal("%.200s line %d: Bad Match condition", filename, - linenum); -@@ -1548,7 +1558,7 @@ parse_keytypes: - pw, host, original_host, options, - flags | SSHCONF_CHECKPERM | - (oactive ? 0 : SSHCONF_NEVERMATCH), -- activep, depth + 1); -+ activep, want_final_pass, depth + 1); - if (r != 1 && errno != ENOENT) { - fatal("Can't open user config file " - "%.100s: %.100s", gl.gl_pathv[i], -@@ -1751,19 +1761,20 @@ parse_keytypes: - */ - int - read_config_file(const char *filename, struct passwd *pw, const char *host, -- const char *original_host, Options *options, int flags) -+ const char *original_host, Options *options, int flags, -+ int *want_final_pass) - { - int active = 1; - - return read_config_file_depth(filename, pw, host, original_host, -- options, flags, &active, 0); -+ options, flags, &active, want_final_pass, 0); - } - - #define READCONF_MAX_DEPTH 16 - static int - read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, -- int flags, int *activep, int depth) -+ int flags, int *activep, int *want_final_pass, int depth) - { - FILE *f; - char *line = NULL; -@@ -1798,7 +1809,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, - /* Update line number counter. */ - linenum++; - if (process_config_line_depth(options, pw, host, original_host, -- line, filename, linenum, activep, flags, depth) != 0) -+ line, filename, linenum, activep, flags, want_final_pass, -+ depth) != 0) - bad_options++; - } - free(line); -diff --git a/readconf.h b/readconf.h -index fc7e3825..8e36bf32 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -185,7 +185,7 @@ typedef struct { - - #define SSHCONF_CHECKPERM 1 /* check permissions on config file */ - #define SSHCONF_USERCONF 2 /* user provided config file not system */ --#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ -+#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */ - #define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ - - #define SSH_UPDATE_HOSTKEYS_NO 0 -@@ -203,7 +203,7 @@ void fill_default_options_for_canonicalization(Options *); - int process_config_line(Options *, struct passwd *, const char *, - const char *, char *, const char *, int, int *, int); - int read_config_file(const char *, struct passwd *, const char *, -- const char *, Options *, int); -+ const char *, Options *, int, int *); - int parse_forward(struct Forward *, const char *, int, int); - int parse_jump(const char *, Options *, int); - int parse_ssh_uri(const char *, char **, char **, int *); -diff --git a/ssh-keysign.c b/ssh-keysign.c -index 8f487b8c..7ea5ad0e 100644 ---- a/ssh-keysign.c -+++ b/ssh-keysign.c -@@ -208,7 +208,8 @@ main(int argc, char **argv) - - /* verify that ssh-keysign is enabled by the admin */ - initialize_options(&options); -- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0); -+ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", -+ &options, 0, NULL); - fill_default_options(&options); - if (options.enable_ssh_keysign != 1) - fatal("ssh-keysign not enabled in %s", -diff --git a/ssh.c b/ssh.c -index 1ac903d1..c6cb7847 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -527,7 +527,8 @@ check_load(int r, const char *path, const char *message) - * file if the user specifies a config file on the command line. - */ - static void --process_config_files(const char *host_name, struct passwd *pw, int post_canon) -+process_config_files(const char *host_name, struct passwd *pw, int final_pass, -+ int *want_final_pass) - { - char buf[PATH_MAX]; - int r; -@@ -535,7 +536,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) - if (config != NULL) { - if (strcasecmp(config, "none") != 0 && - !read_config_file(config, pw, host, host_name, &options, -- SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) -+ SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), -+ want_final_pass)) - fatal("Can't open user config file %.100s: " - "%.100s", config, strerror(errno)); - } else { -@@ -544,12 +546,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) - if (r > 0 && (size_t)r < sizeof(buf)) - (void)read_config_file(buf, pw, host, host_name, - &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | -- (post_canon ? SSHCONF_POSTCANON : 0)); -+ (final_pass ? SSHCONF_FINAL : 0), want_final_pass); - - /* Read systemwide configuration file after user config. */ - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, - host, host_name, &options, -- post_canon ? SSHCONF_POSTCANON : 0); -+ final_pass ? SSHCONF_FINAL : 0, want_final_pass); - } - } - -@@ -581,7 +583,7 @@ main(int ac, char **av) - { - struct ssh *ssh = NULL; - int i, r, opt, exit_status, use_syslog, direct, timeout_ms; -- int was_addr, config_test = 0, opt_terminated = 0; -+ int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; - char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; - char cname[NI_MAXHOST]; - struct stat st; -@@ -1089,7 +1091,9 @@ main(int ac, char **av) - ); - - /* Parse the configuration files */ -- process_config_files(host_arg, pw, 0); -+ process_config_files(host_arg, pw, 0, &want_final_pass); -+ if (want_final_pass) -+ debug("configuration requests final Match pass"); - - /* Hostname canonicalisation needs a few options filled. */ - fill_default_options_for_canonicalization(&options); -@@ -1146,12 +1150,17 @@ main(int ac, char **av) - * If canonicalisation is enabled then re-parse the configuration - * files as new stanzas may match. - */ -- if (options.canonicalize_hostname != 0) { -- debug("Re-reading configuration after hostname " -- "canonicalisation"); -+ if (options.canonicalize_hostname != 0 && !want_final_pass) { -+ debug("hostname canonicalisation enabled, " -+ "will re-parse configuration"); -+ want_final_pass = 1; -+ } -+ -+ if (want_final_pass) { -+ debug("re-parsing configuration"); - free(options.hostname); - options.hostname = xstrdup(host); -- process_config_files(host_arg, pw, 1); -+ process_config_files(host_arg, pw, 1, NULL); - /* - * Address resolution happens early with canonicalisation - * enabled and the port number may have changed since, so -diff --git a/ssh_config.5 b/ssh_config.5 -index 4d5b01d3..58a5fa1c 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -139,6 +139,7 @@ or the single token - which always matches. - The available criteria keywords are: - .Cm canonical , -+.Cm final , - .Cm exec , - .Cm host , - .Cm originalhost , -@@ -148,12 +149,15 @@ and - The - .Cm all - criteria must appear alone or immediately after --.Cm canonical . -+.Cm canonical -+or -+.Cm final . - Other criteria may be combined arbitrarily. - All criteria but - .Cm all --and - .Cm canonical -+and -+.Cm final - require an argument. - Criteria may be negated by prepending an exclamation mark - .Pq Sq !\& . -@@ -166,6 +170,20 @@ after hostname canonicalization (see the - option.) - This may be useful to specify conditions that work with canonical host - names only. -+.Pp -+The -+.Cm final -+keyword requests that the configuration be re-parsed (regardless of whether -+.Cm CanonicalizeHostname -+is enabled), and matches only during this final pass. -+If -+.Cm CanonicalizeHostname -+is enabled, then -+.Cm canonical -+and -+.Cm final -+match during the same pass. -+.Pp - The - .Cm exec - keyword executes the specified command under the user's shell. diff --git a/openssh-7.9p1-updated-cached-pw.patch b/openssh-7.9p1-updated-cached-pw.patch index 7f24ce4..398f6bd 100644 --- a/openssh-7.9p1-updated-cached-pw.patch +++ b/openssh-7.9p1-updated-cached-pw.patch @@ -2,8 +2,8 @@ diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c --- openssh-7.4p1/session.c.update-pw 2019-03-04 14:10:57.287054645 +0100 +++ openssh-7.4p1/session.c 2019-03-04 14:12:39.259997218 +0100 @@ -1522,9 +1522,18 @@ do_child(Session *s, const char *command - char **env; - char *argv[ARGV_MAX]; + extern char **environ; + char **env, *argv[ARGV_MAX], remote_id[512]; const char *shell, *shell0; - struct passwd *pw = s->pw; + struct passwd *pw = NULL; @@ -18,6 +18,6 @@ diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c + pw = s->pw; + } + + sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); + /* remove hostkey from the child's memory */ - destroy_sensitive_data(); - packet_clear_keys(); diff --git a/openssh-7.9p1-gsissh.patch b/openssh-8.0p1-gsissh.patch similarity index 80% rename from openssh-7.9p1-gsissh.patch rename to openssh-8.0p1-gsissh.patch index 9686bd8..e7c8c3a 100644 --- a/openssh-7.9p1-gsissh.patch +++ b/openssh-8.0p1-gsissh.patch @@ -1,10 +1,10 @@ -diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c ---- openssh-7.9p1.orig/auth2.c 2019-02-27 08:08:38.955515147 +0100 -+++ openssh-7.9p1/auth2.c 2019-02-27 08:09:31.745945233 +0100 -@@ -270,7 +270,27 @@ - user = packet_get_cstring(NULL); - service = packet_get_cstring(NULL); - method = packet_get_cstring(NULL); +diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c +--- openssh-8.0p1.orig/auth2.c 2019-05-03 17:45:02.084333024 +0200 ++++ openssh-8.0p1/auth2.c 2019-05-05 14:21:03.207471114 +0200 +@@ -281,7 +281,28 @@ + (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || + (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) + goto out; - debug("userauth-request for user %s service %s method %s", user, service, method); + +#ifdef GSSAPI @@ -19,7 +19,8 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c + debug("set username to %s from gssapi context", user); + } else { + debug("failed to set username from gssapi context"); -+ packet_send_debug("failed to set username from gssapi context"); ++ ssh_packet_send_debug(ssh, ++ "failed to set username from gssapi context"); + } + } + } @@ -30,13 +31,13 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -281,11 +301,32 @@ +@@ -292,11 +313,33 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; - if (authctxt->attempt++ == 0) { - /* setup auth context */ -- authctxt->pw = PRIVSEP(getpwnamallow(user)); +- authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); + /* If first time or username changed or empty username, + setup/reset authentication context. */ + if ((authctxt->attempt++ == 0) || @@ -50,7 +51,8 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c authctxt->user = xstrdup(user); - if (authctxt->pw && strcmp(service, "ssh-connection")==0) { + if (strcmp(service, "ssh-connection") != 0) { -+ packet_disconnect("Unsupported service %s", service); ++ ssh_packet_disconnect(ssh, "Unsupported service %s", ++ service); + } +#ifdef GSSAPI + /* If we're going to set the username based on the @@ -62,12 +64,12 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c + authctxt->pw = fakepw(); + } else { +#endif -+ authctxt->pw = PRIVSEP(getpwnamallow(user)); ++ authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); + if (authctxt->pw) { authctxt->valid = 1; debug2("%s: setting up authctxt for %s", __func__, user); -@@ -293,6 +334,9 @@ +@@ -304,6 +347,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -76,8 +78,8 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c +#endif #ifdef USE_PAM if (options.use_pam) - PRIVSEP(start_pam(authctxt)); -@@ -301,6 +345,7 @@ + PRIVSEP(start_pam(ssh)); +@@ -312,6 +358,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -85,60 +87,61 @@ diff -Nur openssh-7.9p1.orig/auth2.c openssh-7.9p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -315,9 +360,10 @@ - userauth_banner(); +@@ -327,9 +374,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) - packet_disconnect("no authentication methods enabled"); + ssh_packet_disconnect(ssh, + "no authentication methods enabled"); - } else if (strcmp(user, authctxt->user) != 0 || - strcmp(service, authctxt->service) != 0) { -- packet_disconnect("Change of username or service not allowed: " +- ssh_packet_disconnect(ssh, "Change of username or service " + } + } + if (strcmp(service, authctxt->service) != 0) { -+ packet_disconnect("Change of service not allowed: " - "(%s,%s) -> (%s,%s)", ++ ssh_packet_disconnect(ssh, "Change of service " + "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c ---- openssh-7.9p1.orig/auth2-gss.c 2019-02-27 08:08:38.915515578 +0100 -+++ openssh-7.9p1/auth2-gss.c 2019-02-27 08:09:31.783944823 +0100 -@@ -50,6 +50,7 @@ +diff -Nur openssh-8.0p1.orig/auth2-gss.c openssh-8.0p1/auth2-gss.c +--- openssh-8.0p1.orig/auth2-gss.c 2019-05-03 17:45:02.006333854 +0200 ++++ openssh-8.0p1/auth2-gss.c 2019-05-05 13:31:35.509069506 +0200 +@@ -49,6 +49,7 @@ extern ServerOptions options; -+static void ssh_gssapi_userauth_error(Gssctxt *ctxt); ++static void ssh_gssapi_userauth_error(Gssctxt *ctxt, struct ssh *ssh); static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); 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); -@@ -63,8 +64,8 @@ +@@ -62,8 +63,8 @@ { Authctxt *authctxt = ssh->authctxt; - int authenticated = 0; + int r, authenticated = 0; - struct sshbuf *b = NULL; - gss_buffer_desc mic, gssbuf; + struct sshbuf *b = NULL, *b2 = NULL; + gss_buffer_desc mic, gssbuf, gssbuf2; - u_int len; + u_char *p; + size_t len; - mic.value = packet_get_string(&len); -@@ -81,13 +82,27 @@ - gssbuf.value = sshbuf_mutable_ptr(b); +@@ -84,13 +85,28 @@ + fatal("%s: sshbuf_mutable_ptr failed", __func__); gssbuf.length = sshbuf_len(b); + /* client may have used empty username to determine target + name from GSSAPI context */ + ssh_gssapi_buildmic(b2, "", authctxt->service, "gssapi-keyex"); + -+ gssbuf2.value = sshbuf_mutable_ptr(b2); ++ if ((gssbuf2.value = sshbuf_mutable_ptr(b2)) == NULL) ++ fatal("%s: sshbuf_mutable_ptr failed", __func__); + gssbuf2.length = sshbuf_len(b2); + /* gss_kex_context is NULL with privsep, so we can't check it here */ - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, - &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw, 1)); + &gssbuf, &mic))) || -+ !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, ++ !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, + &gssbuf2, &mic)))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { + authenticated = @@ -146,13 +149,13 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c + authctxt->pw, 1)); + } + } - + sshbuf_free(b); + sshbuf_free(b2); free(mic.value); return (authenticated); -@@ -142,7 +157,9 @@ +@@ -145,7 +161,9 @@ return (0); } @@ -163,7 +166,7 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c debug2("%s: disabled because of invalid user", __func__); free(doid); return (0); -@@ -180,7 +197,7 @@ +@@ -183,7 +201,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -172,21 +175,22 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c u_char *p; size_t len; int r; -@@ -201,6 +218,7 @@ +@@ -204,6 +222,7 @@ free(p); if (GSS_ERROR(maj_status)) { -+ ssh_gssapi_userauth_error(gssctxt); ++ ssh_gssapi_userauth_error(gssctxt, ssh); if (send_tok.length != 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || -@@ -275,6 +293,32 @@ +@@ -278,6 +297,34 @@ return 0; } +static void -+gssapi_set_username(Authctxt *authctxt) ++gssapi_set_username(struct ssh *ssh) +{ ++ Authctxt *authctxt = ssh->authctxt; + char *lname = NULL; + + if ((authctxt->user == NULL) || (authctxt->user[0] == '\0')) { @@ -195,17 +199,18 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c + if (authctxt->user) free(authctxt->user); + authctxt->user = lname; + debug("set username to %s from gssapi context", lname); -+ authctxt->pw = PRIVSEP(getpwnamallow(authctxt->user)); ++ authctxt->pw = PRIVSEP(getpwnamallow(ssh, authctxt->user)); + if (authctxt->pw) { + authctxt->valid = 1; +#ifdef USE_PAM + if (options.use_pam) -+ PRIVSEP(start_pam(authctxt)); ++ PRIVSEP(start_pam(ssh)); +#endif + } + } else { + debug("failed to set username from gssapi context"); -+ packet_send_debug("failed to set username from gssapi context"); ++ ssh_packet_send_debug(ssh, ++ "failed to set username from gssapi context"); + } + } +} @@ -213,7 +218,7 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -285,12 +329,14 @@ +@@ -288,12 +335,14 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -224,12 +229,12 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); -+ gssapi_set_username(authctxt); ++ gssapi_set_username(ssh); + /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -299,8 +345,11 @@ +@@ -302,8 +351,11 @@ if ((r = sshpkt_get_end(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); @@ -243,15 +248,15 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -352,11 +401,17 @@ +@@ -355,11 +407,17 @@ fatal("%s: sshbuf_mutable_ptr failed", __func__); gssbuf.length = sshbuf_len(b); - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) -- authenticated = -- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0)); +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, +- authctxt->pw, 0)); - else -+ gssapi_set_username(authctxt); ++ gssapi_set_username(ssh); + + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { @@ -265,23 +270,26 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c sshbuf_free(b); if (micuser != authctxt->user) -@@ -376,6 +431,23 @@ +@@ -379,6 +437,26 @@ return 0; } -+static void ssh_gssapi_userauth_error(Gssctxt *ctxt) { ++static void ssh_gssapi_userauth_error(Gssctxt *ctxt, struct ssh *ssh) { + char *errstr; -+ OM_uint32 maj,min; ++ OM_uint32 maj, min; ++ int r; + -+ errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min)); ++ errstr = PRIVSEP(ssh_gssapi_last_error(ctxt, &maj, &min)); + if (errstr) { -+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR); -+ packet_put_int(maj); -+ packet_put_int(min); -+ packet_put_cstring(errstr); -+ packet_put_cstring(""); -+ packet_send(); -+ packet_write_wait(); ++ if ((r = sshpkt_start(ssh, ++ SSH2_MSG_USERAUTH_GSSAPI_ERROR)) != 0 || ++ (r = sshpkt_put_u32(ssh, maj)) != 0 || ++ (r = sshpkt_put_u32(ssh, min)) != 0 || ++ (r = sshpkt_put_cstring(ssh, errstr)) != 0 || ++ (r = sshpkt_put_cstring(ssh, "")) != 0 || ++ (r = sshpkt_send(ssh)) != 0 || ++ (r = ssh_packet_write_wait(ssh)) != 0) ++ fatal("%s: %s", __func__, ssh_err(r)); + free(errstr); + } +} @@ -289,9 +297,9 @@ diff -Nur openssh-7.9p1.orig/auth2-gss.c openssh-7.9p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c ---- openssh-7.9p1.orig/auth.c 2019-02-27 08:08:38.957515125 +0100 -+++ openssh-7.9p1/auth.c 2019-02-27 08:09:31.784944812 +0100 +diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c +--- openssh-8.0p1.orig/auth.c 2019-05-03 17:45:02.085333014 +0200 ++++ openssh-8.0p1/auth.c 2019-05-04 16:57:48.606935950 +0200 @@ -343,7 +343,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -302,7 +310,7 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -581,6 +582,10 @@ +@@ -581,13 +582,18 @@ #endif pw = getpwnam(user); @@ -313,7 +321,6 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -@@ -600,7 +605,8 @@ #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", @@ -321,11 +328,11 @@ diff -Nur openssh-7.9p1.orig/auth.c openssh-7.9p1/auth.c + (user && user[0]) ? user : "unknown", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN - record_failed_login(user, + record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h ---- openssh-7.9p1.orig/auth.h 2019-02-27 08:08:38.957515125 +0100 -+++ openssh-7.9p1/auth.h 2019-02-27 08:09:31.784944812 +0100 +diff -Nur openssh-8.0p1.orig/auth.h openssh-8.0p1/auth.h +--- openssh-8.0p1.orig/auth.h 2019-05-03 17:45:02.085333014 +0200 ++++ openssh-8.0p1/auth.h 2019-05-04 16:57:48.606935950 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -335,10 +342,18 @@ diff -Nur openssh-7.9p1.orig/auth.h openssh-7.9p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c ---- openssh-7.9p1.orig/auth-pam.c 2019-02-27 08:08:38.523519810 +0100 -+++ openssh-7.9p1/auth-pam.c 2019-02-27 08:11:41.378545748 +0100 -@@ -288,6 +288,56 @@ +diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c +--- openssh-8.0p1.orig/auth-pam.c 2019-05-03 17:45:01.961334333 +0200 ++++ openssh-8.0p1/auth-pam.c 2019-05-05 17:59:01.979771873 +0200 +@@ -251,6 +251,7 @@ + static char *sshpam_rhost = NULL; + static char *sshpam_laddr = NULL; + static char *sshpam_conninfo = NULL; ++static struct ssh *sshpam_ssh = NULL; + + /* Some PAM implementations don't implement this */ + #ifndef HAVE_PAM_GETENVLIST +@@ -291,6 +292,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -382,7 +397,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c + "'%.100s' provided by PAM_USER", user); + pwfree(sshpam_authctxt->pw); + sshpam_authctxt->pw = pwcopy(pw); -+ sshpam_authctxt->valid = allowed_user(pw); ++ sshpam_authctxt->valid = allowed_user(sshpam_ssh, pw); + free(sshpam_authctxt->user); + sshpam_authctxt->user = xstrdup(user); + debug("PAM: user '%.100s' now %svalid", user, @@ -395,7 +410,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c void sshpam_password_change_required(int reqd) { -@@ -319,7 +369,7 @@ +@@ -322,7 +373,7 @@ static void import_environments(struct sshbuf *b) { @@ -404,7 +419,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c u_int n, i, num_env; int r; -@@ -335,6 +385,19 @@ +@@ -338,6 +389,19 @@ if ((r = sshbuf_get_u32(b, &n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshpam_password_change_required(n != 0); @@ -424,7 +439,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -507,6 +570,13 @@ +@@ -510,6 +574,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -438,7 +453,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -527,6 +597,13 @@ +@@ -530,6 +601,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -452,7 +467,16 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -1024,6 +1101,18 @@ +@@ -714,6 +792,8 @@ + xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), + sshpam_laddr, ssh_local_port(ssh)); ++ /* Save so allowed_user can be called later */ ++ sshpam_ssh = ssh; + } + if (sshpam_rhost != NULL) { + debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); +@@ -1050,6 +1130,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -471,7 +495,7 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1314,6 +1403,9 @@ +@@ -1340,6 +1432,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -481,9 +505,9 @@ diff -Nur openssh-7.9p1.orig/auth-pam.c openssh-7.9p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-7.9p1.orig/auth-pam.h openssh-7.9p1/auth-pam.h ---- openssh-7.9p1.orig/auth-pam.h 2019-02-27 08:08:38.523519810 +0100 -+++ openssh-7.9p1/auth-pam.h 2019-02-27 08:09:31.784944812 +0100 +diff -Nur openssh-8.0p1.orig/auth-pam.h openssh-8.0p1/auth-pam.h +--- openssh-8.0p1.orig/auth-pam.h 2019-05-03 17:45:01.961334333 +0200 ++++ openssh-8.0p1/auth-pam.h 2019-05-04 16:57:48.607935939 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -491,9 +515,9 @@ diff -Nur openssh-7.9p1.orig/auth-pam.h openssh-7.9p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c ---- openssh-7.9p1.orig/canohost.c 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/canohost.c 2019-02-27 08:09:31.803944607 +0100 +diff -Nur openssh-8.0p1.orig/canohost.c openssh-8.0p1/canohost.c +--- openssh-8.0p1.orig/canohost.c 2019-05-03 17:45:02.006333854 +0200 ++++ openssh-8.0p1/canohost.c 2019-05-04 16:57:48.607935939 +0200 @@ -17,6 +17,7 @@ #include #include @@ -502,7 +526,7 @@ diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c #include #include -@@ -202,3 +203,33 @@ +@@ -295,3 +296,33 @@ { return get_sock_port(sock, 1); } @@ -536,20 +560,20 @@ diff -Nur openssh-7.9p1.orig/canohost.c openssh-7.9p1/canohost.c + } + } +} -diff -Nur openssh-7.9p1.orig/canohost.h openssh-7.9p1/canohost.h ---- openssh-7.9p1.orig/canohost.h 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/canohost.h 2019-02-27 08:09:31.803944607 +0100 -@@ -23,4 +23,6 @@ +diff -Nur openssh-8.0p1.orig/canohost.h openssh-8.0p1/canohost.h +--- openssh-8.0p1.orig/canohost.h 2019-05-03 17:45:02.006333854 +0200 ++++ openssh-8.0p1/canohost.h 2019-05-04 16:57:48.608935928 +0200 +@@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac ---- openssh-7.9p1.orig/configure.ac 2019-02-27 08:08:38.942515287 +0100 -+++ openssh-7.9p1/configure.ac 2019-02-27 08:09:31.806944574 +0100 -@@ -4631,6 +4631,14 @@ +diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac +--- openssh-8.0p1.orig/configure.ac 2019-05-03 17:45:02.071333163 +0200 ++++ openssh-8.0p1/configure.ac 2019-05-04 16:57:48.609935918 +0200 +@@ -4571,6 +4571,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -562,9 +586,9 @@ diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac + GSSAPI="KRB5"; + fi fi - if test ! -z "$need_dash_r" ; then - LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" -@@ -4670,6 +4678,40 @@ + if test -n "${rpath_opt}" ; then + LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" +@@ -4610,6 +4618,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -605,10 +629,10 @@ diff -Nur openssh-7.9p1.orig/configure.ac openssh-7.9p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c ---- openssh-7.9p1.orig/gss-genr.c 2019-02-27 08:08:38.859516183 +0100 -+++ openssh-7.9p1/gss-genr.c 2019-02-27 08:09:31.806944574 +0100 -@@ -41,6 +41,7 @@ +diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c +--- openssh-8.0p1.orig/gss-genr.c 2019-05-03 17:45:02.008333833 +0200 ++++ openssh-8.0p1/gss-genr.c 2019-05-04 16:57:48.610935907 +0200 +@@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "log.h" @@ -616,7 +640,7 @@ diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -395,9 +396,18 @@ +@@ -412,9 +413,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -636,7 +660,7 @@ diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -405,6 +415,7 @@ +@@ -422,6 +432,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -644,9 +668,9 @@ diff -Nur openssh-7.9p1.orig/gss-genr.c openssh-7.9p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c ---- openssh-7.9p1.orig/gss-serv.c 2019-02-27 08:08:38.915515578 +0100 -+++ openssh-7.9p1/gss-serv.c 2019-02-27 08:09:31.807944563 +0100 +diff -Nur openssh-8.0p1.orig/gss-serv.c openssh-8.0p1/gss-serv.c +--- openssh-8.0p1.orig/gss-serv.c 2019-05-03 17:45:02.025333652 +0200 ++++ openssh-8.0p1/gss-serv.c 2019-05-04 20:13:35.891347677 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -655,7 +679,7 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c 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}, 0, 0}; +- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; + { {0, NULL}, GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, + GSS_C_NO_NAME, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, + GSS_C_NO_CONTEXT, 0, 0}; @@ -734,8 +758,8 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c return GSS_S_COMPLETE; } -- if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -- ctx->client_creds, ctx->oid, &new_name, +- if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, +- ctx->client_creds, ctx->oid, &new_name, + /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech + because GSI doesn't support the latter. -jbasney */ + @@ -746,7 +770,7 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c return (ctx->major); } -- ctx->major = gss_compare_name(&ctx->minor, client->name, +- ctx->major = gss_compare_name(&ctx->minor, client->name, + ctx->major = gss_compare_name(&ctx->minor, client->cred_name, new_name, &equal); @@ -761,7 +785,7 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c - client->name = new_name; + client->cred_name = new_name; client->creds = ctx->client_creds; - ctx->client_creds = GSS_C_NO_CREDENTIAL; + ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; @@ -356,12 +391,17 @@ i++; @@ -892,7 +916,7 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c + return (0); +} + - /* These bits are only used for rekeying. The unpriviledged child is running + /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * @@ -499,9 +583,11 @@ @@ -903,12 +927,12 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c #endif - if (gssapi_client.store.envval == NULL) -+ if (gssapi_client.store.filename == NULL && ++ if (gssapi_client.store.filename == NULL && + gssapi_client.store.envval == NULL) return; - + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -@@ -527,6 +613,18 @@ +@@ -526,6 +612,18 @@ if (ret) return; @@ -924,12 +948,12 @@ diff -Nur openssh-7.9p1.orig/gss-serv.c openssh-7.9p1/gss-serv.c + } + free_pam_environment(p); + - xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, + xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-7.9p1.orig/gss-serv-gsi.c openssh-7.9p1/gss-serv-gsi.c ---- openssh-7.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-7.9p1/gss-serv-gsi.c 2019-02-27 08:09:31.807944563 +0100 +diff -Nur openssh-8.0p1.orig/gss-serv-gsi.c openssh-8.0p1/gss-serv-gsi.c +--- openssh-8.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.0p1/gss-serv-gsi.c 2019-05-04 16:57:48.611935896 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1259,9 +1283,9 @@ diff -Nur openssh-7.9p1.orig/gss-serv-gsi.c openssh-7.9p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c ---- openssh-7.9p1.orig/gss-serv-krb5.c 2019-02-27 08:08:38.787516960 +0100 -+++ openssh-7.9p1/gss-serv-krb5.c 2019-02-27 08:09:31.807944563 +0100 +diff -Nur openssh-8.0p1.orig/gss-serv-krb5.c openssh-8.0p1/gss-serv-krb5.c +--- openssh-8.0p1.orig/gss-serv-krb5.c 2019-05-03 17:45:02.047333418 +0200 ++++ openssh-8.0p1/gss-serv-krb5.c 2019-05-04 17:55:04.987868146 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1297,16 +1321,16 @@ diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -471,7 +499,7 @@ +@@ -473,7 +501,7 @@ return set_env; } -int +static int - ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -542,7 +570,7 @@ +@@ -544,7 +572,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1315,72 +1339,76 @@ diff -Nur openssh-7.9p1.orig/gss-serv-krb5.c openssh-7.9p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-7.9p1.orig/kexgsss.c openssh-7.9p1/kexgsss.c ---- openssh-7.9p1.orig/kexgsss.c 2019-02-27 08:08:38.852516259 +0100 -+++ openssh-7.9p1/kexgsss.c 2019-02-27 08:09:31.808944553 +0100 +diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c +--- openssh-8.0p1.orig/kexgsss.c 2019-05-03 17:45:02.011333801 +0200 ++++ openssh-8.0p1/kexgsss.c 2019-05-05 13:42:59.924759377 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" -+static void kex_gss_send_error(Gssctxt *ctxt); ++static void kex_gss_send_error(Gssctxt *ctxt, struct ssh *ssh); extern ServerOptions options; int -@@ -97,8 +98,10 @@ +@@ -96,8 +97,10 @@ debug2("%s: Acquiring credentials", __func__); - if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) { -+ kex_gss_send_error(ctxt); ++ kex_gss_send_error(ctxt, ssh); fatal("Unable to acquire credentials for the server"); + } - switch (ssh->kex->kex_type) { - case KEX_GSS_GRP1_SHA1: -@@ -190,12 +193,13 @@ + do { + debug("Wait SSH2_MSG_KEXGSS_INIT"); +@@ -170,13 +173,14 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { -+ kex_gss_send_error(ctxt); ++ kex_gss_send_error(ctxt, ssh); if (send_tok.length > 0) { - packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value, send_tok.length); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); } - fatal("accept_ctx died"); -+ packet_disconnect("GSSAPI Key Exchange handshake failed"); ++ ssh_packet_disconnect(ssh, "GSSAPI Key Exchange handshake failed"); } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -638,4 +642,23 @@ - } +@@ -471,4 +475,26 @@ + sshbuf_free(shared_secret); return r; } + +static void -+kex_gss_send_error(Gssctxt *ctxt) { ++kex_gss_send_error(Gssctxt *ctxt, struct ssh *ssh) { + char *errstr; + OM_uint32 maj, min; ++ int r; + + errstr = PRIVSEP(ssh_gssapi_last_error(ctxt, &maj, &min)); + if (errstr) { -+ packet_start(SSH2_MSG_KEXGSS_ERROR); -+ packet_put_int(maj); -+ packet_put_int(min); -+ packet_put_cstring(errstr); -+ packet_put_cstring(""); -+ packet_send(); -+ packet_write_wait(); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_ERROR)) != 0 || ++ (r = sshpkt_put_u32(ssh, maj)) != 0 || ++ (r = sshpkt_put_u32(ssh, min)) != 0 || ++ (r = sshpkt_put_cstring(ssh, errstr)) != 0 || ++ (r = sshpkt_put_cstring(ssh, "")) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if ((r = ssh_packet_write_wait(ssh)) != 0) ++ fatal("ssh_packet_write_wait: %s", ssh_err(r)); + /* XXX - We should probably log the error locally here */ + free(errstr); + } +} - #endif /* GSSAPI */ -diff -Nur openssh-7.9p1.orig/Makefile.in openssh-7.9p1/Makefile.in ---- openssh-7.9p1.orig/Makefile.in 2019-02-27 08:08:39.000514661 +0100 -+++ openssh-7.9p1/Makefile.in 2019-02-27 08:09:31.808944553 +0100 -@@ -124,6 +124,7 @@ + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ +diff -Nur openssh-8.0p1.orig/Makefile.in openssh-8.0p1/Makefile.in +--- openssh-8.0p1.orig/Makefile.in 2019-05-03 17:45:02.098332875 +0200 ++++ openssh-8.0p1/Makefile.in 2019-05-04 16:57:48.613935875 +0200 +@@ -125,6 +125,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1388,10 +1416,10 @@ diff -Nur openssh-7.9p1.orig/Makefile.in openssh-7.9p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c ---- openssh-7.9p1.orig/misc.c 2019-02-27 08:08:38.783517003 +0100 -+++ openssh-7.9p1/misc.c 2019-02-27 08:09:31.808944553 +0100 -@@ -238,11 +238,14 @@ +diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c +--- openssh-8.0p1.orig/misc.c 2019-05-03 17:45:01.962334322 +0200 ++++ openssh-8.0p1/misc.c 2019-05-04 16:57:48.614935864 +0200 +@@ -313,11 +313,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1407,7 +1435,7 @@ diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c int wspace = 0; if (*s == NULL) -@@ -250,6 +253,21 @@ +@@ -325,6 +328,21 @@ old = *s; @@ -1429,7 +1457,7 @@ diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -325,6 +343,20 @@ +@@ -400,6 +418,20 @@ return copy; } @@ -1450,10 +1478,10 @@ diff -Nur openssh-7.9p1.orig/misc.c openssh-7.9p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-7.9p1.orig/misc.h openssh-7.9p1/misc.h ---- openssh-7.9p1.orig/misc.h 2019-02-27 08:08:38.783517003 +0100 -+++ openssh-7.9p1/misc.h 2019-02-27 08:09:31.808944553 +0100 -@@ -83,6 +83,7 @@ +diff -Nur openssh-8.0p1.orig/misc.h openssh-8.0p1/misc.h +--- openssh-8.0p1.orig/misc.h 2019-04-18 00:52:57.000000000 +0200 ++++ openssh-8.0p1/misc.h 2019-05-04 16:57:48.614935864 +0200 +@@ -87,6 +87,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1461,20 +1489,20 @@ diff -Nur openssh-7.9p1.orig/misc.h openssh-7.9p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c ---- openssh-7.9p1.orig/monitor.c 2019-02-27 08:08:39.014514510 +0100 -+++ openssh-7.9p1/monitor.c 2019-02-27 08:09:31.809944542 +0100 -@@ -152,6 +152,9 @@ - int mm_answer_gss_userok(int, struct sshbuf *); - int mm_answer_gss_checkmic(int, struct sshbuf *); - int mm_answer_gss_sign(int, struct sshbuf *); -+int mm_answer_gss_error(int, struct sshbuf *); -+int mm_answer_gss_indicate_mechs(int, struct sshbuf *); -+int mm_answer_gss_localname(int, struct sshbuf *); - int mm_answer_gss_updatecreds(int, struct sshbuf *); +diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c +--- openssh-8.0p1.orig/monitor.c 2019-05-03 17:45:02.106332790 +0200 ++++ openssh-8.0p1/monitor.c 2019-05-04 18:32:50.066418064 +0200 +@@ -154,6 +154,9 @@ + int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_sign(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_error(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_indicate_mechs(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_localname(struct ssh*, int, struct sshbuf *); + int mm_answer_gss_updatecreds(struct ssh*, int, struct sshbuf *); #endif -@@ -202,7 +205,7 @@ +@@ -206,7 +209,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1483,7 +1511,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -210,7 +213,7 @@ +@@ -214,7 +217,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1492,7 +1520,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -234,8 +237,11 @@ +@@ -238,8 +241,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1505,7 +1533,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c #endif {0, 0, NULL} }; -@@ -245,6 +251,8 @@ +@@ -249,6 +255,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1514,7 +1542,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -326,6 +334,8 @@ +@@ -329,6 +337,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1523,16 +1551,16 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -444,6 +454,8 @@ +@@ -448,6 +458,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1); - #endif + #endif if (auth_opts->permit_pty_flag) { -@@ -764,15 +776,18 @@ +@@ -766,15 +778,18 @@ debug3("%s", __func__); @@ -1542,7 +1570,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - pwent = getpwnamallow(username); + pwent = getpwnamallow(ssh, username); + if (authctxt->user) free(authctxt->user); authctxt->user = xstrdup(username); @@ -1554,12 +1582,11 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2070,6 +2085,79 @@ - return (authenticated); +@@ -2067,6 +2082,79 @@ } -+int -+mm_answer_gss_error(int socket, struct sshbuf *m) + int ++mm_answer_gss_error(struct ssh *ssh, int socket, struct sshbuf *m) +{ + OM_uint32 major, minor; + char *msg; @@ -1580,7 +1607,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c +} + +int -+mm_answer_gss_indicate_mechs(int socket, struct sshbuf *m) ++mm_answer_gss_indicate_mechs(struct ssh *ssh, int socket, struct sshbuf *m) +{ + OM_uint32 major, minor; + gss_OID_set mech_set; @@ -1607,7 +1634,7 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c +} + +int -+mm_answer_gss_localname(int socket, struct sshbuf *m) ++mm_answer_gss_localname(struct ssh *ssh, int socket, struct sshbuf *m) +{ + char *name; + int r; @@ -1631,45 +1658,28 @@ diff -Nur openssh-7.9p1.orig/monitor.c openssh-7.9p1/monitor.c + return(0); +} + - int - mm_answer_gss_sign(int socket, struct sshbuf *m) ++int + mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { -@@ -2121,12 +2209,14 @@ - ssh_gssapi_ccache store; - int ok, r; + gss_buffer_desc data; +diff -Nur openssh-8.0p1.orig/monitor.h openssh-8.0p1/monitor.h +--- openssh-8.0p1.orig/monitor.h 2019-05-03 17:45:02.087332993 +0200 ++++ openssh-8.0p1/monitor.h 2019-05-04 18:34:50.027124629 +0200 +@@ -75,6 +75,10 @@ -- if ((r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || -+ if ((r = sshbuf_get_cstring(m, &store.filename, NULL)) != 0 || -+ (r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || - (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - ok = ssh_gssapi_update_creds(&store); - -+ free(store.filename); - free(store.envvar); - free(store.envval); - -diff -Nur openssh-7.9p1.orig/monitor.h openssh-7.9p1/monitor.h ---- openssh-7.9p1.orig/monitor.h 2019-02-27 08:08:38.969514995 +0100 -+++ openssh-7.9p1/monitor.h 2019-02-27 08:09:31.809944542 +0100 -@@ -73,8 +73,10 @@ - MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, - MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, - MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, -- MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124 -- -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, + MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, + MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, ++ + MONITOR_REQ_GSSMECHS = 200, MONITOR_ANS_GSSMECHS = 201, + MONITOR_REQ_GSSLOCALNAME = 202, MONITOR_ANS_GSSLOCALNAME = 203, + MONITOR_REQ_GSSERR = 204, MONITOR_ANS_GSSERR = 205 }; - struct monitor { -diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c ---- openssh-7.9p1.orig/monitor_wrap.c 2019-02-27 08:08:39.015514499 +0100 -+++ openssh-7.9p1/monitor_wrap.c 2019-02-27 08:09:31.810944531 +0100 -@@ -1067,6 +1067,94 @@ + struct ssh; +diff -Nur openssh-8.0p1.orig/monitor_wrap.c openssh-8.0p1/monitor_wrap.c +--- openssh-8.0p1.orig/monitor_wrap.c 2019-05-03 17:45:02.107332780 +0200 ++++ openssh-8.0p1/monitor_wrap.c 2019-05-04 20:14:18.401891101 +0200 +@@ -1061,6 +1061,94 @@ return (authenticated); } @@ -1741,7 +1751,7 @@ diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal("%s: sshbuf_new failed", __func__); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, m); + + debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__); @@ -1764,20 +1774,10 @@ diff -Nur openssh-7.9p1.orig/monitor_wrap.c openssh-7.9p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -@@ -1100,7 +1188,8 @@ - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); - -- if ((r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || -+ if ((r = sshbuf_put_cstring(m, store->filename ? store->filename : "")) != 0 || -+ (r = sshbuf_put_cstring(m, store->envvar ? store->envvar : "")) != 0 || - (r = sshbuf_put_cstring(m, store->envval ? store->envval : "")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - -diff -Nur openssh-7.9p1.orig/monitor_wrap.h openssh-7.9p1/monitor_wrap.h ---- openssh-7.9p1.orig/monitor_wrap.h 2019-02-27 08:08:38.984514834 +0100 -+++ openssh-7.9p1/monitor_wrap.h 2019-02-27 08:09:31.810944531 +0100 -@@ -68,6 +68,10 @@ +diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h +--- openssh-8.0p1.orig/monitor_wrap.h 2019-05-03 17:45:02.093332929 +0200 ++++ openssh-8.0p1/monitor_wrap.h 2019-05-04 16:57:48.617935831 +0200 +@@ -69,6 +69,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1788,10 +1788,10 @@ diff -Nur openssh-7.9p1.orig/monitor_wrap.h openssh-7.9p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c ---- openssh-7.9p1.orig/readconf.c 2019-02-27 08:08:39.002514639 +0100 -+++ openssh-7.9p1/readconf.c 2019-02-27 08:09:31.810944531 +0100 -@@ -2051,13 +2051,13 @@ +diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c +--- openssh-8.0p1.orig/readconf.c 2019-05-03 17:45:02.098332875 +0200 ++++ openssh-8.0p1/readconf.c 2019-05-04 16:57:48.618935821 +0200 +@@ -2052,13 +2052,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1809,9 +1809,9 @@ diff -Nur openssh-7.9p1.orig/readconf.c openssh-7.9p1/readconf.c if (options->gss_renewal_rekey == -1) options->gss_renewal_rekey = 0; #ifdef GSSAPI -diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h ---- openssh-7.9p1.orig/readconf.h 2019-02-27 08:08:38.927515449 +0100 -+++ openssh-7.9p1/readconf.h 2019-02-27 08:09:31.811944520 +0100 +diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h +--- openssh-8.0p1.orig/readconf.h 2019-05-03 17:45:02.013333780 +0200 ++++ openssh-8.0p1/readconf.h 2019-05-04 16:57:48.619935810 +0200 @@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1821,9 +1821,9 @@ diff -Nur openssh-7.9p1.orig/readconf.h openssh-7.9p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c ---- openssh-7.9p1.orig/servconf.c 2019-02-27 08:08:39.017514477 +0100 -+++ openssh-7.9p1/servconf.c 2019-02-27 08:09:31.812944509 +0100 +diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c +--- openssh-8.0p1.orig/servconf.c 2019-05-03 17:45:02.108332769 +0200 ++++ openssh-8.0p1/servconf.c 2019-05-04 19:24:49.590820223 +0200 @@ -84,6 +84,7 @@ /* Portable-specific options */ @@ -1844,7 +1844,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -273,6 +276,8 @@ +@@ -286,6 +289,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1853,7 +1853,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -350,13 +355,17 @@ +@@ -363,13 +368,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1873,7 +1873,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -491,7 +500,7 @@ +@@ -501,7 +510,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1882,7 +1882,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -513,6 +522,9 @@ +@@ -523,6 +532,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1890,9 +1890,9 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel, - sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, -@@ -542,8 +554,10 @@ + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, + sAcceptEnv, sSetEnv, sPermitTunnel, +@@ -553,8 +565,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1903,12 +1903,13 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -591,7 +605,14 @@ +@@ -602,8 +616,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, + { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL }, +#ifdef GSI + { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL }, @@ -1918,18 +1919,19 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -599,7 +620,10 @@ - { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, +@@ -611,8 +632,11 @@ + { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL }, + { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -670,6 +694,8 @@ +@@ -682,6 +706,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1938,7 +1940,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1301,6 +1327,10 @@ +@@ -1313,6 +1339,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1949,7 +1951,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1519,6 +1549,10 @@ +@@ -1533,6 +1563,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1960,7 +1962,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1527,6 +1561,10 @@ +@@ -1541,6 +1575,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1971,7 +1973,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1547,6 +1585,12 @@ +@@ -1561,6 +1599,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1984,7 +1986,7 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2354,6 +2398,7 @@ +@@ -2364,6 +2408,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1992,10 +1994,10 @@ diff -Nur openssh-7.9p1.orig/servconf.c openssh-7.9p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-7.9p1.orig/servconf.h openssh-7.9p1/servconf.h ---- openssh-7.9p1.orig/servconf.h 2019-02-27 08:08:38.830516496 +0100 -+++ openssh-7.9p1/servconf.h 2019-02-27 08:09:31.812944509 +0100 -@@ -130,9 +130,12 @@ +diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h +--- openssh-8.0p1.orig/servconf.h 2019-05-03 17:45:02.059333290 +0200 ++++ openssh-8.0p1/servconf.h 2019-05-04 16:57:48.620935799 +0200 +@@ -131,9 +131,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2016,10 +2018,10 @@ diff -Nur openssh-7.9p1.orig/servconf.h openssh-7.9p1/servconf.h int permit_tun; -diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 ---- openssh-7.9p1.orig/ssh.1 2019-02-27 08:08:38.819516615 +0100 -+++ openssh-7.9p1/ssh.1 2019-02-27 08:09:31.812944509 +0100 -@@ -1433,6 +1433,18 @@ +diff -Nur openssh-8.0p1.orig/ssh.1 openssh-8.0p1/ssh.1 +--- openssh-8.0p1.orig/ssh.1 2019-05-03 17:45:02.014333769 +0200 ++++ openssh-8.0p1/ssh.1 2019-05-04 16:57:48.621935788 +0200 +@@ -1427,6 +1427,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2038,9 +2040,9 @@ diff -Nur openssh-7.9p1.orig/ssh.1 openssh-7.9p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c ---- openssh-7.9p1.orig/ssh.c 2019-02-27 08:08:39.004514618 +0100 -+++ openssh-7.9p1/ssh.c 2019-02-27 08:15:38.242004315 +0100 +diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c +--- openssh-8.0p1.orig/ssh.c 2019-05-03 17:45:02.100332854 +0200 ++++ openssh-8.0p1/ssh.c 2019-05-04 16:57:48.622935778 +0200 @@ -543,6 +543,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2080,8 +2082,8 @@ diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1298,8 +1330,12 @@ - logit("FIPS mode initialized"); +@@ -1295,8 +1327,12 @@ + tty_flag = 0; } - if (options.user == NULL) @@ -2094,9 +2096,9 @@ diff -Nur openssh-7.9p1.orig/ssh.c openssh-7.9p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) -diff -Nur openssh-7.9p1.orig/ssh_config openssh-7.9p1/ssh_config ---- openssh-7.9p1.orig/ssh_config 2019-02-27 08:08:38.702517878 +0100 -+++ openssh-7.9p1/ssh_config 2019-02-27 08:09:31.813944499 +0100 +diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config +--- openssh-8.0p1.orig/ssh_config 2019-05-03 17:45:02.015333759 +0200 ++++ openssh-8.0p1/ssh_config 2019-05-04 16:57:48.622935778 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2112,9 +2114,9 @@ diff -Nur openssh-7.9p1.orig/ssh_config openssh-7.9p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 ---- openssh-7.9p1.orig/ssh_config.5 2019-02-27 08:08:38.933515384 +0100 -+++ openssh-7.9p1/ssh_config.5 2019-02-27 08:09:31.814944488 +0100 +diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 +--- openssh-8.0p1.orig/ssh_config.5 2019-05-03 17:45:02.076333110 +0200 ++++ openssh-8.0p1/ssh_config.5 2019-05-04 16:57:48.623935767 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,8 +2137,8 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 -.Cm no . +.Cm yes . .It Cm GSSAPIClientIdentity - If set, specifies the GSSAPI client identity that ssh should use when - connecting to the server. The default is unset, which means that the default + If set, specifies the GSSAPI client identity that ssh should use when + connecting to the server. The default is unset, which means that the default @@ -761,12 +767,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. @@ -2150,7 +2152,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 -.Dq no . +.Dq yes . .It Cm GSSAPIRenewalForcesRekey - If set to + If set to .Dq yes @@ -798,7 +804,7 @@ the hostname entered on the @@ -2161,7 +2163,7 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1267,7 +1273,7 @@ +@@ -1270,7 +1276,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2170,12 +2172,12 @@ diff -Nur openssh-7.9p1.orig/ssh_config.5 openssh-7.9p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c ---- openssh-7.9p1.orig/sshconnect2.c 2019-02-27 08:08:39.005514607 +0100 -+++ openssh-7.9p1/sshconnect2.c 2019-02-27 08:09:31.815944477 +0100 -@@ -894,6 +894,11 @@ - int r, ok = 0; - const char *gss_host = NULL; +diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c +--- openssh-8.0p1.orig/sshconnect2.c 2019-05-03 17:45:02.100332854 +0200 ++++ openssh-8.0p1/sshconnect2.c 2019-05-04 18:51:03.754633706 +0200 +@@ -778,6 +778,11 @@ + gss_OID mech = NULL; + char *gss_host; + if (!options.gss_authentication) { + verbose("GSSAPI authentication disabled."); @@ -2183,9 +2185,9 @@ diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c + } + if (options.gss_server_identity) - gss_host = options.gss_server_identity; - else if (options.gss_trust_dns) { -@@ -987,7 +992,8 @@ + gss_host = xstrdup(options.gss_server_identity); + else if (options.gss_trust_dns) +@@ -880,7 +885,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2195,7 +2197,7 @@ diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1157,6 +1163,20 @@ +@@ -1050,6 +1056,20 @@ return r; } @@ -2214,9 +2216,9 @@ diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c +#endif + int - userauth_gsskeyex(Authctxt *authctxt) + userauth_gsskeyex(struct ssh *ssh) { -@@ -1177,6 +1197,11 @@ +@@ -1072,6 +1092,11 @@ if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -2228,23 +2230,20 @@ diff -Nur openssh-7.9p1.orig/sshconnect2.c openssh-7.9p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -@@ -1189,7 +1214,13 @@ +@@ -1085,7 +1110,9 @@ } - packet_start(SSH2_MSG_USERAUTH_REQUEST); -+#ifdef GSI -+ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) -+ packet_put_cstring(""); -+ else -+#endif - packet_put_cstring(authctxt->server_user); -+ - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_string(mic.value, mic.length); -diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 ---- openssh-7.9p1.orig/sshd.8 2019-02-27 08:08:38.739517478 +0100 -+++ openssh-7.9p1/sshd.8 2019-02-27 08:09:31.815944477 +0100 + if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || +- (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || ++ (r = sshpkt_put_cstring(ssh, ++ (options.implicit && is_gsi_oid(gss_kex_context->oid)) ? ++ "" : authctxt->server_user)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || +diff -Nur openssh-8.0p1.orig/sshd.8 openssh-8.0p1/sshd.8 +--- openssh-8.0p1.orig/sshd.8 2019-05-03 17:45:02.030333599 +0200 ++++ openssh-8.0p1/sshd.8 2019-05-04 16:57:48.625935745 +0200 @@ -788,6 +788,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2275,10 +2274,10 @@ diff -Nur openssh-7.9p1.orig/sshd.8 openssh-7.9p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-7.9p1.orig/sshd.c openssh-7.9p1/sshd.c ---- openssh-7.9p1.orig/sshd.c 2019-02-27 08:08:39.020514445 +0100 -+++ openssh-7.9p1/sshd.c 2019-02-27 08:09:31.815944477 +0100 -@@ -2305,7 +2305,7 @@ +diff -Nur openssh-8.0p1.orig/sshd.c openssh-8.0p1/sshd.c +--- openssh-8.0p1.orig/sshd.c 2019-05-03 17:45:02.109332758 +0200 ++++ openssh-8.0p1/sshd.c 2019-05-04 16:57:48.625935745 +0200 +@@ -2265,7 +2265,7 @@ #endif #ifdef GSSAPI @@ -2287,9 +2286,9 @@ diff -Nur openssh-7.9p1.orig/sshd.c openssh-7.9p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-7.9p1.orig/sshd_config openssh-7.9p1/sshd_config ---- openssh-7.9p1.orig/sshd_config 2019-02-27 08:08:38.802516798 +0100 -+++ openssh-7.9p1/sshd_config 2019-02-27 08:09:31.816944466 +0100 +diff -Nur openssh-8.0p1.orig/sshd_config openssh-8.0p1/sshd_config +--- openssh-8.0p1.orig/sshd_config 2019-05-03 17:45:02.054333344 +0200 ++++ openssh-8.0p1/sshd_config 2019-05-04 16:57:48.625935745 +0200 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2315,9 +2314,9 @@ diff -Nur openssh-7.9p1.orig/sshd_config openssh-7.9p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 ---- openssh-7.9p1.orig/sshd_config.5 2019-02-27 08:08:38.858516194 +0100 -+++ openssh-7.9p1/sshd_config.5 2019-02-27 08:09:31.816944466 +0100 +diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 +--- openssh-8.0p1.orig/sshd_config.5 2019-05-03 17:45:02.060333280 +0200 ++++ openssh-8.0p1/sshd_config.5 2019-05-04 18:52:25.145757179 +0200 @@ -644,15 +644,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2358,8 +2357,8 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is --.Dq no . -+.Dq yes . +-.Cm no . ++.Cm yes . .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. @@ -2371,7 +2370,7 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a list of comma-separated patterns. -@@ -1681,6 +1699,12 @@ +@@ -1674,6 +1692,12 @@ as a non-root user. The default is .Cm no . @@ -2384,18 +2383,10 @@ diff -Nur openssh-7.9p1.orig/sshd_config.5 openssh-7.9p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h ---- openssh-7.9p1.orig/ssh-gss.h 2019-02-27 08:08:38.917515557 +0100 -+++ openssh-7.9p1/ssh-gss.h 2019-02-27 08:09:31.816944466 +0100 -@@ -85,6 +85,7 @@ - KEX_GSS_GRP14_SHA1_ID - - typedef struct { -+ char *filename; - char *envvar; - char *envval; - struct passwd *owner; -@@ -92,12 +93,14 @@ +diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h +--- openssh-8.0p1.orig/ssh-gss.h 2019-05-03 17:45:02.027333631 +0200 ++++ openssh-8.0p1/ssh-gss.h 2019-05-04 16:58:00.709805460 +0200 +@@ -93,12 +93,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -2411,7 +2402,7 @@ diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -118,7 +121,7 @@ +@@ -119,7 +121,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2420,7 +2411,7 @@ diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -155,6 +158,9 @@ +@@ -157,6 +159,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2428,14 +2419,14 @@ diff -Nur openssh-7.9p1.orig/ssh-gss.h openssh-7.9p1/ssh-gss.h +void ssh_gssapi_rekey_creds(); + /* In the server */ - typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, + typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-7.9p1.orig/version.h openssh-7.9p1/version.h ---- openssh-7.9p1.orig/version.h 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/version.h 2019-02-27 08:09:31.816944466 +0100 +diff -Nur openssh-8.0p1.orig/version.h openssh-8.0p1/version.h +--- openssh-8.0p1.orig/version.h 2019-04-18 00:52:57.000000000 +0200 ++++ openssh-8.0p1/version.h 2019-05-04 18:53:27.162089305 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_7.9" + #define SSH_VERSION "OpenSSH_8.0" +#ifdef GSI +#define GSI_VERSION " GSI" @@ -2451,6 +2442,6 @@ diff -Nur openssh-7.9p1.orig/version.h openssh-7.9p1/version.h + #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE -+#define GSI_PORTABLE "b-GSI" ++#define GSI_PORTABLE "c-GSI" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ + GSI_VERSION KRB5_VERSION diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch new file mode 100644 index 0000000..fe3e7a6 --- /dev/null +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -0,0 +1,3924 @@ +diff --git a/Makefile.in b/Makefile.in +index 6f001bb3..c31821ac 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexgexc.o kexgexs.o \ + sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ ++ kexgssc.o \ + platform-pledge.o platform-tracing.o platform-misc.o + + +@@ -114,7 +115,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ + auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.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 \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ + sftp-server.o sftp-common.o \ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ +diff --git a/auth.c b/auth.c +index 332b6220..7664aaac 100644 +--- a/auth.c ++++ b/auth.c +@@ -399,7 +399,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || +- strcmp(method, "gssapi-with-mic") == 0) ++ strcmp(method, "gssapi-with-mic") == 0 || ++ strcmp(method, "gssapi-keyex") == 0) + return 1; + break; + case PERMIT_FORCED_ONLY: +@@ -723,99 +724,6 @@ fakepw(void) + return (&fake); + } + +-/* +- * 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 legacy rhosts-style authentication. +- * XXX is RhostsRSAAuthentication vulnerable to these? +- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) +- */ +- +-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) < 0) { +- debug("getpeername failed: %.100s", strerror(errno)); +- return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); +- } +- return strdup(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 +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.29 2018/07/31 03:10: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 *); + ++/* ++ * The 'gssapi_keyex' userauth mechanism. ++ */ ++static int ++userauth_gsskeyex(struct ssh *ssh) ++{ ++ Authctxt *authctxt = ssh->authctxt; ++ int r, authenticated = 0; ++ struct sshbuf *b = NULL; ++ gss_buffer_desc mic, gssbuf; ++ u_char *p; ++ size_t len; ++ ++ if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("%s: %s", __func__, ssh_err(r)); ++ ++ if ((b = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ mic.value = p; ++ mic.length = len; ++ ++ ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, ++ "gssapi-keyex"); ++ ++ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) ++ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ 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)); ++ ++ sshbuf_free(b); ++ free(mic.value); ++ ++ return (authenticated); ++} ++ + /* + * 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) + if ((r = sshpkt_get_end(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); ++ authenticated = PRIVSEP(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) + 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)); + else + logit("GSSAPI MIC check failed"); + +@@ -326,6 +370,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) + return 0; + } + ++Authmethod method_gsskeyex = { ++ "gssapi-keyex", ++ userauth_gsskeyex, ++ &options.gss_authentication ++}; ++ + Authmethod method_gssapi = { + "gssapi-with-mic", + userauth_gssapi, +diff --git a/auth2.c b/auth2.c +index 16ae1a36..7417eafa 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -75,6 +75,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif + +@@ -82,6 +83,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + &method_passwd, +diff --git a/canohost.c b/canohost.c +index f71a0856..404731d2 100644 +--- a/canohost.c ++++ b/canohost.c +@@ -35,6 +35,99 @@ + #include "canohost.h" + #include "misc.h" + ++/* ++ * 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 legacy rhosts-style authentication. ++ * XXX is RhostsRSAAuthentication vulnerable to these? ++ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) ++ */ ++ ++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) < 0) { ++ debug("getpeername failed: %.100s", strerror(errno)); ++ return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop); ++ } ++ return strdup(name); ++} ++ + void + ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) + { +diff --git a/canohost.h b/canohost.h +index 26d62855..0cadc9f1 100644 +--- a/canohost.h ++++ b/canohost.h +@@ -15,6 +15,9 @@ + #ifndef _CANOHOST_H + #define _CANOHOST_H + ++struct ssh; ++ ++char *remote_hostname(struct ssh *); + char *get_peer_ipaddr(int); + int get_peer_port(int); + char *get_local_ipaddr(int); +diff --git a/clientloop.c b/clientloop.c +index 521467bd..a0578e9d 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -112,6 +112,10 @@ + #include "ssherr.h" + #include "hostfile.h" + ++#ifdef GSSAPI ++#include "ssh-gss.h" ++#endif ++ + /* import options */ + extern Options options; + +@@ -1374,9 +1378,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, + break; + + /* Do channel operations unless rekeying in progress. */ +- if (!ssh_packet_is_rekeying(ssh)) ++ if (!ssh_packet_is_rekeying(ssh)) { + channel_after_select(ssh, readset, writeset); + ++#ifdef GSSAPI ++ if (options.gss_renewal_rekey && ++ ssh_gssapi_credentials_updated(NULL)) { ++ debug("credentials updated - forcing rekey"); ++ need_rekeying = 1; ++ } ++#endif ++ } ++ + /* Buffer input from the connection. */ + client_process_net_input(ssh, readset); + +diff --git a/configure.ac b/configure.ac +index 30be6c18..2869f704 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -665,6 +665,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + [Use tunnel device compatibility to OpenBSD]) + AC_DEFINE([SSH_TUN_PREPEND_AF], [1], + [Prepend the address family to IP tunnel traffic]) ++ AC_MSG_CHECKING([if we have the Security Authorization Session API]) ++ AC_TRY_COMPILE([#include ], ++ [SessionCreate(0, 0);], ++ [ac_cv_use_security_session_api="yes" ++ AC_DEFINE([USE_SECURITY_SESSION_API], [1], ++ [platform has the Security Authorization Session API]) ++ LIBS="$LIBS -framework Security" ++ AC_MSG_RESULT([yes])], ++ [ac_cv_use_security_session_api="no" ++ AC_MSG_RESULT([no])]) ++ AC_MSG_CHECKING([if we have an in-memory credentials cache]) ++ AC_TRY_COMPILE( ++ [#include ], ++ [cc_context_t c; ++ (void) cc_initialize (&c, 0, NULL, NULL);], ++ [AC_DEFINE([USE_CCAPI], [1], ++ [platform uses an in-memory credentials cache]) ++ LIBS="$LIBS -framework Security" ++ AC_MSG_RESULT([yes]) ++ if test "x$ac_cv_use_security_session_api" = "xno"; then ++ AC_MSG_ERROR([*** Need a security framework to use the credentials cache API ***]) ++ fi], ++ [AC_MSG_RESULT([no])] ++ ) + m4_pattern_allow([AU_IPv]) + AC_CHECK_DECL([AU_IPv4], [], + AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) +diff --git a/gss-genr.c b/gss-genr.c +index d56257b4..3eaa5fa5 100644 +--- a/gss-genr.c ++++ b/gss-genr.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-genr.c,v 1.26 2018/07/10 09:13:30 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,12 +41,36 @@ + #include "sshbuf.h" + #include "log.h" + #include "ssh2.h" ++#include "cipher.h" ++#include "sshkey.h" ++#include "kex.h" ++#include "digest.h" ++#include "packet.h" + + #include "ssh-gss.h" + + extern u_char *session_id2; + extern u_int session_id2_len; + ++typedef struct { ++ char *encoded; ++ gss_OID oid; ++} ssh_gss_kex_mapping; ++ ++/* ++ * XXX - It would be nice to find a more elegant way of handling the ++ * XXX passing of the key exchange context to the userauth routines ++ */ ++ ++Gssctxt *gss_kex_context = NULL; ++ ++static ssh_gss_kex_mapping *gss_enc2oid = NULL; ++ ++int ++ssh_gssapi_oid_table_ok(void) { ++ return (gss_enc2oid != NULL); ++} ++ + /* sshbuf_get for gss_buffer_desc */ + int + ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -62,6 +86,161 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) + return 0; + } + ++/* sshpkt_get of gss_buffer_desc */ ++int ++ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *ssh, gss_buffer_desc *g) ++{ ++ int r; ++ u_char *p; ++ size_t len; ++ ++ if ((r = sshpkt_get_string(ssh, &p, &len)) != 0) ++ return r; ++ g->value = p; ++ g->length = len; ++ return 0; ++} ++ ++/* ++ * Return a list of the gss-group1-sha1 mechanisms supported by this program ++ * ++ * We test mechanisms to ensure that we can use them, to avoid starting ++ * a key exchange with a bad mechanism ++ */ ++ ++char * ++ssh_gssapi_client_mechanisms(const char *host, const char *client, ++ const char *kex) { ++ gss_OID_set gss_supported = NULL; ++ OM_uint32 min_status; ++ ++ if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) ++ return NULL; ++ ++ return ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, ++ host, client, kex); ++} ++ ++char * ++ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, ++ const char *host, const char *client, const char *kex) { ++ struct sshbuf *buf = NULL; ++ size_t i; ++ int r, oidpos, enclen; ++ char *mechs, *encoded; ++ u_char digest[SSH_DIGEST_MAX_LENGTH]; ++ char deroid[2]; ++ struct ssh_digest_ctx *md = NULL; ++ char *s, *cp, *p; ++ ++ if (gss_enc2oid != NULL) { ++ for (i = 0; gss_enc2oid[i].encoded != NULL; i++) ++ free(gss_enc2oid[i].encoded); ++ free(gss_enc2oid); ++ } ++ ++ gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * ++ (gss_supported->count + 1)); ++ ++ if ((buf = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ oidpos = 0; ++ s = cp = xstrdup(kex); ++ for (i = 0; i < gss_supported->count; i++) { ++ if (gss_supported->elements[i].length < 128 && ++ (*check)(NULL, &(gss_supported->elements[i]), host, client)) { ++ ++ deroid[0] = SSH_GSS_OIDTYPE; ++ deroid[1] = gss_supported->elements[i].length; ++ ++ if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || ++ (r = ssh_digest_update(md, deroid, 2)) != 0 || ++ (r = ssh_digest_update(md, ++ gss_supported->elements[i].elements, ++ gss_supported->elements[i].length)) != 0 || ++ (r = ssh_digest_final(md, digest, sizeof(digest))) != 0) ++ fatal("%s: digest failed: %s", __func__, ++ ssh_err(r)); ++ ssh_digest_free(md); ++ md = NULL; ++ ++ encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5) ++ * 2); ++ enclen = __b64_ntop(digest, ++ ssh_digest_bytes(SSH_DIGEST_MD5), encoded, ++ ssh_digest_bytes(SSH_DIGEST_MD5) * 2); ++ ++ cp = strncpy(s, kex, strlen(kex)); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (sshbuf_len(buf) != 0 && ++ (r = sshbuf_put_u8(buf, ',')) != 0) ++ fatal("%s: sshbuf_put_u8 error: %s", ++ __func__, ssh_err(r)); ++ if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || ++ (r = sshbuf_put(buf, encoded, enclen)) != 0) ++ fatal("%s: sshbuf_put error: %s", ++ __func__, ssh_err(r)); ++ } ++ ++ gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); ++ gss_enc2oid[oidpos].encoded = encoded; ++ oidpos++; ++ } ++ } ++ free(s); ++ gss_enc2oid[oidpos].oid = NULL; ++ gss_enc2oid[oidpos].encoded = NULL; ++ ++ if ((mechs = sshbuf_dup_string(buf)) == NULL) ++ fatal("%s: sshbuf_dup_string failed", __func__); ++ ++ sshbuf_free(buf); ++ ++ if (strlen(mechs) == 0) { ++ free(mechs); ++ mechs = NULL; ++ } ++ ++ return (mechs); ++} ++ ++gss_OID ++ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { ++ int i = 0; ++ ++#define SKIP_KEX_NAME(type) \ ++ case type: \ ++ if (strlen(name) < sizeof(type##_ID)) \ ++ return GSS_C_NO_OID; \ ++ name += sizeof(type##_ID) - 1; \ ++ break; ++ ++ switch (kex_type) { ++ SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256) ++ SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512) ++ SKIP_KEX_NAME(KEX_GSS_GEX_SHA1) ++ SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256) ++ SKIP_KEX_NAME(KEX_GSS_C25519_SHA256) ++ default: ++ return GSS_C_NO_OID; ++ } ++ ++#undef SKIP_KEX_NAME ++ ++ while (gss_enc2oid[i].encoded != NULL && ++ strcmp(name, gss_enc2oid[i].encoded) != 0) ++ i++; ++ ++ if (gss_enc2oid[i].oid != NULL && ctx != NULL) ++ ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid); ++ ++ return gss_enc2oid[i].oid; ++} ++ + /* Check that the OID in a data stream matches that in the context */ + int + ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) +@@ -218,7 +397,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, + } + + ctx->major = gss_init_sec_context(&ctx->minor, +- GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, ++ ctx->client_creds, &ctx->context, ctx->name, ctx->oid, + GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, + 0, NULL, recv_tok, NULL, send_tok, flags, NULL); + +@@ -247,9 +426,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) + return (ctx->major); + } + ++OM_uint32 ++ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) ++{ ++ gss_buffer_desc gssbuf; ++ gss_name_t gssname; ++ OM_uint32 status; ++ gss_OID_set oidset; ++ ++ gssbuf.value = (void *) name; ++ gssbuf.length = strlen(gssbuf.value); ++ ++ gss_create_empty_oid_set(&status, &oidset); ++ gss_add_oid_set_member(&status, ctx->oid, &oidset); ++ ++ ctx->major = gss_import_name(&ctx->minor, &gssbuf, ++ GSS_C_NT_USER_NAME, &gssname); ++ ++ if (!ctx->major) ++ ctx->major = gss_acquire_cred(&ctx->minor, ++ gssname, 0, oidset, GSS_C_INITIATE, ++ &ctx->client_creds, NULL, NULL); ++ ++ gss_release_name(&status, &gssname); ++ gss_release_oid_set(&status, &oidset); ++ ++ if (ctx->major) ++ ssh_gssapi_error(ctx); ++ ++ return(ctx->major); ++} ++ + OM_uint32 + ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) + { ++ if (ctx == NULL) ++ return -1; ++ + if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, + GSS_C_QOP_DEFAULT, buffer, hash))) + ssh_gssapi_error(ctx); +@@ -257,6 +470,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) + return (ctx->major); + } + ++/* Priviledged when used by server */ ++OM_uint32 ++ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) ++{ ++ if (ctx == NULL) ++ return -1; ++ ++ ctx->major = gss_verify_mic(&ctx->minor, ctx->context, ++ gssbuf, gssmic, NULL); ++ ++ return (ctx->major); ++} ++ + void + ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, + const char *context) +@@ -273,11 +499,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, + } + + int +-ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) ++ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, ++ const char *client) + { + gss_buffer_desc token = GSS_C_EMPTY_BUFFER; + OM_uint32 major, minor; + gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; ++ Gssctxt *intctx = NULL; ++ ++ if (ctx == NULL) ++ ctx = &intctx; + + /* RFC 4462 says we MUST NOT do SPNEGO */ + if (oid->length == spnego_oid.length && +@@ -287,6 +518,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); ++ ++ if (!GSS_ERROR(major) && client) ++ major = ssh_gssapi_client_identity(*ctx, client); ++ + if (!GSS_ERROR(major)) { + major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, + NULL); +@@ -296,10 +531,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) + GSS_C_NO_BUFFER); + } + +- if (GSS_ERROR(major)) ++ if (GSS_ERROR(major) || intctx != NULL) + ssh_gssapi_delete_ctx(ctx); + + return (!GSS_ERROR(major)); + } + ++int ++ssh_gssapi_credentials_updated(Gssctxt *ctxt) { ++ static gss_name_t saved_name = GSS_C_NO_NAME; ++ static OM_uint32 saved_lifetime = 0; ++ static gss_OID saved_mech = GSS_C_NO_OID; ++ static gss_name_t name; ++ static OM_uint32 last_call = 0; ++ OM_uint32 lifetime, now, major, minor; ++ int equal; ++ ++ now = time(NULL); ++ ++ if (ctxt) { ++ debug("Rekey has happened - updating saved versions"); ++ ++ if (saved_name != GSS_C_NO_NAME) ++ gss_release_name(&minor, &saved_name); ++ ++ major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, ++ &saved_name, &saved_lifetime, NULL, NULL); ++ ++ if (!GSS_ERROR(major)) { ++ saved_mech = ctxt->oid; ++ saved_lifetime+= now; ++ } else { ++ /* Handle the error */ ++ } ++ return 0; ++ } ++ ++ if (now - last_call < 10) ++ return 0; ++ ++ last_call = now; ++ ++ if (saved_mech == GSS_C_NO_OID) ++ return 0; ++ ++ major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, ++ &name, &lifetime, NULL, NULL); ++ if (major == GSS_S_CREDENTIALS_EXPIRED) ++ return 0; ++ else if (GSS_ERROR(major)) ++ return 0; ++ ++ major = gss_compare_name(&minor, saved_name, name, &equal); ++ gss_release_name(&minor, &name); ++ if (GSS_ERROR(major)) ++ return 0; ++ ++ if (equal && (saved_lifetime < lifetime + now - 10)) ++ return 1; ++ ++ return 0; ++} ++ + #endif /* GSSAPI */ +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index a151bc1e..8d2b677f 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus 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 +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; +- int len; ++ const char *new_ccname, *new_cctype; + const char *errmsg; + + if (client->creds == NULL) { +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + return; + } + +- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); ++ new_cctype = krb5_cc_get_type(krb_context, ccache); ++ new_ccname = krb5_cc_get_name(krb_context, ccache); ++ + client->store.envvar = "KRB5CCNAME"; +- len = strlen(client->store.filename) + 6; +- client->store.envval = xmalloc(len); +- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); ++#ifdef USE_CCAPI ++ xasprintf(&client->store.envval, "API:%s", new_ccname); ++ client->store.filename = NULL; ++#else ++ if (new_ccname[0] == ':') ++ new_ccname++; ++ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); ++ if (strcmp(new_cctype, "DIR") == 0) { ++ char *p; ++ p = strrchr(client->store.envval, '/'); ++ if (p) ++ *p = '\0'; ++ } ++ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) ++ client->store.filename = xstrdup(new_ccname); ++#endif + + #ifdef USE_PAM + if (options.use_pam) +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + + krb5_cc_close(krb_context, ccache); + ++ client->store.data = krb_context; ++ + return; + } + ++int ++ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ++ ssh_gssapi_client *client) ++{ ++ krb5_ccache ccache = NULL; ++ krb5_principal principal = NULL; ++ char *name = NULL; ++ krb5_error_code problem; ++ OM_uint32 maj_status, min_status; ++ ++ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { ++ logit("krb5_cc_resolve(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ return 0; ++ } ++ ++ /* Find out who the principal in this cache is */ ++ if ((problem = krb5_cc_get_principal(krb_context, ccache, ++ &principal))) { ++ logit("krb5_cc_get_principal(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { ++ logit("krb5_unparse_name(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ ++ if (strcmp(name,client->exportedname.value)!=0) { ++ debug("Name in local credentials cache differs. Not storing"); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ krb5_free_unparsed_name(krb_context, name); ++ return 0; ++ } ++ krb5_free_unparsed_name(krb_context, name); ++ ++ /* Name matches, so lets get on with it! */ ++ ++ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { ++ logit("krb5_cc_initialize(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ krb5_free_principal(krb_context, principal); ++ ++ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ++ ccache))) { ++ logit("gss_krb5_copy_ccache() failed. Sorry!"); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ return 1; ++} ++ + ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", +@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { + NULL, + &ssh_gssapi_krb5_userok, + NULL, +- &ssh_gssapi_krb5_storecreds ++ &ssh_gssapi_krb5_storecreds, ++ &ssh_gssapi_krb5_updatecreds + }; + + #endif /* KRB5 */ +diff --git a/gss-serv.c b/gss-serv.c +index ab3a15f0..6ce56e92 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-serv.c,v 1.31 2018/07/09 21:37:55 markus 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 +@@ -44,17 +44,19 @@ + #include "session.h" + #include "misc.h" + #include "servconf.h" ++#include "uidswap.h" + + #include "ssh-gss.h" ++#include "monitor_wrap.h" + + extern ServerOptions options; + + static ssh_gssapi_client gssapi_client = +- { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, +- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; ++ { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, ++ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; + + ssh_gssapi_mech gssapi_null_mech = +- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; ++ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; + + #ifdef KRB5 + extern ssh_gssapi_mech gssapi_kerberos_mech; +@@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) + return (ssh_gssapi_acquire_cred(*ctx)); + } + ++/* Unprivileged */ ++char * ++ssh_gssapi_server_mechanisms(void) { ++ if (supported_oids == NULL) ++ ssh_gssapi_prepare_supported_oids(); ++ return (ssh_gssapi_kex_mechs(supported_oids, ++ &ssh_gssapi_server_check_mech, NULL, NULL, ++ options.gss_kex_algorithms)); ++} ++ ++/* Unprivileged */ ++int ++ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, ++ const char *dummy) { ++ Gssctxt *ctx = NULL; ++ int res; ++ ++ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); ++ ssh_gssapi_delete_ctx(&ctx); ++ ++ return (res); ++} ++ + /* Unprivileged */ + void + ssh_gssapi_supported_oids(gss_OID_set *oidset) +@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) + gss_OID_set supported; + + gss_create_empty_oid_set(&min_status, oidset); +- gss_indicate_mechs(&min_status, &supported); ++ ++ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) ++ return; + + while (supported_mechs[i]->name != NULL) { + if (GSS_ERROR(gss_test_oid_set_member(&min_status, +@@ -276,8 +303,48 @@ OM_uint32 + ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + { + int i = 0; ++ int equal = 0; ++ gss_name_t new_name = GSS_C_NO_NAME; ++ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; ++ ++ if (options.gss_store_rekey && client->used && ctx->client_creds) { ++ if (client->mech->oid.length != ctx->oid->length || ++ (memcmp(client->mech->oid.elements, ++ ctx->oid->elements, ctx->oid->length) !=0)) { ++ debug("Rekeyed credentials have different mechanism"); ++ return GSS_S_COMPLETE; ++ } ++ ++ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &new_name, ++ NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } + +- gss_buffer_desc ename; ++ ctx->major = gss_compare_name(&ctx->minor, client->name, ++ new_name, &equal); ++ ++ if (GSS_ERROR(ctx->major)) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ ++ if (!equal) { ++ debug("Rekeyed credentials have different name"); ++ return GSS_S_COMPLETE; ++ } ++ ++ debug("Marking rekeyed credentials for export"); ++ ++ gss_release_name(&ctx->minor, &client->name); ++ gss_release_cred(&ctx->minor, &client->creds); ++ client->name = new_name; ++ client->creds = ctx->client_creds; ++ ctx->client_creds = GSS_C_NO_CREDENTIAL; ++ client->updated = 1; ++ return GSS_S_COMPLETE; ++ } + + client->mech = NULL; + +@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + if (client->mech == NULL) + return GSS_S_FAILURE; + ++ if (ctx->client_creds && ++ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, + &client->displayname, NULL))) { + ssh_gssapi_error(ctx); +@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + return (ctx->major); + } + ++ gss_release_buffer(&ctx->minor, &ename); ++ + /* We can't copy this structure, so we just move the pointer to it */ + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; +@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + void + ssh_gssapi_cleanup_creds(void) + { +- if (gssapi_client.store.filename != NULL) { +- /* Unlink probably isn't sufficient */ +- debug("removing gssapi cred file\"%s\"", +- gssapi_client.store.filename); +- unlink(gssapi_client.store.filename); ++ krb5_ccache ccache = NULL; ++ krb5_error_code problem; ++ ++ if (gssapi_client.store.data != NULL) { ++ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { ++ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { ++ debug("%s: krb5_cc_destroy(): %.100s", __func__, ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else { ++ krb5_free_context(gssapi_client.store.data); ++ gssapi_client.store.data = NULL; ++ } + } + } + +@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) + + /* Privileged */ + int +-ssh_gssapi_userok(char *user) ++ssh_gssapi_userok(char *user, struct passwd *pw, int kex) + { + OM_uint32 lmin; + ++ (void) kex; /* used in privilege separation */ ++ + if (gssapi_client.exportedname.length == 0 || + gssapi_client.exportedname.value == NULL) { + debug("No suitable client data"); + return 0; + } + if (gssapi_client.mech && gssapi_client.mech->userok) +- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) ++ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { ++ gssapi_client.used = 1; ++ gssapi_client.store.owner = pw; + return 1; +- else { ++ } else { + /* 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) + return (0); + } + +-/* Privileged */ +-OM_uint32 +-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) ++/* These bits are only used for rekeying. The unpriviledged child is running ++ * as the user, the monitor is root. ++ * ++ * In the child, we want to : ++ * *) Ask the monitor to store our credentials into the store we specify ++ * *) If it succeeds, maybe do a PAM update ++ */ ++ ++/* Stuff for PAM */ ++ ++#ifdef USE_PAM ++static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, ++ struct pam_response **resp, void *data) + { +- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, +- gssbuf, gssmic, NULL); ++ return (PAM_CONV_ERR); ++} ++#endif + +- return (ctx->major); ++void ++ssh_gssapi_rekey_creds(void) { ++ int ok; ++#ifdef USE_PAM ++ int ret; ++ pam_handle_t *pamh = NULL; ++ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; ++ char *envstr; ++#endif ++ ++ if (gssapi_client.store.filename == NULL && ++ gssapi_client.store.envval == NULL && ++ gssapi_client.store.envvar == NULL) ++ return; ++ ++ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); ++ ++ if (!ok) ++ return; ++ ++ debug("Rekeyed credentials stored successfully"); ++ ++ /* Actually managing to play with the ssh pam stack from here will ++ * be next to impossible. In any case, we may want different options ++ * 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) ++ return; ++ ++ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, ++ gssapi_client.store.envval); ++ ++ ret = pam_putenv(pamh, envstr); ++ if (!ret) ++ pam_setcred(pamh, PAM_REINITIALIZE_CRED); ++ pam_end(pamh, PAM_SUCCESS); ++#endif ++} ++ ++int ++ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { ++ int ok = 0; ++ ++ /* Check we've got credentials to store */ ++ if (!gssapi_client.updated) ++ return 0; ++ ++ gssapi_client.updated = 0; ++ ++ temporarily_use_uid(gssapi_client.store.owner); ++ if (gssapi_client.mech && gssapi_client.mech->updatecreds) ++ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); ++ else ++ debug("No update function for this mechanism"); ++ ++ restore_uid(); ++ ++ return ok; + } + + /* Privileged */ +diff --git a/hmac.c b/hmac.c +index 1c879640..a29f32c5 100644 +--- a/hmac.c ++++ b/hmac.c +@@ -19,6 +19,7 @@ + + #include + #include ++#include + + #include "sshbuf.h" + #include "digest.h" +diff --git a/kex.c b/kex.c +index 34808b5c..a2a4794e 100644 +--- a/kex.c ++++ b/kex.c +@@ -55,11 +55,16 @@ + #include "misc.h" + #include "dispatch.h" + #include "monitor.h" ++#include "xmalloc.h" + + #include "ssherr.h" + #include "sshbuf.h" + #include "digest.h" + ++#ifdef GSSAPI ++#include "ssh-gss.h" ++#endif ++ + /* prototype */ + static int kex_choose_conf(struct ssh *); + static int kex_input_newkeys(int, u_int32_t, struct ssh *); +@@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, -1, -1, -1}, + }; ++static const struct kexalg gss_kexalgs[] = { ++#ifdef GSSAPI ++ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, ++#endif ++ { NULL, -1, -1, -1 }, ++}; + +-char * +-kex_alg_list(char sep) ++static char * ++kex_alg_list_internal(char sep, const struct kexalg *algs) + { + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = algs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -136,6 +154,18 @@ kex_alg_list(char sep) + return ret; + } + ++char * ++kex_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, kexalgs); ++} ++ ++char * ++kex_gss_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, gss_kexalgs); ++} ++ + static const struct kexalg * + kex_alg_by_name(const char *name) + { +@@ -145,6 +175,10 @@ kex_alg_by_name(const char *name) + if (strcmp(k->name, name) == 0) + return k; + } ++ for (k = gss_kexalgs; k->name != NULL; k++) { ++ if (strncmp(k->name, name, strlen(k->name)) == 0) ++ return k; ++ } + return NULL; + } + +@@ -301,6 +335,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) + return r; + } + ++/* Validate GSS KEX method name list */ ++int ++kex_gss_names_valid(const char *names) ++{ ++ char *s, *cp, *p; ++ ++ if (names == NULL || *names == '\0') ++ return 0; ++ s = cp = xstrdup(names); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (strncmp(p, "gss-", 4) != 0 ++ || kex_alg_by_name(p) == NULL) { ++ error("Unsupported KEX algorithm \"%.100s\"", p); ++ free(s); ++ return 0; ++ } ++ } ++ debug3("gss kex names ok: [%s]", names); ++ free(s); ++ return 1; ++} ++ + /* put algorithm proposal into buffer */ + int + kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) +@@ -657,6 +714,9 @@ kex_free(struct kex *kex) + sshbuf_free(kex->server_version); + sshbuf_free(kex->client_pub); + free(kex->session_id); ++#ifdef GSSAPI ++ free(kex->gss_host); ++#endif /* GSSAPI */ + free(kex->failed_choice); + free(kex->hostkey_alg); + free(kex->name); +diff --git a/kex.h b/kex.h +index 6d446d1c..f95dc02c 100644 +--- a/kex.h ++++ b/kex.h +@@ -103,6 +103,15 @@ enum kex_exchange { + KEX_ECDH_SHA2, + KEX_C25519_SHA256, + KEX_KEM_SNTRUP4591761X25519_SHA512, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GRP14_SHA256, ++ KEX_GSS_GRP16_SHA512, ++ KEX_GSS_GEX_SHA1, ++ KEX_GSS_NISTP256_SHA256, ++ KEX_GSS_C25519_SHA256, ++#endif + KEX_MAX + }; + +@@ -154,6 +163,12 @@ struct kex { + u_int flags; + int hash_alg; + int ec_nid; ++#ifdef GSSAPI ++ int gss_deleg_creds; ++ int gss_trust_dns; ++ char *gss_host; ++ char *gss_client; ++#endif + char *failed_choice; + int (*verify_host_key)(struct sshkey *, struct ssh *); + struct sshkey *(*load_host_public_key)(int, int, struct ssh *); +@@ -175,8 +190,10 @@ struct kex { + + 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_gss_names_valid(const char *); + + int kex_exchange_identification(struct ssh *, int, const char *); + +@@ -203,6 +220,12 @@ int kexgex_client(struct ssh *); + int kexgex_server(struct ssh *); + int kex_gen_client(struct ssh *); + int kex_gen_server(struct ssh *); ++#ifdef GSSAPI ++int kexgssgex_client(struct ssh *); ++int kexgssgex_server(struct ssh *); ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); ++#endif + + int kex_dh_keypair(struct kex *); + int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, +@@ -235,6 +258,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, + const BIGNUM *, const u_char *, size_t, + u_char *, size_t *); + ++int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, ++ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, ++ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, ++ const struct sshbuf *client_pub, const struct sshbuf *server_pub, ++ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); ++ + void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); +diff --git a/kexdh.c b/kexdh.c +index 67133e33..edaa4676 100644 +--- a/kexdh.c ++++ b/kexdh.c +@@ -48,13 +48,23 @@ kex_dh_keygen(struct kex *kex) + { + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: ++#ifdef GSSAPI ++ case KEX_GSS_GRP1_SHA1: ++#endif + kex->dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + case KEX_DH_GRP14_SHA256: ++#ifdef GSSAPI ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++#endif + kex->dh = dh_new_group14(); + break; + case KEX_DH_GRP16_SHA512: ++#ifdef GSSAPI ++ case KEX_GSS_GRP16_SHA512: ++#endif + kex->dh = dh_new_group16(); + break; + case KEX_DH_GRP18_SHA512: +diff --git a/kexgen.c b/kexgen.c +index 2abbb9ef..569dc83f 100644 +--- a/kexgen.c ++++ b/kexgen.c +@@ -43,7 +43,7 @@ + static int input_kex_gen_init(int, u_int32_t, struct ssh *); + static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); + +-static int ++int + kex_gen_hash( + int hash_alg, + const struct sshbuf *client_version, +diff --git a/kexgssc.c b/kexgssc.c +new file mode 100644 +index 00000000..0b2f6a56 +--- /dev/null ++++ b/kexgssc.c +@@ -0,0 +1,595 @@ ++/* ++ * 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 ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "includes.h" ++ ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ ++#include "includes.h" ++ ++#include ++#include ++ ++#include ++ ++#include "xmalloc.h" ++#include "sshbuf.h" ++#include "ssh2.h" ++#include "sshkey.h" ++#include "cipher.h" ++#include "kex.h" ++#include "log.h" ++#include "packet.h" ++#include "dh.h" ++#include "digest.h" ++#include "ssherr.h" ++ ++#include "ssh-gss.h" ++ ++int ++kexgss_client(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, ++ recv_tok = GSS_C_EMPTY_BUFFER, ++ gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; ++ Gssctxt *ctxt; ++ OM_uint32 maj_status, min_status, ret_flags; ++ struct sshbuf *server_blob = NULL; ++ struct sshbuf *shared_secret = NULL; ++ struct sshbuf *server_host_key_blob = NULL; ++ struct sshbuf *empty = sshbuf_new(); ++ u_char *msg; ++ int type = 0; ++ int first = 1; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ u_char c; ++ int r; ++ ++ /* Initialise our GSSAPI world */ ++ ssh_gssapi_build_ctx(&ctxt); ++ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) ++ == GSS_C_NO_OID) ++ fatal("Couldn't identify host exchange"); ++ ++ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ fatal("Couldn't import hostname"); ++ ++ if (kex->gss_client && ++ ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ fatal("Couldn't acquire client credentials"); ++ ++ /* Step 1 */ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_keypair(kex); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ r = kex_ecdh_keypair(kex); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ r = kex_c25519_keypair(kex); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ if (r != 0) ++ return r; ++ ++ token_ptr = GSS_C_NO_BUFFER; ++ ++ do { ++ debug("Calling gss_init_sec_context"); ++ ++ maj_status = ssh_gssapi_init_ctx(ctxt, ++ kex->gss_deleg_creds, token_ptr, &send_tok, ++ &ret_flags); ++ ++ if (GSS_ERROR(maj_status)) { ++ /* XXX Useles code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, ++ SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, ++ send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&min_status, &recv_tok); ++ ++ if (maj_status == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (first) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, ++ send_tok.length)) != 0 || ++ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, ++ send_tok.length)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("failed to send packet: %s", ssh_err(r)); ++ gss_release_buffer(&min_status, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ do { ++ type = ssh_packet_read(ssh); ++ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ 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) ++ fatal("Failed to read server host key: %s", ssh_err(r)); ++ } ++ } while (type == SSH2_MSG_KEXGSS_HOSTKEY); ++ ++ switch (type) { ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ debug("Received GSSAPI_CONTINUE"); ++ if (maj_status == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ break; ++ case SSH2_MSG_KEXGSS_COMPLETE: ++ debug("Received GSSAPI_COMPLETE"); ++ if (msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &msg_tok)) != 0) ++ fatal("Failed to read message: %s", ssh_err(r)); ++ ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc( ++ ssh, &recv_tok)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (maj_status == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ /* No token included */ ++ if (maj_status != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); ++ } ++ if ((r = sshpkt_get_end(ssh)) != 0) { ++ fatal("Expecting end of packet."); ++ } ++ break; ++ case SSH2_MSG_KEXGSS_ERROR: ++ debug("Received Error"); ++ if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || ++ (r = sshpkt_get_u32(ssh, &min_status)) != 0 || ++ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || ++ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt_get failed: %s", ssh_err(r)); ++ fatal("GSSAPI Error: \n%.400s", msg); ++ default: ++ sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", ++ type); ++ } ++ token_ptr = &recv_tok; ++ } else { ++ /* No data, and not complete */ ++ if (maj_status != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ /* ++ * We _must_ have received a COMPLETE message in reply from the ++ * server, which will have set server_blob and msg_tok ++ */ ++ ++ if (type != SSH2_MSG_KEXGSS_COMPLETE) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ ++ /* compute shared secret */ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_dec(kex, server_blob, &shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80) ++ fatal("The received key has MSB of last octet set!"); ++ r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ if (sshbuf_len(server_blob) != 65) ++ fatal("The received NIST-P256 key did not match" ++ "expected length (expected 65, got %zu)", sshbuf_len(server_blob)); ++ ++ if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) ++ fatal("The received NIST-P256 key does not have first octet 0x04"); ++ ++ r = kex_ecdh_dec(kex, server_blob, &shared_secret); ++ break; ++ default: ++ r = SSH_ERR_INVALID_ARGUMENT; ++ break; ++ } ++ if (r != 0) ++ goto out; ++ ++ hashlen = sizeof(hash); ++ if ((r = kex_gen_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->my, ++ kex->peer, ++ (server_host_key_blob ? server_host_key_blob : empty), ++ kex->client_pub, ++ server_blob, ++ shared_secret, ++ hash, &hashlen)) != 0) ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ /* Verify that the hash matches the MIC we just got. */ ++ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); ++ ++ gss_release_buffer(&min_status, &msg_tok); ++ ++ if (kex->gss_deleg_creds) ++ ssh_gssapi_credentials_updated(ctxt); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++ ++out: ++ explicit_bzero(hash, sizeof(hash)); ++ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); ++ sshbuf_free(empty); ++ sshbuf_free(server_host_key_blob); ++ sshbuf_free(server_blob); ++ sshbuf_free(shared_secret); ++ sshbuf_free(kex->client_pub); ++ kex->client_pub = NULL; ++ return r; ++} ++ ++int ++kexgssgex_client(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, ++ recv_tok = GSS_C_EMPTY_BUFFER, gssbuf, ++ msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; ++ Gssctxt *ctxt; ++ OM_uint32 maj_status, min_status, ret_flags; ++ struct sshbuf *shared_secret = NULL; ++ BIGNUM *p = NULL; ++ BIGNUM *g = NULL; ++ struct sshbuf *buf = NULL; ++ struct sshbuf *server_host_key_blob = NULL; ++ struct sshbuf *server_blob = NULL; ++ BIGNUM *dh_server_pub = NULL; ++ u_char *msg; ++ int type = 0; ++ int first = 1; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; ++ struct sshbuf *empty = sshbuf_new(); ++ u_char c; ++ int r; ++ ++ /* Initialise our GSSAPI world */ ++ ssh_gssapi_build_ctx(&ctxt); ++ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) ++ == GSS_C_NO_OID) ++ fatal("Couldn't identify host exchange"); ++ ++ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ fatal("Couldn't import hostname"); ++ ++ if (kex->gss_client && ++ ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ fatal("Couldn't acquire client credentials"); ++ ++ debug("Doing group exchange"); ++ nbits = dh_estimate(kex->dh_need * 8); ++ ++ kex->min = DH_GRP_MIN; ++ kex->max = DH_GRP_MAX; ++ kex->nbits = nbits; ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || ++ (r = sshpkt_put_u32(ssh, min)) != 0 || ++ (r = sshpkt_put_u32(ssh, nbits)) != 0 || ++ (r = sshpkt_put_u32(ssh, max)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("Failed to construct a packet: %s", ssh_err(r)); ++ ++ if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0) ++ fatal("Error: %s", ssh_err(r)); ++ ++ if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || ++ (r = sshpkt_get_bignum2(ssh, &g)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); ++ ++ if (BN_num_bits(p) < min || BN_num_bits(p) > max) ++ fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", ++ min, BN_num_bits(p), max); ++ ++ if ((kex->dh = dh_new_group(g, p)) == NULL) ++ fatal("dn_new_group() failed"); ++ p = g = NULL; /* belong to kex->dh now */ ++ ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) ++ goto out; ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ ++ token_ptr = GSS_C_NO_BUFFER; ++ ++ do { ++ /* Step 2 - call GSS_Init_sec_context() */ ++ debug("Calling gss_init_sec_context"); ++ ++ maj_status = ssh_gssapi_init_ctx(ctxt, ++ kex->gss_deleg_creds, token_ptr, &send_tok, ++ &ret_flags); ++ ++ if (GSS_ERROR(maj_status)) { ++ /* XXX Useles code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, ++ SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, ++ send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&min_status, &recv_tok); ++ ++ if (maj_status == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (first) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, ++ send_tok.length)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh,send_tok.value, ++ send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt_send failed: %s", ssh_err(r)); ++ gss_release_buffer(&min_status, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ do { ++ type = ssh_packet_read(ssh); ++ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ 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) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ } while (type == SSH2_MSG_KEXGSS_HOSTKEY); ++ ++ switch (type) { ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ debug("Received GSSAPI_CONTINUE"); ++ if (maj_status == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ break; ++ case SSH2_MSG_KEXGSS_COMPLETE: ++ debug("Received GSSAPI_COMPLETE"); ++ if (msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &msg_tok)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc( ++ ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (maj_status == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ /* No token included */ ++ if (maj_status != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); ++ } ++ break; ++ case SSH2_MSG_KEXGSS_ERROR: ++ debug("Received Error"); ++ if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || ++ (r = sshpkt_get_u32(ssh, &min_status)) != 0 || ++ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || ++ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ fatal("GSSAPI Error: \n%.400s", msg); ++ default: ++ sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", ++ type); ++ } ++ token_ptr = &recv_tok; ++ } else { ++ /* No data, and not complete */ ++ if (maj_status != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ /* ++ * We _must_ have received a COMPLETE message in reply from the ++ * server, which will have set dh_server_pub and msg_tok ++ */ ++ ++ if (type != SSH2_MSG_KEXGSS_COMPLETE) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ ++ /* 7. C verifies that the key Q_S is valid */ ++ /* 8. C computes shared secret */ ++ if ((buf = sshbuf_new()) == NULL || ++ (r = sshbuf_put_stringb(buf, server_blob)) != 0 || ++ (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) ++ goto out; ++ sshbuf_free(buf); ++ ++ if ((shared_secret = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) ++ goto out; ++ ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ hashlen = sizeof(hash); ++ if ((r = kexgex_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->my, ++ kex->peer, ++ (server_host_key_blob ? server_host_key_blob : empty), ++ kex->min, kex->nbits, kex->max, ++ dh_p, dh_g, ++ pub_key, ++ dh_server_pub, ++ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), ++ hash, &hashlen)) != 0) ++ fatal("Failed to calculate hash: %s", ssh_err(r)); ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ /* Verify that the hash matches the MIC we just got. */ ++ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); ++ ++ gss_release_buffer(&min_status, &msg_tok); ++ ++ /* save session id */ ++ if (kex->session_id == NULL) { ++ kex->session_id_len = hashlen; ++ kex->session_id = xmalloc(kex->session_id_len); ++ memcpy(kex->session_id, hash, kex->session_id_len); ++ } ++ ++ if (kex->gss_deleg_creds) ++ ssh_gssapi_credentials_updated(ctxt); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ /* Finally derive the keys and send them */ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++out: ++ sshbuf_free(server_blob); ++ sshbuf_free(empty); ++ explicit_bzero(hash, sizeof(hash)); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ BN_clear_free(dh_server_pub); ++ sshbuf_free(shared_secret); ++ sshbuf_free(server_host_key_blob); ++ return r; ++} ++#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ +diff --git a/kexgsss.c b/kexgsss.c +new file mode 100644 +index 00000000..60bc02de +--- /dev/null ++++ b/kexgsss.c +@@ -0,0 +1,474 @@ ++/* ++ * 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 ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "includes.h" ++ ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ ++#include ++ ++#include ++#include ++ ++#include "xmalloc.h" ++#include "sshbuf.h" ++#include "ssh2.h" ++#include "sshkey.h" ++#include "cipher.h" ++#include "kex.h" ++#include "log.h" ++#include "packet.h" ++#include "dh.h" ++#include "ssh-gss.h" ++#include "monitor_wrap.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ ++#include "servconf.h" ++#include "ssh-gss.h" ++#include "digest.h" ++#include "ssherr.h" ++ ++extern ServerOptions options; ++ ++int ++kexgss_server(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ OM_uint32 maj_status, min_status; ++ ++ /* ++ * Some GSSAPI implementations use the input value of ret_flags (an ++ * output variable) as a means of triggering mechanism specific ++ * features. Initializing it to zero avoids inadvertently ++ * activating this non-standard behaviour. ++ */ ++ ++ OM_uint32 ret_flags = 0; ++ gss_buffer_desc gssbuf, recv_tok, msg_tok; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ Gssctxt *ctxt = NULL; ++ struct sshbuf *shared_secret = NULL; ++ struct sshbuf *client_pubkey = NULL; ++ struct sshbuf *server_pubkey = NULL; ++ struct sshbuf *empty = sshbuf_new(); ++ int type = 0; ++ gss_OID oid; ++ char *mechs; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ int r; ++ ++ /* Initialise GSSAPI */ ++ ++ /* If we're rekeying, privsep means that some of the private structures ++ * in the GSSAPI code are no longer available. This kludges them back ++ * into life ++ */ ++ if (!ssh_gssapi_oid_table_ok()) { ++ mechs = ssh_gssapi_server_mechanisms(); ++ free(mechs); ++ } ++ ++ debug2("%s: Identifying %s", __func__, kex->name); ++ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); ++ if (oid == GSS_C_NO_OID) ++ fatal("Unknown gssapi mechanism"); ++ ++ debug2("%s: Acquiring credentials", __func__); ++ ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ fatal("Unable to acquire credentials for the server"); ++ ++ do { ++ debug("Wait SSH2_MSG_KEXGSS_INIT"); ++ type = ssh_packet_read(ssh); ++ switch(type) { ++ case SSH2_MSG_KEXGSS_INIT: ++ if (client_pubkey != NULL) ++ fatal("Received KEXGSS_INIT after initialising"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_enc(kex, client_pubkey, &server_pubkey, ++ &shared_secret); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, ++ &shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, ++ &shared_secret); ++ break; ++ default: ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ } ++ if (r != 0) ++ goto out; ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ break; ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ break; ++ default: ++ sshpkt_disconnect(ssh, ++ "Protocol error: didn't expect packet type %d", ++ type); ++ } ++ ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags)); ++ ++ gss_release_buffer(&min_status, &recv_tok); ++ ++ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) ++ fatal("Zero length token output when incomplete"); ++ ++ if (client_pubkey == NULL) ++ fatal("No client public key"); ++ ++ if (maj_status & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&min_status, &send_tok); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ if (GSS_ERROR(maj_status)) { ++ if (send_tok.length > 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("accept_ctx died"); ++ } ++ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual Authentication flag wasn't set"); ++ ++ 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"); ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || ++ (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || ++ (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } else { ++ if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt_send failed: %s", ssh_err(r)); ++ ++ gss_release_buffer(&min_status, &send_tok); ++ gss_release_buffer(&min_status, &msg_tok); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++ ++ /* If this was a rekey, then save out any delegated credentials we ++ * just exchanged. */ ++ if (options.gss_store_rekey) ++ ssh_gssapi_rekey_creds(); ++out: ++ sshbuf_free(empty); ++ explicit_bzero(hash, sizeof(hash)); ++ sshbuf_free(shared_secret); ++ sshbuf_free(client_pubkey); ++ sshbuf_free(server_pubkey); ++ return r; ++} ++ ++int ++kexgssgex_server(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ OM_uint32 maj_status, min_status; ++ ++ /* ++ * Some GSSAPI implementations use the input value of ret_flags (an ++ * output variable) as a means of triggering mechanism specific ++ * features. Initializing it to zero avoids inadvertently ++ * activating this non-standard behaviour. ++ */ ++ ++ OM_uint32 ret_flags = 0; ++ gss_buffer_desc gssbuf, recv_tok, msg_tok; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ Gssctxt *ctxt = NULL; ++ struct sshbuf *shared_secret = NULL; ++ int type = 0; ++ gss_OID oid; ++ char *mechs; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ BIGNUM *dh_client_pub = NULL; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ int min = -1, max = -1, nbits = -1; ++ int cmin = -1, cmax = -1; /* client proposal */ ++ struct sshbuf *empty = sshbuf_new(); ++ int r; ++ ++ /* Initialise GSSAPI */ ++ ++ /* If we're rekeying, privsep means that some of the private structures ++ * in the GSSAPI code are no longer available. This kludges them back ++ * into life ++ */ ++ if (!ssh_gssapi_oid_table_ok()) ++ if ((mechs = ssh_gssapi_server_mechanisms())) ++ free(mechs); ++ ++ debug2("%s: Identifying %s", __func__, kex->name); ++ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); ++ if (oid == GSS_C_NO_OID) ++ fatal("Unknown gssapi mechanism"); ++ ++ debug2("%s: Acquiring credentials", __func__); ++ ++ if (GSS_ERROR(PRIVSEP(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) */ ++ debug("Doing group exchange"); ++ ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ); ++ /* store client proposal to provide valid signature */ ++ if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || ++ (r = sshpkt_get_u32(ssh, &nbits)) != 0 || ++ (r = sshpkt_get_u32(ssh, &cmax)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ kex->nbits = nbits; ++ kex->min = cmin; ++ kex->max = cmax; ++ min = MAX(DH_GRP_MIN, cmin); ++ max = MIN(DH_GRP_MAX, cmax); ++ nbits = MAXIMUM(DH_GRP_MIN, nbits); ++ nbits = MINIMUM(DH_GRP_MAX, nbits); ++ 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)); ++ if (kex->dh == NULL) { ++ sshpkt_disconnect(ssh, "Protocol error: no matching group found"); ++ fatal("Protocol error: no matching group found"); ++ } ++ ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ if ((r = ssh_packet_write_wait(ssh)) != 0) ++ fatal("ssh_packet_write_wait: %s", ssh_err(r)); ++ ++ /* Compute our exchange value in parallel with the client */ ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) ++ goto out; ++ ++ do { ++ debug("Wait SSH2_MSG_GSSAPI_INIT"); ++ type = ssh_packet_read(ssh); ++ switch(type) { ++ case SSH2_MSG_KEXGSS_INIT: ++ if (dh_client_pub != NULL) ++ fatal("Received KEXGSS_INIT after initialising"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ break; ++ case SSH2_MSG_KEXGSS_CONTINUE: ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, ++ &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ break; ++ default: ++ sshpkt_disconnect(ssh, ++ "Protocol error: didn't expect packet type %d", ++ type); ++ } ++ ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags)); ++ ++ gss_release_buffer(&min_status, &recv_tok); ++ ++ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) ++ fatal("Zero length token output when incomplete"); ++ ++ if (dh_client_pub == NULL) ++ fatal("No client public key"); ++ ++ if (maj_status & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&min_status, &send_tok); ++ } ++ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ++ if (GSS_ERROR(maj_status)) { ++ if (send_tok.length > 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("accept_ctx died"); ++ } ++ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual Authentication flag wasn't set"); ++ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity flag wasn't set"); ++ ++ /* calculate shared secret */ ++ if ((shared_secret = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) ++ goto out; ++ ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ hashlen = sizeof(hash); ++ if ((r = kexgex_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->peer, ++ kex->my, ++ empty, ++ cmin, nbits, cmax, ++ dh_p, dh_g, ++ dh_client_pub, ++ pub_key, ++ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), ++ hash, &hashlen)) != 0) ++ fatal("kexgex_hash failed: %s", ssh_err(r)); ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) ++ fatal("Couldn't get MIC"); ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || ++ (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } else { ++ if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ gss_release_buffer(&min_status, &send_tok); ++ gss_release_buffer(&min_status, &msg_tok); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = ctxt; ++ else ++ ssh_gssapi_delete_ctx(&ctxt); ++ ++ /* Finally derive the keys and send them */ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++ ++ /* If this was a rekey, then save out any delegated credentials we ++ * just exchanged. */ ++ if (options.gss_store_rekey) ++ ssh_gssapi_rekey_creds(); ++out: ++ sshbuf_free(empty); ++ explicit_bzero(hash, sizeof(hash)); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ BN_clear_free(dh_client_pub); ++ sshbuf_free(shared_secret); ++ return r; ++} ++#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ +diff --git a/mac.c b/mac.c +index 51dc11d7..3d11eba6 100644 +--- a/mac.c ++++ b/mac.c +@@ -29,6 +29,7 @@ + + #include + #include ++#include + + #include "digest.h" + #include "hmac.h" +diff --git a/monitor.c b/monitor.c +index 60e52944..669cdb4a 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_sign(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_updatecreds(struct ssh*, int, struct sshbuf *); + #endif + + #ifdef SSH_AUDIT_EVENTS +@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] = { + {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, + {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, ++ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, + #endif + {0, 0, NULL} + }; + + struct mon_table mon_dispatch_postauth20[] = { ++#ifdef GSSAPI ++ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, ++ {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, ++ {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, ++ {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, ++#endif + #ifdef WITH_OPENSSL + {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, + #endif +@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) + /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); ++#ifdef GSSAPI ++ /* and for the GSSAPI key exchange */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++#endif + + /* The first few requests do not require asynchronous access */ + while (!authenticated) { +@@ -405,6 +418,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); ++#ifdef GSSAPI ++ /* and for the GSSAPI key exchange */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); ++#endif + + if (auth_opts->permit_pty_flag) { + monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); +@@ -1687,6 +1704,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) + # ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + # endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } ++# endif + #endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; +@@ -1780,8 +1808,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) + u_char *p; + int r; + +- if (!options.gss_authentication) +- fatal("%s: GSSAPI authentication not enabled", __func__); ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); + + if ((r = sshbuf_get_string(m, &p, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); +@@ -1813,8 +1841,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) + OM_uint32 flags = 0; /* GSI needs this */ + int r; + +- if (!options.gss_authentication) +- fatal("%s: GSSAPI authentication not enabled", __func__); ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); + + if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); +@@ -1834,6 +1862,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); + } + return (0); + } +@@ -1845,8 +1874,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) + OM_uint32 ret; + int r; + +- if (!options.gss_authentication) +- fatal("%s: GSSAPI authentication not enabled", __func__); ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); + + if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || + (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) +@@ -1872,13 +1901,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) + int + mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) + { +- int r, authenticated; ++ int r, authenticated, kex; + const char *displayname; + +- if (!options.gss_authentication) +- fatal("%s: GSSAPI authentication not enabled", __func__); ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); + +- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); ++ if ((r = sshbuf_get_u32(m, &kex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ authenticated = authctxt->valid && ++ ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); + + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, authenticated)) != 0) +@@ -1887,7 +1920,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); + +- auth_method = "gssapi-with-mic"; ++ if (kex) { ++ auth_method = "gssapi-keyex"; ++ } else { ++ auth_method = "gssapi-with-mic"; ++ } + + if ((displayname = ssh_gssapi_displayname()) != NULL) + auth2_record_info(authctxt, "%s", displayname); +@@ -1895,5 +1932,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) + /* Monitor loop will terminate if authenticated */ + return (authenticated); + } ++ ++int ++mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) ++{ ++ gss_buffer_desc data; ++ gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; ++ OM_uint32 major, minor; ++ size_t len; ++ u_char *p = NULL; ++ int r; ++ ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); ++ ++ if ((r = sshbuf_get_string(m, &p, &len)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ data.value = p; ++ data.length = len; ++ /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ ++ if (data.length != 20 && data.length != 32 && data.length != 64) ++ fatal("%s: data length incorrect: %d", __func__, ++ (int) data.length); ++ ++ /* Save the session ID on the first time around */ ++ if (session_id2_len == 0) { ++ session_id2_len = data.length; ++ session_id2 = xmalloc(session_id2_len); ++ memcpy(session_id2, data.value, session_id2_len); ++ } ++ major = ssh_gssapi_sign(gsscontext, &data, &hash); ++ ++ free(data.value); ++ ++ sshbuf_reset(m); ++ ++ if ((r = sshbuf_put_u32(m, major)) != 0 || ++ (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); ++ ++ gss_release_buffer(&minor, &hash); ++ ++ /* Turn on getpwnam permissions */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); ++ ++ /* And credential updating, for when rekeying */ ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); ++ ++ return (0); ++} ++ ++int ++mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { ++ ssh_gssapi_ccache store; ++ int r, ok; ++ ++ if (!options.gss_authentication && !options.gss_keyex) ++ fatal("%s: GSSAPI not enabled", __func__); ++ ++ if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || ++ (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || ++ (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ ok = ssh_gssapi_update_creds(&store); ++ ++ free(store.filename); ++ free(store.envvar); ++ free(store.envval); ++ ++ sshbuf_reset(m); ++ if ((r = sshbuf_put_u32(m, ok)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); ++ ++ return(0); ++} ++ + #endif /* GSSAPI */ + +diff --git a/monitor.h b/monitor.h +index 683e5e07..2b1a2d59 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -63,6 +63,8 @@ enum monitor_reqtype { + MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, + MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, + ++ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, ++ MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, + }; + + struct ssh; +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 186e8f02..8e4c1c1f 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -978,13 +978,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) + } + + int +-mm_ssh_gssapi_userok(char *user) ++mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex) + { + struct sshbuf *m; + int r, authenticated = 0; + + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_u32(m, kex)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); + mm_request_receive_expect(pmonitor->m_recvfd, +@@ -997,4 +999,57 @@ mm_ssh_gssapi_userok(char *user) + debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); + return (authenticated); + } ++ ++OM_uint32 ++mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) ++{ ++ struct sshbuf *m; ++ OM_uint32 major; ++ int r; ++ ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); ++ ++ if ((r = sshbuf_get_u32(m, &major)) != 0 || ++ (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ sshbuf_free(m); ++ ++ return (major); ++} ++ ++int ++mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) ++{ ++ struct sshbuf *m; ++ int r, ok; ++ ++ if ((m = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ if ((r = sshbuf_put_cstring(m, ++ store->filename ? store->filename : "")) != 0 || ++ (r = sshbuf_put_cstring(m, ++ store->envvar ? store->envvar : "")) != 0 || ++ (r = sshbuf_put_cstring(m, ++ store->envval ? store->envval : "")) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); ++ ++ if ((r = sshbuf_get_u32(m, &ok)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ ++ sshbuf_free(m); ++ ++ return (ok); ++} ++ + #endif /* GSSAPI */ +diff --git a/monitor_wrap.h b/monitor_wrap.h +index fdebb3aa..69164a8c 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -61,8 +61,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, + OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); + OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); +-int mm_ssh_gssapi_userok(char *user); ++int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); + OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); ++OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); ++int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); + #endif + + #ifdef USE_PAM +diff --git a/readconf.c b/readconf.c +index ec497e79..4d699e5f 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -67,6 +67,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + /* Format of the configuration file: + +@@ -162,6 +163,8 @@ typedef enum { + oClearAllForwardings, oNoHostAuthenticationForLocalhost, + oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, + oAddressFamily, oGssAuthentication, oGssDelegateCreds, ++ oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, ++ oGssServerIdentity, oGssKexAlgorithms, + oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, + oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, + oHashKnownHosts, +@@ -202,10 +205,22 @@ static struct { + /* Sometimes-unsupported options */ + #if defined(GSSAPI) + { "gssapiauthentication", oGssAuthentication }, ++ { "gssapikeyexchange", oGssKeyEx }, + { "gssapidelegatecredentials", oGssDelegateCreds }, ++ { "gssapitrustdns", oGssTrustDns }, ++ { "gssapiclientidentity", oGssClientIdentity }, ++ { "gssapiserveridentity", oGssServerIdentity }, ++ { "gssapirenewalforcesrekey", oGssRenewalRekey }, ++ { "gssapikexalgorithms", oGssKexAlgorithms }, + # else + { "gssapiauthentication", oUnsupported }, ++ { "gssapikeyexchange", oUnsupported }, + { "gssapidelegatecredentials", oUnsupported }, ++ { "gssapitrustdns", oUnsupported }, ++ { "gssapiclientidentity", oUnsupported }, ++ { "gssapiserveridentity", oUnsupported }, ++ { "gssapirenewalforcesrekey", oUnsupported }, ++ { "gssapikexalgorithms", oUnsupported }, + #endif + #ifdef ENABLE_PKCS11 + { "pkcs11provider", oPKCS11Provider }, +@@ -983,10 +998,42 @@ parse_time: + intptr = &options->gss_authentication; + goto parse_flag; + ++ case oGssKeyEx: ++ intptr = &options->gss_keyex; ++ goto parse_flag; ++ + case oGssDelegateCreds: + intptr = &options->gss_deleg_creds; + goto parse_flag; + ++ case oGssTrustDns: ++ intptr = &options->gss_trust_dns; ++ goto parse_flag; ++ ++ case oGssClientIdentity: ++ charptr = &options->gss_client_identity; ++ goto parse_string; ++ ++ case oGssServerIdentity: ++ charptr = &options->gss_server_identity; ++ goto parse_string; ++ ++ case oGssRenewalRekey: ++ intptr = &options->gss_renewal_rekey; ++ goto parse_flag; ++ ++ case oGssKexAlgorithms: ++ arg = strdelim(&s); ++ if (!arg || *arg == '\0') ++ fatal("%.200s line %d: Missing argument.", ++ filename, linenum); ++ if (!kex_gss_names_valid(arg)) ++ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", ++ filename, linenum, arg ? arg : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; +@@ -1854,7 +1901,13 @@ initialize_options(Options * options) + options->pubkey_authentication = -1; + options->challenge_response_authentication = -1; + options->gss_authentication = -1; ++ options->gss_keyex = -1; + options->gss_deleg_creds = -1; ++ options->gss_trust_dns = -1; ++ options->gss_renewal_rekey = -1; ++ options->gss_client_identity = NULL; ++ options->gss_server_identity = NULL; ++ options->gss_kex_algorithms = NULL; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->kbd_interactive_devices = NULL; +@@ -2000,8 +2053,18 @@ fill_default_options(Options * options) + options->challenge_response_authentication = 1; + if (options->gss_authentication == -1) + options->gss_authentication = 0; ++ if (options->gss_keyex == -1) ++ options->gss_keyex = 0; + if (options->gss_deleg_creds == -1) + options->gss_deleg_creds = 0; ++ if (options->gss_trust_dns == -1) ++ options->gss_trust_dns = 0; ++ if (options->gss_renewal_rekey == -1) ++ options->gss_renewal_rekey = 0; ++#ifdef GSSAPI ++ if (options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); ++#endif + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) +@@ -2616,7 +2679,14 @@ dump_client_config(Options *o, const char *host) + dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); + #ifdef GSSAPI + dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); ++ dump_cfg_fmtint(oGssKeyEx, o->gss_keyex); + dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); ++ dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns); ++ dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); ++ dump_cfg_string(oGssClientIdentity, o->gss_client_identity); ++ dump_cfg_string(oGssServerIdentity, o->gss_server_identity); ++ dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ? ++ o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX); + #endif /* GSSAPI */ + dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); + dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); +diff --git a/readconf.h b/readconf.h +index 8e36bf32..0bff6d80 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -40,7 +40,13 @@ typedef struct { + int challenge_response_authentication; + /* Try S/Key or TIS, authentication. */ + int gss_authentication; /* Try GSS authentication */ ++ int gss_keyex; /* Try GSS key exchange */ + int gss_deleg_creds; /* Delegate GSS credentials */ ++ int gss_trust_dns; /* Trust DNS for GSS canonicalization */ ++ int gss_renewal_rekey; /* Credential renewal forces rekey */ ++ char *gss_client_identity; /* Principal to initiate GSSAPI with */ ++ char *gss_server_identity; /* GSSAPI target principal */ ++ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ + int password_authentication; /* Try password + * authentication. */ + int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ +diff --git a/servconf.c b/servconf.c +index ffac5d2c..ffdad31e 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -64,6 +64,7 @@ + #include "auth.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + static void add_listen_addr(ServerOptions *, const char *, + const char *, int); +@@ -124,8 +125,11 @@ initialize_server_options(ServerOptions *options) + options->kerberos_ticket_cleanup = -1; + options->kerberos_get_afs_token = -1; + options->gss_authentication=-1; ++ options->gss_keyex = -1; + options->gss_cleanup_creds = -1; + options->gss_strict_acceptor = -1; ++ options->gss_store_rekey = -1; ++ options->gss_kex_algorithms = NULL; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; +@@ -351,10 +355,18 @@ fill_default_server_options(ServerOptions *options) + options->kerberos_get_afs_token = 0; + if (options->gss_authentication == -1) + options->gss_authentication = 0; ++ if (options->gss_keyex == -1) ++ options->gss_keyex = 0; + if (options->gss_cleanup_creds == -1) + options->gss_cleanup_creds = 1; + if (options->gss_strict_acceptor == -1) + options->gss_strict_acceptor = 1; ++ if (options->gss_store_rekey == -1) ++ options->gss_store_rekey = 0; ++#ifdef GSSAPI ++ if (options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); ++#endif + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) +@@ -498,6 +510,7 @@ typedef enum { + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, ++ sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, + sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, sAllowAgentForwarding, +@@ -572,12 +585,22 @@ static struct { + #ifdef GSSAPI + { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, + { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, ++ { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, ++ { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, ++ { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, ++ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, + #else + { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, + { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, + { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, + { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, +@@ -1485,6 +1508,10 @@ process_server_config_line(ServerOptions *options, char *line, + intptr = &options->gss_authentication; + goto parse_flag; + ++ case sGssKeyEx: ++ intptr = &options->gss_keyex; ++ goto parse_flag; ++ + case sGssCleanupCreds: + intptr = &options->gss_cleanup_creds; + goto parse_flag; +@@ -1493,6 +1520,22 @@ process_server_config_line(ServerOptions *options, char *line, + intptr = &options->gss_strict_acceptor; + goto parse_flag; + ++ case sGssStoreRekey: ++ intptr = &options->gss_store_rekey; ++ goto parse_flag; ++ ++ case sGssKexAlgorithms: ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') ++ fatal("%.200s line %d: Missing argument.", ++ filename, linenum); ++ if (!kex_gss_names_valid(arg)) ++ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", ++ filename, linenum, arg ? arg : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; +@@ -2579,6 +2622,10 @@ dump_config(ServerOptions *o) + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); ++ dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); ++ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); ++ dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); ++ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); + #endif + dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(sKbdInteractiveAuthentication, +diff --git a/servconf.h b/servconf.h +index 54e0a8d8..a476d522 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -126,8 +126,11 @@ typedef struct { + int kerberos_get_afs_token; /* If true, try to get AFS token if + * authenticated with Kerberos. */ + int gss_authentication; /* If true, permit GSSAPI authentication */ ++ int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ ++ int gss_store_rekey; ++ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ + int password_authentication; /* If true, permit password + * authentication. */ + int kbd_interactive_authentication; /* If true, permit */ +diff --git a/session.c b/session.c +index 48cfaafb..78cc8358 100644 +--- a/session.c ++++ b/session.c +@@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) + + #ifdef KRB5 + if (options.kerberos_ticket_cleanup && +- authctxt->krb5_ctx) ++ authctxt->krb5_ctx) { ++ temporarily_use_uid(authctxt->pw); + krb5_cleanup_proc(authctxt); ++ restore_uid(); ++ } + #endif + + #ifdef GSSAPI +- if (options.gss_cleanup_creds) ++ if (options.gss_cleanup_creds) { ++ temporarily_use_uid(authctxt->pw); + ssh_gssapi_cleanup_creds(); ++ restore_uid(); ++ } + #endif + + /* remove agent socket */ +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.14 2018/07/10 09:13:30 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,30 @@ + + #define SSH_GSS_OIDTYPE 0x06 + ++#define SSH2_MSG_KEXGSS_INIT 30 ++#define SSH2_MSG_KEXGSS_CONTINUE 31 ++#define SSH2_MSG_KEXGSS_COMPLETE 32 ++#define SSH2_MSG_KEXGSS_HOSTKEY 33 ++#define SSH2_MSG_KEXGSS_ERROR 34 ++#define SSH2_MSG_KEXGSS_GROUPREQ 40 ++#define SSH2_MSG_KEXGSS_GROUP 41 ++#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" ++#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" ++#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" ++#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" ++#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" ++#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" ++#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" ++ ++#define GSS_KEX_DEFAULT_KEX \ ++ KEX_GSS_GEX_SHA1_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID ++ + typedef struct { + char *filename; + char *envvar; + char *envval; ++ struct passwd *owner; + void *data; + } ssh_gssapi_ccache; + +@@ -72,8 +92,11 @@ typedef struct { + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; ++ gss_name_t name; + struct ssh_gssapi_mech_struct *mech; + ssh_gssapi_ccache store; ++ int used; ++ int updated; + } ssh_gssapi_client; + + typedef struct ssh_gssapi_mech_struct { +@@ -84,6 +107,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); + void (*storecreds) (ssh_gssapi_client *); ++ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + + typedef struct { +@@ -94,10 +118,11 @@ typedef struct { + gss_OID oid; /* client */ + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ +- gss_cred_id_t client_creds; /* server */ ++ gss_cred_id_t client_creds; /* both */ + } Gssctxt; + + extern ssh_gssapi_mech *supported_mechs[]; ++extern Gssctxt *gss_kex_context; + + int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); + void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); +@@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); + + struct sshbuf; + int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); ++int ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *, gss_buffer_desc *); + + OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); + OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, +@@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); + OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_buildmic(struct sshbuf *, const char *, + const char *, const char *); +-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); ++int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); ++OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); ++int ssh_gssapi_credentials_updated(Gssctxt *); + + /* In the server */ ++typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, ++ const char *); ++char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); ++char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, ++ const char *, const char *); ++gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); ++int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, ++ const char *); + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +-int ssh_gssapi_userok(char *name); ++int ssh_gssapi_userok(char *name, struct passwd *, int kex); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); + void ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + ++char *ssh_gssapi_server_mechanisms(void); ++int ssh_gssapi_oid_table_ok(void); ++ ++int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); ++void ssh_gssapi_rekey_creds(void); ++ + #endif /* GSSAPI */ + + #endif /* _SSH_GSS_H */ +diff --git a/ssh.1 b/ssh.1 +index 9480eba8..a1c7d230 100644 +--- a/ssh.1 ++++ b/ssh.1 +@@ -497,7 +497,13 @@ For full details of the options listed below, and their possible values, see + .It GatewayPorts + .It GlobalKnownHostsFile + .It GSSAPIAuthentication ++.It GSSAPIKeyExchange ++.It GSSAPIClientIdentity + .It GSSAPIDelegateCredentials ++.It GSSAPIKexAlgorithms ++.It GSSAPIRenewalForcesRekey ++.It GSSAPIServerIdentity ++.It GSSAPITrustDns + .It HashKnownHosts + .It Host + .It HostbasedAuthentication +@@ -573,6 +579,8 @@ flag), + (supported message integrity codes), + .Ar kex + (key exchange algorithms), ++.Ar kex-gss ++(GSSAPI key exchange algorithms), + .Ar key + (key types), + .Ar key-cert +diff --git a/ssh.c b/ssh.c +index 91e7c351..42be7d88 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -736,6 +736,8 @@ main(int ac, char **av) + cp = mac_alg_list('\n'); + else if (strcmp(optarg, "kex") == 0) + cp = kex_alg_list('\n'); ++ else if (strcmp(optarg, "kex-gss") == 0) ++ cp = kex_gss_alg_list('\n'); + else if (strcmp(optarg, "key") == 0) + cp = sshkey_alg_list(0, 0, 0, '\n'); + else if (strcmp(optarg, "key-cert") == 0) +@@ -748,7 +750,7 @@ main(int ac, char **av) + cp = xstrdup("2"); + else if (strcmp(optarg, "help") == 0) { + cp = xstrdup( +- "cipher\ncipher-auth\nkex\nkey\n" ++ "cipher\ncipher-auth\nkex\nkex-gss\nkey\n" + "key-cert\nkey-plain\nmac\n" + "protocol-version\nsig"); + } +diff --git a/ssh_config b/ssh_config +index 5e8ef548..1ff999b6 100644 +--- a/ssh_config ++++ b/ssh_config +@@ -24,6 +24,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP yes + # AddressFamily any +diff --git a/ssh_config.5 b/ssh_config.5 +index 41262963..c3c8b274 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -754,10 +754,67 @@ The default is + Specifies whether user authentication based on GSSAPI is allowed. + The default is + .Cm no . ++.It Cm GSSAPIClientIdentity ++If set, specifies the GSSAPI client identity that ssh should use when ++connecting to the server. The default is unset, which means that the default ++identity will be used. + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is + .Cm no . ++.It Cm GSSAPIKeyExchange ++Specifies whether key exchange based on GSSAPI may be used. When using ++GSSAPI key exchange the server need not have a host key. ++The default is ++.Dq no . ++.It Cm GSSAPIRenewalForcesRekey ++If set to ++.Dq yes ++then renewal of the client's GSSAPI credentials will force the rekeying of the ++ssh connection. With a compatible server, this will delegate the renewed ++credentials to a session on the server. ++.Pp ++Checks are made to ensure that credentials are only propagated when the new ++credentials match the old ones on the originating client and where the ++receiving server still has the old set in its cache. ++.Pp ++The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIServerIdentity ++If set, specifies the GSSAPI server identity that ssh should expect when ++connecting to the server. The default is unset, which means that the ++expected GSSAPI server identity will be determined from the target ++hostname. ++.It Cm GSSAPITrustDns ++Set to ++.Dq yes ++to indicate that the DNS is trusted to securely canonicalize ++the name of the host being connected to. If ++.Dq no , ++the hostname entered on the ++command line will be passed untouched to the GSSAPI library. ++The default is ++.Dq no . ++.It Cm GSSAPIKexAlgorithms ++The list of key exchange algorithms that are offered for 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-curve25519-sha256- ++.Ed ++.Pp ++The default is ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +diff --git a/sshconnect2.c b/sshconnect2.c +index dffee90b..0d0a6cb8 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -78,8 +78,6 @@ + #endif + + /* import */ +-extern char *client_version_string; +-extern char *server_version_string; + extern Options options; + + /* +@@ -161,6 +159,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + char *s, *all_key; + int r; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ char *orig = NULL, *gss = NULL; ++ char *gss_host = NULL; ++#endif ++ + xxx_host = host; + xxx_hostaddr = hostaddr; + +@@ -193,6 +196,35 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + order_hostkeyalgs(host, hostaddr, port)); + } + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ if (options.gss_keyex) { ++ /* Add the GSSAPI mechanisms currently supported on this ++ * client to the key exchange algorithm proposal */ ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ if (options.gss_server_identity) ++ gss_host = xstrdup(options.gss_server_identity); ++ else if (options.gss_trust_dns) ++ gss_host = remote_hostname(ssh); ++ 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 ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +@@ -211,16 +243,46 @@ 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 +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; ++ ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; ++ } ++# endif ++#endif /* WITH_OPENSSL */ + ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_client; + ssh->kex->verify_host_key=&verify_host_key_callback; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ if (options.gss_keyex) { ++ ssh->kex->gss_deleg_creds = options.gss_deleg_creds; ++ ssh->kex->gss_trust_dns = options.gss_trust_dns; ++ ssh->kex->gss_client = options.gss_client_identity; ++ ssh->kex->gss_host = gss_host; ++ } ++#endif ++ + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); + + /* remove ext-info from the KEX proposals for rekeying */ + myproposal[PROPOSAL_KEX_ALGS] = + compat_kex_proposal(options.kex_algorithms); ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ /* repair myproposal after it was crumpled by the */ ++ /* ext-info removal above */ ++ if (gss) { ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ free(gss); ++ } ++#endif + if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) + fatal("kex_prop2buf: %s", ssh_err(r)); + +@@ -317,6 +379,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 *); + static int input_gssapi_errtok(int, u_int32_t, struct ssh *); ++static int userauth_gsskeyex(struct ssh *); + #endif + + void userauth(struct ssh *, char *); +@@ -333,6 +396,11 @@ static char *authmethods_get(void); + + Authmethod authmethods[] = { + #ifdef GSSAPI ++ {"gssapi-keyex", ++ userauth_gsskeyex, ++ NULL, ++ &options.gss_keyex, ++ NULL}, + {"gssapi-with-mic", + userauth_gssapi, + userauth_gssapi_cleanup, +@@ -698,12 +766,23 @@ userauth_gssapi(struct ssh *ssh) + OM_uint32 min; + int r, ok = 0; + gss_OID mech = NULL; ++ char *gss_host; ++ ++ if (options.gss_server_identity) ++ gss_host = xstrdup(options.gss_server_identity); ++ else if (options.gss_trust_dns) ++ gss_host = remote_hostname(ssh); ++ else ++ gss_host = xstrdup(authctxt->host); + + /* Try one GSSAPI method at a time, rather than sending them all at + * once. */ + + if (authctxt->gss_supported_mechs == NULL) +- gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); ++ if (GSS_ERROR(gss_indicate_mechs(&min, &authctxt->gss_supported_mechs))) { ++ free(gss_host); ++ return 0; ++ } + + /* Check to see whether the mechanism is usable before we offer it */ + while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && +@@ -712,13 +791,15 @@ userauth_gssapi(struct ssh *ssh) + elements[authctxt->mech_tried]; + /* My DER encoding requires length<128 */ + if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, +- mech, authctxt->host)) { ++ mech, gss_host, options.gss_client_identity)) { + ok = 1; /* Mechanism works */ + } else { + authctxt->mech_tried++; + } + } + ++ free(gss_host); ++ + if (!ok || mech == NULL) + return 0; + +@@ -958,6 +1039,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) + free(lang); + return r; + } ++ ++int ++userauth_gsskeyex(struct ssh *ssh) ++{ ++ struct sshbuf *b = NULL; ++ Authctxt *authctxt = ssh->authctxt; ++ gss_buffer_desc gssbuf; ++ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ms; ++ int r; ++ ++ static int attempt = 0; ++ if (attempt++ >= 1) ++ return (0); ++ ++ if (gss_kex_context == NULL) { ++ debug("No valid Key exchange context"); ++ return (0); ++ } ++ ++ if ((b = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ ++ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, ++ "gssapi-keyex"); ++ ++ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) ++ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ gssbuf.length = sshbuf_len(b); ++ ++ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { ++ sshbuf_free(b); ++ return (0); ++ } ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || ++ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("%s: %s", __func__, ssh_err(r)); ++ ++ sshbuf_free(b); ++ gss_release_buffer(&ms, &mic); ++ ++ return (1); ++} ++ + #endif /* GSSAPI */ + + static int +diff --git a/sshd.c b/sshd.c +index cbd3bce9..8c223f6a 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -796,8 +796,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3("%s: sent %u hostkeys", __func__, nkeys); + if (nkeys == 0) +- fatal("%s: no hostkeys", __func__); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3("%s: no hostkeys", __func__); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } +@@ -1769,7 +1769,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); + } +@@ -2260,6 +2261,48 @@ do_ssh2_kex(struct ssh *ssh) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( + list_hostkey_types()); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ { ++ char *orig; ++ char *gss = NULL; ++ char *newstr = NULL; ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ /* ++ * If we don't have a host key, then there's no point advertising ++ * the other key exchange algorithms ++ */ ++ ++ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) ++ orig = NULL; ++ ++ if (options.gss_keyex) ++ gss = ssh_gssapi_server_mechanisms(); ++ else ++ gss = NULL; ++ ++ if (gss && orig) ++ xasprintf(&newstr, "%s,%s", gss, orig); ++ else if (gss) ++ newstr = gss; ++ else if (orig) ++ newstr = orig; ++ ++ /* ++ * If we've got GSSAPI mechanisms, then we've got the 'null' host ++ * key alg, but we can't tell people about it unless its the only ++ * host key algorithm we support ++ */ ++ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; ++ ++ if (newstr) ++ myproposal[PROPOSAL_KEX_ALGS] = newstr; ++ else ++ fatal("No supported key exchange algorithms"); ++ } ++#endif ++ + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal("kex_setup: %s", ssh_err(r)); +@@ -2275,7 +2318,18 @@ do_ssh2_kex(struct ssh *ssh) + # ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + # endif +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } ++# endif ++#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; +diff --git a/sshd_config b/sshd_config +index 19b7c91a..2c48105f 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys + # GSSAPI options + GSSAPIAuthentication yes + GSSAPICleanupCredentials no ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange 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 b224f292..2baa6622 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -653,6 +653,11 @@ Specifies whether to automatically destroy the user's credentials cache + on logout. + The default is + .Cm yes . ++.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. ++The default is ++.Cm no . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -667,6 +672,31 @@ machine's default store. + This facility is provided to assist with operation on multi homed machines. + The default is + .Cm yes . ++.It Cm GSSAPIStoreCredentialsOnRekey ++Controls whether the user's GSSAPI credentials should be updated following a ++successful connection rekeying. This option can be used to accepted renewed ++or updated credentials from a compatible client. The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIKexAlgorithms ++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-curve25519-sha256- ++.Ed ++.Pp ++The default is ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a list of comma-separated patterns. +diff --git a/sshkey.c b/sshkey.c +index ad195776..789cd61e 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -135,6 +135,7 @@ static const struct keytype keytypes[] = { + # endif /* OPENSSL_HAS_NISTP521 */ + # endif /* OPENSSL_HAS_ECC */ + #endif /* WITH_OPENSSL */ ++ { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, + { NULL, NULL, NULL, -1, -1, 0, 0 } + }; + +@@ -223,7 +224,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) + const struct keytype *kt; + + for (kt = keytypes; kt->type != -1; kt++) { +- if (kt->name == NULL) ++ if (kt->name == NULL || kt->type == KEY_NULL) + continue; + if (!include_sigonly && kt->sigonly) + continue; +diff --git a/sshkey.h b/sshkey.h +index a91e6043..c11106c9 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -65,6 +65,7 @@ enum sshkey_types { + KEY_ED25519_CERT, + KEY_XMSS, + KEY_XMSS_CERT, ++ KEY_NULL, + KEY_UNSPEC + }; + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch new file mode 100644 index 0000000..9618863 --- /dev/null +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -0,0 +1,3068 @@ +diff --git a/Makefile.in b/Makefile.in +index 6f001bb3..c9424f1e 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -250,6 +250,8 @@ clean: regressclean + rm -f regress/unittests/match/test_match$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) clean) +@@ -280,6 +282,8 @@ distclean: regressclean + rm -f regress/unittests/match/test_match + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + rm -f regress/misc/kexfuzz/*.o + rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) + (cd openbsd-compat && $(MAKE) distclean) +@@ -442,6 +446,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/kex + $(MKDIR_P) `pwd`/regress/unittests/match + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/kexfuzz + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -565,6 +570,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ + MISC_KEX_FUZZ_OBJS=\ + regress/misc/kexfuzz/kexfuzz.o + +@@ -585,6 +600,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ + regress/unittests/kex/test_kex$(EXEEXT) \ + regress/unittests/match/test_match$(EXEEXT) \ + regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + regress/misc/kexfuzz/kexfuzz$(EXEEXT) + + tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) +diff --git a/authfd.c b/authfd.c +index 95348abf..5383df92 100644 +--- a/authfd.c ++++ b/authfd.c +@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identitylist *idl) + if (idl->comments != NULL) + free(idl->comments[i]); + } ++ free(idl->keys); ++ free(idl->comments); + free(idl); + } + +diff --git a/configure.ac b/configure.ac +index 30be6c18..82459746 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1854,12 +1854,14 @@ AC_LINK_IFELSE( + [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) + ]) + ++SCARD_MSG="yes" + disable_pkcs11= + AC_ARG_ENABLE([pkcs11], + [ --disable-pkcs11 disable PKCS#11 support code [no]], + [ + if test "x$enableval" = "xno" ; then + disable_pkcs11=1 ++ SCARD_MSG="no" + fi + ] + ) +@@ -1875,6 +1877,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then + ) + fi + ++# Check whether we have a p11-kit, we got default provider on command line ++DEFAULT_PKCS11_PROVIDER_MSG="no" ++AC_ARG_WITH([default-pkcs11-provider], ++ [ --with-default-pkcs11-provider[[=PATH]] Use default pkcs11 provider (p11-kit detected by default)], ++ [ if test "x$withval" != "xno" && test "x$disable_pkcs11" = "x"; then ++ if test "x$withval" = "xyes" ; then ++ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) ++ if test "x$PKGCONFIG" != "xno"; then ++ AC_MSG_CHECKING([if $PKGCONFIG knows about p11-kit]) ++ if "$PKGCONFIG" "p11-kit-1"; then ++ AC_MSG_RESULT([yes]) ++ use_pkgconfig_for_p11kit=yes ++ else ++ AC_MSG_RESULT([no]) ++ fi ++ fi ++ else ++ PKCS11_PATH="${withval}" ++ fi ++ if test "x$use_pkgconfig_for_p11kit" = "xyes"; then ++ PKCS11_PATH=`$PKGCONFIG --variable=proxy_module p11-kit-1` ++ fi ++ AC_CHECK_FILE("$PKCS11_PATH", ++ [ AC_DEFINE_UNQUOTED([PKCS11_DEFAULT_PROVIDER], ["$PKCS11_PATH"], [Path to default PKCS#11 provider (p11-kit proxy)]) ++ DEFAULT_PKCS11_PROVIDER_MSG="$PKCS11_PATH" ++ ], ++ [ AC_MSG_ERROR([Requested PKCS11 provided not found]) ] ++ ) ++ else ++ AC_MSG_WARN([Needs PKCS11 support to enable default pkcs11 provider]) ++ fi ] ++) ++ ++ + # IRIX has a const char return value for gai_strerror() + AC_CHECK_FUNCS([gai_strerror], [ + AC_DEFINE([HAVE_GAI_STRERROR]) +@@ -5256,6 +5292,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + echo " BSD Auth support: $BSD_AUTH_MSG" + echo " Random number source: $RAND_MSG" + echo " Privsep sandbox style: $SANDBOX_STYLE" ++echo " Default PKCS#11 provider: $DEFAULT_PKCS11_PROVIDER_MSG" + + echo "" + +diff --git a/regress/Makefile b/regress/Makefile +index 925edf71..94bb25e9 100644 +--- a/regress/Makefile ++++ b/regress/Makefile +@@ -109,9 +109,11 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ + known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ + modpipe netcat no_identity_config \ + pidfile putty.rsa2 ready regress.log \ +- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ ++ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ ++ rsa-agent-cert.pub rsa.pub \ + rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ +- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ ++ pkcs11*.crt pkcs11*.key \ ++ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ + sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ + ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ +@@ -231,6 +233,7 @@ unit: + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ +diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh +index 5205d906..5ca49be5 100644 +--- a/regress/agent-pkcs11.sh ++++ b/regress/agent-pkcs11.sh +@@ -29,6 +29,13 @@ fi + + test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + ++# requires ssh-agent built with correct path to ssh-pkcs11-helper ++# otherwise it fails to start the helper ++strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" ++if [ $? -ne 0 ]; then ++ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" ++fi ++ + # setup environment for softhsm2 token + DIR=$OBJ/SOFTHSM + rm -rf $DIR +@@ -113,7 +120,7 @@ else + done + + trace "remove pkcs11 keys" +- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 ++ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" +diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh +new file mode 100644 +index 00000000..19fc8169 +--- /dev/null ++++ b/regress/pkcs11.sh +@@ -0,0 +1,352 @@ ++# ++# Copyright (c) 2017 Red Hat ++# ++# Authors: Jakub Jelen ++# ++# Permission to use, copy, modify, and distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ++tid="pkcs11 tests with soft token" ++ ++try_token_libs() { ++ for _lib in "$@" ; do ++ if test -f "$_lib" ; then ++ verbose "Using token library $_lib" ++ TEST_SSH_PKCS11="$_lib" ++ return ++ fi ++ done ++ echo "skipped: Unable to find PKCS#11 token library" ++ exit 0 ++} ++ ++try_token_libs \ ++ /usr/local/lib/softhsm/libsofthsm2.so \ ++ /usr/lib64/pkcs11/libsofthsm2.so \ ++ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so ++ ++TEST_SSH_PIN=1234 ++TEST_SSH_SOPIN=12345678 ++if [ "x$TEST_SSH_SSHPKCS11HELPER" != "x" ]; then ++ SSH_PKCS11_HELPER="${TEST_SSH_SSHPKCS11HELPER}" ++ export SSH_PKCS11_HELPER ++fi ++ ++test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" ++ ++# requires ssh-agent built with correct path to ssh-pkcs11-helper ++# otherwise it fails to start the helper ++strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" ++if [ $? -ne 0 ]; then ++ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" ++fi ++ ++# setup environment for softhsm token ++DIR=$OBJ/SOFTHSM ++rm -rf $DIR ++TOKEN=$DIR/tokendir ++mkdir -p $TOKEN ++SOFTHSM2_CONF=$DIR/softhsm2.conf ++export SOFTHSM2_CONF ++cat > $SOFTHSM2_CONF << EOF ++# SoftHSM v2 configuration file ++directories.tokendir = ${TOKEN} ++objectstore.backend = file ++# ERROR, WARNING, INFO, DEBUG ++log.level = DEBUG ++# If CKF_REMOVABLE_DEVICE flag should be set ++slots.removable = false ++EOF ++out=$(softhsm2-util --init-token --free --label token-slot-0 --pin "$TEST_SSH_PIN" --so-pin "$TEST_SSH_SOPIN") ++slot=$(echo -- $out | sed 's/.* //') ++ ++# prevent ssh-agent from calling ssh-askpass ++SSH_ASKPASS=/usr/bin/true ++export SSH_ASKPASS ++unset DISPLAY ++# We need interactive access to test PKCS# since it prompts for PIN ++sed -i 's/.*BatchMode.*//g' $OBJ/ssh_proxy ++ ++# start command w/o tty, so ssh accepts pin from stdin (from agent-pkcs11.sh) ++notty() { ++ perl -e 'use POSIX; POSIX::setsid(); ++ if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" ++} ++ ++trace "generating keys" ++ID1="02" ++ID2="04" ++RSA=${DIR}/RSA ++EC=${DIR}/EC ++openssl genpkey -algorithm rsa > $RSA ++openssl pkcs8 -nocrypt -in $RSA |\ ++ softhsm2-util --slot "$slot" --label "SSH RSA Key $ID1" --id $ID1 \ ++ --pin "$TEST_SSH_PIN" --import /dev/stdin ++openssl genpkey \ ++ -genparam \ ++ -algorithm ec \ ++ -pkeyopt ec_paramgen_curve:prime256v1 |\ ++ openssl genpkey \ ++ -paramfile /dev/stdin > $EC ++openssl pkcs8 -nocrypt -in $EC |\ ++ softhsm2-util --slot "$slot" --label "SSH ECDSA Key $ID2" --id $ID2 \ ++ --pin "$TEST_SSH_PIN" --import /dev/stdin ++ ++trace "List the keys in the ssh-keygen with PKCS#11 URIs" ++${SSHKEYGEN} -D ${TEST_SSH_PKCS11} > $OBJ/token_keys ++if [ $? -ne 0 ]; then ++ fail "keygen fails to enumerate keys on PKCS#11 token" ++fi ++grep "pkcs11:" $OBJ/token_keys > /dev/null ++if [ $? -ne 0 ]; then ++ fail "The keys from ssh-keygen do not contain PKCS#11 URI as a comment" ++fi ++tail -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++ ++trace "Simple connect with ssh (without PKCS#11 URI)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -I ${TEST_SSH_PKCS11} \ ++ -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with pkcs11 failed (exit code $r)" ++fi ++ ++trace "Connect with PKCS#11 URI" ++trace " (second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (first key should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++trace "Connect with PKCS#11 URI including PIN should not prompt" ++trace " (second key should succeed)" ++${SSH} -F $OBJ/ssh_proxy -i \ ++ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (first key should fail)" ++${SSH} -F $OBJ/ssh_proxy -i \ ++ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++trace "Connect with various filtering options in PKCS#11 URI" ++trace " (by object label, second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:object=SSH%20RSA%20Key%202?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (by object label, first key should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:object=SSH%20RSA%20Key?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++trace " (by token label, second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID2};token=SoftToken%20(token)?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++fi ++ ++trace " (by wrong token label, should fail)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:token=SoftToken?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++fi ++ ++ ++ ++ ++trace "Test PKCS#11 URI specification in configuration files" ++echo "IdentityFile \"pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}\"" \ ++ >> $OBJ/ssh_proxy ++trace " (second key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI in config failed (exit code $r)" ++fi ++ ++trace " (first key should fail)" ++head -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -eq 5 ]; then ++ fail "ssh connect with PKCS#11 URI in config succeeded (should fail)" ++fi ++sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy ++ ++trace "Test PKCS#11 URI specification in configuration files with bogus spaces" ++echo "IdentityFile \" pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} \"" \ ++ >> $OBJ/ssh_proxy ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI with bogus spaces in config failed" \ ++ "(exit code $r)" ++fi ++sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy ++ ++ ++trace "Combination of PKCS11Provider and PKCS11URI on commandline" ++trace " (first key should succeed)" ++echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ ++ -i "pkcs11:id=${ID1}" -I ${TEST_SSH_PKCS11} somehost exit 5 ++r=$? ++if [ $r -ne 5 ]; then ++ fail "ssh connect with PKCS#11 URI and provider combination" \ ++ "failed (exit code $r)" ++fi ++ ++trace "Regress: Missing provider in PKCS11URI option" ++${SSH} -F $OBJ/ssh_proxy \ ++ -o IdentityFile=\"pkcs11:token=segfault\" somehost exit 5 ++r=$? ++if [ $r -eq 139 ]; then ++ fail "ssh connect with missing provider_id from configuration option" \ ++ "crashed (exit code $r)" ++fi ++ ++ ++trace "SSH Agent can work with PKCS#11 URI" ++trace "start the agent" ++eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null ++ ++r=$? ++if [ $r -ne 0 ]; then ++ fail "could not start ssh-agent: exit code $r" ++else ++ trace "add whole provider to agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with whole provider: exit code $r" ++ fi ++ ++ trace " pkcs11 list via agent (all keys)" ++ ${SSHADD} -l > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -l failed with whole provider: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (all keys)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with whole provider (exit code $r)" ++ fi ++ ++ trace " remove pkcs11 keys (all keys)" ++ ${SSHADD} -d "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with whole provider: exit code $r" ++ fi ++ ++ trace "add only first key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with first key: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (first key)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with first key (exit code $r)" ++ fi ++ ++ trace " remove first pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with first key: exit code $r" ++ fi ++ ++ trace "add only second key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with second key: exit code $r" ++ fi ++ ++ trace " pkcs11 connect via agent (second key should fail)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -eq 5 ]; then ++ fail "ssh connect passed without key (should fail)" ++ fi ++ ++ trace "add also the first key to the agent" ++ echo ${TEST_SSH_PIN} | notty ${SSHADD} \ ++ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add failed with first key: exit code $r" ++ fi ++ ++ trace " remove second pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -ne 0 ]; then ++ fail "ssh-add -d failed with second key: exit code $r" ++ fi ++ ++ trace " remove already-removed pkcs11 key should fail" ++ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ > /dev/null 2>&1 ++ r=$? ++ if [ $r -eq 0 ]; then ++ fail "ssh-add -d passed with non-existing key (should fail)" ++ fi ++ ++ trace " pkcs11 connect via agent (the first key should be still usable)" ++ ${SSH} -F $OBJ/ssh_proxy somehost exit 5 ++ r=$? ++ if [ $r -ne 5 ]; then ++ fail "ssh connect failed with first key (after removing second): exit code $r" ++ fi ++ ++ trace "kill agent" ++ ${SSHAGENT} -k > /dev/null ++fi +diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile +index e464b085..a0e5a37c 100644 +--- a/regress/unittests/Makefile ++++ b/regress/unittests/Makefile +@@ -2,6 +2,6 @@ + + REGRESS_FAIL_EARLY?= yes + SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion +-SUBDIR+=authopt ++SUBDIR+=pkcs11 authopt + + .include +diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c +new file mode 100644 +index 00000000..b637cb13 +--- /dev/null ++++ b/regress/unittests/pkcs11/tests.c +@@ -0,0 +1,337 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#include ++#include ++ ++#include "../test_helper/test_helper.h" ++ ++#include "sshbuf.h" ++#include "ssh-pkcs11-uri.h" ++ ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) ++ ++/* prototypes are not public -- specify them here internally for tests */ ++struct sshbuf *percent_encode(const char *, size_t, char *); ++int percent_decode(char *, char **); ++ ++void ++compare_uri(struct pkcs11_uri *a, struct pkcs11_uri *b) ++{ ++ ASSERT_PTR_NE(a, NULL); ++ ASSERT_PTR_NE(b, NULL); ++ ASSERT_SIZE_T_EQ(a->id_len, b->id_len); ++ ASSERT_MEM_EQ(a->id, b->id, a->id_len); ++ if (b->object != NULL) ++ ASSERT_STRING_EQ(a->object, b->object); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->object, b->object); ++ if (b->module_path != NULL) ++ ASSERT_STRING_EQ(a->module_path, b->module_path); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->module_path, b->module_path); ++ if (b->token != NULL) ++ ASSERT_STRING_EQ(a->token, b->token); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->token, b->token); ++ if (b->manuf != NULL) ++ ASSERT_STRING_EQ(a->manuf, b->manuf); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->manuf, b->manuf); ++ if (b->lib_manuf != NULL) ++ ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); ++} ++ ++void ++check_parse_rv(char *uri, struct pkcs11_uri *expect, int expect_rv) ++{ ++ char *buf = NULL, *str; ++ struct pkcs11_uri *pkcs11uri = NULL; ++ int rv; ++ ++ if (expect_rv == 0) ++ str = "Valid"; ++ else ++ str = "Invalid"; ++ asprintf(&buf, "%s PKCS#11 URI parsing: %s", str, uri); ++ TEST_START(buf); ++ free(buf); ++ pkcs11uri = pkcs11_uri_init(); ++ rv = pkcs11_uri_parse(uri, pkcs11uri); ++ ASSERT_INT_EQ(rv, expect_rv); ++ if (rv == 0) /* in case of failure result is undefined */ ++ compare_uri(pkcs11uri, expect); ++ pkcs11_uri_cleanup(pkcs11uri); ++ free(expect); ++ TEST_DONE(); ++} ++ ++void ++check_parse(char *uri, struct pkcs11_uri *expect) ++{ ++ check_parse_rv(uri, expect, 0); ++} ++ ++struct pkcs11_uri * ++compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, ++ char *manuf, char *module_path, char *object, char *pin) ++{ ++ struct pkcs11_uri *uri = pkcs11_uri_init(); ++ if (id_len > 0) { ++ uri->id_len = id_len; ++ uri->id = id; ++ } ++ uri->module_path = module_path; ++ uri->token = token; ++ uri->lib_manuf = lib_manuf; ++ uri->manuf = manuf; ++ uri->object = object; ++ uri->pin = pin; ++ return uri; ++} ++ ++static void ++test_parse_valid(void) ++{ ++ /* path arguments */ ++ check_parse("pkcs11:id=%01", ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:id=%00%01", ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:token=SSH%20Keys", ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:library-manufacturer=OpenSC", ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ check_parse("pkcs11:object=SIGN%20Key", ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); ++ /* query arguments */ ++ check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ check_parse("pkcs11:?pin-value=123456", ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "123456")); ++ ++ /* combinations */ ++ /* ID SHOULD be percent encoded */ ++ check_parse("pkcs11:token=SSH%20Key;id=0", ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL)); ++ check_parse( ++ "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, "CAC", ++ "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ check_parse( ++ "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, ++ "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key", NULL)); ++ check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so&pin-value=123456", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); ++ ++ /* empty path component matches everything */ ++ check_parse("pkcs11:", EMPTY_URI); ++ ++ /* empty string is a valid to match against (and different from NULL) */ ++ check_parse("pkcs11:token=", ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL)); ++ /* Percent character needs to be percent-encoded */ ++ check_parse("pkcs11:token=%25", ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL)); ++} ++ ++static void ++test_parse_invalid(void) ++{ ++ /* Invalid percent encoding */ ++ check_parse_rv("pkcs11:id=%0", EMPTY_URI, -1); ++ /* Invalid percent encoding */ ++ check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); ++ /* Space MUST be percent encoded -- XXX not enforced yet */ ++ check_parse("pkcs11:token=SSH Keys", ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ /* MUST NOT contain duplicate attributes of the same name */ ++ check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); ++ /* MUST NOT contain duplicate attributes of the same name */ ++ check_parse_rv("pkcs11:?pin-value=111111&pin-value=123456", EMPTY_URI, -1); ++ /* Unrecognized attribute in path are ignored with log message */ ++ check_parse("pkcs11:key_name=SSH", EMPTY_URI); ++ /* Unrecognized attribute in query SHOULD be ignored */ ++ check_parse("pkcs11:?key_name=SSH", EMPTY_URI); ++} ++ ++void ++check_gen(char *expect, struct pkcs11_uri *uri) ++{ ++ char *buf = NULL, *uri_str; ++ ++ asprintf(&buf, "Valid PKCS#11 URI generation: %s", expect); ++ TEST_START(buf); ++ free(buf); ++ uri_str = pkcs11_uri_get(uri); ++ ASSERT_PTR_NE(uri_str, NULL); ++ ASSERT_STRING_EQ(uri_str, expect); ++ free(uri_str); ++ TEST_DONE(); ++} ++ ++static void ++test_generate_valid(void) ++{ ++ /* path arguments */ ++ check_gen("pkcs11:id=%01", ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:id=%00%01", ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ /* library-manufacturer is not implmented now */ ++ /*check_gen("pkcs11:library-manufacturer=OpenSC", ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL));*/ ++ check_gen("pkcs11:manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ check_gen("pkcs11:object=RSA%20Key", ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key", NULL)); ++ /* query arguments */ ++ check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ ++ /* combinations */ ++ check_gen("pkcs11:id=%02;token=SSH%20Keys", ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key", NULL)); ++ ++ /* empty path component matches everything */ ++ check_gen("pkcs11:", EMPTY_URI); ++ ++} ++ ++void ++check_encode(char *source, size_t len, char *whitelist, char *expect) ++{ ++ char *buf = NULL; ++ struct sshbuf *b; ++ ++ asprintf(&buf, "percent_encode: expected %s", expect); ++ TEST_START(buf); ++ free(buf); ++ ++ b = percent_encode(source, len, whitelist); ++ ASSERT_STRING_EQ(sshbuf_ptr(b), expect); ++ sshbuf_free(b); ++ TEST_DONE(); ++} ++ ++static void ++test_percent_encode_multibyte(void) ++{ ++ /* SHOULD be encoded as octets according to the UTF-8 character encoding */ ++ ++ /* multi-byte characters are "for free" */ ++ check_encode("$", 1, "", "%24"); ++ check_encode("¢", 2, "", "%C2%A2"); ++ check_encode("€", 3, "", "%E2%82%AC"); ++ check_encode("𐍈", 4, "", "%F0%90%8D%88"); ++ ++ /* CK_UTF8CHAR is unsigned char (1 byte) */ ++ /* labels SHOULD be normalized to NFC [UAX15] */ ++ ++} ++ ++static void ++test_percent_encode(void) ++{ ++ /* Without whitelist encodes everything (for CKA_ID) */ ++ check_encode("A*", 2, "", "%41%2A"); ++ check_encode("\x00", 1, "", "%00"); ++ check_encode("\x7F", 1, "", "%7F"); ++ check_encode("\x80", 1, "", "%80"); ++ check_encode("\xff", 1, "", "%FF"); ++ ++ /* Default whitelist encodes anything but safe letters */ ++ check_encode("test" "\x00" "0alpha", 11, PKCS11_URI_WHITELIST, ++ "test%000alpha"); ++ check_encode(" ", 1, PKCS11_URI_WHITELIST, ++ "%20"); /* Space MUST be percent encoded */ ++ check_encode("/", 1, PKCS11_URI_WHITELIST, ++ "%2F"); /* '/' delimiter MUST be percent encoded (in the path) */ ++ check_encode("?", 1, PKCS11_URI_WHITELIST, ++ "%3F"); /* delimiter '?' MUST be percent encoded (in the path) */ ++ check_encode("#", 1, PKCS11_URI_WHITELIST, ++ "%23"); /* '#' MUST be always percent encoded */ ++ check_encode("key=value;separator?query&#anch", 35, PKCS11_URI_WHITELIST, ++ "key%3Dvalue%3Bseparator%3Fquery%26amp%3B%23anch"); ++ ++ /* Components in query can have '/' unencoded (useful for paths) */ ++ check_encode("/path/to.file", 13, PKCS11_URI_WHITELIST "/", ++ "/path/to.file"); ++} ++ ++void ++check_decode(char *source, char *expect, int expect_len) ++{ ++ char *buf = NULL, *out = NULL; ++ int rv; ++ ++ asprintf(&buf, "percent_decode: %s", source); ++ TEST_START(buf); ++ free(buf); ++ ++ rv = percent_decode(source, &out); ++ ASSERT_INT_EQ(rv, expect_len); ++ if (rv >= 0) ++ ASSERT_MEM_EQ(out, expect, expect_len); ++ free(out); ++ TEST_DONE(); ++} ++ ++static void ++test_percent_decode(void) ++{ ++ /* simple valid cases */ ++ check_decode("%00", "\x00", 1); ++ check_decode("%FF", "\xFF", 1); ++ ++ /* normal strings shold be kept intact */ ++ check_decode("strings are left", "strings are left", 16); ++ check_decode("10%25 of trees", "10% of trees", 12); ++ ++ /* make sure no more than 2 bytes are parsed */ ++ check_decode("%222", "\x22" "2", 2); ++ ++ /* invalid expects failure */ ++ check_decode("%0", "", -1); ++ check_decode("%Z", "", -1); ++ check_decode("%FG", "", -1); ++} ++ ++void ++tests(void) ++{ ++ test_percent_encode(); ++ test_percent_encode_multibyte(); ++ test_percent_decode(); ++ test_parse_valid(); ++ test_parse_invalid(); ++ test_generate_valid(); ++} +diff --git a/ssh-add.c b/ssh-add.c +index ac9c808d..f039e00e 100644 +--- a/ssh-add.c ++++ b/ssh-add.c +@@ -64,6 +64,7 @@ + #include "misc.h" + #include "ssherr.h" + #include "digest.h" ++#include "ssh-pkcs11-uri.h" + + /* argv0 */ + extern char *__progname; +@@ -188,6 +189,24 @@ delete_all(int agent_fd, int qflag) + return ret; + } + ++#ifdef ENABLE_PKCS11 ++static int update_card(int, int, const char *, int); ++ ++int ++update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) ++{ ++ struct pkcs11_uri *uri; ++ ++ /* dry-run parse to make sure the URI is valid and to report errors */ ++ uri = pkcs11_uri_init(); ++ if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ pkcs11_uri_cleanup(uri); ++ ++ return update_card(agent_fd, adding, pkcs11_uri, qflag); ++} ++#endif ++ + static int + add_file(int agent_fd, const char *filename, int key_only, int qflag) + { +@@ -529,6 +548,13 @@ lock_agent(int agent_fd, int lock) + static int + do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) + { ++#ifdef ENABLE_PKCS11 ++ if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(file, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ return update_pkcs11_uri(agent_fd, !deleting, file, qflag); ++ } ++#endif + if (deleting) { + if (delete_file(agent_fd, file, key_only, qflag) == -1) + return -1; +diff --git a/ssh-agent.c b/ssh-agent.c +index d06ecfd9..9c1b328f 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -548,10 +548,72 @@ no_identities(SocketEntry *e) + } + + #ifdef ENABLE_PKCS11 ++static char * ++sanitize_pkcs11_provider(const char *provider) ++{ ++ struct pkcs11_uri *uri = NULL; ++ char *sane_uri, *module_path = NULL; /* default path */ ++ char canonical_provider[PATH_MAX]; ++ ++ if (provider == NULL) ++ return NULL; ++ ++ if (strlen(provider) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ /* PKCS#11 URI */ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) { ++ error("Failed to init PCKS#11 URI"); ++ return NULL; ++ } ++ ++ if (pkcs11_uri_parse(provider, uri) != 0) { ++ error("Failed to parse PKCS#11 URI"); ++ return NULL; ++ } ++ /* validate also provider from URI */ ++ if (uri->module_path) ++ module_path = strdup(uri->module_path); ++ } else ++ module_path = strdup(provider); /* simple path */ ++ ++ if (module_path != NULL) { /* do not validate default NULL path in URI */ ++ if (realpath(module_path, canonical_provider) == NULL) { ++ verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", ++ module_path, strerror(errno)); ++ free(module_path); ++ pkcs11_uri_cleanup(uri); ++ return NULL; ++ } ++ free(module_path); ++ if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { ++ verbose("refusing PKCS#11 provider \"%.100s\": " ++ "not whitelisted", canonical_provider); ++ pkcs11_uri_cleanup(uri); ++ return NULL; ++ } ++ ++ /* copy verified and sanitized provider path back to the uri */ ++ if (uri) { ++ free(uri->module_path); ++ uri->module_path = xstrdup(canonical_provider); ++ } ++ } ++ ++ if (uri) { ++ sane_uri = pkcs11_uri_get(uri); ++ pkcs11_uri_cleanup(uri); ++ return sane_uri; ++ } else { ++ return xstrdup(canonical_provider); /* simple path */ ++ } ++} ++ + static void + process_add_smartcard_key(SocketEntry *e) + { +- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; ++ char *provider = NULL, *pin = NULL, *sane_uri = NULL; + int r, i, count = 0, success = 0, confirm = 0; + u_int seconds; + time_t death = 0; +@@ -587,28 +649,23 @@ process_add_smartcard_key(SocketEntry *e) + goto send; + } + } +- if (realpath(provider, canonical_provider) == NULL) { +- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", +- provider, strerror(errno)); +- goto send; +- } +- if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { +- verbose("refusing PKCS#11 add of \"%.100s\": " +- "provider not whitelisted", canonical_provider); ++ ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; +- } +- debug("%s: add %.100s", __func__, canonical_provider); ++ + if (lifetime && !death) + death = monotime() + lifetime; + +- count = pkcs11_add_provider(canonical_provider, pin, &keys); ++ debug("%s: add %.100s", __func__, sane_uri); ++ count = pkcs11_add_provider(sane_uri, pin, &keys); + for (i = 0; i < count; i++) { + k = keys[i]; + if (lookup_identity(k) == NULL) { + id = xcalloc(1, sizeof(Identity)); + id->key = k; +- id->provider = xstrdup(canonical_provider); +- id->comment = xstrdup(canonical_provider); /* XXX */ ++ id->provider = xstrdup(sane_uri); ++ id->comment = xstrdup(sane_uri); + id->death = death; + id->confirm = confirm; + TAILQ_INSERT_TAIL(&idtab->idlist, id, next); +@@ -622,6 +679,7 @@ process_add_smartcard_key(SocketEntry *e) + send: + free(pin); + free(provider); ++ free(sane_uri); + free(keys); + send_status(e, success); + } +@@ -629,7 +687,7 @@ send: + static void + process_remove_smartcard_key(SocketEntry *e) + { +- char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; ++ char *provider = NULL, *pin = NULL, *sane_uri = NULL; + int r, success = 0; + Identity *id, *nxt; + +@@ -640,30 +698,29 @@ process_remove_smartcard_key(SocketEntry *e) + } + free(pin); + +- if (realpath(provider, canonical_provider) == NULL) { +- verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", +- provider, strerror(errno)); ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; +- } + +- debug("%s: remove %.100s", __func__, canonical_provider); ++ debug("%s: remove %.100s", __func__, sane_uri); + for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { + nxt = TAILQ_NEXT(id, next); + /* Skip file--based keys */ + if (id->provider == NULL) + continue; +- if (!strcmp(canonical_provider, id->provider)) { ++ if (!strcmp(sane_uri, id->provider)) { + TAILQ_REMOVE(&idtab->idlist, id, next); + free_identity(id); + idtab->nentries--; + } + } +- if (pkcs11_del_provider(canonical_provider) == 0) ++ if (pkcs11_del_provider(sane_uri) == 0) + success = 1; + else + error("%s: pkcs11_del_provider failed", __func__); + send: + free(provider); ++ free(sane_uri); + send_status(e, success); + } + #endif /* ENABLE_PKCS11 */ +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 3898b281..91c43b14 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -798,6 +798,7 @@ do_download(struct passwd *pw) + free(fp); + } else { + (void) sshkey_write(keys[i], stdout); /* XXX check */ ++ (void) pkcs11_uri_write(keys[i], stdout); + fprintf(stdout, "\n"); + } + sshkey_free(keys[i]); +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +index e7860de8..7b2a9115 100644 +--- a/ssh-pkcs11-client.c ++++ b/ssh-pkcs11-client.c +@@ -321,6 +321,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) + u_int nkeys, i; + struct sshbuf *msg; + ++ debug("%s: called, name = %s", __func__, name); ++ + if (fd < 0 && pkcs11_start_helper() < 0) + return (-1); + +@@ -338,6 +340,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) + if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); ++ debug("%s: nkeys = %u", __func__, nkeys); + for (i = 0; i < nkeys; i++) { + /* XXX clean up properly instead of fatal() */ + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || +diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c +new file mode 100644 +index 00000000..e1a7b4e0 +--- /dev/null ++++ b/ssh-pkcs11-uri.c +@@ -0,0 +1,421 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#ifdef ENABLE_PKCS11 ++ ++#include ++#include ++ ++#include "sshkey.h" ++#include "sshbuf.h" ++#include "log.h" ++ ++#define CRYPTOKI_COMPAT ++#include "pkcs11.h" ++ ++#include "ssh-pkcs11-uri.h" ++ ++#define PKCS11_URI_PATH_SEPARATOR ";" ++#define PKCS11_URI_QUERY_SEPARATOR "&" ++#define PKCS11_URI_VALUE_SEPARATOR "=" ++#define PKCS11_URI_ID "id" ++#define PKCS11_URI_TOKEN "token" ++#define PKCS11_URI_OBJECT "object" ++#define PKCS11_URI_LIB_MANUF "library-manufacturer" ++#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_MODULE_PATH "module-path" ++#define PKCS11_URI_PIN_VALUE "pin-value" ++ ++/* Keyword tokens. */ ++typedef enum { ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pPinValue, pBadOption ++} pkcs11uriOpCodes; ++ ++/* Textual representation of the tokens. */ ++static struct { ++ const char *name; ++ pkcs11uriOpCodes opcode; ++} keywords[] = { ++ { PKCS11_URI_ID, pId }, ++ { PKCS11_URI_TOKEN, pToken }, ++ { PKCS11_URI_OBJECT, pObject }, ++ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, ++ { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_MODULE_PATH, pModulePath }, ++ { PKCS11_URI_PIN_VALUE, pPinValue }, ++ { NULL, pBadOption } ++}; ++ ++static pkcs11uriOpCodes ++parse_token(const char *cp) ++{ ++ u_int i; ++ ++ for (i = 0; keywords[i].name; i++) ++ if (strncasecmp(cp, keywords[i].name, ++ strlen(keywords[i].name)) == 0) ++ return keywords[i].opcode; ++ ++ return pBadOption; ++} ++ ++int ++percent_decode(char *data, char **outp) ++{ ++ char tmp[3]; ++ char *out, *tmp_end; ++ char *p = data; ++ long value; ++ size_t outlen = 0; ++ ++ out = malloc(strlen(data)+1); /* upper bound */ ++ if (out == NULL) ++ return -1; ++ while (*p != '\0') { ++ switch (*p) { ++ case '%': ++ p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[0] = *p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[1] = *p++; ++ tmp[2] = '\0'; ++ tmp_end = NULL; ++ value = strtol(tmp, &tmp_end, 16); ++ if (tmp_end != tmp+2) ++ goto fail; ++ else ++ out[outlen++] = (char) value; ++ break; ++ default: ++ out[outlen++] = *p++; ++ break; ++ } ++ } ++ ++ /* zero terminate */ ++ out[outlen] = '\0'; ++ *outp = out; ++ return outlen; ++fail: ++ free(out); ++ return -1; ++} ++ ++struct sshbuf * ++percent_encode(const char *data, size_t length, const char *whitelist) ++{ ++ struct sshbuf *b = NULL; ++ char tmp[4], *cp; ++ size_t i; ++ ++ if ((b = sshbuf_new()) == NULL) ++ return NULL; ++ for (i = 0; i < length; i++) { ++ cp = strchr(whitelist, data[i]); ++ /* if c is specified as '\0' pointer to terminator is returned !! */ ++ if (cp != NULL && *cp != '\0') { ++ if (sshbuf_put(b, &data[i], 1) != 0) ++ goto err; ++ } else ++ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 ++ || sshbuf_put(b, tmp, 3) != 0) ++ goto err; ++ } ++ if (sshbuf_put(b, "\0", 1) == 0) ++ return b; ++err: ++ sshbuf_free(b); ++ return NULL; ++} ++ ++char * ++pkcs11_uri_append(char *part, const char *separator, const char *key, ++ struct sshbuf *value) ++{ ++ char *new_part; ++ size_t size = 0; ++ ++ if (value == NULL) ++ return NULL; ++ ++ size = asprintf(&new_part, ++ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", ++ (part != NULL ? part : ""), ++ (part != NULL ? separator : ""), ++ key, sshbuf_ptr(value)); ++ sshbuf_free(value); ++ free(part); ++ ++ if (size <= 0) ++ return NULL; ++ return new_part; ++} ++ ++char * ++pkcs11_uri_get(struct pkcs11_uri *uri) ++{ ++ size_t size = 0; ++ char *p = NULL, *path = NULL, *query = NULL; ++ ++ /* compose a percent-encoded ID */ ++ if (uri->id_len > 0) { ++ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_ID, key_id); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write object label */ ++ if (uri->object) { ++ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_OBJECT, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write token label */ ++ if (uri->token) { ++ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_TOKEN, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write manufacturer */ ++ if (uri->manuf) { ++ struct sshbuf *manuf = percent_encode(uri->manuf, ++ strlen(uri->manuf), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_MANUF, manuf); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write module_path */ ++ if (uri->module_path) { ++ struct sshbuf *module = percent_encode(uri->module_path, ++ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); ++ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, ++ PKCS11_URI_MODULE_PATH, module); ++ if (query == NULL) ++ goto err; ++ } ++ ++ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", ++ path != NULL ? path : "", ++ query != NULL ? "?" : "", ++ query != NULL ? query : ""); ++err: ++ free(query); ++ free(path); ++ if (size <= 0) ++ return NULL; ++ return p; ++} ++ ++struct pkcs11_uri * ++pkcs11_uri_init() ++{ ++ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); ++ return d; ++} ++ ++void ++pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) ++{ ++ free(pkcs11->id); ++ free(pkcs11->module_path); ++ free(pkcs11->token); ++ free(pkcs11->object); ++ free(pkcs11->lib_manuf); ++ free(pkcs11->manuf); ++ if (pkcs11->pin) ++ freezero(pkcs11->pin, strlen(pkcs11->pin)); ++ free(pkcs11); ++} ++ ++int ++pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) ++{ ++ char *saveptr1, *saveptr2, *str1, *str2, *tok; ++ int rv = 0, len; ++ char *p = NULL; ++ ++ size_t scheme_len = strlen(PKCS11_URI_SCHEME); ++ if (strlen(uri) < scheme_len || /* empty URI matches everything */ ++ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { ++ error("%s: The '%s' does not look like PKCS#11 URI", ++ __func__, uri); ++ return -1; ++ } ++ ++ if (pkcs11 == NULL) { ++ error("%s: Bad arguments. The pkcs11 can't be null", __func__); ++ return -1; ++ } ++ ++ /* skip URI schema name */ ++ p = strdup(uri); ++ str1 = p; ++ ++ /* everything before ? */ ++ tok = strtok_r(str1, "?", &saveptr1); ++ if (tok == NULL) { ++ error("%s: pk11-path expected, got EOF", __func__); ++ rv = -1; ++ goto out; ++ } ++ ++ /* skip URI schema name: ++ * the scheme ensures that there is at least something before "?" ++ * allowing empty pk11-path. Resulting token at worst pointing to ++ * \0 byte */ ++ tok = tok + scheme_len; ++ ++ /* parse pk11-path */ ++ for (str2 = tok; ; str2 = NULL) { ++ char **charptr, *arg = NULL; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ ++ switch (opcode) { ++ case pId: ++ /* CKA_ID */ ++ if (pkcs11->id != NULL) { ++ verbose("%s: The id already set in the PKCS#11 URI", ++ __func__); ++ rv = -1; ++ goto out; ++ } ++ len = percent_decode(arg, &pkcs11->id); ++ if (len <= 0) { ++ verbose("%s: Failed to percent-decode CKA_ID: %s", ++ __func__, arg); ++ rv = -1; ++ goto out; ++ } else ++ pkcs11->id_len = len; ++ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", ++ __func__, arg); ++ break; ++ case pToken: ++ /* CK_TOKEN_INFO -> label */ ++ charptr = &pkcs11->token; ++ parse_string: ++ if (*charptr != NULL) { ++ verbose("%s: The %s already set in the PKCS#11 URI", ++ keywords[opcode].name, __func__); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, charptr); ++ debug3("%s: Setting %s = %s from PKCS#11 URI", ++ __func__, keywords[opcode].name, *charptr); ++ break; ++ ++ case pObject: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->object; ++ goto parse_string; ++ ++ case pManufacturer: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->manuf; ++ goto parse_string; ++ ++ case pLibraryManufacturer: ++ /* CK_INFO -> manufacturerID */ ++ charptr = &pkcs11->lib_manuf; ++ goto parse_string; ++ ++ default: ++ /* Unrecognized attribute in the URI path SHOULD be error */ ++ verbose("%s: Unknown part of path in PKCS#11 URI: %s", ++ __func__, tok); ++ } ++ } ++ ++ tok = strtok_r(NULL, "?", &saveptr1); ++ if (tok == NULL) { ++ goto out; ++ } ++ /* parse pk11-query (optional) */ ++ for (str2 = tok; ; str2 = NULL) { ++ char *arg; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ ++ switch (opcode) { ++ case pModulePath: ++ /* module-path is PKCS11Provider */ ++ if (pkcs11->module_path != NULL) { ++ verbose("%s: Multiple module-path attributes are" ++ "not supported the PKCS#11 URI", __func__); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->module_path); ++ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", ++ __func__, pkcs11->module_path); ++ break; ++ ++ case pPinValue: ++ /* pin-value */ ++ if (pkcs11->pin != NULL) { ++ verbose("%s: Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI", __func__); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->pin); ++ debug3("%s: Setting PIN from PKCS#11 URI", __func__); ++ break; ++ ++ default: ++ /* Unrecognized attribute in the URI query SHOULD be ignored */ ++ verbose("%s: Unknown part of query in PKCS#11 URI: %s", ++ __func__, tok); ++ } ++ } ++out: ++ free(p); ++ return rv; ++} ++ ++#endif /* ENABLE_PKCS11 */ +diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h +new file mode 100644 +index 00000000..942a5a5a +--- /dev/null ++++ b/ssh-pkcs11-uri.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#define PKCS11_URI_SCHEME "pkcs11:" ++#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789_-.()" ++ ++struct pkcs11_uri { ++ /* path */ ++ char *id; ++ size_t id_len; ++ char *token; ++ char *object; ++ char *lib_manuf; ++ char *manuf; ++ /* query */ ++ char *module_path; ++ char *pin; /* Only parsed, but not printed */ ++}; ++ ++struct pkcs11_uri *pkcs11_uri_init(); ++void pkcs11_uri_cleanup(struct pkcs11_uri *); ++int pkcs11_uri_parse(const char *, struct pkcs11_uri *); ++struct pkcs11_uri *pkcs11_uri_init(); ++char *pkcs11_uri_get(struct pkcs11_uri *uri); ++ +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index 70f06bff..59332945 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -54,8 +54,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -64,6 +64,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -74,6 +81,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +114,63 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug("pkcs11_provider_finalize: %p refcount %d valid %d", +- p, p->refcount, p->valid); +- if (!p->valid) ++ debug("%s: %p refcount %d valid %d", __func__, ++ m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug("%s: %p refcount %d", __func__, m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error("%s: %p still valid", __func__, m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared libarary, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug("%s: %p refcount %d valid %d", __func__, ++ p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -135,13 +180,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) + static void + pkcs11_provider_unref(struct pkcs11_provider *p) + { +- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); ++ debug("%s: %p refcount %d", __func__, p, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error("pkcs11_provider_unref: %p still valid", p); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +202,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +230,52 @@ pkcs11_provider_lookup(char *provider_id) + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) ++{ ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) + { + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3("%s(%s): called", __func__, provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +285,55 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: ++ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ break; ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: ++ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ break; ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); ++ } ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -252,8 +392,8 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if (!pkcs11_interactive) { + error("need pin entry%s", +@@ -300,8 +440,8 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + attr.type = type; + attr.pValue = &flag; +@@ -332,13 +472,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) + int always_auth = 0; + int did_login = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || !k11->provider->module ++ || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (pkcs11_login(k11, CKU_USER) < 0) { +@@ -415,8 +556,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + tlen = RSA_size(rsa); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ +@@ -460,7 +601,7 @@ pkcs11_rsa_start_wrapper(void) + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + +@@ -478,6 +619,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + RSA_set_method(rsa, rsa_method); + RSA_set_ex_data(rsa, rsa_idx, k11); + return (0); +@@ -508,8 +655,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, + return (NULL); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + siglen = ECDSA_size(ec); + sig = xmalloc(siglen); +@@ -574,7 +721,7 @@ pkcs11_ecdsa_start_wrapper(void) + + static int + pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) + { + struct pkcs11_key *k11; + +@@ -590,6 +737,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + EC_KEY_set_method(ec, ec_key_method); + EC_KEY_set_ex_data(ec, ec_key_idx, k11); + +@@ -624,47 +777,26 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, + CK_FUNCTION_LIST *f; + CK_RV rv; + CK_SESSION_HANDLE session; +- int login_required, have_pinpad, ret; +- char prompt[1024], *xpin = NULL; ++ int login_required, ret; + +- f = p->function_list; +- si = &p->slotinfo[slotidx]; ++ f = p->module->function_list; ++ si = &p->module->slotinfo[slotidx]; + +- have_pinpad = si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH; + login_required = si->token.flags & CKF_LOGIN_REQUIRED; + + /* fail early before opening session */ +- if (login_required && !have_pinpad && !pkcs11_interactive && ++ if (login_required && !pkcs11_interactive && + (pin == NULL || strlen(pin) == 0)) { + error("pin required"); + return (-SSH_PKCS11_ERR_PIN_REQUIRED); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } +- if (login_required) { +- if (have_pinpad && (pin == NULL || strlen(pin) == 0)) { +- /* defer PIN entry to the reader keypad */ +- rv = f->C_Login(session, CKU_USER, NULL_PTR, 0); +- } else { +- if (pkcs11_interactive) { +- snprintf(prompt, sizeof(prompt), +- "Enter PIN for '%s': ", si->token.label); +- if ((xpin = read_passphrase(prompt, +- RP_ALLOW_EOF)) == NULL) { +- debug("%s: no pin specified", +- __func__); +- return (-SSH_PKCS11_ERR_PIN_REQUIRED); +- } +- pin = xpin; +- } +- rv = f->C_Login(session, CKU_USER, +- (u_char *)pin, strlen(pin)); +- if (xpin != NULL) +- freezero(xpin, strlen(xpin)); +- } ++ if (login_required && pin != NULL && strlen(pin) != 0) { ++ rv = f->C_Login(session, user, (u_char *)pin, strlen(pin)); + if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { + error("C_Login failed: %lu", rv); + ret = (rv == CKR_PIN_LOCKED) ? +@@ -696,7 +828,8 @@ static struct sshkey * + pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -710,14 +843,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; ++ key_attr[3].type = CKA_EC_PARAMS; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -729,18 +863,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * XXX assumes CKA_ID is always first. + */ + if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, public point and curve parameters of EC key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -752,8 +887,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- attrp = key_attr[2].pValue; +- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); ++ attrp = key_attr[3].pValue; ++ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); + if (group == NULL) { + ossl_error("d2i_ECPKParameters failed"); + goto fail; +@@ -764,13 +899,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (key_attr[1].ulValueLen <= 2) { ++ if (key_attr[2].ulValueLen <= 2) { + error("CKA_EC_POINT too small"); + goto fail; + } + +- attrp = key_attr[1].pValue; +- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); ++ attrp = key_attr[2].pValue; ++ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); + if (octet == NULL) { + ossl_error("d2i_ASN1_OCTET_STRING failed"); + goto fail; +@@ -787,7 +922,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -803,7 +938,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + ec = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -820,7 +955,8 @@ static struct sshkey * + pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -831,14 +967,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_MODULUS; +- key_attr[2].type = CKA_PUBLIC_EXPONENT; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_MODULUS; ++ key_attr[3].type = CKA_PUBLIC_EXPONENT; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -850,18 +987,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * XXX assumes CKA_ID is always first. + */ + if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, modulus and public exponent of RSA key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -873,8 +1011,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) { + error("BN_bin2bn failed"); + goto fail; +@@ -883,7 +1021,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + fatal("%s: set key", __func__); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -898,7 +1036,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + rsa = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -909,7 +1047,8 @@ static struct sshkey * + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE cert_attr[3]; ++ CK_ATTRIBUTE cert_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -926,14 +1065,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&cert_attr, 0, sizeof(cert_attr)); + cert_attr[0].type = CKA_ID; +- cert_attr[1].type = CKA_SUBJECT; +- cert_attr[2].type = CKA_VALUE; ++ cert_attr[1].type = CKA_LABEL; ++ cert_attr[2].type = CKA_SUBJECT; ++ cert_attr[3].type = CKA_VALUE; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -945,18 +1085,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * XXX assumes CKA_ID is always first. + */ + if (cert_attr[1].ulValueLen == 0 || +- cert_attr[2].ulValueLen == 0) { ++ cert_attr[2].ulValueLen == 0 || ++ cert_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (cert_attr[i].ulValueLen > 0) + cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + + /* retrieve ID, subject and value of certificate */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -968,8 +1109,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- cp = cert_attr[2].pValue; +- if (d2i_X509(&x509, &cp, cert_attr[2].ulValueLen) == NULL) { ++ cp = cert_attr[3].pValue; ++ if (d2i_X509(&x509, &cp, cert_attr[3].ulValueLen) == NULL) { + error("d2i_x509 failed"); + goto fail; + } +@@ -990,7 +1131,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -1020,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -1039,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + error("unknown certificate key type"); + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1066,11 +1207,12 @@ have_rsa_key(const RSA *rsa) + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, int *nkeys) ++ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1086,10 +1228,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1163,11 +1318,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, int *nkeys) ++ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1183,10 +1339,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1443,15 +1612,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, + } + #endif /* WITH_PKCS11_KEYGEN */ + +-/* +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. +- */ + static int +-pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) + { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; + struct pkcs11_provider *p = NULL; + void *handle = NULL; +@@ -1460,148 +1624,285 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; +- +- if (providerp == NULL) ++ char *provider_module = NULL; ++ struct pkcs11_module *m; ++ ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error("%s: No module path provided", __func__); + goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; ++#endif ++ } else { ++ provider_module = strdup(uri->module_path); ++ } + +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug("%s: provider already registered: %s", +- __func__, provider_id); +- goto fail; ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); ++ ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug("%s: provider module already initialized: %s", ++ __func__, provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-library */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ ++ p->module->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug("%s: Skipping provider %s not matching library_manufacturer", ++ __func__, m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { ++ if (m->nslots == 0) { + error("%s: provider %s returned no slots", __func__, +- provider_id); ++ provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->valid = 1; ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (unsigned long)i, rv); ++ "failed: %lu", provider_module, (unsigned long)i, rv); ++ token->flags = 0; + continue; + } ++ rmspace(token->label, sizeof(token->label)); ++ rmspace(token->manufacturerID, sizeof(token->manufacturerID)); ++ rmspace(token->model, sizeof(token->model)); ++ rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); ++ } ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return ret; ++} ++ ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; ++ ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; ++ ++ if (keyp != NULL) ++ *keyp = NULL; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ provider_uri = pkcs11_uri_get(uri); ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; + if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { + debug2("%s: ignoring uninitialised token in " + "provider %s slot %lu", __func__, +- provider_id, (unsigned long)i); ++ provider_uri, (unsigned long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2("%s: ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", __func__, ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2("%s: ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", __func__, ++ token->manufacturerID, (unsigned long)i); + continue; + } +- rmspace(token->label, sizeof(token->label)); +- rmspace(token->manufacturerID, sizeof(token->manufacturerID)); +- rmspace(token->model, sizeof(token->model)); +- rmspace(token->serialNumber, sizeof(token->serialNumber)); + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } + /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) ++ * open session if not yet openend, login with pin and ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) == 0) { ++ if (p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) == 0) { + if (keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3("%s: No keys found. Retrying without label (%s) ", ++ __func__, token->label); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ uri->object = label; ++ } + } ++ pin = NULL; /* Will be cleaned up with URI */ + } + + /* now owned by caller */ + *providerp = p; + +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- ++ free(provider_uri); + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ struct pkcs11_uri *uri = NULL; ++ int r; ++ ++ debug("%s: called, provider_id = %s", __func__, provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, providerp, user); ++ pkcs11_uri_cleanup(uri); ++ ++ return r; ++} ++ + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp) + { +- struct pkcs11_provider *p = NULL; + int nkeys; ++ struct pkcs11_provider *p = NULL; ++ char *provider_uri = pkcs11_uri_get(uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, &p, CKU_USER); ++ debug("%s: called, provider_uri = %s", __func__, provider_uri); ++ ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1611,7 +1912,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) + } + if (nkeys == 0) + debug("%s: provider %s returned no keys", __func__, +- provider_id); ++ provider_uri); ++ ++ free(provider_uri); ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ ++int ++pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) ++{ ++ struct pkcs11_uri *uri; ++ int nkeys; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +@@ -1633,8 +1963,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, + + if ((p = pkcs11_provider_lookup(provider_id)) != NULL) + debug("%s: provider \"%s\" available", __func__, provider_id); +- else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, &p, +- CKU_SO)) < 0) { ++ else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, &p, CKU_SO)) != 0) { + debug("%s: could not register provider %s", __func__, + provider_id); + goto out; +@@ -1705,8 +2034,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, + + if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { + debug("%s: using provider \"%s\"", __func__, provider_id); +- } else if (pkcs11_register_provider(provider_id, pin, NULL, &p, +- CKU_SO) < 0) { ++ } else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, &p, CKU_SO)) != 0) { + debug("%s: could not register provider %s", __func__, + provider_id); + goto out; +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +index b9038450..5a855338 100644 +--- a/ssh-pkcs11.h ++++ b/ssh-pkcs11.h +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff --git a/ssh.c b/ssh.c +index 91e7c351..47f4f299 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -772,6 +772,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) < 0) + fprintf(stderr, "Warning: Identity file %s " +@@ -1521,6 +1529,7 @@ main(int ac, char **av) + free(options.certificate_files[i]); + options.certificate_files[i] = NULL; + } ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, pw); +@@ -1994,6 +2003,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(struct passwd *pw) +@@ -2008,10 +2056,6 @@ load_public_identity_files(struct passwd *pw) + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2024,32 +2068,46 @@ load_public_identity_files(struct passwd *pw) + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = +- xstrdup(options.pkcs11_provider); /* XXX */ +- n_ids++; +- } +- free(keys); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PCKS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = percent_expand(cp, "d", pw->pw_dir, + "u", pw->pw_name, "l", thishost, "h", host, + "r", options.user, (char *)NULL); +diff --git a/ssh_config.5 b/ssh_config.5 +index 41262963..a211034e 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -952,6 +952,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. From 678fe5c83c2f9d9871d80de6722032dff72f3337 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 5 May 2019 18:16:41 +0200 Subject: [PATCH 073/146] Update sources file --- sources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources b/sources index 48349e8..bbbcdc2 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-7.9p1.tar.gz) = 0412c9c429c9287f0794023951469c8e6ec833cdb55821bfa0300dd90d0879ff60484f620cffd93372641ab69bf0b032c2d700ccc680950892725fb631b7708e -SHA512 (openssh-7.9p1.tar.gz.asc) = 881db1b541813136fabd9adb9f5430c4f0fae372c06c99cb049feb8526a573275fe80c129c89511dd4e65f73f41e29364fefaaf8b7c78835224691c488d5da32 +SHA512 (openssh-8.0p1.tar.gz) = e280fa2d56f550efd37c5d2477670326261aa8b94d991f9eb17aad90e0c6c9c939efa90fe87d33260d0f709485cb05c379f0fd1bd44fc0d5190298b6398c9982 +SHA512 (openssh-8.0p1.tar.gz.asc) = fe9e7383d9467e869762864f2b719165d9a3f2c5316c07067df1d45fc7819bd2cb8ef758454865595688804a4c160dd3d3aaee4c5f887859555d2c7bb8c4592b SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From b9cd944358d375e4e14eeea3fa25172730e5c4b8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 20 May 2019 08:38:52 +0200 Subject: [PATCH 074/146] Based on openssh-8.0p1-2.fc30 --- gsi-openssh.spec | 25 +- openssh-5.8p1-getaddrinfo.patch | 24 - openssh-7.7p1-fips.patch | 194 -------- openssh-8.0p1-crypto-policies.patch | 210 ++++++++ openssh-8.0p1-gsissh.patch | 170 +++---- openssh-8.0p1-openssl-evp.patch | 720 ++++++++++++++++++++++++++++ openssh-8.0p1-openssl-kdf.patch | 137 ++++++ openssh-8.0p1-scp-tests.patch | 61 +++ 8 files changed, 1235 insertions(+), 306 deletions(-) delete mode 100644 openssh-5.8p1-getaddrinfo.patch create mode 100644 openssh-8.0p1-crypto-policies.patch create mode 100644 openssh-8.0p1-openssl-evp.patch create mode 100644 openssh-8.0p1-openssl-kdf.patch create mode 100644 openssh-8.0p1-scp-tests.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f157605..5e17ca0 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.0p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -56,9 +56,6 @@ Source99: README.sshd-and-gsisshd #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 Patch100: openssh-6.7p1-coverity.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1894 -#https://bugzilla.redhat.com/show_bug.cgi?id=735889 -#Patch102: openssh-5.8p1-getaddrinfo.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 @@ -155,6 +152,15 @@ Patch953: openssh-7.8p1-scp-ipv6.patch Patch958: openssh-7.9p1-ssh-copy-id.patch # Update cached passwd structure after PAM authentication (#1674541) Patch960: openssh-7.9p1-updated-cached-pw.patch +# Verify the SCP vulnerabilities are fixed in the package testsuite +# https://bugzilla.mindrot.org/show_bug.cgi?id=3007 +Patch961: openssh-8.0p1-scp-tests.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 # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -257,8 +263,6 @@ This version of OpenSSH has been modified to support GSI authentication. gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %setup -q -n openssh-%{version} -# investigate %%patch102 -p1 -b .getaddrinfo - %patch400 -p1 -b .role-mls %patch404 -p1 -b .privsep-selinux @@ -304,6 +308,10 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch953 -p1 -b .scp-ipv6 %patch958 -p1 -b .ssh-copy-id %patch960 -p1 -b .update-pw +%patch961 -p1 -b .scp-tests +%patch962 -p1 -b .crypto-policies +%patch963 -p1 -b .openssl-evp +%patch964 -p1 -b .openssl-kdf %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -515,7 +523,10 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog -* Fri May 3 2019 Mattias Ellert - 8.0p1-1 +* Mon May 20 2019 Mattias Ellert - 8.0p1-2 +- Based on openssh-8.0p1-2.fc30 + +* Fri May 03 2019 Mattias Ellert - 8.0p1-1 - Based on openssh-8.0p1-1.fc30 * Fri Mar 22 2019 Mattias Ellert - 7.9p1-7 diff --git a/openssh-5.8p1-getaddrinfo.patch b/openssh-5.8p1-getaddrinfo.patch deleted file mode 100644 index 76deaef..0000000 --- a/openssh-5.8p1-getaddrinfo.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up openssh-5.6p1/channels.c.getaddrinfo openssh-5.6p1/channels.c ---- openssh-5.6p1/channels.c.getaddrinfo 2012-02-14 16:12:54.427852524 +0100 -+++ openssh-5.6p1/channels.c 2012-02-14 16:13:22.818928690 +0100 -@@ -3275,6 +3275,9 @@ x11_create_display_inet(int x11_display_ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; -+#ifdef AI_ADDRCONFIG -+ hints.ai_flags |= AI_ADDRCONFIG; -+#endif - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", port); - if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { -diff -up openssh-5.6p1/sshconnect.c.getaddrinfo openssh-5.6p1/sshconnect.c ---- openssh-5.6p1/sshconnect.c.getaddrinfo 2012-02-14 16:09:25.057964291 +0100 -+++ openssh-5.6p1/sshconnect.c 2012-02-14 16:09:25.106047007 +0100 -@@ -343,6 +343,7 @@ ssh_connect(const char *host, struct soc - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; -+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; - snprintf(strport, sizeof strport, "%u", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("%s: Could not resolve hostname %.100s: %s", __progname, diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 14cf5c3..f28b943 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,67 +1,3 @@ -diff -up openssh-7.9p1/cipher.c.fips openssh-7.9p1/cipher.c ---- openssh-7.9p1/cipher.c.fips 2019-03-11 17:06:37.614877975 +0100 -+++ openssh-7.9p1/cipher.c 2019-03-11 17:06:37.620878031 +0100 -@@ -39,6 +39,8 @@ - - #include - -+#include -+ - #include - #include - #include -@@ -92,6 +94,33 @@ static const struct sshcipher ciphers[] - { NULL, 0, 0, 0, 0, 0, NULL } - }; - -+static const struct sshcipher fips_ciphers[] = { -+#ifdef WITH_OPENSSL -+ { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, -+ { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc }, -+ { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc }, -+ { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, -+ { "rijndael-cbc@lysator.liu.se", -+ 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, -+ { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, -+ { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, -+ { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, -+# ifdef OPENSSL_HAVE_EVPGCM -+ { "aes128-gcm@openssh.com", -+ 16, 16, 12, 16, 0, EVP_aes_128_gcm }, -+ { "aes256-gcm@openssh.com", -+ 16, 32, 12, 16, 0, EVP_aes_256_gcm }, -+# endif /* OPENSSL_HAVE_EVPGCM */ -+#else -+ { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, -+ { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, -+ { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL }, -+#endif -+ { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, -+ -+ { NULL, 0, 0, 0, 0, 0, NULL } -+}; -+ - /*--*/ - - /* Returns a comma-separated list of supported ciphers. */ -@@ -102,7 +131,7 @@ cipher_alg_list(char sep, int auth_only) - size_t nlen, rlen = 0; - const struct sshcipher *c; - -- for (c = ciphers; c->name != NULL; c++) { -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { - if ((c->flags & CFLAG_INTERNAL) != 0) - continue; - if (auth_only && c->auth_len == 0) -@@ -174,7 +203,7 @@ const struct sshcipher * - cipher_by_name(const char *name) - { - const struct sshcipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcmp(c->name, name) == 0) - return c; - return NULL; diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c --- openssh-7.9p1/cipher-ctr.c.fips 2019-03-11 17:06:37.519877082 +0100 +++ openssh-7.9p1/cipher-ctr.c 2019-03-11 17:06:37.620878031 +0100 @@ -154,75 +90,9 @@ diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h u_int dh_estimate(int); -diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c ---- openssh-7.9p1/entropy.c.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/entropy.c 2019-03-11 17:06:37.621878041 +0100 -@@ -223,6 +223,11 @@ seed_rng(void) - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, - OpenSSL_version_num()); - -+ /* clean the PRNG status when exiting the program */ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ atexit(RAND_cleanup); -+#endif -+ - #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) - debug3("RNG is ready, skipping seeding"); diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c --- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100 +++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100 -@@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = { - { NULL, -1, -1, -1 }, - }; - -+static const struct kexalg kexalgs_fips[] = { -+ { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, -+#ifdef HAVE_EVP_SHA256 -+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, -+#endif -+#ifdef OPENSSL_HAS_ECC -+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, -+ SSH_DIGEST_SHA384 }, -+# ifdef OPENSSL_HAS_NISTP521 -+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, -+ SSH_DIGEST_SHA512 }, -+# endif -+#endif -+ { NULL, -1, -1, -1 }, -+}; -+ - static char * - kex_alg_list_internal(char sep, const struct kexalg *algs) - { -@@ -129,7 +150,7 @@ kex_alg_list(char sep) - char * - kex_alg_list(char sep) - { -- return kex_alg_list_internal(sep, kexalgs); -+ return kex_alg_list_internal(sep, (FIPS_mode() ? kexalgs_fips : kexalgs)); - } - - char * -@@ -149,11 +170,11 @@ kex_alg_by_name(const char *name) - { - const struct kexalg *k; - -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { - if (strcmp(k->name, name) == 0) - return k; - } -- for (k = gss_kexalgs; k->name != NULL; k++) { -+ for (k = (FIPS_mode() ? NULL : gss_kexalgs); k->name != NULL; k++) { - if (strncmp(k->name, name, strlen(k->name)) == 0) - return k; - } - return NULL; @@ -175,7 +196,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { @@ -257,70 +127,6 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c ---- openssh-7.9p1/mac.c.fips 2019-03-11 17:06:37.614877975 +0100 -+++ openssh-7.9p1/mac.c 2019-03-11 17:06:37.621878041 +0100 -@@ -27,6 +27,8 @@ - - #include - -+#include -+ - #include - #include - #include -@@ -54,7 +56,7 @@ struct macalg { - int etm; /* Encrypt-then-MAC */ - }; - --static const struct macalg macs[] = { -+static const struct macalg all_macs[] = { - /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ - { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, - { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, -@@ -82,6 +84,24 @@ static const struct macalg macs[] = { - { NULL, 0, 0, 0, 0, 0, 0 } - }; - -+static const struct macalg fips_macs[] = { -+ /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ -+ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, -+#ifdef HAVE_EVP_SHA256 -+ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, -+ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, -+#endif -+ -+ /* Encrypt-then-MAC variants */ -+ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, -+#ifdef HAVE_EVP_SHA256 -+ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, -+ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, -+#endif -+ -+ { NULL, 0, 0, 0, 0, 0, 0 } -+}; -+ - /* Returns a list of supported MACs separated by the specified char. */ - char * - mac_alg_list(char sep) -@@ -90,7 +110,7 @@ mac_alg_list(char sep) - size_t nlen, rlen = 0; - const struct macalg *m; - -- for (m = macs; m->name != NULL; m++) { -+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(m->name); -@@ -129,7 +149,7 @@ mac_setup(struct sshmac *mac, char *name - { - const struct macalg *m; - -- for (m = macs; m->name != NULL; m++) { -+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { - if (strcmp(name, m->name) != 0) - continue; - if (mac != NULL) diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in --- openssh-7.9p1/Makefile.in.fips 2019-03-11 17:06:37.615877984 +0100 +++ openssh-7.9p1/Makefile.in 2019-03-11 17:06:37.621878041 +0100 diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch new file mode 100644 index 0000000..8a63501 --- /dev/null +++ b/openssh-8.0p1-crypto-policies.patch @@ -0,0 +1,210 @@ +diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 +--- openssh-8.0p1/ssh_config.5.crypto-policies 2019-05-13 14:04:01.999099570 +0200 ++++ openssh-8.0p1/ssh_config.5 2019-05-13 14:12:36.343923071 +0200 +@@ -445,12 +445,10 @@ 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 ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available ciphers may also be obtained using + .Qq ssh -Q cipher . +@@ -812,8 +810,10 @@ gss-nistp256-sha256-, + gss-curve25519-sha256- + .Ed + .Pp +-The default is +-.Dq gss-gex-sha1-,gss-group14-sha1- . ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that +@@ -1123,16 +1123,10 @@ If the specified value begins with a + .Sq - + character, then the specified methods (including wildcards) will be removed + from the default set instead of replacing them. +-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, +-diffie-hellman-group14-sha1 +-.Ed ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available key exchange algorithms may also be obtained using + .Qq ssh -Q kex . +@@ -1210,14 +1204,10 @@ The algorithms that contain + 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 ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available MAC algorithms may also be obtained using + .Qq ssh -Q mac . +@@ -1361,17 +1351,10 @@ If the specified value begins with a + .Sq - + character, then the specified key types (including wildcards) will be removed + from the default set instead of replacing them. +-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, +-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, +-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-.Ed ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available key types may also be obtained using + .Qq ssh -Q key . +diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 +--- openssh-8.0p1/sshd_config.5.crypto-policies 2019-05-13 14:12:41.226968863 +0200 ++++ openssh-8.0p1/sshd_config.5 2019-05-13 14:15:14.581406997 +0200 +@@ -490,12 +490,10 @@ 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 ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available ciphers may also be obtained using + .Qq ssh -Q cipher . +@@ -700,8 +698,10 @@ gss-nistp256-sha256-, + gss-curve25519-sha256- + .Ed + .Pp +-The default is +-.Dq gss-gex-sha1-,gss-group14-sha1- . ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication +@@ -792,17 +792,10 @@ environment variable. + .It Cm HostKeyAlgorithms + 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, +-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, +-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-.Ed ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available key types may also be obtained using + .Qq ssh -Q key . +@@ -960,14 +953,10 @@ ecdh-sha2-nistp384 + ecdh-sha2-nistp521 + .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,diffie-hellman-group14-sha1 +-.Ed ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available key exchange algorithms may also be obtained using + .Qq ssh -Q kex . +@@ -1090,14 +1079,10 @@ 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 ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available MAC algorithms may also be obtained using + .Qq ssh -Q mac . +@@ -1455,17 +1440,10 @@ If the specified value begins with a + .Sq - + character, then the specified key types (including wildcards) will be removed + from the default set instead of replacing them. +-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, +-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, +-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-.Ed ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++To see the defaults and how to modifuy this default, see manual page ++.Xr update-crypto-policies 8 . + .Pp + The list of available key types may also be obtained using + .Qq ssh -Q key . diff --git a/openssh-8.0p1-gsissh.patch b/openssh-8.0p1-gsissh.patch index e7c8c3a..d889a8f 100644 --- a/openssh-8.0p1-gsissh.patch +++ b/openssh-8.0p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c ---- openssh-8.0p1.orig/auth2.c 2019-05-03 17:45:02.084333024 +0200 -+++ openssh-8.0p1/auth2.c 2019-05-05 14:21:03.207471114 +0200 +--- openssh-8.0p1.orig/auth2.c 2019-05-20 08:24:38.155774971 +0200 ++++ openssh-8.0p1/auth2.c 2019-05-20 08:25:21.577323166 +0200 @@ -281,7 +281,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -102,8 +102,8 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-8.0p1.orig/auth2-gss.c openssh-8.0p1/auth2-gss.c ---- openssh-8.0p1.orig/auth2-gss.c 2019-05-03 17:45:02.006333854 +0200 -+++ openssh-8.0p1/auth2-gss.c 2019-05-05 13:31:35.509069506 +0200 +--- openssh-8.0p1.orig/auth2-gss.c 2019-05-20 08:24:38.068775876 +0200 ++++ openssh-8.0p1/auth2-gss.c 2019-05-20 08:25:21.578323156 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -298,8 +298,8 @@ diff -Nur openssh-8.0p1.orig/auth2-gss.c openssh-8.0p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c ---- openssh-8.0p1.orig/auth.c 2019-05-03 17:45:02.085333014 +0200 -+++ openssh-8.0p1/auth.c 2019-05-04 16:57:48.606935950 +0200 +--- openssh-8.0p1.orig/auth.c 2019-05-20 08:24:38.155774971 +0200 ++++ openssh-8.0p1/auth.c 2019-05-20 08:25:21.578323156 +0200 @@ -343,7 +343,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -331,8 +331,8 @@ diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-8.0p1.orig/auth.h openssh-8.0p1/auth.h ---- openssh-8.0p1.orig/auth.h 2019-05-03 17:45:02.085333014 +0200 -+++ openssh-8.0p1/auth.h 2019-05-04 16:57:48.606935950 +0200 +--- openssh-8.0p1.orig/auth.h 2019-05-20 08:24:38.156774960 +0200 ++++ openssh-8.0p1/auth.h 2019-05-20 08:25:21.578323156 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -343,8 +343,8 @@ diff -Nur openssh-8.0p1.orig/auth.h openssh-8.0p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c ---- openssh-8.0p1.orig/auth-pam.c 2019-05-03 17:45:01.961334333 +0200 -+++ openssh-8.0p1/auth-pam.c 2019-05-05 17:59:01.979771873 +0200 +--- openssh-8.0p1.orig/auth-pam.c 2019-05-20 08:24:38.017776406 +0200 ++++ openssh-8.0p1/auth-pam.c 2019-05-20 08:25:21.579323145 +0200 @@ -251,6 +251,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -506,8 +506,8 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-8.0p1.orig/auth-pam.h openssh-8.0p1/auth-pam.h ---- openssh-8.0p1.orig/auth-pam.h 2019-05-03 17:45:01.961334333 +0200 -+++ openssh-8.0p1/auth-pam.h 2019-05-04 16:57:48.607935939 +0200 +--- openssh-8.0p1.orig/auth-pam.h 2019-05-20 08:24:38.017776406 +0200 ++++ openssh-8.0p1/auth-pam.h 2019-05-20 08:25:21.579323145 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -516,8 +516,8 @@ diff -Nur openssh-8.0p1.orig/auth-pam.h openssh-8.0p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-8.0p1.orig/canohost.c openssh-8.0p1/canohost.c ---- openssh-8.0p1.orig/canohost.c 2019-05-03 17:45:02.006333854 +0200 -+++ openssh-8.0p1/canohost.c 2019-05-04 16:57:48.607935939 +0200 +--- openssh-8.0p1.orig/canohost.c 2019-05-20 08:24:38.068775876 +0200 ++++ openssh-8.0p1/canohost.c 2019-05-20 08:25:21.579323145 +0200 @@ -17,6 +17,7 @@ #include #include @@ -561,8 +561,8 @@ diff -Nur openssh-8.0p1.orig/canohost.c openssh-8.0p1/canohost.c + } +} diff -Nur openssh-8.0p1.orig/canohost.h openssh-8.0p1/canohost.h ---- openssh-8.0p1.orig/canohost.h 2019-05-03 17:45:02.006333854 +0200 -+++ openssh-8.0p1/canohost.h 2019-05-04 16:57:48.608935928 +0200 +--- openssh-8.0p1.orig/canohost.h 2019-05-20 08:24:38.068775876 +0200 ++++ openssh-8.0p1/canohost.h 2019-05-20 08:25:21.579323145 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -571,9 +571,9 @@ diff -Nur openssh-8.0p1.orig/canohost.h openssh-8.0p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac ---- openssh-8.0p1.orig/configure.ac 2019-05-03 17:45:02.071333163 +0200 -+++ openssh-8.0p1/configure.ac 2019-05-04 16:57:48.609935918 +0200 -@@ -4571,6 +4571,14 @@ +--- openssh-8.0p1.orig/configure.ac 2019-05-20 08:24:38.151775012 +0200 ++++ openssh-8.0p1/configure.ac 2019-05-20 08:25:21.580323135 +0200 +@@ -4572,6 +4572,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -588,7 +588,7 @@ diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac fi if test -n "${rpath_opt}" ; then LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" -@@ -4610,6 +4618,40 @@ +@@ -4611,6 +4619,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -630,8 +630,8 @@ diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c ---- openssh-8.0p1.orig/gss-genr.c 2019-05-03 17:45:02.008333833 +0200 -+++ openssh-8.0p1/gss-genr.c 2019-05-04 16:57:48.610935907 +0200 +--- openssh-8.0p1.orig/gss-genr.c 2019-05-20 08:24:38.070775855 +0200 ++++ openssh-8.0p1/gss-genr.c 2019-05-20 08:25:21.581323124 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -669,8 +669,8 @@ diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c return (ctx->major); } diff -Nur openssh-8.0p1.orig/gss-serv.c openssh-8.0p1/gss-serv.c ---- openssh-8.0p1.orig/gss-serv.c 2019-05-03 17:45:02.025333652 +0200 -+++ openssh-8.0p1/gss-serv.c 2019-05-04 20:13:35.891347677 +0200 +--- openssh-8.0p1.orig/gss-serv.c 2019-05-20 08:24:38.086775688 +0200 ++++ openssh-8.0p1/gss-serv.c 2019-05-20 08:25:21.581323124 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -953,7 +953,7 @@ diff -Nur openssh-8.0p1.orig/gss-serv.c openssh-8.0p1/gss-serv.c diff -Nur openssh-8.0p1.orig/gss-serv-gsi.c openssh-8.0p1/gss-serv-gsi.c --- openssh-8.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.0p1/gss-serv-gsi.c 2019-05-04 16:57:48.611935896 +0200 ++++ openssh-8.0p1/gss-serv-gsi.c 2019-05-20 08:25:21.582323114 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1284,8 +1284,8 @@ diff -Nur openssh-8.0p1.orig/gss-serv-gsi.c openssh-8.0p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-8.0p1.orig/gss-serv-krb5.c openssh-8.0p1/gss-serv-krb5.c ---- openssh-8.0p1.orig/gss-serv-krb5.c 2019-05-03 17:45:02.047333418 +0200 -+++ openssh-8.0p1/gss-serv-krb5.c 2019-05-04 17:55:04.987868146 +0200 +--- openssh-8.0p1.orig/gss-serv-krb5.c 2019-05-20 08:24:38.107775470 +0200 ++++ openssh-8.0p1/gss-serv-krb5.c 2019-05-20 08:25:21.582323114 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1340,8 +1340,8 @@ diff -Nur openssh-8.0p1.orig/gss-serv-krb5.c openssh-8.0p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c ---- openssh-8.0p1.orig/kexgsss.c 2019-05-03 17:45:02.011333801 +0200 -+++ openssh-8.0p1/kexgsss.c 2019-05-05 13:42:59.924759377 +0200 +--- openssh-8.0p1.orig/kexgsss.c 2019-05-20 08:24:38.072775834 +0200 ++++ openssh-8.0p1/kexgsss.c 2019-05-20 08:25:21.582323114 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1406,8 +1406,8 @@ diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff -Nur openssh-8.0p1.orig/Makefile.in openssh-8.0p1/Makefile.in ---- openssh-8.0p1.orig/Makefile.in 2019-05-03 17:45:02.098332875 +0200 -+++ openssh-8.0p1/Makefile.in 2019-05-04 16:57:48.613935875 +0200 +--- openssh-8.0p1.orig/Makefile.in 2019-05-20 08:24:38.168774835 +0200 ++++ openssh-8.0p1/Makefile.in 2019-05-20 08:25:21.583323104 +0200 @@ -125,6 +125,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1417,8 +1417,8 @@ diff -Nur openssh-8.0p1.orig/Makefile.in openssh-8.0p1/Makefile.in sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c ---- openssh-8.0p1.orig/misc.c 2019-05-03 17:45:01.962334322 +0200 -+++ openssh-8.0p1/misc.c 2019-05-04 16:57:48.614935864 +0200 +--- openssh-8.0p1.orig/misc.c 2019-05-20 08:24:38.020776375 +0200 ++++ openssh-8.0p1/misc.c 2019-05-20 08:25:21.583323104 +0200 @@ -313,11 +313,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1480,7 +1480,7 @@ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c * Port must be >=0 and <=65535. diff -Nur openssh-8.0p1.orig/misc.h openssh-8.0p1/misc.h --- openssh-8.0p1.orig/misc.h 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/misc.h 2019-05-04 16:57:48.614935864 +0200 ++++ openssh-8.0p1/misc.h 2019-05-20 08:25:21.583323104 +0200 @@ -87,6 +87,7 @@ void sock_set_v6only(int); @@ -1490,8 +1490,8 @@ diff -Nur openssh-8.0p1.orig/misc.h openssh-8.0p1/misc.h typedef struct arglist arglist; diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c ---- openssh-8.0p1.orig/monitor.c 2019-05-03 17:45:02.106332790 +0200 -+++ openssh-8.0p1/monitor.c 2019-05-04 18:32:50.066418064 +0200 +--- openssh-8.0p1.orig/monitor.c 2019-05-20 08:24:38.176774752 +0200 ++++ openssh-8.0p1/monitor.c 2019-05-20 08:25:21.584323093 +0200 @@ -154,6 +154,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1663,8 +1663,8 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c { gss_buffer_desc data; diff -Nur openssh-8.0p1.orig/monitor.h openssh-8.0p1/monitor.h ---- openssh-8.0p1.orig/monitor.h 2019-05-03 17:45:02.087332993 +0200 -+++ openssh-8.0p1/monitor.h 2019-05-04 18:34:50.027124629 +0200 +--- openssh-8.0p1.orig/monitor.h 2019-05-20 08:24:38.158774939 +0200 ++++ openssh-8.0p1/monitor.h 2019-05-20 08:25:21.584323093 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1677,8 +1677,8 @@ diff -Nur openssh-8.0p1.orig/monitor.h openssh-8.0p1/monitor.h struct ssh; diff -Nur openssh-8.0p1.orig/monitor_wrap.c openssh-8.0p1/monitor_wrap.c ---- openssh-8.0p1.orig/monitor_wrap.c 2019-05-03 17:45:02.107332780 +0200 -+++ openssh-8.0p1/monitor_wrap.c 2019-05-04 20:14:18.401891101 +0200 +--- openssh-8.0p1.orig/monitor_wrap.c 2019-05-20 08:24:38.176774752 +0200 ++++ openssh-8.0p1/monitor_wrap.c 2019-05-20 08:25:21.584323093 +0200 @@ -1061,6 +1061,94 @@ return (authenticated); } @@ -1775,8 +1775,8 @@ diff -Nur openssh-8.0p1.orig/monitor_wrap.c openssh-8.0p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h ---- openssh-8.0p1.orig/monitor_wrap.h 2019-05-03 17:45:02.093332929 +0200 -+++ openssh-8.0p1/monitor_wrap.h 2019-05-04 16:57:48.617935831 +0200 +--- openssh-8.0p1.orig/monitor_wrap.h 2019-05-20 08:24:38.164774877 +0200 ++++ openssh-8.0p1/monitor_wrap.h 2019-05-20 08:25:21.585323083 +0200 @@ -69,6 +69,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1789,8 +1789,8 @@ diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h #endif diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c ---- openssh-8.0p1.orig/readconf.c 2019-05-03 17:45:02.098332875 +0200 -+++ openssh-8.0p1/readconf.c 2019-05-04 16:57:48.618935821 +0200 +--- openssh-8.0p1.orig/readconf.c 2019-05-20 08:24:38.169774825 +0200 ++++ openssh-8.0p1/readconf.c 2019-05-20 08:25:21.586323072 +0200 @@ -2052,13 +2052,13 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1810,8 +1810,8 @@ diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c options->gss_renewal_rekey = 0; #ifdef GSSAPI diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h ---- openssh-8.0p1.orig/readconf.h 2019-05-03 17:45:02.013333780 +0200 -+++ openssh-8.0p1/readconf.h 2019-05-04 16:57:48.619935810 +0200 +--- openssh-8.0p1.orig/readconf.h 2019-05-20 08:24:38.074775813 +0200 ++++ openssh-8.0p1/readconf.h 2019-05-20 08:25:21.586323072 +0200 @@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1822,8 +1822,8 @@ diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c ---- openssh-8.0p1.orig/servconf.c 2019-05-03 17:45:02.108332769 +0200 -+++ openssh-8.0p1/servconf.c 2019-05-04 19:24:49.590820223 +0200 +--- openssh-8.0p1.orig/servconf.c 2019-05-20 08:24:38.177774742 +0200 ++++ openssh-8.0p1/servconf.c 2019-05-20 08:25:21.587323062 +0200 @@ -84,6 +84,7 @@ /* Portable-specific options */ @@ -1995,8 +1995,8 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h ---- openssh-8.0p1.orig/servconf.h 2019-05-03 17:45:02.059333290 +0200 -+++ openssh-8.0p1/servconf.h 2019-05-04 16:57:48.620935799 +0200 +--- openssh-8.0p1.orig/servconf.h 2019-05-20 08:24:38.119775345 +0200 ++++ openssh-8.0p1/servconf.h 2019-05-20 08:25:21.587323062 +0200 @@ -131,9 +131,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2019,8 +2019,8 @@ diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h int permit_tun; diff -Nur openssh-8.0p1.orig/ssh.1 openssh-8.0p1/ssh.1 ---- openssh-8.0p1.orig/ssh.1 2019-05-03 17:45:02.014333769 +0200 -+++ openssh-8.0p1/ssh.1 2019-05-04 16:57:48.621935788 +0200 +--- openssh-8.0p1.orig/ssh.1 2019-05-20 08:24:38.075775803 +0200 ++++ openssh-8.0p1/ssh.1 2019-05-20 08:25:21.587323062 +0200 @@ -1427,6 +1427,18 @@ on to new connections). .It Ev USER @@ -2041,8 +2041,8 @@ diff -Nur openssh-8.0p1.orig/ssh.1 openssh-8.0p1/ssh.1 .Pp Additionally, diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c ---- openssh-8.0p1.orig/ssh.c 2019-05-03 17:45:02.100332854 +0200 -+++ openssh-8.0p1/ssh.c 2019-05-04 16:57:48.622935778 +0200 +--- openssh-8.0p1.orig/ssh.c 2019-05-20 08:24:38.170774815 +0200 ++++ openssh-8.0p1/ssh.c 2019-05-20 08:25:21.588323052 +0200 @@ -543,6 +543,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2097,8 +2097,8 @@ diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config ---- openssh-8.0p1.orig/ssh_config 2019-05-03 17:45:02.015333759 +0200 -+++ openssh-8.0p1/ssh_config 2019-05-04 16:57:48.622935778 +0200 +--- openssh-8.0p1.orig/ssh_config 2019-05-20 08:24:38.076775793 +0200 ++++ openssh-8.0p1/ssh_config 2019-05-20 08:25:21.588323052 +0200 @@ -22,10 +22,10 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2115,8 +2115,8 @@ diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config # CheckHostIP yes # AddressFamily any diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 ---- openssh-8.0p1.orig/ssh_config.5 2019-05-03 17:45:02.076333110 +0200 -+++ openssh-8.0p1/ssh_config.5 2019-05-04 16:57:48.623935767 +0200 +--- openssh-8.0p1.orig/ssh_config.5 2019-05-20 08:24:38.145775075 +0200 ++++ openssh-8.0p1/ssh_config.5 2019-05-20 08:32:58.762570830 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2130,7 +2130,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -753,7 +759,7 @@ +@@ -751,7 +757,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2139,7 +2139,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -761,12 +767,12 @@ +@@ -759,12 +765,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2154,7 +2154,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -798,7 +804,7 @@ +@@ -796,7 +802,7 @@ the hostname entered on the command line will be passed untouched to the GSSAPI library. The default is @@ -2163,7 +2163,15 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIKexAlgorithms The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are -@@ -1270,7 +1276,7 @@ +@@ -814,7 +820,6 @@ + .Xr crypto-policies 7 . + To see the defaults and how to modifuy this default, see manual page + .Xr update-crypto-policies 8 . +-This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +@@ -1260,7 +1265,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2173,8 +2181,8 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c ---- openssh-8.0p1.orig/sshconnect2.c 2019-05-03 17:45:02.100332854 +0200 -+++ openssh-8.0p1/sshconnect2.c 2019-05-04 18:51:03.754633706 +0200 +--- openssh-8.0p1.orig/sshconnect2.c 2019-05-20 08:24:38.171774804 +0200 ++++ openssh-8.0p1/sshconnect2.c 2019-05-20 08:25:21.590323031 +0200 @@ -778,6 +778,11 @@ gss_OID mech = NULL; char *gss_host; @@ -2242,8 +2250,8 @@ diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || diff -Nur openssh-8.0p1.orig/sshd.8 openssh-8.0p1/sshd.8 ---- openssh-8.0p1.orig/sshd.8 2019-05-03 17:45:02.030333599 +0200 -+++ openssh-8.0p1/sshd.8 2019-05-04 16:57:48.625935745 +0200 +--- openssh-8.0p1.orig/sshd.8 2019-05-20 08:24:38.090775647 +0200 ++++ openssh-8.0p1/sshd.8 2019-05-20 08:25:21.590323031 +0200 @@ -788,6 +788,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2275,8 +2283,8 @@ diff -Nur openssh-8.0p1.orig/sshd.8 openssh-8.0p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-8.0p1.orig/sshd.c openssh-8.0p1/sshd.c ---- openssh-8.0p1.orig/sshd.c 2019-05-03 17:45:02.109332758 +0200 -+++ openssh-8.0p1/sshd.c 2019-05-04 16:57:48.625935745 +0200 +--- openssh-8.0p1.orig/sshd.c 2019-05-20 08:24:38.179774721 +0200 ++++ openssh-8.0p1/sshd.c 2019-05-20 08:25:21.590323031 +0200 @@ -2265,7 +2265,7 @@ #endif @@ -2287,8 +2295,8 @@ diff -Nur openssh-8.0p1.orig/sshd.c openssh-8.0p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-8.0p1.orig/sshd_config openssh-8.0p1/sshd_config ---- openssh-8.0p1.orig/sshd_config 2019-05-03 17:45:02.054333344 +0200 -+++ openssh-8.0p1/sshd_config 2019-05-04 16:57:48.625935745 +0200 +--- openssh-8.0p1.orig/sshd_config 2019-05-20 08:24:38.114775397 +0200 ++++ openssh-8.0p1/sshd_config 2019-05-20 08:25:21.591323020 +0200 @@ -84,10 +84,11 @@ #KerberosUseKuserok yes @@ -2315,9 +2323,9 @@ diff -Nur openssh-8.0p1.orig/sshd_config openssh-8.0p1/sshd_config #AllowTcpForwarding yes #GatewayPorts no diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 ---- openssh-8.0p1.orig/sshd_config.5 2019-05-03 17:45:02.060333280 +0200 -+++ openssh-8.0p1/sshd_config.5 2019-05-04 18:52:25.145757179 +0200 -@@ -644,15 +644,34 @@ +--- openssh-8.0p1.orig/sshd_config.5 2019-05-20 08:24:38.146775064 +0200 ++++ openssh-8.0p1/sshd_config.5 2019-05-20 08:32:15.212022217 +0200 +@@ -642,15 +642,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2353,7 +2361,7 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -663,7 +682,7 @@ +@@ -661,7 +680,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2363,14 +2371,14 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. @@ -702,7 +721,6 @@ - .Pp - The default is - .Dq gss-gex-sha1-,gss-group14-sha1- . + .Xr crypto-policies 7 . + To see the defaults and how to modifuy this default, see manual page + .Xr update-crypto-policies 8 . -This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a list of comma-separated patterns. -@@ -1674,6 +1692,12 @@ +@@ -1652,6 +1670,12 @@ as a non-root user. The default is .Cm no . @@ -2384,8 +2392,8 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h ---- openssh-8.0p1.orig/ssh-gss.h 2019-05-03 17:45:02.027333631 +0200 -+++ openssh-8.0p1/ssh-gss.h 2019-05-04 16:58:00.709805460 +0200 +--- openssh-8.0p1.orig/ssh-gss.h 2019-05-20 08:24:38.087775678 +0200 ++++ openssh-8.0p1/ssh-gss.h 2019-05-20 08:25:21.592323010 +0200 @@ -93,12 +93,14 @@ } ssh_gssapi_ccache; @@ -2423,7 +2431,7 @@ diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h const char *); diff -Nur openssh-8.0p1.orig/version.h openssh-8.0p1/version.h --- openssh-8.0p1.orig/version.h 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/version.h 2019-05-04 18:53:27.162089305 +0200 ++++ openssh-8.0p1/version.h 2019-05-20 08:25:21.592323010 +0200 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_8.0" diff --git a/openssh-8.0p1-openssl-evp.patch b/openssh-8.0p1-openssl-evp.patch new file mode 100644 index 0000000..ade0bbb --- /dev/null +++ b/openssh-8.0p1-openssl-evp.patch @@ -0,0 +1,720 @@ +From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +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 ++/* 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 **); + diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch new file mode 100644 index 0000000..1db95c3 --- /dev/null +++ b/openssh-8.0p1-openssl-kdf.patch @@ -0,0 +1,137 @@ +commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a +Author: Jakub Jelen +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 + #include ++# ifdef HAVE_EVP_KDF_CTX_NEW_ID ++# include ++# 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 + diff --git a/openssh-8.0p1-scp-tests.patch b/openssh-8.0p1-scp-tests.patch new file mode 100644 index 0000000..e0a63c4 --- /dev/null +++ b/openssh-8.0p1-scp-tests.patch @@ -0,0 +1,61 @@ +diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh +index 59f1ff63..dd48a482 100644 +--- a/regress/scp-ssh-wrapper.sh ++++ b/regress/scp-ssh-wrapper.sh +@@ -51,6 +51,18 @@ badserver_4) + echo "C755 2 file" + echo "X" + ;; ++badserver_5) ++ echo "D0555 0 " ++ echo "X" ++ ;; ++badserver_6) ++ echo "D0555 0 ." ++ echo "X" ++ ;; ++badserver_7) ++ echo "C0755 2 extrafile" ++ echo "X" ++ ;; + *) + set -- $arg + shift +diff --git a/regress/scp.sh b/regress/scp.sh +index 57cc7706..104c89e1 100644 +--- a/regress/scp.sh ++++ b/regress/scp.sh +@@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp + scpclean() { + rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} + mkdir ${DIR} ${DIR2} ++ chmod 755 ${DIR} ${DIR2} + } + + verbose "$tid: simple copy local file to local file" +@@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then + $SUDO rm ${DIR2}/copy + fi + +-for i in 0 1 2 3 4; do ++for i in 0 1 2 3 4 5 6 7; do + verbose "$tid: disallow bad server #$i" + SCPTESTMODE=badserver_$i + export DIR SCPTESTMODE +@@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do + scpclean + $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null + [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" ++ ++ scpclean ++ $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null ++ [ ! -w ${DIR2} ] && fail "allows target root attribute change" ++ ++ scpclean ++ $SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null ++ [ -e ${DIR2}/extrafile ] && fail "allows extranous object creation" ++ rm -f ${DIR2}/extrafile + done + + verbose "$tid: detect non-directory target" + From 7ea48e01a09f1c61b754b10fcc68cd6a611d2e12 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 28 May 2019 15:41:32 +0200 Subject: [PATCH 075/146] Based on openssh-8.0p1-3.fc30 Change GSSAPITrustDNS default to no --- gsi-openssh.spec | 9 +++++---- openssh-7.9p1-updated-cached-pw.patch | 23 ----------------------- openssh-8.0p1-gsissh.patch | 22 ++++------------------ openssh-8.0p1-pkcs11-uri.patch | 14 ++++++++------ 4 files changed, 17 insertions(+), 51 deletions(-) delete mode 100644 openssh-7.9p1-updated-cached-pw.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 5e17ca0..756fe74 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.0p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -150,8 +150,6 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # - do not return 0 if the write fails (full disk) # - shellcheck reports (upstream #2902) Patch958: openssh-7.9p1-ssh-copy-id.patch -# Update cached passwd structure after PAM authentication (#1674541) -Patch960: openssh-7.9p1-updated-cached-pw.patch # Verify the SCP vulnerabilities are fixed in the package testsuite # https://bugzilla.mindrot.org/show_bug.cgi?id=3007 Patch961: openssh-8.0p1-scp-tests.patch @@ -307,7 +305,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch951 -p1 -b .pkcs11-uri %patch953 -p1 -b .scp-ipv6 %patch958 -p1 -b .ssh-copy-id -%patch960 -p1 -b .update-pw %patch961 -p1 -b .scp-tests %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp @@ -523,6 +520,10 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue May 28 2019 Mattias Ellert - 8.0p1-3 +- Based on openssh-8.0p1-3.fc30 +- Change GSSAPITrustDNS default to no + * Mon May 20 2019 Mattias Ellert - 8.0p1-2 - Based on openssh-8.0p1-2.fc30 diff --git a/openssh-7.9p1-updated-cached-pw.patch b/openssh-7.9p1-updated-cached-pw.patch deleted file mode 100644 index 398f6bd..0000000 --- a/openssh-7.9p1-updated-cached-pw.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.update-pw 2019-03-04 14:10:57.287054645 +0100 -+++ openssh-7.4p1/session.c 2019-03-04 14:12:39.259997218 +0100 -@@ -1522,9 +1522,18 @@ do_child(Session *s, const char *command - extern char **environ; - char **env, *argv[ARGV_MAX], remote_id[512]; - const char *shell, *shell0; -- struct passwd *pw = s->pw; -+ struct passwd *pw = NULL; - int r = 0; - -+ /* Update the users passwd structure after successful login */ -+ pw = getpwuid(s->pw->pw_uid); -+ if (pw != NULL) { -+ free(s->pw); -+ s->pw = pw; -+ } else { -+ pw = s->pw; -+ } -+ - sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - - /* remove hostkey from the child's memory */ diff --git a/openssh-8.0p1-gsissh.patch b/openssh-8.0p1-gsissh.patch index d889a8f..799a8f0 100644 --- a/openssh-8.0p1-gsissh.patch +++ b/openssh-8.0p1-gsissh.patch @@ -1791,7 +1791,7 @@ diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c --- openssh-8.0p1.orig/readconf.c 2019-05-20 08:24:38.169774825 +0200 +++ openssh-8.0p1/readconf.c 2019-05-20 08:25:21.586323072 +0200 -@@ -2052,13 +2052,13 @@ +@@ -2052,11 +2052,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1804,11 +1804,8 @@ diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c - options->gss_deleg_creds = 0; + options->gss_deleg_creds = 1; if (options->gss_trust_dns == -1) -- options->gss_trust_dns = 0; -+ options->gss_trust_dns = 1; + options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) - options->gss_renewal_rekey = 0; - #ifdef GSSAPI diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h --- openssh-8.0p1.orig/readconf.h 2019-05-20 08:24:38.074775813 +0200 +++ openssh-8.0p1/readconf.h 2019-05-20 08:25:21.586323072 +0200 @@ -2099,21 +2096,19 @@ diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config --- openssh-8.0p1.orig/ssh_config 2019-05-20 08:24:38.076775793 +0200 +++ openssh-8.0p1/ssh_config 2019-05-20 08:25:21.588323052 +0200 -@@ -22,10 +22,10 @@ +@@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes # HostbasedAuthentication no -# GSSAPIAuthentication no -# GSSAPIDelegateCredentials no -# GSSAPIKeyExchange no --# GSSAPITrustDNS no +# GSSAPIAuthentication yes +# GSSAPIDelegateCredentials yes +# GSSAPIKeyExchange yes -+# GSSAPITrustDNS yes + # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes - # AddressFamily any diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 --- openssh-8.0p1.orig/ssh_config.5 2019-05-20 08:24:38.145775075 +0200 +++ openssh-8.0p1/ssh_config.5 2019-05-20 08:32:58.762570830 +0200 @@ -2154,15 +2149,6 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -796,7 +802,7 @@ - the hostname entered on the - command line will be passed untouched to the GSSAPI library. - The default is --.Dq no . -+.Dq yes . - .It Cm GSSAPIKexAlgorithms - The list of key exchange algorithms that are offered for GSSAPI - key exchange. Possible values are @@ -814,7 +820,6 @@ .Xr crypto-policies 7 . To see the defaults and how to modifuy this default, see manual page diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 9618863..65a94ca 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -2111,12 +2111,13 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -729,18 +863,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -730,19 +863,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2211,12 +2212,13 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -850,18 +987,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -850,19 +987,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); From 15b86ea960b32d0cd1ca29530e75f029669881f8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 19 Jun 2019 10:17:38 +0200 Subject: [PATCH 076/146] Based on openssh-8.0p1-4.fc30 --- gsi-openssh.spec | 11 ++++- openssh-7.5p1-sandbox.patch | 38 ++++++++++++++++ openssh-8.0p1-agent-certs-sha2.patch | 31 +++++++++++++ openssh-8.0p1-openssl-pem.patch | 67 +++++++++++++++++++++++++++ openssh-8.0p1-pkcs11-uri.patch | 68 +++++++++++++++++++++++++++- 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 openssh-8.0p1-agent-certs-sha2.patch create mode 100644 openssh-8.0p1-openssl-pem.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 756fe74..56578c1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.0p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -159,6 +159,10 @@ Patch962: openssh-8.0p1-crypto-policies.patch Patch963: openssh-8.0p1-openssl-evp.patch # Use OpenSSL KDF (#1631761) Patch964: openssh-8.0p1-openssl-kdf.patch +# Use new OpenSSL for PEM export to avoid MD5 dependency (#1712436) +Patch965: openssh-8.0p1-openssl-pem.patch +# Properly encode SHA2 certificate types in ssh-agent +Patch966: openssh-8.0p1-agent-certs-sha2.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -309,6 +313,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp %patch964 -p1 -b .openssl-kdf +%patch965 -p1 -b .openssl-pem +%patch966 -p1 -b .agent-cert-sha2 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -520,6 +526,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Jun 19 2019 Mattias Ellert - 8.0p1-4 +- Based on openssh-8.0p1-4.fc30 + * Tue May 28 2019 Mattias Ellert - 8.0p1-3 - Based on openssh-8.0p1-3.fc30 - Change GSSAPITrustDNS default to no diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 85a4b0f..7190813 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -106,3 +106,41 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se #ifdef __NR_getrandom SC_ALLOW(__NR_getrandom), #endif + + +From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001 +From: Harald Freudenberger +Date: Fri, 24 May 2019 10:11:15 +0200 +Subject: [PATCH] allow s390 specific ioctl for ecc hardware support + +Adding another s390 specific ioctl to be able to support ECC hardware acceleration +to the sandbox seccomp filter rules. + +Now the ibmca openssl engine provides elliptic curve cryptography support with the +help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt +device driver and so there is a need to enable this on the openssl sandbox. + +Code is s390 specific and has been tested, verified and reviewed. + +Please note that I am also the originator of the previous changes in that area. +I posted these changes to Eduardo and he forwarded the patches to the openssl +community. + +Signed-off-by: Harald Freudenberger +Reviewed-by: Joerg Schmidbauer +--- + sandbox-seccomp-filter.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 5edbc6946..56eb9317f 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = { + SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), + /* Allow ioctls for EP11 crypto card on s390 */ + SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), ++ SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB), + #endif + #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) + /* diff --git a/openssh-8.0p1-agent-certs-sha2.patch b/openssh-8.0p1-agent-certs-sha2.patch new file mode 100644 index 0000000..b9888d9 --- /dev/null +++ b/openssh-8.0p1-agent-certs-sha2.patch @@ -0,0 +1,31 @@ +From 2317ce4b0ed7d8c4b0c684e2d47bff5006bd1178 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Fri, 14 Jun 2019 03:51:47 +0000 +Subject: [PATCH] upstream: process agent requests for RSA certificate private + keys using + +correct signature algorithm when requested. Patch from Jakub Jelen in bz3016 +ok dtucker markus + +OpenBSD-Commit-ID: 61f86efbeb4a1857a3e91298c1ccc6cf49b79624 +--- + ssh-agent.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ssh-agent.c b/ssh-agent.c +index 034f31387..4669b679c 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -269,6 +269,11 @@ agent_decode_alg(struct sshkey *key, u_int flags) + return "rsa-sha2-256"; + else if (flags & SSH_AGENT_RSA_SHA2_512) + return "rsa-sha2-512"; ++ } else if (key->type == KEY_RSA_CERT) { ++ if (flags & SSH_AGENT_RSA_SHA2_256) ++ return "rsa-sha2-256-cert-v01@openssh.com"; ++ else if (flags & SSH_AGENT_RSA_SHA2_512) ++ return "rsa-sha2-512-cert-v01@openssh.com"; + } + return NULL; + } + diff --git a/openssh-8.0p1-openssl-pem.patch b/openssh-8.0p1-openssl-pem.patch new file mode 100644 index 0000000..28becd0 --- /dev/null +++ b/openssh-8.0p1-openssl-pem.patch @@ -0,0 +1,67 @@ +commit 2fe812887139ce32eeca52f9a0c141bdc7c4c8af +Author: Jakub Jelen +Date: Wed May 22 17:25:22 2019 +0200 + + New PEM export format withou MD5 + +diff --git a/sshkey.c b/sshkey.c +index b95ed0b1..1a271512 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -3805,26 +3805,28 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, + const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; + char *bptr; + BIO *bio = NULL; ++ EVP_PKEY *pkey = NULL; + + if (len > 0 && len <= 4) + return SSH_ERR_PASSPHRASE_TOO_SHORT; + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return SSH_ERR_ALLOC_FAIL; ++ if ((pkey = EVP_PKEY_new()) == NULL) { ++ BIO_free(bio); ++ return SSH_ERR_ALLOC_FAIL; ++ } + + switch (key->type) { + case KEY_DSA: +- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, +- cipher, passphrase, len, NULL, NULL); ++ success = EVP_PKEY_set1_DSA(pkey, key->dsa); + break; + #ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: +- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, +- cipher, passphrase, len, NULL, NULL); ++ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); + break; + #endif + case KEY_RSA: +- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, +- cipher, passphrase, len, NULL, NULL); ++ success = EVP_PKEY_set1_RSA(pkey, key->rsa); + break; + default: + success = 0; +@@ -3834,6 +3836,12 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ++ success = PEM_write_bio_PrivateKey(bio, pkey, ++ cipher, passphrase, len, NULL, NULL); ++ if (success == 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; +@@ -3842,6 +3850,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, + goto out; + r = 0; + out: ++ EVP_PKEY_free(pkey); + BIO_free(bio); + return r; + } + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 65a94ca..41b138a 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -2466,7 +2466,7 @@ index 70f06bff..59332945 100644 - - if (providerp == NULL) + char *provider_module = NULL; -+ struct pkcs11_module *m; ++ struct pkcs11_module *m = NULL; + + /* if no provider specified, fallback to p11-kit */ + if (uri->module_path == NULL) { @@ -3068,3 +3068,69 @@ index 41262963..a211034e 100644 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. + +commit 1efe98998408593861fdcd4da392dd10820f0fde +Author: Jakub Jelen +Date: Wed Jun 12 14:30:30 2019 +0200 + + Allow to specify the pin also for the ssh-add + +diff --git a/ssh-add.c b/ssh-add.c +index f039e00e..adc4e5c9 100644 +--- a/ssh-add.c ++++ b/ssh-add.c +@@ -190,20 +190,28 @@ delete_all(int agent_fd, int qflag) + } + + #ifdef ENABLE_PKCS11 +-static int update_card(int, int, const char *, int); ++static int update_card(int, int, const char *, int, char *); + + int + update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) + { ++ char *pin = NULL; + struct pkcs11_uri *uri; + + /* dry-run parse to make sure the URI is valid and to report errors */ + uri = pkcs11_uri_init(); + if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) + fatal("Failed to parse PKCS#11 URI"); ++ if (uri->pin != NULL) { ++ pin = strdup(uri->pin); ++ if (pin == NULL) { ++ fatal("Failed to dupplicate string"); ++ } ++ /* pin is freed in the update_card() */ ++ } + pkcs11_uri_cleanup(uri); + +- return update_card(agent_fd, adding, pkcs11_uri, qflag); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); + } + #endif + +@@ -409,12 +417,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) + } + + static int +-update_card(int agent_fd, int add, const char *id, int qflag) ++update_card(int agent_fd, int add, const char *id, int qflag, char *pin) + { +- char *pin = NULL; + int r, ret = -1; + +- if (add) { ++ if (add && pin == NULL) { + if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", + RP_ALLOW_STDIN)) == NULL) + return -1; +@@ -734,7 +741,7 @@ main(int argc, char **argv) + } + if (pkcs11provider != NULL) { + if (update_card(agent_fd, !deleting, pkcs11provider, +- qflag) == -1) ++ qflag, NULL) == -1) + ret = 1; + goto done; + } From db99f0a0e6ed16721cfc70cf1c9c0873ebf7102e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jul 2019 07:50:56 +0000 Subject: [PATCH 077/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 56578c1..6c599a1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -526,6 +526,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Jul 25 2019 Fedora Release Engineering - 8.0p1-4.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + * Wed Jun 19 2019 Mattias Ellert - 8.0p1-4 - Based on openssh-8.0p1-4.fc30 From f67408c45e88400ced1f89de1f87d28bdd84c412 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 7 Aug 2019 21:57:57 +0200 Subject: [PATCH 078/146] Based on openssh-8.0p1-5.fc30 --- gsi-openssh.spec | 10 +- openssh-8.0p1-crypto-policies.patch | 22 +- openssh-8.0p1-gsissh.patch | 6 +- openssh-8.0p1-openssl-pem.patch | 301 ++++++++++++++++++++++++++-- 4 files changed, 299 insertions(+), 40 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 6c599a1..b359cde 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,12 +31,12 @@ %global ldap 1 %global openssh_ver 8.0p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -170,7 +170,6 @@ Patch98: openssh-8.0p1-gsissh.patch License: BSD Requires: /sbin/nologin -Obsoletes: %{name}-clients-fips, %{name}-server-fips %if %{ldap} BuildRequires: openldap-devel @@ -483,7 +482,7 @@ getent passwd sshd >/dev/null || \ %files %license LICENCE -%doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO +%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli %attr(0755,root,root) %{_bindir}/gsissh-keygen @@ -526,6 +525,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Aug 02 2019 Mattias Ellert - 8.0p1-5 +- Based on openssh-8.0p1-5.fc30 + * Thu Jul 25 2019 Fedora Release Engineering - 8.0p1-4.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 8a63501..ffd4bae 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -13,7 +13,7 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available ciphers may also be obtained using @@ -26,7 +26,7 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -.Dq gss-gex-sha1-,gss-group14-sha1- . +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . This option only applies to protocol version 2 connections using GSSAPI. .It Cm HashKnownHosts @@ -47,7 +47,7 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available key exchange algorithms may also be obtained using @@ -66,7 +66,7 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available MAC algorithms may also be obtained using @@ -88,7 +88,7 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available key types may also be obtained using @@ -108,7 +108,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available ciphers may also be obtained using @@ -121,7 +121,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Dq gss-gex-sha1-,gss-group14-sha1- . +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedKeyTypes @@ -143,7 +143,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available key types may also be obtained using @@ -162,7 +162,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available key exchange algorithms may also be obtained using @@ -181,7 +181,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available MAC algorithms may also be obtained using @@ -203,7 +203,7 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -.Ed +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modifuy this default, see manual page ++To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . .Pp The list of available key types may also be obtained using diff --git a/openssh-8.0p1-gsissh.patch b/openssh-8.0p1-gsissh.patch index 799a8f0..9990164 100644 --- a/openssh-8.0p1-gsissh.patch +++ b/openssh-8.0p1-gsissh.patch @@ -1366,7 +1366,7 @@ diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { -+ kex_gss_send_error(ctxt, ssh); ++ kex_gss_send_error(ctxt, ssh); if (send_tok.length > 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || @@ -2151,7 +2151,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .Dq yes @@ -814,7 +820,6 @@ .Xr crypto-policies 7 . - To see the defaults and how to modifuy this default, see manual page + To see the defaults and how to modify this default, see manual page .Xr update-crypto-policies 8 . -This option only applies to protocol version 2 connections using GSSAPI. .It Cm HashKnownHosts @@ -2358,7 +2358,7 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 a client authenticates against. @@ -702,7 +721,6 @@ .Xr crypto-policies 7 . - To see the defaults and how to modifuy this default, see manual page + To see the defaults and how to modify this default, see manual page .Xr update-crypto-policies 8 . -This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedKeyTypes diff --git a/openssh-8.0p1-openssl-pem.patch b/openssh-8.0p1-openssl-pem.patch index 28becd0..7e4fa81 100644 --- a/openssh-8.0p1-openssl-pem.patch +++ b/openssh-8.0p1-openssl-pem.patch @@ -1,14 +1,176 @@ -commit 2fe812887139ce32eeca52f9a0c141bdc7c4c8af -Author: Jakub Jelen -Date: Wed May 22 17:25:22 2019 +0200 +From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Mon, 15 Jul 2019 13:16:29 +0000 +Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of - New PEM export format withou MD5 +private keys, enabled via "ssh-keygen -m PKCS8" on operations that save +private keys to disk. +The OpenSSH native key format remains the default, but PKCS8 is a +superior format to PEM if interoperability with non-OpenSSH software +is required, as it may use a less terrible KDF (IIRC PEM uses a single +round of MD5 as a KDF). + +adapted from patch by Jakub Jelen via bz3013; ok markus + +OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1 +--- + authfile.c | 6 ++-- + ssh-keygen.1 | 9 +++--- + ssh-keygen.c | 25 +++++++++-------- + sshkey.c | 78 +++++++++++++++++++++++++++++++++++++--------------- + sshkey.h | 11 ++++++-- + 5 files changed, 87 insertions(+), 42 deletions(-) + +diff --git a/authfile.c b/authfile.c +index 2166c1689..851c1a8a1 100644 +--- a/authfile.c ++++ b/authfile.c +@@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) + int + sshkey_save_private(struct sshkey *key, const char *filename, + const char *passphrase, const char *comment, +- int force_new_format, const char *new_format_cipher, int new_format_rounds) ++ int format, const char *openssh_format_cipher, int openssh_format_rounds) + { + struct sshbuf *keyblob = NULL; + int r; +@@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename, + if ((keyblob = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, +- force_new_format, new_format_cipher, new_format_rounds)) != 0) ++ format, openssh_format_cipher, openssh_format_rounds)) != 0) + goto out; + if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) + goto out; +diff --git a/ssh-keygen.1 b/ssh-keygen.1 +index f42127c60..8184a1797 100644 +--- a/ssh-keygen.1 ++++ b/ssh-keygen.1 +@@ -419,11 +419,12 @@ The supported key formats are: + .Dq RFC4716 + (RFC 4716/SSH2 public or private key), + .Dq PKCS8 +-(PEM PKCS8 public key) ++(PKCS8 public or private key) + or + .Dq PEM + (PEM public key). +-The default conversion format is ++By default OpenSSH will write newly-generated private keys in its own ++format, but when converting public keys for export the default format is + .Dq RFC4716 . + Setting a format of + .Dq PEM +diff --git a/ssh-keygen.c b/ssh-keygen.c +index b019a02ff..5dcad1f61 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -147,11 +147,11 @@ static char *key_type_name = NULL; + /* Load key from this PKCS#11 provider */ + static char *pkcs11provider = NULL; + +-/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ +-static int use_new_format = 1; ++/* Format for writing private keys */ ++static int private_key_format = SSHKEY_PRIVATE_OPENSSH; + + /* Cipher for new-format private keys */ +-static char *new_format_cipher = NULL; ++static char *openssh_format_cipher = NULL; + + /* + * Number of KDF rounds to derive new format keys / +@@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw) + snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, + hostname); + if ((r = sshkey_save_private(private, prv_tmp, "", +- comment, use_new_format, new_format_cipher, rounds)) != 0) { ++ comment, private_key_format, openssh_format_cipher, ++ rounds)) != 0) { + error("Saving key \"%s\" failed: %s", + prv_tmp, ssh_err(r)); + goto failnext; +@@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw) + + /* Save the file using the new passphrase. */ + if ((r = sshkey_save_private(private, identity_file, passphrase1, +- comment, use_new_format, new_format_cipher, rounds)) != 0) { ++ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { + error("Saving key \"%s\" failed: %s.", + identity_file, ssh_err(r)); + explicit_bzero(passphrase1, strlen(passphrase1)); +@@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) + } + + if (private->type != KEY_ED25519 && private->type != KEY_XMSS && +- !use_new_format) { ++ private_key_format != SSHKEY_PRIVATE_OPENSSH) { + error("Comments are only supported for keys stored in " + "the new format (-o)."); + explicit_bzero(passphrase, strlen(passphrase)); +@@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment) + + /* Save the file using the new passphrase. */ + if ((r = sshkey_save_private(private, identity_file, passphrase, +- new_comment, use_new_format, new_format_cipher, rounds)) != 0) { ++ new_comment, private_key_format, openssh_format_cipher, ++ rounds)) != 0) { + error("Saving key \"%s\" failed: %s", + identity_file, ssh_err(r)); + explicit_bzero(passphrase, strlen(passphrase)); +@@ -2525,11 +2527,12 @@ main(int argc, char **argv) + } + if (strcasecmp(optarg, "PKCS8") == 0) { + convert_format = FMT_PKCS8; ++ private_key_format = SSHKEY_PRIVATE_PKCS8; + break; + } + if (strcasecmp(optarg, "PEM") == 0) { + convert_format = FMT_PEM; +- use_new_format = 0; ++ private_key_format = SSHKEY_PRIVATE_PEM; + break; + } + fatal("Unsupported conversion format \"%s\"", optarg); +@@ -2567,7 +2570,7 @@ main(int argc, char **argv) + add_cert_option(optarg); + break; + case 'Z': +- new_format_cipher = optarg; ++ openssh_format_cipher = optarg; + break; + case 'C': + identity_comment = optarg; +@@ -2912,7 +2915,7 @@ main(int argc, char **argv) + + /* Save the key with the given passphrase and comment. */ + if ((r = sshkey_save_private(private, identity_file, passphrase1, +- comment, use_new_format, new_format_cipher, rounds)) != 0) { ++ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { + error("Saving key \"%s\" failed: %s", + identity_file, ssh_err(r)); + explicit_bzero(passphrase1, strlen(passphrase1)); diff --git a/sshkey.c b/sshkey.c -index b95ed0b1..1a271512 100644 +index 6b5ff0485..a0cea9257 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -3805,26 +3805,28 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, +@@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, + + + #ifdef WITH_OPENSSL +-/* convert SSH v2 key in OpenSSL PEM format */ ++/* convert SSH v2 key to PEM or PKCS#8 format */ + static int +-sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, +- const char *_passphrase, const char *comment) ++sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob, ++ int format, const char *_passphrase, const char *comment) + { + int success, r; + int blen, len = strlen(_passphrase); +@@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; char *bptr; BIO *bio = NULL; @@ -16,47 +178,68 @@ index b95ed0b1..1a271512 100644 if (len > 0 && len <= 4) return SSH_ERR_PASSPHRASE_TOO_SHORT; - if ((bio = BIO_new(BIO_s_mem())) == NULL) - return SSH_ERR_ALLOC_FAIL; -+ if ((pkey = EVP_PKEY_new()) == NULL) { -+ BIO_free(bio); -+ return SSH_ERR_ALLOC_FAIL; -+ } +- if ((bio = BIO_new(BIO_s_mem())) == NULL) +- return SSH_ERR_ALLOC_FAIL; ++ if ((bio = BIO_new(BIO_s_mem())) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } switch (key->type) { case KEY_DSA: - success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, - cipher, passphrase, len, NULL, NULL); -+ success = EVP_PKEY_set1_DSA(pkey, key->dsa); ++ if (format == SSHKEY_PRIVATE_PEM) { ++ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, ++ cipher, passphrase, len, NULL, NULL); ++ } else { ++ success = EVP_PKEY_set1_DSA(pkey, key->dsa); ++ } break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: - success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, - cipher, passphrase, len, NULL, NULL); -+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); ++ if (format == SSHKEY_PRIVATE_PEM) { ++ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, ++ cipher, passphrase, len, NULL, NULL); ++ } else { ++ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); ++ } break; #endif case KEY_RSA: - success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, - cipher, passphrase, len, NULL, NULL); -+ success = EVP_PKEY_set1_RSA(pkey, key->rsa); ++ if (format == SSHKEY_PRIVATE_PEM) { ++ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, ++ cipher, passphrase, len, NULL, NULL); ++ } else { ++ success = EVP_PKEY_set1_RSA(pkey, key->rsa); ++ } break; default: success = 0; -@@ -3834,6 +3836,12 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, +@@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -+ success = PEM_write_bio_PrivateKey(bio, pkey, -+ cipher, passphrase, len, NULL, NULL); -+ if (success == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; ++ if (format == SSHKEY_PRIVATE_PKCS8) { ++ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher, ++ passphrase, len, NULL, NULL)) == 0) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + } if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { r = SSH_ERR_INTERNAL_ERROR; goto out; -@@ -3842,6 +3850,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, +@@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, goto out; r = 0; out: @@ -64,4 +247,78 @@ index b95ed0b1..1a271512 100644 BIO_free(bio); return r; } +@@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, + int + sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, + const char *passphrase, const char *comment, +- int force_new_format, const char *new_format_cipher, int new_format_rounds) ++ int format, const char *openssh_format_cipher, int openssh_format_rounds) + { + switch (key->type) { + #ifdef WITH_OPENSSL + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: +- if (force_new_format) { +- return sshkey_private_to_blob2(key, blob, passphrase, +- comment, new_format_cipher, new_format_rounds); +- } +- return sshkey_private_pem_to_blob(key, blob, +- passphrase, comment); ++ break; /* see below */ + #endif /* WITH_OPENSSL */ + case KEY_ED25519: + #ifdef WITH_XMSS + case KEY_XMSS: + #endif /* WITH_XMSS */ + return sshkey_private_to_blob2(key, blob, passphrase, +- comment, new_format_cipher, new_format_rounds); ++ comment, openssh_format_cipher, openssh_format_rounds); + default: + return SSH_ERR_KEY_TYPE_UNKNOWN; + } ++ ++#ifdef WITH_OPENSSL ++ switch (format) { ++ case SSHKEY_PRIVATE_OPENSSH: ++ return sshkey_private_to_blob2(key, blob, passphrase, ++ comment, openssh_format_cipher, openssh_format_rounds); ++ case SSHKEY_PRIVATE_PEM: ++ case SSHKEY_PRIVATE_PKCS8: ++ return sshkey_private_to_blob_pem_pkcs8(key, blob, ++ format, passphrase, comment); ++ default: ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++#endif /* WITH_OPENSSL */ + } + + +diff --git a/sshkey.h b/sshkey.h +index 41d159a1b..d30a69cc9 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -88,6 +88,13 @@ enum sshkey_serialize_rep { + SSHKEY_SERIALIZE_INFO = 254, + }; + ++/* Private key disk formats */ ++enum sshkey_private_format { ++ SSHKEY_PRIVATE_OPENSSH = 0, ++ SSHKEY_PRIVATE_PEM = 1, ++ SSHKEY_PRIVATE_PKCS8 = 2, ++}; ++ + /* key is stored in external hardware */ + #define SSHKEY_FLAG_EXT 0x0001 + +@@ -221,7 +228,7 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); + /* private key file format parsing and serialisation */ + int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, + const char *passphrase, const char *comment, +- int force_new_format, const char *new_format_cipher, int new_format_rounds); ++ int format, const char *openssh_format_cipher, int openssh_format_rounds); + int sshkey_parse_private_fileblob(struct sshbuf *buffer, + const char *passphrase, struct sshkey **keyp, char **commentp); + int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, From abde90a9cb00b23708308b23d023a51dee96f187 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 8 Aug 2019 11:24:52 +0200 Subject: [PATCH 079/146] Based on openssh-8.0p1-8.fc31 --- gsi-openssh.spec | 8 ++++---- gsisshd.service | 3 ++- gsisshd@.service | 3 ++- openssh-6.9p1-permit-root-login.patch | 12 ------------ 4 files changed, 8 insertions(+), 18 deletions(-) delete mode 100644 openssh-6.9p1-permit-root-login.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index b359cde..3a0ffa8 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.0p1 -%global openssh_rel 5 +%global openssh_rel 6 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -130,8 +130,6 @@ Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch 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 -# Restore compatible default (#89216) -Patch929: openssh-6.9p1-permit-root-login.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch # Move MAX_DISPLAYS to a configuration option (#1341302) @@ -299,7 +297,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch802 -p1 -b .GSSAPIEnablek5users %patch922 -p1 -b .sshdt %patch926 -p1 -b .sftp-force-mode -%patch929 -p1 -b .root-login %patch939 -p1 -b .s390-dev %patch944 -p1 -b .x11max %patch948 -p1 -b .systemd @@ -525,6 +522,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Aug 08 2019 Mattias Ellert - 8.0p1-6 +- Based on openssh-8.0p1-8.fc31 + * Fri Aug 02 2019 Mattias Ellert - 8.0p1-5 - Based on openssh-8.0p1-5.fc30 diff --git a/gsisshd.service b/gsisshd.service index bfa96b5..56e6094 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -7,8 +7,9 @@ Wants=gsisshd-keygen.target [Service] Type=notify EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config +EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd -D $OPTIONS $CRYPTO_POLICY +ExecStart=/usr/sbin/gsisshd -D $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/gsisshd@.service b/gsisshd@.service index 3bbdd78..284a914 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -6,6 +6,7 @@ After=gsisshd-keygen.target [Service] EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config +EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $CRYPTO_POLICY +ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN StandardInput=socket diff --git a/openssh-6.9p1-permit-root-login.patch b/openssh-6.9p1-permit-root-login.patch deleted file mode 100644 index 6b4c4da..0000000 --- a/openssh-6.9p1-permit-root-login.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-7.0p1/sshd_config.root-login openssh-7.0p1/sshd_config ---- openssh-7.0p1/sshd_config.root-login 2015-08-12 11:29:12.919269245 +0200 -+++ openssh-7.0p1/sshd_config 2015-08-12 11:31:03.653096466 +0200 -@@ -46,7 +46,7 @@ SyslogFacility AUTHPRIV - # Authentication: - - #LoginGraceTime 2m --#PermitRootLogin prohibit-password -+PermitRootLogin yes - #StrictModes yes - #MaxAuthTries 6 - #MaxSessions 10 From 03327bb7c388de7f0acb56e36681d703d1b27c0c Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 21 Oct 2019 10:23:32 +0200 Subject: [PATCH 080/146] Based on openssh-8.1p1-1.fc31 --- gsi-openssh.spec | 19 +- openssh-6.6.1p1-log-in-chroot.patch | 2 +- ...h-6.6.1p1-scp-non-existing-directory.patch | 2 +- openssh-7.2p2-k5login_directory.patch | 7 +- openssh-7.2p2-s390-closefrom.patch | 2 +- openssh-7.2p2-x11.patch | 2 +- openssh-7.3p1-x11-max-displays.patch | 4 +- openssh-7.5p1-sandbox.patch | 60 --- openssh-7.6p1-audit.patch | 10 +- openssh-7.7p1-fips.patch | 177 ++++--- openssh-7.7p1-gssapi-new-unique.patch | 7 +- openssh-7.8p1-role-mls.patch | 2 +- openssh-8.0p1-agent-certs-sha2.patch | 31 -- openssh-8.0p1-crypto-policies.patch | 18 +- openssh-8.0p1-gssapi-keyex.patch | 34 +- openssh-8.0p1-openssl-pem.patch | 324 ------------ openssh-8.0p1-pkcs11-uri.patch | 468 ++++++++---------- openssh-8.0p1-scp-tests.patch | 61 --- ...gsissh.patch => openssh-8.1p1-gsissh.patch | 4 +- sources | 4 +- 20 files changed, 343 insertions(+), 895 deletions(-) delete mode 100644 openssh-8.0p1-agent-certs-sha2.patch delete mode 100644 openssh-8.0p1-openssl-pem.patch delete mode 100644 openssh-8.0p1-scp-tests.patch rename openssh-8.0p1-gsissh.patch => openssh-8.1p1-gsissh.patch (99%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 3a0ffa8..efb37df 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 8.0p1 -%global openssh_rel 6 +%global openssh_ver 8.1p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -148,23 +148,16 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # - do not return 0 if the write fails (full disk) # - shellcheck reports (upstream #2902) Patch958: openssh-7.9p1-ssh-copy-id.patch -# Verify the SCP vulnerabilities are fixed in the package testsuite -# https://bugzilla.mindrot.org/show_bug.cgi?id=3007 -Patch961: openssh-8.0p1-scp-tests.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 -# Use new OpenSSL for PEM export to avoid MD5 dependency (#1712436) -Patch965: openssh-8.0p1-openssl-pem.patch -# Properly encode SHA2 certificate types in ssh-agent -Patch966: openssh-8.0p1-agent-certs-sha2.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-8.0p1-gsissh.patch +Patch98: openssh-8.1p1-gsissh.patch License: BSD Requires: /sbin/nologin @@ -305,12 +298,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch951 -p1 -b .pkcs11-uri %patch953 -p1 -b .scp-ipv6 %patch958 -p1 -b .ssh-copy-id -%patch961 -p1 -b .scp-tests %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp %patch964 -p1 -b .openssl-kdf -%patch965 -p1 -b .openssl-pem -%patch966 -p1 -b .agent-cert-sha2 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -522,6 +512,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Oct 21 2019 Mattias Ellert - 8.1p1-1 +- Based on openssh-8.1p1-1.fc31 + * Thu Aug 08 2019 Mattias Ellert - 8.0p1-6 - Based on openssh-8.0p1-8.fc31 diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index b009d99..f3f7cad 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -210,8 +210,8 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c 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; - ssh_malloc_init(); /* must be called before any mallocs */ __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); diff --git a/openssh-6.6.1p1-scp-non-existing-directory.patch b/openssh-6.6.1p1-scp-non-existing-directory.patch index 5412bc5..bb55c0b 100644 --- a/openssh-6.6.1p1-scp-non-existing-directory.patch +++ b/openssh-6.6.1p1-scp-non-existing-directory.patch @@ -10,5 +10,5 @@ + } omode = mode; mode |= S_IWUSR; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { -- diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 600117f..242294a 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -28,14 +28,15 @@ diff --git a/auth.h b/auth.h index f9d191c..c432d2f 100644 --- a/auth.h +++ b/auth.h -@@ -222,5 +222,7 @@ int sys_auth_passwd(Authctxt *, const char *); +@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *); + #if defined(KRB5) && !defined(HEIMDAL) - #include krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, + char **k5login_directory); #endif - #endif + + #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index a7c0c5f..df8cc9a 100644 --- a/gss-serv-krb5.c diff --git a/openssh-7.2p2-s390-closefrom.patch b/openssh-7.2p2-s390-closefrom.patch index 301a523..363538c 100644 --- a/openssh-7.2p2-s390-closefrom.patch +++ b/openssh-7.2p2-s390-closefrom.patch @@ -48,5 +48,5 @@ Author: Harald Freudenberger +#endif } (void) closedir(dirp); - } else + return; diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index 48ce840..0a19ecb 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -14,7 +14,7 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c + if (len <= 0) + return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) + if (sock == -1) error("socket: %.100s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 94dac8f..c8a147b 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -59,7 +59,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c 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) < 0) { + 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)); @@ -197,7 +197,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 +.Cm X11MaxDisplays , .Cm X11Forwarding and - .Cm X11UseLocalHost . + .Cm X11UseLocalhost . @@ -1566,6 +1567,12 @@ Specifies the first display number avail X11 forwarding. This prevents sshd from interfering with real X11 servers. diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7190813..7217c64 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -69,29 +69,6 @@ index 6e7de31..e86aa2c 100644 SC_ALLOW(__NR_getrandom), #endif -- 1.9.1 - -The EP11 crypto card needs to make an ioctl call, which receives an -specific argument. This crypto card is for s390 only. - -Signed-off-by: Eduardo Barretto ---- - sandbox-seccomp-filter.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index e86aa2c..98062f1 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -250,6 +250,8 @@ static const struct sock_filter preauth_insns[] = { - SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), -+ /* Allow ioctls for EP11 crypto card on s390 */ -+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), - #endif - #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) - /* --- 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 @@ -107,40 +84,3 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se SC_ALLOW(__NR_getrandom), #endif - -From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001 -From: Harald Freudenberger -Date: Fri, 24 May 2019 10:11:15 +0200 -Subject: [PATCH] allow s390 specific ioctl for ecc hardware support - -Adding another s390 specific ioctl to be able to support ECC hardware acceleration -to the sandbox seccomp filter rules. - -Now the ibmca openssl engine provides elliptic curve cryptography support with the -help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt -device driver and so there is a need to enable this on the openssl sandbox. - -Code is s390 specific and has been tested, verified and reviewed. - -Please note that I am also the originator of the previous changes in that area. -I posted these changes to Eduardo and he forwarded the patches to the openssl -community. - -Signed-off-by: Harald Freudenberger -Reviewed-by: Joerg Schmidbauer ---- - sandbox-seccomp-filter.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 5edbc6946..56eb9317f 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = { - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), - /* Allow ioctls for EP11 crypto card on s390 */ - SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), -+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB), - #endif - #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) - /* diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 01e509e..a59cfc2 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -941,8 +941,8 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) { + error("%s: unsupported cipher %s", __func__, name); free(name); - return SSH_ERR_INTERNAL_ERROR; @@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -955,8 +955,8 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) { + error("%s: unsupported MAC %s", __func__, name); free(name); - return SSH_ERR_INTERNAL_ERROR; @@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma } @@ -1659,9 +1659,9 @@ diff -up openssh/packet.c.audit openssh/packet.c #include "xmalloc.h" +#include "audit.h" - #include "crc32.h" #include "compat.h" #include "ssh2.h" + #include "cipher.h" @@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -2309,8 +2309,8 @@ diff -up openssh/sshkey.h.audit openssh/sshkey.h --- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 +++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 @@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey - int sshkey_generate(int type, u_int bits, struct sshkey **keyp); - int sshkey_from_private(const struct sshkey *, struct sshkey **); + int sshkey_unshield_private(struct sshkey *); + int sshkey_type_from_name(const char *); +int sshkey_is_private(const struct sshkey *); int sshkey_is_cert(const struct sshkey *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index f28b943..36af30a 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c ---- openssh-7.9p1/cipher-ctr.c.fips 2019-03-11 17:06:37.519877082 +0100 -+++ openssh-7.9p1/cipher-ctr.c 2019-03-11 17:06:37.620878031 +0100 +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 @@ -11,10 +11,10 @@ diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-7.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c ---- openssh-7.9p1/clientloop.c.fips 2019-03-11 17:06:37.523877120 +0100 -+++ openssh-7.9p1/clientloop.c 2019-03-11 17:06:37.620878031 +0100 -@@ -2014,7 +2014,8 @@ key_accepted_by_hostkeyalgs(const struct +diff -up openssh-8.0p1/clientloop.c.fips openssh-8.0p1/clientloop.c +--- openssh-8.0p1/clientloop.c.fips 2019-07-23 14:55:45.331525692 +0200 ++++ openssh-8.0p1/clientloop.c 2019-07-23 14:55:45.401526401 +0200 +@@ -2049,7 +2049,8 @@ key_accepted_by_hostkeyalgs(const struct { const char *ktype = sshkey_ssh_name(key); const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? @@ -24,9 +24,9 @@ diff -up openssh-7.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c if (key == NULL || key->type == KEY_UNSPEC) return 0; -diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c ---- openssh-7.9p1/dh.c.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/dh.c 2019-03-11 17:08:11.769763057 +0100 +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; @@ -79,9 +79,9 @@ diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c +} + #endif /* WITH_OPENSSL */ -diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h ---- openssh-7.9p1/dh.h.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/dh.h 2019-03-11 17:08:18.718828381 +0100 +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); @@ -90,10 +90,10 @@ diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h u_int dh_estimate(int); -diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c ---- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100 -+++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100 -@@ -175,7 +196,10 @@ kex_names_valid(const char *names) +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) { @@ -105,9 +105,9 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c free(s); return 0; } -diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c ---- openssh-7.9p1/kexgexc.c.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/kexgexc.c 2019-03-11 17:06:37.621878041 +0100 +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 @@ -116,7 +116,7 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c #include #include -@@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -113,6 +114,10 @@ input_kex_dh_gex_group(int type, u_int32 r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -127,10 +127,10 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in ---- openssh-7.9p1/Makefile.in.fips 2019-03-11 17:06:37.615877984 +0100 -+++ openssh-7.9p1/Makefile.in 2019-03-11 17:06:37.621878041 +0100 -@@ -179,25 +179,25 @@ libssh.a: $(LIBSSH_OBJS) +diff -up openssh-8.0p1/Makefile.in.fips openssh-8.0p1/Makefile.in +--- openssh-8.0p1/Makefile.in.fips 2019-07-23 14:55:45.396526350 +0200 ++++ openssh-8.0p1/Makefile.in 2019-07-23 14:55:45.402526411 +0200 +@@ -180,25 +180,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) @@ -152,9 +152,9 @@ diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in - $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o -- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o sshsig.o +- $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o - $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -162,24 +162,26 @@ diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -215,7 +215,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a +@@ -216,7 +216,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h ---- openssh-7.9p1/myproposal.h.fips 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/myproposal.h 2019-03-11 17:06:37.621878041 +0100 -@@ -116,6 +116,14 @@ + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-realpath.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-realpath.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +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,16 @@ "rsa-sha2-256," \ "ssh-rsa" +#define KEX_FIPS_PK_ALG \ + HOSTKEY_ECDSA_CERT_METHODS \ ++ "rsa-sha2-512-cert-v01@openssh.com," \ ++ "rsa-sha2-256-cert-v01@openssh.com," \ + "ssh-rsa-cert-v01@openssh.com," \ + HOSTKEY_ECDSA_METHODS \ + "rsa-sha2-512," \ @@ -189,7 +191,7 @@ diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h /* the actual algorithms */ #define KEX_SERVER_ENCRYPT \ -@@ -139,6 +147,38 @@ +@@ -134,6 +142,38 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -227,11 +229,11 @@ diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h + /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ - "ecdsa-sha2-nistp256," \ -diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c ---- openssh-7.9p1/readconf.c.fips 2019-03-11 17:06:37.601877853 +0100 -+++ openssh-7.9p1/readconf.c 2019-03-11 17:06:37.622878050 +0100 -@@ -2178,18 +2178,19 @@ fill_default_options(Options * options) + HOSTKEY_ECDSA_METHODS \ +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,18 +2179,19 @@ fill_default_options(Options * options) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -259,9 +261,9 @@ diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c #undef ASSEMBLE free(all_cipher); free(all_mac); -diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-seccomp-filter.c ---- openssh-7.9p1/sandbox-seccomp-filter.c.fips 2019-03-11 17:06:37.586877712 +0100 -+++ openssh-7.9p1/sandbox-seccomp-filter.c 2019-03-11 17:06:37.622878050 +0100 +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), @@ -272,10 +274,10 @@ diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c ---- openssh-7.9p1/servconf.c.fips 2019-03-11 17:06:37.568877543 +0100 -+++ openssh-7.9p1/servconf.c 2019-03-11 17:06:37.622878050 +0100 -@@ -209,18 +209,19 @@ assemble_algorithms(ServerOptions *o) +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,18 +208,19 @@ assemble_algorithms(ServerOptions *o) all_kex = kex_alg_list(','); all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -304,9 +306,9 @@ diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c #undef ASSEMBLE free(all_cipher); free(all_mac); -diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c ---- openssh-7.9p1/ssh.c.fips 2019-03-11 17:06:37.602877862 +0100 -+++ openssh-7.9p1/ssh.c 2019-03-11 17:06:37.623878060 +0100 +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,8 @@ #include #include @@ -333,7 +335,7 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -1283,6 +1294,10 @@ main(int ac, char **av) +@@ -614,6 +626,10 @@ main(int ac, char **av) seed_rng(); @@ -344,9 +346,9 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c /* * Discard other fds that are hanging around. These can cause problem * with backgrounded ssh processes started by ControlPersist. -diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c ---- openssh-7.9p1/sshconnect2.c.fips 2019-03-11 17:06:37.580877655 +0100 -+++ openssh-7.9p1/sshconnect2.c 2019-03-11 17:06:37.623878060 +0100 +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 #endif @@ -356,7 +358,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc +@@ -115,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc for (i = 0; i < options.num_system_hostfiles; i++) load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); @@ -366,7 +368,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); -@@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -182,14 +185,16 @@ ssh_kex2(struct ssh *ssh, char *host, st if (options.hostkeyalgorithms != NULL) { all_key = sshkey_alg_list(0, 0, 1, ','); if (kex_assemble_names(&options.hostkeyalgorithms, @@ -385,7 +387,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( -@@ -201,29 +201,34 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -198,29 +203,34 @@ ssh_kex2(struct ssh *ssh, char *host, st #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -443,9 +445,9 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c } } #endif -diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c ---- openssh-7.9p1/sshd.c.fips 2019-03-11 17:06:37.617878003 +0100 -+++ openssh-7.9p1/sshd.c 2019-03-11 17:06:37.624878069 +0100 +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 #include @@ -463,7 +465,7 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1581,6 +1584,18 @@ main(int ac, char **av) +@@ -1529,6 +1532,18 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -482,7 +484,7 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -2036,6 +2051,10 @@ main(int ac, char **av) +@@ -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); @@ -493,7 +495,7 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) -@@ -2412,10 +2431,14 @@ do_ssh2_kex(void) +@@ -2382,10 +2401,14 @@ do_ssh2_kex(struct ssh *ssh) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -512,9 +514,9 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c ---- openssh-7.9p1/sshkey.c.fips 2019-03-11 17:06:37.617878003 +0100 -+++ openssh-7.9p1/sshkey.c 2019-03-11 17:06:37.624878069 +0100 +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 #include @@ -524,14 +526,14 @@ diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c #include "crypto_api.h" @@ -57,6 +58,7 @@ + #define SSHKEY_INTERNAL #include "sshkey.h" - #include "sshkey-xmss.h" #include "match.h" +#include "log.h" - #include "xmss_fast.h" - -@@ -1514,6 +1516,8 @@ rsa_generate_private_key(u_int bits, RSA + #ifdef WITH_XMSS + #include "sshkey-xmss.h" +@@ -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)) { @@ -540,13 +542,13 @@ diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c ---- openssh-7.9p1/ssh-keygen.c.fips 2019-03-11 17:06:37.590877750 +0100 -+++ openssh-7.9p1/ssh-keygen.c 2019-03-11 17:06:37.625878079 +0100 -@@ -230,6 +230,12 @@ type_bits_valid(int type, const char *na - OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; - if (*bitsp > maxbits) - fatal("key bits exceeds maximum %d", maxbits); +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"); @@ -556,3 +558,22 @@ diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c 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 public key in %s: %s", + prv_tmp, strerror(errno)); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 2eea250..9386249 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -336,14 +336,15 @@ index 29491df9..fdab5040 100644 #endif struct sshbuf *loginmsg; -@@ -243,6 +244,6 @@ int sys_auth_passwd(struct ssh *, const char *); +@@ -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) - #include -krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); #endif - #endif + + #endif /* AUTH_H */ 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 diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 84ba9b3..da0abd7 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -141,7 +141,7 @@ diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c +do_pam_putenv(char *name, const char *value) { int ret = 1; - #ifdef HAVE_PAM_PUTENV + 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 diff --git a/openssh-8.0p1-agent-certs-sha2.patch b/openssh-8.0p1-agent-certs-sha2.patch deleted file mode 100644 index b9888d9..0000000 --- a/openssh-8.0p1-agent-certs-sha2.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2317ce4b0ed7d8c4b0c684e2d47bff5006bd1178 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 14 Jun 2019 03:51:47 +0000 -Subject: [PATCH] upstream: process agent requests for RSA certificate private - keys using - -correct signature algorithm when requested. Patch from Jakub Jelen in bz3016 -ok dtucker markus - -OpenBSD-Commit-ID: 61f86efbeb4a1857a3e91298c1ccc6cf49b79624 ---- - ssh-agent.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/ssh-agent.c b/ssh-agent.c -index 034f31387..4669b679c 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -269,6 +269,11 @@ agent_decode_alg(struct sshkey *key, u_int flags) - return "rsa-sha2-256"; - else if (flags & SSH_AGENT_RSA_SHA2_512) - return "rsa-sha2-512"; -+ } else if (key->type == KEY_RSA_CERT) { -+ if (flags & SSH_AGENT_RSA_SHA2_256) -+ return "rsa-sha2-256-cert-v01@openssh.com"; -+ else if (flags & SSH_AGENT_RSA_SHA2_512) -+ return "rsa-sha2-512-cert-v01@openssh.com"; - } - return NULL; - } - diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index ffd4bae..37263a5 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -32,9 +32,9 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 .It Cm HashKnownHosts Indicates that @@ -1123,16 +1123,10 @@ If the specified value begins with a - .Sq - - character, then the specified methods (including wildcards) will be removed - from the default set instead of replacing them. + .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, @@ -72,9 +72,9 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -1361,17 +1351,10 @@ If the specified value begins with a - .Sq - - character, then the specified key types (including wildcards) will be removed - from the default set instead of replacing them. + .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, @@ -187,9 +187,9 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -1455,17 +1440,10 @@ If the specified value begins with a - .Sq - - character, then the specified key types (including wildcards) will be removed - from the default set instead of replacing them. + .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, diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index fe3e7a6..631c824 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -17,7 +17,7 @@ index 6f001bb3..c31821ac 100644 - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o sftp-realpath.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/auth.c b/auth.c index 332b6220..7664aaac 100644 @@ -60,7 +60,7 @@ index 332b6220..7664aaac 100644 - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (getpeername(ssh_packet_get_connection_in(ssh), -- (struct sockaddr *)&from, &fromlen) < 0) { +- (struct sockaddr *)&from, &fromlen) == -1) { - debug("getpeername failed: %.100s", strerror(errno)); - return strdup(ntop); - } @@ -279,7 +279,7 @@ index f71a0856..404731d2 100644 + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(ssh_packet_get_connection_in(ssh), -+ (struct sockaddr *)&from, &fromlen) < 0) { ++ (struct sockaddr *)&from, &fromlen) == -1) { + debug("getpeername failed: %.100s", strerror(errno)); + return strdup(ntop); + } @@ -1258,18 +1258,6 @@ index ab3a15f0..6ce56e92 100644 } /* Privileged */ -diff --git a/hmac.c b/hmac.c -index 1c879640..a29f32c5 100644 ---- a/hmac.c -+++ b/hmac.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - #include "sshbuf.h" - #include "digest.h" diff --git a/kex.c b/kex.c index 34808b5c..a2a4794e 100644 --- a/kex.c @@ -1293,7 +1281,7 @@ index 34808b5c..a2a4794e 100644 static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, -1, -1, -1}, + { NULL, 0, -1, -1}, }; +static const struct kexalg gss_kexalgs[] = { +#ifdef GSSAPI @@ -1306,7 +1294,7 @@ index 34808b5c..a2a4794e 100644 + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif -+ { NULL, -1, -1, -1 }, ++ { NULL, 0, -1, -1 }, +}; -char * @@ -2585,18 +2573,6 @@ index 00000000..60bc02de + return r; +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/mac.c b/mac.c -index 51dc11d7..3d11eba6 100644 ---- a/mac.c -+++ b/mac.c -@@ -29,6 +29,7 @@ - - #include - #include -+#include - - #include "digest.h" - #include "hmac.h" diff --git a/monitor.c b/monitor.c index 60e52944..669cdb4a 100644 --- a/monitor.c diff --git a/openssh-8.0p1-openssl-pem.patch b/openssh-8.0p1-openssl-pem.patch deleted file mode 100644 index 7e4fa81..0000000 --- a/openssh-8.0p1-openssl-pem.patch +++ /dev/null @@ -1,324 +0,0 @@ -From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 15 Jul 2019 13:16:29 +0000 -Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of - -private keys, enabled via "ssh-keygen -m PKCS8" on operations that save -private keys to disk. - -The OpenSSH native key format remains the default, but PKCS8 is a -superior format to PEM if interoperability with non-OpenSSH software -is required, as it may use a less terrible KDF (IIRC PEM uses a single -round of MD5 as a KDF). - -adapted from patch by Jakub Jelen via bz3013; ok markus - -OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1 ---- - authfile.c | 6 ++-- - ssh-keygen.1 | 9 +++--- - ssh-keygen.c | 25 +++++++++-------- - sshkey.c | 78 +++++++++++++++++++++++++++++++++++++--------------- - sshkey.h | 11 ++++++-- - 5 files changed, 87 insertions(+), 42 deletions(-) - -diff --git a/authfile.c b/authfile.c -index 2166c1689..851c1a8a1 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) - int - sshkey_save_private(struct sshkey *key, const char *filename, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds) -+ int format, const char *openssh_format_cipher, int openssh_format_rounds) - { - struct sshbuf *keyblob = NULL; - int r; -@@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename, - if ((keyblob = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, -- force_new_format, new_format_cipher, new_format_rounds)) != 0) -+ format, openssh_format_cipher, openssh_format_rounds)) != 0) - goto out; - if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) - goto out; -diff --git a/ssh-keygen.1 b/ssh-keygen.1 -index f42127c60..8184a1797 100644 ---- a/ssh-keygen.1 -+++ b/ssh-keygen.1 -@@ -419,11 +419,12 @@ The supported key formats are: - .Dq RFC4716 - (RFC 4716/SSH2 public or private key), - .Dq PKCS8 --(PEM PKCS8 public key) -+(PKCS8 public or private key) - or - .Dq PEM - (PEM public key). --The default conversion format is -+By default OpenSSH will write newly-generated private keys in its own -+format, but when converting public keys for export the default format is - .Dq RFC4716 . - Setting a format of - .Dq PEM -diff --git a/ssh-keygen.c b/ssh-keygen.c -index b019a02ff..5dcad1f61 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -147,11 +147,11 @@ static char *key_type_name = NULL; - /* Load key from this PKCS#11 provider */ - static char *pkcs11provider = NULL; - --/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ --static int use_new_format = 1; -+/* Format for writing private keys */ -+static int private_key_format = SSHKEY_PRIVATE_OPENSSH; - - /* Cipher for new-format private keys */ --static char *new_format_cipher = NULL; -+static char *openssh_format_cipher = NULL; - - /* - * Number of KDF rounds to derive new format keys / -@@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw) - snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, - hostname); - if ((r = sshkey_save_private(private, prv_tmp, "", -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, -+ rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - prv_tmp, ssh_err(r)); - goto failnext; -@@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw) - - /* Save the file using the new passphrase. */ - if ((r = sshkey_save_private(private, identity_file, passphrase1, -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { - error("Saving key \"%s\" failed: %s.", - identity_file, ssh_err(r)); - explicit_bzero(passphrase1, strlen(passphrase1)); -@@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) - } - - if (private->type != KEY_ED25519 && private->type != KEY_XMSS && -- !use_new_format) { -+ private_key_format != SSHKEY_PRIVATE_OPENSSH) { - error("Comments are only supported for keys stored in " - "the new format (-o)."); - explicit_bzero(passphrase, strlen(passphrase)); -@@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment) - - /* Save the file using the new passphrase. */ - if ((r = sshkey_save_private(private, identity_file, passphrase, -- new_comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ new_comment, private_key_format, openssh_format_cipher, -+ rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - identity_file, ssh_err(r)); - explicit_bzero(passphrase, strlen(passphrase)); -@@ -2525,11 +2527,12 @@ main(int argc, char **argv) - } - if (strcasecmp(optarg, "PKCS8") == 0) { - convert_format = FMT_PKCS8; -+ private_key_format = SSHKEY_PRIVATE_PKCS8; - break; - } - if (strcasecmp(optarg, "PEM") == 0) { - convert_format = FMT_PEM; -- use_new_format = 0; -+ private_key_format = SSHKEY_PRIVATE_PEM; - break; - } - fatal("Unsupported conversion format \"%s\"", optarg); -@@ -2567,7 +2570,7 @@ main(int argc, char **argv) - add_cert_option(optarg); - break; - case 'Z': -- new_format_cipher = optarg; -+ openssh_format_cipher = optarg; - break; - case 'C': - identity_comment = optarg; -@@ -2912,7 +2915,7 @@ main(int argc, char **argv) - - /* Save the key with the given passphrase and comment. */ - if ((r = sshkey_save_private(private, identity_file, passphrase1, -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - identity_file, ssh_err(r)); - explicit_bzero(passphrase1, strlen(passphrase1)); -diff --git a/sshkey.c b/sshkey.c -index 6b5ff0485..a0cea9257 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, - - - #ifdef WITH_OPENSSL --/* convert SSH v2 key in OpenSSL PEM format */ -+/* convert SSH v2 key to PEM or PKCS#8 format */ - static int --sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, -- const char *_passphrase, const char *comment) -+sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob, -+ int format, const char *_passphrase, const char *comment) - { - int success, r; - int blen, len = strlen(_passphrase); -@@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; - char *bptr; - BIO *bio = NULL; -+ EVP_PKEY *pkey = NULL; - - if (len > 0 && len <= 4) - return SSH_ERR_PASSPHRASE_TOO_SHORT; -- if ((bio = BIO_new(BIO_s_mem())) == NULL) -- return SSH_ERR_ALLOC_FAIL; -+ if ((bio = BIO_new(BIO_s_mem())) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } - - switch (key->type) { - case KEY_DSA: -- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_DSA(pkey, key->dsa); -+ } - break; - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); -+ } - break; - #endif - case KEY_RSA: -- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_RSA(pkey, key->rsa); -+ } - break; - default: - success = 0; -@@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ if (format == SSHKEY_PRIVATE_PKCS8) { -+ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher, -+ passphrase, len, NULL, NULL)) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ } - if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; -@@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - goto out; - r = 0; - out: -+ EVP_PKEY_free(pkey); - BIO_free(bio); - return r; - } -@@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - int - sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds) -+ int format, const char *openssh_format_cipher, int openssh_format_rounds) - { - switch (key->type) { - #ifdef WITH_OPENSSL - case KEY_DSA: - case KEY_ECDSA: - case KEY_RSA: -- if (force_new_format) { -- return sshkey_private_to_blob2(key, blob, passphrase, -- comment, new_format_cipher, new_format_rounds); -- } -- return sshkey_private_pem_to_blob(key, blob, -- passphrase, comment); -+ break; /* see below */ - #endif /* WITH_OPENSSL */ - case KEY_ED25519: - #ifdef WITH_XMSS - case KEY_XMSS: - #endif /* WITH_XMSS */ - return sshkey_private_to_blob2(key, blob, passphrase, -- comment, new_format_cipher, new_format_rounds); -+ comment, openssh_format_cipher, openssh_format_rounds); - default: - return SSH_ERR_KEY_TYPE_UNKNOWN; - } -+ -+#ifdef WITH_OPENSSL -+ switch (format) { -+ case SSHKEY_PRIVATE_OPENSSH: -+ return sshkey_private_to_blob2(key, blob, passphrase, -+ comment, openssh_format_cipher, openssh_format_rounds); -+ case SSHKEY_PRIVATE_PEM: -+ case SSHKEY_PRIVATE_PKCS8: -+ return sshkey_private_to_blob_pem_pkcs8(key, blob, -+ format, passphrase, comment); -+ default: -+ return SSH_ERR_INVALID_ARGUMENT; -+ } -+#endif /* WITH_OPENSSL */ - } - - -diff --git a/sshkey.h b/sshkey.h -index 41d159a1b..d30a69cc9 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -88,6 +88,13 @@ enum sshkey_serialize_rep { - SSHKEY_SERIALIZE_INFO = 254, - }; - -+/* Private key disk formats */ -+enum sshkey_private_format { -+ SSHKEY_PRIVATE_OPENSSH = 0, -+ SSHKEY_PRIVATE_PEM = 1, -+ SSHKEY_PRIVATE_PKCS8 = 2, -+}; -+ - /* key is stored in external hardware */ - #define SSHKEY_FLAG_EXT 0x0001 - -@@ -221,7 +228,7 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); - /* private key file format parsing and serialisation */ - int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds); -+ int format, const char *openssh_format_cipher, int openssh_format_rounds); - int sshkey_parse_private_fileblob(struct sshbuf *buffer, - const char *passphrase, struct sshkey **keyp, char **commentp); - int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, - diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 41b138a..cd7d0e5 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,9 +1,9 @@ diff --git a/Makefile.in b/Makefile.in -index 6f001bb3..c9424f1e 100644 +index adb1977e..9b01a017 100644 --- a/Makefile.in +++ b/Makefile.in @@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \ + atomicio.o dispatch.o mac.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ @@ -11,7 +11,7 @@ index 6f001bb3..c9424f1e 100644 poly1305.o chacha.o cipher-chachapoly.o \ ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -250,6 +250,8 @@ clean: regressclean +@@ -255,6 +255,8 @@ clean: regressclean rm -f regress/unittests/match/test_match$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -20,7 +20,7 @@ index 6f001bb3..c9424f1e 100644 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) clean) -@@ -280,6 +282,8 @@ distclean: regressclean +@@ -285,6 +287,8 @@ distclean: regressclean rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -29,7 +29,7 @@ index 6f001bb3..c9424f1e 100644 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) distclean) -@@ -442,6 +446,7 @@ regress-prep: +@@ -447,6 +451,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/kex $(MKDIR_P) `pwd`/regress/unittests/match $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -37,7 +37,7 @@ index 6f001bb3..c9424f1e 100644 $(MKDIR_P) `pwd`/regress/misc/kexfuzz [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -565,6 +570,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ +@@ -570,6 +575,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -54,32 +54,19 @@ index 6f001bb3..c9424f1e 100644 MISC_KEX_FUZZ_OBJS=\ regress/misc/kexfuzz/kexfuzz.o -@@ -585,6 +600,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ +@@ -593,6 +608,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ regress/misc/kexfuzz/kexfuzz$(EXEEXT) - tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) -diff --git a/authfd.c b/authfd.c -index 95348abf..5383df92 100644 ---- a/authfd.c -+++ b/authfd.c -@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identitylist *idl) - if (idl->comments != NULL) - free(idl->comments[i]); - } -+ free(idl->keys); -+ free(idl->comments); - free(idl); - } - + tests: file-tests t-exec interop-tests unit diff --git a/configure.ac b/configure.ac -index 30be6c18..82459746 100644 +index 3e93c027..351f0ba5 100644 --- a/configure.ac +++ b/configure.ac -@@ -1854,12 +1854,14 @@ AC_LINK_IFELSE( +@@ -1861,12 +1861,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -94,7 +81,7 @@ index 30be6c18..82459746 100644 fi ] ) -@@ -1875,6 +1877,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then +@@ -1882,6 +1884,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then ) fi @@ -135,7 +122,7 @@ index 30be6c18..82459746 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5256,6 +5292,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" +@@ -5229,6 +5265,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -144,24 +131,20 @@ index 30be6c18..82459746 100644 echo "" diff --git a/regress/Makefile b/regress/Makefile -index 925edf71..94bb25e9 100644 +index 34c47e8c..d693aa4a 100644 --- a/regress/Makefile +++ b/regress/Makefile -@@ -109,9 +109,11 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +@@ -115,7 +115,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log \ -- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ -+ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ -+ rsa-agent-cert.pub rsa.pub \ - rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ -- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ -+ pkcs11*.crt pkcs11*.key \ -+ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + pidfile putty.rsa2 ready regress.log remote_pid \ +- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ ++ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ ++ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ + rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ - ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ -@@ -231,6 +233,7 @@ unit: +@@ -245,6 +246,7 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -170,24 +153,10 @@ index 925edf71..94bb25e9 100644 $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -d ${.CURDIR}/unittests/sshkey/testdata ; \ diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index 5205d906..5ca49be5 100644 +index 5205d906..bfbaeb65 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh -@@ -29,6 +29,13 @@ fi - - test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" - -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ - # setup environment for softhsm2 token - DIR=$OBJ/SOFTHSM - rm -rf $DIR -@@ -113,7 +120,7 @@ else +@@ -113,7 +113,7 @@ else done trace "remove pkcs11 keys" @@ -198,10 +167,10 @@ index 5205d906..5ca49be5 100644 fail "ssh-add -e failed: exit code $r" diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh new file mode 100644 -index 00000000..19fc8169 +index 00000000..f2d6c41c --- /dev/null +++ b/regress/pkcs11.sh -@@ -0,0 +1,352 @@ +@@ -0,0 +1,345 @@ +# +# Copyright (c) 2017 Red Hat +# @@ -247,13 +216,6 @@ index 00000000..19fc8169 + +test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ +# setup environment for softhsm token +DIR=$OBJ/SOFTHSM +rm -rf $DIR @@ -555,15 +517,15 @@ index 00000000..19fc8169 + ${SSHAGENT} -k > /dev/null +fi diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e464b085..a0e5a37c 100644 +index 4e56e110..2690ebeb 100644 --- a/regress/unittests/Makefile +++ b/regress/unittests/Makefile @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion --SUBDIR+=authopt -+SUBDIR+=pkcs11 authopt +-SUBDIR+=authopt misc ++SUBDIR+=authopt misc pkcs11 .include diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c @@ -910,10 +872,10 @@ index 00000000..b637cb13 + test_generate_valid(); +} diff --git a/ssh-add.c b/ssh-add.c -index ac9c808d..f039e00e 100644 +index ebfb8a32..c32d1cb5 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -64,6 +64,7 @@ +@@ -66,6 +66,7 @@ #include "misc.h" #include "ssherr.h" #include "digest.h" @@ -921,32 +883,55 @@ index ac9c808d..f039e00e 100644 /* argv0 */ extern char *__progname; -@@ -188,6 +189,24 @@ delete_all(int agent_fd, int qflag) +@@ -190,6 +191,32 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int); ++static int update_card(int, int, const char *, int, char *); + +int +update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) +{ ++ char *pin = NULL; + struct pkcs11_uri *uri; + + /* dry-run parse to make sure the URI is valid and to report errors */ + uri = pkcs11_uri_init(); + if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) + fatal("Failed to parse PKCS#11 URI"); ++ if (uri->pin != NULL) { ++ pin = strdup(uri->pin); ++ if (pin == NULL) { ++ fatal("Failed to dupplicate string"); ++ } ++ /* pin is freed in the update_card() */ ++ } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); +} +#endif + static int add_file(int agent_fd, const char *filename, int key_only, int qflag) { -@@ -529,6 +548,13 @@ lock_agent(int agent_fd, int lock) +@@ -392,12 +419,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) + } + + static int +-update_card(int agent_fd, int add, const char *id, int qflag) ++update_card(int agent_fd, int add, const char *id, int qflag, char *pin) + { +- char *pin = NULL; + int r, ret = -1; + +- if (add) { ++ if (add && pin == NULL) { + if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", + RP_ALLOW_STDIN)) == NULL) + return -1; +@@ -531,6 +557,13 @@ lock_agent(int agent_fd, int lock) static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) { @@ -960,11 +945,20 @@ index ac9c808d..f039e00e 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; +@@ -709,7 +742,7 @@ main(int argc, char **argv) + } + if (pkcs11provider != NULL) { + if (update_card(agent_fd, !deleting, pkcs11provider, +- qflag) == -1) ++ qflag, NULL) == -1) + ret = 1; + goto done; + } diff --git a/ssh-agent.c b/ssh-agent.c -index d06ecfd9..9c1b328f 100644 +index 9c6680a2..e3336073 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -548,10 +548,72 @@ no_identities(SocketEntry *e) +@@ -556,10 +556,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1038,7 +1032,7 @@ index d06ecfd9..9c1b328f 100644 int r, i, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; -@@ -587,28 +649,23 @@ process_add_smartcard_key(SocketEntry *e) +@@ -595,28 +657,23 @@ process_add_smartcard_key(SocketEntry *e) goto send; } } @@ -1075,7 +1069,7 @@ index d06ecfd9..9c1b328f 100644 id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&idtab->idlist, id, next); -@@ -622,6 +679,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -630,6 +687,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); @@ -1083,7 +1077,7 @@ index d06ecfd9..9c1b328f 100644 free(keys); send_status(e, success); } -@@ -629,7 +687,7 @@ send: +@@ -637,7 +695,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1092,7 +1086,7 @@ index d06ecfd9..9c1b328f 100644 int r, success = 0; Identity *id, *nxt; -@@ -640,30 +698,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -648,30 +706,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1130,10 +1124,10 @@ index d06ecfd9..9c1b328f 100644 } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-keygen.c b/ssh-keygen.c -index 3898b281..91c43b14 100644 +index e039be30..6770fafb 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -798,6 +798,7 @@ do_download(struct passwd *pw) +@@ -829,6 +829,7 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1638,7 +1632,7 @@ index 00000000..942a5a5a +char *pkcs11_uri_get(struct pkcs11_uri *uri); + diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 70f06bff..59332945 100644 +index 09f1ea34..fceddfe3 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -54,8 +54,8 @@ struct pkcs11_slotinfo { @@ -1900,11 +1894,11 @@ index 70f06bff..59332945 100644 static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, @@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); + free(k11->label); - free(k11); + free(k11); } @@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, @@ -1918,18 +1912,40 @@ index 70f06bff..59332945 100644 if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -252,8 +392,8 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) +@@ -267,7 +407,7 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -282,13 +422,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); return (-1); } -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } - if (!pkcs11_interactive) { - error("need pin entry%s", -@@ -300,8 +440,8 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + +@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); return (-1); } @@ -1940,13 +1956,13 @@ index 70f06bff..59332945 100644 attr.type = type; attr.pValue = &flag; -@@ -332,13 +472,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) +@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) int always_auth = 0; int did_login = 0; - if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || !k11->provider->module -+ || !k11->provider->module->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { error("no pkcs11 (valid) provider found"); return (-1); } @@ -1958,7 +1974,7 @@ index 70f06bff..59332945 100644 if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -415,8 +556,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, +@@ -424,8 +567,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, return (-1); } @@ -1969,7 +1985,7 @@ index 70f06bff..59332945 100644 tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -460,7 +601,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -469,7 +612,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1978,7 +1994,7 @@ index 70f06bff..59332945 100644 { struct pkcs11_key *k11; -@@ -478,6 +619,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1991,7 +2007,7 @@ index 70f06bff..59332945 100644 RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -508,8 +655,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, +@@ -517,8 +666,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, return (NULL); } @@ -2002,7 +2018,7 @@ index 70f06bff..59332945 100644 siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -574,7 +721,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -2011,7 +2027,7 @@ index 70f06bff..59332945 100644 { struct pkcs11_key *k11; -@@ -590,6 +737,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); @@ -2024,26 +2040,18 @@ index 70f06bff..59332945 100644 EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -624,47 +777,26 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - CK_FUNCTION_LIST *f; - CK_RV rv; +@@ -635,8 +790,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_SESSION_HANDLE session; -- int login_required, have_pinpad, ret; -- char prompt[1024], *xpin = NULL; -+ int login_required, ret; + int login_required, ret; - f = p->function_list; - si = &p->slotinfo[slotidx]; + f = p->module->function_list; + si = &p->module->slotinfo[slotidx]; -- have_pinpad = si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH; login_required = si->token.flags & CKF_LOGIN_REQUIRED; - /* fail early before opening session */ -- if (login_required && !have_pinpad && !pkcs11_interactive && -+ if (login_required && !pkcs11_interactive && - (pin == NULL || strlen(pin) == 0)) { +@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2054,33 +2062,8 @@ index 70f06bff..59332945 100644 + error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); return (-1); } -- if (login_required) { -- if (have_pinpad && (pin == NULL || strlen(pin) == 0)) { -- /* defer PIN entry to the reader keypad */ -- rv = f->C_Login(session, CKU_USER, NULL_PTR, 0); -- } else { -- if (pkcs11_interactive) { -- snprintf(prompt, sizeof(prompt), -- "Enter PIN for '%s': ", si->token.label); -- if ((xpin = read_passphrase(prompt, -- RP_ALLOW_EOF)) == NULL) { -- debug("%s: no pin specified", -- __func__); -- return (-SSH_PKCS11_ERR_PIN_REQUIRED); -- } -- pin = xpin; -- } -- rv = f->C_Login(session, CKU_USER, -- (u_char *)pin, strlen(pin)); -- if (xpin != NULL) -- freezero(xpin, strlen(xpin)); -- } -+ if (login_required && pin != NULL && strlen(pin) != 0) { -+ rv = f->C_Login(session, user, (u_char *)pin, strlen(pin)); - if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { - error("C_Login failed: %lu", rv); - ret = (rv == CKR_PIN_LOCKED) ? -@@ -696,7 +828,8 @@ static struct sshkey * + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -684,7 +839,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2090,7 +2073,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -710,14 +843,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -698,14 +854,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2111,13 +2094,12 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -730,19 +863,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. +@@ -717,18 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ -- if (key_attr[1].ulValueLen == 0 || + if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || ++ key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2135,7 +2117,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -752,8 +887,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -740,8 +898,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2146,7 +2128,7 @@ index 70f06bff..59332945 100644 if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -764,13 +899,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -752,13 +910,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2163,7 +2145,7 @@ index 70f06bff..59332945 100644 if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -787,7 +922,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -775,7 +933,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2172,7 +2154,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -803,7 +938,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, ec = NULL; /* now owned by key */ fail: @@ -2181,7 +2163,7 @@ index 70f06bff..59332945 100644 free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -820,7 +955,8 @@ static struct sshkey * +@@ -808,7 +966,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2191,7 +2173,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -831,14 +967,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -819,14 +978,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2212,13 +2194,12 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -850,19 +987,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. +@@ -838,18 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ -- if (key_attr[1].ulValueLen == 0 || + if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || ++ key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2236,7 +2217,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -873,8 +1011,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -861,8 +1022,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2247,7 +2228,7 @@ index 70f06bff..59332945 100644 if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -883,7 +1021,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("%s: set key", __func__); rsa_n = rsa_e = NULL; /* transferred */ @@ -2256,7 +2237,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -898,7 +1036,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, rsa = NULL; /* now owned by key */ fail: @@ -2265,7 +2246,7 @@ index 70f06bff..59332945 100644 free(key_attr[i].pValue); RSA_free(rsa); -@@ -909,7 +1047,8 @@ static struct sshkey * +@@ -897,7 +1058,8 @@ static struct sshkey * pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2275,7 +2256,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -926,14 +1065,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -916,14 +1078,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2296,7 +2277,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -945,18 +1085,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -935,18 +1098,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2319,7 +2300,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -968,8 +1109,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -958,8 +1122,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2330,7 +2311,7 @@ index 70f06bff..59332945 100644 error("d2i_x509 failed"); goto fail; } -@@ -990,7 +1131,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -980,7 +1144,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2339,7 +2320,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -1020,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1010,7 +1174,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2348,7 +2329,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -1039,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1029,7 +1193,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, error("unknown certificate key type"); fail: @@ -2357,7 +2338,7 @@ index 70f06bff..59332945 100644 free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1066,11 +1207,12 @@ have_rsa_key(const RSA *rsa) +@@ -1058,11 +1222,12 @@ have_rsa_key(const RSA *rsa) */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2372,7 +2353,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1086,10 +1228,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1078,10 +1243,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2399,7 +2380,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1163,11 +1318,12 @@ fail: +@@ -1155,11 +1333,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2414,7 +2395,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1183,10 +1339,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1175,10 +1354,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2441,7 +2422,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1443,15 +1612,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1435,15 +1627,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } #endif /* WITH_PKCS11_KEYGEN */ @@ -2459,7 +2440,7 @@ index 70f06bff..59332945 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1460,148 +1624,285 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, +@@ -1452,161 +1639,298 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2547,17 +2528,17 @@ index 70f06bff..59332945 100644 error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ goto fail; ++ } + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { + debug("%s: Skipping provider %s not matching library_manufacturer", + __func__, m->info.manufacturerID); -+ goto fail; -+ } + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", @@ -2583,7 +2564,7 @@ index 70f06bff..59332945 100644 } - if (p->nslots == 0) { + if (m->nslots == 0) { - error("%s: provider %s returned no slots", __func__, + debug("%s: provider %s returned no slots", __func__, - provider_id); + provider_module); ret = -SSH_PKCS11_ERR_NO_SLOTS; @@ -2720,26 +2701,43 @@ index 70f06bff..59332945 100644 + * open session if not yet openend, login with pin and + * retrieve public keys (if keyp is provided) */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) == 0) { -+ if (p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) == 0) { - if (keyp == NULL) +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); continue; + } - pkcs11_fetch_keys(p, i, keyp, &nkeys); - pkcs11_fetch_certs(p, i, keyp, &nkeys); + pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); + pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3("%s: No keys found. Retrying without label (%s) ", -+ __func__, token->label); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); -+ uri->object = label; -+ } } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3("%s: No keys found. Retrying without label (%s) ", ++ __func__, uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ uri->object = label; ++ } + pin = NULL; /* Will be cleaned up with URI */ } @@ -2816,7 +2814,7 @@ index 70f06bff..59332945 100644 /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1611,7 +1912,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) +@@ -1616,7 +1940,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) } if (nkeys == 0) debug("%s: provider %s returned no keys", __func__, @@ -2854,7 +2852,7 @@ index 70f06bff..59332945 100644 return (nkeys); } -@@ -1633,8 +1963,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, +@@ -1638,8 +1991,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) debug("%s: provider \"%s\" available", __func__, provider_id); @@ -2864,7 +2862,7 @@ index 70f06bff..59332945 100644 debug("%s: could not register provider %s", __func__, provider_id); goto out; -@@ -1705,8 +2034,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, +@@ -1710,8 +2062,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { debug("%s: using provider \"%s\"", __func__, provider_id); @@ -2894,7 +2892,7 @@ index b9038450..5a855338 100644 struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, diff --git a/ssh.c b/ssh.c -index 91e7c351..47f4f299 100644 +index ee51823c..2268755b 100644 --- a/ssh.c +++ b/ssh.c @@ -772,6 +772,14 @@ main(int ac, char **av) @@ -2910,9 +2908,9 @@ index 91e7c351..47f4f299 100644 + } +#endif p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) < 0) + if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1521,6 +1529,7 @@ main(int ac, char **av) +@@ -1524,6 +1532,7 @@ main(int ac, char **av) free(options.certificate_files[i]); options.certificate_files[i] = NULL; } @@ -2920,7 +2918,7 @@ index 91e7c351..47f4f299 100644 skip_connect: exit_status = ssh_session2(ssh, pw); -@@ -1994,6 +2003,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) +@@ -1997,6 +2006,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -2966,7 +2964,7 @@ index 91e7c351..47f4f299 100644 /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(struct passwd *pw) -@@ -2008,10 +2056,6 @@ load_public_identity_files(struct passwd *pw) +@@ -2011,10 +2059,6 @@ load_public_identity_files(struct passwd *pw) char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -2977,7 +2975,7 @@ index 91e7c351..47f4f299 100644 n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2024,32 +2068,46 @@ load_public_identity_files(struct passwd *pw) +@@ -2027,32 +2071,46 @@ load_public_identity_files(struct passwd *pw) sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -3043,10 +3041,10 @@ index 91e7c351..47f4f299 100644 "u", pw->pw_name, "l", thishost, "h", host, "r", options.user, (char *)NULL); diff --git a/ssh_config.5 b/ssh_config.5 -index 41262963..a211034e 100644 +index 02a87892..41acfa33 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -952,6 +952,21 @@ may also be used in conjunction with +@@ -964,6 +964,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -3068,69 +3066,3 @@ index 41262963..a211034e 100644 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. - -commit 1efe98998408593861fdcd4da392dd10820f0fde -Author: Jakub Jelen -Date: Wed Jun 12 14:30:30 2019 +0200 - - Allow to specify the pin also for the ssh-add - -diff --git a/ssh-add.c b/ssh-add.c -index f039e00e..adc4e5c9 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -190,20 +190,28 @@ delete_all(int agent_fd, int qflag) - } - - #ifdef ENABLE_PKCS11 --static int update_card(int, int, const char *, int); -+static int update_card(int, int, const char *, int, char *); - - int - update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) - { -+ char *pin = NULL; - struct pkcs11_uri *uri; - - /* dry-run parse to make sure the URI is valid and to report errors */ - uri = pkcs11_uri_init(); - if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) - fatal("Failed to parse PKCS#11 URI"); -+ if (uri->pin != NULL) { -+ pin = strdup(uri->pin); -+ if (pin == NULL) { -+ fatal("Failed to dupplicate string"); -+ } -+ /* pin is freed in the update_card() */ -+ } - pkcs11_uri_cleanup(uri); - -- return update_card(agent_fd, adding, pkcs11_uri, qflag); -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); - } - #endif - -@@ -409,12 +417,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) - } - - static int --update_card(int agent_fd, int add, const char *id, int qflag) -+update_card(int agent_fd, int add, const char *id, int qflag, char *pin) - { -- char *pin = NULL; - int r, ret = -1; - -- if (add) { -+ if (add && pin == NULL) { - if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", - RP_ALLOW_STDIN)) == NULL) - return -1; -@@ -734,7 +741,7 @@ main(int argc, char **argv) - } - if (pkcs11provider != NULL) { - if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag) == -1) -+ qflag, NULL) == -1) - ret = 1; - goto done; - } diff --git a/openssh-8.0p1-scp-tests.patch b/openssh-8.0p1-scp-tests.patch deleted file mode 100644 index e0a63c4..0000000 --- a/openssh-8.0p1-scp-tests.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh -index 59f1ff63..dd48a482 100644 ---- a/regress/scp-ssh-wrapper.sh -+++ b/regress/scp-ssh-wrapper.sh -@@ -51,6 +51,18 @@ badserver_4) - echo "C755 2 file" - echo "X" - ;; -+badserver_5) -+ echo "D0555 0 " -+ echo "X" -+ ;; -+badserver_6) -+ echo "D0555 0 ." -+ echo "X" -+ ;; -+badserver_7) -+ echo "C0755 2 extrafile" -+ echo "X" -+ ;; - *) - set -- $arg - shift -diff --git a/regress/scp.sh b/regress/scp.sh -index 57cc7706..104c89e1 100644 ---- a/regress/scp.sh -+++ b/regress/scp.sh -@@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp - scpclean() { - rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} - mkdir ${DIR} ${DIR2} -+ chmod 755 ${DIR} ${DIR2} - } - - verbose "$tid: simple copy local file to local file" -@@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then - $SUDO rm ${DIR2}/copy - fi - --for i in 0 1 2 3 4; do -+for i in 0 1 2 3 4 5 6 7; do - verbose "$tid: disallow bad server #$i" - SCPTESTMODE=badserver_$i - export DIR SCPTESTMODE -@@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do - scpclean - $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null - [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" -+ -+ scpclean -+ $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null -+ [ ! -w ${DIR2} ] && fail "allows target root attribute change" -+ -+ scpclean -+ $SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null -+ [ -e ${DIR2}/extrafile ] && fail "allows extranous object creation" -+ rm -f ${DIR2}/extrafile - done - - verbose "$tid: detect non-directory target" - diff --git a/openssh-8.0p1-gsissh.patch b/openssh-8.1p1-gsissh.patch similarity index 99% rename from openssh-8.0p1-gsissh.patch rename to openssh-8.1p1-gsissh.patch index 9990164..f467e21 100644 --- a/openssh-8.0p1-gsissh.patch +++ b/openssh-8.1p1-gsissh.patch @@ -1414,7 +1414,7 @@ diff -Nur openssh-8.0p1.orig/Makefile.in openssh-8.0p1/Makefile.in auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o sftp-realpath.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c --- openssh-8.0p1.orig/misc.c 2019-05-20 08:24:38.020776375 +0200 @@ -2420,7 +2420,7 @@ diff -Nur openssh-8.0p1.orig/version.h openssh-8.0p1/version.h +++ openssh-8.0p1/version.h 2019-05-20 08:25:21.592323010 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.0" + #define SSH_VERSION "OpenSSH_8.1" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/sources b/sources index bbbcdc2..6989a16 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.0p1.tar.gz) = e280fa2d56f550efd37c5d2477670326261aa8b94d991f9eb17aad90e0c6c9c939efa90fe87d33260d0f709485cb05c379f0fd1bd44fc0d5190298b6398c9982 -SHA512 (openssh-8.0p1.tar.gz.asc) = fe9e7383d9467e869762864f2b719165d9a3f2c5316c07067df1d45fc7819bd2cb8ef758454865595688804a4c160dd3d3aaee4c5f887859555d2c7bb8c4592b +SHA512 (openssh-8.1p1.tar.gz) = b987ea4ffd4ab0c94110723860273b06ed8ffb4d21cbd99ca144a4722dc55f4bf86f6253d500386b6bee7af50f066e2aa2dd095d50746509a10e11221d39d925 +SHA512 (openssh-8.1p1.tar.gz.asc) = f36458ef8822376a5b305cfbc971f5d2db8bf2f48fea9a957e02ef2fc27a48bacb59495587fee81fa2d89bca6250a8fb407e1f5a7dae7ceb361ab332c0771344 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From 2469144c2d5ef38237aa15dd8c3ce28fd1e40b71 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 29 Jan 2020 03:38:21 +0000 Subject: [PATCH 081/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index efb37df..0ce9ae3 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -512,6 +512,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Jan 29 2020 Fedora Release Engineering - 8.1p1-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Mon Oct 21 2019 Mattias Ellert - 8.1p1-1 - Based on openssh-8.1p1-1.fc31 From 9549c46d29dfeace232f1b49cfac04226958205c Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 14 Apr 2020 15:47:13 +0200 Subject: [PATCH 082/146] Based on openssh-8.2p1-3.fc32 --- gsi-openssh.spec | 39 +- openssh-5.1p1-askpass-progress.patch | 77 ++- openssh-6.6.1p1-log-in-chroot.patch | 4 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 2 +- openssh-6.6p1-ctr-cavstest.patch | 18 +- openssh-6.6p1-keycat.patch | 20 +- openssh-6.6p1-keyperm.patch | 29 +- openssh-6.6p1-kuserok.patch | 4 +- openssh-6.7p1-coverity.patch | 10 +- openssh-6.7p1-kdf-cavs.patch | 20 +- openssh-6.7p1-ldap.patch | 46 +- openssh-6.8p1-sshdT-output.patch | 4 +- openssh-7.6p1-audit.patch | 99 ++-- openssh-7.7p1-fips.patch | 310 +++------- openssh-7.7p1-redhat.patch | 135 ++--- openssh-7.8p1-UsePAM-warning.patch | 4 +- openssh-7.8p1-role-mls.patch | 4 +- openssh-8.0p1-crypto-policies.patch | 418 +++++++++++--- openssh-8.0p1-gssapi-keyex.patch | 358 ++++++------ openssh-8.0p1-pkcs11-uri.patch | 538 ++++++++++-------- ...gsissh.patch => openssh-8.2p1-gsissh.patch | 429 +++++++------- openssh-8.2p1-visibility.patch | 40 ++ openssh-8.2p1-x11-without-ipv6.patch | 30 + sources | 4 +- 24 files changed, 1475 insertions(+), 1167 deletions(-) rename openssh-8.1p1-gsissh.patch => openssh-8.2p1-gsissh.patch (87%) create mode 100644 openssh-8.2p1-visibility.patch create mode 100644 openssh-8.2p1-x11-without-ipv6.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 0ce9ae3..ea8f115 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,13 +30,13 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 8.1p1 +%global openssh_ver 8.2p1 %global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -141,6 +141,8 @@ 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 @@ -154,10 +156,14 @@ Patch962: openssh-8.0p1-crypto-policies.patch 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 # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-8.1p1-gsissh.patch +Patch98: openssh-8.2p1-gsissh.patch License: BSD Requires: /sbin/nologin @@ -169,11 +175,11 @@ BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel -BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel BuildRequires: gcc BuildRequires: p11-kit-devel +BuildRequires: libfido2-devel Recommends: p11-kit %if %{kerberos5} @@ -206,7 +212,6 @@ Summary: SSH client applications with GSI authentication Provides: gsissh-clients = %{version}-%{release} Obsoletes: gsissh-clients < 5.8p2-2 Requires: %{name} = %{version}-%{release} -Requires: fipscheck-lib%{_isa} >= 1.3.0 Requires: crypto-policies >= 20180306-1 %package server @@ -216,7 +221,6 @@ Obsoletes: gsissh-server < 5.8p2-2 Requires: %{name} = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 -Requires: fipscheck-lib%{_isa} >= 1.3.0 Requires: crypto-policies >= 20180306-1 %{?systemd_requires} @@ -301,6 +305,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp %patch964 -p1 -b .openssl-kdf +%patch965 -p1 -b .visibility +%patch966 -p1 -b .x11-ipv6 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -364,6 +370,7 @@ fi --without-hardening `# The hardening flags are configured by system` \ --with-systemd \ --with-default-pkcs11-provider=yes \ + --with-security-key-builtin=yes \ %if %{ldap} --with-ldap \ %endif @@ -391,18 +398,11 @@ fi make SSH_PROGRAM=%{_bindir}/gsissh \ ASKPASS_PROGRAM=%{_libexecdir}/openssh/ssh-askpass -# Add generation of HMAC checksums of the final stripped binaries -%global __spec_install_post \ - %%{?__debug_package:%%{__debug_install_post}} \ - %%{__arch_install_post} \ - %%{__os_install_post} \ - fipshmac -d $RPM_BUILD_ROOT%{_libdir}/fipscheck $RPM_BUILD_ROOT%{_bindir}/gsissh $RPM_BUILD_ROOT%{_sbindir}/gsisshd \ -%{nil} - %install rm -rf $RPM_BUILD_ROOT 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 DESTDIR=$RPM_BUILD_ROOT @@ -411,10 +411,10 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ldap.conf install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/sysconfig/ install -d $RPM_BUILD_ROOT%{_libexecdir}/gsissh -install -d $RPM_BUILD_ROOT%{_libdir}/fipscheck 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/etc/gsissh/ssh_config.d/05-redhat.conf +install -m644 sshd_config_redhat $RPM_BUILD_ROOT/etc/gsissh/sshd_config.d/05-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 @@ -434,12 +434,14 @@ rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-ldap-helper rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-ldap-wrapper 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}/man5/ssh-ldap.conf.5* rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-ldap-helper.8* 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}/* \ $RPM_BUILD_ROOT%{_sbindir}/* \ @@ -480,7 +482,6 @@ getent passwd sshd >/dev/null || \ %files clients %attr(0755,root,root) %{_bindir}/gsissh -%attr(0644,root,root) %{_libdir}/fipscheck/gsissh.hmac %attr(0644,root,root) %{_mandir}/man1/gsissh.1* %attr(0755,root,root) %{_bindir}/gsiscp %attr(0644,root,root) %{_mandir}/man1/gsiscp.1* @@ -494,7 +495,6 @@ getent passwd sshd >/dev/null || \ %files server %dir %attr(0711,root,root) %{_var}/empty/gsisshd %attr(0755,root,root) %{_sbindir}/gsisshd -%attr(0644,root,root) %{_libdir}/fipscheck/gsisshd.hmac %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* @@ -502,6 +502,8 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man8/gsisshd.8* %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/05-redhat.conf %attr(0644,root,root) %config(noreplace) /etc/pam.d/gsisshd %attr(0640,root,root) %config(noreplace) /etc/sysconfig/gsisshd %attr(0644,root,root) %{_unitdir}/gsisshd.service @@ -512,6 +514,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Apr 14 2020 Mattias Ellert - 8.2p1-1 +- Based on openssh-8.2p1-3.fc32 + * Wed Jan 29 2020 Fedora Release Engineering - 8.1p1-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index 6601fbf..21f6502 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -9,7 +9,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr #include #include -@@ -81,13 +82,24 @@ ok_dialog(GtkWidget *entry, gpointer dia +@@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); } @@ -25,57 +25,54 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr +} + static int - passphrase_dialog(char *message) + 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; - GtkWidget *parent_window, *dialog, *entry; + GtkWidget *parent_window, *dialog, *entry, *progress, *hbox; GdkGrabStatus status; grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); -@@ -104,14 +116,32 @@ passphrase_dialog(char *message) - "%s", - message); +@@ -104,16 +116,37 @@ passphrase_dialog(char *message) + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); -+ hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, -+ FALSE, 0); -+ gtk_widget_show(hbox); + if (prompt_type == PROMPT_ENTRY) { ++ hbox = gtk_hbox_new(FALSE, 0); ++ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, ++ FALSE, 0); ++ gtk_widget_show(hbox); + - entry = gtk_entry_new(); - 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); -+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); - gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); - gtk_widget_grab_focus(entry); - gtk_widget_show(entry); - -+ hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, + entry = gtk_entry_new(); + 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); ++ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + /* Make close dialog */ + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(ok_dialog), dialog); ++ ++ hbox = gtk_hbox_new(FALSE, 0); ++ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, + FALSE, 8); -+ gtk_widget_show(hbox); ++ gtk_widget_show(hbox); + -+ progress = gtk_progress_bar_new(); -+ -+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); -+ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, -+ TRUE, 5); -+ gtk_widget_show(progress); ++ progress = gtk_progress_bar_new(); + - gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); - gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); -@@ -120,6 +150,8 @@ passphrase_dialog(char *message) - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); -+ g_signal_connect(G_OBJECT(entry), "changed", -+ G_CALLBACK(move_progress), progress); - - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); ++ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); ++ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, ++ TRUE, 5); ++ gtk_widget_show(progress); ++ g_signal_connect(G_OBJECT(entry), "changed", ++ G_CALLBACK(move_progress), progress); ++ + } + /* Grab focus */ diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index f3f7cad..1260242 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -56,8 +56,8 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c + pmonitor->m_state = "postauth"; + monitor_set_child_handler(pmonitor->m_pid); - signal(SIGHUP, &monitor_child_handler); - signal(SIGTERM, &monitor_child_handler); + 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?)", diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index d943f41..01ea156 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -122,7 +122,7 @@ 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 no + #GSSAPICleanupCredentials yes #GSSAPIStrictAcceptorCheck yes #GSSAPIKeyExchange no +#GSSAPIEnablek5users no diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 2e31fbf..1e12dcc 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -7,26 +7,26 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in 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@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -66,7 +67,7 @@ EXEEXT=@EXEEXT@ - MKDIR_P=@MKDIR_P@ - INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ --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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(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-ldap-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-ldap-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 -lfipscheck $(KEYCATLIBS) $(LIBS) + $(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 -lfipscheck $(LIBS) ++ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.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 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index e22a5f3..b5e055a 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -41,34 +41,34 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper +SSH_KEYCAT=$(libexecdir)/ssh-keycat SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHLIBS=@SSHLIBS@ SSHDLIBS=@SSHDLIBS@ +KEYCATLIBS=@KEYCATLIBS@ LIBEDIT=@LIBEDIT@ + LIBFIDO2=@LIBFIDO2@ AR=@AR@ - AWK=@AWK@ @@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ - MKDIR_P=@MKDIR_P@ - INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ --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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) XMSS_OBJS=\ ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o -+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) ++ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.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) @@ -321,6 +325,7 @@ install-files: $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ diff --git a/openssh-6.6p1-keyperm.patch b/openssh-6.6p1-keyperm.patch index fbe33b0..5e06940 100644 --- a/openssh-6.6p1-keyperm.patch +++ b/openssh-6.6p1-keyperm.patch @@ -1,8 +1,7 @@ -diff --git a/authfile.c b/authfile.c -index e93d867..4fc5b3d 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -32,6 +32,7 @@ +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 #include @@ -10,17 +9,23 @@ index e93d867..4fc5b3d 100644 #include #include #include -@@ -207,6 +208,13 @@ sshkey_perm_ok(int fd, const char *filename) +@@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen #ifdef HAVE_CYGWIN if (check_ntsec(filename)) #endif -+ if (st.st_mode & 040) { -+ struct group *gr; -+ -+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) -+ st.st_mode &= ~040; -+ } + 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("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 56a6950..8428c1c 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -217,7 +217,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions - *activep = value; + *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; break; + case sKerberosUseKuserok: @@ -286,4 +286,4 @@ diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config +#KerberosUseKuserok yes # GSSAPI options - GSSAPIAuthentication yes + #GSSAPIAuthentication no diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 15d489d..3f34464 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -136,11 +136,11 @@ 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) - { - if (sshpid > 1) { - kill(sshpid, SIGTERM); -- waitpid(sshpid, NULL, 0); -+ (void) waitpid(sshpid, NULL, 0); + pid = sshpid; + if (pid > 1) { + kill(pid, SIGTERM); +- waitpid(pid, NULL, 0); ++ (void) waitpid(pid, NULL, 0); } _exit(1); diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index a5beb8c..40966d3 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -7,26 +7,26 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in 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@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -67,7 +68,7 @@ EXEEXT=@EXEEXT@ - MKDIR_P=@MKDIR_P@ - INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ --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-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(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-ldap-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-ldap-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 -lfipscheck $(LIBS) + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o -+ $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(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 ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.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) @@ -331,6 +335,8 @@ install-files: fi diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch index a8770e0..bf0dfe6 100644 --- a/openssh-6.7p1-ldap.patch +++ b/openssh-6.7p1-ldap.patch @@ -134,52 +134,54 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in +SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper +SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -50,6 +50,7 @@ - CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ + PICFLAG=@PICFLAG@ LIBS=@LIBS@ +LDAPLIBS=@LDAPLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHLIBS=@SSHLIBS@ -@@ -61,8 +63,9 @@ XAUTH_PATH=@XAUTH_PATH@ +@@ -61,10 +63,11 @@ XAUTH_PATH=@XAUTH_PATH@ EXEEXT=@EXEEXT@ MANFMT=@MANFMT@ MKDIR_P=@MKDIR_P@ +INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ --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) -+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-ldap-helper$(EXEEXT) + .SUFFIXES: .lo + +-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) XMSS_OBJS=\ ssh-xmss.o \ @@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o uidswap.o --MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out --MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 -+MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap-helper.8.out ssh-ldap.conf.5.out -+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 ssh-ldap-helper.8 ssh-ldap.conf.5 + SFTP_OBJS= sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o + +-MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out +-MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 ++MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap-helper.8.out ssh-ldap.conf.5.out ++MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 ssh-ldap-helper.8 ssh-ldap.conf.5 MANTYPE = @MANTYPE@ CONFIGFILES=sshd_config.out ssh_config.out moduli.out @@ -184,6 +187,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) + $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) +ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) ++ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS) + - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.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) @@ -311,6 +317,10 @@ install-files: - $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(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) + if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ + $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ + $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ @@ -188,9 +190,9 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 @@ -327,6 +337,10 @@ install-files: - $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 + $(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 + if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ + $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ + $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ @@ -213,18 +215,18 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in host-key: ssh-keygen$(EXEEXT) @if [ -z "$(DESTDIR)" ] ; then \ @@ -419,6 +440,8 @@ uninstall: - -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 @@ -430,6 +453,7 @@ uninstall: - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 regress-prep: @@ -233,8 +235,8 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac --- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 @@ -1605,6 +1605,110 @@ if test "x$use_pie" != "xno"; then - fi - fi + CFLAGS="$SAVED_CFLAGS" + AC_SUBST([PICFLAG]) +# Check whether user wants LDAP support +LDAP_MSG="no" diff --git a/openssh-6.8p1-sshdT-output.patch b/openssh-6.8p1-sshdT-output.patch index ac9169a..156e66d 100644 --- a/openssh-6.8p1-sshdT-output.patch +++ b/openssh-6.8p1-sshdT-output.patch @@ -3,8 +3,8 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c +++ 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 ? o->ciphers : KEX_SERVER_ENCRYPT); - dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); + 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); diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index a59cfc2..024d990 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -747,20 +747,21 @@ diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c 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)) == 0) + sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0) authenticated = 1; -@@ -175,6 +175,19 @@ done: +@@ -175,6 +175,20 @@ done: return authenticated; } +int +hostbased_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, -+ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat, ++ struct sshkey_sig_details **detailsp) +{ + int rv; + -+ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); ++ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat, detailsp); +#ifdef SSH_AUDIT_EVENTS + audit_key(ssh, 0, &rv, key); +#endif @@ -781,18 +782,19 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c + PRIVSEP(user_key_verify(ssh, key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, - ssh->compat)) == 0) { -@@ -278,6 +278,19 @@ done: + ssh->compat, &sig_details)) == 0) { +@@ -278,6 +278,20 @@ done: return authenticated; } +int +user_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, -+ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++ size_t slen, const u_char *data, size_t datalen, const char *pkalg, u_int compat, ++ struct sshkey_sig_details **detailsp) +{ + int rv; + -+ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat); ++ rv = sshkey_verify(key, sig, slen, data, datalen, pkalg, compat, detailsp); +#ifdef SSH_AUDIT_EVENTS + audit_key(ssh, 1, &rv, key); +#endif @@ -832,7 +834,7 @@ diff -up openssh/auth.h.audit openssh/auth.h char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); +int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int); ++ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); @@ -841,7 +843,7 @@ diff -up openssh/auth.h.audit openssh/auth.h int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *); +int hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int); ++ 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 *); @@ -973,9 +975,9 @@ diff -up openssh/kex.c.audit openssh/kex.c +#endif return SSH_ERR_NO_COMPRESS_ALG_MATCH; + } + #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; - } else if (strcmp(name, "zlib") == 0) { @@ -933,7 +946,7 @@ kex_choose_conf(struct ssh *ssh) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; @@ -1091,16 +1093,15 @@ diff -up openssh/mac.h.audit openssh/mac.h diff -up openssh/Makefile.in.audit openssh/Makefile.in --- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 +++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 -@@ -109,7 +109,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexgexc.o kexgexs.o \ +@@ -109,7 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ kexgssc.o \ -- platform-pledge.o platform-tracing.o platform-misc.o -+ platform-pledge.o platform-tracing.o platform-misc.o \ -+ auditstub.o + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ +- sshbuf-io.o ++ sshbuf-io.o auditstub.o + SKOBJS= ssh-sk-client.o - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ diff -up openssh/monitor.c.audit openssh/monitor.c --- openssh/monitor.c.audit 2019-04-03 17:02:20.674885671 +0200 +++ openssh/monitor.c 2019-04-03 17:03:17.201421405 +0200 @@ -1111,7 +1112,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c +#include "audit.h" #include "match.h" #include "ssherr.h" - + #include "sk-api.h" @@ -107,6 +108,8 @@ extern u_char session_id[]; extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1157,16 +1158,16 @@ diff -up openssh/monitor.c.audit openssh/monitor.c {0, 0, NULL} }; @@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int - char *sigalg; size_t signaturelen, datalen, bloblen; - int r, ret, valid_data = 0, encoded_ret; + int r, ret, req_presence = 0, valid_data = 0, encoded_ret; + struct sshkey_sig_details *sig_details = NULL; + int type = 0; -- if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || +- if ((r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 || + if ((r = sshbuf_get_u32(m, &type)) != 0 || -+ (r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || - (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || - (r = sshbuf_get_string(m, &data, &datalen)) != 0 || ++ (r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 || + (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || + (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) @@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || @@ -1177,19 +1178,19 @@ diff -up openssh/monitor.c.audit openssh/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1470,21 +1491,24 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1470,25 +1491,28 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: valid_data = monitor_valid_userblob(data, datalen); auth_method = "publickey"; + ret = user_key_verify(ssh, key, signature, signaturelen, data, -+ datalen, sigalg, ssh->compat); ++ datalen, sigalg, ssh->compat, &sig_details); break; case MM_HOSTKEY: valid_data = monitor_valid_hostbasedblob(data, datalen, hostbased_cuser, hostbased_chost); -+ ret = hostbased_key_verify(ssh, key, signature, signaturelen, data, -+ datalen, sigalg, ssh->compat); auth_method = "hostbased"; ++ ret = hostbased_key_verify(ssh, key, signature, signaturelen, data, ++ datalen, sigalg, ssh->compat, &sig_details); break; default: valid_data = 0; @@ -1199,11 +1200,15 @@ diff -up openssh/monitor.c.audit openssh/monitor.c if (!valid_data) fatal("%s: bad signature data blob", __func__); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + - ret = sshkey_verify(key, signature, signaturelen, data, datalen, -- sigalg, ssh->compat); - debug3("%s: %s %p signature %s", __func__, auth_method, key, - (ret == 0) ? "verified" : "unverified"); - auth2_record_key(authctxt, ret == 0, key); +- sigalg, ssh->compat, &sig_details); + debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, + (ret == 0) ? "verified" : "unverified", + (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); @@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session } @@ -1459,11 +1464,11 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c int -mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +mm_sshkey_verify(enum mm_keytype type, const struct sshkey *key, const u_char *sig, size_t siglen, - const u_char *data, size_t datalen, const char *sigalg, u_int compat) + const u_char *data, size_t datalen, const char *sigalg, u_int compat, + struct sshkey_sig_details **sig_detailsp) { - struct sshbuf *m; @@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke - + *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); - if ((r = sshkey_puts(key, m)) != 0 || @@ -1472,22 +1477,24 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -547,6 +548,20 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -547,6 +548,22 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } +int +mm_hostbased_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, size_t siglen, -+ const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat, ++ struct sshkey_sig_details **detailsp) +{ -+ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, pkalg, compat); ++ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, pkalg, compat, detailsp); +} + +int +mm_user_key_verify(struct ssh *ssh, const struct sshkey *key, const u_char *sig, size_t siglen, -+ const u_char *data, size_t datalen, const char *pkalg, u_int compat) ++ const u_char *data, size_t datalen, const char *pkalg, u_int compat, ++ struct sshkey_sig_details **detailsp) +{ -+ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, pkalg, compat); ++ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, pkalg, compat, detailsp); +} + void @@ -1632,9 +1639,9 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h const char *, struct sshkey *); -int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +int mm_hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int); ++ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); +int mm_user_key_verify(struct ssh*, const struct sshkey *, const u_char *, size_t, - const u_char *, size_t, const char *, u_int); + const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); #ifdef GSSAPI @@ -82,7 +84,12 @@ void mm_sshpam_free_ctx(void *); @@ -1655,7 +1662,7 @@ diff -up openssh/packet.c.audit openssh/packet.c --- openssh/packet.c.audit 2019-03-27 23:26:14.000000000 +0100 +++ openssh/packet.c 2019-04-03 17:02:20.716886069 +0200 @@ -77,6 +77,7 @@ - #include + #endif #include "xmalloc.h" +#include "audit.h" @@ -1705,7 +1712,7 @@ diff -up openssh/packet.c.audit openssh/packet.c kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; @@ -636,8 +641,18 @@ ssh_packet_close_internal(struct ssh *ss - } + #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); + if (had_keys && state->server_side) { @@ -2041,7 +2048,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c +void demote_sensitive_data(struct ssh *); static void do_ssh2_kex(struct ssh *); - /* + static char *listener_proctitle; @@ -278,6 +279,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2314,5 +2321,5 @@ diff -up openssh/sshkey.h.audit openssh/sshkey.h int sshkey_type_from_name(const char *); +int sshkey_is_private(const struct sshkey *); int sshkey_is_cert(const struct sshkey *); + int sshkey_is_sk(const struct sshkey *); int sshkey_type_is_cert(int); - int sshkey_type_plain(int); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 36af30a..21eba1d 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -11,19 +11,6 @@ diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-8.0p1/clientloop.c.fips openssh-8.0p1/clientloop.c ---- openssh-8.0p1/clientloop.c.fips 2019-07-23 14:55:45.331525692 +0200 -+++ openssh-8.0p1/clientloop.c 2019-07-23 14:55:45.401526401 +0200 -@@ -2049,7 +2049,8 @@ key_accepted_by_hostkeyalgs(const struct - { - const char *ktype = sshkey_ssh_name(key); - const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? -- options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG; -+ options.hostkeyalgorithms : (FIPS_mode() ? -+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG); - - if (key == NULL || key->type == KEY_UNSPEC) - return 0; 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 @@ -127,140 +114,83 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-8.0p1/Makefile.in.fips openssh-8.0p1/Makefile.in ---- openssh-8.0p1/Makefile.in.fips 2019-07-23 14:55:45.396526350 +0200 -+++ openssh-8.0p1/Makefile.in 2019-07-23 14:55:45.402526411 +0200 -@@ -180,25 +180,25 @@ libssh.a: $(LIBSSH_OBJS) - $(RANLIB) $@ - - ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) -- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) -+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) - - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o -- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o -- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o sshsig.o -- $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o -- $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -216,7 +216,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a - $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o -- $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-realpath.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-realpath.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 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,16 @@ +@@ -111,6 +111,20 @@ "rsa-sha2-256," \ "ssh-rsa" +#define KEX_FIPS_PK_ALG \ -+ HOSTKEY_ECDSA_CERT_METHODS \ ++ "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," \ -+ HOSTKEY_ECDSA_METHODS \ ++ "ecdsa-sha2-nistp256," \ ++ "ecdsa-sha2-nistp384," \ ++ "ecdsa-sha2-nistp521," \ + "rsa-sha2-512," \ + "rsa-sha2-256," \ + "ssh-rsa" + - /* the actual algorithms */ - - #define KEX_SERVER_ENCRYPT \ -@@ -134,6 +142,38 @@ + #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" \ -+ AESGCM_CIPHER_MODES -+#ifdef HAVE_EVP_SHA256 -+# define KEX_DEFAULT_KEX_FIPS \ -+ KEX_ECDH_METHODS \ -+ KEX_SHA2_METHODS \ ++ "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 \ ++#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" -+#else -+# ifdef OPENSSL_HAS_NISTP521 -+# define KEX_DEFAULT_KEX_FIPS \ -+ "ecdh-sha2-nistp256," \ -+ "ecdh-sha2-nistp384," \ -+ "ecdh-sha2-nistp521" -+# else -+# define KEX_DEFAULT_KEX_FIPS \ -+ "ecdh-sha2-nistp256," \ -+ "ecdh-sha2-nistp384" -+# endif -+#define KEX_FIPS_MAC \ -+ "hmac-sha1" -+#endif + /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ - HOSTKEY_ECDSA_METHODS \ + "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,18 +2179,19 @@ fill_default_options(Options * options) - all_kex = kex_alg_list(','); +@@ -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, ','); --#define ASSEMBLE(what, defaults, all) \ -+#define ASSEMBLE(what, defaults, fips_defaults, all) \ + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_whitelist(KEX_CLIENT_ENCRYPT, all_cipher); +- def_mac = match_filter_whitelist(KEX_CLIENT_MAC, all_mac); +- def_kex = match_filter_whitelist(KEX_CLIENT_KEX, all_kex); +- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); ++ def_mac = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); ++ def_kex = match_filter_whitelist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); ++ def_key = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_whitelist((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, \ -- defaults, all)) != 0) \ -+ (FIPS_mode() ? fips_defaults : defaults), \ -+ all)) != 0) \ - fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ - } while (0) -- ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher); -- ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac); -- ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex); -- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); -- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); -- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); -+ ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); -+ ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac); -+ ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); -+ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); -+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); -+ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig); - #undef ASSEMBLE - free(all_cipher); - free(all_mac); 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 @@ -277,75 +207,50 @@ diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-secco 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,18 +208,19 @@ assemble_algorithms(ServerOptions *o) - all_kex = kex_alg_list(','); +@@ -208,11 +208,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); --#define ASSEMBLE(what, defaults, all) \ -+#define ASSEMBLE(what, defaults, fips_defaults, all) \ + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_whitelist(KEX_SERVER_ENCRYPT, all_cipher); +- def_mac = match_filter_whitelist(KEX_SERVER_MAC, all_mac); +- def_kex = match_filter_whitelist(KEX_SERVER_KEX, all_kex); +- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); ++ def_mac = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); ++ def_kex = match_filter_whitelist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); ++ def_key = match_filter_whitelist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_whitelist((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) \ -+ if ((r = kex_assemble_names(&o->what, (FIPS_mode() \ -+ ? fips_defaults : defaults), all)) != 0) \ - fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ - } while (0) -- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); -- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); -- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); -- ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); -- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); -- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); -- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); -+ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher); -+ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac); -+ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex); -+ ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); -+ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); -+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key); -+ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig); - #undef ASSEMBLE - free(all_cipher); - free(all_mac); + 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,8 @@ +@@ -76,6 +76,7 @@ #include #include #endif +#include -+#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -600,6 +602,16 @@ main(int ac, char **av) - sanitise_stdfd(); - - __progname = ssh_get_progname(av[0]); -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ SSLeay_add_all_algorithms(); -+#endif -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)){ -+ if (FIPS_mode()) -+ fatal("FIPS integrity verification test failed."); -+ else -+ logit("FIPS integrity verification test failed."); -+ } - - #ifndef HAVE_SETPROCTITLE - /* Prepare for later setproctitle emulation */ @@ -614,6 +626,10 @@ main(int ac, char **av) - - seed_rng(); - -+ if (FIPS_mode()) { -+ logit("FIPS mode initialized"); -+ } + dump_client_config(&options, host); + exit(0); + } + - /* - * Discard other fds that are hanging around. These can cause problem - * with backgrounded ssh processes started by ControlPersist. ++ 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 @@ -358,36 +263,7 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -115,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc - for (i = 0; i < options.num_system_hostfiles; i++) - load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); - -- oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); -+ oavail = avail = xstrdup((FIPS_mode() -+ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); - maxlen = strlen(avail) + 1; - first = xmalloc(maxlen); - last = xmalloc(maxlen); -@@ -182,14 +185,16 @@ ssh_kex2(struct ssh *ssh, char *host, st - if (options.hostkeyalgorithms != NULL) { - all_key = sshkey_alg_list(0, 0, 1, ','); - if (kex_assemble_names(&options.hostkeyalgorithms, -- KEX_DEFAULT_PK_ALG, all_key) != 0) -+ (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), -+ all_key) != 0) - fatal("%s: kex_assemble_namelist", __func__); - free(all_key); - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - compat_pkalg_proposal(options.hostkeyalgorithms); - } else { - /* Enforce default */ -- options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); -+ options.hostkeyalgorithms = xstrdup((FIPS_mode() -+ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); - /* Prefer algorithms that we already have keys for */ - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - compat_pkalg_proposal( -@@ -198,29 +203,34 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -198,36 +203,41 @@ ssh_kex2(struct ssh *ssh, char *host, st #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -395,12 +271,19 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c - * client to the key exchange algorithm proposal */ - orig = myproposal[PROPOSAL_KEX_ALGS]; - -- if (options.gss_server_identity) +- if (options.gss_server_identity) { - gss_host = xstrdup(options.gss_server_identity); -- else if (options.gss_trust_dns) +- } else if (options.gss_trust_dns) { - gss_host = remote_hostname(ssh); -- else +- /* 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); @@ -422,12 +305,19 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; + -+ if (options.gss_server_identity) ++ if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) ++ } else if (options.gss_trust_dns) { + gss_host = remote_hostname(ssh); -+ else ++ /* 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); @@ -456,31 +346,19 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c #include #include #include -@@ -77,6 +78,8 @@ +@@ -77,6 +78,7 @@ #include #include #include +#include -+#include #include "openbsd-compat/openssl-compat.h" #endif -@@ -1529,6 +1532,18 @@ main(int ac, char **av) +@@ -1529,6 +1532,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); + OpenSSL_add_all_algorithms(); -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) { -+ openlog(__progname, LOG_PID, LOG_AUTHPRIV); -+ if (FIPS_mode()) { -+ syslog(LOG_CRIT, "FIPS integrity verification test failed."); -+ cleanup_exit(255); -+ } -+ else -+ syslog(LOG_INFO, "FIPS integrity verification test failed."); -+ closelog(); -+ } /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; @@ -489,7 +367,7 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c log_init(__progname, options.log_level, options.log_facility, log_stderr); + if (FIPS_mode()) { -+ logit("FIPS mode initialized"); ++ debug("FIPS mode initialized"); + } + /* Chdir to the root directory so that the current disk can be @@ -530,9 +408,9 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c #include "sshkey.h" #include "match.h" +#include "log.h" + #include "ssh-sk.h" #ifdef WITH_XMSS - #include "sshkey-xmss.h" @@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 6fd9daf..6c8d539 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -1,17 +1,20 @@ -diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config ---- openssh-7.7p1/ssh_config.redhat 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/ssh_config 2018-07-03 10:44:06.522245125 +0200 -@@ -44,3 +44,7 @@ +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 @@ # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h +# -+# To modify the system-wide ssh configuration, create a *.conf file under -+# /etc/ssh/ssh_config.d/ which will be automatically included below ++# This system is following system-wide crypto policy. ++# To modify the crypto properties (Ciphers, MACs, ...), create a *.conf ++# file under /etc/ssh/ssh_config.d/ which will be automatically ++# included below. For more information, see manual page for ++# update-crypto-policies(8) and ssh_config(5). +Include /etc/ssh/ssh_config.d/*.conf -diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat ---- openssh-7.7p1/ssh_config_redhat.redhat 2018-07-03 10:44:06.522245125 +0200 -+++ openssh-7.7p1/ssh_config_redhat 2018-07-03 10:44:06.522245125 +0200 +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 @@ -34,11 +37,10 @@ diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat + +# Uncomment this if you want to use .local domain +# Host *.local -+# CheckHostIP no -diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0 ---- openssh-7.7p1/sshd_config.0.redhat 2018-04-02 07:39:27.000000000 +0200 -+++ openssh-7.7p1/sshd_config.0 2018-07-03 10:44:06.523245133 +0200 -@@ -872,9 +872,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 @@ -51,10 +53,10 @@ diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0 TCPKeepAlive Specifies whether the system should send TCP keepalive messages -diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5 ---- openssh-7.7p1/sshd_config.5.redhat 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/sshd_config.5 2018-07-03 10:44:06.523245133 +0200 -@@ -1461,7 +1461,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 . @@ -63,10 +65,10 @@ diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive -diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config ---- openssh-7.7p1/sshd_config.redhat 2018-04-02 07:38:28.000000000 +0200 -+++ openssh-7.7p1/sshd_config 2018-07-03 10:45:16.950782466 +0200 -@@ -10,20 +10,34 @@ +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,10 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -77,90 +79,43 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 - #ListenAddress :: - --#HostKey /etc/ssh/ssh_host_rsa_key --#HostKey /etc/ssh/ssh_host_ecdsa_key --#HostKey /etc/ssh/ssh_host_ed25519_key -+HostKey /etc/ssh/ssh_host_rsa_key -+HostKey /etc/ssh/ssh_host_ecdsa_key -+HostKey /etc/ssh/ssh_host_ed25519_key - - # Ciphers and keying - #RekeyLimit default none - -+# System-wide Crypto policy: -+# This system is following system-wide crypto policy. The changes to -+# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any -+# effect here. They will be overridden by command-line options passed on -+# the server start up. -+# To opt out, uncomment a line with redefinition of CRYPTO_POLICY= -+# variable in /etc/sysconfig/sshd to overwrite the policy. -+# For more information, see manual page for update-crypto-policies(8). +@@ -114,3 +118,7 @@ Subsystem sftp /usr/libexec/sftp-server + # AllowTcpForwarding no + # PermitTTY no + # ForceCommand cvs server ++ ++# 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 +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 here. ++# They will be overridden by command-line options passed to the server ++# on command line. ++# Please, check manual pages for update-crypto-policies(8) and sshd_config(5). + - # Logging - #SyslogFacility AUTH +SyslogFacility AUTHPRIV - #LogLevel INFO - - # Authentication: -@@ -56,9 +70,11 @@ AuthorizedKeysFile .ssh/authorized_keys - # To disable tunneled clear text passwords, change to no here! - #PasswordAuthentication yes - #PermitEmptyPasswords no ++ +PasswordAuthentication yes - - # Change to no to disable s/key passwords - #ChallengeResponseAuthentication yes +ChallengeResponseAuthentication no - - # Kerberos options - #KerberosAuthentication no -@@ -67,8 +83,8 @@ AuthorizedKeysFile .ssh/authorized_keys - #KerberosGetAFSToken no - - # GSSAPI options --#GSSAPIAuthentication no --#GSSAPICleanupCredentials yes ++ +GSSAPIAuthentication yes +GSSAPICleanupCredentials no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -79,16 +95,20 @@ 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 ChallengeResponseAuthentication to 'no'. --#UsePAM no ++ +UsePAM yes - - #AllowAgentForwarding yes - #AllowTcpForwarding yes - #GatewayPorts no --#X11Forwarding no ++ +X11Forwarding yes - #X11DisplayOffset 10 - #X11UseLocalhost yes - #PermitTTY yes --#PrintMotd yes + +# 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 + - #PrintLastLog yes - #TCPKeepAlive yes - #PermitUserEnvironment no -@@ -106,6 +126,12 @@ AuthorizedKeysFile .ssh/authorized_keys - # no default banner path - #Banner none - +# 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 + - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index ef2c737..d4c53db 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -3,7 +3,7 @@ diff --git a/sshd.c b/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, NULL); + cfg, &includes, NULL); + /* 'UsePAM no' is not supported in Fedora */ + if (! options.use_pam) @@ -21,6 +21,6 @@ diff --git a/sshd_config b/sshd_config # and ChallengeResponseAuthentication to 'no'. +# WARNING: 'UsePAM no' is not supported in Fedora and may cause several +# problems. - UsePAM yes + #UsePAM no #AllowAgentForwarding yes diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index da0abd7..fb7ce7c 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -339,7 +339,7 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h +++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200 @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int); int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, - const u_char *, size_t, const char *, u_int compat); + const u_char *, size_t, const char *, const char *, u_int compat); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -359,7 +359,7 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make + port-linux-sshd.o .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c --- openssh/openbsd-compat/port-linux.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/openbsd-compat/port-linux.c 2018-08-22 11:14:56.819430949 +0200 diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 37263a5..b23599d 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,60 @@ -diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 ---- openssh-8.0p1/ssh_config.5.crypto-policies 2019-05-13 14:04:01.999099570 +0200 -+++ openssh-8.0p1/ssh_config.5 2019-05-13 14:12:36.343923071 +0200 -@@ -445,12 +445,10 @@ aes256-gcm@openssh.com +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 ++character, then the specified ciphers will be appended to the built-in 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 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 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 @@ -11,30 +64,59 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -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 available ciphers may also be obtained using - .Qq ssh -Q cipher . -@@ -812,8 +810,10 @@ gss-nistp256-sha256-, ++.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-gex-sha1-,gss-group14-sha1- . +-.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 . - This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HashKnownHosts - Indicates that -@@ -1123,16 +1123,10 @@ If the specified value begins with a ++.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 ++character, then the specified methods will be appended to the built-in 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 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. +-default set. -The default is: -.Bd -literal -offset indent -curve25519-sha256,curve25519-sha256@libssh.org, @@ -42,17 +124,43 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -diffie-hellman-group-exchange-sha256, -diffie-hellman-group16-sha512, -diffie-hellman-group18-sha512, --diffie-hellman-group14-sha256, --diffie-hellman-group14-sha1 +-diffie-hellman-group14-sha256 -.Ed ++built-in 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 ++character, then the specified algorithms will be appended to the built-in 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 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 default set. .Pp - The list of available key exchange algorithms may also be obtained using - .Qq ssh -Q kex . -@@ -1210,14 +1204,10 @@ The algorithms that contain + The algorithms that contain + .Qq -etm calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. .Pp @@ -64,39 +172,111 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 -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 - The list of available MAC algorithms may also be obtained using - .Qq ssh -Q mac . -@@ -1361,17 +1351,10 @@ If the specified value begins with a ++.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 ++character, then the key types after it will be appended to the built-in 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 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. +-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, --rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-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, --ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-sk-ecdsa-sha2-nistp256@openssh.com, +-ssh-ed25519,sk-ssh-ed25519@openssh.com, +-rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed ++built-in 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 ++character, then the specified ciphers will be appended to the built-in 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 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 default set. .Pp - The list of available key types may also be obtained using - .Qq ssh -Q key . -diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 ---- openssh-8.0p1/sshd_config.5.crypto-policies 2019-05-13 14:12:41.226968863 +0200 -+++ openssh-8.0p1/sshd_config.5 2019-05-13 14:15:14.581406997 +0200 -@@ -490,12 +490,10 @@ aes256-gcm@openssh.com + The supported ciphers are: + .Pp +@@ -486,13 +491,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp @@ -106,28 +286,54 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com -.Ed -+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 +-.Pp The list of available ciphers may also be obtained using .Qq ssh -Q cipher . -@@ -700,8 +698,10 @@ gss-nistp256-sha256-, - gss-curve25519-sha256- - .Ed - .Pp --The default is --.Dq gss-gex-sha1-,gss-group14-sha1- . + .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 . - This option only applies to protocol version 2 connections using GSSAPI. ++.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 -@@ -792,17 +792,10 @@ environment variable. + 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: @@ -135,21 +341,52 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -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, --rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-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, --ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-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 ++character, then the specified methods will be appended to the built-in 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 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 default set. + The supported algorithms are: .Pp - The list of available key types may also be obtained using - .Qq ssh -Q key . -@@ -960,14 +953,10 @@ ecdh-sha2-nistp384 - ecdh-sha2-nistp521 + .Bl -item -compact -offset indent +@@ -988,15 +981,6 @@ ecdh-sha2-nistp521 + sntrup4591761x25519-sha512@tinyssh.org .El .Pp -The default is: @@ -158,16 +395,43 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -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,diffie-hellman-group14-sha1 +-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 ++character, then the specified algorithms will be appended to the built-in 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 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 default set. .Pp - The list of available key exchange algorithms may also be obtained using - .Qq ssh -Q kex . -@@ -1090,14 +1079,10 @@ umac-64-etm@openssh.com + The algorithms that contain + .Qq -etm +@@ -1122,15 +1111,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -179,32 +443,52 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 -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 - The list of available MAC algorithms may also be obtained using - .Qq ssh -Q mac . -@@ -1455,17 +1440,10 @@ If the specified value begins with a ++.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 ++character, then the specified key types will be appended to the built-in 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 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. +-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, --rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-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, --ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-sk-ecdsa-sha2-nistp256@openssh.com, +-ssh-ed25519,sk-ssh-ed25519@openssh.com, +-rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -+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 . ++built-in default set. .Pp The list of available key types may also be obtained using - .Qq ssh -Q key . + .Qq ssh -Q PubkeyAcceptedKeyTypes . diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 631c824..8c6de02 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1,29 +1,29 @@ diff --git a/Makefile.in b/Makefile.in -index 6f001bb3..c31821ac 100644 +index e7549470..b68c1710 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexgssc.o \ - platform-pledge.o platform-tracing.o platform-misc.o + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sshbuf-io.o - -@@ -114,7 +115,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ +@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.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 \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o sftp-realpath.o \ + sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/auth.c b/auth.c -index 332b6220..7664aaac 100644 +index 086b8ebb..687c57b4 100644 --- a/auth.c +++ b/auth.c -@@ -399,7 +399,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +@@ -400,7 +400,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -33,7 +33,7 @@ index 332b6220..7664aaac 100644 return 1; break; case PERMIT_FORCED_ONLY: -@@ -723,99 +724,6 @@ fakepw(void) +@@ -724,99 +725,6 @@ fakepw(void) return (&fake); } @@ -62,7 +62,7 @@ index 332b6220..7664aaac 100644 - if (getpeername(ssh_packet_get_connection_in(ssh), - (struct sockaddr *)&from, &fromlen) == -1) { - debug("getpeername failed: %.100s", strerror(errno)); -- return strdup(ntop); +- return xstrdup(ntop); - } - - ipv64_normalise_mapped(&from, &fromlen); @@ -74,7 +74,7 @@ index 332b6220..7664aaac 100644 - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) != 0) { - /* Host name not found. Use ip address. */ -- return strdup(ntop); +- return xstrdup(ntop); - } - - /* @@ -89,7 +89,7 @@ index 332b6220..7664aaac 100644 - logit("Nasty PTR record \"%s\" is set up for %s, ignoring", - name, ntop); - freeaddrinfo(ai); -- return strdup(ntop); +- return xstrdup(ntop); - } - - /* Names are stored in lowercase. */ @@ -110,7 +110,7 @@ index 332b6220..7664aaac 100644 - if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { - logit("reverse mapping checking getaddrinfo for %.700s " - "[%s] failed.", name, ntop); -- return strdup(ntop); +- return xstrdup(ntop); - } - /* Look for the address from the list of addresses. */ - for (ai = aitop; ai; ai = ai->ai_next) { @@ -125,9 +125,9 @@ index 332b6220..7664aaac 100644 - /* 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 strdup(ntop); +- return xstrdup(ntop); - } -- return strdup(name); +- return xstrdup(name); -} - /* @@ -229,10 +229,10 @@ index 9351e042..d6446c0c 100644 "gssapi-with-mic", userauth_gssapi, diff --git a/auth2.c b/auth2.c -index 16ae1a36..7417eafa 100644 +index 0e776224..1c217268 100644 --- a/auth2.c +++ b/auth2.c -@@ -75,6 +75,7 @@ extern Authmethod method_passwd; +@@ -73,6 +73,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -240,7 +240,7 @@ index 16ae1a36..7417eafa 100644 extern Authmethod method_gssapi; #endif -@@ -82,6 +83,7 @@ Authmethod *authmethods[] = { +@@ -80,6 +81,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -249,7 +249,7 @@ index 16ae1a36..7417eafa 100644 #endif &method_passwd, diff --git a/canohost.c b/canohost.c -index f71a0856..404731d2 100644 +index abea9c6e..8e81b519 100644 --- a/canohost.c +++ b/canohost.c @@ -35,6 +35,99 @@ @@ -281,7 +281,7 @@ index f71a0856..404731d2 100644 + if (getpeername(ssh_packet_get_connection_in(ssh), + (struct sockaddr *)&from, &fromlen) == -1) { + debug("getpeername failed: %.100s", strerror(errno)); -+ return strdup(ntop); ++ return xstrdup(ntop); + } + + ipv64_normalise_mapped(&from, &fromlen); @@ -293,7 +293,7 @@ index f71a0856..404731d2 100644 + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) != 0) { + /* Host name not found. Use ip address. */ -+ return strdup(ntop); ++ return xstrdup(ntop); + } + + /* @@ -308,7 +308,7 @@ index f71a0856..404731d2 100644 + logit("Nasty PTR record \"%s\" is set up for %s, ignoring", + name, ntop); + freeaddrinfo(ai); -+ return strdup(ntop); ++ return xstrdup(ntop); + } + + /* Names are stored in lowercase. */ @@ -329,7 +329,7 @@ index f71a0856..404731d2 100644 + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + logit("reverse mapping checking getaddrinfo for %.700s " + "[%s] failed.", name, ntop); -+ return strdup(ntop); ++ return xstrdup(ntop); + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { @@ -344,9 +344,9 @@ index f71a0856..404731d2 100644 + /* 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 strdup(ntop); ++ return xstrdup(ntop); + } -+ return strdup(name); ++ return xstrdup(name); +} + void @@ -367,7 +367,7 @@ index 26d62855..0cadc9f1 100644 int get_peer_port(int); char *get_local_ipaddr(int); diff --git a/clientloop.c b/clientloop.c -index 521467bd..a0578e9d 100644 +index ebd0dbca..1bdac6a4 100644 --- a/clientloop.c +++ b/clientloop.c @@ -112,6 +112,10 @@ @@ -381,7 +381,7 @@ index 521467bd..a0578e9d 100644 /* import options */ extern Options options; -@@ -1374,9 +1378,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, break; /* Do channel operations unless rekeying in progress. */ @@ -402,10 +402,10 @@ index 521467bd..a0578e9d 100644 client_process_net_input(ssh, readset); diff --git a/configure.ac b/configure.ac -index 30be6c18..2869f704 100644 +index b689db4b..efafb6bd 100644 --- a/configure.ac +++ b/configure.ac -@@ -665,6 +665,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -674,6 +674,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -437,7 +437,7 @@ index 30be6c18..2869f704 100644 AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --git a/gss-genr.c b/gss-genr.c -index d56257b4..3eaa5fa5 100644 +index d56257b4..763a63ff 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ @@ -486,7 +486,7 @@ index d56257b4..3eaa5fa5 100644 /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,161 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -62,6 +86,162 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -530,7 +530,8 @@ index d56257b4..3eaa5fa5 100644 + const char *host, const char *client, const char *kex) { + struct sshbuf *buf = NULL; + size_t i; -+ int r, oidpos, enclen; ++ int r = SSH_ERR_ALLOC_FAIL; ++ int oidpos, enclen; + char *mechs, *encoded; + u_char digest[SSH_DIGEST_MAX_LENGTH]; + char deroid[2]; @@ -648,7 +649,7 @@ index d56257b4..3eaa5fa5 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -218,7 +397,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -218,7 +398,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -657,7 +658,7 @@ index d56257b4..3eaa5fa5 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -247,9 +426,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +@@ -247,9 +427,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) return (ctx->major); } @@ -701,7 +702,7 @@ index d56257b4..3eaa5fa5 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -257,6 +470,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -257,6 +471,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -721,7 +722,7 @@ index d56257b4..3eaa5fa5 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context) -@@ -273,11 +499,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } int @@ -739,7 +740,7 @@ index d56257b4..3eaa5fa5 100644 /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -287,6 +518,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -287,6 +519,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); @@ -750,7 +751,7 @@ index d56257b4..3eaa5fa5 100644 if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -296,10 +531,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -296,10 +532,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -1259,10 +1260,10 @@ index ab3a15f0..6ce56e92 100644 /* Privileged */ diff --git a/kex.c b/kex.c -index 34808b5c..a2a4794e 100644 +index ce85f043..574c7609 100644 --- a/kex.c +++ b/kex.c -@@ -55,11 +55,16 @@ +@@ -57,11 +57,16 @@ #include "misc.h" #include "dispatch.h" #include "monitor.h" @@ -1279,7 +1280,7 @@ index 34808b5c..a2a4794e 100644 /* prototype */ static int kex_choose_conf(struct ssh *); static int kex_input_newkeys(int, u_int32_t, struct ssh *); -@@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { +@@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, 0, -1, -1}, }; @@ -1294,7 +1295,7 @@ index 34808b5c..a2a4794e 100644 + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif -+ { NULL, 0, -1, -1 }, ++ { NULL, 0, -1, -1}, +}; -char * @@ -1311,7 +1312,7 @@ index 34808b5c..a2a4794e 100644 if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); -@@ -136,6 +154,18 @@ kex_alg_list(char sep) +@@ -138,6 +156,18 @@ kex_alg_list(char sep) return ret; } @@ -1330,7 +1331,7 @@ index 34808b5c..a2a4794e 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -145,6 +175,10 @@ kex_alg_by_name(const char *name) +@@ -147,6 +177,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1341,7 +1342,7 @@ index 34808b5c..a2a4794e 100644 return NULL; } -@@ -301,6 +335,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) +@@ -315,6 +349,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) return r; } @@ -1371,7 +1372,7 @@ index 34808b5c..a2a4794e 100644 /* put algorithm proposal into buffer */ int kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) -@@ -657,6 +714,9 @@ kex_free(struct kex *kex) +@@ -698,6 +755,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); free(kex->session_id); @@ -1382,10 +1383,10 @@ index 34808b5c..a2a4794e 100644 free(kex->hostkey_alg); free(kex->name); diff --git a/kex.h b/kex.h -index 6d446d1c..f95dc02c 100644 +index a5ae6ac0..fe714141 100644 --- a/kex.h +++ b/kex.h -@@ -103,6 +103,15 @@ enum kex_exchange { +@@ -102,6 +102,15 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, KEX_KEM_SNTRUP4591761X25519_SHA512, @@ -1401,7 +1402,7 @@ index 6d446d1c..f95dc02c 100644 KEX_MAX }; -@@ -154,6 +163,12 @@ struct kex { +@@ -153,6 +162,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1414,7 +1415,7 @@ index 6d446d1c..f95dc02c 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -175,8 +190,10 @@ struct kex { +@@ -174,8 +189,10 @@ struct kex { int kex_names_valid(const char *); char *kex_alg_list(char); @@ -1425,11 +1426,11 @@ index 6d446d1c..f95dc02c 100644 int kex_exchange_identification(struct ssh *, int, const char *); -@@ -203,6 +220,12 @@ int kexgex_client(struct ssh *); +@@ -202,6 +219,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); -+#ifdef GSSAPI ++#if defined(GSSAPI) && defined(WITH_OPENSSL) +int kexgssgex_client(struct ssh *); +int kexgssgex_server(struct ssh *); +int kexgss_client(struct ssh *); @@ -1438,7 +1439,7 @@ index 6d446d1c..f95dc02c 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -235,6 +258,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -234,6 +257,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1480,10 +1481,10 @@ index 67133e33..edaa4676 100644 break; case KEX_DH_GRP18_SHA512: diff --git a/kexgen.c b/kexgen.c -index 2abbb9ef..569dc83f 100644 +index 69348b96..c0e8c2f4 100644 --- a/kexgen.c +++ b/kexgen.c -@@ -43,7 +43,7 @@ +@@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1494,10 +1495,10 @@ index 2abbb9ef..569dc83f 100644 const struct sshbuf *client_version, diff --git a/kexgssc.c b/kexgssc.c new file mode 100644 -index 00000000..0b2f6a56 +index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,595 @@ +@@ -0,0 +1,606 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1559,7 +1560,7 @@ index 00000000..0b2f6a56 + struct sshbuf *server_blob = NULL; + struct sshbuf *shared_secret = NULL; + struct sshbuf *server_host_key_blob = NULL; -+ struct sshbuf *empty = sshbuf_new(); ++ struct sshbuf *empty = NULL; + u_char *msg; + int type = 0; + int first = 1; @@ -1767,6 +1768,11 @@ index 00000000..0b2f6a56 + if (r != 0) + goto out; + ++ if ((empty = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ + hashlen = sizeof(hash); + if ((r = kex_gen_hash( + kex->hash_alg, @@ -1836,7 +1842,7 @@ index 00000000..0b2f6a56 + size_t hashlen; + const BIGNUM *pub_key, *dh_p, *dh_g; + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; -+ struct sshbuf *empty = sshbuf_new(); ++ struct sshbuf *empty = NULL; + u_char c; + int r; + @@ -2028,6 +2034,7 @@ index 00000000..0b2f6a56 + (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) + goto out; + sshbuf_free(buf); ++ buf = NULL; + + if ((shared_secret = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; @@ -2036,6 +2043,10 @@ index 00000000..0b2f6a56 + + if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) + goto out; ++ if ((empty = sshbuf_new()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); + hashlen = sizeof(hash); @@ -2082,6 +2093,7 @@ index 00000000..0b2f6a56 + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); +out: ++ sshbuf_free(buf); + sshbuf_free(server_blob); + sshbuf_free(empty); + explicit_bzero(hash, sizeof(hash)); @@ -2574,19 +2586,19 @@ index 00000000..60bc02de +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index 60e52944..669cdb4a 100644 +index 2ce89fe9..ebf76c7f 100644 --- a/monitor.c +++ b/monitor.c -@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +@@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); -+int mm_answer_gss_sign(struct ssh*, int, struct sshbuf *); -+int mm_answer_gss_updatecreds(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif #ifdef SSH_AUDIT_EVENTS -@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -220,11 +222,18 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2605,7 +2617,7 @@ index 60e52944..669cdb4a 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -293,6 +302,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2616,7 +2628,7 @@ index 60e52944..669cdb4a 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -405,6 +418,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2627,7 +2639,7 @@ index 60e52944..669cdb4a 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1687,6 +1704,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2645,7 +2657,7 @@ index 60e52944..669cdb4a 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; -@@ -1780,8 +1808,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2656,7 +2668,7 @@ index 60e52944..669cdb4a 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); -@@ -1813,8 +1841,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2667,7 +2679,7 @@ index 60e52944..669cdb4a 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); -@@ -1834,6 +1862,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2675,7 +2687,7 @@ index 60e52944..669cdb4a 100644 } return (0); } -@@ -1845,8 +1874,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1871,8 +1900,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2686,7 +2698,7 @@ index 60e52944..669cdb4a 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1872,13 +1901,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1898,13 +1927,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2708,7 +2720,7 @@ index 60e52944..669cdb4a 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1887,7 +1920,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2721,7 +2733,7 @@ index 60e52944..669cdb4a 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1895,5 +1932,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1921,5 +1958,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2821,10 +2833,10 @@ index 683e5e07..2b1a2d59 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index 186e8f02..8e4c1c1f 100644 +index 001a8fa1..6edb509a 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -978,13 +978,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +@@ -993,13 +993,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -2841,7 +2853,7 @@ index 186e8f02..8e4c1c1f 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -997,4 +999,57 @@ mm_ssh_gssapi_userok(char *user) +@@ -1012,4 +1014,57 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -2900,10 +2912,10 @@ index 186e8f02..8e4c1c1f 100644 + #endif /* GSSAPI */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index fdebb3aa..69164a8c 100644 +index 23ab096a..485590c1 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -61,8 +61,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +@@ -64,8 +64,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2916,7 +2928,7 @@ index fdebb3aa..69164a8c 100644 #ifdef USE_PAM diff --git a/readconf.c b/readconf.c -index ec497e79..4d699e5f 100644 +index f3cac6b3..da8022dd 100644 --- a/readconf.c +++ b/readconf.c @@ -67,6 +67,7 @@ @@ -2927,7 +2939,7 @@ index ec497e79..4d699e5f 100644 /* Format of the configuration file: -@@ -162,6 +163,8 @@ typedef enum { +@@ -160,6 +161,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2936,7 +2948,7 @@ index ec497e79..4d699e5f 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -202,10 +205,22 @@ static struct { +@@ -204,10 +207,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2959,7 +2971,7 @@ index ec497e79..4d699e5f 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -983,10 +998,42 @@ parse_time: +@@ -1029,10 +1044,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3002,7 +3014,7 @@ index ec497e79..4d699e5f 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1854,7 +1901,13 @@ initialize_options(Options * options) +@@ -1911,7 +1958,13 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -3016,7 +3028,7 @@ index ec497e79..4d699e5f 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2000,8 +2053,18 @@ fill_default_options(Options * options) +@@ -2059,8 +2112,18 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3035,7 +3047,7 @@ index ec497e79..4d699e5f 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -2616,7 +2679,14 @@ dump_client_config(Options *o, const char *host) +@@ -2702,7 +2765,14 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3051,10 +3063,10 @@ index ec497e79..4d699e5f 100644 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); diff --git a/readconf.h b/readconf.h -index 8e36bf32..0bff6d80 100644 +index feedb3d2..a8a8870d 100644 --- a/readconf.h +++ b/readconf.h -@@ -40,7 +40,13 @@ typedef struct { +@@ -41,7 +41,13 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -3069,10 +3081,10 @@ index 8e36bf32..0bff6d80 100644 * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c -index ffac5d2c..ffdad31e 100644 +index 70f5f73f..191575a1 100644 --- a/servconf.c +++ b/servconf.c -@@ -64,6 +64,7 @@ +@@ -69,6 +69,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" @@ -3080,7 +3092,7 @@ index ffac5d2c..ffdad31e 100644 static void add_listen_addr(ServerOptions *, const char *, const char *, int); -@@ -124,8 +125,11 @@ initialize_server_options(ServerOptions *options) +@@ -133,8 +134,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3092,7 +3104,7 @@ index ffac5d2c..ffdad31e 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -351,10 +355,18 @@ fill_default_server_options(ServerOptions *options) +@@ -375,10 +379,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3111,7 +3123,7 @@ index ffac5d2c..ffdad31e 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -498,6 +510,7 @@ typedef enum { +@@ -531,6 +543,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3119,7 +3131,7 @@ index ffac5d2c..ffdad31e 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -572,12 +585,22 @@ static struct { +@@ -607,12 +620,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3142,7 +3154,7 @@ index ffac5d2c..ffdad31e 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1485,6 +1508,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1548,6 +1571,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3153,7 +3165,7 @@ index ffac5d2c..ffdad31e 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1493,6 +1520,22 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1556,6 +1583,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3176,7 +3188,7 @@ index ffac5d2c..ffdad31e 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2579,6 +2622,10 @@ dump_config(ServerOptions *o) +@@ -2777,6 +2820,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3188,10 +3200,10 @@ index ffac5d2c..ffdad31e 100644 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index 54e0a8d8..a476d522 100644 +index 4202a2d0..3f47ea25 100644 --- a/servconf.h +++ b/servconf.h -@@ -126,8 +126,11 @@ typedef struct { +@@ -132,8 +132,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3204,10 +3216,10 @@ index 54e0a8d8..a476d522 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index 48cfaafb..78cc8358 100644 +index 8c0e54f7..06a33442 100644 --- a/session.c +++ b/session.c -@@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2678,13 +2678,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3241,7 +3253,7 @@ index 36180d07..70dd3665 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -61,10 +61,30 @@ +@@ -61,10 +61,34 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -3261,6 +3273,10 @@ index 36180d07..70dd3665 100644 +#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" + +#define GSS_KEX_DEFAULT_KEX \ ++ KEX_GSS_GRP14_SHA256_ID "," \ ++ KEX_GSS_GRP16_SHA512_ID "," \ ++ KEX_GSS_NISTP256_SHA256_ID "," \ ++ KEX_GSS_C25519_SHA256_ID "," \ + KEX_GSS_GEX_SHA1_ID "," \ + KEX_GSS_GRP14_SHA1_ID + @@ -3350,10 +3366,10 @@ index 36180d07..70dd3665 100644 #endif /* _SSH_GSS_H */ diff --git a/ssh.1 b/ssh.1 -index 9480eba8..a1c7d230 100644 +index 60de6087..db5c65bc 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -497,7 +497,13 @@ For full details of the options listed below, and their possible values, see +@@ -503,7 +503,13 @@ For full details of the options listed below, and their possible values, see .It GatewayPorts .It GlobalKnownHostsFile .It GSSAPIAuthentication @@ -3367,7 +3383,7 @@ index 9480eba8..a1c7d230 100644 .It HashKnownHosts .It Host .It HostbasedAuthentication -@@ -573,6 +579,8 @@ flag), +@@ -579,6 +585,8 @@ flag), (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3377,27 +3393,29 @@ index 9480eba8..a1c7d230 100644 (key types), .Ar key-cert diff --git a/ssh.c b/ssh.c -index 91e7c351..42be7d88 100644 +index 15aee569..110cf9c1 100644 --- a/ssh.c +++ b/ssh.c -@@ -736,6 +736,8 @@ main(int ac, char **av) - cp = mac_alg_list('\n'); - else if (strcmp(optarg, "kex") == 0) +@@ -747,6 +747,8 @@ main(int ac, char **av) + else if (strcmp(optarg, "kex") == 0 || + strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); + else if (strcmp(optarg, "kex-gss") == 0) + cp = kex_gss_alg_list('\n'); else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -748,7 +750,7 @@ main(int ac, char **av) - cp = xstrdup("2"); - else if (strcmp(optarg, "help") == 0) { +@@ -772,8 +774,8 @@ main(int ac, char **av) + } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( -- "cipher\ncipher-auth\nkex\nkey\n" -+ "cipher\ncipher-auth\nkex\nkex-gss\nkey\n" - "key-cert\nkey-plain\nmac\n" - "protocol-version\nsig"); + "cipher\ncipher-auth\ncompression\nkex\n" +- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" +- "protocol-version\nsig"); ++ "kex-gss\nkey\nkey-cert\nkey-plain\n" ++ "key-sig\nmac\nprotocol-version\nsig"); } + if (cp == NULL) + fatal("Unsupported query \"%s\"", optarg); diff --git a/ssh_config b/ssh_config index 5e8ef548..1ff999b6 100644 --- a/ssh_config @@ -3412,10 +3430,10 @@ index 5e8ef548..1ff999b6 100644 # CheckHostIP yes # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index 41262963..c3c8b274 100644 +index 06a32d31..3f490697 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -754,10 +754,67 @@ The default is +@@ -766,10 +766,68 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3478,16 +3496,17 @@ index 41262963..c3c8b274 100644 +.Ed +.Pp +The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. ++.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 HashKnownHosts Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index dffee90b..0d0a6cb8 100644 +index af00fb30..03bc87eb 100644 --- a/sshconnect2.c +++ b/sshconnect2.c -@@ -78,8 +78,6 @@ +@@ -80,8 +80,6 @@ #endif /* import */ @@ -3496,9 +3515,9 @@ index dffee90b..0d0a6cb8 100644 extern Options options; /* -@@ -161,6 +159,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) +@@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) char *s, *all_key; - int r; + int r, use_known_hosts_order = 0; +#if defined(GSSAPI) && defined(WITH_OPENSSL) + char *orig = NULL, *gss = NULL; @@ -3508,8 +3527,8 @@ index dffee90b..0d0a6cb8 100644 xxx_host = host; xxx_hostaddr = hostaddr; -@@ -193,6 +196,35 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - order_hostkeyalgs(host, hostaddr, port)); +@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + compat_pkalg_proposal(options.hostkeyalgorithms); } +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3518,12 +3537,19 @@ index dffee90b..0d0a6cb8 100644 + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; + -+ if (options.gss_server_identity) ++ if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) ++ } else if (options.gss_trust_dns) { + gss_host = remote_hostname(ssh); -+ else ++ /* 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); @@ -3544,7 +3570,7 @@ index dffee90b..0d0a6cb8 100644 if (options.rekey_limit || options.rekey_interval) ssh_packet_set_rekey_limits(ssh, options.rekey_limit, options.rekey_interval); -@@ -211,16 +243,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) +@@ -224,16 +256,46 @@ 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 @@ -3592,7 +3618,7 @@ index dffee90b..0d0a6cb8 100644 if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) fatal("kex_prop2buf: %s", ssh_err(r)); -@@ -317,6 +379,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); +@@ -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 *); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -3600,7 +3626,7 @@ index dffee90b..0d0a6cb8 100644 #endif void userauth(struct ssh *, char *); -@@ -333,6 +396,11 @@ static char *authmethods_get(void); +@@ -346,6 +409,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -3612,32 +3638,41 @@ index dffee90b..0d0a6cb8 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -698,12 +766,23 @@ userauth_gssapi(struct ssh *ssh) +@@ -716,12 +784,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; -+ char *gss_host; ++ char *gss_host = NULL; + -+ if (options.gss_server_identity) ++ if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) ++ } else if (options.gss_trust_dns) { + gss_host = remote_hostname(ssh); -+ else ++ /* 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(authctxt->host); ++ } ++ } else { + gss_host = xstrdup(authctxt->host); ++ } /* Try one GSSAPI method at a time, rather than sending them all at * once. */ if (authctxt->gss_supported_mechs == NULL) - gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); -+ if (GSS_ERROR(gss_indicate_mechs(&min, &authctxt->gss_supported_mechs))) { ++ if (GSS_ERROR(gss_indicate_mechs(&min, ++ &authctxt->gss_supported_mechs))) { ++ authctxt->gss_supported_mechs = NULL; + free(gss_host); + return 0; + } /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -712,13 +791,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -730,13 +811,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3654,7 +3689,7 @@ index dffee90b..0d0a6cb8 100644 if (!ok || mech == NULL) return 0; -@@ -958,6 +1039,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -976,6 +1059,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) free(lang); return r; } @@ -3711,10 +3746,10 @@ index dffee90b..0d0a6cb8 100644 static int diff --git a/sshd.c b/sshd.c -index cbd3bce9..8c223f6a 100644 +index 60b2aaf7..d92f03aa 100644 --- a/sshd.c +++ b/sshd.c -@@ -796,8 +796,8 @@ notify_hostkeys(struct ssh *ssh) +@@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %u hostkeys", __func__, nkeys); if (nkeys == 0) @@ -3725,7 +3760,7 @@ index cbd3bce9..8c223f6a 100644 sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); } -@@ -1769,7 +1769,8 @@ main(int ac, char **av) +@@ -1852,7 +1852,8 @@ main(int ac, char **av) free(fp); } accumulate_host_timing_secret(cfg, NULL); @@ -3735,7 +3770,7 @@ index cbd3bce9..8c223f6a 100644 logit("sshd: no hostkeys available -- exiting."); exit(1); } -@@ -2260,6 +2261,48 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -3784,7 +3819,7 @@ index cbd3bce9..8c223f6a 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2275,7 +2318,18 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -3810,18 +3845,18 @@ index 19b7c91a..2c48105f 100644 +++ b/sshd_config @@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options - GSSAPIAuthentication yes - GSSAPICleanupCredentials no + #GSSAPIAuthentication no + #GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange 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 b224f292..2baa6622 100644 +index 70ccea44..f6b41a2f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -653,6 +653,11 @@ Specifies whether to automatically destroy the user's credentials cache +@@ -646,6 +646,11 @@ Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Cm yes . @@ -3833,7 +3868,7 @@ index b224f292..2baa6622 100644 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -667,6 +672,31 @@ machine's default store. +@@ -660,6 +665,32 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -3860,24 +3895,25 @@ index b224f292..2baa6622 100644 +.Ed +.Pp +The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. ++.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 HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c -index ad195776..789cd61e 100644 +index 57995ee6..fd5b7724 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -135,6 +135,7 @@ static const struct keytype keytypes[] = { - # endif /* OPENSSL_HAS_NISTP521 */ +@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { + KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 }, # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ + { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, { NULL, NULL, NULL, -1, -1, 0, 0 } }; -@@ -223,7 +224,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { @@ -3887,13 +3923,13 @@ index ad195776..789cd61e 100644 if (!include_sigonly && kt->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index a91e6043..c11106c9 100644 +index 71a3fddc..37a43a67 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -65,6 +65,7 @@ enum sshkey_types { - KEY_ED25519_CERT, - KEY_XMSS, - KEY_XMSS_CERT, +@@ -69,6 +69,7 @@ enum sshkey_types { + KEY_ECDSA_SK_CERT, + KEY_ED25519_SK, + KEY_ED25519_SK_CERT, + KEY_NULL, KEY_UNSPEC }; diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index cd7d0e5..712f703 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,17 +1,57 @@ +commit ed3eaf7d68c083b6015ca3425b75932999dafaad +Author: Jakub Jelen +Date: Wed Apr 24 17:23:21 2019 +0200 + + PKCS#11 URI from Fedora + + * Print PKCS#11 URIs from ssh-keygen + * Accept PKCS#11 URIs in -i argument to ssh + * Allow PKCS#11 URI specification in ssh_config + * Fallback to p11-kit-proxy + * PKCS#11 URI support for ssh-add and ssh-agent + * internal representation is URI + * Allow to specify pin-value in URI to avoid interactive prompts + + Currently recognized and used parts of PKCS#11 URI: + * path (optional) + * token + * id + * manufacturer + * (library-manufacturer) + * query (optional) + * module-path + * pin-value + + Unit test for PKCS#11 URIs + + * test PKCS#11 URI parser, generator + * test percent_encodeer and decoder + + Regression tests for PKCS#11 URI support + + * soft-pkcs11.so from people.su.se/~lha/soft-pkcs11 + * Return correct CKR for unknown attributes + * Adjust and build it with regress tests (allowing agent-pkcs11 test) + * Test PKCS#11 URIs support with soft-pkcs11 + * Direct usage from commandline (URI, provider and combination) + * Usage from configuration files + * Usage in ssh-agent (add, sign, remove) + * Make sure it is built with correct paths + diff --git a/Makefile.in b/Makefile.in -index adb1977e..9b01a017 100644 +index e7549470..4511f82a 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - atomicio.o dispatch.o mac.o misc.o utf8.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ +@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ + ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -255,6 +255,8 @@ clean: regressclean + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -289,6 +289,8 @@ clean: regressclean rm -f regress/unittests/match/test_match$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -19,8 +59,8 @@ index adb1977e..9b01a017 100644 + rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - (cd openbsd-compat && $(MAKE) clean) -@@ -285,6 +287,8 @@ distclean: regressclean + rm -f regress/misc/sk-dummy/*.o +@@ -322,6 +324,8 @@ distclean: regressclean rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -29,15 +69,15 @@ index adb1977e..9b01a017 100644 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) distclean) -@@ -447,6 +451,7 @@ regress-prep: +@@ -490,6 +494,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/kex $(MKDIR_P) `pwd`/regress/unittests/match $(MKDIR_P) `pwd`/regress/unittests/utf8 + $(MKDIR_P) `pwd`/regress/unittests/pkcs11 $(MKDIR_P) `pwd`/regress/misc/kexfuzz + $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -570,6 +575,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ +@@ -617,6 +622,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -52,9 +92,9 @@ index adb1977e..9b01a017 100644 + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o - -@@ -593,6 +608,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ + regress/misc/kexfuzz/kexfuzz.o \ + $(SKOBJS) +@@ -655,6 +670,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ regress/unittests/utf8/test_utf8$(EXEEXT) \ @@ -63,10 +103,10 @@ index adb1977e..9b01a017 100644 tests: file-tests t-exec interop-tests unit diff --git a/configure.ac b/configure.ac -index 3e93c027..351f0ba5 100644 +index b689db4b..98d3ce4f 100644 --- a/configure.ac +++ b/configure.ac -@@ -1861,12 +1861,14 @@ AC_LINK_IFELSE( +@@ -1911,12 +1911,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -81,9 +121,9 @@ index 3e93c027..351f0ba5 100644 fi ] ) -@@ -1882,6 +1884,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then - ) - fi +@@ -1945,6 +1947,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) + AC_CHECK_FUNCS([dlopen]) + AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) +# Check whether we have a p11-kit, we got default provider on command line +DEFAULT_PKCS11_PROVIDER_MSG="no" @@ -122,19 +162,19 @@ index 3e93c027..351f0ba5 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5229,6 +5265,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" - echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5401,6 +5437,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" + echo " PKCS#11 support: $enable_pkcs11" +echo " Default PKCS#11 provider: $DEFAULT_PKCS11_PROVIDER_MSG" + echo " U2F/FIDO support: $enable_sk" echo "" - diff --git a/regress/Makefile b/regress/Makefile -index 34c47e8c..d693aa4a 100644 +index 774c10d4..6bf3b627 100644 --- a/regress/Makefile +++ b/regress/Makefile -@@ -115,7 +115,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +@@ -116,7 +116,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -144,7 +184,7 @@ index 34c47e8c..d693aa4a 100644 rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -245,6 +246,7 @@ unit: +@@ -246,6 +247,7 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -153,7 +193,7 @@ index 34c47e8c..d693aa4a 100644 $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -d ${.CURDIR}/unittests/sshkey/testdata ; \ diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index 5205d906..bfbaeb65 100644 +index fbbaea51..5d75d69f 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh @@ -113,7 +113,7 @@ else @@ -167,10 +207,10 @@ index 5205d906..bfbaeb65 100644 fail "ssh-add -e failed: exit code $r" diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh new file mode 100644 -index 00000000..f2d6c41c +index 00000000..a91aee94 --- /dev/null +++ b/regress/pkcs11.sh -@@ -0,0 +1,345 @@ +@@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat +# @@ -270,130 +310,134 @@ index 00000000..f2d6c41c +trace "List the keys in the ssh-keygen with PKCS#11 URIs" +${SSHKEYGEN} -D ${TEST_SSH_PKCS11} > $OBJ/token_keys +if [ $? -ne 0 ]; then -+ fail "keygen fails to enumerate keys on PKCS#11 token" ++ fail "FAIL: keygen fails to enumerate keys on PKCS#11 token" +fi +grep "pkcs11:" $OBJ/token_keys > /dev/null +if [ $? -ne 0 ]; then -+ fail "The keys from ssh-keygen do not contain PKCS#11 URI as a comment" ++ fail "FAIL: The keys from ssh-keygen do not contain PKCS#11 URI as a comment" +fi -+tail -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++ ++# Set the ECDSA key to authorized keys ++grep "ECDSA" $OBJ/token_keys > $OBJ/authorized_keys_$USER + +trace "Simple connect with ssh (without PKCS#11 URI)" +echo ${TEST_SSH_PIN} | notty ${SSH} -I ${TEST_SSH_PKCS11} \ + -F $OBJ/ssh_proxy somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with pkcs11 failed (exit code $r)" ++ fail "FAIL: ssh connect with pkcs11 failed (exit code $r)" +fi + +trace "Connect with PKCS#11 URI" -+trace " (second key should succeed)" ++trace " (ECDSA key should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++ fail "FAIL: ssh connect with PKCS#11 URI failed (exit code $r)" +fi + -+trace " (first key should fail)" ++trace " (RSA key should fail)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:id=%${ID1}?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++ fail "FAIL: ssh connect with PKCS#11 URI succeeded (should fail)" +fi + +trace "Connect with PKCS#11 URI including PIN should not prompt" -+trace " (second key should succeed)" ++trace " (ECDSA key should succeed)" +${SSH} -F $OBJ/ssh_proxy -i \ -+ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 ++ "pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++ fail "FAIL: ssh connect with PKCS#11 URI failed (exit code $r)" +fi + -+trace " (first key should fail)" ++trace " (RSA key should fail)" +${SSH} -F $OBJ/ssh_proxy -i \ -+ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 ++ "pkcs11:id=%${ID1}?module-path=${TEST_SSH_PKCS11}&pin-value=${TEST_SSH_PIN}" somehost exit 5 +r=$? +if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++ fail "FAIL: ssh connect with PKCS#11 URI succeeded (should fail)" +fi + +trace "Connect with various filtering options in PKCS#11 URI" -+trace " (by object label, second key should succeed)" ++trace " (by object label, ECDSA should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:object=SSH%20RSA%20Key%202?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:object=SSH%20ECDSA%20Key%2004?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++ fail "FAIL: ssh connect with PKCS#11 URI failed (exit code $r)" +fi + -+trace " (by object label, first key should fail)" ++trace " (by object label, RSA key should fail)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:object=SSH%20RSA%20Key?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:object=SSH%20RSA%20Key%2002?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++ fail "FAIL: ssh connect with PKCS#11 URI succeeded (should fail)" +fi + -+trace " (by token label, second key should succeed)" ++trace " (by token label, ECDSA key should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID2};token=SoftToken%20(token)?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:id=%${ID2};token=token-slot-0?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI failed (exit code $r)" ++ fail "FAIL: ssh connect with PKCS#11 URI failed (exit code $r)" +fi + +trace " (by wrong token label, should fail)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:token=SoftToken?module-path=${TEST_SSH_PKCS11}" somehost exit 5 ++ -i "pkcs11:token=token-slot-99?module-path=${TEST_SSH_PKCS11}" somehost exit 5 +r=$? +if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI succeeded (should fail)" ++ fail "FAIL: ssh connect with PKCS#11 URI succeeded (should fail)" +fi + + + + +trace "Test PKCS#11 URI specification in configuration files" -+echo "IdentityFile \"pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}\"" \ ++echo "IdentityFile \"pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}\"" \ + >> $OBJ/ssh_proxy -+trace " (second key should succeed)" ++trace " (ECDSA key should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI in config failed (exit code $r)" ++ fail "FAIL: ssh connect with PKCS#11 URI in config failed (exit code $r)" +fi + -+trace " (first key should fail)" -+head -n 1 $OBJ/token_keys > $OBJ/authorized_keys_$USER ++# Set the RSA key as authorized ++grep "RSA" $OBJ/token_keys > $OBJ/authorized_keys_$USER ++ ++trace " (RSA key should fail)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 +r=$? +if [ $r -eq 5 ]; then -+ fail "ssh connect with PKCS#11 URI in config succeeded (should fail)" ++ fail "FAIL: ssh connect with PKCS#11 URI in config succeeded (should fail)" +fi +sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy + +trace "Test PKCS#11 URI specification in configuration files with bogus spaces" -+echo "IdentityFile \" pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11} \"" \ ++echo "IdentityFile \" pkcs11:?module-path=${TEST_SSH_PKCS11} \"" \ + >> $OBJ/ssh_proxy +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI with bogus spaces in config failed" \ ++ fail "FAIL: ssh connect with PKCS#11 URI with bogus spaces in config failed" \ + "(exit code $r)" +fi +sed -i -e "/IdentityFile/d" $OBJ/ssh_proxy + + +trace "Combination of PKCS11Provider and PKCS11URI on commandline" -+trace " (first key should succeed)" ++trace " (RSA key should succeed)" +echo ${TEST_SSH_PIN} | notty ${SSH} -F $OBJ/ssh_proxy \ -+ -i "pkcs11:id=${ID1}" -I ${TEST_SSH_PKCS11} somehost exit 5 ++ -i "pkcs11:id=%${ID1}" -I ${TEST_SSH_PKCS11} somehost exit 5 +r=$? +if [ $r -ne 5 ]; then -+ fail "ssh connect with PKCS#11 URI and provider combination" \ ++ fail "FAIL: ssh connect with PKCS#11 URI and provider combination" \ + "failed (exit code $r)" +fi + @@ -402,14 +446,14 @@ index 00000000..f2d6c41c + -o IdentityFile=\"pkcs11:token=segfault\" somehost exit 5 +r=$? +if [ $r -eq 139 ]; then -+ fail "ssh connect with missing provider_id from configuration option" \ ++ fail "FAIL: ssh connect with missing provider_id from configuration option" \ + "crashed (exit code $r)" +fi + + +trace "SSH Agent can work with PKCS#11 URI" +trace "start the agent" -+eval `${SSHAGENT} -s -P "${OBJ}/*"` > /dev/null ++eval `${SSHAGENT} -s` > /dev/null + +r=$? +if [ $r -ne 0 ]; then @@ -417,100 +461,100 @@ index 00000000..f2d6c41c +else + trace "add whole provider to agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ "pkcs11:?module-path=${TEST_SSH_PKCS11}" #> /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add failed with whole provider: exit code $r" ++ fail "FAIL: ssh-add failed with whole provider: exit code $r" + fi + + trace " pkcs11 list via agent (all keys)" + ${SSHADD} -l > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add -l failed with whole provider: exit code $r" ++ fail "FAIL: ssh-add -l failed with whole provider: exit code $r" + fi + + trace " pkcs11 connect via agent (all keys)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -ne 5 ]; then -+ fail "ssh connect failed with whole provider (exit code $r)" ++ fail "FAIL: ssh connect failed with whole provider (exit code $r)" + fi + + trace " remove pkcs11 keys (all keys)" + ${SSHADD} -d "pkcs11:?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with whole provider: exit code $r" ++ fail "FAIL: ssh-add -d failed with whole provider: exit code $r" + fi + -+ trace "add only first key to the agent" ++ trace "add only RSA key to the agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ "pkcs11:id=%${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add failed with first key: exit code $r" ++ fail "FAIL ssh-add failed with RSA key: exit code $r" + fi + -+ trace " pkcs11 connect via agent (first key)" ++ trace " pkcs11 connect via agent (RSA key)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -ne 5 ]; then -+ fail "ssh connect failed with first key (exit code $r)" ++ fail "FAIL: ssh connect failed with RSA key (exit code $r)" + fi + -+ trace " remove first pkcs11 key" -+ ${SSHADD} -d "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" \ ++ trace " remove RSA pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=%${ID1}?module-path=${TEST_SSH_PKCS11}" \ + > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with first key: exit code $r" ++ fail "FAIL: ssh-add -d failed with RSA key: exit code $r" + fi + -+ trace "add only second key to the agent" ++ trace "add only ECDSA key to the agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ "pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add failed with second key: exit code $r" ++ fail "FAIL: ssh-add failed with second key: exit code $r" + fi + -+ trace " pkcs11 connect via agent (second key should fail)" ++ trace " pkcs11 connect via agent (ECDSA key should fail)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -eq 5 ]; then -+ fail "ssh connect passed without key (should fail)" ++ fail "FAIL: ssh connect passed with ECDSA key (should fail)" + fi + -+ trace "add also the first key to the agent" ++ trace "add also the RSA key to the agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} \ -+ "pkcs11:id=${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 ++ "pkcs11:id=%${ID1}?module-path=${TEST_SSH_PKCS11}" > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add failed with first key: exit code $r" ++ fail "FAIL: ssh-add failed with first key: exit code $r" + fi + -+ trace " remove second pkcs11 key" -+ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ trace " remove ECDSA pkcs11 key" ++ ${SSHADD} -d "pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}" \ + > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then -+ fail "ssh-add -d failed with second key: exit code $r" ++ fail "ssh-add -d failed with ECDSA key: exit code $r" + fi + + trace " remove already-removed pkcs11 key should fail" -+ ${SSHADD} -d "pkcs11:id=${ID2}?module-path=${TEST_SSH_PKCS11}" \ ++ ${SSHADD} -d "pkcs11:id=%${ID2}?module-path=${TEST_SSH_PKCS11}" \ + > /dev/null 2>&1 + r=$? + if [ $r -eq 0 ]; then -+ fail "ssh-add -d passed with non-existing key (should fail)" ++ fail "FAIL: ssh-add -d passed with non-existing key (should fail)" + fi + -+ trace " pkcs11 connect via agent (the first key should be still usable)" ++ trace " pkcs11 connect via agent (the RSA key should be still usable)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -ne 5 ]; then -+ fail "ssh connect failed with first key (after removing second): exit code $r" ++ fail "ssh connect failed with RSA key (after removing ECDSA): exit code $r" + fi + + trace "kill agent" @@ -872,18 +916,18 @@ index 00000000..b637cb13 + test_generate_valid(); +} diff --git a/ssh-add.c b/ssh-add.c -index ebfb8a32..c32d1cb5 100644 +index 8057eb1f..0c470e32 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -66,6 +66,7 @@ - #include "misc.h" +@@ -67,6 +67,7 @@ #include "ssherr.h" #include "digest.h" + #include "ssh-sk.h" +#include "ssh-pkcs11-uri.h" /* argv0 */ extern char *__progname; -@@ -190,6 +191,32 @@ delete_all(int agent_fd, int qflag) +@@ -193,6 +194,32 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -914,9 +958,9 @@ index ebfb8a32..c32d1cb5 100644 +#endif + static int - add_file(int agent_fd, const char *filename, int key_only, int qflag) - { -@@ -392,12 +419,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) + add_file(int agent_fd, const char *filename, int key_only, int qflag, + const char *skprovider) +@@ -402,12 +429,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, } static int @@ -931,9 +975,9 @@ index ebfb8a32..c32d1cb5 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -531,6 +557,13 @@ lock_agent(int agent_fd, int lock) - static int - do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) +@@ -591,6 +617,13 @@ static int + do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, + const char *skprovider) { +#ifdef ENABLE_PKCS11 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && @@ -945,7 +989,7 @@ index ebfb8a32..c32d1cb5 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -@@ -709,7 +742,7 @@ main(int argc, char **argv) +@@ -773,7 +806,7 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, @@ -955,10 +999,10 @@ index ebfb8a32..c32d1cb5 100644 goto done; } diff --git a/ssh-agent.c b/ssh-agent.c -index 9c6680a2..e3336073 100644 +index 7eb6f0dc..27d8e4af 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -556,10 +556,72 @@ no_identities(SocketEntry *e) +@@ -641,10 +641,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -978,7 +1022,7 @@ index 9c6680a2..e3336073 100644 + /* PKCS#11 URI */ + uri = pkcs11_uri_init(); + if (uri == NULL) { -+ error("Failed to init PCKS#11 URI"); ++ error("Failed to init PKCS#11 URI"); + return NULL; + } + @@ -1001,7 +1045,7 @@ index 9c6680a2..e3336073 100644 + return NULL; + } + free(module_path); -+ if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { ++ if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { + verbose("refusing PKCS#11 provider \"%.100s\": " + "not whitelisted", canonical_provider); + pkcs11_uri_cleanup(uri); @@ -1029,10 +1073,10 @@ index 9c6680a2..e3336073 100644 { - char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; + char *provider = NULL, *pin = NULL, *sane_uri = NULL; + char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds; - time_t death = 0; -@@ -595,28 +657,23 @@ process_add_smartcard_key(SocketEntry *e) +@@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) goto send; } } @@ -1041,7 +1085,7 @@ index 9c6680a2..e3336073 100644 - provider, strerror(errno)); - goto send; - } -- if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { +- if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " - "provider not whitelisted", canonical_provider); + @@ -1054,30 +1098,35 @@ index 9c6680a2..e3336073 100644 if (lifetime && !death) death = monotime() + lifetime; -- count = pkcs11_add_provider(canonical_provider, pin, &keys); +- count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); + debug("%s: add %.100s", __func__, sane_uri); -+ count = pkcs11_add_provider(sane_uri, pin, &keys); ++ count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { k = keys[i]; if (lookup_identity(k) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; + keys[i] = NULL; /* transferred */ - id->provider = xstrdup(canonical_provider); -- id->comment = xstrdup(canonical_provider); /* XXX */ + id->provider = xstrdup(sane_uri); -+ id->comment = xstrdup(sane_uri); + if (*comments[i] != '\0') { + id->comment = comments[i]; + comments[i] = NULL; /* transferred */ + } else { +- id->comment = xstrdup(canonical_provider); ++ id->comment = xstrdup(sane_uri); + } id->death = death; id->confirm = confirm; - TAILQ_INSERT_TAIL(&idtab->idlist, id, next); -@@ -630,6 +687,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -721,6 +778,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); + free(sane_uri); free(keys); + free(comments); send_status(e, success); - } -@@ -637,7 +695,7 @@ send: +@@ -729,7 +787,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1086,7 +1135,7 @@ index 9c6680a2..e3336073 100644 int r, success = 0; Identity *id, *nxt; -@@ -648,30 +706,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -740,30 +798,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1124,22 +1173,28 @@ index 9c6680a2..e3336073 100644 } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-keygen.c b/ssh-keygen.c -index e039be30..6770fafb 100644 +index 0d6ed1ff..182f4f2b 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -829,6 +829,7 @@ do_download(struct passwd *pw) +@@ -855,8 +855,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ +- fprintf(stdout, "%s%s\n", +- *(comments[i]) == '\0' ? "" : " ", comments[i]); ++ if (*(comments[i]) != '\0') { ++ fprintf(stdout, " %s", comments[i]); ++ } + (void) pkcs11_uri_write(keys[i], stdout); - fprintf(stdout, "\n"); ++ fprintf(stdout, "\n"); } + free(comments[i]); sshkey_free(keys[i]); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index e7860de8..7b2a9115 100644 +index 8a0ffef5..ead8a562 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c -@@ -321,6 +321,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) +@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, u_int nkeys, i; struct sshbuf *msg; @@ -1148,10 +1203,10 @@ index e7860de8..7b2a9115 100644 if (fd < 0 && pkcs11_start_helper() < 0) return (-1); -@@ -338,6 +340,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) - if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); +@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); + if (labelsp) + *labelsp = xcalloc(nkeys, sizeof(char *)); + debug("%s: nkeys = %u", __func__, nkeys); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ @@ -1632,7 +1687,7 @@ index 00000000..942a5a5a +char *pkcs11_uri_get(struct pkcs11_uri *uri); + diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 09f1ea34..fceddfe3 100644 +index a302c79c..879fe917 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -54,8 +54,8 @@ struct pkcs11_slotinfo { @@ -1798,7 +1853,7 @@ index 09f1ea34..fceddfe3 100644 + + uri = pkcs11_uri_init(); + if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); ++ fatal("Failed to init PKCS#11 URI"); + + if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && + strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { @@ -1912,7 +1967,13 @@ index 09f1ea34..fceddfe3 100644 if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -267,7 +407,7 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, +@@ -262,12 +402,12 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + else { + snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug("%s: no pin specified", __func__); return (-1); /* bail out */ } } @@ -2246,9 +2307,9 @@ index 09f1ea34..fceddfe3 100644 free(key_attr[i].pValue); RSA_free(rsa); -@@ -897,7 +1058,8 @@ static struct sshkey * +@@ -897,7 +1058,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { - CK_ATTRIBUTE cert_attr[3]; + CK_ATTRIBUTE cert_attr[4]; @@ -2256,7 +2317,7 @@ index 09f1ea34..fceddfe3 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -916,14 +1078,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -921,14 +1083,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2276,8 +2337,8 @@ index 09f1ea34..fceddfe3 100644 + rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -935,18 +1098,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + return -1; +@@ -940,18 +1103,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2285,7 +2346,7 @@ index 09f1ea34..fceddfe3 100644 + cert_attr[2].ulValueLen == 0 || + cert_attr[3].ulValueLen == 0) { error("invalid attribute length"); - return (NULL); + return -1; } /* allocate buffers for attributes */ @@ -2299,51 +2360,51 @@ index 09f1ea34..fceddfe3 100644 + rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -958,8 +1122,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } + goto out; +@@ -965,8 +1129,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + subject = xstrdup("invalid subject"); + X509_NAME_free(x509_name); - cp = cert_attr[2].pValue; -- if (d2i_X509(&x509, &cp, cert_attr[2].ulValueLen) == NULL) { +- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { + cp = cert_attr[3].pValue; -+ if (d2i_X509(&x509, &cp, cert_attr[3].ulValueLen) == NULL) { ++ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { error("d2i_x509 failed"); - goto fail; + goto out; } -@@ -980,7 +1144,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; +@@ -986,7 +1150,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; } - if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) + if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto fail; + goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1010,7 +1174,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; +@@ -1016,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; } - if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) + if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto fail; + goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1029,7 +1193,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - error("unknown certificate key type"); - - fail: +@@ -1036,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + out: - for (i = 0; i < 3; i++) + for (i = 0; i < nattr; i++) free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1058,11 +1222,12 @@ have_rsa_key(const RSA *rsa) +@@ -1071,11 +1235,12 @@ have_rsa_key(const RSA *rsa) */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, int *nkeys) -+ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) { struct sshkey *key = NULL; CK_OBJECT_CLASS key_class; @@ -2353,7 +2414,7 @@ index 09f1ea34..fceddfe3 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1078,10 +1243,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1092,10 +1257,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2371,31 +2432,31 @@ index 09f1ea34..fceddfe3 100644 + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ + session = p->module->slotinfo[slotidx].session; + f = p->module->function_list; -+ + +- rv = f->C_FindObjectsInit(session, key_attr, 1); + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1155,11 +1333,12 @@ fail: +@@ -1175,11 +1353,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, int *nkeys) -+ struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) { struct sshkey *key = NULL; CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; +- CK_ATTRIBUTE key_attr[2]; + CK_ATTRIBUTE key_attr[3]; + int nattr = 1; CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1175,10 +1354,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1195,10 +1374,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2413,16 +2474,16 @@ index 09f1ea34..fceddfe3 100644 + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ + session = p->module->slotinfo[slotidx].session; + f = p->module->function_list; -+ + +- rv = f->C_FindObjectsInit(session, key_attr, 1); + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1435,15 +1627,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1466,16 +1658,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } #endif /* WITH_PKCS11_KEYGEN */ @@ -2431,7 +2492,8 @@ index 09f1ea34..fceddfe3 100644 - * keyp is provided, fetch keys. - */ static int --pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, - struct pkcs11_provider **providerp, CK_ULONG user) +pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) { @@ -2440,7 +2502,7 @@ index 09f1ea34..fceddfe3 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1452,161 +1639,298 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, +@@ -1484,165 +1670,301 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2460,6 +2522,8 @@ index 09f1ea34..fceddfe3 100644 - - if (keyp != NULL) - *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; +#endif + } else { + provider_module = strdup(uri->module_path); @@ -2528,17 +2592,17 @@ index 09f1ea34..fceddfe3 100644 error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); -+ goto fail; -+ } + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { + debug("%s: Skipping provider %s not matching library_manufacturer", + __func__, m->info.manufacturerID); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ goto fail; ++ } + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", @@ -2636,7 +2700,8 @@ index 09f1ea34..fceddfe3 100644 + */ +static int +pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, struct pkcs11_provider **providerp, CK_ULONG user) ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) +{ + int nkeys; + int ret = -1; @@ -2706,11 +2771,11 @@ index 09f1ea34..fceddfe3 100644 + (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ keyp == NULL) continue; -- pkcs11_fetch_keys(p, i, keyp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, &nkeys); +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); - if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + if (nkeys == 0 && !p->module->slotinfo[i].logged_in && pkcs11_interactive) { /* @@ -2718,26 +2783,28 @@ index 09f1ea34..fceddfe3 100644 * expose keys. */ - if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3("%s: Trying to login as there were no keys found", ++ __func__); + if (pkcs11_login_slot(p, &p->module->slotinfo[i], CKU_USER) < 0) { error("login failed"); continue; } -- pkcs11_fetch_keys(p, i, keyp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); - } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } + if (nkeys == 0 && uri->object != NULL) { + debug3("%s: No keys found. Retrying without label (%s) ", + __func__, uri->object); + /* Try once more without the label filter */ + char *label = uri->object; + uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + uri->object = label; -+ } + } + pin = NULL; /* Will be cleaned up with URI */ } @@ -2772,7 +2839,7 @@ index 09f1ea34..fceddfe3 100644 - */ +static int +pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ struct pkcs11_provider **providerp, CK_ULONG user) ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) +{ + struct pkcs11_uri *uri = NULL; + int r; @@ -2791,30 +2858,32 @@ index 09f1ea34..fceddfe3 100644 + uri->module_path = strdup(provider_id); + } + -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, providerp, user); ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); + pkcs11_uri_cleanup(uri); + + return r; +} + int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) +pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp) ++ struct sshkey ***keyp, char ***labelsp) { - struct pkcs11_provider *p = NULL; int nkeys; + struct pkcs11_provider *p = NULL; + char *provider_uri = pkcs11_uri_get(uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, &p, CKU_USER); -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); + -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, &p, CKU_USER); ++ debug("%s: called, provider_uri = %s", __func__, provider_uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1616,7 +1940,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) +@@ -1652,7 +1974,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, } if (nkeys == 0) debug("%s: provider %s returned no keys", __func__, @@ -2830,14 +2899,15 @@ index 09f1ea34..fceddfe3 100644 + * fails if provider already exists + */ +int -+pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) +{ + struct pkcs11_uri *uri; + int nkeys; + + uri = pkcs11_uri_init(); + if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); ++ fatal("Failed to init PKCS#11 URI"); + + if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && + strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { @@ -2847,33 +2917,33 @@ index 09f1ea34..fceddfe3 100644 + uri->module_path = strdup(provider_id); + } + -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp); ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); + pkcs11_uri_cleanup(uri); return (nkeys); } -@@ -1638,8 +1991,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, +@@ -1674,7 +2026,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) debug("%s: provider \"%s\" available", __func__, provider_id); -- else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, &p, -- CKU_SO)) < 0) { -+ else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, &p, CKU_SO)) != 0) { +- else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL, ++ else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, + &p, CKU_SO)) < 0) { debug("%s: could not register provider %s", __func__, provider_id); - goto out; -@@ -1710,8 +2062,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, +@@ -1746,8 +2098,8 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { debug("%s: using provider \"%s\"", __func__, provider_id); -- } else if (pkcs11_register_provider(provider_id, pin, NULL, &p, +- } else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p, - CKU_SO) < 0) { -+ } else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, &p, CKU_SO)) != 0) { ++ } else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, ++ &p, CKU_SO)) < 0) { debug("%s: could not register provider %s", __func__, provider_id); goto out; diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index b9038450..5a855338 100644 +index 81f1d7c5..feaf74de 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h @@ -22,10 +22,14 @@ @@ -2884,18 +2954,18 @@ index b9038450..5a855338 100644 + int pkcs11_init(int); void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); int pkcs11_del_provider(char *); +int pkcs11_uri_write(const struct sshkey *, FILE *); #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, diff --git a/ssh.c b/ssh.c -index ee51823c..2268755b 100644 +index 15aee569..976844cb 100644 --- a/ssh.c +++ b/ssh.c -@@ -772,6 +772,14 @@ main(int ac, char **av) +@@ -795,6 +795,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -2910,7 +2980,7 @@ index ee51823c..2268755b 100644 p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1524,6 +1532,7 @@ main(int ac, char **av) +@@ -1603,6 +1611,7 @@ main(int ac, char **av) free(options.certificate_files[i]); options.certificate_files[i] = NULL; } @@ -2918,7 +2988,7 @@ index ee51823c..2268755b 100644 skip_connect: exit_status = ssh_session2(ssh, pw); -@@ -1997,6 +2006,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) +@@ -2076,6 +2085,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -2934,7 +3004,7 @@ index ee51823c..2268755b 100644 + debug("identity file '%s' from pkcs#11", pkcs11_uri); + uri = pkcs11_uri_init(); + if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); ++ fatal("Failed to init PKCS#11 URI"); + + if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) + fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); @@ -2944,7 +3014,7 @@ index ee51823c..2268755b 100644 + uri->module_path = strdup(options.pkcs11_provider); + + if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys)) > 0) { ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { + for (i = 0; i < nkeys; i++) { + if (*n_ids >= SSH_MAX_IDENTITY_FILES) { + sshkey_free(keys[i]); @@ -2964,18 +3034,19 @@ index ee51823c..2268755b 100644 /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(struct passwd *pw) -@@ -2011,10 +2059,6 @@ load_public_identity_files(struct passwd *pw) +@@ -2090,11 +2138,6 @@ load_public_identity_files(struct passwd *pw) char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; -#ifdef ENABLE_PKCS11 -- struct sshkey **keys; +- struct sshkey **keys = NULL; +- char **comments = NULL; - int nkeys; -#endif /* PKCS11 */ n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2027,32 +2071,46 @@ load_public_identity_files(struct passwd *pw) +@@ -2107,33 +2150,46 @@ load_public_identity_files(struct passwd *pw) sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -2983,18 +3054,19 @@ index ee51823c..2268755b 100644 - options.num_identity_files < SSH_MAX_IDENTITY_FILES && - (pkcs11_init(!options.batch_mode) == 0) && - (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys)) > 0) { +- &keys, &comments)) > 0) { - for (i = 0; i < nkeys; i++) { - if (n_ids >= SSH_MAX_IDENTITY_FILES) { - sshkey_free(keys[i]); +- free(comments[i]); - continue; - } - identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = -- xstrdup(options.pkcs11_provider); /* XXX */ +- identity_files[n_ids] = comments[i]; /* transferred */ - n_ids++; - } - free(keys); +- free(comments); + /* handle fallback from PKCS11Provider option */ + pkcs11_init(!options.batch_mode); + @@ -3003,7 +3075,7 @@ index ee51823c..2268755b 100644 + + uri = pkcs11_uri_init(); + if (uri == NULL) -+ fatal("Failed to init PCKS#11 URI"); ++ fatal("Failed to init PKCS#11 URI"); + + /* Construct simple PKCS#11 URI to simplify access */ + uri->module_path = strdup(options.pkcs11_provider); @@ -3041,10 +3113,10 @@ index ee51823c..2268755b 100644 "u", pw->pw_name, "l", thishost, "h", host, "r", options.user, (char *)NULL); diff --git a/ssh_config.5 b/ssh_config.5 -index 02a87892..41acfa33 100644 +index 06a32d31..4b2763bd 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -964,6 +964,21 @@ may also be used in conjunction with +@@ -986,6 +986,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. diff --git a/openssh-8.1p1-gsissh.patch b/openssh-8.2p1-gsissh.patch similarity index 87% rename from openssh-8.1p1-gsissh.patch rename to openssh-8.2p1-gsissh.patch index f467e21..95e6d9a 100644 --- a/openssh-8.1p1-gsissh.patch +++ b/openssh-8.2p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c ---- openssh-8.0p1.orig/auth2.c 2019-05-20 08:24:38.155774971 +0200 -+++ openssh-8.0p1/auth2.c 2019-05-20 08:25:21.577323166 +0200 -@@ -281,7 +281,28 @@ +diff -Nur openssh-8.2p1.orig/auth2.c openssh-8.2p1/auth2.c +--- openssh-8.2p1.orig/auth2.c 2020-04-14 11:45:12.784455303 +0200 ++++ openssh-8.2p1/auth2.c 2020-04-14 11:46:12.089851375 +0200 +@@ -279,7 +279,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) goto out; @@ -31,7 +31,7 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -292,11 +313,33 @@ +@@ -290,11 +311,33 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -69,7 +69,7 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c authctxt->valid = 1; debug2("%s: setting up authctxt for %s", __func__, user); -@@ -304,6 +347,9 @@ +@@ -302,6 +345,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -79,7 +79,7 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(ssh)); -@@ -312,6 +358,7 @@ +@@ -310,6 +356,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -87,7 +87,7 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -327,9 +374,10 @@ +@@ -325,9 +372,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -101,9 +101,9 @@ diff -Nur openssh-8.0p1.orig/auth2.c openssh-8.0p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.0p1.orig/auth2-gss.c openssh-8.0p1/auth2-gss.c ---- openssh-8.0p1.orig/auth2-gss.c 2019-05-20 08:24:38.068775876 +0200 -+++ openssh-8.0p1/auth2-gss.c 2019-05-20 08:25:21.578323156 +0200 +diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c +--- openssh-8.2p1.orig/auth2-gss.c 2020-04-14 11:45:12.638456788 +0200 ++++ openssh-8.2p1/auth2-gss.c 2020-04-14 11:46:12.090851364 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -297,10 +297,10 @@ diff -Nur openssh-8.0p1.orig/auth2-gss.c openssh-8.0p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c ---- openssh-8.0p1.orig/auth.c 2019-05-20 08:24:38.155774971 +0200 -+++ openssh-8.0p1/auth.c 2019-05-20 08:25:21.578323156 +0200 -@@ -343,7 +343,8 @@ +diff -Nur openssh-8.2p1.orig/auth.c openssh-8.2p1/auth.c +--- openssh-8.2p1.orig/auth.c 2020-04-14 11:45:12.785455293 +0200 ++++ openssh-8.2p1/auth.c 2020-04-14 11:46:12.091851354 +0200 +@@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -310,7 +310,7 @@ diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -581,13 +582,18 @@ +@@ -582,13 +583,18 @@ #endif pw = getpwnam(user); @@ -330,10 +330,10 @@ diff -Nur openssh-8.0p1.orig/auth.c openssh-8.0p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.0p1.orig/auth.h openssh-8.0p1/auth.h ---- openssh-8.0p1.orig/auth.h 2019-05-20 08:24:38.156774960 +0200 -+++ openssh-8.0p1/auth.h 2019-05-20 08:25:21.578323156 +0200 -@@ -85,6 +85,8 @@ +diff -Nur openssh-8.2p1.orig/auth.h openssh-8.2p1/auth.h +--- openssh-8.2p1.orig/auth.h 2020-04-14 11:45:12.785455293 +0200 ++++ openssh-8.2p1/auth.h 2020-04-14 11:46:12.092851344 +0200 +@@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; char *krb5_ccname; @@ -342,10 +342,10 @@ diff -Nur openssh-8.0p1.orig/auth.h openssh-8.0p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c ---- openssh-8.0p1.orig/auth-pam.c 2019-05-20 08:24:38.017776406 +0200 -+++ openssh-8.0p1/auth-pam.c 2019-05-20 08:25:21.579323145 +0200 -@@ -251,6 +251,7 @@ +diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c +--- openssh-8.2p1.orig/auth-pam.c 2020-04-14 11:45:12.592457256 +0200 ++++ openssh-8.2p1/auth-pam.c 2020-04-14 12:59:59.598859650 +0200 +@@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; static char *sshpam_conninfo = NULL; @@ -353,7 +353,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c /* Some PAM implementations don't implement this */ #ifndef HAVE_PAM_GETENVLIST -@@ -291,6 +292,56 @@ +@@ -301,6 +302,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -407,10 +407,10 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c + sshpam_authctxt->pw->pw_name); +} + - void + static void sshpam_password_change_required(int reqd) { -@@ -322,7 +373,7 @@ +@@ -332,7 +383,7 @@ static void import_environments(struct sshbuf *b) { @@ -419,7 +419,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c u_int n, i, num_env; int r; -@@ -338,6 +389,19 @@ +@@ -348,6 +399,19 @@ if ((r = sshbuf_get_u32(b, &n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshpam_password_change_required(n != 0); @@ -439,7 +439,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -510,6 +574,13 @@ +@@ -518,6 +582,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -453,7 +453,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -530,6 +601,13 @@ +@@ -538,6 +609,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -467,7 +467,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -714,6 +792,8 @@ +@@ -722,6 +800,8 @@ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), sshpam_laddr, ssh_local_port(ssh)); @@ -476,7 +476,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1050,6 +1130,18 @@ +@@ -1064,6 +1144,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -495,7 +495,7 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1340,6 +1432,9 @@ +@@ -1352,6 +1444,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -505,9 +505,9 @@ diff -Nur openssh-8.0p1.orig/auth-pam.c openssh-8.0p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.0p1.orig/auth-pam.h openssh-8.0p1/auth-pam.h ---- openssh-8.0p1.orig/auth-pam.h 2019-05-20 08:24:38.017776406 +0200 -+++ openssh-8.0p1/auth-pam.h 2019-05-20 08:25:21.579323145 +0200 +diff -Nur openssh-8.2p1.orig/auth-pam.h openssh-8.2p1/auth-pam.h +--- openssh-8.2p1.orig/auth-pam.h 2020-04-14 11:45:12.592457256 +0200 ++++ openssh-8.2p1/auth-pam.h 2020-04-14 11:46:12.094851324 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -515,9 +515,9 @@ diff -Nur openssh-8.0p1.orig/auth-pam.h openssh-8.0p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.0p1.orig/canohost.c openssh-8.0p1/canohost.c ---- openssh-8.0p1.orig/canohost.c 2019-05-20 08:24:38.068775876 +0200 -+++ openssh-8.0p1/canohost.c 2019-05-20 08:25:21.579323145 +0200 +diff -Nur openssh-8.2p1.orig/canohost.c openssh-8.2p1/canohost.c +--- openssh-8.2p1.orig/canohost.c 2020-04-14 11:45:12.639456778 +0200 ++++ openssh-8.2p1/canohost.c 2020-04-14 11:46:12.094851324 +0200 @@ -17,6 +17,7 @@ #include #include @@ -560,9 +560,9 @@ diff -Nur openssh-8.0p1.orig/canohost.c openssh-8.0p1/canohost.c + } + } +} -diff -Nur openssh-8.0p1.orig/canohost.h openssh-8.0p1/canohost.h ---- openssh-8.0p1.orig/canohost.h 2019-05-20 08:24:38.068775876 +0200 -+++ openssh-8.0p1/canohost.h 2019-05-20 08:25:21.579323145 +0200 +diff -Nur openssh-8.2p1.orig/canohost.h openssh-8.2p1/canohost.h +--- openssh-8.2p1.orig/canohost.h 2020-04-14 11:45:12.639456778 +0200 ++++ openssh-8.2p1/canohost.h 2020-04-14 11:46:12.095851313 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -570,10 +570,10 @@ diff -Nur openssh-8.0p1.orig/canohost.h openssh-8.0p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac ---- openssh-8.0p1.orig/configure.ac 2019-05-20 08:24:38.151775012 +0200 -+++ openssh-8.0p1/configure.ac 2019-05-20 08:25:21.580323135 +0200 -@@ -4572,6 +4572,14 @@ +diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac +--- openssh-8.2p1.orig/configure.ac 2020-04-14 11:45:12.777455374 +0200 ++++ openssh-8.2p1/configure.ac 2020-04-14 11:46:12.096851303 +0200 +@@ -4710,6 +4710,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -588,7 +588,7 @@ diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac fi if test -n "${rpath_opt}" ; then LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" -@@ -4611,6 +4619,40 @@ +@@ -4749,6 +4757,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -629,9 +629,9 @@ diff -Nur openssh-8.0p1.orig/configure.ac openssh-8.0p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c ---- openssh-8.0p1.orig/gss-genr.c 2019-05-20 08:24:38.070775855 +0200 -+++ openssh-8.0p1/gss-genr.c 2019-05-20 08:25:21.581323124 +0200 +diff -Nur openssh-8.2p1.orig/gss-genr.c openssh-8.2p1/gss-genr.c +--- openssh-8.2p1.orig/gss-genr.c 2020-04-14 11:45:12.640456767 +0200 ++++ openssh-8.2p1/gss-genr.c 2020-04-14 11:46:12.097851293 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -640,7 +640,7 @@ diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -412,9 +413,18 @@ +@@ -413,9 +414,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -660,7 +660,7 @@ diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -422,6 +432,7 @@ +@@ -423,6 +433,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -668,9 +668,9 @@ diff -Nur openssh-8.0p1.orig/gss-genr.c openssh-8.0p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.0p1.orig/gss-serv.c openssh-8.0p1/gss-serv.c ---- openssh-8.0p1.orig/gss-serv.c 2019-05-20 08:24:38.086775688 +0200 -+++ openssh-8.0p1/gss-serv.c 2019-05-20 08:25:21.581323124 +0200 +diff -Nur openssh-8.2p1.orig/gss-serv.c openssh-8.2p1/gss-serv.c +--- openssh-8.2p1.orig/gss-serv.c 2020-04-14 11:45:12.656456605 +0200 ++++ openssh-8.2p1/gss-serv.c 2020-04-14 11:46:12.098851283 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -951,9 +951,9 @@ diff -Nur openssh-8.0p1.orig/gss-serv.c openssh-8.0p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.0p1.orig/gss-serv-gsi.c openssh-8.0p1/gss-serv-gsi.c ---- openssh-8.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.0p1/gss-serv-gsi.c 2019-05-20 08:25:21.582323114 +0200 +diff -Nur openssh-8.2p1.orig/gss-serv-gsi.c openssh-8.2p1/gss-serv-gsi.c +--- openssh-8.2p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.2p1/gss-serv-gsi.c 2020-04-14 11:46:12.098851283 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1283,9 +1283,9 @@ diff -Nur openssh-8.0p1.orig/gss-serv-gsi.c openssh-8.0p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.0p1.orig/gss-serv-krb5.c openssh-8.0p1/gss-serv-krb5.c ---- openssh-8.0p1.orig/gss-serv-krb5.c 2019-05-20 08:24:38.107775470 +0200 -+++ openssh-8.0p1/gss-serv-krb5.c 2019-05-20 08:25:21.582323114 +0200 +diff -Nur openssh-8.2p1.orig/gss-serv-krb5.c openssh-8.2p1/gss-serv-krb5.c +--- openssh-8.2p1.orig/gss-serv-krb5.c 2020-04-14 11:45:12.676456401 +0200 ++++ openssh-8.2p1/gss-serv-krb5.c 2020-04-14 11:46:12.098851283 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1339,9 +1339,9 @@ diff -Nur openssh-8.0p1.orig/gss-serv-krb5.c openssh-8.0p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c ---- openssh-8.0p1.orig/kexgsss.c 2019-05-20 08:24:38.072775834 +0200 -+++ openssh-8.0p1/kexgsss.c 2019-05-20 08:25:21.582323114 +0200 +diff -Nur openssh-8.2p1.orig/kexgsss.c openssh-8.2p1/kexgsss.c +--- openssh-8.2p1.orig/kexgsss.c 2020-04-14 11:45:12.642456747 +0200 ++++ openssh-8.2p1/kexgsss.c 2020-04-14 11:46:12.099851273 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1405,21 +1405,21 @@ diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.0p1.orig/Makefile.in openssh-8.0p1/Makefile.in ---- openssh-8.0p1.orig/Makefile.in 2019-05-20 08:24:38.168774835 +0200 -+++ openssh-8.0p1/Makefile.in 2019-05-20 08:25:21.583323104 +0200 -@@ -125,6 +125,7 @@ +diff -Nur openssh-8.2p1.orig/Makefile.in openssh-8.2p1/Makefile.in +--- openssh-8.2p1.orig/Makefile.in 2020-04-14 11:45:12.787455273 +0200 ++++ openssh-8.2p1/Makefile.in 2020-04-14 11:46:12.099851273 +0200 +@@ -135,6 +135,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o sftp-realpath.o \ + sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c ---- openssh-8.0p1.orig/misc.c 2019-05-20 08:24:38.020776375 +0200 -+++ openssh-8.0p1/misc.c 2019-05-20 08:25:21.583323104 +0200 -@@ -313,11 +313,14 @@ +diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c +--- openssh-8.2p1.orig/misc.c 2020-04-14 11:45:12.594457235 +0200 ++++ openssh-8.2p1/misc.c 2020-04-14 11:46:12.100851262 +0200 +@@ -325,11 +325,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1435,7 +1435,7 @@ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c int wspace = 0; if (*s == NULL) -@@ -325,6 +328,21 @@ +@@ -337,6 +340,21 @@ old = *s; @@ -1457,7 +1457,7 @@ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -400,6 +418,20 @@ +@@ -412,6 +430,20 @@ return copy; } @@ -1478,10 +1478,10 @@ diff -Nur openssh-8.0p1.orig/misc.c openssh-8.0p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.0p1.orig/misc.h openssh-8.0p1/misc.h ---- openssh-8.0p1.orig/misc.h 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/misc.h 2019-05-20 08:25:21.583323104 +0200 -@@ -87,6 +87,7 @@ +diff -Nur openssh-8.2p1.orig/misc.h openssh-8.2p1/misc.h +--- openssh-8.2p1.orig/misc.h 2020-02-14 01:40:54.000000000 +0100 ++++ openssh-8.2p1/misc.h 2020-04-14 11:46:12.100851262 +0200 +@@ -90,6 +90,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1489,20 +1489,20 @@ diff -Nur openssh-8.0p1.orig/misc.h openssh-8.0p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c ---- openssh-8.0p1.orig/monitor.c 2019-05-20 08:24:38.176774752 +0200 -+++ openssh-8.0p1/monitor.c 2019-05-20 08:25:21.584323093 +0200 -@@ -154,6 +154,9 @@ +diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c +--- openssh-8.2p1.orig/monitor.c 2020-04-14 11:45:12.805455090 +0200 ++++ openssh-8.2p1/monitor.c 2020-04-14 11:57:51.391466736 +0200 +@@ -155,6 +155,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); - int mm_answer_gss_sign(struct ssh*, int, struct sshbuf *); -+int mm_answer_gss_error(struct ssh*, int, struct sshbuf *); -+int mm_answer_gss_indicate_mechs(struct ssh*, int, struct sshbuf *); -+int mm_answer_gss_localname(struct ssh*, int, struct sshbuf *); - int mm_answer_gss_updatecreds(struct ssh*, int, struct sshbuf *); + int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_error(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_indicate_mechs(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_localname(struct ssh *, int, struct sshbuf *); + int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -206,7 +209,7 @@ +@@ -207,7 +210,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1511,7 +1511,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -214,7 +217,7 @@ +@@ -215,7 +218,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1520,7 +1520,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -238,8 +241,11 @@ +@@ -239,8 +242,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1533,7 +1533,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c #endif {0, 0, NULL} }; -@@ -249,6 +255,8 @@ +@@ -250,6 +256,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1542,7 +1542,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -329,6 +337,8 @@ +@@ -330,6 +338,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1551,7 +1551,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -448,6 +458,8 @@ +@@ -449,6 +459,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1560,7 +1560,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -766,15 +778,18 @@ +@@ -767,15 +779,18 @@ debug3("%s", __func__); @@ -1582,7 +1582,7 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2067,6 +2082,79 @@ +@@ -2093,6 +2108,79 @@ } int @@ -1662,9 +1662,9 @@ diff -Nur openssh-8.0p1.orig/monitor.c openssh-8.0p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.0p1.orig/monitor.h openssh-8.0p1/monitor.h ---- openssh-8.0p1.orig/monitor.h 2019-05-20 08:24:38.158774939 +0200 -+++ openssh-8.0p1/monitor.h 2019-05-20 08:25:21.584323093 +0200 +diff -Nur openssh-8.2p1.orig/monitor.h openssh-8.2p1/monitor.h +--- openssh-8.2p1.orig/monitor.h 2020-04-14 11:45:12.788455263 +0200 ++++ openssh-8.2p1/monitor.h 2020-04-14 11:46:12.102851242 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1676,10 +1676,10 @@ diff -Nur openssh-8.0p1.orig/monitor.h openssh-8.0p1/monitor.h }; struct ssh; -diff -Nur openssh-8.0p1.orig/monitor_wrap.c openssh-8.0p1/monitor_wrap.c ---- openssh-8.0p1.orig/monitor_wrap.c 2019-05-20 08:24:38.176774752 +0200 -+++ openssh-8.0p1/monitor_wrap.c 2019-05-20 08:25:21.584323093 +0200 -@@ -1061,6 +1061,94 @@ +diff -Nur openssh-8.2p1.orig/monitor_wrap.c openssh-8.2p1/monitor_wrap.c +--- openssh-8.2p1.orig/monitor_wrap.c 2020-04-14 11:45:12.805455090 +0200 ++++ openssh-8.2p1/monitor_wrap.c 2020-04-14 11:46:12.103851232 +0200 +@@ -1078,6 +1078,94 @@ return (authenticated); } @@ -1774,10 +1774,10 @@ diff -Nur openssh-8.0p1.orig/monitor_wrap.c openssh-8.0p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h ---- openssh-8.0p1.orig/monitor_wrap.h 2019-05-20 08:24:38.164774877 +0200 -+++ openssh-8.0p1/monitor_wrap.h 2019-05-20 08:25:21.585323083 +0200 -@@ -69,6 +69,10 @@ +diff -Nur openssh-8.2p1.orig/monitor_wrap.h openssh-8.2p1/monitor_wrap.h +--- openssh-8.2p1.orig/monitor_wrap.h 2020-04-14 11:45:12.794455202 +0200 ++++ openssh-8.2p1/monitor_wrap.h 2020-04-14 11:46:12.103851232 +0200 +@@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1788,10 +1788,10 @@ diff -Nur openssh-8.0p1.orig/monitor_wrap.h openssh-8.0p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c ---- openssh-8.0p1.orig/readconf.c 2019-05-20 08:24:38.169774825 +0200 -+++ openssh-8.0p1/readconf.c 2019-05-20 08:25:21.586323072 +0200 -@@ -2052,11 +2052,11 @@ +diff -Nur openssh-8.2p1.orig/readconf.c openssh-8.2p1/readconf.c +--- openssh-8.2p1.orig/readconf.c 2020-04-14 11:45:12.798455161 +0200 ++++ openssh-8.2p1/readconf.c 2020-04-14 11:46:12.104851222 +0200 +@@ -2111,11 +2111,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1806,10 +1806,10 @@ diff -Nur openssh-8.0p1.orig/readconf.c openssh-8.0p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h ---- openssh-8.0p1.orig/readconf.h 2019-05-20 08:24:38.074775813 +0200 -+++ openssh-8.0p1/readconf.h 2019-05-20 08:25:21.586323072 +0200 -@@ -78,6 +78,8 @@ +diff -Nur openssh-8.2p1.orig/readconf.h openssh-8.2p1/readconf.h +--- openssh-8.2p1.orig/readconf.h 2020-04-14 11:45:12.644456727 +0200 ++++ openssh-8.2p1/readconf.h 2020-04-14 11:46:12.104851222 +0200 +@@ -79,6 +79,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1818,10 +1818,10 @@ diff -Nur openssh-8.0p1.orig/readconf.h openssh-8.0p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c ---- openssh-8.0p1.orig/servconf.c 2019-05-20 08:24:38.177774742 +0200 -+++ openssh-8.0p1/servconf.c 2019-05-20 08:25:21.587323062 +0200 -@@ -84,6 +84,7 @@ +diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c +--- openssh-8.2p1.orig/servconf.c 2020-04-14 11:45:12.806455079 +0200 ++++ openssh-8.2p1/servconf.c 2020-04-14 11:46:12.105851211 +0200 +@@ -92,6 +92,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1829,7 +1829,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -127,9 +128,11 @@ +@@ -136,9 +137,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1841,7 +1841,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -286,6 +289,8 @@ +@@ -312,6 +315,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1850,7 +1850,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -363,13 +368,17 @@ +@@ -391,13 +396,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1870,7 +1870,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -501,7 +510,7 @@ +@@ -538,7 +547,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1879,7 +1879,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -523,6 +532,9 @@ +@@ -560,6 +569,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -553,8 +565,10 @@ +@@ -591,8 +603,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1900,7 +1900,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -602,8 +616,15 @@ +@@ -641,8 +655,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1916,7 +1916,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -611,8 +632,11 @@ +@@ -650,8 +671,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1928,7 +1928,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -682,6 +706,8 @@ +@@ -721,6 +745,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1937,7 +1937,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1313,6 +1339,10 @@ +@@ -1361,6 +1387,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1948,7 +1948,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1533,6 +1563,10 @@ +@@ -1600,6 +1630,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1959,7 +1959,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1541,6 +1575,10 @@ +@@ -1608,6 +1642,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1970,7 +1970,7 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1561,6 +1599,12 @@ +@@ -1628,6 +1666,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1983,18 +1983,18 @@ diff -Nur openssh-8.0p1.orig/servconf.c openssh-8.0p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2364,6 +2408,7 @@ +@@ -2550,6 +2594,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); + M_CP_INTOPT(gss_deleg_creds); M_CP_INTOPT(pubkey_authentication); + M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); - M_CP_INTOPT(hostbased_authentication); -diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h ---- openssh-8.0p1.orig/servconf.h 2019-05-20 08:24:38.119775345 +0200 -+++ openssh-8.0p1/servconf.h 2019-05-20 08:25:21.587323062 +0200 -@@ -131,9 +131,12 @@ +diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h +--- openssh-8.2p1.orig/servconf.h 2020-04-14 11:45:12.687456290 +0200 ++++ openssh-8.2p1/servconf.h 2020-04-14 11:46:12.106851201 +0200 +@@ -137,9 +137,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2007,7 +2007,7 @@ diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -192,6 +195,7 @@ +@@ -198,6 +201,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2015,10 +2015,10 @@ diff -Nur openssh-8.0p1.orig/servconf.h openssh-8.0p1/servconf.h int permit_tun; -diff -Nur openssh-8.0p1.orig/ssh.1 openssh-8.0p1/ssh.1 ---- openssh-8.0p1.orig/ssh.1 2019-05-20 08:24:38.075775803 +0200 -+++ openssh-8.0p1/ssh.1 2019-05-20 08:25:21.587323062 +0200 -@@ -1427,6 +1427,18 @@ +diff -Nur openssh-8.2p1.orig/ssh.1 openssh-8.2p1/ssh.1 +--- openssh-8.2p1.orig/ssh.1 2020-04-14 11:45:12.646456706 +0200 ++++ openssh-8.2p1/ssh.1 2020-04-14 11:46:12.107851191 +0200 +@@ -1449,6 +1449,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2037,10 +2037,10 @@ diff -Nur openssh-8.0p1.orig/ssh.1 openssh-8.0p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c ---- openssh-8.0p1.orig/ssh.c 2019-05-20 08:24:38.170774815 +0200 -+++ openssh-8.0p1/ssh.c 2019-05-20 08:25:21.588323052 +0200 -@@ -543,6 +543,38 @@ +diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c +--- openssh-8.2p1.orig/ssh.c 2020-04-14 11:45:12.799455151 +0200 ++++ openssh-8.2p1/ssh.c 2020-04-14 11:46:12.107851191 +0200 +@@ -550,6 +550,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2079,7 +2079,7 @@ diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1295,8 +1327,12 @@ +@@ -1320,8 +1352,12 @@ tty_flag = 0; } @@ -2093,9 +2093,9 @@ diff -Nur openssh-8.0p1.orig/ssh.c openssh-8.0p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) -diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config ---- openssh-8.0p1.orig/ssh_config 2019-05-20 08:24:38.076775793 +0200 -+++ openssh-8.0p1/ssh_config 2019-05-20 08:25:21.588323052 +0200 +diff -Nur openssh-8.2p1.orig/ssh_config openssh-8.2p1/ssh_config +--- openssh-8.2p1.orig/ssh_config 2020-04-14 11:45:12.646456706 +0200 ++++ openssh-8.2p1/ssh_config 2020-04-14 11:46:12.108851181 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2109,9 +2109,9 @@ diff -Nur openssh-8.0p1.orig/ssh_config openssh-8.0p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 ---- openssh-8.0p1.orig/ssh_config.5 2019-05-20 08:24:38.145775075 +0200 -+++ openssh-8.0p1/ssh_config.5 2019-05-20 08:32:58.762570830 +0200 +diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 +--- openssh-8.2p1.orig/ssh_config.5 2020-04-14 11:45:12.770455446 +0200 ++++ openssh-8.2p1/ssh_config.5 2020-04-14 11:46:12.109851171 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2125,7 +2125,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -751,7 +757,7 @@ +@@ -763,7 +769,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2134,7 +2134,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -759,12 +765,12 @@ +@@ -771,12 +777,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2149,15 +2149,7 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -814,7 +820,6 @@ - .Xr crypto-policies 7 . - To see the defaults and how to modify this default, see manual page - .Xr update-crypto-policies 8 . --This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HashKnownHosts - Indicates that - .Xr ssh 1 -@@ -1260,7 +1265,7 @@ +@@ -1306,7 +1312,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2166,22 +2158,22 @@ diff -Nur openssh-8.0p1.orig/ssh_config.5 openssh-8.0p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c ---- openssh-8.0p1.orig/sshconnect2.c 2019-05-20 08:24:38.171774804 +0200 -+++ openssh-8.0p1/sshconnect2.c 2019-05-20 08:25:21.590323031 +0200 -@@ -778,6 +778,11 @@ +diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c +--- openssh-8.2p1.orig/sshconnect2.c 2020-04-14 11:45:12.800455140 +0200 ++++ openssh-8.2p1/sshconnect2.c 2020-04-14 12:05:31.541615458 +0200 +@@ -800,6 +800,11 @@ gss_OID mech = NULL; - char *gss_host; + char *gss_host = NULL; + if (!options.gss_authentication) { + verbose("GSSAPI authentication disabled."); + return 0; + } + - if (options.gss_server_identity) + if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); - else if (options.gss_trust_dns) -@@ -880,7 +885,8 @@ + } else if (options.gss_trust_dns) { +@@ -911,7 +916,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2191,7 +2183,7 @@ diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1050,6 +1056,20 @@ +@@ -1081,6 +1087,20 @@ return r; } @@ -2212,7 +2204,7 @@ diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1072,6 +1092,11 @@ +@@ -1103,6 +1123,11 @@ if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -2224,7 +2216,7 @@ diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -@@ -1085,7 +1110,9 @@ +@@ -1116,7 +1141,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2235,10 +2227,10 @@ diff -Nur openssh-8.0p1.orig/sshconnect2.c openssh-8.0p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.0p1.orig/sshd.8 openssh-8.0p1/sshd.8 ---- openssh-8.0p1.orig/sshd.8 2019-05-20 08:24:38.090775647 +0200 -+++ openssh-8.0p1/sshd.8 2019-05-20 08:25:21.590323031 +0200 -@@ -788,6 +788,29 @@ +diff -Nur openssh-8.2p1.orig/sshd.8 openssh-8.2p1/sshd.8 +--- openssh-8.2p1.orig/sshd.8 2020-04-14 11:45:12.661456554 +0200 ++++ openssh-8.2p1/sshd.8 2020-04-14 11:46:12.110851160 +0200 +@@ -808,6 +808,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2268,10 +2260,10 @@ diff -Nur openssh-8.0p1.orig/sshd.8 openssh-8.0p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.0p1.orig/sshd.c openssh-8.0p1/sshd.c ---- openssh-8.0p1.orig/sshd.c 2019-05-20 08:24:38.179774721 +0200 -+++ openssh-8.0p1/sshd.c 2019-05-20 08:25:21.590323031 +0200 -@@ -2265,7 +2265,7 @@ +diff -Nur openssh-8.2p1.orig/sshd.c openssh-8.2p1/sshd.c +--- openssh-8.2p1.orig/sshd.c 2020-04-14 11:45:12.808455059 +0200 ++++ openssh-8.2p1/sshd.c 2020-04-14 11:46:12.111851150 +0200 +@@ -2338,7 +2338,7 @@ #endif #ifdef GSSAPI @@ -2280,26 +2272,26 @@ diff -Nur openssh-8.0p1.orig/sshd.c openssh-8.0p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.0p1.orig/sshd_config openssh-8.0p1/sshd_config ---- openssh-8.0p1.orig/sshd_config 2019-05-20 08:24:38.114775397 +0200 -+++ openssh-8.0p1/sshd_config 2019-05-20 08:25:21.591323020 +0200 -@@ -84,10 +84,11 @@ +diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config +--- openssh-8.2p1.orig/sshd_config 2020-04-14 11:45:12.678456381 +0200 ++++ openssh-8.2p1/sshd_config 2020-04-14 11:53:17.643165851 +0200 +@@ -72,10 +72,11 @@ #KerberosUseKuserok yes # GSSAPI options --GSSAPIAuthentication yes +-#GSSAPIAuthentication no +#GSSAPIAuthentication yes +#GSSAPIDelegateCredentials yes - GSSAPICleanupCredentials no + #GSSAPICleanupCredentials yes #GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no +#GSSAPIKeyExchange yes #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -103,6 +104,10 @@ +@@ -91,6 +92,10 @@ # problems. - UsePAM yes + #UsePAM no +# Set to 'yes' to allow the PAM stack to change the user name during +# calls to authentication @@ -2308,10 +2300,10 @@ diff -Nur openssh-8.0p1.orig/sshd_config openssh-8.0p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 ---- openssh-8.0p1.orig/sshd_config.5 2019-05-20 08:24:38.146775064 +0200 -+++ openssh-8.0p1/sshd_config.5 2019-05-20 08:32:15.212022217 +0200 -@@ -642,15 +642,34 @@ +diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 +--- openssh-8.2p1.orig/sshd_config.5 2020-04-14 11:45:12.771455435 +0200 ++++ openssh-8.2p1/sshd_config.5 2020-04-14 11:46:12.113851130 +0200 +@@ -635,15 +635,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2347,7 +2339,7 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -661,7 +680,7 @@ +@@ -654,7 +673,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2356,15 +2348,7 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -702,7 +721,6 @@ - .Xr crypto-policies 7 . - To see the defaults and how to modify this default, see manual page - .Xr update-crypto-policies 8 . --This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. -@@ -1652,6 +1670,12 @@ +@@ -1715,6 +1734,12 @@ as a non-root user. The default is .Cm no . @@ -2377,10 +2361,23 @@ diff -Nur openssh-8.0p1.orig/sshd_config.5 openssh-8.0p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h ---- openssh-8.0p1.orig/ssh-gss.h 2019-05-20 08:24:38.087775678 +0200 -+++ openssh-8.0p1/ssh-gss.h 2019-05-20 08:25:21.592323010 +0200 -@@ -93,12 +93,14 @@ +diff -Nur openssh-8.2p1.orig/sshd_config_redhat openssh-8.2p1/sshd_config_redhat +--- openssh-8.2p1.orig/sshd_config_redhat 2020-04-14 11:45:12.629456879 +0200 ++++ openssh-8.2p1/sshd_config_redhat 2020-04-14 12:29:19.383253136 +0200 +@@ -9,9 +9,6 @@ + PasswordAuthentication yes + ChallengeResponseAuthentication no + +-GSSAPIAuthentication yes +-GSSAPICleanupCredentials no +- + UsePAM yes + + X11Forwarding yes +diff -Nur openssh-8.2p1.orig/ssh-gss.h openssh-8.2p1/ssh-gss.h +--- openssh-8.2p1.orig/ssh-gss.h 2020-04-14 11:45:12.657456595 +0200 ++++ openssh-8.2p1/ssh-gss.h 2020-04-14 11:46:12.113851130 +0200 +@@ -97,12 +97,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -2396,7 +2393,7 @@ diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -119,7 +121,7 @@ +@@ -123,7 +125,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2405,7 +2402,7 @@ diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -157,6 +159,9 @@ +@@ -161,6 +163,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2415,12 +2412,12 @@ diff -Nur openssh-8.0p1.orig/ssh-gss.h openssh-8.0p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.0p1.orig/version.h openssh-8.0p1/version.h ---- openssh-8.0p1.orig/version.h 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/version.h 2019-05-20 08:25:21.592323010 +0200 +diff -Nur openssh-8.2p1.orig/version.h openssh-8.2p1/version.h +--- openssh-8.2p1.orig/version.h 2020-02-14 01:40:54.000000000 +0100 ++++ openssh-8.2p1/version.h 2020-04-14 11:46:12.114851120 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.1" + #define SSH_VERSION "OpenSSH_8.2" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.2p1-visibility.patch b/openssh-8.2p1-visibility.patch new file mode 100644 index 0000000..2f0b191 --- /dev/null +++ b/openssh-8.2p1-visibility.patch @@ -0,0 +1,40 @@ +diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c +index dca158de..afdcb1d2 100644 +--- a/regress/misc/sk-dummy/sk-dummy.c ++++ b/regress/misc/sk-dummy/sk-dummy.c +@@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...) + #endif + } + +-uint32_t ++uint32_t __attribute__((visibility("default"))) + sk_api_version(void) + { + return SSH_SK_VERSION_MAJOR; +@@ -220,7 +220,7 @@ check_options(struct sk_option **options) + return 0; + } + +-int ++int __attribute__((visibility("default"))) + sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, + const char *application, uint8_t flags, const char *pin, + struct sk_option **options, struct sk_enroll_response **enroll_response) +@@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, + return ret; + } + +-int ++int __attribute__((visibility("default"))) + sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, + const char *application, const uint8_t *key_handle, size_t key_handle_len, + uint8_t flags, const char *pin, struct sk_option **options, +@@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, + return ret; + } + +-int ++int __attribute__((visibility("default"))) + sk_load_resident_keys(const char *pin, struct sk_option **options, + struct sk_resident_key ***rks, size_t *nrks) + { diff --git a/openssh-8.2p1-x11-without-ipv6.patch b/openssh-8.2p1-x11-without-ipv6.patch new file mode 100644 index 0000000..18b0376 --- /dev/null +++ b/openssh-8.2p1-x11-without-ipv6.patch @@ -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; diff --git a/sources b/sources index 6989a16..dcb370b 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.1p1.tar.gz) = b987ea4ffd4ab0c94110723860273b06ed8ffb4d21cbd99ca144a4722dc55f4bf86f6253d500386b6bee7af50f066e2aa2dd095d50746509a10e11221d39d925 -SHA512 (openssh-8.1p1.tar.gz.asc) = f36458ef8822376a5b305cfbc971f5d2db8bf2f48fea9a957e02ef2fc27a48bacb59495587fee81fa2d89bca6250a8fb407e1f5a7dae7ceb361ab332c0771344 +SHA512 (openssh-8.2p1.tar.gz) = c4db64e52a3a4c410de9de49f9cb104dd493b10250af3599b92457dd986277b3fd99a6f51cec94892fd1be5bd0369c5757262ea7805f0de464b245c3d34c120a +SHA512 (openssh-8.2p1.tar.gz.asc) = e6d091289d62d3a01d5978e3c26f72d8ea6979c345fbebc215515185ea567c959f5b17e32052d752829ab4c6bc537fd977f7aa02cf0a23280da63fd9d880f303 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From c2b8146adc8c913d8219919cddd4105e01bb2c01 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 4 May 2020 19:43:04 +0200 Subject: [PATCH 083/146] Add missing buffer initialization in gsissh patch --- gsi-openssh.spec | 5 +- openssh-8.2p1-gsissh.patch | 170 ++++++++++++++++++++----------------- 2 files changed, 94 insertions(+), 81 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ea8f115..db394d5 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.2p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -514,6 +514,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon May 04 2020 Mattias Ellert - 8.2p1-2 +- Add missing buffer initialization in gsissh patch + * Tue Apr 14 2020 Mattias Ellert - 8.2p1-1 - Based on openssh-8.2p1-3.fc32 diff --git a/openssh-8.2p1-gsissh.patch b/openssh-8.2p1-gsissh.patch index 95e6d9a..61254ae 100644 --- a/openssh-8.2p1-gsissh.patch +++ b/openssh-8.2p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-8.2p1.orig/auth2.c openssh-8.2p1/auth2.c ---- openssh-8.2p1.orig/auth2.c 2020-04-14 11:45:12.784455303 +0200 -+++ openssh-8.2p1/auth2.c 2020-04-14 11:46:12.089851375 +0200 +--- openssh-8.2p1.orig/auth2.c 2020-05-04 19:34:53.561875424 +0200 ++++ openssh-8.2p1/auth2.c 2020-05-04 19:35:31.393472137 +0200 @@ -279,7 +279,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -102,8 +102,8 @@ diff -Nur openssh-8.2p1.orig/auth2.c openssh-8.2p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c ---- openssh-8.2p1.orig/auth2-gss.c 2020-04-14 11:45:12.638456788 +0200 -+++ openssh-8.2p1/auth2-gss.c 2020-04-14 11:46:12.090851364 +0200 +--- openssh-8.2p1.orig/auth2-gss.c 2020-05-04 19:34:53.476876332 +0200 ++++ openssh-8.2p1/auth2-gss.c 2020-05-04 19:37:33.020181539 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -123,7 +123,17 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c u_char *p; size_t len; -@@ -84,13 +85,28 @@ +@@ -74,6 +75,9 @@ + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + ++ if ((b2 = sshbuf_new()) == NULL) ++ fatal("%s: sshbuf_new failed", __func__); ++ + mic.value = p; + mic.length = len; + +@@ -84,13 +88,28 @@ fatal("%s: sshbuf_mutable_ptr failed", __func__); gssbuf.length = sshbuf_len(b); @@ -155,7 +165,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -145,7 +161,9 @@ +@@ -145,7 +164,9 @@ return (0); } @@ -166,7 +176,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c debug2("%s: disabled because of invalid user", __func__); free(doid); return (0); -@@ -183,7 +201,7 @@ +@@ -183,7 +204,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -175,7 +185,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c u_char *p; size_t len; int r; -@@ -204,6 +222,7 @@ +@@ -204,6 +225,7 @@ free(p); if (GSS_ERROR(maj_status)) { @@ -183,7 +193,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c if (send_tok.length != 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || -@@ -278,6 +297,34 @@ +@@ -278,6 +300,34 @@ return 0; } @@ -218,7 +228,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -288,12 +335,14 @@ +@@ -288,12 +338,14 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -234,7 +244,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -302,8 +351,11 @@ +@@ -302,8 +354,11 @@ if ((r = sshpkt_get_end(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); @@ -248,7 +258,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -355,11 +407,17 @@ +@@ -355,11 +410,17 @@ fatal("%s: sshbuf_mutable_ptr failed", __func__); gssbuf.length = sshbuf_len(b); @@ -270,7 +280,7 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c sshbuf_free(b); if (micuser != authctxt->user) -@@ -379,6 +437,26 @@ +@@ -379,6 +440,26 @@ return 0; } @@ -298,8 +308,8 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c "gssapi-keyex", userauth_gsskeyex, diff -Nur openssh-8.2p1.orig/auth.c openssh-8.2p1/auth.c ---- openssh-8.2p1.orig/auth.c 2020-04-14 11:45:12.785455293 +0200 -+++ openssh-8.2p1/auth.c 2020-04-14 11:46:12.091851354 +0200 +--- openssh-8.2p1.orig/auth.c 2020-05-04 19:34:53.562875413 +0200 ++++ openssh-8.2p1/auth.c 2020-05-04 19:35:31.394472126 +0200 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -331,8 +341,8 @@ diff -Nur openssh-8.2p1.orig/auth.c openssh-8.2p1/auth.c record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-8.2p1.orig/auth.h openssh-8.2p1/auth.h ---- openssh-8.2p1.orig/auth.h 2020-04-14 11:45:12.785455293 +0200 -+++ openssh-8.2p1/auth.h 2020-04-14 11:46:12.092851344 +0200 +--- openssh-8.2p1.orig/auth.h 2020-05-04 19:34:53.563875402 +0200 ++++ openssh-8.2p1/auth.h 2020-05-04 19:35:31.394472126 +0200 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -343,8 +353,8 @@ diff -Nur openssh-8.2p1.orig/auth.h openssh-8.2p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c ---- openssh-8.2p1.orig/auth-pam.c 2020-04-14 11:45:12.592457256 +0200 -+++ openssh-8.2p1/auth-pam.c 2020-04-14 12:59:59.598859650 +0200 +--- openssh-8.2p1.orig/auth-pam.c 2020-05-04 19:34:53.433876791 +0200 ++++ openssh-8.2p1/auth-pam.c 2020-05-04 19:35:31.395472115 +0200 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -506,8 +516,8 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-8.2p1.orig/auth-pam.h openssh-8.2p1/auth-pam.h ---- openssh-8.2p1.orig/auth-pam.h 2020-04-14 11:45:12.592457256 +0200 -+++ openssh-8.2p1/auth-pam.h 2020-04-14 11:46:12.094851324 +0200 +--- openssh-8.2p1.orig/auth-pam.h 2020-05-04 19:34:53.433876791 +0200 ++++ openssh-8.2p1/auth-pam.h 2020-05-04 19:35:31.395472115 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -516,8 +526,8 @@ diff -Nur openssh-8.2p1.orig/auth-pam.h openssh-8.2p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-8.2p1.orig/canohost.c openssh-8.2p1/canohost.c ---- openssh-8.2p1.orig/canohost.c 2020-04-14 11:45:12.639456778 +0200 -+++ openssh-8.2p1/canohost.c 2020-04-14 11:46:12.094851324 +0200 +--- openssh-8.2p1.orig/canohost.c 2020-05-04 19:34:53.476876332 +0200 ++++ openssh-8.2p1/canohost.c 2020-05-04 19:35:31.395472115 +0200 @@ -17,6 +17,7 @@ #include #include @@ -561,8 +571,8 @@ diff -Nur openssh-8.2p1.orig/canohost.c openssh-8.2p1/canohost.c + } +} diff -Nur openssh-8.2p1.orig/canohost.h openssh-8.2p1/canohost.h ---- openssh-8.2p1.orig/canohost.h 2020-04-14 11:45:12.639456778 +0200 -+++ openssh-8.2p1/canohost.h 2020-04-14 11:46:12.095851313 +0200 +--- openssh-8.2p1.orig/canohost.h 2020-05-04 19:34:53.476876332 +0200 ++++ openssh-8.2p1/canohost.h 2020-05-04 19:35:31.396472105 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -571,8 +581,8 @@ diff -Nur openssh-8.2p1.orig/canohost.h openssh-8.2p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac ---- openssh-8.2p1.orig/configure.ac 2020-04-14 11:45:12.777455374 +0200 -+++ openssh-8.2p1/configure.ac 2020-04-14 11:46:12.096851303 +0200 +--- openssh-8.2p1.orig/configure.ac 2020-05-04 19:34:53.554875498 +0200 ++++ openssh-8.2p1/configure.ac 2020-05-04 19:35:31.397472094 +0200 @@ -4710,6 +4710,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -630,8 +640,8 @@ diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac SYSTEMD_MSG="no" AC_ARG_WITH(systemd, diff -Nur openssh-8.2p1.orig/gss-genr.c openssh-8.2p1/gss-genr.c ---- openssh-8.2p1.orig/gss-genr.c 2020-04-14 11:45:12.640456767 +0200 -+++ openssh-8.2p1/gss-genr.c 2020-04-14 11:46:12.097851293 +0200 +--- openssh-8.2p1.orig/gss-genr.c 2020-05-04 19:34:53.478876310 +0200 ++++ openssh-8.2p1/gss-genr.c 2020-05-04 19:35:31.397472094 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -669,8 +679,8 @@ diff -Nur openssh-8.2p1.orig/gss-genr.c openssh-8.2p1/gss-genr.c return (ctx->major); } diff -Nur openssh-8.2p1.orig/gss-serv.c openssh-8.2p1/gss-serv.c ---- openssh-8.2p1.orig/gss-serv.c 2020-04-14 11:45:12.656456605 +0200 -+++ openssh-8.2p1/gss-serv.c 2020-04-14 11:46:12.098851283 +0200 +--- openssh-8.2p1.orig/gss-serv.c 2020-05-04 19:34:53.494876139 +0200 ++++ openssh-8.2p1/gss-serv.c 2020-05-04 19:35:31.397472094 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -953,7 +963,7 @@ diff -Nur openssh-8.2p1.orig/gss-serv.c openssh-8.2p1/gss-serv.c diff -Nur openssh-8.2p1.orig/gss-serv-gsi.c openssh-8.2p1/gss-serv-gsi.c --- openssh-8.2p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.2p1/gss-serv-gsi.c 2020-04-14 11:46:12.098851283 +0200 ++++ openssh-8.2p1/gss-serv-gsi.c 2020-05-04 19:35:31.398472084 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1284,8 +1294,8 @@ diff -Nur openssh-8.2p1.orig/gss-serv-gsi.c openssh-8.2p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-8.2p1.orig/gss-serv-krb5.c openssh-8.2p1/gss-serv-krb5.c ---- openssh-8.2p1.orig/gss-serv-krb5.c 2020-04-14 11:45:12.676456401 +0200 -+++ openssh-8.2p1/gss-serv-krb5.c 2020-04-14 11:46:12.098851283 +0200 +--- openssh-8.2p1.orig/gss-serv-krb5.c 2020-05-04 19:34:53.514875926 +0200 ++++ openssh-8.2p1/gss-serv-krb5.c 2020-05-04 19:35:31.398472084 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1340,8 +1350,8 @@ diff -Nur openssh-8.2p1.orig/gss-serv-krb5.c openssh-8.2p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-8.2p1.orig/kexgsss.c openssh-8.2p1/kexgsss.c ---- openssh-8.2p1.orig/kexgsss.c 2020-04-14 11:45:12.642456747 +0200 -+++ openssh-8.2p1/kexgsss.c 2020-04-14 11:46:12.099851273 +0200 +--- openssh-8.2p1.orig/kexgsss.c 2020-05-04 19:34:53.480876289 +0200 ++++ openssh-8.2p1/kexgsss.c 2020-05-04 19:35:31.398472084 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1406,8 +1416,8 @@ diff -Nur openssh-8.2p1.orig/kexgsss.c openssh-8.2p1/kexgsss.c +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff -Nur openssh-8.2p1.orig/Makefile.in openssh-8.2p1/Makefile.in ---- openssh-8.2p1.orig/Makefile.in 2020-04-14 11:45:12.787455273 +0200 -+++ openssh-8.2p1/Makefile.in 2020-04-14 11:46:12.099851273 +0200 +--- openssh-8.2p1.orig/Makefile.in 2020-05-04 19:34:53.564875392 +0200 ++++ openssh-8.2p1/Makefile.in 2020-05-04 19:35:31.398472084 +0200 @@ -135,6 +135,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1417,8 +1427,8 @@ diff -Nur openssh-8.2p1.orig/Makefile.in openssh-8.2p1/Makefile.in sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c ---- openssh-8.2p1.orig/misc.c 2020-04-14 11:45:12.594457235 +0200 -+++ openssh-8.2p1/misc.c 2020-04-14 11:46:12.100851262 +0200 +--- openssh-8.2p1.orig/misc.c 2020-05-04 19:34:53.434876780 +0200 ++++ openssh-8.2p1/misc.c 2020-05-04 19:35:31.399472073 +0200 @@ -325,11 +325,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1480,7 +1490,7 @@ diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c * Port must be >=0 and <=65535. diff -Nur openssh-8.2p1.orig/misc.h openssh-8.2p1/misc.h --- openssh-8.2p1.orig/misc.h 2020-02-14 01:40:54.000000000 +0100 -+++ openssh-8.2p1/misc.h 2020-04-14 11:46:12.100851262 +0200 ++++ openssh-8.2p1/misc.h 2020-05-04 19:35:31.399472073 +0200 @@ -90,6 +90,7 @@ void sock_set_v6only(int); @@ -1490,8 +1500,8 @@ diff -Nur openssh-8.2p1.orig/misc.h openssh-8.2p1/misc.h typedef struct arglist arglist; diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c ---- openssh-8.2p1.orig/monitor.c 2020-04-14 11:45:12.805455090 +0200 -+++ openssh-8.2p1/monitor.c 2020-04-14 11:57:51.391466736 +0200 +--- openssh-8.2p1.orig/monitor.c 2020-05-04 19:34:53.583875189 +0200 ++++ openssh-8.2p1/monitor.c 2020-05-04 19:35:31.400472062 +0200 @@ -155,6 +155,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1663,8 +1673,8 @@ diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c { gss_buffer_desc data; diff -Nur openssh-8.2p1.orig/monitor.h openssh-8.2p1/monitor.h ---- openssh-8.2p1.orig/monitor.h 2020-04-14 11:45:12.788455263 +0200 -+++ openssh-8.2p1/monitor.h 2020-04-14 11:46:12.102851242 +0200 +--- openssh-8.2p1.orig/monitor.h 2020-05-04 19:34:53.565875381 +0200 ++++ openssh-8.2p1/monitor.h 2020-05-04 19:35:31.400472062 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1677,8 +1687,8 @@ diff -Nur openssh-8.2p1.orig/monitor.h openssh-8.2p1/monitor.h struct ssh; diff -Nur openssh-8.2p1.orig/monitor_wrap.c openssh-8.2p1/monitor_wrap.c ---- openssh-8.2p1.orig/monitor_wrap.c 2020-04-14 11:45:12.805455090 +0200 -+++ openssh-8.2p1/monitor_wrap.c 2020-04-14 11:46:12.103851232 +0200 +--- openssh-8.2p1.orig/monitor_wrap.c 2020-05-04 19:34:53.583875189 +0200 ++++ openssh-8.2p1/monitor_wrap.c 2020-05-04 19:35:31.400472062 +0200 @@ -1078,6 +1078,94 @@ return (authenticated); } @@ -1775,8 +1785,8 @@ diff -Nur openssh-8.2p1.orig/monitor_wrap.c openssh-8.2p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-8.2p1.orig/monitor_wrap.h openssh-8.2p1/monitor_wrap.h ---- openssh-8.2p1.orig/monitor_wrap.h 2020-04-14 11:45:12.794455202 +0200 -+++ openssh-8.2p1/monitor_wrap.h 2020-04-14 11:46:12.103851232 +0200 +--- openssh-8.2p1.orig/monitor_wrap.h 2020-05-04 19:34:53.572875306 +0200 ++++ openssh-8.2p1/monitor_wrap.h 2020-05-04 19:35:31.401472052 +0200 @@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1789,8 +1799,8 @@ diff -Nur openssh-8.2p1.orig/monitor_wrap.h openssh-8.2p1/monitor_wrap.h #endif diff -Nur openssh-8.2p1.orig/readconf.c openssh-8.2p1/readconf.c ---- openssh-8.2p1.orig/readconf.c 2020-04-14 11:45:12.798455161 +0200 -+++ openssh-8.2p1/readconf.c 2020-04-14 11:46:12.104851222 +0200 +--- openssh-8.2p1.orig/readconf.c 2020-05-04 19:34:53.576875263 +0200 ++++ openssh-8.2p1/readconf.c 2020-05-04 19:35:31.401472052 +0200 @@ -2111,11 +2111,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; @@ -1807,8 +1817,8 @@ diff -Nur openssh-8.2p1.orig/readconf.c openssh-8.2p1/readconf.c options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) diff -Nur openssh-8.2p1.orig/readconf.h openssh-8.2p1/readconf.h ---- openssh-8.2p1.orig/readconf.h 2020-04-14 11:45:12.644456727 +0200 -+++ openssh-8.2p1/readconf.h 2020-04-14 11:46:12.104851222 +0200 +--- openssh-8.2p1.orig/readconf.h 2020-05-04 19:34:53.482876268 +0200 ++++ openssh-8.2p1/readconf.h 2020-05-04 19:35:31.401472052 +0200 @@ -79,6 +79,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1819,8 +1829,8 @@ diff -Nur openssh-8.2p1.orig/readconf.h openssh-8.2p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c ---- openssh-8.2p1.orig/servconf.c 2020-04-14 11:45:12.806455079 +0200 -+++ openssh-8.2p1/servconf.c 2020-04-14 11:46:12.105851211 +0200 +--- openssh-8.2p1.orig/servconf.c 2020-05-04 19:34:53.584875178 +0200 ++++ openssh-8.2p1/servconf.c 2020-05-04 19:35:31.402472041 +0200 @@ -92,6 +92,7 @@ /* Portable-specific options */ @@ -1992,8 +2002,8 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h ---- openssh-8.2p1.orig/servconf.h 2020-04-14 11:45:12.687456290 +0200 -+++ openssh-8.2p1/servconf.h 2020-04-14 11:46:12.106851201 +0200 +--- openssh-8.2p1.orig/servconf.h 2020-05-04 19:34:53.525875808 +0200 ++++ openssh-8.2p1/servconf.h 2020-05-04 19:35:31.402472041 +0200 @@ -137,9 +137,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2016,8 +2026,8 @@ diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h int permit_tun; diff -Nur openssh-8.2p1.orig/ssh.1 openssh-8.2p1/ssh.1 ---- openssh-8.2p1.orig/ssh.1 2020-04-14 11:45:12.646456706 +0200 -+++ openssh-8.2p1/ssh.1 2020-04-14 11:46:12.107851191 +0200 +--- openssh-8.2p1.orig/ssh.1 2020-05-04 19:34:53.484876246 +0200 ++++ openssh-8.2p1/ssh.1 2020-05-04 19:35:31.403472031 +0200 @@ -1449,6 +1449,18 @@ on to new connections). .It Ev USER @@ -2038,8 +2048,8 @@ diff -Nur openssh-8.2p1.orig/ssh.1 openssh-8.2p1/ssh.1 .Pp Additionally, diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c ---- openssh-8.2p1.orig/ssh.c 2020-04-14 11:45:12.799455151 +0200 -+++ openssh-8.2p1/ssh.c 2020-04-14 11:46:12.107851191 +0200 +--- openssh-8.2p1.orig/ssh.c 2020-05-04 19:34:53.577875253 +0200 ++++ openssh-8.2p1/ssh.c 2020-05-04 19:35:31.403472031 +0200 @@ -550,6 +550,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2094,8 +2104,8 @@ diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c /* Set up strings used to percent_expand() arguments */ if (gethostname(thishost, sizeof(thishost)) == -1) diff -Nur openssh-8.2p1.orig/ssh_config openssh-8.2p1/ssh_config ---- openssh-8.2p1.orig/ssh_config 2020-04-14 11:45:12.646456706 +0200 -+++ openssh-8.2p1/ssh_config 2020-04-14 11:46:12.108851181 +0200 +--- openssh-8.2p1.orig/ssh_config 2020-05-04 19:34:53.484876246 +0200 ++++ openssh-8.2p1/ssh_config 2020-05-04 19:35:31.404472020 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2110,8 +2120,8 @@ diff -Nur openssh-8.2p1.orig/ssh_config openssh-8.2p1/ssh_config # BatchMode no # CheckHostIP yes diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 ---- openssh-8.2p1.orig/ssh_config.5 2020-04-14 11:45:12.770455446 +0200 -+++ openssh-8.2p1/ssh_config.5 2020-04-14 11:46:12.109851171 +0200 +--- openssh-8.2p1.orig/ssh_config.5 2020-05-04 19:34:53.548875562 +0200 ++++ openssh-8.2p1/ssh_config.5 2020-05-04 19:35:31.404472020 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2159,8 +2169,8 @@ diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c ---- openssh-8.2p1.orig/sshconnect2.c 2020-04-14 11:45:12.800455140 +0200 -+++ openssh-8.2p1/sshconnect2.c 2020-04-14 12:05:31.541615458 +0200 +--- openssh-8.2p1.orig/sshconnect2.c 2020-05-04 19:34:53.578875242 +0200 ++++ openssh-8.2p1/sshconnect2.c 2020-05-04 19:35:31.405472009 +0200 @@ -800,6 +800,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2228,8 +2238,8 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || diff -Nur openssh-8.2p1.orig/sshd.8 openssh-8.2p1/sshd.8 ---- openssh-8.2p1.orig/sshd.8 2020-04-14 11:45:12.661456554 +0200 -+++ openssh-8.2p1/sshd.8 2020-04-14 11:46:12.110851160 +0200 +--- openssh-8.2p1.orig/sshd.8 2020-05-04 19:34:53.499876086 +0200 ++++ openssh-8.2p1/sshd.8 2020-05-04 19:35:31.405472009 +0200 @@ -808,6 +808,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2261,8 +2271,8 @@ diff -Nur openssh-8.2p1.orig/sshd.8 openssh-8.2p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-8.2p1.orig/sshd.c openssh-8.2p1/sshd.c ---- openssh-8.2p1.orig/sshd.c 2020-04-14 11:45:12.808455059 +0200 -+++ openssh-8.2p1/sshd.c 2020-04-14 11:46:12.111851150 +0200 +--- openssh-8.2p1.orig/sshd.c 2020-05-04 19:34:53.586875156 +0200 ++++ openssh-8.2p1/sshd.c 2020-05-04 19:35:31.406471999 +0200 @@ -2338,7 +2338,7 @@ #endif @@ -2273,8 +2283,8 @@ diff -Nur openssh-8.2p1.orig/sshd.c openssh-8.2p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config ---- openssh-8.2p1.orig/sshd_config 2020-04-14 11:45:12.678456381 +0200 -+++ openssh-8.2p1/sshd_config 2020-04-14 11:53:17.643165851 +0200 +--- openssh-8.2p1.orig/sshd_config 2020-05-04 19:34:53.516875904 +0200 ++++ openssh-8.2p1/sshd_config 2020-05-04 19:35:31.406471999 +0200 @@ -72,10 +72,11 @@ #KerberosUseKuserok yes @@ -2301,8 +2311,8 @@ diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config #AllowTcpForwarding yes #GatewayPorts no diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 ---- openssh-8.2p1.orig/sshd_config.5 2020-04-14 11:45:12.771455435 +0200 -+++ openssh-8.2p1/sshd_config.5 2020-04-14 11:46:12.113851130 +0200 +--- openssh-8.2p1.orig/sshd_config.5 2020-05-04 19:34:53.548875562 +0200 ++++ openssh-8.2p1/sshd_config.5 2020-05-04 19:35:31.406471999 +0200 @@ -635,15 +635,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2362,8 +2372,8 @@ diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. diff -Nur openssh-8.2p1.orig/sshd_config_redhat openssh-8.2p1/sshd_config_redhat ---- openssh-8.2p1.orig/sshd_config_redhat 2020-04-14 11:45:12.629456879 +0200 -+++ openssh-8.2p1/sshd_config_redhat 2020-04-14 12:29:19.383253136 +0200 +--- openssh-8.2p1.orig/sshd_config_redhat 2020-05-04 19:34:53.466876438 +0200 ++++ openssh-8.2p1/sshd_config_redhat 2020-05-04 19:35:31.407471988 +0200 @@ -9,9 +9,6 @@ PasswordAuthentication yes ChallengeResponseAuthentication no @@ -2375,8 +2385,8 @@ diff -Nur openssh-8.2p1.orig/sshd_config_redhat openssh-8.2p1/sshd_config_redhat X11Forwarding yes diff -Nur openssh-8.2p1.orig/ssh-gss.h openssh-8.2p1/ssh-gss.h ---- openssh-8.2p1.orig/ssh-gss.h 2020-04-14 11:45:12.657456595 +0200 -+++ openssh-8.2p1/ssh-gss.h 2020-04-14 11:46:12.113851130 +0200 +--- openssh-8.2p1.orig/ssh-gss.h 2020-05-04 19:34:53.496876118 +0200 ++++ openssh-8.2p1/ssh-gss.h 2020-05-04 19:35:31.407471988 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2414,7 +2424,7 @@ diff -Nur openssh-8.2p1.orig/ssh-gss.h openssh-8.2p1/ssh-gss.h const char *); diff -Nur openssh-8.2p1.orig/version.h openssh-8.2p1/version.h --- openssh-8.2p1.orig/version.h 2020-02-14 01:40:54.000000000 +0100 -+++ openssh-8.2p1/version.h 2020-04-14 11:46:12.114851120 +0200 ++++ openssh-8.2p1/version.h 2020-05-04 19:35:31.407471988 +0200 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_8.2" From 3e49e59ef47a9360613ce7257b94903c17e208ca Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 30 May 2020 19:33:41 +0200 Subject: [PATCH 084/146] Based on openssh-8.3p1-1.fc32 --- gsi-openssh.spec | 12 +- openssh-7.6p1-audit.patch | 4 +- openssh-7.7p1-fips.patch | 4 +- openssh-7.7p1-gssapi-new-unique.patch | 4 +- openssh-8.0p1-gssapi-keyex.patch | 6 +- openssh-8.0p1-pkcs11-uri.patch | 12 +- openssh-8.2p1-visibility.patch | 2 +- ...gsissh.patch => openssh-8.3p1-gsissh.patch | 2 +- openssh-8.3p1-sshd_include.patch | 227 ++++++++++++++++++ sources | 4 +- 10 files changed, 256 insertions(+), 21 deletions(-) rename openssh-8.2p1-gsissh.patch => openssh-8.3p1-gsissh.patch (99%) create mode 100644 openssh-8.3p1-sshd_include.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index db394d5..310f8f2 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -30,8 +30,8 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 8.2p1 -%global openssh_rel 2 +%global openssh_ver 8.3p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -160,10 +160,12 @@ Patch964: openssh-8.0p1-openssl-kdf.patch Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 Patch966: openssh-8.2p1-x11-without-ipv6.patch +# Unbreak sshd_config include corner cases (#3122) +Patch967: openssh-8.3p1-sshd_include.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-8.2p1-gsissh.patch +Patch98: openssh-8.3p1-gsissh.patch License: BSD Requires: /sbin/nologin @@ -307,6 +309,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch964 -p1 -b .openssl-kdf %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 +%patch967 -p1 -b .include %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -514,6 +517,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Sat May 30 2020 Mattias Ellert - 8.3p1-1 +- Based on openssh-8.3p1-1.fc32 + * Mon May 04 2020 Mattias Ellert - 8.2p1-2 - Add missing buffer initialization in gsissh patch diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 024d990..675b672 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -883,8 +883,8 @@ diff -up openssh/cipher.c.audit openssh/cipher.c - if (cc == NULL) + if (cc == NULL || cc->cipher == NULL) return; - if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) - explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { + chachapoly_free(cc->cp_ctx); diff -up openssh/cipher.h.audit openssh/cipher.h --- openssh/cipher.h.audit 2019-03-27 23:26:14.000000000 +0100 +++ openssh/cipher.h 2019-04-03 17:02:20.714886050 +0200 diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 21eba1d..bb69efe 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -453,5 +453,5 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c fflush(stdout); - type = sshkey_type_from_name(key_types[i].key_type); if ((fd = mkstemp(prv_tmp)) == -1) { - error("Could not save your public key in %s: %s", - prv_tmp, strerror(errno)); + error("Could not save your private key in %s: %s", + prv_tmp, strerror(errno)); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 9386249..506c79a 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -480,7 +480,7 @@ index 6cae720e..16e55cbc 100644 + return 0; } - /* This allows GSSAPI methods to do things to the childs environment based + /* This allows GSSAPI methods to do things to the child's environment based @@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() { char *envstr; #endif @@ -574,7 +574,7 @@ index 85df6a27..480a5ead 100644 +++ b/session.c @@ -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 childs environment as they see fit + * the child's environment as they see fit */ - ssh_gssapi_do_child(&env, &envsize); + if (s->authctxt->krb5_set_env) diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 8c6de02..770e99e 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -964,7 +964,7 @@ index ab3a15f0..6ce56e92 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.31 2018/07/09 21:37:55 markus Exp $ */ + /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -3277,8 +3277,8 @@ index 36180d07..70dd3665 100644 + KEX_GSS_GRP16_SHA512_ID "," \ + KEX_GSS_NISTP256_SHA256_ID "," \ + KEX_GSS_C25519_SHA256_ID "," \ -+ KEX_GSS_GEX_SHA1_ID "," \ -+ KEX_GSS_GRP14_SHA1_ID ++ KEX_GSS_GRP14_SHA1_ID "," \ ++ KEX_GSS_GEX_SHA1_ID + typedef struct { char *filename; diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 712f703..7c00b13 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -48,7 +48,7 @@ index e7549470..4511f82a 100644 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ + ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ @@ -289,6 +289,8 @@ clean: regressclean @@ -2502,7 +2502,7 @@ index a302c79c..879fe917 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1484,165 +1670,301 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1484,167 +1670,303 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2830,6 +2830,8 @@ index a302c79c..879fe917 100644 } - if (handle) - dlclose(handle); + if (ret > 0) + ret = -1; return (ret); } @@ -3109,9 +3111,9 @@ index 15aee569..976844cb 100644 + } +#endif /* ENABLE_PKCS11 */ + cp = tilde_expand_filename(name, getuid()); - filename = percent_expand(cp, "d", pw->pw_dir, - "u", pw->pw_name, "l", thishost, "h", host, - "r", options.user, (char *)NULL); + filename = default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); + free(cp); diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..4b2763bd 100644 --- a/ssh_config.5 diff --git a/openssh-8.2p1-visibility.patch b/openssh-8.2p1-visibility.patch index 2f0b191..89c35ef 100644 --- a/openssh-8.2p1-visibility.patch +++ b/openssh-8.2p1-visibility.patch @@ -26,7 +26,7 @@ index dca158de..afdcb1d2 100644 -int +int __attribute__((visibility("default"))) - sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, + sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, const char *pin, struct sk_option **options, @@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, diff --git a/openssh-8.2p1-gsissh.patch b/openssh-8.3p1-gsissh.patch similarity index 99% rename from openssh-8.2p1-gsissh.patch rename to openssh-8.3p1-gsissh.patch index 61254ae..284cb1c 100644 --- a/openssh-8.2p1-gsissh.patch +++ b/openssh-8.3p1-gsissh.patch @@ -2427,7 +2427,7 @@ diff -Nur openssh-8.2p1.orig/version.h openssh-8.2p1/version.h +++ openssh-8.2p1/version.h 2020-05-04 19:35:31.407471988 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.2" + #define SSH_VERSION "OpenSSH_8.3" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.3p1-sshd_include.patch b/openssh-8.3p1-sshd_include.patch new file mode 100644 index 0000000..a399e6a --- /dev/null +++ b/openssh-8.3p1-sshd_include.patch @@ -0,0 +1,227 @@ +From 3caa40f40c7f97ecf46969e050e530338864033e Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 25 May 2020 15:46:51 +0200 +Subject: [PATCH 1/3] regress: Add more test cases + +--- + regress/servcfginclude.sh | 36 +++++++++++++++++++++++++++++++++++- + 1 file changed, 35 insertions(+), 1 deletion(-) + +diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh +index b25c8faa..b6a9a248 100644 +--- a/regress/servcfginclude.sh ++++ b/regress/servcfginclude.sh +@@ -146,9 +146,43 @@ Include + _EOF + + trace "disallow invalid with no argument" +-${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x \ ++${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x -T \ + -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \ + fail "sshd allowed Include with no argument" + ++# Ensure the Include before any Match block works as expected (bug #3122) ++cat > $OBJ/sshd_config.i << _EOF ++Banner /xx ++HostKey $OBJ/host.ssh-ed25519 ++Include $OBJ/sshd_config.i.2 ++Match host a ++ Banner /aaaa ++_EOF ++cat > $OBJ/sshd_config.i.2 << _EOF ++Match host a ++ Banner /aa ++_EOF ++ ++trace "Include before match blocks" ++trial a /aa "included file before match blocks is properly evaluated" ++ ++# Port in included file is correctly interpretted (bug #3169) ++cat > $OBJ/sshd_config.i << _EOF ++Include $OBJ/sshd_config.i.2 ++Port 7722 ++_EOF ++cat > $OBJ/sshd_config.i.2 << _EOF ++HostKey $OBJ/host.ssh-ed25519 ++_EOF ++ ++trace "Port after included files" ++${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \ ++ -C "host=x,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out || \ ++ fail "failed to parse Port after included files" ++_port=`grep -i '^port ' $OBJ/sshd_config.out | awk '{print $2}'` ++if test "x7722" != "x$_port" ; then ++ fail "The Port in included file was intertepretted wrongly. Expected 7722, got $_port" ++fi ++ + # cleanup + rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out +-- +2.25.4 + + +From 924922fcb8f34fb4a156367de2ee33ad92a68a6a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 25 May 2020 16:56:39 +0200 +Subject: [PATCH 2/3] Do not call process_queued_listen_addrs() for every + included file + +Fixes #3169 +--- + servconf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/servconf.c b/servconf.c +index 5bb4b1f8..78a7d87d 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -74,7 +74,7 @@ static void add_listen_addr(ServerOptions *, const char *, + const char *, int); + static void add_one_listen_addr(ServerOptions *, const char *, + const char *, int); +-void parse_server_config_depth(ServerOptions *options, const char *filename, ++static void parse_server_config_depth(ServerOptions *options, const char *filename, + struct sshbuf *conf, struct include_list *includes, + struct connection_info *connectinfo, int flags, int *activep, int depth); + +@@ -2580,7 +2580,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + #undef M_CP_STRARRAYOPT + + #define SERVCONF_MAX_DEPTH 16 +-void ++static void + parse_server_config_depth(ServerOptions *options, const char *filename, + struct sshbuf *conf, struct include_list *includes, + struct connection_info *connectinfo, int flags, int *activep, int depth) +@@ -2606,7 +2606,6 @@ parse_server_config_depth(ServerOptions *options, const char *filename, + if (bad_options > 0) + fatal("%s: terminating, %d bad configuration options", + filename, bad_options); +- process_queued_listen_addrs(options); + } + + void +@@ -2617,6 +2616,7 @@ parse_server_config(ServerOptions *options, const char *filename, + int active = connectinfo ? 0 : 1; + parse_server_config_depth(options, filename, conf, includes, + connectinfo, 0, &active, 0); ++ process_queued_listen_addrs(options); + } + + static const char * +-- +2.25.4 + + +From 26d970b4fb373cb7bd99286e41dd095cd1eadbd0 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 26 May 2020 16:25:24 +0200 +Subject: [PATCH 3/3] servconf: Fix parsing of Match blocks in included files + (#3122) + +--- + servconf.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/servconf.c b/servconf.c +index 78a7d87d..a8541514 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -554,6 +554,7 @@ typedef enum { + #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ + #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) + #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */ ++#define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */ + + /* Textual representation of the tokens. */ + static struct { +@@ -1265,7 +1266,7 @@ static const struct multistate multistate_tcpfwd[] = { + static int + process_server_config_line_depth(ServerOptions *options, char *line, + const char *filename, int linenum, int *activep, +- struct connection_info *connectinfo, int inc_flags, int depth, ++ struct connection_info *connectinfo, int *inc_flags, int depth, + struct include_list *includes) + { + char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; +@@ -2012,7 +2013,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, + parse_server_config_depth(options, + item->filename, item->contents, + includes, connectinfo, +- (oactive ? 0 : SSHCFG_NEVERMATCH), ++ (*inc_flags & SSHCFG_MATCH_ONLY ++ ? SSHCFG_MATCH_ONLY : (oactive ++ ? 0 : SSHCFG_NEVERMATCH)), + activep, depth + 1); + } + found = 1; +@@ -2060,7 +2063,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, + parse_server_config_depth(options, + item->filename, item->contents, + includes, connectinfo, +- (oactive ? 0 : SSHCFG_NEVERMATCH), ++ (*inc_flags & SSHCFG_MATCH_ONLY ++ ? SSHCFG_MATCH_ONLY : (oactive ++ ? 0 : SSHCFG_NEVERMATCH)), + activep, depth + 1); + *activep = oactive; + TAILQ_INSERT_TAIL(includes, item, entry); +@@ -2078,11 +2083,14 @@ process_server_config_line_depth(ServerOptions *options, char *line, + if (cmdline) + fatal("Match directive not supported as a command-line " + "option"); +- value = match_cfg_line(&cp, linenum, connectinfo); ++ value = match_cfg_line(&cp, linenum, ++ (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo)); + if (value < 0) + fatal("%s line %d: Bad Match condition", filename, + linenum); +- *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; ++ *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; ++ /* The MATCH_ONLY is applicable only until the first match block */ ++ *inc_flags &= ~SSHCFG_MATCH_ONLY; + break; + + case sKerberosUseKuserok: +@@ -2385,8 +2393,9 @@ process_server_config_line(ServerOptions *options, char *line, + const char *filename, int linenum, int *activep, + struct connection_info *connectinfo, struct include_list *includes) + { ++ int inc_flags = 0; + return process_server_config_line_depth(options, line, filename, +- linenum, activep, connectinfo, 0, 0, includes); ++ linenum, activep, connectinfo, &inc_flags, 0, includes); + } + + +@@ -2591,14 +2600,15 @@ parse_server_config_depth(ServerOptions *options, const char *filename, + if (depth < 0 || depth > SERVCONF_MAX_DEPTH) + fatal("Too many recursive configuration includes"); + +- debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); ++ debug2("%s: config %s len %zu%s", __func__, filename, sshbuf_len(conf), ++ (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : "")); + + if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) + fatal("%s: sshbuf_dup_string failed", __func__); + linenum = 1; + while ((cp = strsep(&cbuf, "\n")) != NULL) { + if (process_server_config_line_depth(options, cp, +- filename, linenum++, activep, connectinfo, flags, ++ filename, linenum++, activep, connectinfo, &flags, + depth, includes) != 0) + bad_options++; + } +@@ -2615,7 +2625,7 @@ parse_server_config(ServerOptions *options, const char *filename, + { + int active = connectinfo ? 0 : 1; + parse_server_config_depth(options, filename, conf, includes, +- connectinfo, 0, &active, 0); ++ connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0); + process_queued_listen_addrs(options); + } + +-- +2.25.4 + + diff --git a/sources b/sources index dcb370b..c3131e5 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.2p1.tar.gz) = c4db64e52a3a4c410de9de49f9cb104dd493b10250af3599b92457dd986277b3fd99a6f51cec94892fd1be5bd0369c5757262ea7805f0de464b245c3d34c120a -SHA512 (openssh-8.2p1.tar.gz.asc) = e6d091289d62d3a01d5978e3c26f72d8ea6979c345fbebc215515185ea567c959f5b17e32052d752829ab4c6bc537fd977f7aa02cf0a23280da63fd9d880f303 +SHA512 (openssh-8.3p1.tar.gz) = b5232f7c85bf59ae2ff9d17b030117012e257e3b8c0d5ac60bb139a85b1fbf298b40f2e04203a2e13ca7273053ed668b9dedd54d3a67a7cb8e8e58c0228c5f40 +SHA512 (openssh-8.3p1.tar.gz.asc) = 569fa12b3671af15bd7cd54fc7b13d1d64f3e96eb28f6dc430082f7bec4595689c633d3d56c23faad45b73e4da666c3ec090de26bf54f49410ba9bb8b5363e75 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From 4713fab392a6bb2e92f327fe3d71326c738de954 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 4 Jun 2020 15:55:34 +0200 Subject: [PATCH 085/146] Based on openssh-8.3p1-2.fc32 --- gsi-openssh.spec | 5 ++++- openssh-7.6p1-audit.patch | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 310f8f2..eab233a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.3p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -517,6 +517,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Jun 04 2020 Mattias Ellert - 8.3p1-2 +- Based on openssh-8.3p1-2.fc32 + * Sat May 30 2020 Mattias Ellert - 8.3p1-1 - Based on openssh-8.3p1-1.fc32 diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 675b672..98d5709 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1738,7 +1738,7 @@ diff -up openssh/packet.c.audit openssh/packet.c state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2167,6 +2183,71 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2167,6 +2183,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1769,6 +1769,7 @@ diff -up openssh/packet.c.audit openssh/packet.c + + cipher_free(state->receive_context); + cipher_free(state->send_context); ++ state->send_context = state->receive_context = NULL; + + sshbuf_free(state->input); + state->input = NULL; From e920d28c57ce33f0223830d96b9818d31c8f0281 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 11 Jun 2020 10:03:55 +0200 Subject: [PATCH 086/146] Based on openssh-8.3p1-3.fc32 --- gsi-openssh.spec | 17 ++++++++++------- gsisshd.service | 3 +-- gsisshd@.service | 3 +-- openssh-7.7p1-redhat.patch | 27 ++++++++++++--------------- openssh-8.0p1-pkcs11-uri.patch | 8 ++++---- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index eab233a..82b408d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -31,7 +31,7 @@ %global ldap 1 %global openssh_ver 8.3p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -214,7 +214,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 >= 20180306-1 +Requires: crypto-policies >= 20200610-1 %package server Summary: SSH server daemon with GSI authentication @@ -223,7 +223,7 @@ Obsoletes: gsissh-server < 5.8p2-2 Requires: %{name} = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 -Requires: crypto-policies >= 20180306-1 +Requires: crypto-policies >= 20200610-1 %{?systemd_requires} %description @@ -416,8 +416,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/etc/gsissh/ssh_config.d/05-redhat.conf -install -m644 sshd_config_redhat $RPM_BUILD_ROOT/etc/gsissh/sshd_config.d/05-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 @@ -490,7 +490,7 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man1/gsiscp.1* %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config %dir %attr(0755,root,root) %{_sysconfdir}/gsissh/ssh_config.d/ -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config.d/05-redhat.conf +%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(0644,root,root) %{_mandir}/man1/gsisftp.1* @@ -506,7 +506,7 @@ getent passwd sshd >/dev/null || \ %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/05-redhat.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 %attr(0644,root,root) %{_unitdir}/gsisshd.service @@ -517,6 +517,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Thu Jun 11 2020 Mattias Ellert - 8.3p1-3 +- Based on openssh-8.3p1-3.fc32 + * Thu Jun 04 2020 Mattias Ellert - 8.3p1-2 - Based on openssh-8.3p1-2.fc32 diff --git a/gsisshd.service b/gsisshd.service index 56e6094..7dd7ae6 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -6,10 +6,9 @@ Wants=gsisshd-keygen.target [Service] Type=notify -EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd -D $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN +ExecStart=/usr/sbin/gsisshd -D $OPTIONS $PERMITROOTLOGIN ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/gsisshd@.service b/gsisshd@.service index 284a914..6fcedbd 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -5,8 +5,7 @@ Wants=gsisshd-keygen.target After=gsisshd-keygen.target [Service] -EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN +ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $PERMITROOTLOGIN StandardInput=socket diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 6c8d539..fe4200d 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -68,10 +68,14 @@ diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 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,10 @@ +@@ -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 @@ -79,23 +83,16 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -114,3 +118,7 @@ Subsystem sftp /usr/libexec/sftp-server - # AllowTcpForwarding no - # PermitTTY no - # ForceCommand cvs server -+ -+# 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 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 @@ +@@ -0,0 +1,29 @@ +# This system is following system-wide crypto policy. The changes to -+# crypto properties (Ciphers, MACs, ...) will not have any effect here. -+# They will be overridden by command-line options passed to the server -+# on command line. -+# Please, check manual pages for update-crypto-policies(8) and sshd_config(5). ++# 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 + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 7c00b13..50fd29a 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -2722,6 +2722,9 @@ index a302c79c..879fe917 100644 + } + + provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } + nkeys = 0; + for (i = 0; i < p->module->nslots; i++) { + token = &p->module->slotinfo[i].token; @@ -2757,9 +2760,6 @@ index a302c79c..879fe917 100644 + provider_uri, (unsigned long)i, token->label, token->manufacturerID, token->model, token->serialNumber, token->flags); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; -+ } /* - * open session, login with pin and retrieve public - * keys (if keyp is provided) @@ -2805,8 +2805,8 @@ index a302c79c..879fe917 100644 + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + uri->object = label; } -+ pin = NULL; /* Will be cleaned up with URI */ } ++ pin = NULL; /* Will be cleaned up with URI */ /* now owned by caller */ *providerp = p; From acf84ac51a7f9365f05602d099255d07213fbc04 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 28 Jul 2020 00:25:23 +0000 Subject: [PATCH 087/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 82b408d..957f5ec 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -36,7 +36,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -517,6 +517,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Jul 28 2020 Fedora Release Engineering - 8.3p1-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Thu Jun 11 2020 Mattias Ellert - 8.3p1-3 - Based on openssh-8.3p1-3.fc32 From 79afa4b64ae892b25839447b85a73a28d6273e70 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 6 Oct 2020 12:30:41 +0200 Subject: [PATCH 088/146] Based on openssh-8.4p1-2.fc33 --- gsi-openssh.spec | 45 +- gsisshd.service | 3 +- gsisshd.sysconfig | 4 - gsisshd@.service | 3 +- openssh-5.1p1-askpass-progress.patch | 39 +- openssh-6.6.1p1-log-in-chroot.patch | 6 +- openssh-6.6p1-ctr-cavstest.patch | 12 +- openssh-6.6p1-keycat.patch | 26 +- openssh-6.6p1-kuserok.patch | 2 +- openssh-6.7p1-kdf-cavs.patch | 8 +- openssh-6.7p1-ldap.patch | 2748 ----------------- openssh-6.7p1-sftp-force-permission.patch | 16 +- openssh-7.1p2-audit-race-condition.patch | 2 +- openssh-7.6p1-audit.patch | 4 +- openssh-7.7p1-fips.patch | 40 +- openssh-7.7p1-redhat.patch | 2 +- openssh-7.8p1-role-mls.patch | 18 +- openssh-7.9p1-ssh-copy-id.patch | 58 +- openssh-8.0p1-crypto-policies.patch | 72 +- openssh-8.0p1-pkcs11-uri.patch | 34 +- openssh-8.3p1-sshd_include.patch | 227 -- ...gsissh.patch => openssh-8.4p1-gsissh.patch | 334 +- openssh-8.4p1-ssh-copy-id.patch | 130 + sources | 4 +- 24 files changed, 484 insertions(+), 3353 deletions(-) delete mode 100644 openssh-6.7p1-ldap.patch delete mode 100644 openssh-8.3p1-sshd_include.patch rename openssh-8.3p1-gsissh.patch => openssh-8.4p1-gsissh.patch (89%) create mode 100644 openssh-8.4p1-ssh-copy-id.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 957f5ec..ed191ac 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,16 +27,13 @@ # Do we want libedit support %global libedit 1 -# Do we want LDAP support -%global ldap 1 - -%global openssh_ver 8.3p1 -%global openssh_rel 3 +%global openssh_ver 8.4p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -68,9 +65,6 @@ Patch201: openssh-7.1p2-audit-race-condition.patch Patch400: openssh-7.8p1-role-mls.patch #https://bugzilla.redhat.com/show_bug.cgi?id=781634 Patch404: openssh-6.6p1-privsep-selinux.patch - -#?-- unwanted child :( -Patch501: openssh-6.7p1-ldap.patch #? Patch502: openssh-6.6p1-keycat.patch @@ -147,8 +141,7 @@ 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 -# - do not return 0 if the write fails (full disk) -# - shellcheck reports (upstream #2902) +# 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 @@ -160,26 +153,22 @@ Patch964: openssh-8.0p1-openssl-kdf.patch Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 Patch966: openssh-8.2p1-x11-without-ipv6.patch -# Unbreak sshd_config include corner cases (#3122) -Patch967: openssh-8.3p1-sshd_include.patch +Patch967: openssh-8.4p1-ssh-copy-id.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-8.3p1-gsissh.patch +Patch98: openssh-8.4p1-gsissh.patch License: BSD Requires: /sbin/nologin -%if %{ldap} -BuildRequires: openldap-devel -%endif BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel -BuildRequires: gcc +BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel Recommends: p11-kit @@ -264,9 +253,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch400 -p1 -b .role-mls %patch404 -p1 -b .privsep-selinux -%if %{ldap} -%patch501 -p1 -b .ldap -%endif %patch502 -p1 -b .keycat %patch601 -p1 -b .ip-opts @@ -309,7 +295,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch964 -p1 -b .openssl-kdf %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 -%patch967 -p1 -b .include +%patch967 -p1 -b .ssh-copy-id %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -374,9 +360,6 @@ fi --with-systemd \ --with-default-pkcs11-provider=yes \ --with-security-key-builtin=yes \ -%if %{ldap} - --with-ldap \ -%endif --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ @@ -398,7 +381,7 @@ fi --without-libedit %endif -make SSH_PROGRAM=%{_bindir}/gsissh \ +%make_build SSH_PROGRAM=%{_bindir}/gsissh \ ASKPASS_PROGRAM=%{_libexecdir}/openssh/ssh-askpass %install @@ -408,8 +391,7 @@ 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 DESTDIR=$RPM_BUILD_ROOT -rm -f $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ldap.conf +%make_install install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/sysconfig/ @@ -433,16 +415,12 @@ 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-ldap-helper -rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-ldap-wrapper 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}/man5/ssh-ldap.conf.5* -rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-ldap-helper.8* rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-pkcs11-helper.8* rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-sk-helper.8* @@ -517,6 +495,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Oct 06 2020 Mattias Ellert - 8.4p1-1 +- Based on openssh-8.4p1-2.fc33 + * Tue Jul 28 2020 Fedora Release Engineering - 8.3p1-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild diff --git a/gsisshd.service b/gsisshd.service index 7dd7ae6..afe165d 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -6,9 +6,8 @@ Wants=gsisshd-keygen.target [Service] Type=notify -EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=/usr/sbin/gsisshd -D $OPTIONS $PERMITROOTLOGIN +ExecStart=/usr/sbin/gsisshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 2981eee..904d8c1 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -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. - -# System-wide crypto policy: -# To opt-out, uncomment the following line -# CRYPTO_POLICY= diff --git a/gsisshd@.service b/gsisshd@.service index 6fcedbd..3f5ecbd 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -5,7 +5,6 @@ Wants=gsisshd-keygen.target After=gsisshd-keygen.target [Service] -EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/gsisshd -ExecStart=-/usr/sbin/gsisshd -i $OPTIONS $PERMITROOTLOGIN +ExecStart=-/usr/sbin/gsisshd -i $OPTIONS StandardInput=socket diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index 21f6502..e0ecb80 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -2,15 +2,15 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr --- 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 #include + #include +#include #include #include - + #include @@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia - gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + return 1; } +static void @@ -34,39 +34,44 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr - GtkWidget *parent_window, *dialog, *entry; + GtkWidget *parent_window, *dialog, *entry, *progress, *hbox; GdkGrabStatus status; + GdkColor fg, bg; + int fg_set = 0, bg_set = 0; +@@ -104,14 +116,19 @@ passphrase_dialog(char *message) + gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg); - grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); -@@ -104,16 +116,37 @@ passphrase_dialog(char *message) - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - - if (prompt_type == PROMPT_ENTRY) { + if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, + 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( - GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), - entry, FALSE, FALSE, 0); -+ GTK_BOX(hbox), entry, -+ TRUE, FALSE, 0); ++ GTK_BOX(hbox), entry, TRUE, FALSE, 0); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); - gtk_widget_show(entry); - /* Make close dialog */ - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); + if (prompt_type == PROMPT_ENTRY) { +@@ -130,6 +145,22 @@ passphrase_dialog(char *message) + g_signal_connect(G_OBJECT(entry), "key_press_event", + G_CALLBACK(check_none), dialog); + } + + hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, -+ FALSE, 8); ++ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), ++ hbox, FALSE, FALSE, 8); + gtk_widget_show(hbox); + + progress = gtk_progress_bar_new(); + -+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); ++ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), ++ "Passphrase length hidden intentionally"); + gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, + TRUE, 5); + gtk_widget_show(progress); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 1260242..fa0717f 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -145,9 +145,9 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c session_type, tty == NULL ? "" : " on ", @@ -1486,14 +1492,6 @@ child_close_fds(void) - * descriptors left by system functions. They will be closed later. - */ - endpwent(); + + /* 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 diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index 1e12dcc..81da034 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -2,8 +2,8 @@ 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 - SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + 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 @@ -13,8 +13,8 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/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) ssh-ldap-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-ldap-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) ++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 \ @@ -29,8 +29,8 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -326,6 +330,7 @@ install-files: - $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ - fi + $(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) diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index b5e055a..9e71efe 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -36,16 +36,16 @@ 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_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper +SSH_KEYCAT=$(libexecdir)/ssh-keycat SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ + K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ - SSHLIBS=@SSHLIBS@ SSHDLIBS=@SSHDLIBS@ +KEYCATLIBS=@KEYCATLIBS@ LIBEDIT=@LIBEDIT@ @@ -55,14 +55,14 @@ 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) ssh-ldap-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-ldap-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) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) XMSS_OBJS=\ ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) - ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS) + ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) + $(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) @@ -71,9 +71,9 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -321,6 +325,7 @@ install-files: - $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ - $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ - fi + $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) @@ -466,16 +466,16 @@ index 3bbccfd..6481f1f 100644 esac fi @@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux], + fi ] ) - AC_SUBST([SSHLIBS]) AC_SUBST([SSHDLIBS]) +AC_SUBST([KEYCATLIBS]) # Check whether user wants Kerberos 5 support KRB5_MSG="no" @@ -5031,6 +5034,9 @@ fi - if test ! -z "${SSHLIBS}"; then - echo " +for ssh: ${SSHLIBS}" + if test ! -z "${SSHDLIBS}"; then + echo " +for sshd: ${SSHDLIBS}" fi +if test ! -z "${KEYCATLIBS}"; then +echo " +for ssh-keycat: ${KEYCATLIBS}" diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 8428c1c..5009e2a 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -217,7 +217,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions - *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; + *inc_flags &= ~SSHCFG_MATCH_ONLY; break; + case sKerberosUseKuserok: diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch index 40966d3..f892bc8 100644 --- a/openssh-6.7p1-kdf-cavs.patch +++ b/openssh-6.7p1-kdf-cavs.patch @@ -2,7 +2,7 @@ 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_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_KEYCAT=$(libexecdir)/ssh-keycat CTR_CAVSTEST=$(libexecdir)/ctr-cavstest +SSH_CAVS=$(libexecdir)/ssh-cavs @@ -13,8 +13,8 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/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) ssh-ldap-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-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(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) ++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 \ @@ -29,7 +29,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -331,6 +335,8 @@ install-files: - fi + $(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) diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch deleted file mode 100644 index bf0dfe6..0000000 --- a/openssh-6.7p1-ldap.patch +++ /dev/null @@ -1,2748 +0,0 @@ -diff -up openssh-6.8p1/HOWTO.ldap-keys.ldap openssh-6.8p1/HOWTO.ldap-keys ---- openssh-6.8p1/HOWTO.ldap-keys.ldap 2015-03-18 11:11:29.029801467 +0100 -+++ openssh-6.8p1/HOWTO.ldap-keys 2015-03-18 11:11:29.029801467 +0100 -@@ -0,0 +1,122 @@ -+ -+HOW TO START -+ -+1) configure LDAP server -+ * Use LDAP server documentation -+2) add appropriate LDAP schema -+ * For OpenLDAP or SunONE Use attached schema, otherwise you have to create it. -+ * LDAP user entry -+ User entry: -+ - attached to the 'ldapPublicKey' objectclass -+ - attached to the 'posixAccount' objectclass -+ - with a filled 'sshPublicKey' attribute -+3) insert users into LDAP -+ * Use LDAP Tree management tool as useful -+ * Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema and the additionnal lpk.schema. -+ * Example: -+ dn: uid=captain,ou=commanders,dc=enterprise,dc=universe -+ objectclass: top -+ objectclass: person -+ objectclass: organizationalPerson -+ objectclass: posixAccount -+ objectclass: ldapPublicKey -+ description: Jonathan Archer -+ userPassword: Porthos -+ cn: onathan Archer -+ sn: onathan Archer -+ uid: captain -+ uidNumber: 1001 -+ gidNumber: 1001 -+ homeDirectory: /home/captain -+ sshPublicKey: ssh-rss AAAAB3.... =captain@universe -+ sshPublicKey: command="kill -9 1" ssh-rss AAAAM5... -+4) on the ssh side set in sshd_config -+ * Set up the backend -+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper -+ AuthorizedKeysCommandUser -+ * Do not forget to set -+ PubkeyAuthentication yes -+ * Swith off unnecessary auth methods -+5) confugure ldap.conf -+ * Default ldap.conf is placed in /etc/ssh -+ * The configuration style is the same as other ldap based aplications -+6) if necessary edit ssh-ldap-wrapper -+ * There is a possibility to change ldap.conf location -+ * There are some debug options -+ * Example -+ /usr/libexec/openssh -s -f /etc/ldap.conf -w -d >> /tmp/ldapdebuglog.txt -+7) Configure SELinux boolean which allows ldap-helper to bind ldap server -+ Run this command -+ # setsebool -P authlogin_nsswitch_use_ldap on -+ -+HOW TO MIGRATE FROM LPK -+ -+1) goto HOW TO START 4) .... the ldap schema is the same -+ -+2) convert the group requests to the appropriate LDAP requests -+ -+HOW TO SOLVE PROBLEMS -+ -+1) use debug in sshd -+ * /usr/sbin/sshd -d -d -d -d -+2) use debug in ssh-ldap-helper -+ * ssh-ldap-helper -d -d -d -d -s -+3) use tcpdump ... other ldap client etc. -+ -+HOW TO CONFIGURE SSH FOR OTHER LDAP CONFIGURATION / SERVER /SCHEMA -+ -+You can adjust search format string in /etc/ldap.conf using -+ 1) SSH_Filter option to limit results for only specified users -+ (this appends search condition after original query) -+ 2) Search_Format option to define your own search string using expansion -+ characters %u for username, %c for objectclass and %f for above mentioned filter. -+ -+Example: -+Search_Format (&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%u)%f) -+ -+ADVANTAGES -+ -+1) Blocking an user account can be done directly from LDAP (if sshd is using PubkeyAuthentication + AuthorizedKeysCommand with ldap only). -+ -+DISADVANTAGES -+ -+1) LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP -+ allows write to users dn, somebody could replace some user's public key by his own and impersonate some -+ of your users in all your server farm -- be VERY CAREFUL. -+2) With incomplete PKI the MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login -+ as the impersonated user. -+3) If LDAP server is down there may be no fallback on passwd auth. -+ -+MISC. -+ -+1) todo -+ * Possibility to reuse the ssh-ldap-helper. -+ * Tune the LDAP part to accept all possible LDAP configurations. -+ -+2) differences from original lpk -+ * No LDAP code in sshd. -+ * Support for various LDAP platforms and configurations. -+ * LDAP is configured in separate ldap.conf file. -+ -+3) docs/link -+ * http://pacsec.jp/core05/psj05-barisani-en.pdf -+ * http://fritz.potsdam.edu/projects/openssh-lpk/ -+ * http://fritz.potsdam.edu/projects/sshgate/ -+ * http://dev.inversepath.com/trac/openssh-lpk -+ * http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm ) -+ -+4) contributors/ideas/greets -+ - Eric AUGE -+ - Andrea Barisani -+ - Falk Siemonsmeier. -+ - Jacob Rief. -+ - Michael Durchgraf. -+ - frederic peters. -+ - Finlay dobbie. -+ - Stefan Fisher. -+ - Robin H. Johnson. -+ - Adrian Bridgett. -+ -+5) Author -+ Jan F. Chadima -+ -diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.ldap 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 11:13:10.147561177 +0100 -@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh - ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass - SFTP_SERVER=$(libexecdir)/sftp-server - SSH_KEYSIGN=$(libexecdir)/ssh-keysign -+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper -+SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ -@@ -50,6 +50,7 @@ - CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ - PICFLAG=@PICFLAG@ - LIBS=@LIBS@ -+LDAPLIBS=@LDAPLIBS@ - K5LIBS=@K5LIBS@ - GSSLIBS=@GSSLIBS@ - SSHLIBS=@SSHLIBS@ -@@ -61,10 +63,11 @@ XAUTH_PATH=@XAUTH_PATH@ - EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ - MKDIR_P=@MKDIR_P@ -+INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ - - .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-ldap-helper$(EXEEXT) - - XMSS_OBJS=\ - ssh-xmss.o \ -@@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - - SFTP_OBJS= sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o - --MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out --MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 -+MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap-helper.8.out ssh-ldap.conf.5.out -+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 ssh-ldap-helper.8 ssh-ldap.conf.5 - MANTYPE = @MANTYPE@ - - CONFIGFILES=sshd_config.out ssh_config.out moduli.out -@@ -184,6 +187,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss - ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) - $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) - -+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -311,6 +317,10 @@ 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) -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ -+ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ -+ fi - $(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 -@@ -327,6 +337,10 @@ install-files: - $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - $(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ -+ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ -+ fi - - install-sysconf: - $(MKDIR_P) $(DESTDIR)$(sysconfdir) -@@ -356,6 +370,13 @@ install-sysconf: - else \ - echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ - fi -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ -+ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ -+ else \ -+ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ -+ fi ; \ -+ fi - - host-key: ssh-keygen$(EXEEXT) - @if [ -z "$(DESTDIR)" ] ; then \ -@@ -419,6 +440,8 @@ uninstall: - -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 -@@ -430,6 +453,7 @@ uninstall: - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 -+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 - - regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/test_helper -diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac ---- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 -@@ -1605,6 +1605,110 @@ if test "x$use_pie" != "xno"; then - CFLAGS="$SAVED_CFLAGS" - AC_SUBST([PICFLAG]) - -+# Check whether user wants LDAP support -+LDAP_MSG="no" -+INSTALL_SSH_LDAP_HELPER="" -+AC_ARG_WITH(ldap, -+ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)], -+ [ -+ if test "x$withval" != "xno" ; then -+ -+ INSTALL_SSH_LDAP_HELPER="yes" -+ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" -+ -+ if test "x$withval" != "xyes" ; then -+ CPPFLAGS="$CPPFLAGS -I${withval}/include" -+ LDFLAGS="$LDFLAGS -L${withval}/lib" -+ fi -+ -+ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) -+ LDAP_MSG="yes" -+ -+ AC_CHECK_HEADERS(lber.h) -+ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate )) -+ AC_CHECK_HEADERS(ldap_ssl.h) -+ -+ AC_ARG_WITH(ldap-lib, -+ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) -+ -+ if test -z "$with_ldap_lib"; then -+ with_ldap_lib=auto -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then -+ AC_CHECK_LIB(lber, main, LDAPLIBS="-llber $LDAPLIBS" found_ldap_lib=yes) -+ AC_CHECK_LIB(ldap, main, LDAPLIBS="-lldap $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then -+ AC_CHECK_LIB(ldap50, main, LDAPLIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then -+ AC_CHECK_LIB(ldapssl41, main, LDAPLIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LDAPLIBS" found_ldap_lib=yes) -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldapssl40, main, LDAPLIBS="-lldapssl40 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap41, main, LDAPLIBS="-lldap41 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap40, main, LDAPLIBS="-lldap40 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then -+ AC_CHECK_LIB(ldapssl30, main, LDAPLIBS="-lldapssl30 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib"; then -+ AC_MSG_ERROR(could not locate a valid LDAP library) -+ fi -+ -+ saved_LIBS="$LIBS" -+ LIBS="$LIBS $LDAPLIBS" -+ AC_MSG_CHECKING([for working LDAP support]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [(void)ldap_init(0, 0);], -+ [AC_MSG_RESULT(yes)], -+ [ -+ AC_MSG_RESULT(no) -+ AC_MSG_ERROR([** Incomplete or missing ldap libraries **]) -+ ]) -+ AC_CHECK_FUNCS( \ -+ ldap_init \ -+ ldap_get_lderrno \ -+ ldap_set_lderrno \ -+ ldap_parse_result \ -+ ldap_memfree \ -+ ldap_controls_free \ -+ ldap_set_option \ -+ ldap_get_option \ -+ ldapssl_init \ -+ ldap_start_tls_s \ -+ ldap_pvt_tls_set_option \ -+ ldap_initialize \ -+ ) -+ AC_CHECK_FUNCS(ldap_set_rebind_proc, -+ AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [ldap_set_rebind_proc(0, 0, 0);], -+ [ac_cv_ldap_set_rebind_proc=3], -+ [ac_cv_ldap_set_rebind_proc=2]) -+ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) -+ AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) -+ ) -+ LIBS="$saved_LIBS" -+ fi -+ ] -+) -+AC_SUBST(INSTALL_SSH_LDAP_HELPER) -+AC_SUBST(LDAPLIBS) -+ - dnl Checks for library functions. Please keep in alphabetical order - AC_CHECK_FUNCS([ \ - Blowfish_initstate \ -@@ -5227,6 +5352,9 @@ - echo "Preprocessor flags: ${CPPFLAGS}" - echo " Linker flags: ${LDFLAGS}" - echo " Libraries: ${LIBS}" -+if test ! -z "${LDAPLIBS}"; then -+echo " +for ldap: ${LDAPLIBS}" -+fi - if test ! -z "${SSHDLIBS}"; then - echo " +for sshd: ${SSHDLIBS}" - fi -diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c ---- openssh-6.8p1/ldap-helper.c.ldap 2015-03-18 11:11:29.030801464 +0100 -+++ openssh-6.8p1/ldap-helper.c 2015-03-18 11:11:29.030801464 +0100 -@@ -0,0 +1,151 @@ -+/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapbody.h" -+#include -+#include -+#include -+ -+static int config_debug = 0; -+int config_exclusive_config_file = 0; -+static char *config_file_name = "/etc/ssh/ldap.conf"; -+static char *config_single_user = NULL; -+static int config_verbose = SYSLOG_LEVEL_VERBOSE; -+int config_warning_config_file = 0; -+extern char *__progname; -+ -+static void -+usage(void) -+{ -+ fprintf(stderr, "usage: %s [options]\n", -+ __progname); -+ fprintf(stderr, "Options:\n"); -+ fprintf(stderr, " -d Output the log messages to stderr.\n"); -+ fprintf(stderr, " -e Check the config file for unknown commands.\n"); -+ fprintf(stderr, " -f file Use alternate config file (default is /etc/ssh/ldap.conf).\n"); -+ fprintf(stderr, " -s user Do not demonize, send the user's key to stdout.\n"); -+ fprintf(stderr, " -v Increase verbosity of the debug output (implies -d).\n"); -+ fprintf(stderr, " -w Warn on unknown commands in the config file.\n"); -+ exit(1); -+} -+ -+/* -+ * Main program for the ssh pka ldap agent. -+ */ -+ -+int -+main(int ac, char **av) -+{ -+ int opt; -+ FILE *outfile = NULL; -+ -+ __progname = ssh_get_progname(av[0]); -+ -+ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); -+ -+ /* -+ * Initialize option structure to indicate that no values have been -+ * set. -+ */ -+ initialize_options(); -+ -+ /* Parse command-line arguments. */ -+ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { -+ switch (opt) { -+ case 'd': -+ config_debug = 1; -+ break; -+ -+ case 'e': -+ config_exclusive_config_file = 1; -+ config_warning_config_file = 1; -+ break; -+ -+ case 'f': -+ config_file_name = optarg; -+ break; -+ -+ case 's': -+ config_single_user = optarg; -+ outfile = fdopen (dup (fileno (stdout)), "w"); -+ break; -+ -+ case 'v': -+ config_debug = 1; -+ if (config_verbose < SYSLOG_LEVEL_DEBUG3) -+ config_verbose++; -+ break; -+ -+ case 'w': -+ config_warning_config_file = 1; -+ break; -+ -+ case '?': -+ default: -+ usage(); -+ break; -+ } -+ } -+ -+ /* Initialize loging */ -+ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); -+ -+ if (ac != optind) -+ fatal ("illegal extra parameter %s", av[1]); -+ -+ /* Ensure that fds 0 and 2 are open or directed to /dev/null */ -+ if (config_debug == 0) -+ sanitise_stdfd(); -+ -+ /* Read config file */ -+ read_config_file(config_file_name); -+ fill_default_options(); -+ if (config_verbose == SYSLOG_LEVEL_DEBUG3) { -+ debug3 ("=== Configuration ==="); -+ dump_config(); -+ debug3 ("=== *** ==="); -+ } -+ -+ ldap_checkconfig(); -+ ldap_do_connect(); -+ -+ if (config_single_user) { -+ process_user (config_single_user, outfile); -+ } else { -+ usage(); -+ fatal ("Not yet implemented"); -+/* TODO -+ * open unix socket a run the loop on it -+ */ -+ } -+ -+ ldap_do_close(); -+ return 0; -+} -diff -up openssh-6.8p1/ldap-helper.h.ldap openssh-6.8p1/ldap-helper.h ---- openssh-6.8p1/ldap-helper.h.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldap-helper.h 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,32 @@ -+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAP_HELPER_H -+#define LDAP_HELPER_H -+ -+extern int config_exclusive_config_file; -+extern int config_warning_config_file; -+ -+#endif /* LDAP_HELPER_H */ -diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf ---- openssh-6.8p1/ldap.conf.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldap.conf 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,95 @@ -+# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ -+# -+# This is the example configuration file for the OpenSSH -+# LDAP backend -+# -+# see ssh-ldap.conf(5) -+# -+ -+# URI with your LDAP server name. This allows to use -+# Unix Domain Sockets to connect to a local LDAP Server. -+#uri ldap://127.0.0.1/ -+#uri ldaps://127.0.0.1/ -+#uri ldapi://%2fvar%2frun%2fldapi_sock/ -+# Note: %2f encodes the '/' used as directory separator -+ -+# Another way to specify your LDAP server is to provide an -+# host name and the port of our LDAP server. Host name -+# must be resolvable without using LDAP. -+# Multiple hosts may be specified, each separated by a -+# space. How long nss_ldap takes to failover depends on -+# whether your LDAP client library supports configurable -+# network or connect timeouts (see bind_timelimit). -+#host 127.0.0.1 -+ -+# The port. -+# Optional: default is 389. -+#port 389 -+ -+# The distinguished name to bind to the server with. -+# Optional: default is to bind anonymously. -+#binddn cn=openssh_keys,dc=example,dc=org -+ -+# The credentials to bind with. -+# Optional: default is no credential. -+#bindpw TopSecret -+ -+# The distinguished name of the search base. -+#base dc=example,dc=org -+ -+# The LDAP version to use (defaults to 3 -+# if supported by client library) -+#ldap_version 3 -+ -+# The search scope. -+#scope sub -+#scope one -+#scope base -+ -+# Search timelimit -+#timelimit 30 -+ -+# Bind/connect timelimit -+#bind_timelimit 30 -+ -+# Reconnect policy: hard (default) will retry connecting to -+# the software with exponential backoff, soft will fail -+# immediately. -+#bind_policy hard -+ -+# SSL setup, may be implied by URI also. -+#ssl no -+#ssl on -+#ssl start_tls -+ -+# OpenLDAP SSL options -+# Require and verify server certificate (yes/no) -+# Default is to use libldap's default behavior, which can be configured in -+# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for -+# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". -+#tls_checkpeer hard -+ -+# CA certificates for server certificate verification -+# At least one of these are required if tls_checkpeer is "yes" -+#tls_cacertfile /etc/ssl/ca.cert -+#tls_cacertdir /etc/pki/tls/certs -+ -+# Seed the PRNG if /dev/urandom is not provided -+#tls_randfile /var/run/egd-pool -+ -+# SSL cipher suite -+# See man ciphers for syntax -+#tls_ciphers TLSv1 -+ -+# Client certificate and key -+# Use these, if your server requires client authentication. -+#tls_cert -+#tls_key -+ -+# OpenLDAP search_format -+# format used to search for users in LDAP directory using substitution -+# for %u for user name and %f for SSH_Filter option (optional, empty by default) -+#search_format (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) -+ -+#AccountClass posixAccount -+ -diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c ---- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,499 @@ -+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "log.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapmisc.h" -+#include "ldapbody.h" -+#include -+#include -+#include -+#include "misc.h" -+ -+#define LDAPSEARCH_FORMAT "(&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f)" -+#define PUBKEYATTR "sshPublicKey" -+#define LDAP_LOGFILE "%s/ldap.%d" -+ -+static FILE *logfile = NULL; -+static LDAP *ld; -+ -+static char *attrs[] = { -+ PUBKEYATTR, -+ NULL -+}; -+ -+void -+ldap_checkconfig (void) -+{ -+#ifdef HAVE_LDAP_INITIALIZE -+ if (options.host == NULL && options.uri == NULL) -+#else -+ if (options.host == NULL) -+#endif -+ fatal ("missing \"host\" in config file"); -+} -+ -+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -+static int -+#if LDAP_API_VERSION > 3000 -+_rebind_proc (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params) -+#else -+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) -+#endif -+{ -+ struct timeval timeout; -+ int rc; -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ LDAPMessage *result; -+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */ -+ -+ debug2 ("Doing LDAP rebind to %s", options.binddn); -+ if (options.ssl == SSL_START_TLS) { -+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) { -+ error ("ldap_starttls_s: %s", ldap_err2string (rc)); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ } -+ -+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE) -+ return ldap_simple_bind_s (ld, options.binddn, options.bindpw); -+#else -+ if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0) -+ fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0))); -+ -+ timeout.tv_sec = options.bind_timelimit; -+ timeout.tv_usec = 0; -+ result = NULL; -+ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { -+ error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0))); -+ ldap_msgfree (result); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ debug3 ("LDAP rebind to %s succesfull", options.binddn); -+ return rc; -+#endif -+} -+#else -+ -+static int -+_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit) -+{ -+ if (freeit) -+ return LDAP_SUCCESS; -+ -+ *whop = strdup (options.binddn); -+ *credp = strdup (options.bindpw); -+ *methodp = LDAP_AUTH_SIMPLE; -+ debug2 ("Doing LDAP rebind for %s", *whop); -+ return LDAP_SUCCESS; -+} -+#endif -+ -+void -+ldap_do_connect(void) -+{ -+ int rc, msgid, ld_errno = 0; -+ struct timeval timeout; -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ int parserc; -+ LDAPMessage *result; -+ LDAPControl **controls; -+ int reconnect = 0; -+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */ -+ -+ debug ("LDAP do connect"); -+ -+retry: -+ if (reconnect) { -+ debug3 ("Reconnecting with ld_errno %d", ld_errno); -+ if (options.bind_policy == 0 || -+ (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) || -+ reconnect > 5) -+ fatal ("Cannot connect to LDAP server"); -+ -+ if (reconnect > 1) -+ sleep (reconnect - 1); -+ -+ if (ld != NULL) { -+ ldap_unbind (ld); -+ ld = NULL; -+ } -+ logit("reconnecting to LDAP server..."); -+ } -+ -+ if (ld == NULL) { -+ int rc; -+ struct timeval tv; -+ -+#ifdef HAVE_LDAP_SET_OPTION -+ if (options.debug > 0) { -+#ifdef LBER_OPT_LOG_PRINT_FILE -+ if (options.logdir) { -+ char *logfilename; -+ int logfilenamelen; -+ -+ logfilenamelen = strlen(LDAP_LOGFILE) -+ + strlen("000000") + strlen (options.logdir); -+ logfilename = xmalloc (logfilenamelen); -+ snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ()); -+ logfilename[logfilenamelen - 1] = 0; -+ if ((logfile = fopen (logfilename, "a")) == NULL) -+ fatal ("cannot append to %s: %s", logfilename, strerror (errno)); -+ debug3 ("LDAP debug into %s", logfilename); -+ free (logfilename); -+ ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, logfile); -+ } -+#endif -+ if (options.debug) { -+#ifdef LBER_OPT_DEBUG_LEVEL -+ ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &options.debug); -+#endif /* LBER_OPT_DEBUG_LEVEL */ -+#ifdef LDAP_OPT_DEBUG_LEVEL -+ (void) ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &options.debug); -+#endif /* LDAP_OPT_DEBUG_LEVEL */ -+ debug3 ("Set LDAP debug to %d", options.debug); -+ } -+ } -+#endif /* HAVE_LDAP_SET_OPTION */ -+ -+ ld = NULL; -+#ifdef HAVE_LDAPSSL_INIT -+ if (options.host != NULL) { -+ if (options.ssl_on == SSL_LDAPS) { -+ if ((rc = ldapssl_client_init (options.sslpath, NULL)) != LDAP_SUCCESS) -+ fatal ("ldapssl_client_init %s", ldap_err2string (rc)); -+ debug3 ("LDAPssl client init"); -+ } -+ -+ if (options.ssl_on != SSL_OFF) { -+ if ((ld = ldapssl_init (options.host, options.port, 1)) == NULL) -+ fatal ("ldapssl_init failed"); -+ debug3 ("LDAPssl init"); -+ } -+ } -+#endif /* HAVE_LDAPSSL_INIT */ -+ -+ /* continue with opening */ -+ if (ld == NULL) { -+#if defined (HAVE_LDAP_START_TLS_S) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) -+ /* Some global TLS-specific options need to be set before we create our -+ * session context, so we set them here. */ -+ -+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE -+ /* rand file */ -+ if (options.tls_randfile != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, -+ options.tls_randfile)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS random file %s", options.tls_randfile); -+ } -+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */ -+ -+ /* ca cert file */ -+ if (options.tls_cacertfile != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, -+ options.tls_cacertfile)) != LDAP_SUCCESS) -+ error ("ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS CA cert file %s ", options.tls_cacertfile); -+ } -+ -+ /* ca cert directory */ -+ if (options.tls_cacertdir != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, -+ options.tls_cacertdir)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS CA cert dir %s ", options.tls_cacertdir); -+ } -+ -+ /* require cert? */ -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, -+ &options.tls_checkpeer)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS check peer to %d ", options.tls_checkpeer); -+ -+ /* set cipher suite, certificate and private key: */ -+ if (options.tls_ciphers != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, -+ options.tls_ciphers)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS ciphers to %s ", options.tls_ciphers); -+ } -+ -+ /* cert file */ -+ if (options.tls_cert != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, -+ options.tls_cert)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CERTFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS cert file %s ", options.tls_cert); -+ } -+ -+ /* key file */ -+ if (options.tls_key != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, -+ options.tls_key)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_KEYFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS key file %s ", options.tls_key); -+ } -+#endif -+#ifdef HAVE_LDAP_INITIALIZE -+ if (options.uri != NULL) { -+ if ((rc = ldap_initialize (&ld, options.uri)) != LDAP_SUCCESS) -+ fatal ("ldap_initialize %s", ldap_err2string (rc)); -+ debug3 ("LDAP initialize %s", options.uri); -+ } -+ } -+#endif /* HAVE_LDAP_INTITIALIZE */ -+ -+ /* continue with opening */ -+ if ((ld == NULL) && (options.host != NULL)) { -+#ifdef HAVE_LDAP_INIT -+ if ((ld = ldap_init (options.host, options.port)) == NULL) -+ fatal ("ldap_init failed"); -+ debug3 ("LDAP init %s:%d", options.host, options.port); -+#else -+ if ((ld = ldap_open (options.host, options.port)) == NULL) -+ fatal ("ldap_open failed"); -+ debug3 ("LDAP open %s:%d", options.host, options.port); -+#endif /* HAVE_LDAP_INIT */ -+ } -+ -+ if (ld == NULL) -+ fatal ("no way to open ldap"); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) -+ if (options.ssl == SSL_LDAPS) { -+ if ((rc = ldap_set_option (ld, LDAP_OPT_X_TLS, &options.tls_checkpeer)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS) %s", ldap_err2string (rc)); -+ debug3 ("LDAP set LDAP_OPT_X_TLS_%d", options.tls_checkpeer); -+ } -+#endif /* LDAP_OPT_X_TLS */ -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION) -+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, -+ &options.ldap_version); -+#else -+ ld->ld_version = options.ldap_version; -+#endif -+ debug3 ("LDAP set version to %d", options.ldap_version); -+ -+#if LDAP_SET_REBIND_PROC_ARGS == 3 -+ ldap_set_rebind_proc (ld, _rebind_proc, NULL); -+#elif LDAP_SET_REBIND_PROC_ARGS == 2 -+ ldap_set_rebind_proc (ld, _rebind_proc); -+#else -+#warning unknown LDAP_SET_REBIND_PROC_ARGS -+#endif -+ debug3 ("LDAP set rebind proc"); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF) -+ (void) ldap_set_option (ld, LDAP_OPT_DEREF, &options.deref); -+#else -+ ld->ld_deref = options.deref; -+#endif -+ debug3 ("LDAP set deref to %d", options.deref); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT) -+ (void) ldap_set_option (ld, LDAP_OPT_TIMELIMIT, -+ &options.timelimit); -+#else -+ ld->ld_timelimit = options.timelimit; -+#endif -+ debug3 ("LDAP set timelimit to %d", options.timelimit); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT) -+ /* -+ * This is a new option in the Netscape SDK which sets -+ * the TCP connect timeout. For want of a better value, -+ * we use the bind_timelimit to control this. -+ */ -+ timeout = options.bind_timelimit * 1000; -+ (void) ldap_set_option (ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout); -+ debug3 ("LDAP set opt connect timeout to %d", timeout); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT) -+ tv.tv_sec = options.bind_timelimit; -+ tv.tv_usec = 0; -+ (void) ldap_set_option (ld, LDAP_OPT_NETWORK_TIMEOUT, &tv); -+ debug3 ("LDAP set opt network timeout to %ld.0", tv.tv_sec); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS) -+ (void) ldap_set_option (ld, LDAP_OPT_REFERRALS, -+ options.referrals ? LDAP_OPT_ON : LDAP_OPT_OFF); -+ debug3 ("LDAP set referrals to %d", options.referrals); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART) -+ (void) ldap_set_option (ld, LDAP_OPT_RESTART, -+ options.restart ? LDAP_OPT_ON : LDAP_OPT_OFF); -+ debug3 ("LDAP set restart to %d", options.restart); -+#endif -+ -+#ifdef HAVE_LDAP_START_TLS_S -+ if (options.ssl == SSL_START_TLS) { -+ int version; -+ -+ if (ldap_get_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) -+ == LDAP_SUCCESS) { -+ if (version < LDAP_VERSION3) { -+ version = LDAP_VERSION3; -+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, -+ &version); -+ debug3 ("LDAP set version to %d", version); -+ } -+ } -+ -+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) -+ fatal ("ldap_starttls_s: %s", ldap_err2string (rc)); -+ debug3 ("LDAP start TLS"); -+ } -+#endif /* HAVE_LDAP_START_TLS_S */ -+ } -+ -+ if ((msgid = ldap_simple_bind (ld, options.binddn, -+ options.bindpw)) == -1) { -+ ld_errno = ldap_get_lderrno (ld, 0, 0); -+ -+ error ("ldap_simple_bind %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP simple bind (%s)", options.binddn); -+ -+ timeout.tv_sec = options.bind_timelimit; -+ timeout.tv_usec = 0; -+ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { -+ ld_errno = ldap_get_lderrno (ld, 0, 0); -+ -+ error ("ldap_result %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP result in time"); -+ -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ controls = NULL; -+ if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, 1)) != LDAP_SUCCESS) -+ fatal ("ldap_parse_result %s", ldap_err2string (parserc)); -+ debug3 ("LDAP parse result OK"); -+ -+ if (controls != NULL) { -+ ldap_controls_free (controls); -+ } -+#else -+ rc = ldap_result2error (session->ld, result, 1); -+#endif -+ if (rc != LDAP_SUCCESS) -+ fatal ("error trying to bind as user \"%s\" (%s)", -+ options.binddn, ldap_err2string (rc)); -+ -+ debug2 ("LDAP do connect OK"); -+} -+ -+void -+process_user (const char *user, FILE *output) -+{ -+ LDAPMessage *res, *e; -+ char *buffer, *format; -+ int rc, i; -+ struct timeval timeout; -+ -+ debug ("LDAP process user"); -+ -+ /* quick check for attempts to be evil */ -+ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || -+ (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) { -+ logit ("illegal user name %s not processed", user); -+ return; -+ } -+ -+ /* build filter for LDAP request */ -+ format = LDAPSEARCH_FORMAT; -+ if (options.search_format != NULL) -+ format = options.search_format; -+ buffer = percent_expand(format, "c", options.account_class, "u", user, "f", options.ssh_filter, (char *)NULL); -+ -+ debug3 ("LDAP search scope = %d %s", options.scope, buffer); -+ -+ timeout.tv_sec = options.timelimit; -+ timeout.tv_usec = 0; -+ if ((rc = ldap_search_st(ld, options.base, options.scope, buffer, attrs, 0, &timeout, &res)) != LDAP_SUCCESS) { -+ error ("ldap_search_st(): %s", ldap_err2string (rc)); -+ free (buffer); -+ return; -+ } -+ -+ /* free */ -+ free (buffer); -+ -+ for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) { -+ int num; -+ struct berval **keys; -+ -+ keys = ldap_get_values_len(ld, e, PUBKEYATTR); -+ num = ldap_count_values_len(keys); -+ for (i = 0 ; i < num ; i++) { -+ char *cp; //, *options = NULL; -+ -+ for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++); -+ if (!*cp || *cp == '\n' || *cp == '#') -+ continue; -+ -+ /* We have found the desired key. */ -+ fprintf (output, "%s\n", keys[i]->bv_val); -+ } -+ -+ ldap_value_free_len(keys); -+ } -+ -+ ldap_msgfree(res); -+ debug2 ("LDAP process user finished"); -+} -+ -+void -+ldap_do_close(void) -+{ -+ int rc; -+ -+ debug ("LDAP do close"); -+ if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS) -+ fatal ("ldap_unbind_ext: %s", -+ ldap_err2string (rc)); -+ -+ ld = NULL; -+ debug2 ("LDAP do close OK"); -+ return; -+} -+ -diff -up openssh-6.8p1/ldapbody.h.ldap openssh-6.8p1/ldapbody.h ---- openssh-6.8p1/ldapbody.h.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldapbody.h 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,37 @@ -+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPBODY_H -+#define LDAPBODY_H -+ -+#include -+ -+void ldap_checkconfig(void); -+void ldap_do_connect(void); -+void process_user(const char *, FILE *); -+void ldap_do_close(void); -+ -+#endif /* LDAPBODY_H */ -+ -diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c ---- openssh-6.8p1/ldapconf.c.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapconf.c 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,729 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "ldap-helper.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include -+#include -+#include -+ -+/* Keyword tokens. */ -+ -+typedef enum { -+ lBadOption, -+ lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN, -+ lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit, -+ lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals, -+ lRestart, lTLS_CheckPeer, lTLS_CaCertFile, -+ lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, -+ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, lSearch_Format, -+ lAccountClass, lDeprecated, lUnsupported -+} OpCodes; -+ -+/* Textual representations of the tokens. */ -+ -+static struct { -+ const char *name; -+ OpCodes opcode; -+} keywords[] = { -+ { "URI", lURI }, -+ { "Base", lBase }, -+ { "BindDN", lBindDN }, -+ { "BindPW", lBindPW }, -+ { "RootBindDN", lRootBindDN }, -+ { "Host", lHost }, -+ { "Port", lPort }, -+ { "Scope", lScope }, -+ { "Deref", lDeref }, -+ { "TimeLimit", lTimeLimit }, -+ { "TimeOut", lTimeLimit }, -+ { "Bind_Timelimit", lBind_TimeLimit }, -+ { "Network_TimeOut", lBind_TimeLimit }, -+/* -+ * Todo -+ * SIZELIMIT -+ */ -+ { "Ldap_Version", lLdap_Version }, -+ { "Version", lLdap_Version }, -+ { "Bind_Policy", lBind_Policy }, -+ { "SSLPath", lSSLPath }, -+ { "SSL", lSSL }, -+ { "Referrals", lReferrals }, -+ { "Restart", lRestart }, -+ { "TLS_CheckPeer", lTLS_CheckPeer }, -+ { "TLS_ReqCert", lTLS_CheckPeer }, -+ { "TLS_CaCertFile", lTLS_CaCertFile }, -+ { "TLS_CaCert", lTLS_CaCertFile }, -+ { "TLS_CaCertDir", lTLS_CaCertDir }, -+ { "TLS_Ciphers", lTLS_Ciphers }, -+ { "TLS_Cipher_Suite", lTLS_Ciphers }, -+ { "TLS_Cert", lTLS_Cert }, -+ { "TLS_Certificate", lTLS_Cert }, -+ { "TLS_Key", lTLS_Key }, -+ { "TLS_RandFile", lTLS_RandFile }, -+/* -+ * Todo -+ * TLS_CRLCHECK -+ * TLS_CRLFILE -+ */ -+ { "LogDir", lLogDir }, -+ { "Debug", lDebug }, -+ { "SSH_Filter", lSSH_Filter }, -+ { "search_format", lSearch_Format }, -+ { "AccountClass", lAccountClass }, -+ { NULL, lBadOption } -+}; -+ -+/* Configuration ptions. */ -+ -+Options options; -+ -+/* -+ * Returns the number of the token pointed to by cp or oBadOption. -+ */ -+ -+static OpCodes -+parse_token(const char *cp, const char *filename, int linenum) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name; i++) -+ if (strcasecmp(cp, keywords[i].name) == 0) -+ return keywords[i].opcode; -+ -+ if (config_warning_config_file) -+ logit("%s: line %d: Bad configuration option: %s", -+ filename, linenum, cp); -+ return lBadOption; -+} -+ -+/* Characters considered whitespace in strsep calls. */ -+#define WHITESPACE " \t\r\n" -+ -+/* return next token in configuration line */ -+static char * -+ldap_strdelim(char **s) -+{ -+ char *old; -+ int wspace = 0; -+ -+ if (*s == NULL) -+ return NULL; -+ -+ old = *s; -+ -+ *s = strpbrk(*s, WHITESPACE); -+ if (*s == NULL) -+ return (old); -+ -+ *s[0] = '\0'; -+ -+ /* Skip any extra whitespace after first token */ -+ *s += strspn(*s + 1, WHITESPACE) + 1; -+ if (*s[0] == '=' && !wspace) -+ *s += strspn(*s + 1, WHITESPACE) + 1; -+ -+ return (old); -+} -+ -+/* -+ * Processes a single option line as used in the configuration files. This -+ * only sets those values that have not already been set. -+ */ -+#define WHITESPACE " \t\r\n" -+ -+static int -+process_config_line(char *line, const char *filename, int linenum) -+{ -+ char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg; -+ char *rootbinddn = NULL; -+ int opcode, *intptr, value; -+ size_t len; -+ -+ /* Strip trailing whitespace */ -+ for (len = strlen(line) - 1; len > 0; len--) { -+ if (strchr(WHITESPACE, line[len]) == NULL) -+ break; -+ line[len] = '\0'; -+ } -+ -+ s = line; -+ /* Get the keyword. (Each line is supposed to begin with a keyword). */ -+ if ((keyword = ldap_strdelim(&s)) == NULL) -+ return 0; -+ /* Ignore leading whitespace. */ -+ if (*keyword == '\0') -+ keyword = ldap_strdelim(&s); -+ if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') -+ return 0; -+ -+ opcode = parse_token(keyword, filename, linenum); -+ -+ switch (opcode) { -+ case lBadOption: -+ /* don't panic, but count bad options */ -+ return -1; -+ /* NOTREACHED */ -+ -+ case lHost: -+ xstringptr = &options.host; -+parse_xstring: -+ if (!s || *s == '\0') -+ fatal("%s line %d: missing dn",filename,linenum); -+ if (*xstringptr == NULL) -+ *xstringptr = xstrdup(s); -+ return 0; -+ -+ case lURI: -+ xstringptr = &options.uri; -+ goto parse_xstring; -+ -+ case lBase: -+ xstringptr = &options.base; -+ goto parse_xstring; -+ -+ case lBindDN: -+ xstringptr = &options.binddn; -+ goto parse_xstring; -+ -+ case lBindPW: -+ charptr = &options.bindpw; -+parse_string: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", filename, linenum); -+ if (*charptr == NULL) -+ *charptr = xstrdup(arg); -+ break; -+ -+ case lRootBindDN: -+ xstringptr = &rootbinddn; -+ goto parse_xstring; -+ -+ case lScope: -+ intptr = &options.scope; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp (arg, "sub") == 0 || strcasecmp (arg, "subtree") == 0) -+ value = LDAP_SCOPE_SUBTREE; -+ else if (strcasecmp (arg, "one") == 0) -+ value = LDAP_SCOPE_ONELEVEL; -+ else if (strcasecmp (arg, "base") == 0) -+ value = LDAP_SCOPE_BASE; -+ else -+ fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lDeref: -+ intptr = &options.scope; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (!strcasecmp (arg, "never")) -+ value = LDAP_DEREF_NEVER; -+ else if (!strcasecmp (arg, "searching")) -+ value = LDAP_DEREF_SEARCHING; -+ else if (!strcasecmp (arg, "finding")) -+ value = LDAP_DEREF_FINDING; -+ else if (!strcasecmp (arg, "always")) -+ value = LDAP_DEREF_ALWAYS; -+ else -+ fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lPort: -+ intptr = &options.port; -+parse_int: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", filename, linenum); -+ if (arg[0] < '0' || arg[0] > '9') -+ fatal("%.200s line %d: Bad number.", filename, linenum); -+ -+ /* Octal, decimal, or hex format? */ -+ value = strtol(arg, &endofnumber, 0); -+ if (arg == endofnumber) -+ fatal("%.200s line %d: Bad number.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lTimeLimit: -+ intptr = &options.timelimit; -+parse_time: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: missing time value.", -+ filename, linenum); -+ if ((value = convtime(arg)) == -1) -+ fatal("%s line %d: invalid time value.", -+ filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lBind_TimeLimit: -+ intptr = &options.bind_timelimit; -+ goto parse_time; -+ -+ case lLdap_Version: -+ intptr = &options.ldap_version; -+ goto parse_int; -+ -+ case lBind_Policy: -+ intptr = &options.bind_policy; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 0) -+ value = 1; -+ else if (strcasecmp(arg, "soft") == 0) -+ value = 0; -+ else -+ fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lSSLPath: -+ charptr = &options.sslpath; -+ goto parse_string; -+ -+ case lSSL: -+ intptr = &options.ssl; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = SSL_LDAPS; -+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = SSL_OFF; -+ else if (!strcasecmp (arg, "start_tls")) -+ value = SSL_START_TLS; -+ else -+ fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lReferrals: -+ intptr = &options.referrals; -+parse_flag: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = 1; -+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = 0; -+ else -+ fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lRestart: -+ intptr = &options.restart; -+ goto parse_flag; -+ -+ case lTLS_CheckPeer: -+ intptr = &options.tls_checkpeer; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "never") == 0 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = LDAP_OPT_X_TLS_NEVER; -+ else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = LDAP_OPT_X_TLS_HARD; -+ else if (strcasecmp(arg, "demand") == 0) -+ value = LDAP_OPT_X_TLS_DEMAND; -+ else if (strcasecmp(arg, "allow") == 0) -+ value = LDAP_OPT_X_TLS_ALLOW; -+ else if (strcasecmp(arg, "try") == 0) -+ value = LDAP_OPT_X_TLS_TRY; -+ else -+ fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lTLS_CaCertFile: -+ charptr = &options.tls_cacertfile; -+ goto parse_string; -+ -+ case lTLS_CaCertDir: -+ charptr = &options.tls_cacertdir; -+ goto parse_string; -+ -+ case lTLS_Ciphers: -+ xstringptr = &options.tls_ciphers; -+ goto parse_xstring; -+ -+ case lTLS_Cert: -+ charptr = &options.tls_cert; -+ goto parse_string; -+ -+ case lTLS_Key: -+ charptr = &options.tls_key; -+ goto parse_string; -+ -+ case lTLS_RandFile: -+ charptr = &options.tls_randfile; -+ goto parse_string; -+ -+ case lLogDir: -+ charptr = &options.logdir; -+ goto parse_string; -+ -+ case lDebug: -+ intptr = &options.debug; -+ goto parse_int; -+ -+ case lSSH_Filter: -+ xstringptr = &options.ssh_filter; -+ goto parse_xstring; -+ -+ case lSearch_Format: -+ charptr = &options.search_format; -+ goto parse_string; -+ -+ case lAccountClass: -+ charptr = &options.account_class; -+ goto parse_string; -+ -+ case lDeprecated: -+ debug("%s line %d: Deprecated option \"%s\"", -+ filename, linenum, keyword); -+ return 0; -+ -+ case lUnsupported: -+ error("%s line %d: Unsupported option \"%s\"", -+ filename, linenum, keyword); -+ return 0; -+ -+ default: -+ fatal("process_config_line: Unimplemented opcode %d", opcode); -+ } -+ -+ /* Check that there is no garbage at end of line. */ -+ if ((arg = ldap_strdelim(&s)) != NULL && *arg != '\0') { -+ fatal("%.200s line %d: garbage at end of line; \"%.200s\".", -+ filename, linenum, arg); -+ } -+ return 0; -+} -+ -+/* -+ * Reads the config file and modifies the options accordingly. Options -+ * should already be initialized before this call. This never returns if -+ * there is an error. If the file does not exist, this returns 0. -+ */ -+ -+void -+read_config_file(const char *filename) -+{ -+ FILE *f; -+ char line[1024]; -+ int linenum; -+ int bad_options = 0; -+ struct stat sb; -+ -+ if ((f = fopen(filename, "r")) == NULL) -+ fatal("fopen %s: %s", filename, strerror(errno)); -+ -+ if (fstat(fileno(f), &sb) == -1) -+ fatal("fstat %s: %s", filename, strerror(errno)); -+ if (((sb.st_uid != 0 && sb.st_uid != getuid()) || -+ (sb.st_mode & 022) != 0)) -+ fatal("Bad owner or permissions on %s", filename); -+ -+ debug("Reading configuration data %.200s", filename); -+ -+ /* -+ * Mark that we are now processing the options. This flag is turned -+ * on/off by Host specifications. -+ */ -+ linenum = 0; -+ while (fgets(line, sizeof(line), f)) { -+ /* Update line number counter. */ -+ linenum++; -+ if (process_config_line(line, filename, linenum) != 0) -+ bad_options++; -+ } -+ fclose(f); -+ if ((bad_options > 0) && config_exclusive_config_file) -+ fatal("%s: terminating, %d bad configuration options", -+ filename, bad_options); -+} -+ -+/* -+ * Initializes options to special values that indicate that they have not yet -+ * been set. Read_config_file will only set options with this value. Options -+ * are processed in the following order: command line, user config file, -+ * system config file. Last, fill_default_options is called. -+ */ -+ -+void -+initialize_options(void) -+{ -+ memset(&options, 'X', sizeof(options)); -+ options.host = NULL; -+ options.uri = NULL; -+ options.base = NULL; -+ options.binddn = NULL; -+ options.bindpw = NULL; -+ options.scope = -1; -+ options.deref = -1; -+ options.port = -1; -+ options.timelimit = -1; -+ options.bind_timelimit = -1; -+ options.ldap_version = -1; -+ options.bind_policy = -1; -+ options.sslpath = NULL; -+ options.ssl = -1; -+ options.referrals = -1; -+ options.restart = -1; -+ options.tls_checkpeer = -1; -+ options.tls_cacertfile = NULL; -+ options.tls_cacertdir = NULL; -+ options.tls_ciphers = NULL; -+ options.tls_cert = NULL; -+ options.tls_key = NULL; -+ options.tls_randfile = NULL; -+ options.logdir = NULL; -+ options.debug = -1; -+ options.ssh_filter = NULL; -+ options.search_format = NULL; -+ options.account_class = NULL; -+} -+ -+/* -+ * Called after processing other sources of option data, this fills those -+ * options for which no value has been specified with their default values. -+ */ -+ -+void -+fill_default_options(void) -+{ -+ if (options.uri != NULL) { -+ LDAPURLDesc *ludp; -+ -+ if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) { -+ if (options.ssl == -1) { -+ if (strcmp (ludp->lud_scheme, "ldap") == 0) -+ options.ssl = 2; -+ if (strcmp (ludp->lud_scheme, "ldapi") == 0) -+ options.ssl = 0; -+ else if (strcmp (ludp->lud_scheme, "ldaps") == 0) -+ options.ssl = 1; -+ } -+ if (options.host == NULL) -+ options.host = xstrdup (ludp->lud_host); -+ if (options.port == -1) -+ options.port = ludp->lud_port; -+ -+ ldap_free_urldesc (ludp); -+ } -+ } -+ if (options.ssl == -1) -+ options.ssl = SSL_START_TLS; -+ if (options.port == -1) -+ options.port = (options.ssl == 0) ? 389 : 636; -+ if (options.uri == NULL) { -+ int len; -+#define MAXURILEN 4096 -+ -+ options.uri = xmalloc (MAXURILEN); -+ len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d", -+ (options.ssl == 0) ? "" : "s", options.host, options.port); -+ options.uri[MAXURILEN - 1] = 0; -+ options.uri = xreallocarray(options.uri, len + 1, 1); -+ } -+ if (options.binddn == NULL) -+ options.binddn = ""; -+ if (options.bindpw == NULL) -+ options.bindpw = ""; -+ if (options.scope == -1) -+ options.scope = LDAP_SCOPE_SUBTREE; -+ if (options.deref == -1) -+ options.deref = LDAP_DEREF_NEVER; -+ if (options.timelimit == -1) -+ options.timelimit = 10; -+ if (options.bind_timelimit == -1) -+ options.bind_timelimit = 10; -+ if (options.ldap_version == -1) -+ options.ldap_version = 3; -+ if (options.bind_policy == -1) -+ options.bind_policy = 1; -+ if (options.referrals == -1) -+ options.referrals = 1; -+ if (options.restart == -1) -+ options.restart = 1; -+ if (options.tls_checkpeer == -1) -+ options.tls_checkpeer = LDAP_OPT_X_TLS_HARD; -+ if (options.debug == -1) -+ options.debug = 0; -+ if (options.ssh_filter == NULL) -+ options.ssh_filter = ""; -+ if (options.account_class == NULL) -+ options.account_class = "posixAccount"; -+} -+ -+static const char * -+lookup_opcode_name(OpCodes code) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name != NULL; i++) -+ if (keywords[i].opcode == code) -+ return(keywords[i].name); -+ return "UNKNOWN"; -+} -+ -+static void -+dump_cfg_string(OpCodes code, const char *val) -+{ -+ if (val == NULL) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %s", lookup_opcode_name(code), val); -+} -+ -+static void -+dump_cfg_int(OpCodes code, int val) -+{ -+ if (val == -1) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %d", lookup_opcode_name(code), val); -+} -+ -+struct names { -+ int value; -+ char *name; -+}; -+ -+static void -+dump_cfg_namedint(OpCodes code, int val, struct names *names) -+{ -+ u_int i; -+ -+ if (val == -1) -+ debug3("%s ", lookup_opcode_name(code)); -+ else { -+ for (i = 0; names[i].value != -1; i++) -+ if (names[i].value == val) { -+ debug3("%s %s", lookup_opcode_name(code), names[i].name); -+ return; -+ } -+ debug3("%s unknown: %d", lookup_opcode_name(code), val); -+ } -+} -+ -+static struct names _yesnotls[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { 2, "Start_TLS" }, -+ { -1, NULL }}; -+ -+static struct names _scope[] = { -+ { LDAP_SCOPE_BASE, "Base" }, -+ { LDAP_SCOPE_ONELEVEL, "One" }, -+ { LDAP_SCOPE_SUBTREE, "Sub"}, -+ { -1, NULL }}; -+ -+static struct names _deref[] = { -+ { LDAP_DEREF_NEVER, "Never" }, -+ { LDAP_DEREF_SEARCHING, "Searching" }, -+ { LDAP_DEREF_FINDING, "Finding" }, -+ { LDAP_DEREF_ALWAYS, "Always" }, -+ { -1, NULL }}; -+ -+static struct names _yesno[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { -1, NULL }}; -+ -+static struct names _bindpolicy[] = { -+ { 0, "Soft" }, -+ { 1, "Hard" }, -+ { -1, NULL }}; -+ -+static struct names _checkpeer[] = { -+ { LDAP_OPT_X_TLS_NEVER, "Never" }, -+ { LDAP_OPT_X_TLS_HARD, "Hard" }, -+ { LDAP_OPT_X_TLS_DEMAND, "Demand" }, -+ { LDAP_OPT_X_TLS_ALLOW, "Allow" }, -+ { LDAP_OPT_X_TLS_TRY, "TRY" }, -+ { -1, NULL }}; -+ -+void -+dump_config(void) -+{ -+ dump_cfg_string(lURI, options.uri); -+ dump_cfg_string(lHost, options.host); -+ dump_cfg_int(lPort, options.port); -+ dump_cfg_namedint(lSSL, options.ssl, _yesnotls); -+ dump_cfg_int(lLdap_Version, options.ldap_version); -+ dump_cfg_int(lTimeLimit, options.timelimit); -+ dump_cfg_int(lBind_TimeLimit, options.bind_timelimit); -+ dump_cfg_string(lBase, options.base); -+ dump_cfg_string(lBindDN, options.binddn); -+ dump_cfg_string(lBindPW, options.bindpw); -+ dump_cfg_namedint(lScope, options.scope, _scope); -+ dump_cfg_namedint(lDeref, options.deref, _deref); -+ dump_cfg_namedint(lReferrals, options.referrals, _yesno); -+ dump_cfg_namedint(lRestart, options.restart, _yesno); -+ dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy); -+ dump_cfg_string(lSSLPath, options.sslpath); -+ dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer); -+ dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile); -+ dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir); -+ dump_cfg_string(lTLS_Ciphers, options.tls_ciphers); -+ dump_cfg_string(lTLS_Cert, options.tls_cert); -+ dump_cfg_string(lTLS_Key, options.tls_key); -+ dump_cfg_string(lTLS_RandFile, options.tls_randfile); -+ dump_cfg_string(lLogDir, options.logdir); -+ dump_cfg_int(lDebug, options.debug); -+ dump_cfg_string(lSSH_Filter, options.ssh_filter); -+ dump_cfg_string(lSearch_Format, options.search_format); -+ dump_cfg_string(lAccountClass, options.account_class); -+} -+ -diff -up openssh-6.8p1/ldapconf.h.ldap openssh-6.8p1/ldapconf.h ---- openssh-6.8p1/ldapconf.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapconf.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,73 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPCONF_H -+#define LDAPCONF_H -+ -+#define SSL_OFF 0 -+#define SSL_LDAPS 1 -+#define SSL_START_TLS 2 -+ -+/* Data structure for representing option data. */ -+ -+typedef struct { -+ char *host; -+ char *uri; -+ char *base; -+ char *binddn; -+ char *bindpw; -+ int scope; -+ int deref; -+ int port; -+ int timelimit; -+ int bind_timelimit; -+ int ldap_version; -+ int bind_policy; -+ char *sslpath; -+ int ssl; -+ int referrals; -+ int restart; -+ int tls_checkpeer; -+ char *tls_cacertfile; -+ char *tls_cacertdir; -+ char *tls_ciphers; -+ char *tls_cert; -+ char *tls_key; -+ char *tls_randfile; -+ char *logdir; -+ int debug; -+ char *ssh_filter; -+ char *search_format; -+ char *account_class; -+} Options; -+ -+extern Options options; -+ -+void read_config_file(const char *); -+void initialize_options(void); -+void fill_default_options(void); -+void dump_config(void); -+ -+#endif /* LDAPCONF_H */ -diff -up openssh-6.8p1/ldapincludes.h.ldap openssh-6.8p1/ldapincludes.h ---- openssh-6.8p1/ldapincludes.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapincludes.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,41 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPINCLUDES_H -+#define LDAPINCLUDES_H -+ -+#include "includes.h" -+ -+#ifdef HAVE_LBER_H -+#include -+#endif -+#ifdef HAVE_LDAP_H -+#include -+#endif -+#ifdef HAVE_LDAP_SSL_H -+#include -+#endif -+ -+#endif /* LDAPINCLUDES_H */ -diff -up openssh-6.8p1/ldapmisc.c.ldap openssh-6.8p1/ldapmisc.c ---- openssh-6.8p1/ldapmisc.c.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapmisc.c 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,79 @@ -+ -+#include "ldapincludes.h" -+#include "ldapmisc.h" -+ -+#ifndef HAVE_LDAP_GET_LDERRNO -+int -+ldap_get_lderrno (LDAP * ld, char **m, char **s) -+{ -+#ifdef HAVE_LDAP_GET_OPTION -+ int rc; -+#endif -+ int lderrno; -+ -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS) -+ return rc; -+#else -+ lderrno = ld->ld_errno; -+#endif -+ -+ if (s != NULL) { -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_STRING) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS) -+ return rc; -+#else -+ *s = ld->ld_error; -+#endif -+ } -+ -+ if (m != NULL) { -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_MATCHED_DN) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS) -+ return rc; -+#else -+ *m = ld->ld_matched; -+#endif -+ } -+ -+ return lderrno; -+} -+#endif -+ -+#ifndef HAVE_LDAP_SET_LDERRNO -+int -+ldap_set_lderrno (LDAP * ld, int lderrno, const char *m, const char *s) -+{ -+#ifdef HAVE_LDAP_SET_OPTION -+ int rc; -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_errno = lderrno; -+#endif -+ -+ if (s != NULL) { -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_STRING) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_error = s; -+#endif -+ } -+ -+ if (m != NULL) { -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_MATCHED_DN) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_matched = m; -+#endif -+ } -+ -+ return LDAP_SUCCESS; -+} -+#endif -+ -diff -up openssh-6.8p1/ldapmisc.h.ldap openssh-6.8p1/ldapmisc.h ---- openssh-6.8p1/ldapmisc.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapmisc.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,35 @@ -+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * 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, this list of conditions and the following disclaimer. -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPMISC_H -+#define LDAPMISC_H -+ -+#include "ldapincludes.h" -+ -+int ldap_get_lderrno (LDAP *, char **, char **); -+int ldap_set_lderrno (LDAP *, int, const char *, const char *); -+ -+#endif /* LDAPMISC_H */ -+ -diff -up openssh-6.8p1/openssh-lpk-openldap.schema.ldap openssh-6.8p1/openssh-lpk-openldap.schema ---- openssh-6.8p1/openssh-lpk-openldap.schema.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/openssh-lpk-openldap.schema 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,21 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# Based on the proposal of : Mark Ruijter -+# -+ -+ -+# octetString SYNTAX -+attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' -+ DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch -+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+ -+# printableString SYNTAX yes|no -+objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY -+ DESC 'MANDATORY: OpenSSH LPK objectclass' -+ MUST ( sshPublicKey $ uid ) -+ ) -diff -up openssh-6.8p1/openssh-lpk-sun.schema.ldap openssh-6.8p1/openssh-lpk-sun.schema ---- openssh-6.8p1/openssh-lpk-sun.schema.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/openssh-lpk-sun.schema 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,23 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# Schema for Sun Directory Server. -+# Based on the original schema, modified by Stefan Fischer. -+# -+ -+dn: cn=schema -+ -+# octetString SYNTAX -+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' -+ DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch -+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+ -+# printableString SYNTAX yes|no -+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY -+ DESC 'MANDATORY: OpenSSH LPK objectclass' -+ MUST ( sshPublicKey $ uid ) -+ ) -diff -up openssh-6.8p1/ssh-ldap-helper.8.ldap openssh-6.8p1/ssh-ldap-helper.8 ---- openssh-6.8p1/ssh-ldap-helper.8.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap-helper.8 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,79 @@ -+.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $ -+.\" -+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. -+.\" -+.\" Permission to use, copy, modify, and distribute this software for any -+.\" purpose with or without fee is hereby granted, provided that the above -+.\" copyright notice and this permission notice appear in all copies. -+.\" -+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+.\" -+.Dd $Mdocdate: April 29 2010 $ -+.Dt SSH-LDAP-HELPER 8 -+.Os -+.Sh NAME -+.Nm ssh-ldap-helper -+.Nd sshd helper program for ldap support -+.Sh SYNOPSIS -+.Nm ssh-ldap-helper -+.Op Fl devw -+.Op Fl f Ar file -+.Op Fl s Ar user -+.Sh DESCRIPTION -+.Nm -+is used by -+.Xr sshd 1 -+to access keys provided by an LDAP. -+.Nm -+is disabled by default and can only be enabled in the -+sshd configuration file -+.Pa /etc/ssh/sshd_config -+by setting -+.Cm AuthorizedKeysCommand -+to -+.Dq /usr/libexec/ssh-ldap-wrapper . -+.Pp -+.Nm -+is not intended to be invoked by the user, but from -+.Xr sshd 8 via -+.Xr ssh-ldap-wrapper . -+.Pp -+The options are as follows: -+.Bl -tag -width Ds -+.It Fl d -+Set the debug mode; -+.Nm -+prints all logs to stderr instead of syslog. -+.It Fl e -+Implies \-w; -+.Nm -+halts if it encounters an unknown item in the ldap.conf file. -+.It Fl f -+.Nm -+uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). -+.It Fl s -+.Nm -+prints out the user's keys to stdout and exits. -+.It Fl v -+Implies \-d; -+increases verbosity. -+.It Fl w -+.Nm -+writes warnings about unknown items in the ldap.conf configuration file. -+.El -+.Sh SEE ALSO -+.Xr sshd 8 , -+.Xr sshd_config 5 , -+.Xr ssh-ldap.conf 5 , -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.8p1/ssh-ldap-wrapper.ldap openssh-6.8p1/ssh-ldap-wrapper ---- openssh-6.8p1/ssh-ldap-wrapper.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap-wrapper 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" -+ -diff -up openssh-6.8p1/ssh-ldap.conf.5.ldap openssh-6.8p1/ssh-ldap.conf.5 ---- openssh-6.8p1/ssh-ldap.conf.5.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap.conf.5 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,385 @@ -+.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ -+.\" -+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. -+.\" -+.\" Permission to use, copy, modify, and distribute this software for any -+.\" purpose with or without fee is hereby granted, provided that the above -+.\" copyright notice and this permission notice appear in all copies. -+.\" -+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+.\" -+.Dd $Mdocdate: may 12 2010 $ -+.Dt SSH-LDAP.CONF 5 -+.Os -+.Sh NAME -+.Nm ssh-ldap.conf -+.Nd configuration file for ssh-ldap-helper -+.Sh SYNOPSIS -+.Nm /etc/ssh/ldap.conf -+.Sh DESCRIPTION -+.Xr ssh-ldap-helper 8 -+reads configuration data from -+.Pa /etc/ssh/ldap.conf -+(or the file specified with -+.Fl f -+on the command line). -+The file contains keyword-argument pairs, one per line. -+Lines starting with -+.Ql # -+and empty lines are interpreted as comments. -+.Pp -+The value starts with the first non-blank character after -+the keyword's name, and terminates at the end of the line, -+or at the last sequence of blanks before the end of the line. -+Quoting values that contain blanks -+may be incorrect, as the quotes would become part of the value. -+The possible keywords and their meanings are as follows (note that -+keywords are case-insensitive, and arguments, on a case by case basis, may be case-sensitive). -+.Bl -tag -width Ds -+.It Cm URI -+The argument(s) are in the form -+.Pa ldap[si]://[name[:port]] -+and specify the URI(s) of an LDAP server(s) to which the -+.Xr ssh-ldap-helper 8 -+should connect. The URI scheme may be any of -+.Dq ldap , -+.Dq ldaps -+or -+.Dq ldapi , -+which refer to LDAP over TCP, LDAP over SSL (TLS) and LDAP -+over IPC (UNIX domain sockets), respectively. -+Each server's name can be specified as a -+domain-style name or an IP address literal. Optionally, the -+server's name can followed by a ':' and the port number the LDAP -+server is listening on. If no port number is provided, the default -+port for the scheme is used (389 for ldap://, 636 for ldaps://). -+For LDAP over IPC, name is the name of the socket, and no port -+is required, nor allowed; note that directory separators must be -+URL-encoded, like any other characters that are special to URLs; -+A space separated list of URIs may be provided. -+There is no default. -+.It Cm Base -+Specifies the default base Distinguished Name (DN) to use when performing ldap operations. -+The base must be specified as a DN in LDAP format. -+There is no default. -+.It Cm BindDN -+Specifies the default BIND DN to use when connecting to the ldap server. -+The bind DN must be specified as a Distinguished Name in LDAP format. -+There is no default. -+.It Cm BindPW -+Specifies the default password to use when connecting to the ldap server via -+.Cm BindDN . -+There is no default. -+.It Cm RootBindDN -+Intentionaly does nothing. Recognized for compatibility reasons. -+.It Cm Host -+The argument(s) specifies the name(s) of an LDAP server(s) to which the -+.Xr ssh-ldap-helper 8 -+should connect. Each server's name can be specified as a -+domain-style name or an IP address and optionally followed by a ':' and -+the port number the ldap server is listening on. A space-separated -+list of hosts may be provided. -+There is no default. -+.Cm Host -+is deprecated in favor of -+.Cm URI . -+.It Cm Port -+Specifies the default port used when connecting to LDAP servers(s). -+The port may be specified as a number. -+The default port is 389 for ldap:// or 636 for ldaps:// respectively. -+.Cm Port -+is deprecated in favor of -+.Cm URI . -+.It Cm Scope -+Specifies the starting point of an LDAP search and the depth from the base DN to which the search should descend. -+There are three options (values) that can be assigned to the -+.Cm Scope parameter: -+.Dq base , -+.Dq one -+and -+.Dq subtree . -+Alias for the subtree is -+.Dq sub . -+The value -+.Dq base -+is used to indicate searching only the entry at the base DN, resulting in only that entry being returned (keeping in mind that it also has to meet the search filter criteria!). -+The value -+.Dq one -+is used to indicate searching all entries one level under the base DN, but not including the base DN and not including any entries under that one level under the base DN. -+The value -+.Dq subtree -+is used to indicate searching of all entries at all levels under and including the specified base DN. -+The default is -+.Dq subtree . -+.It Cm Deref -+Specifies how alias dereferencing is done when performing a search. There are four -+possible values that can be assigned to the -+.Cm Deref -+parameter: -+.Dq never , -+.Dq searching , -+.Dq finding , -+and -+.Dq always . -+The value -+.Dq never -+means that the aliases are never dereferenced. -+The value -+.Dq searching -+means that the aliases are dereferenced in subordinates of the base object, but -+not in locating the base object of the search. -+The value -+.Dq finding -+means that the aliases are only dereferenced when locating the base object of the search. -+The value -+.Dq always -+means that the aliases are dereferenced both in searching and in locating the base object -+of the search. -+The default is -+.Dq never . -+.It Cm TimeLimit -+Specifies a time limit (in seconds) to use when performing searches. -+The number should be a non-negative integer. A -+.Cm TimeLimit -+of zero (0) specifies that the search time is unlimited. Please note that the server -+may still apply any server-side limit on the duration of a search operation. -+The default value is 10. -+.It Cm TimeOut -+Is an aliast to -+.Cm TimeLimit . -+.It Cm Bind_TimeLimit -+Specifies the timeout (in seconds) after which the poll(2)/select(2) -+following a connect(2) returns in case of no activity. -+The default value is 10. -+.It Cm Network_TimeOut -+Is an alias to -+.Cm Bind_TimeLimit . -+.It Cm Ldap_Version -+Specifies what version of the LDAP protocol should be used. -+The allowed values are 2 or 3. The default is 3. -+.It Cm Version -+Is an alias to -+.Cm Ldap_Version . -+.It Cm Bind_Policy -+Specifies the policy to use for reconnecting to an unavailable LDAP server. There are 2 available values: -+.Dq hard -+and -+.Dq soft. -+.Dq hard has 2 aliases -+.Dq hard_open -+and -+.Dq hard_init . -+The value -+.Dq hard -+means that reconects that the -+.Xr ssh-ldap-helper 8 -+tries to reconnect to the LDAP server 5 times before failure. There is exponential backoff before retrying. -+The value -+.Dq soft -+means that -+.Xr ssh-ldap-helper 8 -+fails immediately when it cannot connect to the LDAP seerver. -+The deault is -+.Dq hard . -+.It Cm SSLPath -+Specifies the path to the X.509 certificate database. -+There is no default. -+.It Cm SSL -+Specifies whether to use SSL/TLS or not. -+There are three allowed values: -+.Dq yes , -+.Dq no -+and -+.Dq start_tls -+Both -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+If -+.Dq start_tls -+is specified then StartTLS is used rather than raw LDAP over SSL. -+The default for ldap:// is -+.Dq start_tls , -+for ldaps:// -+.Dq yes -+and -+.Dq no -+for the ldapi:// . -+In case of host based configuration the default is -+.Dq start_tls . -+.It Cm Referrals -+Specifies if the client should automatically follow referrals returned -+by LDAP servers. -+The value can be or -+.Dq yes -+or -+.Dq no . -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+The default is yes. -+.It Cm Restart -+Specifies whether the LDAP client library should restart the select(2) system call when interrupted. -+The value can be or -+.Dq yes -+or -+.Dq no . -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+The default is yes. -+.It Cm TLS_CheckPeer -+Specifies what checks to perform on server certificates in a TLS session, -+if any. The value -+can be specified as one of the following keywords: -+.Dq never , -+.Dq hard , -+.Dq demand , -+.Dq allow -+and -+.Dq try . -+.Dq true , -+.Dq on -+and -+.Dq yes -+are aliases for -+.Dq hard . -+.Dq false , -+.Dq off -+and -+.Dq no -+are the aliases for -+.Dq never . -+The value -+.Dq never -+means that the client will not request or check any server certificate. -+The value -+.Dq allow -+means that the server certificate is requested. If no certificate is provided, -+the session proceeds normally. If a bad certificate is provided, it will -+be ignored and the session proceeds normally. -+The value -+.Dq try -+means that the server certificate is requested. If no certificate is provided, -+the session proceeds normally. If a bad certificate is provided, -+the session is immediately terminated. -+The value -+.Dq demand -+means that the server certificate is requested. If no -+certificate is provided, or a bad certificate is provided, the session -+is immediately terminated. -+The value -+.Dq hard -+is the same as -+.Dq demand . -+It requires an SSL connection. In the case of the plain conection the -+session is immediately terminated. -+The default is -+.Dq hard . -+.It Cm TLS_ReqCert -+Is an alias for -+.Cm TLS_CheckPeer . -+.It Cm TLS_CACertFile -+Specifies the file that contains certificates for all of the Certificate -+Authorities the client will recognize. -+There is no default. -+.It Cm TLS_CACert -+Is an alias for -+.Cm TLS_CACertFile . -+.It Cm TLS_CACertDIR -+Specifies the path of a directory that contains Certificate Authority -+certificates in separate individual files. The -+.Cm TLS_CACert -+is always used before -+.Cm TLS_CACertDir . -+The specified directory must be managed with the OpenSSL c_rehash utility. -+There is no default. -+.It Cm TLS_Ciphers -+Specifies acceptable cipher suite and preference order. -+The value should be a cipher specification for OpenSSL, -+e.g., -+.Dq HIGH:MEDIUM:+SSLv2 . -+The default is -+.Dq ALL . -+.It Cm TLS_Cipher_Suite -+Is an alias for -+.Cm TLS_Ciphers . -+.It Cm TLS_Cert -+Specifies the file that contains the client certificate. -+There is no default. -+.It Cm TLS_Certificate -+Is an alias for -+.Cm TLS_Cert . -+.It Cm TLS_Key -+Specifies the file that contains the private key that matches the certificate -+stored in the -+.Cm TLS_Cert -+file. Currently, the private key must not be protected with a password, so -+it is of critical importance that the key file is protected carefully. -+There is no default. -+.It Cm TLS_RandFile -+Specifies the file to obtain random bits from when /dev/[u]random is -+not available. Generally set to the name of the EGD/PRNGD socket. -+The environment variable RANDFILE can also be used to specify the filename. -+There is no default. -+.It Cm LogDir -+Specifies the directory used for logging by the LDAP client library. -+There is no default. -+.It Cm Debug -+Specifies the debug level used for logging by the LDAP client library. -+There is no default. -+.It Cm SSH_Filter -+Specifies the user filter applied on the LDAP search. -+The default is no filter. -+.It Cm AccountClass -+Specifies the LDAP class used to find user accounts. -+The default is posixAccount. -+.It Cm search_format -+Specifies the user format of search string in LDAP substituting %u for user name -+and %f for additional ssh filter -+.Cm SSH_Filter -+(optional). -+The default value is (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) -+.El -+.Sh FILES -+.Bl -tag -width Ds -+.It Pa /etc/ssh/ldap.conf -+Ldap configuration file for -+.Xr ssh-ldap-helper 8 . -+.El -+.Sh "SEE ALSO" -+.Xr ldap.conf 5 , -+.Xr ssh-ldap-helper 8 -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff --git a/openssh-lpk-openldap.ldif b/openssh-lpk-openldap.ldif -new file mode 100644 -index 0000000..9adf4b8 ---- /dev/null -+++ b/openssh-lpk-openldap.ldif -@@ -0,0 +1,19 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# LDIF for openLDAP Directory Server. -+# Based on the original schema, modified by Jakub Jelen. -+# -+ -+dn: cn=openssh-lpk,cn=schema,cn=config -+objectClass: olcSchemaConfig -+cn: openssh-lpk -+olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 -+ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 -+ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' -+ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) -diff --git a/openssh-lpk-sun.ldif b/openssh-lpk-sun.ldif -new file mode 100644 -index 0000000..9adf4b8 ---- /dev/null -+++ b/openssh-lpk-sun.ldif -@@ -0,0 +1,17 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# LDIF for Sun Directory Server. -+# Based on the original schema, modified by Jakub Jelen. -+# -+ -+dn: cn=schema -+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 -+ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 -+ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' -+ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) diff --git a/openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch index 2d6e730..1cfa309 100644 --- a/openssh-6.7p1-sftp-force-permission.patch +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -2,21 +2,23 @@ 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 blacklisted_requests - .Op Fl p Ar whitelisted_requests + .Op Fl P Ar denied_requests + .Op Fl p Ar allowed_requests .Op Fl u Ar umask +.Op Fl m Ar force_file_perms .Ek .Nm .Fl Q Ar protocol_feature -@@ -138,6 +139,10 @@ Sets an explicit +@@ -138,6 +139,12 @@ Sets an explicit .Xr umask 2 to be applied to newly-created files and directories, instead of the user's default mask. +.It Fl m Ar force_file_perms +Sets explicit file permissions to be applied to newly-created files instead +of the default or client requested mode. Numeric values include: -+777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set. ++777, 755, 750, 666, 644, 640, etc. Using both -m and -u switches makes the ++umask (-u) effective only for newly created directories and explicit mode (-m) ++for newly created files. .El .Pp On some systems, @@ -65,9 +67,9 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c @@ -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 blacklisted_requests] " -- "[-p whitelisted_requests] [-u umask]\n" -+ "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n" + "[-l log_level]\n\t[-P denied_requests] " +- "[-p allowed_requests] [-u umask]\n" ++ "[-p allowed_requests] [-u umask] [-m force_file_perms]\n" " %s -Q protocol_feature\n", __progname, __progname); exit(1); diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 9c9a680..de70ff5 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -137,7 +137,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c } @@ -1538,6 +1565,34 @@ child_close_fds(void) - endpwent(); + log_redirect_stderr_to(NULL); } +void diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 98d5709..35a1a8a 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1158,8 +1158,8 @@ diff -up openssh/monitor.c.audit openssh/monitor.c {0, 0, NULL} }; @@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int - size_t signaturelen, datalen, bloblen; - int r, ret, req_presence = 0, valid_data = 0, encoded_ret; + int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; + int encoded_ret; struct sshkey_sig_details *sig_details = NULL; + int type = 0; diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index bb69efe..19f3d97 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -173,20 +173,20 @@ diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c 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_whitelist(KEX_CLIENT_ENCRYPT, all_cipher); -- def_mac = match_filter_whitelist(KEX_CLIENT_MAC, all_mac); -- def_kex = match_filter_whitelist(KEX_CLIENT_KEX, all_kex); -- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_whitelist((FIPS_mode() ? +- 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_whitelist((FIPS_mode() ? ++ def_mac = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); -+ def_kex = match_filter_whitelist((FIPS_mode() ? ++ def_kex = match_filter_allowlist((FIPS_mode() ? + KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); -+ def_key = match_filter_whitelist((FIPS_mode() ? ++ def_key = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_whitelist((FIPS_mode() ? ++ def_sig = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); #define ASSEMBLE(what, defaults, all) \ do { \ @@ -211,20 +211,20 @@ diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c 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_whitelist(KEX_SERVER_ENCRYPT, all_cipher); -- def_mac = match_filter_whitelist(KEX_SERVER_MAC, all_mac); -- def_kex = match_filter_whitelist(KEX_SERVER_KEX, all_kex); -- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_whitelist((FIPS_mode() ? +- 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_whitelist((FIPS_mode() ? ++ def_mac = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); -+ def_kex = match_filter_whitelist((FIPS_mode() ? ++ def_kex = match_filter_allowlist((FIPS_mode() ? + KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); -+ def_key = match_filter_whitelist((FIPS_mode() ? ++ def_key = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_whitelist((FIPS_mode() ? ++ def_sig = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); #define ASSEMBLE(what, defaults, all) \ do { \ diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index fe4200d..6011593 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -2,9 +2,9 @@ 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 @@ - # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h + # UserKnownHostsFile ~/.ssh/known_hosts.d/%k +# +# This system is following system-wide crypto policy. +# To modify the crypto properties (Ciphers, MACs, ...), create a *.conf diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index fb7ce7c..add4727 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -154,20 +154,6 @@ diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh/configure.ac.role-mls openssh/configure.ac ---- openssh/configure.ac.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/configure.ac 2018-08-22 11:14:56.820430957 +0200 -@@ -4241,10 +4241,7 @@ AC_ARG_WITH([selinux], - LIBS="$LIBS -lselinux" - ], - AC_MSG_ERROR([SELinux support requires libselinux library])) -- SSHLIBS="$SSHLIBS $LIBSELINUX" -- SSHDLIBS="$SSHDLIBS $LIBSELINUX" - AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) -- LIBS="$save_LIBS" - fi ] - ) - AC_SUBST([SSHLIBS]) 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 @@ -338,8 +324,8 @@ 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); - int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, - const u_char *, size_t, const char *, const char *, u_int compat); + const u_char *, size_t, const char *, const char *, + const char *, u_int compat); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); diff --git a/openssh-7.9p1-ssh-copy-id.patch b/openssh-7.9p1-ssh-copy-id.patch index d47880a..24598b8 100644 --- a/openssh-7.9p1-ssh-copy-id.patch +++ b/openssh-7.9p1-ssh-copy-id.patch @@ -1,31 +1,27 @@ -diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id ---- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/contrib/ssh-copy-id 2019-01-23 20:49:30.513393667 +0100 -@@ -112,7 +112,8 @@ do - usage - } - -- OPT= OPTARG= -+ OPT= -+ OPTARG= - # implement something like getopt to avoid Solaris pain - case "$1" in - -i?*|-o?*|-p?*) -@@ -261,7 +262,7 @@ populate_new_ids() { - fi - if [ -z "$NEW_IDS" ] ; then - printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 -- printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 -+ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2 - exit 0 - fi - printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 -@@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in - # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; - # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ -- ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ -+ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ - || exit 1 - ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) - ;; +From 22bfdcf060b632b5a6ff603f8f42ff166c211a66 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +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 + + diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index b23599d..fe2f7cd 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -39,18 +39,19 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 If the specified list begins with a .Sq + -character, then the specified ciphers will be appended to the default set -+character, then the specified ciphers will be appended to the built-in default set - instead of replacing them. +-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 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 default set. ++built-in openssh default set. .Pp The supported ciphers are: .Bd -literal -offset indent @@ -106,13 +107,14 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 If the specified list begins with a .Sq + -character, then the specified methods will be appended to the default set -+character, then the specified methods will be appended to the built-in default set - instead of replacing them. +-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 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 @@ -126,7 +128,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 -diffie-hellman-group18-sha512, -diffie-hellman-group14-sha256 -.Ed -+built-in default set. ++built-in openssh default set. .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . @@ -146,18 +148,19 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 If the specified list begins with a .Sq + -character, then the specified algorithms will be appended to the default set -+character, then the specified algorithms will be appended to the built-in default set - instead of replacing them. +-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 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 default set. ++built-in openssh default set. .Pp The algorithms that contain .Qq -etm @@ -190,13 +193,14 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 If the specified list begins with a .Sq + -character, then the key types after it will be appended to the default -+character, then the key types after it will be appended to the built-in default - instead of replacing it. +-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 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 @@ -217,7 +221,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 -ssh-ed25519,sk-ssh-ed25519@openssh.com, -rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -+built-in default set. ++built-in openssh default set. .Pp The list of available key types may also be obtained using .Qq ssh -Q PubkeyAcceptedKeyTypes . @@ -261,18 +265,19 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 If the specified list begins with a .Sq + -character, then the specified ciphers will be appended to the default set -+character, then the specified ciphers will be appended to the built-in default set - instead of replacing them. +-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 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 default set. ++built-in openssh default set. .Pp The supported ciphers are: .Pp @@ -370,18 +375,19 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 Alternately if the specified list begins with a .Sq + -character, then the specified methods will be appended to the default set -+character, then the specified methods will be appended to the built-in default set - instead of replacing them. +-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 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 default set. ++built-in openssh default set. The supported algorithms are: .Pp .Bl -item -compact -offset indent @@ -416,18 +422,19 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 If the specified list begins with a .Sq + -character, then the specified algorithms will be appended to the default set -+character, then the specified algorithms will be appended to the built-in default set - instead of replacing them. +-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 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 default set. ++built-in openssh default set. .Pp The algorithms that contain .Qq -etm @@ -461,13 +468,14 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 Alternately if the specified list begins with a .Sq + -character, then the specified key types will be appended to the default set -+character, then the specified key types will be appended to the built-in default set - instead of replacing them. +-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 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 @@ -488,7 +496,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 -ssh-ed25519,sk-ssh-ed25519@openssh.com, -rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -+built-in default set. ++built-in openssh default set. .Pp The list of available key types may also be obtained using .Qq ssh -Q PubkeyAcceptedKeyTypes . diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 50fd29a..d55df23 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -568,8 +568,8 @@ index 4e56e110..2690ebeb 100644 REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion --SUBDIR+=authopt misc -+SUBDIR+=authopt misc pkcs11 +-SUBDIR+=authopt misc sshsig ++SUBDIR+=authopt misc sshsig pkcs11 .include diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c @@ -807,7 +807,7 @@ index 00000000..b637cb13 +} + +void -+check_encode(char *source, size_t len, char *whitelist, char *expect) ++check_encode(char *source, size_t len, char *allow_list, char *expect) +{ + char *buf = NULL; + struct sshbuf *b; @@ -816,7 +816,7 @@ index 00000000..b637cb13 + TEST_START(buf); + free(buf); + -+ b = percent_encode(source, len, whitelist); ++ b = percent_encode(source, len, allow_list); + ASSERT_STRING_EQ(sshbuf_ptr(b), expect); + sshbuf_free(b); + TEST_DONE(); @@ -841,14 +841,14 @@ index 00000000..b637cb13 +static void +test_percent_encode(void) +{ -+ /* Without whitelist encodes everything (for CKA_ID) */ ++ /* Without allow list encodes everything (for CKA_ID) */ + check_encode("A*", 2, "", "%41%2A"); + check_encode("\x00", 1, "", "%00"); + check_encode("\x7F", 1, "", "%7F"); + check_encode("\x80", 1, "", "%80"); + check_encode("\xff", 1, "", "%FF"); + -+ /* Default whitelist encodes anything but safe letters */ ++ /* Default allow list encodes anything but safe letters */ + check_encode("test" "\x00" "0alpha", 11, PKCS11_URI_WHITELIST, + "test%000alpha"); + check_encode(" ", 1, PKCS11_URI_WHITELIST, @@ -920,9 +920,9 @@ index 8057eb1f..0c470e32 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -67,6 +67,7 @@ - #include "ssherr.h" #include "digest.h" #include "ssh-sk.h" + #include "sk-api.h" +#include "ssh-pkcs11-uri.h" /* argv0 */ @@ -1045,9 +1045,9 @@ index 7eb6f0dc..27d8e4af 100644 + return NULL; + } + free(module_path); -+ if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { ++ if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { + verbose("refusing PKCS#11 provider \"%.100s\": " -+ "not whitelisted", canonical_provider); ++ "not allowed", canonical_provider); + pkcs11_uri_cleanup(uri); + return NULL; + } @@ -1085,9 +1085,9 @@ index 7eb6f0dc..27d8e4af 100644 - provider, strerror(errno)); - goto send; - } -- if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { +- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " -- "provider not whitelisted", canonical_provider); +- "provider not allowed", canonical_provider); + + sane_uri = sanitize_pkcs11_provider(provider); + if (sane_uri == NULL) @@ -1216,7 +1216,7 @@ new file mode 100644 index 00000000..e1a7b4e0 --- /dev/null +++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,421 @@ +@@ -0,0 +1,425 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -1342,7 +1342,7 @@ index 00000000..e1a7b4e0 +} + +struct sshbuf * -+percent_encode(const char *data, size_t length, const char *whitelist) ++percent_encode(const char *data, size_t length, const char *allow_list) +{ + struct sshbuf *b = NULL; + char tmp[4], *cp; @@ -1351,7 +1351,7 @@ index 00000000..e1a7b4e0 + if ((b = sshbuf_new()) == NULL) + return NULL; + for (i = 0; i < length; i++) { -+ cp = strchr(whitelist, data[i]); ++ cp = strchr(allow_list, data[i]); + /* if c is specified as '\0' pointer to terminator is returned !! */ + if (cp != NULL && *cp != '\0') { + if (sshbuf_put(b, &data[i], 1) != 0) @@ -1468,6 +1468,10 @@ index 00000000..e1a7b4e0 +void +pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) +{ ++ if (pkcs11 == NULL) { ++ return; ++ } ++ + free(pkcs11->id); + free(pkcs11->module_path); + free(pkcs11->token); @@ -3111,7 +3115,7 @@ index 15aee569..976844cb 100644 + } +#endif /* ENABLE_PKCS11 */ + cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_expand(cp, + filename = default_client_percent_dollar_expand(cp, pw->pw_dir, host, options.user, pw->pw_name); free(cp); diff --git a/ssh_config.5 b/ssh_config.5 diff --git a/openssh-8.3p1-sshd_include.patch b/openssh-8.3p1-sshd_include.patch deleted file mode 100644 index a399e6a..0000000 --- a/openssh-8.3p1-sshd_include.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 3caa40f40c7f97ecf46969e050e530338864033e Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 25 May 2020 15:46:51 +0200 -Subject: [PATCH 1/3] regress: Add more test cases - ---- - regress/servcfginclude.sh | 36 +++++++++++++++++++++++++++++++++++- - 1 file changed, 35 insertions(+), 1 deletion(-) - -diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh -index b25c8faa..b6a9a248 100644 ---- a/regress/servcfginclude.sh -+++ b/regress/servcfginclude.sh -@@ -146,9 +146,43 @@ Include - _EOF - - trace "disallow invalid with no argument" --${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x \ -+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x -T \ - -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \ - fail "sshd allowed Include with no argument" - -+# Ensure the Include before any Match block works as expected (bug #3122) -+cat > $OBJ/sshd_config.i << _EOF -+Banner /xx -+HostKey $OBJ/host.ssh-ed25519 -+Include $OBJ/sshd_config.i.2 -+Match host a -+ Banner /aaaa -+_EOF -+cat > $OBJ/sshd_config.i.2 << _EOF -+Match host a -+ Banner /aa -+_EOF -+ -+trace "Include before match blocks" -+trial a /aa "included file before match blocks is properly evaluated" -+ -+# Port in included file is correctly interpretted (bug #3169) -+cat > $OBJ/sshd_config.i << _EOF -+Include $OBJ/sshd_config.i.2 -+Port 7722 -+_EOF -+cat > $OBJ/sshd_config.i.2 << _EOF -+HostKey $OBJ/host.ssh-ed25519 -+_EOF -+ -+trace "Port after included files" -+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \ -+ -C "host=x,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out || \ -+ fail "failed to parse Port after included files" -+_port=`grep -i '^port ' $OBJ/sshd_config.out | awk '{print $2}'` -+if test "x7722" != "x$_port" ; then -+ fail "The Port in included file was intertepretted wrongly. Expected 7722, got $_port" -+fi -+ - # cleanup - rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out --- -2.25.4 - - -From 924922fcb8f34fb4a156367de2ee33ad92a68a6a Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 25 May 2020 16:56:39 +0200 -Subject: [PATCH 2/3] Do not call process_queued_listen_addrs() for every - included file - -Fixes #3169 ---- - servconf.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/servconf.c b/servconf.c -index 5bb4b1f8..78a7d87d 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -74,7 +74,7 @@ static void add_listen_addr(ServerOptions *, const char *, - const char *, int); - static void add_one_listen_addr(ServerOptions *, const char *, - const char *, int); --void parse_server_config_depth(ServerOptions *options, const char *filename, -+static void parse_server_config_depth(ServerOptions *options, const char *filename, - struct sshbuf *conf, struct include_list *includes, - struct connection_info *connectinfo, int flags, int *activep, int depth); - -@@ -2580,7 +2580,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) - #undef M_CP_STRARRAYOPT - - #define SERVCONF_MAX_DEPTH 16 --void -+static void - parse_server_config_depth(ServerOptions *options, const char *filename, - struct sshbuf *conf, struct include_list *includes, - struct connection_info *connectinfo, int flags, int *activep, int depth) -@@ -2606,7 +2606,6 @@ parse_server_config_depth(ServerOptions *options, const char *filename, - if (bad_options > 0) - fatal("%s: terminating, %d bad configuration options", - filename, bad_options); -- process_queued_listen_addrs(options); - } - - void -@@ -2617,6 +2616,7 @@ parse_server_config(ServerOptions *options, const char *filename, - int active = connectinfo ? 0 : 1; - parse_server_config_depth(options, filename, conf, includes, - connectinfo, 0, &active, 0); -+ process_queued_listen_addrs(options); - } - - static const char * --- -2.25.4 - - -From 26d970b4fb373cb7bd99286e41dd095cd1eadbd0 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 26 May 2020 16:25:24 +0200 -Subject: [PATCH 3/3] servconf: Fix parsing of Match blocks in included files - (#3122) - ---- - servconf.c | 28 +++++++++++++++++++--------- - 1 file changed, 19 insertions(+), 9 deletions(-) - -diff --git a/servconf.c b/servconf.c -index 78a7d87d..a8541514 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -554,6 +554,7 @@ typedef enum { - #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ - #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) - #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */ -+#define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */ - - /* Textual representation of the tokens. */ - static struct { -@@ -1265,7 +1266,7 @@ static const struct multistate multistate_tcpfwd[] = { - static int - process_server_config_line_depth(ServerOptions *options, char *line, - const char *filename, int linenum, int *activep, -- struct connection_info *connectinfo, int inc_flags, int depth, -+ struct connection_info *connectinfo, int *inc_flags, int depth, - struct include_list *includes) - { - char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; -@@ -2012,7 +2013,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, - parse_server_config_depth(options, - item->filename, item->contents, - includes, connectinfo, -- (oactive ? 0 : SSHCFG_NEVERMATCH), -+ (*inc_flags & SSHCFG_MATCH_ONLY -+ ? SSHCFG_MATCH_ONLY : (oactive -+ ? 0 : SSHCFG_NEVERMATCH)), - activep, depth + 1); - } - found = 1; -@@ -2060,7 +2063,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, - parse_server_config_depth(options, - item->filename, item->contents, - includes, connectinfo, -- (oactive ? 0 : SSHCFG_NEVERMATCH), -+ (*inc_flags & SSHCFG_MATCH_ONLY -+ ? SSHCFG_MATCH_ONLY : (oactive -+ ? 0 : SSHCFG_NEVERMATCH)), - activep, depth + 1); - *activep = oactive; - TAILQ_INSERT_TAIL(includes, item, entry); -@@ -2078,11 +2083,14 @@ process_server_config_line_depth(ServerOptions *options, char *line, - if (cmdline) - fatal("Match directive not supported as a command-line " - "option"); -- value = match_cfg_line(&cp, linenum, connectinfo); -+ value = match_cfg_line(&cp, linenum, -+ (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo)); - if (value < 0) - fatal("%s line %d: Bad Match condition", filename, - linenum); -- *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; -+ *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; -+ /* The MATCH_ONLY is applicable only until the first match block */ -+ *inc_flags &= ~SSHCFG_MATCH_ONLY; - break; - - case sKerberosUseKuserok: -@@ -2385,8 +2393,9 @@ process_server_config_line(ServerOptions *options, char *line, - const char *filename, int linenum, int *activep, - struct connection_info *connectinfo, struct include_list *includes) - { -+ int inc_flags = 0; - return process_server_config_line_depth(options, line, filename, -- linenum, activep, connectinfo, 0, 0, includes); -+ linenum, activep, connectinfo, &inc_flags, 0, includes); - } - - -@@ -2591,14 +2600,15 @@ parse_server_config_depth(ServerOptions *options, const char *filename, - if (depth < 0 || depth > SERVCONF_MAX_DEPTH) - fatal("Too many recursive configuration includes"); - -- debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); -+ debug2("%s: config %s len %zu%s", __func__, filename, sshbuf_len(conf), -+ (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : "")); - - if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) - fatal("%s: sshbuf_dup_string failed", __func__); - linenum = 1; - while ((cp = strsep(&cbuf, "\n")) != NULL) { - if (process_server_config_line_depth(options, cp, -- filename, linenum++, activep, connectinfo, flags, -+ filename, linenum++, activep, connectinfo, &flags, - depth, includes) != 0) - bad_options++; - } -@@ -2615,7 +2625,7 @@ parse_server_config(ServerOptions *options, const char *filename, - { - int active = connectinfo ? 0 : 1; - parse_server_config_depth(options, filename, conf, includes, -- connectinfo, 0, &active, 0); -+ connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0); - process_queued_listen_addrs(options); - } - --- -2.25.4 - - diff --git a/openssh-8.3p1-gsissh.patch b/openssh-8.4p1-gsissh.patch similarity index 89% rename from openssh-8.3p1-gsissh.patch rename to openssh-8.4p1-gsissh.patch index 284cb1c..9c178c4 100644 --- a/openssh-8.3p1-gsissh.patch +++ b/openssh-8.4p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.2p1.orig/auth2.c openssh-8.2p1/auth2.c ---- openssh-8.2p1.orig/auth2.c 2020-05-04 19:34:53.561875424 +0200 -+++ openssh-8.2p1/auth2.c 2020-05-04 19:35:31.393472137 +0200 +diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c +--- openssh-8.4p1.orig/auth2.c 2020-10-06 11:23:35.222491390 +0200 ++++ openssh-8.4p1/auth2.c 2020-10-06 11:24:20.006596864 +0200 @@ -279,7 +279,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -101,9 +101,9 @@ diff -Nur openssh-8.2p1.orig/auth2.c openssh-8.2p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c ---- openssh-8.2p1.orig/auth2-gss.c 2020-05-04 19:34:53.476876332 +0200 -+++ openssh-8.2p1/auth2-gss.c 2020-05-04 19:37:33.020181539 +0200 +diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c +--- openssh-8.4p1.orig/auth2-gss.c 2020-10-06 11:23:35.124491159 +0200 ++++ openssh-8.4p1/auth2-gss.c 2020-10-06 11:24:20.006596864 +0200 @@ -49,6 +49,7 @@ extern ServerOptions options; @@ -307,9 +307,9 @@ diff -Nur openssh-8.2p1.orig/auth2-gss.c openssh-8.2p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.2p1.orig/auth.c openssh-8.2p1/auth.c ---- openssh-8.2p1.orig/auth.c 2020-05-04 19:34:53.562875413 +0200 -+++ openssh-8.2p1/auth.c 2020-05-04 19:35:31.394472126 +0200 +diff -Nur openssh-8.4p1.orig/auth.c openssh-8.4p1/auth.c +--- openssh-8.4p1.orig/auth.c 2020-10-06 11:23:35.223491392 +0200 ++++ openssh-8.4p1/auth.c 2020-10-06 11:24:20.007596867 +0200 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -340,9 +340,9 @@ diff -Nur openssh-8.2p1.orig/auth.c openssh-8.2p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.2p1.orig/auth.h openssh-8.2p1/auth.h ---- openssh-8.2p1.orig/auth.h 2020-05-04 19:34:53.563875402 +0200 -+++ openssh-8.2p1/auth.h 2020-05-04 19:35:31.394472126 +0200 +diff -Nur openssh-8.4p1.orig/auth.h openssh-8.4p1/auth.h +--- openssh-8.4p1.orig/auth.h 2020-10-06 11:23:35.224491395 +0200 ++++ openssh-8.4p1/auth.h 2020-10-06 11:24:20.007596867 +0200 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +352,9 @@ diff -Nur openssh-8.2p1.orig/auth.h openssh-8.2p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c ---- openssh-8.2p1.orig/auth-pam.c 2020-05-04 19:34:53.433876791 +0200 -+++ openssh-8.2p1/auth-pam.c 2020-05-04 19:35:31.395472115 +0200 +diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c +--- openssh-8.4p1.orig/auth-pam.c 2020-10-06 11:23:35.083491063 +0200 ++++ openssh-8.4p1/auth-pam.c 2020-10-06 11:24:20.008596869 +0200 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -449,7 +449,7 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -518,6 +582,13 @@ +@@ -522,6 +586,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -463,7 +463,7 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; -@@ -538,6 +609,13 @@ +@@ -542,6 +613,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -477,7 +477,7 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -722,6 +800,8 @@ +@@ -726,6 +804,8 @@ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), sshpam_laddr, ssh_local_port(ssh)); @@ -486,7 +486,7 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1064,6 +1144,18 @@ +@@ -1068,6 +1148,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -505,7 +505,7 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1352,6 +1444,9 @@ +@@ -1356,6 +1448,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -515,9 +515,9 @@ diff -Nur openssh-8.2p1.orig/auth-pam.c openssh-8.2p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.2p1.orig/auth-pam.h openssh-8.2p1/auth-pam.h ---- openssh-8.2p1.orig/auth-pam.h 2020-05-04 19:34:53.433876791 +0200 -+++ openssh-8.2p1/auth-pam.h 2020-05-04 19:35:31.395472115 +0200 +diff -Nur openssh-8.4p1.orig/auth-pam.h openssh-8.4p1/auth-pam.h +--- openssh-8.4p1.orig/auth-pam.h 2020-10-06 11:23:35.083491063 +0200 ++++ openssh-8.4p1/auth-pam.h 2020-10-06 11:24:20.008596869 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +525,9 @@ diff -Nur openssh-8.2p1.orig/auth-pam.h openssh-8.2p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.2p1.orig/canohost.c openssh-8.2p1/canohost.c ---- openssh-8.2p1.orig/canohost.c 2020-05-04 19:34:53.476876332 +0200 -+++ openssh-8.2p1/canohost.c 2020-05-04 19:35:31.395472115 +0200 +diff -Nur openssh-8.4p1.orig/canohost.c openssh-8.4p1/canohost.c +--- openssh-8.4p1.orig/canohost.c 2020-10-06 11:23:35.125491161 +0200 ++++ openssh-8.4p1/canohost.c 2020-10-06 11:24:20.009596871 +0200 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +570,9 @@ diff -Nur openssh-8.2p1.orig/canohost.c openssh-8.2p1/canohost.c + } + } +} -diff -Nur openssh-8.2p1.orig/canohost.h openssh-8.2p1/canohost.h ---- openssh-8.2p1.orig/canohost.h 2020-05-04 19:34:53.476876332 +0200 -+++ openssh-8.2p1/canohost.h 2020-05-04 19:35:31.396472105 +0200 +diff -Nur openssh-8.4p1.orig/canohost.h openssh-8.4p1/canohost.h +--- openssh-8.4p1.orig/canohost.h 2020-10-06 11:23:35.125491161 +0200 ++++ openssh-8.4p1/canohost.h 2020-10-06 11:24:20.009596871 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,10 +580,10 @@ diff -Nur openssh-8.2p1.orig/canohost.h openssh-8.2p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac ---- openssh-8.2p1.orig/configure.ac 2020-05-04 19:34:53.554875498 +0200 -+++ openssh-8.2p1/configure.ac 2020-05-04 19:35:31.397472094 +0200 -@@ -4710,6 +4710,14 @@ +diff -Nur openssh-8.4p1.orig/configure.ac openssh-8.4p1/configure.ac +--- openssh-8.4p1.orig/configure.ac 2020-10-06 11:23:35.212491366 +0200 ++++ openssh-8.4p1/configure.ac 2020-10-06 11:24:20.010596874 +0200 +@@ -4730,6 +4730,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -598,7 +598,7 @@ diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac fi if test -n "${rpath_opt}" ; then LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" -@@ -4749,6 +4757,40 @@ +@@ -4769,6 +4777,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,9 +639,9 @@ diff -Nur openssh-8.2p1.orig/configure.ac openssh-8.2p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.2p1.orig/gss-genr.c openssh-8.2p1/gss-genr.c ---- openssh-8.2p1.orig/gss-genr.c 2020-05-04 19:34:53.478876310 +0200 -+++ openssh-8.2p1/gss-genr.c 2020-05-04 19:35:31.397472094 +0200 +diff -Nur openssh-8.4p1.orig/gss-genr.c openssh-8.4p1/gss-genr.c +--- openssh-8.4p1.orig/gss-genr.c 2020-10-06 11:23:35.127491166 +0200 ++++ openssh-8.4p1/gss-genr.c 2020-10-06 11:24:20.010596874 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -678,9 +678,9 @@ diff -Nur openssh-8.2p1.orig/gss-genr.c openssh-8.2p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.2p1.orig/gss-serv.c openssh-8.2p1/gss-serv.c ---- openssh-8.2p1.orig/gss-serv.c 2020-05-04 19:34:53.494876139 +0200 -+++ openssh-8.2p1/gss-serv.c 2020-05-04 19:35:31.397472094 +0200 +diff -Nur openssh-8.4p1.orig/gss-serv.c openssh-8.4p1/gss-serv.c +--- openssh-8.4p1.orig/gss-serv.c 2020-10-06 11:23:35.145491208 +0200 ++++ openssh-8.4p1/gss-serv.c 2020-10-06 11:24:20.011596876 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +961,9 @@ diff -Nur openssh-8.2p1.orig/gss-serv.c openssh-8.2p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.2p1.orig/gss-serv-gsi.c openssh-8.2p1/gss-serv-gsi.c ---- openssh-8.2p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.2p1/gss-serv-gsi.c 2020-05-04 19:35:31.398472084 +0200 +diff -Nur openssh-8.4p1.orig/gss-serv-gsi.c openssh-8.4p1/gss-serv-gsi.c +--- openssh-8.4p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/gss-serv-gsi.c 2020-10-06 11:24:20.011596876 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1293,9 @@ diff -Nur openssh-8.2p1.orig/gss-serv-gsi.c openssh-8.2p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.2p1.orig/gss-serv-krb5.c openssh-8.2p1/gss-serv-krb5.c ---- openssh-8.2p1.orig/gss-serv-krb5.c 2020-05-04 19:34:53.514875926 +0200 -+++ openssh-8.2p1/gss-serv-krb5.c 2020-05-04 19:35:31.398472084 +0200 +diff -Nur openssh-8.4p1.orig/gss-serv-krb5.c openssh-8.4p1/gss-serv-krb5.c +--- openssh-8.4p1.orig/gss-serv-krb5.c 2020-10-06 11:23:35.166491258 +0200 ++++ openssh-8.4p1/gss-serv-krb5.c 2020-10-06 11:24:20.011596876 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1349,9 @@ diff -Nur openssh-8.2p1.orig/gss-serv-krb5.c openssh-8.2p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.2p1.orig/kexgsss.c openssh-8.2p1/kexgsss.c ---- openssh-8.2p1.orig/kexgsss.c 2020-05-04 19:34:53.480876289 +0200 -+++ openssh-8.2p1/kexgsss.c 2020-05-04 19:35:31.398472084 +0200 +diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c +--- openssh-8.4p1.orig/kexgsss.c 2020-10-06 11:23:35.129491171 +0200 ++++ openssh-8.4p1/kexgsss.c 2020-10-06 11:24:20.012596878 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1415,10 +1415,10 @@ diff -Nur openssh-8.2p1.orig/kexgsss.c openssh-8.2p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.2p1.orig/Makefile.in openssh-8.2p1/Makefile.in ---- openssh-8.2p1.orig/Makefile.in 2020-05-04 19:34:53.564875392 +0200 -+++ openssh-8.2p1/Makefile.in 2020-05-04 19:35:31.398472084 +0200 -@@ -135,6 +135,7 @@ +diff -Nur openssh-8.4p1.orig/Makefile.in openssh-8.4p1/Makefile.in +--- openssh-8.4p1.orig/Makefile.in 2020-10-06 11:23:35.228491404 +0200 ++++ openssh-8.4p1/Makefile.in 2020-10-06 11:24:20.012596878 +0200 +@@ -129,6 +129,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1426,10 +1426,10 @@ diff -Nur openssh-8.2p1.orig/Makefile.in openssh-8.2p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c ---- openssh-8.2p1.orig/misc.c 2020-05-04 19:34:53.434876780 +0200 -+++ openssh-8.2p1/misc.c 2020-05-04 19:35:31.399472073 +0200 -@@ -325,11 +325,14 @@ +diff -Nur openssh-8.4p1.orig/misc.c openssh-8.4p1/misc.c +--- openssh-8.4p1.orig/misc.c 2020-10-06 11:23:35.084491065 +0200 ++++ openssh-8.4p1/misc.c 2020-10-06 11:24:20.013596881 +0200 +@@ -324,11 +324,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1445,7 +1445,7 @@ diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c int wspace = 0; if (*s == NULL) -@@ -337,6 +340,21 @@ +@@ -336,6 +339,21 @@ old = *s; @@ -1467,7 +1467,7 @@ diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -412,6 +430,20 @@ +@@ -411,6 +429,20 @@ return copy; } @@ -1488,10 +1488,10 @@ diff -Nur openssh-8.2p1.orig/misc.c openssh-8.2p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.2p1.orig/misc.h openssh-8.2p1/misc.h ---- openssh-8.2p1.orig/misc.h 2020-02-14 01:40:54.000000000 +0100 -+++ openssh-8.2p1/misc.h 2020-05-04 19:35:31.399472073 +0200 -@@ -90,6 +90,7 @@ +diff -Nur openssh-8.4p1.orig/misc.h openssh-8.4p1/misc.h +--- openssh-8.4p1.orig/misc.h 2020-09-27 09:25:01.000000000 +0200 ++++ openssh-8.4p1/misc.h 2020-10-06 11:24:20.013596881 +0200 +@@ -94,6 +94,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1499,9 +1499,9 @@ diff -Nur openssh-8.2p1.orig/misc.h openssh-8.2p1/misc.h const char *ssh_gai_strerror(int); typedef struct arglist arglist; -diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c ---- openssh-8.2p1.orig/monitor.c 2020-05-04 19:34:53.583875189 +0200 -+++ openssh-8.2p1/monitor.c 2020-05-04 19:35:31.400472062 +0200 +diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c +--- openssh-8.4p1.orig/monitor.c 2020-10-06 11:23:35.252491460 +0200 ++++ openssh-8.4p1/monitor.c 2020-10-06 11:24:20.014596883 +0200 @@ -155,6 +155,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1592,7 +1592,7 @@ diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2093,6 +2108,79 @@ +@@ -2105,6 +2120,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.2p1.orig/monitor.c openssh-8.2p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.2p1.orig/monitor.h openssh-8.2p1/monitor.h ---- openssh-8.2p1.orig/monitor.h 2020-05-04 19:34:53.565875381 +0200 -+++ openssh-8.2p1/monitor.h 2020-05-04 19:35:31.400472062 +0200 +diff -Nur openssh-8.4p1.orig/monitor.h openssh-8.4p1/monitor.h +--- openssh-8.4p1.orig/monitor.h 2020-10-06 11:23:35.230491409 +0200 ++++ openssh-8.4p1/monitor.h 2020-10-06 11:24:20.014596883 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,9 +1686,9 @@ diff -Nur openssh-8.2p1.orig/monitor.h openssh-8.2p1/monitor.h }; struct ssh; -diff -Nur openssh-8.2p1.orig/monitor_wrap.c openssh-8.2p1/monitor_wrap.c ---- openssh-8.2p1.orig/monitor_wrap.c 2020-05-04 19:34:53.583875189 +0200 -+++ openssh-8.2p1/monitor_wrap.c 2020-05-04 19:35:31.400472062 +0200 +diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c +--- openssh-8.4p1.orig/monitor_wrap.c 2020-10-06 11:23:35.252491460 +0200 ++++ openssh-8.4p1/monitor_wrap.c 2020-10-06 11:24:20.015596885 +0200 @@ -1078,6 +1078,94 @@ return (authenticated); } @@ -1784,10 +1784,10 @@ diff -Nur openssh-8.2p1.orig/monitor_wrap.c openssh-8.2p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.2p1.orig/monitor_wrap.h openssh-8.2p1/monitor_wrap.h ---- openssh-8.2p1.orig/monitor_wrap.h 2020-05-04 19:34:53.572875306 +0200 -+++ openssh-8.2p1/monitor_wrap.h 2020-05-04 19:35:31.401472052 +0200 -@@ -72,6 +72,10 @@ +diff -Nur openssh-8.4p1.orig/monitor_wrap.h openssh-8.4p1/monitor_wrap.h +--- openssh-8.4p1.orig/monitor_wrap.h 2020-10-06 11:23:35.239491430 +0200 ++++ openssh-8.4p1/monitor_wrap.h 2020-10-06 11:24:20.015596885 +0200 +@@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-8.2p1.orig/monitor_wrap.h openssh-8.2p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.2p1.orig/readconf.c openssh-8.2p1/readconf.c ---- openssh-8.2p1.orig/readconf.c 2020-05-04 19:34:53.576875263 +0200 -+++ openssh-8.2p1/readconf.c 2020-05-04 19:35:31.401472052 +0200 -@@ -2111,11 +2111,11 @@ +diff -Nur openssh-8.4p1.orig/readconf.c openssh-8.4p1/readconf.c +--- openssh-8.4p1.orig/readconf.c 2020-10-06 11:23:35.244491442 +0200 ++++ openssh-8.4p1/readconf.c 2020-10-06 11:24:20.016596888 +0200 +@@ -2177,11 +2177,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1816,9 +1816,9 @@ diff -Nur openssh-8.2p1.orig/readconf.c openssh-8.2p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.2p1.orig/readconf.h openssh-8.2p1/readconf.h ---- openssh-8.2p1.orig/readconf.h 2020-05-04 19:34:53.482876268 +0200 -+++ openssh-8.2p1/readconf.h 2020-05-04 19:35:31.401472052 +0200 +diff -Nur openssh-8.4p1.orig/readconf.h openssh-8.4p1/readconf.h +--- openssh-8.4p1.orig/readconf.h 2020-10-06 11:23:35.133491180 +0200 ++++ openssh-8.4p1/readconf.h 2020-10-06 11:24:20.017596890 +0200 @@ -79,6 +79,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1828,10 +1828,10 @@ diff -Nur openssh-8.2p1.orig/readconf.h openssh-8.2p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c ---- openssh-8.2p1.orig/servconf.c 2020-05-04 19:34:53.584875178 +0200 -+++ openssh-8.2p1/servconf.c 2020-05-04 19:35:31.402472041 +0200 -@@ -92,6 +92,7 @@ +diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c +--- openssh-8.4p1.orig/servconf.c 2020-10-06 11:23:35.253491463 +0200 ++++ openssh-8.4p1/servconf.c 2020-10-06 11:24:20.017596890 +0200 +@@ -93,6 +93,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1839,7 +1839,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -136,9 +137,11 @@ +@@ -137,9 +138,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1851,7 +1851,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -312,6 +315,8 @@ +@@ -313,6 +316,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -391,13 +396,17 @@ +@@ -392,13 +397,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -538,7 +547,7 @@ +@@ -530,7 +539,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -560,6 +569,9 @@ +@@ -552,6 +561,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -591,8 +603,10 @@ +@@ -584,8 +596,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -641,8 +655,15 @@ +@@ -634,8 +648,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -650,8 +671,11 @@ +@@ -643,8 +664,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -721,6 +745,8 @@ +@@ -714,6 +738,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1361,6 +1387,10 @@ +@@ -1367,6 +1393,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1600,6 +1630,10 @@ +@@ -1609,6 +1639,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1608,6 +1642,10 @@ +@@ -1617,6 +1651,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1628,6 +1666,12 @@ +@@ -1637,6 +1675,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2550,6 +2594,7 @@ +@@ -2577,6 +2621,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,10 +2001,10 @@ diff -Nur openssh-8.2p1.orig/servconf.c openssh-8.2p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h ---- openssh-8.2p1.orig/servconf.h 2020-05-04 19:34:53.525875808 +0200 -+++ openssh-8.2p1/servconf.h 2020-05-04 19:35:31.402472041 +0200 -@@ -137,9 +137,12 @@ +diff -Nur openssh-8.4p1.orig/servconf.h openssh-8.4p1/servconf.h +--- openssh-8.4p1.orig/servconf.h 2020-10-06 11:23:35.178491286 +0200 ++++ openssh-8.4p1/servconf.h 2020-10-06 11:24:20.018596893 +0200 +@@ -143,9 +143,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2017,7 +2017,7 @@ diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -198,6 +201,7 @@ +@@ -204,6 +207,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2025,10 +2025,10 @@ diff -Nur openssh-8.2p1.orig/servconf.h openssh-8.2p1/servconf.h int permit_tun; -diff -Nur openssh-8.2p1.orig/ssh.1 openssh-8.2p1/ssh.1 ---- openssh-8.2p1.orig/ssh.1 2020-05-04 19:34:53.484876246 +0200 -+++ openssh-8.2p1/ssh.1 2020-05-04 19:35:31.403472031 +0200 -@@ -1449,6 +1449,18 @@ +diff -Nur openssh-8.4p1.orig/ssh.1 openssh-8.4p1/ssh.1 +--- openssh-8.4p1.orig/ssh.1 2020-10-06 11:23:35.134491183 +0200 ++++ openssh-8.4p1/ssh.1 2020-10-06 11:24:20.019596895 +0200 +@@ -1471,6 +1471,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-8.2p1.orig/ssh.1 openssh-8.2p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c ---- openssh-8.2p1.orig/ssh.c 2020-05-04 19:34:53.577875253 +0200 -+++ openssh-8.2p1/ssh.c 2020-05-04 19:35:31.403472031 +0200 -@@ -550,6 +550,38 @@ +diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c +--- openssh-8.4p1.orig/ssh.c 2020-10-06 11:23:35.246491446 +0200 ++++ openssh-8.4p1/ssh.c 2020-10-06 11:24:20.019596895 +0200 +@@ -605,6 +605,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,9 +2089,9 @@ diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1320,8 +1352,12 @@ - tty_flag = 0; - } +@@ -1267,8 +1299,12 @@ + /* Fill configuration defaults. */ + fill_default_options(&options); - if (options.user == NULL) + if (options.user == NULL) { @@ -2101,11 +2101,11 @@ diff -Nur openssh-8.2p1.orig/ssh.c openssh-8.2p1/ssh.c + options.implicit = 0; + } - /* Set up strings used to percent_expand() arguments */ - if (gethostname(thishost, sizeof(thishost)) == -1) -diff -Nur openssh-8.2p1.orig/ssh_config openssh-8.2p1/ssh_config ---- openssh-8.2p1.orig/ssh_config 2020-05-04 19:34:53.484876246 +0200 -+++ openssh-8.2p1/ssh_config 2020-05-04 19:35:31.404472020 +0200 + /* + * If ProxyJump option specified, then construct a ProxyCommand now. +diff -Nur openssh-8.4p1.orig/ssh_config openssh-8.4p1/ssh_config +--- openssh-8.4p1.orig/ssh_config 2020-10-06 11:23:35.135491185 +0200 ++++ openssh-8.4p1/ssh_config 2020-10-06 11:24:20.020596897 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.2p1.orig/ssh_config openssh-8.2p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 ---- openssh-8.2p1.orig/ssh_config.5 2020-05-04 19:34:53.548875562 +0200 -+++ openssh-8.2p1/ssh_config.5 2020-05-04 19:35:31.404472020 +0200 +diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 +--- openssh-8.4p1.orig/ssh_config.5 2020-10-06 11:23:35.205491350 +0200 ++++ openssh-8.4p1/ssh_config.5 2020-10-06 11:24:20.020596897 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -763,7 +769,7 @@ +@@ -776,7 +782,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -771,12 +777,12 @@ +@@ -784,12 +790,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1306,7 +1312,7 @@ +@@ -1330,7 +1336,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-8.2p1.orig/ssh_config.5 openssh-8.2p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c ---- openssh-8.2p1.orig/sshconnect2.c 2020-05-04 19:34:53.578875242 +0200 -+++ openssh-8.2p1/sshconnect2.c 2020-05-04 19:35:31.405472009 +0200 -@@ -800,6 +800,11 @@ +diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c +--- openssh-8.4p1.orig/sshconnect2.c 2020-10-06 11:23:35.246491446 +0200 ++++ openssh-8.4p1/sshconnect2.c 2020-10-06 11:24:20.021596900 +0200 +@@ -847,6 +847,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -911,7 +916,8 @@ +@@ -958,7 +963,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1081,6 +1087,20 @@ +@@ -1128,6 +1134,20 @@ return r; } @@ -2214,7 +2214,7 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1103,6 +1123,11 @@ +@@ -1150,6 +1170,11 @@ if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -2226,7 +2226,7 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -@@ -1116,7 +1141,9 @@ +@@ -1163,7 +1188,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2237,10 +2237,10 @@ diff -Nur openssh-8.2p1.orig/sshconnect2.c openssh-8.2p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.2p1.orig/sshd.8 openssh-8.2p1/sshd.8 ---- openssh-8.2p1.orig/sshd.8 2020-05-04 19:34:53.499876086 +0200 -+++ openssh-8.2p1/sshd.8 2020-05-04 19:35:31.405472009 +0200 -@@ -808,6 +808,29 @@ +diff -Nur openssh-8.4p1.orig/sshd.8 openssh-8.4p1/sshd.8 +--- openssh-8.4p1.orig/sshd.8 2020-10-06 11:23:35.149491218 +0200 ++++ openssh-8.4p1/sshd.8 2020-10-06 11:24:20.022596902 +0200 +@@ -815,6 +815,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2270,10 +2270,10 @@ diff -Nur openssh-8.2p1.orig/sshd.8 openssh-8.2p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.2p1.orig/sshd.c openssh-8.2p1/sshd.c ---- openssh-8.2p1.orig/sshd.c 2020-05-04 19:34:53.586875156 +0200 -+++ openssh-8.2p1/sshd.c 2020-05-04 19:35:31.406471999 +0200 -@@ -2338,7 +2338,7 @@ +diff -Nur openssh-8.4p1.orig/sshd.c openssh-8.4p1/sshd.c +--- openssh-8.4p1.orig/sshd.c 2020-10-06 11:23:35.255491467 +0200 ++++ openssh-8.4p1/sshd.c 2020-10-06 11:24:20.023596904 +0200 +@@ -2384,7 +2384,7 @@ #endif #ifdef GSSAPI @@ -2282,10 +2282,10 @@ diff -Nur openssh-8.2p1.orig/sshd.c openssh-8.2p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config ---- openssh-8.2p1.orig/sshd_config 2020-05-04 19:34:53.516875904 +0200 -+++ openssh-8.2p1/sshd_config 2020-05-04 19:35:31.406471999 +0200 -@@ -72,10 +72,11 @@ +diff -Nur openssh-8.4p1.orig/sshd_config openssh-8.4p1/sshd_config +--- openssh-8.4p1.orig/sshd_config 2020-10-06 11:23:35.168491263 +0200 ++++ openssh-8.4p1/sshd_config 2020-10-06 11:24:20.023596904 +0200 +@@ -76,10 +76,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2299,7 +2299,7 @@ diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -91,6 +92,10 @@ +@@ -95,6 +96,10 @@ # problems. #UsePAM no @@ -2310,10 +2310,10 @@ diff -Nur openssh-8.2p1.orig/sshd_config openssh-8.2p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 ---- openssh-8.2p1.orig/sshd_config.5 2020-05-04 19:34:53.548875562 +0200 -+++ openssh-8.2p1/sshd_config.5 2020-05-04 19:35:31.406471999 +0200 -@@ -635,15 +635,34 @@ +diff -Nur openssh-8.4p1.orig/sshd_config.5 openssh-8.4p1/sshd_config.5 +--- openssh-8.4p1.orig/sshd_config.5 2020-10-06 11:23:35.206491352 +0200 ++++ openssh-8.4p1/sshd_config.5 2020-10-06 11:24:20.024596907 +0200 +@@ -633,15 +633,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2349,7 +2349,7 @@ diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -654,7 +673,7 @@ +@@ -652,7 +671,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2358,7 +2358,7 @@ diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1715,6 +1734,12 @@ +@@ -1738,6 +1757,12 @@ as a non-root user. The default is .Cm no . @@ -2371,10 +2371,10 @@ diff -Nur openssh-8.2p1.orig/sshd_config.5 openssh-8.2p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.2p1.orig/sshd_config_redhat openssh-8.2p1/sshd_config_redhat ---- openssh-8.2p1.orig/sshd_config_redhat 2020-05-04 19:34:53.466876438 +0200 -+++ openssh-8.2p1/sshd_config_redhat 2020-05-04 19:35:31.407471988 +0200 -@@ -9,9 +9,6 @@ +diff -Nur openssh-8.4p1.orig/sshd_config_redhat openssh-8.4p1/sshd_config_redhat +--- openssh-8.4p1.orig/sshd_config_redhat 2020-10-06 11:23:35.114491135 +0200 ++++ openssh-8.4p1/sshd_config_redhat 2020-10-06 11:24:20.024596907 +0200 +@@ -10,9 +10,6 @@ PasswordAuthentication yes ChallengeResponseAuthentication no @@ -2384,9 +2384,9 @@ diff -Nur openssh-8.2p1.orig/sshd_config_redhat openssh-8.2p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.2p1.orig/ssh-gss.h openssh-8.2p1/ssh-gss.h ---- openssh-8.2p1.orig/ssh-gss.h 2020-05-04 19:34:53.496876118 +0200 -+++ openssh-8.2p1/ssh-gss.h 2020-05-04 19:35:31.407471988 +0200 +diff -Nur openssh-8.4p1.orig/ssh-gss.h openssh-8.4p1/ssh-gss.h +--- openssh-8.4p1.orig/ssh-gss.h 2020-10-06 11:23:35.146491211 +0200 ++++ openssh-8.4p1/ssh-gss.h 2020-10-06 11:24:20.025596909 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2422,12 +2422,12 @@ diff -Nur openssh-8.2p1.orig/ssh-gss.h openssh-8.2p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.2p1.orig/version.h openssh-8.2p1/version.h ---- openssh-8.2p1.orig/version.h 2020-02-14 01:40:54.000000000 +0100 -+++ openssh-8.2p1/version.h 2020-05-04 19:35:31.407471988 +0200 +diff -Nur openssh-8.4p1.orig/version.h openssh-8.4p1/version.h +--- openssh-8.4p1.orig/version.h 2020-09-27 09:25:01.000000000 +0200 ++++ openssh-8.4p1/version.h 2020-10-06 11:24:20.025596909 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.3" + #define SSH_VERSION "OpenSSH_8.4" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.4p1-ssh-copy-id.patch b/openssh-8.4p1-ssh-copy-id.patch new file mode 100644 index 0000000..7bc4c7d --- /dev/null +++ b/openssh-8.4p1-ssh-copy-id.patch @@ -0,0 +1,130 @@ +From 66f16e5425eb881570e82bfef7baeac2e7accc0a Mon Sep 17 00:00:00 2001 +From: Oleg +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 +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 +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; +-- diff --git a/sources b/sources index c3131e5..d7fc727 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.3p1.tar.gz) = b5232f7c85bf59ae2ff9d17b030117012e257e3b8c0d5ac60bb139a85b1fbf298b40f2e04203a2e13ca7273053ed668b9dedd54d3a67a7cb8e8e58c0228c5f40 -SHA512 (openssh-8.3p1.tar.gz.asc) = 569fa12b3671af15bd7cd54fc7b13d1d64f3e96eb28f6dc430082f7bec4595689c633d3d56c23faad45b73e4da666c3ec090de26bf54f49410ba9bb8b5363e75 +SHA512 (openssh-8.4p1.tar.gz) = d65275b082c46c5efe7cf3264fa6794d6e99a36d4a54b50554fc56979d6c0837381587fd5399195e1db680d2a5ad1ef0b99a180eac2b4de5637906cb7a89e9ce +SHA512 (openssh-8.4p1.tar.gz.asc) = 3d9a026db27729a5a56785db3824230ccf2a3beca4bb48ef465e44d869b944dbc5d443152a1b1be21bc9c213c465d3d7ca1f876a387d0a6b9682a0cfec3e6e32 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d From 409dc9ed6234a5d941bbae36ffdf4ba0441e3dbd Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 30 Nov 2020 07:39:27 +0100 Subject: [PATCH 089/146] Based on openssh-8.4p1-3.fc33 --- gsi-openssh.spec | 11 +++++- openssh-8.4p1-debian-compat.patch | 57 +++++++++++++++++++++++++++++ openssh-8.4p1-sandbox-seccomp.patch | 14 +++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 openssh-8.4p1-debian-compat.patch create mode 100644 openssh-8.4p1-sandbox-seccomp.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ed191ac..96f274e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.4p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -154,6 +154,10 @@ 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 # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -296,6 +300,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 %patch967 -p1 -b .ssh-copy-id +%patch968 -p1 -b .seccomp +%patch969 -p0 -b .debian %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -495,6 +501,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Mon Nov 30 2020 Mattias Ellert - 8.4p1-2 +- Based on openssh-8.4p1-3.fc33 + * Tue Oct 06 2020 Mattias Ellert - 8.4p1-1 - Based on openssh-8.4p1-2.fc33 diff --git a/openssh-8.4p1-debian-compat.patch b/openssh-8.4p1-debian-compat.patch new file mode 100644 index 0000000..0af1d3d --- /dev/null +++ b/openssh-8.4p1-debian-compat.patch @@ -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; + } + + diff --git a/openssh-8.4p1-sandbox-seccomp.patch b/openssh-8.4p1-sandbox-seccomp.patch new file mode 100644 index 0000000..ac4ee61 --- /dev/null +++ b/openssh-8.4p1-sandbox-seccomp.patch @@ -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 From 02fff1664210960bca9a916779bbe6709321b033 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 9 Dec 2020 20:27:08 +0100 Subject: [PATCH 090/146] Based on openssh-8.4p1-4.fc33 --- gsi-openssh.spec | 7 +++++-- openssh-7.7p1-redhat.patch | 3 +-- openssh-8.4p1-gsissh.patch | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 96f274e..23d80e8 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.4p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -96,7 +96,7 @@ 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 + draft-ietf-curdle-gss-keyex-sha2-08) +# 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 @@ -501,6 +501,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Wed Dec 9 2020 Mattias Ellert - 8.4p1-3 +- Based on openssh-8.4p1-4.fc33 + * Mon Nov 30 2020 Mattias Ellert - 8.4p1-2 - Based on openssh-8.4p1-3.fc33 diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 6011593..fcda6c6 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -86,7 +86,7 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config 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,29 @@ +@@ -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, @@ -96,7 +96,6 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat + +SyslogFacility AUTHPRIV + -+PasswordAuthentication yes +ChallengeResponseAuthentication no + +GSSAPIAuthentication yes diff --git a/openssh-8.4p1-gsissh.patch b/openssh-8.4p1-gsissh.patch index 9c178c4..d664fdd 100644 --- a/openssh-8.4p1-gsissh.patch +++ b/openssh-8.4p1-gsissh.patch @@ -2375,7 +2375,7 @@ diff -Nur openssh-8.4p1.orig/sshd_config_redhat openssh-8.4p1/sshd_config_redhat --- openssh-8.4p1.orig/sshd_config_redhat 2020-10-06 11:23:35.114491135 +0200 +++ openssh-8.4p1/sshd_config_redhat 2020-10-06 11:24:20.024596907 +0200 @@ -10,9 +10,6 @@ - PasswordAuthentication yes + ChallengeResponseAuthentication no -GSSAPIAuthentication yes From 01d6be4f82b0b88a5e53be305cb7d4b977b590c1 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 26 Jan 2021 13:01:57 +0000 Subject: [PATCH 091/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 23d80e8..c3dee73 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -501,6 +501,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf %changelog +* Tue Jan 26 2021 Fedora Release Engineering - 8.4p1-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Wed Dec 9 2020 Mattias Ellert - 8.4p1-3 - Based on openssh-8.4p1-4.fc33 From b77bb495c71231126f49d3cb4574dda51e4ef105 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 5 Feb 2021 15:06:38 +0100 Subject: [PATCH 092/146] Based on openssh-8.4p1-5.fc34 --- gsi-openssh.spec | 29 +- gsisshd.tmpfiles | 1 - openssh-6.6p1-ctr-cavstest.patch | 257 ------------- openssh-6.7p1-kdf-cavs.patch | 618 ------------------------------- openssh-8.0p1-pkcs11-uri.patch | 14 +- 5 files changed, 18 insertions(+), 901 deletions(-) delete mode 100644 gsisshd.tmpfiles delete mode 100644 openssh-6.6p1-ctr-cavstest.patch delete mode 100644 openssh-6.7p1-kdf-cavs.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index c3dee73..1e5583b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,12 +28,12 @@ %global libedit 1 %global openssh_ver 8.4p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -47,7 +47,6 @@ Source10: gsisshd.socket Source11: gsisshd.service Source12: gsisshd-keygen@.service Source13: gsisshd-keygen -Source14: gsisshd.tmpfiles Source15: gsisshd-keygen.target Source99: README.sshd-and-gsisshd @@ -91,10 +90,6 @@ Patch707: openssh-7.7p1-redhat.patch 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 @@ -270,8 +265,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %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 @@ -356,7 +349,7 @@ fi --datadir=%{_datadir}/gsissh \ --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 \ + --with-privsep-path=%{_datadir}/empty.sshd \ --disable-strip \ --without-zlib-version-check \ --with-ssl-engine \ @@ -396,7 +389,6 @@ 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/ @@ -413,14 +405,11 @@ 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 -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/gsissh.conf +install -d -m711 ${RPM_BUILD_ROOT}/%{_datadir}/empty.sshd 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 @@ -445,7 +434,7 @@ getent group ssh_keys >/dev/null || groupadd -r ssh_keys || : 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 || : + -s /sbin/nologin -r -d /usr/share/empty.sshd sshd 2> /dev/null || : %post server %systemd_post gsisshd.service gsisshd.socket @@ -480,7 +469,7 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man1/gsisftp.1* %files server -%dir %attr(0711,root,root) %{_var}/empty/gsisshd +%dir %attr(0711,root,root) %{_datadir}/empty.sshd %attr(0755,root,root) %{_sbindir}/gsisshd %attr(0755,root,root) %{_libexecdir}/gsissh/sftp-server %attr(0755,root,root) %{_libexecdir}/gsissh/sshd-keygen @@ -498,13 +487,15 @@ getent passwd sshd >/dev/null || \ %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) %{_tmpfilesdir}/gsissh.conf %changelog +* Fri Feb 05 2021 Mattias Ellert - 8.4p1-4 +- Based on openssh-8.4p1-5.fc34 + * Tue Jan 26 2021 Fedora Release Engineering - 8.4p1-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild -* Wed Dec 9 2020 Mattias Ellert - 8.4p1-3 +* Wed Dec 09 2020 Mattias Ellert - 8.4p1-3 - Based on openssh-8.4p1-4.fc33 * Mon Nov 30 2020 Mattias Ellert - 8.4p1-2 diff --git a/gsisshd.tmpfiles b/gsisshd.tmpfiles deleted file mode 100644 index e13d962..0000000 --- a/gsisshd.tmpfiles +++ /dev/null @@ -1 +0,0 @@ -d /var/empty/gsisshd 711 root root - diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch deleted file mode 100644 index 81da034..0000000 --- a/openssh-6.6p1-ctr-cavstest.patch +++ /dev/null @@ -1,257 +0,0 @@ -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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 \n" -+ " --key --mode \n" -+ " [--iv ] --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; -+} -+ diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch deleted file mode 100644 index f892bc8..0000000 --- a/openssh-6.7p1-kdf-cavs.patch +++ /dev/null @@ -1,618 +0,0 @@ -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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+ -+#include -+ -+#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 -+# -+# 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() { -+ -+ 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; diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index d55df23..0713ffe 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -2159,12 +2159,13 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -717,18 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -717,19 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2259,12 +2260,13 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -838,18 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -838,19 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); From b7578f68fde9c175fd76447de401957a994368c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Mar 2021 16:13:40 +0100 Subject: [PATCH 093/146] Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. --- gsi-openssh.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 1e5583b..26185f9 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -489,6 +489,10 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 8.4p1-4.1 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + * Fri Feb 05 2021 Mattias Ellert - 8.4p1-4 - Based on openssh-8.4p1-5.fc34 From d482358b1809ab68aac5016aa3078826394bf210 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 16 Mar 2021 19:39:34 +0100 Subject: [PATCH 094/146] Based on openssh-8.5p1-1.fc34 Fix issue with read-only ssh buffer during gssapi key exchange Add HPN patch --- .gitignore | 2 +- gsi-openssh.spec | 36 +- openssh-6.6.1p1-log-in-chroot.patch | 24 +- openssh-6.6.1p1-selinux-contexts.patch | 19 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 4 +- openssh-6.6p1-keycat.patch | 17 +- openssh-6.6p1-kuserok.patch | 2 +- openssh-6.6p1-privsep-selinux.patch | 8 +- openssh-6.7p1-coverity.patch | 6 +- openssh-7.1p2-audit-race-condition.patch | 14 +- openssh-7.2p2-k5login_directory.patch | 4 +- openssh-7.6p1-audit.patch | 95 +- openssh-7.6p1-cleanup-selinux.patch | 76 +- openssh-7.7p1-fips.patch | 4 +- openssh-7.7p1-gssapi-new-unique.patch | 20 +- openssh-7.8p1-role-mls.patch | 64 +- openssh-7.9p1-ssh-copy-id.patch | 27 - openssh-8.0p1-crypto-policies.patch | 106 +- openssh-8.0p1-gssapi-keyex.patch | 198 +- openssh-8.0p1-openssl-kdf.patch | 2 +- openssh-8.0p1-pkcs11-uri.patch | 193 +- openssh-8.0p1-sshbuf-readonly.patch | 152 + openssh-8.2p1-x11-without-ipv6.patch | 4 +- openssh-8.4p1-debian-compat.patch | 4 +- openssh-8.4p1-sandbox-seccomp.patch | 14 - openssh-8.4p1-ssh-copy-id.patch | 130 - ...gsissh.patch => openssh-8.5p1-gsissh.patch | 473 +-- openssh-8.5p1-hpn-15.2-modified.patch | 2587 +++++++++++++++++ sources | 6 +- 29 files changed, 3410 insertions(+), 881 deletions(-) delete mode 100644 openssh-7.9p1-ssh-copy-id.patch create mode 100644 openssh-8.0p1-sshbuf-readonly.patch delete mode 100644 openssh-8.4p1-sandbox-seccomp.patch delete mode 100644 openssh-8.4p1-ssh-copy-id.patch rename openssh-8.4p1-gsissh.patch => openssh-8.5p1-gsissh.patch (85%) create mode 100644 openssh-8.5p1-hpn-15.2-modified.patch diff --git a/.gitignore b/.gitignore index 149e338..7f20fba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /*.tar.bz2 /*.tar.gz /*.tar.gz.asc -/DJM-GPG-KEY.gpg +/*.gpg diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 26185f9..dc322ed 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,20 +27,20 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 8.4p1 -%global openssh_rel 4 +%global openssh_ver 8.5p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +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: DJM-GPG-KEY.gpg +Source3: gpgkey-736060BA.gpg Source7: gsisshd.sysconfig Source9: gsisshd@.service Source10: gsisshd.socket @@ -135,9 +135,6 @@ Patch950: openssh-7.5p1-sandbox.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) @@ -148,15 +145,19 @@ Patch964: openssh-8.0p1-openssl-kdf.patch 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 +# 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 -Patch98: openssh-8.4p1-gsissh.patch +Patch98: openssh-8.5p1-gsissh.patch + +# This is the HPN patch +# Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ +Patch99: openssh-8.5p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -167,6 +168,7 @@ BuildRequires: util-linux, groff BuildRequires: pam-devel BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel +BuildRequires: systemd-rpm-macros BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel @@ -286,14 +288,11 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %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 %patch200 -p1 -b .audit @@ -302,7 +301,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %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 @@ -447,7 +448,7 @@ getent passwd sshd >/dev/null || \ %files %license LICENCE -%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO +%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README HPN-README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO %attr(0755,root,root) %dir %{_sysconfdir}/gsissh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli %attr(0755,root,root) %{_bindir}/gsissh-keygen @@ -489,6 +490,11 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Mar 16 2021 Mattias Ellert - 8.5p1-1 +- Based on openssh-8.5p1-1.fc34 +- Fix issue with read-only ssh buffer during gssapi key exchange +- Add HPN patch + * Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 8.4p1-4.1 - Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index fa0717f..664e11a 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -2,14 +2,14 @@ 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(const 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) { ++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 @@ -30,10 +30,10 @@ 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 *); + const char *, void *); - void log_init(char *, LogLevel, SyslogFacility, int); -+void log_init_handler(char *, LogLevel, SyslogFacility, int, int); + 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); @@ -59,14 +59,14 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c ssh_signal(SIGHUP, &monitor_child_handler); ssh_signal(SIGTERM, &monitor_child_handler); @@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito + /* Log it */ 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); + fatal_f("invalid log level %u (corrupted message?)", level); +- sshlog(file, func, line, 0, level, NULL, "%s [preauth]", msg); ++ sshlog(file, func, line, 0, level, NULL, "%s [%s]", msg, pmonitor->m_state); sshbuf_free(logmsg); - free(msg); + free(file); @@ -1719,13 +1723,28 @@ monitor_init(void) mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); @@ -89,7 +89,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c + 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); ++ 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); diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 3a7193e..fa9d591 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -34,19 +34,19 @@ index 8f32464..18a2ca4 100644 + + contexts_path = selinux_openssh_contexts_path(); + if (contexts_path == NULL) { -+ debug3("%s: Failed to get the path to SELinux context", __func__); ++ debug3_f("Failed to get the path to SELinux context"); + return; + } + + if ((contexts_file = fopen(contexts_path, "r")) == NULL) { -+ debug("%s: Failed to open SELinux context file", __func__); ++ debug_f("Failed to open SELinux context file"); + return; + } + + if (fstat(fileno(contexts_file), &sb) != 0 || + sb.st_uid != 0 || (sb.st_mode & 022) != 0) { -+ logit("%s: SELinux context file needs to be owned by root" -+ " and not writable by anyone else", __func__); ++ logit_f("SELinux context file needs to be owned by root" ++ " and not writable by anyone else"); + fclose(contexts_file); + return; + } @@ -70,7 +70,7 @@ index 8f32464..18a2ca4 100644 + if (arg && strcmp(arg, "privsep_preauth") == 0) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { -+ debug("%s: privsep_preauth is empty", __func__); ++ debug_f("privsep_preauth is empty"); + fclose(contexts_file); + return; + } @@ -80,8 +80,8 @@ index 8f32464..18a2ca4 100644 + fclose(contexts_file); + + if (preauth_context == NULL) { -+ debug("%s: Unable to find 'privsep_preauth' option in" -+ " SELinux context file", __func__); ++ debug_f("Unable to find 'privsep_preauth' option in" ++ " SELinux context file"); + return; + } + @@ -101,10 +101,11 @@ index 22ea8ef..1fc963d 100644 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__, ++ debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) - switchlog("%s: setcon %s from %s failed with %s", __func__, + do_log2(log_level, "%s: setcon %s from %s failed with %s", + __func__, newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 01ea156..6ee2535 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -39,8 +39,8 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -418,7 +421,7 @@ typedef enum { - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, - sHostKeyAlgorithms, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 9e71efe..2aa14bd 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,10 +1,10 @@ -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 +diff -up openssh/misc.c.keycat openssh/misc.c +--- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 ++++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 +@@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw + error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } - +#ifdef WITH_SELINUX + if (sshd_selinux_setup_env_variables() < 0) { + error ("failed to copy environment: %s", @@ -12,10 +12,9 @@ diff -up openssh/auth.c.keycat openssh/misc.c + _exit(127); + } +#endif -+ - execve(av[0], av, child_env); - error("%s exec \"%s\": %s", tag, command, strerror(errno)); - _exit(127); + if (env != NULL) + execve(av[0], av, env); + else diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat --- openssh/HOWTO.ssh-keycat.keycat 2015-06-24 10:57:50.157849608 +0200 +++ openssh/HOWTO.ssh-keycat 2015-06-24 10:57:50.157849608 +0200 diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 5009e2a..407ff4c 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -193,7 +193,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -399,7 +402,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 3d4c287..8047fc3 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -13,7 +13,7 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- --- 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__); + debug3_f("done"); } +void @@ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- + return; + + if (getexeccon((security_context_t *)&ctx) != 0) { -+ logit("%s: getexeccon failed with %s", __func__, strerror(errno)); ++ 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("%s: setexeccon failed with %s", __func__, strerror(errno)); ++ fatal_f("setexeccon failed with %s", strerror(errno)); + if (setcon(ctx) != 0) -+ fatal("%s: setcon failed with %s", __func__, strerror(errno)); ++ fatal_f("setcon failed with %s", strerror(errno)); + freecon(ctx); + } +} diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 3f34464..5b75dda 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -34,7 +34,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c @@ -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__); + error_f("cannot allocate fds for pty"); - if (tmp1 > 0) + if (tmp1 >= 0) close(tmp1); @@ -120,11 +120,11 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c - 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__); + debug2_f("reading"); } @@ -518,7 +518,7 @@ server_request_tun(void) - debug("%s: invalid tun", __func__); + debug_f("invalid tun"); goto done; } - if (auth_opts->force_tun_device != -1) { diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index de70ff5..b5895f7 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -13,33 +13,33 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c + struct sshbuf *m; + int r, ret = 0; + -+ debug3("%s: entering", __func__); ++ debug3_f("entering"); + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + do { + blen = atomicio(read, fdin, buf, sizeof(buf)); + if (blen == 0) /* closed pipe */ + break; + if (blen != sizeof(buf)) { -+ error("%s: Failed to read the buffer from child", __func__); ++ error_f("Failed to read the buffer from child"); + ret = -1; + break; + } + + msg_len = get_u32(buf); + if (msg_len > 256 * 1024) -+ fatal("%s: read: bad msg_len %d", __func__, msg_len); ++ fatal_f("read: bad msg_len %d", msg_len); + sshbuf_reset(m); + if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) { -+ error("%s: Failed to read the the buffer content from the child", __func__); ++ error_f("Failed to read the the buffer content from the child"); + 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("%s: Failed to write the message to the monitor", __func__); ++ error_f("Failed to write the message to the monitor"); + ret = -1; + break; + } diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 242294a..80e7678 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -49,7 +49,7 @@ index a7c0c5f..df8cc9a 100644 + int ret = 0; + + ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory); -+ debug3("%s: k5login_directory = %s (rv=%d)", __func__, k5login_directory, ret); ++ debug3_f("k5login_directory = %s (rv=%d)", 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. @@ -64,7 +64,7 @@ index a7c0c5f..df8cc9a 100644 + k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "", + pw->pw_name); + } -+ debug("%s: Checking existence of file %s", __func__, file); ++ debug_f("Checking existence of file %s", file); - snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); return access(file, F_OK) == 0; diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 35a1a8a..85d0650 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -943,7 +943,7 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) { - error("%s: unsupported cipher %s", __func__, name); + error_f("unsupported cipher %s", name); free(name); @@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma { @@ -957,7 +957,7 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) { - error("%s: unsupported MAC %s", __func__, name); + error_f("unsupported MAC %s", name); free(name); @@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma } @@ -1094,7 +1094,7 @@ diff -up openssh/Makefile.in.audit openssh/Makefile.in --- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 +++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 @@ -109,7 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o @@ -1172,15 +1172,15 @@ diff -up openssh/monitor.c.audit openssh/monitor.c @@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) - fatal("%s: bad key, not previously allowed", __func__); + fatal_f("bad key, not previously allowed"); + if (type != key_blobtype) -+ fatal("%s: bad key type", __func__); ++ fatal_f("bad key type"); /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1470,25 +1491,28 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1470,27 +1491,30 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: - valid_data = monitor_valid_userblob(data, datalen); + valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; + ret = user_key_verify(ssh, key, signature, signaturelen, data, + datalen, sigalg, ssh->compat, &sig_details); @@ -1198,15 +1198,17 @@ diff -up openssh/monitor.c.audit openssh/monitor.c break; } if (!valid_data) - fatal("%s: bad signature data blob", __func__); + fatal_f("bad %s signature data blob", + key_blobtype == MM_USERKEY ? "userkey" : + (key_blobtype == MM_HOSTKEY ? "hostkey" : "unknown")); if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); + fatal_f("sshkey_fingerprint failed"); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, + debug3_f("%s %p signature %s%s%s", auth_method, key, (ret == 0) ? "verified" : "unverified", (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); @@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session @@ -1216,14 +1218,14 @@ diff -up openssh/monitor.c.audit openssh/monitor.c -mm_session_close(Session *s) +mm_session_close(struct ssh *ssh, Session *s) { - debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); + debug3_f("session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) { - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); + debug3_f("tty %s ptyfd %d", s->tty, s->ptyfd); session_pty_cleanup2(s); } +#ifdef SSH_AUDIT_EVENTS + if (s->command != NULL) { -+ debug3("%s: command %d", __func__, s->command_handle); ++ debug3_f("command %d", s->command_handle); + session_end_command2(ssh, s); + } +#endif @@ -1237,11 +1239,11 @@ diff -up openssh/monitor.c.audit openssh/monitor.c - mm_session_close(s); + mm_session_close(ssh, s); if ((r = sshbuf_put_u32(m, 0)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); @@ -1628,7 +1658,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) - mm_session_close(s); + mm_session_close(ssh, s); @@ -1271,7 +1273,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c - audit_run_command(cmd); + s = session_new(); + if (s == NULL) -+ fatal("%s: error allocating a session", __func__); ++ fatal_f("error allocating a session"); + s->command = cmd; +#ifdef SSH_AUDIT_EVENTS + s->command_handle = audit_run_command(ssh, cmd); @@ -1293,15 +1295,15 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + u_char *cmd = NULL; + Session *s; + -+ debug3("%s entering", __func__); ++ debug3_f("entering"); + if ((r = sshbuf_get_u32(m, &handle)) != 0 || + (r = sshbuf_get_string(m, &cmd, &len)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + s = session_by_id(handle); + if (s == NULL || s->ttyfd != -1 || s->command == NULL || + strcmp(s->command, cmd) != 0) -+ fatal("%s: invalid handle", __func__); ++ fatal_f("invalid handle"); + mm_session_close(ssh, s); free(cmd); return (0); @@ -1311,13 +1313,13 @@ diff -up openssh/monitor.c.audit openssh/monitor.c mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { + struct sshbuf *m; - debug3("%s: Waiting for new keys", __func__); + debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) @@ -1774,6 +1842,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); - debug3("%s: GOT new keys", __func__); + debug3_f("GOT new keys"); + +#ifdef SSH_AUDIT_EVENTS + m = sshbuf_new(); @@ -1345,7 +1347,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + int what, r; + + if ((r = sshbuf_get_u32(m, &what)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + audit_unsupported_body(ssh, what); + @@ -1370,10 +1372,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + (r = sshbuf_get_cstring(m, &compress, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &pfs, NULL)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (pid_t) tmp; + + audit_kex_body(ssh, ctos, cipher, mac, compress, pfs, pid, uid); @@ -1398,10 +1400,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + + if ((r = sshbuf_get_u32(m, &ctos)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (uid_t) tmp; + + audit_session_key_free_body(ssh, ctos, pid, uid); @@ -1423,10 +1425,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + + if ((r = sshbuf_get_cstring(m, &fp, &len)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (uid_t) tmp; + + audit_destroy_sensitive_data(ssh, fp, pid, uid); @@ -1470,7 +1472,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c @@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); - if ((r = sshkey_puts(key, m)) != 0 || + if ((r = sshbuf_put_u32(m, type)) != 0 || + (r = sshkey_puts(key, m)) != 0 || @@ -1522,7 +1524,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); + + if ((r = sshbuf_get_u32(m, &handle)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + sshbuf_free(m); + + return (handle); @@ -1534,13 +1536,13 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + int r; + struct sshbuf *m; + -+ debug3("%s entering command %s", __func__, command); ++ debug3_f("entering command %s", command); + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, handle)) != 0 || + (r = sshbuf_put_cstring(m, command)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, m); sshbuf_free(m); @@ -1558,9 +1560,9 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, what)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED, @@ -1577,7 +1579,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_cstring(m, cipher)) != 0 || + (r = sshbuf_put_cstring(m, (mac ? mac : ""))) != 0 || @@ -1585,7 +1587,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + (r = sshbuf_put_cstring(m, fps)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX, @@ -1601,11 +1603,11 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, @@ -1620,11 +1622,11 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_cstring(m, fp)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); + sshbuf_free(m); @@ -1903,7 +1905,7 @@ diff -up openssh/session.c.audit openssh/session.c + if (s->used) + return s; + } -+ debug("%s: unknown id %d", __func__, id); ++ debug_f("unknown id %d", id); + session_dump(); + return NULL; +} @@ -2115,7 +2117,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -400,14 +437,26 @@ destroy_sensitive_data(void) +@@ -400,20 +437,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2142,9 +2144,8 @@ diff -up openssh/sshd.c.audit openssh/sshd.c + fp = NULL; if ((r = sshkey_from_private( sensitive_data.host_keys[i], &tmp)) != 0) - fatal("could not demote host %s key: %s", -@@ -415,6 +464,12 @@ demote_sensitive_data(void) - ssh_err(r)); + fatal_r(r, "could not demote host %s key", + sshkey_type(sensitive_data.host_keys[i])); sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; + if (fp != NULL) { @@ -2254,7 +2255,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && @@ -2414,9 +2482,16 @@ cleanup_exit(int i) - pmonitor->m_pid, strerror(errno)); + } } } + is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 08cd349..f7cd50f 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -2,9 +2,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c --- openssh/auth2-pubkey.c.refactor 2019-04-04 13:19:12.188821236 +0200 +++ openssh/auth2-pubkey.c 2019-04-04 13:19:12.276822078 +0200 @@ -72,6 +72,9 @@ + + /* import */ extern ServerOptions options; - extern u_char *session_id2; - extern u_int session_id2_len; +extern int inetd_flag; +extern int rexeced_flag; +extern Authctxt *the_authctxt; @@ -12,59 +12,59 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c 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, + if ((pid = subprocess("AuthorizedPrincipalsCommand", command, ac, av, &f, -- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) -+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, +- runas_pw, temporarily_use_uid, restore_uid)) == 0) ++ runas_pw, temporarily_use_uid, restore_uid, + (inetd_flag && !rexeced_flag), the_authctxt)) == 0) goto out; uid_swapped = 1; @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss - - if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, + if ((pid = subprocess("AuthorizedKeysCommand", command, ac, av, &f, -- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) -+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, +- runas_pw, temporarily_use_uid, restore_uid)) == 0) ++ runas_pw, temporarily_use_uid, restore_uid, + (inetd_flag && !rexeced_flag), the_authctxt)) == 0) 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 +diff -up openssh/misc.c.refactor openssh/misc.c +--- openssh/misc.c.refactor 2019-04-04 13:19:12.235821686 +0200 ++++ openssh/misc.c 2019-04-04 13:19:12.276822078 +0200 @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh * - */ pid_t - subprocess(const char *tag, 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) + 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; @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw + _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 -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 +diff -up openssh/misc.h.refactor openssh/misc.h +--- openssh/misc.h.refactor 2019-04-04 13:19:12.251821839 +0200 ++++ openssh/misc.h 2019-04-04 13:19:12.276822078 +0200 @@ -235,7 +235,7 @@ struct passwd *fakepw(void); - #define SSH_SUBPROCESS_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 *); + #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 -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 @@ -145,7 +145,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa char *role; @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it - debug3("%s: setting execution context", __func__); + debug3_f("setting execution context"); - ssh_selinux_get_role_level(&role, &reqlvl); + ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt); @@ -203,10 +203,10 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa + if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) { switch (security_getenforce()) { case -1: - fatal("%s: security_getenforce() failed", __func__); + fatal_f("security_getenforce() failed"); @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw - debug3("%s: setting execution context", __func__); + 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); @@ -269,3 +269,15 @@ diff -up openssh/sshd.c.refactor openssh/sshd.c #endif #ifdef USE_PAM if (options.use_pam) { +diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c +--- openssh/sshconnect.c.refactor 2021-02-24 00:12:03.065325046 +0100 ++++ openssh/sshconnect.c 2021-02-24 00:12:12.126449544 +0100 +@@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h + + if ((pid = subprocess(tag, command, ac, av, &f, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| +- 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/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 19f3d97..f199fb2 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -165,7 +165,7 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h + /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ - "ecdsa-sha2-nistp256," \ + "ssh-ed25519," \ 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 @@ -416,7 +416,7 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c 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__); ++ 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/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 506c79a..3b9ef3a 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -151,7 +151,7 @@ index a5a81ed2..63f877f2 100644 +ssh_krb5_expand_template(char **result, const char *template) { + char *p_n, *p_o, *r, *tmp_template; + -+ debug3("%s: called, template = %s", __func__, template); ++ debug3_f("called, template = %s", template); + if (template == NULL) + return -1; + @@ -179,7 +179,7 @@ index a5a81ed2..63f877f2 100644 + } else { + p_o = strchr(p_n, '}') + 1; + *p_o = '\0'; -+ debug("%s: unsupported token %s in %s", __func__, p_n, template); ++ debug_f("unsupported token %s in %s", p_n, template); + /* unknown token, fallback to the default */ + goto cleanup; + } @@ -207,7 +207,7 @@ index a5a81ed2..63f877f2 100644 + int ret = 0; + char *value = NULL; + -+ debug3("%s: called", __func__); ++ debug3_f("called"); + ret = krb5_get_profile(ctx, &p); + if (ret) + return ret; @@ -218,7 +218,7 @@ index a5a81ed2..63f877f2 100644 + + ret = ssh_krb5_expand_template(ccname, value); + -+ debug3("%s: returning with ccname = %s", __func__, *ccname); ++ debug3_f("returning with ccname = %s", *ccname); + return ret; +} + @@ -242,7 +242,7 @@ index a5a81ed2..63f877f2 100644 - logit("mkstemp(): %.100s", strerror(oerrno)); - return oerrno; - } -+ debug3("%s: called", __func__); ++ debug3_f("called"); + if (need_environment) + *need_environment = 0; + ret = ssh_krb5_get_cctemplate(ctx, &ccname); @@ -283,7 +283,7 @@ index a5a81ed2..63f877f2 100644 - close(tmpfd); - return (krb5_cc_resolve(ctx, ccname, ccache)); -+ debug3("%s: setting default ccname to %s", __func__, ccname); ++ debug3_f("setting default ccname to %s", ccname); + /* set the default with already expanded user IDs */ + ret = krb5_cc_set_default_name(ctx, ccname); + if (ret) @@ -304,13 +304,13 @@ index a5a81ed2..63f877f2 100644 + * a primary cache for this collection, if it supports that (non-FILE) + */ + if (krb5_cc_support_switch(ctx, type)) { -+ debug3("%s: calling cc_new_unique(%s)", __func__, ccname); ++ debug3_f("calling cc_new_unique(%s)", ccname); + ret = krb5_cc_new_unique(ctx, type, NULL, ccache); + free(type); + if (ret) + return ret; + -+ debug3("%s: calling cc_switch()", __func__); ++ debug3_f("calling cc_switch()"); + return krb5_cc_switch(ctx, *ccache); + } else { + /* Otherwise, we can not create a unique ccname here (either @@ -318,7 +318,7 @@ index a5a81ed2..63f877f2 100644 + * collections + */ + free(type); -+ debug3("%s: calling cc_resolve(%s)", __func__, ccname); ++ debug3_f("calling cc_resolve(%s)", ccname); + return (krb5_cc_resolve(ctx, ccname, ccache)); + } } @@ -513,7 +513,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c options->gss_authentication = 0; if (options->gss_keyex == -1) @@ -447,7 +450,8 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sChallengeResponseAuthentication, diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index add4727..a6c3bae 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -52,7 +52,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c gss_buffer_desc mic, gssbuf; const char *displayname; @@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mic.value = p; mic.length = len; - ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, @@ -63,7 +63,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c +#endif + micuser = authctxt->user; + ssh_gssapi_buildmic(b, micuser, authctxt->service, - "gssapi-with-mic"); + "gssapi-with-mic", ssh->kex->session_id); if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) @@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple @@ -80,7 +80,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c +++ 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_string(b, session_id2, session_id2_len)) != 0 || + if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || +#ifdef WITH_SELINUX + (authctxt->role @@ -224,8 +224,8 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c + monitor_permit_authentications(1); + + if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ debug3("%s: role=%s", __func__, authctxt->role); ++ fatal_f("buffer error: %s", ssh_err(r)); ++ debug3_f("role=%s", authctxt->role); + + if (strlen(authctxt->role) == 0) { + free(authctxt->role); @@ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c @@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse userstyle"); + if ((s = strchr(cp, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, @@ -269,7 +269,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c @@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse userstyle"); + if ((s = strchr(p, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, @@ -305,12 +305,12 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c + int r; + struct sshbuf *m; + -+ debug3("%s entering", __func__); ++ debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_f("buffer error: %s", ssh_err(r)); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m); + + sshbuf_free(m); @@ -357,7 +357,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por -void -ssh_selinux_setup_exec_context(char *pwname) -{ -- security_context_t user_ctx = NULL; +- char *user_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; @@ -393,7 +393,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por - user_ctx = ssh_selinux_getctxbyname(pwname); + if (getexeccon(&user_ctx) != 0) { -+ error("%s: getexeccon: %s", __func__, strerror(errno)); ++ error_f("getexeccon: %s", strerror(errno)); + goto out; + } + @@ -418,7 +418,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,425 @@ +@@ -0,0 +1,421 @@ +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2014 Petr Lautrbach @@ -530,7 +530,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + access_vector_t bit; + security_class_t class; + -+ debug("%s: src:%s dst:%s", __func__, src, dst); ++ debug_f("src:%s dst:%s", src, dst); + class = string_to_security_class("context"); + if (!class) { + error("string_to_security_class failed to translate security class context"); @@ -692,7 +692,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + /* we actually don't change level */ + reqlvl = ""; + -+ debug("%s: current connection level '%s'", __func__, reqlvl); ++ debug_f("current connection level '%s'", reqlvl); + + } + @@ -720,8 +720,8 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + } + } + if (r != 0) { -+ error("%s: Failed to get default SELinux security " -+ "context for %s", __func__, pwname); ++ error_f("Failed to get default SELinux security " ++ "context for %s", pwname); + } + +#ifdef HAVE_GETSEUSERBYNAME @@ -746,7 +746,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + char *use_current; + int rv; + -+ debug3("%s: setting execution context", __func__); ++ debug3_f("setting execution context"); + + ssh_selinux_get_role_level(&role, &reqlvl); + @@ -783,32 +783,30 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (sshd_selinux_setup_pam_variables()) { + switch (security_getenforce()) { + case -1: -+ fatal("%s: security_getenforce() failed", __func__); ++ fatal_f("security_getenforce() failed"); + case 0: -+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", -+ __func__); ++ error_f("SELinux PAM variable setup failure. Continuing in permissive mode."); + break; + default: -+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", -+ __func__); ++ fatal_f("SELinux PAM variable setup failure. Aborting connection."); + } + } + return; + } + -+ debug3("%s: setting execution context", __func__); ++ debug3_f("setting execution context"); + + r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); + if (r >= 0) { + r = setexeccon(user_ctx); + if (r < 0) { -+ error("%s: Failed to set SELinux execution context %s for %s", -+ __func__, user_ctx, pwname); ++ error_f("Failed to set SELinux execution context %s for %s", ++ user_ctx, pwname); + } +#ifdef HAVE_SETKEYCREATECON + else if (setkeycreatecon(user_ctx) < 0) { -+ error("%s: Failed to set SELinux keyring creation context %s for %s", -+ __func__, user_ctx, pwname); ++ error_f("Failed to set SELinux keyring creation context %s for %s", ++ user_ctx, pwname); + } +#endif + } @@ -823,14 +821,12 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (r < 0) { + switch (security_getenforce()) { + case -1: -+ fatal("%s: security_getenforce() failed", __func__); ++ fatal_f("security_getenforce() failed"); + case 0: -+ error("%s: SELinux failure. Continuing in permissive mode.", -+ __func__); ++ error_f("ELinux failure. Continuing in permissive mode."); + break; + default: -+ fatal("%s: SELinux failure. Aborting connection.", -+ __func__); ++ fatal_f("SELinux failure. Aborting connection."); + } + } + if (user_ctx != NULL && user_ctx != default_ctx) @@ -838,7 +834,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (default_ctx != NULL) + freecon(default_ctx); + -+ debug3("%s: done", __func__); ++ debug3_f("done"); +} + +#endif diff --git a/openssh-7.9p1-ssh-copy-id.patch b/openssh-7.9p1-ssh-copy-id.patch deleted file mode 100644 index 24598b8..0000000 --- a/openssh-7.9p1-ssh-copy-id.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 22bfdcf060b632b5a6ff603f8f42ff166c211a66 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -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 - - diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index fe2f7cd..813b7ac 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ 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 +@@ -359,14 +359,13 @@ or .Qq *.c.example.com domains. .It Cm CASignatureAlgorithms @@ -14,19 +14,15 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 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 +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, +-ecdsa-sha2-nistp521,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 default), the check will not be executed. .It Cm Ciphers +The default is handled system-wide by @@ -133,8 +129,8 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 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. + 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 . @@ -179,56 +175,57 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 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 +@@ -1394,37 +1387,25 @@ instead of continuing to execute and pas The default is .Cm no . - .It Cm PubkeyAcceptedKeyTypes + .It Cm PubkeyAcceptedAlgorithms +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. + 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 key types after it will be appended to the default +-character, then the algorithms 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 ++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 key types (including wildcards) will be removed + 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 key types will be placed at the head of the + 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-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-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-rsa-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, --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 . + The list of available signature algorithms may also be obtained using + .Qq ssh -Q PubkeyAcceptedAlgorithms . 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 +@@ -375,14 +375,13 @@ If the argument is then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -241,16 +238,13 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 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 +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, +-ecdsa-sha2-nistp521,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 . @@ -295,7 +289,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 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 +@@ -681,21 +679,22 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -326,11 +320,9 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 -.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 + .It Cm HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased +@@ -793,26 +793,13 @@ is specified, the location of the socket .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -339,26 +331,27 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . +.Pp - Specifies the host key algorithms + 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-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-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-rsa-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, --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 + The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts @@ -943,20 +931,25 @@ Specifies whether to look at .k5login fi @@ -392,7 +385,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp .Bl -item -compact -offset indent @@ -988,15 +981,6 @@ ecdh-sha2-nistp521 - sntrup4591761x25519-sha512@tinyssh.org + sntrup761x25519-sha512@openssh.com .El .Pp -The default is: @@ -408,8 +401,8 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .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. + 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 . @@ -454,49 +447,50 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1480,36 +1460,25 @@ or equivalent.) +@@ -1480,37 +1460,25 @@ or equivalent.) The default is .Cm yes . - .It Cm PubkeyAcceptedKeyTypes + .It Cm PubkeyAcceptedAlgorithms +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. + 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 key types will be appended to the default set +-character, then the specified algorithms will be appended to the default set -instead of replacing them. -+character, then the specified key types will be appended to the built-in ++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 key types (including wildcards) will be removed + 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 key types will be placed at the head of the + 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-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-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-rsa-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, --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 . + The list of available signature algorithms may also be obtained using + .Qq ssh -Q PubkeyAcceptedAlgorithms . diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 770e99e..2c29486 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -5,7 +5,7 @@ index e7549470..b68c1710 100644 @@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ - sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o @@ -17,7 +17,7 @@ index e7549470..b68c1710 100644 - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/auth.c b/auth.c index 086b8ebb..687c57b4 100644 @@ -138,7 +138,7 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.29 2018/07/31 03:10:27 djm Exp $ */ + /* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -165,19 +165,19 @@ index 9351e042..d6446c0c 100644 + + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) -+ fatal("%s: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "parsing"); + + if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + mic.value = p; + mic.length = len; + + ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, -+ "gssapi-keyex"); ++ "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ fatal_f("sshbuf_mutable_ptr failed"); + gssbuf.length = sshbuf_len(b); + + /* gss_kex_context is NULL with privsep, so we can't check it here */ @@ -197,7 +197,7 @@ index 9351e042..d6446c0c 100644 * 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) if ((r = sshpkt_get_end(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse packet"); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, @@ -441,7 +441,7 @@ index d56257b4..763a63ff 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-genr.c,v 1.26 2018/07/10 09:13:30 djm Exp $ */ + /* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */ /* - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -449,7 +449,7 @@ index d56257b4..763a63ff 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -41,12 +41,36 @@ +@@ -41,9 +41,33 @@ #include "sshbuf.h" #include "log.h" #include "ssh2.h" @@ -461,9 +461,6 @@ index d56257b4..763a63ff 100644 #include "ssh-gss.h" - extern u_char *session_id2; - extern u_int session_id2_len; - +typedef struct { + char *encoded; + gss_OID oid; @@ -486,7 +483,7 @@ index d56257b4..763a63ff 100644 /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,162 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -62,6 +86,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -548,7 +545,7 @@ index d56257b4..763a63ff 100644 + (gss_supported->count + 1)); + + if ((buf = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + oidpos = 0; + s = cp = xstrdup(kex); @@ -565,8 +562,7 @@ index d56257b4..763a63ff 100644 + gss_supported->elements[i].elements, + gss_supported->elements[i].length)) != 0 || + (r = ssh_digest_final(md, digest, sizeof(digest))) != 0) -+ fatal("%s: digest failed: %s", __func__, -+ ssh_err(r)); ++ fatal_fr(r, "digest failed"); + ssh_digest_free(md); + md = NULL; + @@ -581,12 +577,10 @@ index d56257b4..763a63ff 100644 + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && + (r = sshbuf_put_u8(buf, ',')) != 0) -+ fatal("%s: sshbuf_put_u8 error: %s", -+ __func__, ssh_err(r)); ++ fatal_fr(r, "sshbuf_put_u8 error"); + if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || + (r = sshbuf_put(buf, encoded, enclen)) != 0) -+ fatal("%s: sshbuf_put error: %s", -+ __func__, ssh_err(r)); ++ fatal_fr(r, "sshbuf_put error"); + } + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); @@ -599,7 +593,7 @@ index d56257b4..763a63ff 100644 + gss_enc2oid[oidpos].encoded = NULL; + + if ((mechs = sshbuf_dup_string(buf)) == NULL) -+ fatal("%s: sshbuf_dup_string failed", __func__); ++ fatal_f("sshbuf_dup_string failed"); + + sshbuf_free(buf); + @@ -721,7 +715,7 @@ index d56257b4..763a63ff 100644 + void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, - const char *context) + const char *context, const struct sshbuf *session_id) @@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } @@ -1123,10 +1117,10 @@ index ab3a15f0..6ce56e92 100644 + + if (gssapi_client.store.data != NULL) { + if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ debug_f("krb5_cc_resolve(): %.100s", + krb5_get_err_text(gssapi_client.store.data, problem)); + } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug("%s: krb5_cc_destroy(): %.100s", __func__, ++ debug_f("krb5_cc_destroy(): %.100s", + krb5_get_err_text(gssapi_client.store.data, problem)); + } else { + krb5_free_context(gssapi_client.store.data); @@ -1375,7 +1369,7 @@ index ce85f043..574c7609 100644 @@ -698,6 +755,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); - free(kex->session_id); + sshbuf_free(kex->session_id); +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ @@ -1389,7 +1383,7 @@ index a5ae6ac0..fe714141 100644 @@ -102,6 +102,15 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, - KEX_KEM_SNTRUP4591761X25519_SHA512, + KEX_KEM_SNTRUP761X25519_SHA512, +#ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, @@ -1498,7 +1492,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,606 @@ +@@ -0,0 +1,599 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1597,7 +1591,7 @@ index 00000000..f6e1405e + r = kex_c25519_keypair(kex); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + } + if (r != 0) + return r; @@ -1785,7 +1779,7 @@ index 00000000..f6e1405e + server_blob, + shared_secret, + hash, &hashlen)) != 0) -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + + gssbuf.value = hash; + gssbuf.length = hashlen; @@ -2074,13 +2068,6 @@ index 00000000..f6e1405e + + gss_release_buffer(&min_status, &msg_tok); + -+ /* save session id */ -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); -+ } -+ + if (kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + @@ -2202,12 +2189,12 @@ index 00000000..60bc02de + free(mechs); + } + -+ debug2("%s: Identifying %s", __func__, kex->name); ++ debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2("%s: Acquiring credentials", __func__); ++ debug2_f("Acquiring credentials"); + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); @@ -2242,7 +2229,7 @@ index 00000000..60bc02de + &shared_secret); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + } + if (r != 0) + goto out; @@ -2398,12 +2385,12 @@ index 00000000..60bc02de + if ((mechs = ssh_gssapi_server_mechanisms())) + free(mechs); + -+ debug2("%s: Identifying %s", __func__, kex->name); ++ debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2("%s: Acquiring credentials", __func__); ++ debug2_f("Acquiring credentials"); + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); @@ -2641,44 +2628,44 @@ index 2ce89fe9..ebf76c7f 100644 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); @@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif +# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } +# endif #endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; @@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = sshbuf_get_string(m, &p, &len)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); @@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "ssh_gssapi_get_buffer_desc"); @@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); @@ -2692,9 +2679,9 @@ index 2ce89fe9..ebf76c7f 100644 int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) @@ -2707,13 +2694,13 @@ index 2ce89fe9..ebf76c7f 100644 const char *displayname; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + if ((r = sshbuf_get_u32(m, &kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); @@ -2721,7 +2708,7 @@ index 2ce89fe9..ebf76c7f 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) @@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) - debug3("%s: sending result %d", __func__, authenticated); + debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - auth_method = "gssapi-with-mic"; @@ -2733,7 +2720,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1921,5 +1958,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1921,5 +1958,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2749,16 +2736,15 @@ index 2ce89fe9..ebf76c7f 100644 + int r; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); + + if ((r = sshbuf_get_string(m, &p, &len)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + data.value = p; + data.length = len; + /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ + if (data.length != 20 && data.length != 32 && data.length != 64) -+ fatal("%s: data length incorrect: %d", __func__, -+ (int) data.length); ++ fatal_f("data length incorrect: %d", (int) data.length); + + /* Save the session ID on the first time around */ + if (session_id2_len == 0) { @@ -2774,7 +2760,7 @@ index 2ce89fe9..ebf76c7f 100644 + + if ((r = sshbuf_put_u32(m, major)) != 0 || + (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); + @@ -2795,12 +2781,12 @@ index 2ce89fe9..ebf76c7f 100644 + int r, ok; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); + + if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + ok = ssh_gssapi_update_creds(&store); + @@ -2810,7 +2796,7 @@ index 2ce89fe9..ebf76c7f 100644 + + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); + @@ -2847,14 +2833,14 @@ index 001a8fa1..6edb509a 100644 int r, authenticated = 0; if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); 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) - debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); + debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } + @@ -2866,16 +2852,16 @@ index 001a8fa1..6edb509a 100644 + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); + + if ((r = sshbuf_get_u32(m, &major)) != 0 || + (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + @@ -2889,7 +2875,7 @@ index 001a8fa1..6edb509a 100644 + int r, ok; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + if ((r = sshbuf_put_cstring(m, + store->filename ? store->filename : "")) != 0 || @@ -2897,13 +2883,13 @@ index 001a8fa1..6edb509a 100644 + store->envvar ? store->envvar : "")) != 0 || + (r = sshbuf_put_cstring(m, + store->envval ? store->envval : "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); + + if ((r = sshbuf_get_u32(m, &ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + @@ -3124,7 +3110,7 @@ index 70f5f73f..191575a1 100644 options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -531,6 +543,7 @@ typedef enum { - sHostKeyAlgorithms, + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, @@ -3246,7 +3232,7 @@ index 36180d07..70dd3665 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 djm Exp $ */ + /* $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. @@ -3332,7 +3318,7 @@ index 36180d07..70dd3665 100644 @@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(struct sshbuf *, const char *, - const char *, const char *); + const char *, const char *, const struct sshbuf *); -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); @@ -3382,7 +3368,7 @@ index 60de6087..db5c65bc 100644 +.It GSSAPITrustDns .It HashKnownHosts .It Host - .It HostbasedAuthentication + .It HostbasedAcceptedAlgorithms @@ -579,6 +585,8 @@ flag), (supported message integrity codes), .Ar kex @@ -3526,9 +3512,9 @@ index af00fb30..03bc87eb 100644 + xxx_host = host; xxx_hostaddr = hostaddr; - + xxx_conn_info = cinfo; @@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - compat_pkalg_proposal(options.hostkeyalgorithms); + compat_pkalg_proposal(ssh, options.hostkeyalgorithms); } +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3588,7 +3574,7 @@ index af00fb30..03bc87eb 100644 +# endif +#endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; - ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3604,7 +3590,7 @@ index af00fb30..03bc87eb 100644 /* remove ext-info from the KEX proposals for rekeying */ myproposal[PROPOSAL_KEX_ALGS] = - compat_kex_proposal(options.kex_algorithms); + 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 */ @@ -3616,7 +3602,7 @@ index af00fb30..03bc87eb 100644 + } +#endif if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) - fatal("kex_prop2buf: %s", ssh_err(r)); + fatal_r(r, "kex_prop2buf"); @@ -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 *); @@ -3714,13 +3700,13 @@ index af00fb30..03bc87eb 100644 + } + + if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex"); ++ "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ fatal_f("sshbuf_mutable_ptr failed"); + gssbuf.length = sshbuf_len(b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { @@ -3734,7 +3720,7 @@ index af00fb30..03bc87eb 100644 + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || + (r = sshpkt_send(ssh)) != 0) -+ fatal("%s: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "parsing"); + + sshbuf_free(b); + gss_release_buffer(&ms, &mic); @@ -3751,11 +3737,11 @@ index 60b2aaf7..d92f03aa 100644 +++ b/sshd.c @@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) } - debug3("%s: sent %u hostkeys", __func__, nkeys); + debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) -- fatal("%s: no hostkeys", __func__); +- fatal_f("no hostkeys"); - if ((r = sshpkt_send(ssh)) != 0) -+ debug3("%s: no hostkeys", __func__); ++ debug3_f("no hostkeys"); + else if ((r = sshpkt_send(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); @@ -3772,7 +3758,7 @@ index 60b2aaf7..d92f03aa 100644 } @@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - list_hostkey_types()); + ssh, list_hostkey_types()); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + { @@ -3818,7 +3804,7 @@ index 60b2aaf7..d92f03aa 100644 + /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) - fatal("kex_setup: %s", ssh_err(r)); + fatal_r(r, "kex_setup"); @@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; @@ -3837,7 +3823,7 @@ index 60b2aaf7..d92f03aa 100644 +# endif +#endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; diff --git a/sshd_config b/sshd_config index 19b7c91a..2c48105f 100644 @@ -3898,9 +3884,9 @@ index 70ccea44..f6b41a2f 100644 +.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 HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. + .It Cm HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased + authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c index 57995ee6..fd5b7724 100644 --- a/sshkey.c diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch index 1db95c3..5d76a4f 100644 --- a/openssh-8.0p1-openssl-kdf.patch +++ b/openssh-8.0p1-openssl-kdf.patch @@ -96,7 +96,7 @@ index b6f041f4..1fbce2bb 100644 + goto out; + } + r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, -+ kex->session_id, kex->session_id_len); ++ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)); + if (r != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 0713ffe..748ab48 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -57,26 +57,26 @@ index e7549470..4511f82a 100644 rm -f regress/unittests/utf8/test_utf8$(EXEEXT) + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so @@ -322,6 +324,8 @@ distclean: regressclean rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) distclean) + if test -d pkg ; then \ + rm -fr pkg ; \ @@ -490,6 +494,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/kex $(MKDIR_P) `pwd`/regress/unittests/match $(MKDIR_P) `pwd`/regress/unittests/utf8 + $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/kexfuzz $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile @@ -617,6 +622,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -91,17 +91,17 @@ index e7549470..4511f82a 100644 + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + - MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o \ - $(SKOBJS) + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ @@ -655,6 +670,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - regress/misc/kexfuzz/kexfuzz$(EXEEXT) tests: file-tests t-exec interop-tests unit + echo all tests passed diff --git a/configure.ac b/configure.ac index b689db4b..98d3ce4f 100644 --- a/configure.ac @@ -1075,10 +1075,10 @@ index 7eb6f0dc..27d8e4af 100644 + char *provider = NULL, *pin = NULL, *sane_uri = NULL; char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; - u_int seconds; + u_int seconds = 0; @@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) - goto send; - } + error_f("failed to parse constraints"); + goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", @@ -1093,13 +1093,13 @@ index 7eb6f0dc..27d8e4af 100644 + if (sane_uri == NULL) goto send; - } -- debug("%s: add %.100s", __func__, canonical_provider); +- debug_f("add %.100s", canonical_provider); + if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); -+ debug("%s: add %.100s", __func__, sane_uri); ++ debug_f("add %.100s", sane_uri); + count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { k = keys[i]; @@ -1147,8 +1147,8 @@ index 7eb6f0dc..27d8e4af 100644 goto send; - } -- debug("%s: remove %.100s", __func__, canonical_provider); -+ debug("%s: remove %.100s", __func__, sane_uri); +- debug_f("remove %.100s", canonical_provider); ++ debug_f("remove %.100s", sane_uri); for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); /* Skip file--based keys */ @@ -1165,7 +1165,7 @@ index 7eb6f0dc..27d8e4af 100644 + if (pkcs11_del_provider(sane_uri) == 0) success = 1; else - error("%s: pkcs11_del_provider failed", __func__); + error_f("pkcs11_del_provider failed"); send: free(provider); + free(sane_uri); @@ -1198,7 +1198,7 @@ index 8a0ffef5..ead8a562 100644 u_int nkeys, i; struct sshbuf *msg; -+ debug("%s: called, name = %s", __func__, name); ++ debug_f("called, name = %s", name); + if (fd < 0 && pkcs11_start_helper() < 0) return (-1); @@ -1207,7 +1207,7 @@ index 8a0ffef5..ead8a562 100644 *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); -+ debug("%s: nkeys = %u", __func__, nkeys); ++ debug_f("nkeys = %u", nkeys); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || @@ -1216,7 +1216,7 @@ new file mode 100644 index 00000000..e1a7b4e0 --- /dev/null +++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,425 @@ +@@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -1493,13 +1493,12 @@ index 00000000..e1a7b4e0 + size_t scheme_len = strlen(PKCS11_URI_SCHEME); + if (strlen(uri) < scheme_len || /* empty URI matches everything */ + strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { -+ error("%s: The '%s' does not look like PKCS#11 URI", -+ __func__, uri); ++ error_f("The '%s' does not look like PKCS#11 URI", uri); + return -1; + } + + if (pkcs11 == NULL) { -+ error("%s: Bad arguments. The pkcs11 can't be null", __func__); ++ error_f("Bad arguments. The pkcs11 can't be null"); + return -1; + } + @@ -1510,7 +1509,7 @@ index 00000000..e1a7b4e0 + /* everything before ? */ + tok = strtok_r(str1, "?", &saveptr1); + if (tok == NULL) { -+ error("%s: pk11-path expected, got EOF", __func__); ++ error_f("pk11-path expected, got EOF"); + rv = -1; + goto out; + } @@ -1536,35 +1535,32 @@ index 00000000..e1a7b4e0 + case pId: + /* CKA_ID */ + if (pkcs11->id != NULL) { -+ verbose("%s: The id already set in the PKCS#11 URI", -+ __func__); ++ verbose_f("The id already set in the PKCS#11 URI"); + rv = -1; + goto out; + } + len = percent_decode(arg, &pkcs11->id); + if (len <= 0) { -+ verbose("%s: Failed to percent-decode CKA_ID: %s", -+ __func__, arg); ++ verbose_f("Failed to percent-decode CKA_ID: %s", arg); + rv = -1; + goto out; + } else + pkcs11->id_len = len; -+ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", -+ __func__, arg); ++ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); + break; + case pToken: + /* CK_TOKEN_INFO -> label */ + charptr = &pkcs11->token; + parse_string: + if (*charptr != NULL) { -+ verbose("%s: The %s already set in the PKCS#11 URI", -+ keywords[opcode].name, __func__); ++ verbose_f("The %s already set in the PKCS#11 URI", ++ keywords[opcode].name); + rv = -1; + goto out; + } + percent_decode(arg, charptr); -+ debug3("%s: Setting %s = %s from PKCS#11 URI", -+ __func__, keywords[opcode].name, *charptr); ++ debug3_f("Setting %s = %s from PKCS#11 URI", ++ keywords[opcode].name, *charptr); + break; + + case pObject: @@ -1584,8 +1580,7 @@ index 00000000..e1a7b4e0 + + default: + /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose("%s: Unknown part of path in PKCS#11 URI: %s", -+ __func__, tok); ++ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); + } + } + @@ -1608,32 +1603,31 @@ index 00000000..e1a7b4e0 + case pModulePath: + /* module-path is PKCS11Provider */ + if (pkcs11->module_path != NULL) { -+ verbose("%s: Multiple module-path attributes are" -+ "not supported the PKCS#11 URI", __func__); ++ verbose_f("Multiple module-path attributes are" ++ "not supported the PKCS#11 URI"); + rv = -1; + goto out; + } + percent_decode(arg, &pkcs11->module_path); -+ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", -+ __func__, pkcs11->module_path); ++ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", ++ pkcs11->module_path); + break; + + case pPinValue: + /* pin-value */ + if (pkcs11->pin != NULL) { -+ verbose("%s: Multiple pin-value attributes are" -+ "not supported the PKCS#11 URI", __func__); ++ verbose_f("Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI"); + rv = -1; + goto out; + } + percent_decode(arg, &pkcs11->pin); -+ debug3("%s: Setting PIN from PKCS#11 URI", __func__); ++ debug3_f("Setting PIN from PKCS#11 URI"); + break; + + default: + /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose("%s: Unknown part of query in PKCS#11 URI: %s", -+ __func__, tok); ++ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); + } + } +out: @@ -1727,7 +1721,7 @@ index a302c79c..879fe917 100644 }; int pkcs11_interactive = 0; -@@ -106,26 +114,63 @@ pkcs11_init(int interactive) +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) * this is called when a provider gets unregistered. */ static void @@ -1740,8 +1734,7 @@ index a302c79c..879fe917 100644 - debug("pkcs11_provider_finalize: %p refcount %d valid %d", - p, p->refcount, p->valid); - if (!p->valid) -+ debug("%s: %p refcount %d valid %d", __func__, -+ m, m->refcount, m->valid); ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); + if (!m->valid) return; - for (i = 0; i < p->nslots; i++) { @@ -1769,11 +1762,11 @@ index a302c79c..879fe917 100644 +static void +pkcs11_module_unref(struct pkcs11_module *m) +{ -+ debug("%s: %p refcount %d", __func__, m, m->refcount); ++ debug_f("%p refcount %d", m, m->refcount); + if (--m->refcount <= 0) { + pkcs11_module_finalize(m); + if (m->valid) -+ error("%s: %p still valid", __func__, m); ++ error_f("%p still valid", m); + free(m->slotlist); + free(m->slotinfo); + free(m->module_path); @@ -1790,8 +1783,7 @@ index a302c79c..879fe917 100644 +static void +pkcs11_provider_finalize(struct pkcs11_provider *p) +{ -+ debug("%s: %p refcount %d valid %d", __func__, -+ p, p->refcount, p->valid); ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); + if (!p->valid) + return; + pkcs11_module_unref(p->module); @@ -1807,7 +1799,7 @@ index a302c79c..879fe917 100644 pkcs11_provider_unref(struct pkcs11_provider *p) { - debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug("%s: %p refcount %d", __func__, p, p->refcount); ++ debug_f("%p refcount %d", p, p->refcount); if (--p->refcount <= 0) { - if (p->valid) - error("pkcs11_provider_unref: %p still valid", p); @@ -1853,7 +1845,7 @@ index a302c79c..879fe917 100644 + int rv; + struct pkcs11_uri *uri; + -+ debug("%s: called, provider_id = %s", __func__, provider_id); ++ debug_f("called, provider_id = %s", provider_id); + + uri = pkcs11_uri_init(); + if (uri == NULL) @@ -1881,7 +1873,7 @@ index a302c79c..879fe917 100644 + char *provider_uri = pkcs11_uri_get(uri); - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3("%s(%s): called", __func__, provider_uri); ++ debug3_f("called with provider %s", provider_uri); + + if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); @@ -1977,7 +1969,7 @@ index a302c79c..879fe917 100644 si->token.label); - if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { + if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug("%s: no pin specified", __func__); + debug_f("no pin specified"); return (-1); /* bail out */ } } @@ -2296,7 +2288,7 @@ index a302c79c..879fe917 100644 error("BN_bin2bn failed"); goto fail; @@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - fatal("%s: set key", __func__); + fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ - if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) @@ -2508,7 +2500,7 @@ index a302c79c..879fe917 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1484,167 +1670,303 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1484,164 +1670,298 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2522,7 +2514,7 @@ index a302c79c..879fe917 100644 +#ifdef PKCS11_DEFAULT_PROVIDER + provider_module = strdup(PKCS11_DEFAULT_PROVIDER); +#else -+ error("%s: No module path provided", __func__); ++ error_f("No module path provided"); goto fail; - *providerp = NULL; - @@ -2536,16 +2528,14 @@ index a302c79c..879fe917 100644 + } - if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug("%s: provider already registered: %s", -- __func__, provider_id); +- debug_f("provider already registered: %s", provider_id); - goto fail; + p = xcalloc(1, sizeof(*p)); + p->name = pkcs11_uri_get(uri); + + if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL + && m->valid) { -+ debug("%s: provider module already initialized: %s", -+ __func__, provider_module); ++ debug_f("provider module already initialized: %s", provider_module); + free(provider_module); + /* Skip the initialization of PKCS#11 module */ + m->refcount++; @@ -2605,8 +2595,8 @@ index a302c79c..879fe917 100644 + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug("%s: Skipping provider %s not matching library_manufacturer", -+ __func__, m->info.manufacturerID); ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); + goto fail; + } + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); @@ -2634,9 +2624,8 @@ index a302c79c..879fe917 100644 } - if (p->nslots == 0) { + if (m->nslots == 0) { - debug("%s: provider %s returned no slots", __func__, -- provider_id); -+ provider_module); +- debug_f("provider %s returned no slots", provider_id); ++ debug_f("provider %s returned no slots", provider_module); ret = -SSH_PKCS11_ERR_NO_SLOTS; goto fail; } @@ -2663,8 +2652,8 @@ index a302c79c..879fe917 100644 + if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) != CKR_OK) { error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (unsigned long)i, rv); -+ "failed: %lu", provider_module, (unsigned long)i, rv); +- "failed: %lu", provider_id, (u_long)i, rv); ++ "failed: %lu", provider_module, (u_long)i, rv); + token->flags = 0; continue; } @@ -2735,25 +2724,23 @@ index a302c79c..879fe917 100644 + for (i = 0; i < p->module->nslots; i++) { + token = &p->module->slotinfo[i].token; if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { - debug2("%s: ignoring uninitialised token in " - "provider %s slot %lu", __func__, -- provider_id, (unsigned long)i); -+ provider_uri, (unsigned long)i); + debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "provider %s slot %lu", provider_uri, (u_long)i); + continue; + } + if (uri->token != NULL && + strcmp(token->label, uri->token) != 0) { -+ debug2("%s: ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", __func__, ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", + token->label, (unsigned long)i); + continue; + } + if (uri->manuf != NULL && + strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2("%s: ignoring token not matching requrested " ++ debug2_f("ignoring token not matching requrested " + "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", __func__, -+ token->manufacturerID, (unsigned long)i); ++ "slot %lu", token->manufacturerID, (unsigned long)i); continue; } - rmspace(token->label, sizeof(token->label)); @@ -2789,8 +2776,7 @@ index a302c79c..879fe917 100644 * expose keys. */ - if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3("%s: Trying to login as there were no keys found", -+ __func__); ++ debug3_f("Trying to login as there were no keys found"); + if (pkcs11_login_slot(p, &p->module->slotinfo[i], CKU_USER) < 0) { error("login failed"); @@ -2802,8 +2788,8 @@ index a302c79c..879fe917 100644 + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } + if (nkeys == 0 && uri->object != NULL) { -+ debug3("%s: No keys found. Retrying without label (%s) ", -+ __func__, uri->object); ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); + /* Try once more without the label filter */ + char *label = uri->object; + uri->object = NULL; /* XXX clone uri? */ @@ -2852,7 +2838,7 @@ index a302c79c..879fe917 100644 + struct pkcs11_uri *uri = NULL; + int r; + -+ debug("%s: called, provider_id = %s", __func__, provider_id); ++ debug_f("called, provider_id = %s", provider_id); + + uri = pkcs11_uri_init(); + if (uri == NULL) @@ -2878,12 +2864,11 @@ index a302c79c..879fe917 100644 +pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, + struct sshkey ***keyp, char ***labelsp) { -- struct pkcs11_provider *p = NULL; + struct pkcs11_provider *p = NULL; int nkeys; -+ struct pkcs11_provider *p = NULL; + char *provider_uri = pkcs11_uri_get(uri); + -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); ++ debug_f("called, provider_uri = %s", provider_uri); - nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, - &p, CKU_USER); @@ -2892,11 +2877,11 @@ index a302c79c..879fe917 100644 /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { @@ -1652,7 +1974,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, + pkcs11_provider_unref(p); } if (nkeys == 0) - debug("%s: provider %s returned no keys", __func__, -- provider_id); -+ provider_uri); +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); + + free(provider_uri); + return nkeys; @@ -2930,26 +2915,6 @@ index a302c79c..879fe917 100644 return (nkeys); } -@@ -1674,7 +2026,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, - - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) - debug("%s: provider \"%s\" available", __func__, provider_id); -- else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL, -+ else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, - &p, CKU_SO)) < 0) { - debug("%s: could not register provider %s", __func__, - provider_id); -@@ -1746,8 +2098,8 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, - - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { - debug("%s: using provider \"%s\"", __func__, provider_id); -- } else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p, -- CKU_SO) < 0) { -+ } else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, -+ &p, CKU_SO)) < 0) { - debug("%s: could not register provider %s", __func__, - provider_id); - goto out; diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index 81f1d7c5..feaf74de 100644 --- a/ssh-pkcs11.h @@ -2995,7 +2960,7 @@ index 15aee569..976844cb 100644 + pkcs11_terminate(); skip_connect: - exit_status = ssh_session2(ssh, pw); + exit_status = ssh_session2(ssh, cinfo); @@ -2076,6 +2085,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -3041,7 +3006,7 @@ index 15aee569..976844cb 100644 + /* Loads all IdentityFile and CertificateFile keys */ static void - load_public_identity_files(struct passwd *pw) + load_public_identity_files(const struct ssh_conn_info *cinfo) @@ -2090,11 +2138,6 @@ load_public_identity_files(struct passwd *pw) char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; @@ -3117,9 +3082,9 @@ index 15aee569..976844cb 100644 + } +#endif /* ENABLE_PKCS11 */ + cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_dollar_expand(cp, - pw->pw_dir, host, options.user, pw->pw_name); + filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); + check_load(sshkey_load_public(filename, &public, NULL), diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..4b2763bd 100644 --- a/ssh_config.5 diff --git a/openssh-8.0p1-sshbuf-readonly.patch b/openssh-8.0p1-sshbuf-readonly.patch new file mode 100644 index 0000000..edc8bec --- /dev/null +++ b/openssh-8.0p1-sshbuf-readonly.patch @@ -0,0 +1,152 @@ +From 063e1a255b53abde1147522f9aceccfd2a7ceb9b Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +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"); + diff --git a/openssh-8.2p1-x11-without-ipv6.patch b/openssh-8.2p1-x11-without-ipv6.patch index 18b0376..8b83bc3 100644 --- a/openssh-8.2p1-x11-without-ipv6.patch +++ b/openssh-8.2p1-x11-without-ipv6.patch @@ -7,8 +7,8 @@ diff --git a/channels.c b/channels.c 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)); + debug2_f("bind port %d: %.100s", port, + strerror(errno)); close(sock); + + /* do not remove successfully opened diff --git a/openssh-8.4p1-debian-compat.patch b/openssh-8.4p1-debian-compat.patch index 0af1d3d..1285979 100644 --- a/openssh-8.4p1-debian-compat.patch +++ b/openssh-8.4p1-debian-compat.patch @@ -37,8 +37,8 @@ + * SHA2 signature types. + */ + if (alg == NULL && -+ (key->type == KEY_RSA && (datafellows & SSH_BUG_SIGTYPE74))) { -+ oallowed = allowed = xstrdup(options.pubkey_key_types); ++ (key->type == KEY_RSA && (ssh->compat & SSH_BUG_SIGTYPE74))) { ++ oallowed = allowed = xstrdup(options.pubkey_accepted_algos); + while ((cp = strsep(&allowed, ",")) != NULL) { + if (sshkey_type_from_name(cp) != key->type) + continue; diff --git a/openssh-8.4p1-sandbox-seccomp.patch b/openssh-8.4p1-sandbox-seccomp.patch deleted file mode 100644 index ac4ee61..0000000 --- a/openssh-8.4p1-sandbox-seccomp.patch +++ /dev/null @@ -1,14 +0,0 @@ -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 diff --git a/openssh-8.4p1-ssh-copy-id.patch b/openssh-8.4p1-ssh-copy-id.patch deleted file mode 100644 index 7bc4c7d..0000000 --- a/openssh-8.4p1-ssh-copy-id.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 66f16e5425eb881570e82bfef7baeac2e7accc0a Mon Sep 17 00:00:00 2001 -From: Oleg -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 -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 -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; --- diff --git a/openssh-8.4p1-gsissh.patch b/openssh-8.5p1-gsissh.patch similarity index 85% rename from openssh-8.4p1-gsissh.patch rename to openssh-8.5p1-gsissh.patch index d664fdd..3d2a798 100644 --- a/openssh-8.4p1-gsissh.patch +++ b/openssh-8.5p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c ---- openssh-8.4p1.orig/auth2.c 2020-10-06 11:23:35.222491390 +0200 -+++ openssh-8.4p1/auth2.c 2020-10-06 11:24:20.006596864 +0200 -@@ -279,7 +279,28 @@ +diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c +--- openssh-8.5p1.orig/auth2.c 2021-03-16 18:29:34.889456973 +0100 ++++ openssh-8.5p1/auth2.c 2021-03-16 18:30:25.470567118 +0100 +@@ -277,7 +277,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) goto out; @@ -31,7 +31,7 @@ diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -290,11 +311,33 @@ +@@ -288,17 +309,42 @@ if ((style = strchr(user, ':')) != NULL) *style++ = 0; @@ -67,9 +67,8 @@ diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c + authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); + if (authctxt->pw) { authctxt->valid = 1; - debug2("%s: setting up authctxt for %s", - __func__, user); -@@ -302,6 +345,9 @@ + debug2_f("setting up authctxt for %s", user); + } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -79,7 +78,7 @@ diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(ssh)); -@@ -310,6 +356,7 @@ +@@ -307,6 +353,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -87,7 +86,7 @@ diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -325,9 +372,10 @@ +@@ -322,9 +369,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -101,10 +100,10 @@ diff -Nur openssh-8.4p1.orig/auth2.c openssh-8.4p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c ---- openssh-8.4p1.orig/auth2-gss.c 2020-10-06 11:23:35.124491159 +0200 -+++ openssh-8.4p1/auth2-gss.c 2020-10-06 11:24:20.006596864 +0200 -@@ -49,6 +49,7 @@ +diff -Nur openssh-8.5p1.orig/auth2-gss.c openssh-8.5p1/auth2-gss.c +--- openssh-8.5p1.orig/auth2-gss.c 2021-03-16 18:29:34.802456784 +0100 ++++ openssh-8.5p1/auth2-gss.c 2021-03-16 18:30:25.470567118 +0100 +@@ -50,6 +50,7 @@ extern ServerOptions options; @@ -112,7 +111,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); 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); -@@ -62,8 +63,8 @@ +@@ -63,8 +64,8 @@ { Authctxt *authctxt = ssh->authctxt; int r, authenticated = 0; @@ -123,26 +122,27 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c u_char *p; size_t len; -@@ -74,6 +75,9 @@ +@@ -75,6 +76,9 @@ if ((b = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); + if ((b2 = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + mic.value = p; mic.length = len; -@@ -84,13 +88,28 @@ - fatal("%s: sshbuf_mutable_ptr failed", __func__); +@@ -85,13 +89,29 @@ + fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); + /* client may have used empty username to determine target + name from GSSAPI context */ -+ ssh_gssapi_buildmic(b2, "", authctxt->service, "gssapi-keyex"); ++ ssh_gssapi_buildmic(b2, "", authctxt->service, "gssapi-keyex", ++ ssh->kex->session_id); + + if ((gssbuf2.value = sshbuf_mutable_ptr(b2)) == NULL) -+ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ fatal_f("sshbuf_mutable_ptr failed"); + gssbuf2.length = sshbuf_len(b2); + /* gss_kex_context is NULL with privsep, so we can't check it here */ @@ -165,7 +165,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -145,7 +164,9 @@ +@@ -146,7 +166,9 @@ return (0); } @@ -173,10 +173,10 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c + /* authctxt->valid may be 0 if we haven't yet determined + username from gssapi context. */ + if (authctxt->user == NULL) { - debug2("%s: disabled because of invalid user", __func__); + debug2_f("disabled because of invalid user"); free(doid); return (0); -@@ -183,7 +204,7 @@ +@@ -184,7 +206,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -185,7 +185,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c u_char *p; size_t len; int r; -@@ -204,6 +225,7 @@ +@@ -205,6 +227,7 @@ free(p); if (GSS_ERROR(maj_status)) { @@ -193,7 +193,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c if (send_tok.length != 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || -@@ -278,6 +300,34 @@ +@@ -279,6 +302,34 @@ return 0; } @@ -228,7 +228,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -288,12 +338,14 @@ +@@ -289,12 +340,14 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -244,9 +244,9 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -302,8 +354,11 @@ +@@ -303,8 +356,11 @@ if ((r = sshpkt_get_end(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse packet"); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw, 1)); @@ -258,8 +258,8 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -355,11 +410,17 @@ - fatal("%s: sshbuf_mutable_ptr failed", __func__); +@@ -356,11 +412,17 @@ + fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -280,7 +280,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c sshbuf_free(b); if (micuser != authctxt->user) -@@ -379,6 +440,26 @@ +@@ -380,6 +442,26 @@ return 0; } @@ -299,7 +299,7 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c + (r = sshpkt_put_cstring(ssh, "")) != 0 || + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) -+ fatal("%s: %s", __func__, ssh_err(r)); ++ fatal_fr(r, ""); + free(errstr); + } +} @@ -307,9 +307,9 @@ diff -Nur openssh-8.4p1.orig/auth2-gss.c openssh-8.4p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.4p1.orig/auth.c openssh-8.4p1/auth.c ---- openssh-8.4p1.orig/auth.c 2020-10-06 11:23:35.223491392 +0200 -+++ openssh-8.4p1/auth.c 2020-10-06 11:24:20.007596867 +0200 +diff -Nur openssh-8.5p1.orig/auth.c openssh-8.5p1/auth.c +--- openssh-8.5p1.orig/auth.c 2021-03-16 18:29:34.890456975 +0100 ++++ openssh-8.5p1/auth.c 2021-03-16 18:30:25.471567120 +0100 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -320,7 +320,7 @@ diff -Nur openssh-8.4p1.orig/auth.c openssh-8.4p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -582,13 +583,18 @@ +@@ -586,13 +587,18 @@ #endif pw = getpwnam(user); @@ -340,9 +340,9 @@ diff -Nur openssh-8.4p1.orig/auth.c openssh-8.4p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.4p1.orig/auth.h openssh-8.4p1/auth.h ---- openssh-8.4p1.orig/auth.h 2020-10-06 11:23:35.224491395 +0200 -+++ openssh-8.4p1/auth.h 2020-10-06 11:24:20.007596867 +0200 +diff -Nur openssh-8.5p1.orig/auth.h openssh-8.5p1/auth.h +--- openssh-8.5p1.orig/auth.h 2021-03-16 18:29:34.890456975 +0100 ++++ openssh-8.5p1/auth.h 2021-03-16 18:30:25.471567120 +0100 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +352,9 @@ diff -Nur openssh-8.4p1.orig/auth.h openssh-8.4p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c ---- openssh-8.4p1.orig/auth-pam.c 2020-10-06 11:23:35.083491063 +0200 -+++ openssh-8.4p1/auth-pam.c 2020-10-06 11:24:20.008596869 +0200 +diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c +--- openssh-8.5p1.orig/auth-pam.c 2021-03-16 18:29:34.770456714 +0100 ++++ openssh-8.5p1/auth-pam.c 2021-03-16 18:30:25.472567122 +0100 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -477,7 +477,7 @@ diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -726,6 +804,8 @@ +@@ -732,6 +810,8 @@ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), sshpam_laddr, ssh_local_port(ssh)); @@ -486,7 +486,7 @@ diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1068,6 +1148,18 @@ +@@ -1074,6 +1154,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -505,7 +505,7 @@ diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1356,6 +1448,9 @@ +@@ -1362,6 +1454,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -515,9 +515,9 @@ diff -Nur openssh-8.4p1.orig/auth-pam.c openssh-8.4p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.4p1.orig/auth-pam.h openssh-8.4p1/auth-pam.h ---- openssh-8.4p1.orig/auth-pam.h 2020-10-06 11:23:35.083491063 +0200 -+++ openssh-8.4p1/auth-pam.h 2020-10-06 11:24:20.008596869 +0200 +diff -Nur openssh-8.5p1.orig/auth-pam.h openssh-8.5p1/auth-pam.h +--- openssh-8.5p1.orig/auth-pam.h 2021-03-16 18:29:34.771456716 +0100 ++++ openssh-8.5p1/auth-pam.h 2021-03-16 18:30:25.472567122 +0100 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +525,9 @@ diff -Nur openssh-8.4p1.orig/auth-pam.h openssh-8.4p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.4p1.orig/canohost.c openssh-8.4p1/canohost.c ---- openssh-8.4p1.orig/canohost.c 2020-10-06 11:23:35.125491161 +0200 -+++ openssh-8.4p1/canohost.c 2020-10-06 11:24:20.009596871 +0200 +diff -Nur openssh-8.5p1.orig/canohost.c openssh-8.5p1/canohost.c +--- openssh-8.5p1.orig/canohost.c 2021-03-16 18:29:34.802456784 +0100 ++++ openssh-8.5p1/canohost.c 2021-03-16 18:30:25.473567125 +0100 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +570,9 @@ diff -Nur openssh-8.4p1.orig/canohost.c openssh-8.4p1/canohost.c + } + } +} -diff -Nur openssh-8.4p1.orig/canohost.h openssh-8.4p1/canohost.h ---- openssh-8.4p1.orig/canohost.h 2020-10-06 11:23:35.125491161 +0200 -+++ openssh-8.4p1/canohost.h 2020-10-06 11:24:20.009596871 +0200 +diff -Nur openssh-8.5p1.orig/canohost.h openssh-8.5p1/canohost.h +--- openssh-8.5p1.orig/canohost.h 2021-03-16 18:29:34.802456784 +0100 ++++ openssh-8.5p1/canohost.h 2021-03-16 18:30:25.473567125 +0100 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,10 +580,10 @@ diff -Nur openssh-8.4p1.orig/canohost.h openssh-8.4p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.4p1.orig/configure.ac openssh-8.4p1/configure.ac ---- openssh-8.4p1.orig/configure.ac 2020-10-06 11:23:35.212491366 +0200 -+++ openssh-8.4p1/configure.ac 2020-10-06 11:24:20.010596874 +0200 -@@ -4730,6 +4730,14 @@ +diff -Nur openssh-8.5p1.orig/configure.ac openssh-8.5p1/configure.ac +--- openssh-8.5p1.orig/configure.ac 2021-03-16 18:29:34.879456951 +0100 ++++ openssh-8.5p1/configure.ac 2021-03-16 18:30:25.474567127 +0100 +@@ -4718,6 +4718,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -598,7 +598,7 @@ diff -Nur openssh-8.4p1.orig/configure.ac openssh-8.4p1/configure.ac fi if test -n "${rpath_opt}" ; then LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" -@@ -4769,6 +4777,40 @@ +@@ -4757,6 +4765,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,9 +639,9 @@ diff -Nur openssh-8.4p1.orig/configure.ac openssh-8.4p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.4p1.orig/gss-genr.c openssh-8.4p1/gss-genr.c ---- openssh-8.4p1.orig/gss-genr.c 2020-10-06 11:23:35.127491166 +0200 -+++ openssh-8.4p1/gss-genr.c 2020-10-06 11:24:20.010596874 +0200 +diff -Nur openssh-8.5p1.orig/gss-genr.c openssh-8.5p1/gss-genr.c +--- openssh-8.5p1.orig/gss-genr.c 2021-03-16 18:29:34.804456788 +0100 ++++ openssh-8.5p1/gss-genr.c 2021-03-16 18:30:25.475567129 +0100 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -650,7 +650,7 @@ diff -Nur openssh-8.4p1.orig/gss-genr.c openssh-8.4p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -413,9 +414,18 @@ +@@ -407,9 +408,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -670,7 +670,7 @@ diff -Nur openssh-8.4p1.orig/gss-genr.c openssh-8.4p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -423,6 +433,7 @@ +@@ -417,6 +427,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -678,9 +678,9 @@ diff -Nur openssh-8.4p1.orig/gss-genr.c openssh-8.4p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.4p1.orig/gss-serv.c openssh-8.4p1/gss-serv.c ---- openssh-8.4p1.orig/gss-serv.c 2020-10-06 11:23:35.145491208 +0200 -+++ openssh-8.4p1/gss-serv.c 2020-10-06 11:24:20.011596876 +0200 +diff -Nur openssh-8.5p1.orig/gss-serv.c openssh-8.5p1/gss-serv.c +--- openssh-8.5p1.orig/gss-serv.c 2021-03-16 18:29:34.820456823 +0100 ++++ openssh-8.5p1/gss-serv.c 2021-03-16 18:30:25.475567129 +0100 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +961,9 @@ diff -Nur openssh-8.4p1.orig/gss-serv.c openssh-8.4p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.4p1.orig/gss-serv-gsi.c openssh-8.4p1/gss-serv-gsi.c ---- openssh-8.4p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.4p1/gss-serv-gsi.c 2020-10-06 11:24:20.011596876 +0200 +diff -Nur openssh-8.5p1.orig/gss-serv-gsi.c openssh-8.5p1/gss-serv-gsi.c +--- openssh-8.5p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.5p1/gss-serv-gsi.c 2021-03-16 18:30:25.476567131 +0100 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1293,9 @@ diff -Nur openssh-8.4p1.orig/gss-serv-gsi.c openssh-8.4p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.4p1.orig/gss-serv-krb5.c openssh-8.4p1/gss-serv-krb5.c ---- openssh-8.4p1.orig/gss-serv-krb5.c 2020-10-06 11:23:35.166491258 +0200 -+++ openssh-8.4p1/gss-serv-krb5.c 2020-10-06 11:24:20.011596876 +0200 +diff -Nur openssh-8.5p1.orig/gss-serv-krb5.c openssh-8.5p1/gss-serv-krb5.c +--- openssh-8.5p1.orig/gss-serv-krb5.c 2021-03-16 18:29:34.840456866 +0100 ++++ openssh-8.5p1/gss-serv-krb5.c 2021-03-16 18:30:25.476567131 +0100 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1349,9 @@ diff -Nur openssh-8.4p1.orig/gss-serv-krb5.c openssh-8.4p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c ---- openssh-8.4p1.orig/kexgsss.c 2020-10-06 11:23:35.129491171 +0200 -+++ openssh-8.4p1/kexgsss.c 2020-10-06 11:24:20.012596878 +0200 +diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c +--- openssh-8.5p1.orig/kexgsss.c 2021-03-16 18:29:34.916457032 +0100 ++++ openssh-8.5p1/kexgsss.c 2021-03-16 18:30:25.477567133 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1360,9 +1360,9 @@ diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c extern ServerOptions options; int -@@ -96,8 +97,10 @@ +@@ -99,8 +100,10 @@ - debug2("%s: Acquiring credentials", __func__); + debug2_f("Acquiring credentials"); - if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) { @@ -1372,7 +1372,7 @@ diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c do { debug("Wait SSH2_MSG_KEXGSS_INIT"); -@@ -170,13 +173,14 @@ +@@ -188,13 +191,14 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1388,7 +1388,7 @@ diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -471,4 +475,26 @@ +@@ -490,4 +494,26 @@ sshbuf_free(shared_secret); return r; } @@ -1415,21 +1415,21 @@ diff -Nur openssh-8.4p1.orig/kexgsss.c openssh-8.4p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.4p1.orig/Makefile.in openssh-8.4p1/Makefile.in ---- openssh-8.4p1.orig/Makefile.in 2020-10-06 11:23:35.228491404 +0200 -+++ openssh-8.4p1/Makefile.in 2020-10-06 11:24:20.012596878 +0200 -@@ -129,6 +129,7 @@ +diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in +--- openssh-8.5p1.orig/Makefile.in 2021-03-16 18:29:34.892456980 +0100 ++++ openssh-8.5p1/Makefile.in 2021-03-16 18:30:25.477567133 +0100 +@@ -127,6 +127,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.4p1.orig/misc.c openssh-8.4p1/misc.c ---- openssh-8.4p1.orig/misc.c 2020-10-06 11:23:35.084491065 +0200 -+++ openssh-8.4p1/misc.c 2020-10-06 11:24:20.013596881 +0200 -@@ -324,11 +324,14 @@ +diff -Nur openssh-8.5p1.orig/misc.c openssh-8.5p1/misc.c +--- openssh-8.5p1.orig/misc.c 2021-03-16 18:29:34.857456904 +0100 ++++ openssh-8.5p1/misc.c 2021-03-16 18:30:25.478567135 +0100 +@@ -378,11 +378,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1445,7 +1445,7 @@ diff -Nur openssh-8.4p1.orig/misc.c openssh-8.4p1/misc.c int wspace = 0; if (*s == NULL) -@@ -336,6 +339,21 @@ +@@ -390,6 +393,21 @@ old = *s; @@ -1467,7 +1467,7 @@ diff -Nur openssh-8.4p1.orig/misc.c openssh-8.4p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -411,6 +429,20 @@ +@@ -465,6 +483,20 @@ return copy; } @@ -1488,21 +1488,21 @@ diff -Nur openssh-8.4p1.orig/misc.c openssh-8.4p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.4p1.orig/misc.h openssh-8.4p1/misc.h ---- openssh-8.4p1.orig/misc.h 2020-09-27 09:25:01.000000000 +0200 -+++ openssh-8.4p1/misc.h 2020-10-06 11:24:20.013596881 +0200 -@@ -94,6 +94,7 @@ +diff -Nur openssh-8.5p1.orig/misc.h openssh-8.5p1/misc.h +--- openssh-8.5p1.orig/misc.h 2021-03-16 18:29:34.857456904 +0100 ++++ openssh-8.5p1/misc.h 2021-03-16 18:30:25.479567137 +0100 +@@ -97,6 +97,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); +void pwfree(struct passwd *); const char *ssh_gai_strerror(int); - typedef struct arglist arglist; -diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c ---- openssh-8.4p1.orig/monitor.c 2020-10-06 11:23:35.252491460 +0200 -+++ openssh-8.4p1/monitor.c 2020-10-06 11:24:20.014596883 +0200 -@@ -155,6 +155,9 @@ + typedef void privdrop_fn(struct passwd *); +diff -Nur openssh-8.5p1.orig/monitor.c openssh-8.5p1/monitor.c +--- openssh-8.5p1.orig/monitor.c 2021-03-16 18:29:34.911457021 +0100 ++++ openssh-8.5p1/monitor.c 2021-03-16 18:30:25.479567137 +0100 +@@ -154,6 +154,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1512,7 +1512,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -207,7 +210,7 @@ +@@ -206,7 +209,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1521,7 +1521,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -215,7 +218,7 @@ +@@ -214,7 +217,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1530,7 +1530,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -239,8 +242,11 @@ +@@ -238,8 +241,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1543,7 +1543,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c #endif {0, 0, NULL} }; -@@ -250,6 +256,8 @@ +@@ -249,6 +255,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1552,7 +1552,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -330,6 +338,8 @@ +@@ -329,6 +337,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1561,7 +1561,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -449,6 +459,8 @@ +@@ -446,6 +456,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1570,15 +1570,15 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -767,15 +779,18 @@ +@@ -766,15 +778,18 @@ - debug3("%s", __func__); + debug3_f("entering"); - if (authctxt->attempt++ != 0) -- fatal("%s: multiple attempts for getpwnam", __func__); +- fatal_f("multiple attempts for getpwnam"); - if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); pwent = getpwnamallow(ssh, username); @@ -1592,7 +1592,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2105,6 +2120,79 @@ +@@ -2117,6 +2132,79 @@ } int @@ -1607,7 +1607,7 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c + if ((r = sshbuf_put_u32(m, major)) != 0 || + (r = sshbuf_put_u32(m, minor)) != 0 || + (r = sshbuf_put_cstring(m, msg)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(socket, MONITOR_ANS_GSSERR, m); + @@ -1629,11 +1629,11 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, major)) != 0 || + (r = sshbuf_put_u32(m, mech_set->count)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + for (i = 0; i < mech_set->count; i++) { + if ((r = sshbuf_put_string(m, mech_set->elements[i].elements, + mech_set->elements[i].length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + } + + gss_release_oid_set(&minor, &mech_set); @@ -1654,13 +1654,13 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c + sshbuf_reset(m); + if (name) { + if ((r = sshbuf_put_cstring(m, name)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ debug3("%s: sending result %s", __func__, name); ++ fatal_fr(r, "buffer error"); ++ debug3_f("sending result %s", name); + free(name); + } else { + if ((r = sshbuf_put_cstring(m, "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ debug3("%s: sending result \"\"", __func__); ++ fatal_fr(r, "buffer error"); ++ debug3_f("sending result \"\""); + } + + mm_request_send(socket, MONITOR_ANS_GSSLOCALNAME, m); @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.4p1.orig/monitor.c openssh-8.4p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.4p1.orig/monitor.h openssh-8.4p1/monitor.h ---- openssh-8.4p1.orig/monitor.h 2020-10-06 11:23:35.230491409 +0200 -+++ openssh-8.4p1/monitor.h 2020-10-06 11:24:20.014596883 +0200 +diff -Nur openssh-8.5p1.orig/monitor.h openssh-8.5p1/monitor.h +--- openssh-8.5p1.orig/monitor.h 2021-03-16 18:29:34.893456982 +0100 ++++ openssh-8.5p1/monitor.h 2021-03-16 18:30:25.480567140 +0100 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,10 +1686,10 @@ diff -Nur openssh-8.4p1.orig/monitor.h openssh-8.4p1/monitor.h }; struct ssh; -diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c ---- openssh-8.4p1.orig/monitor_wrap.c 2020-10-06 11:23:35.252491460 +0200 -+++ openssh-8.4p1/monitor_wrap.c 2020-10-06 11:24:20.015596885 +0200 -@@ -1078,6 +1078,94 @@ +diff -Nur openssh-8.5p1.orig/monitor_wrap.c openssh-8.5p1/monitor_wrap.c +--- openssh-8.5p1.orig/monitor_wrap.c 2021-03-16 18:29:34.911457021 +0100 ++++ openssh-8.5p1/monitor_wrap.c 2021-03-16 18:30:25.480567140 +0100 +@@ -1087,6 +1087,94 @@ return (authenticated); } @@ -1702,20 +1702,20 @@ diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, m); + + if ((r = sshbuf_get_u32(m, &maj)) != 0 || + (r = sshbuf_get_u32(m, &min)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + if (major) *major=maj; + if (minor) *minor=min; + + if ((r = sshbuf_get_cstring(m, &errstr, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + @@ -1733,18 +1733,18 @@ diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS, m); + if ((r = sshbuf_get_u32(m, &major)) != 0 || + (r = sshbuf_get_u32(m, &count)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + gss_create_empty_oid_set(&minor, mech_set); + while(count-->0) { + if ((r = sshbuf_get_string(m, (u_char **)&oid.elements, &length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + oid.length = length; + gss_add_oid_set_member(&minor, &oid, mech_set); + } @@ -1761,21 +1761,21 @@ diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, m); + -+ debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__); ++ debug3_f("waiting for MONITOR_ANS_GSSLOCALNAME"); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME, + m); + + if ((r = sshbuf_get_cstring(m, lname, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + if ((*lname == NULL) || (*lname[0] == '\0')) { -+ debug3("%s: gssapi identity mapping failed", __func__); ++ debug3_f("gssapi identity mapping failed"); + } else { -+ debug3("%s: gssapi identity mapped to %s", __func__, *lname); ++ debug3_f("gssapi identity mapped to %s", *lname); + } + + return(0); @@ -1784,10 +1784,10 @@ diff -Nur openssh-8.4p1.orig/monitor_wrap.c openssh-8.4p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.4p1.orig/monitor_wrap.h openssh-8.4p1/monitor_wrap.h ---- openssh-8.4p1.orig/monitor_wrap.h 2020-10-06 11:23:35.239491430 +0200 -+++ openssh-8.4p1/monitor_wrap.h 2020-10-06 11:24:20.015596885 +0200 -@@ -73,6 +73,10 @@ +diff -Nur openssh-8.5p1.orig/monitor_wrap.h openssh-8.5p1/monitor_wrap.h +--- openssh-8.5p1.orig/monitor_wrap.h 2021-03-16 18:29:34.899456995 +0100 ++++ openssh-8.5p1/monitor_wrap.h 2021-03-16 18:30:25.481567142 +0100 +@@ -74,6 +74,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-8.4p1.orig/monitor_wrap.h openssh-8.4p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.4p1.orig/readconf.c openssh-8.4p1/readconf.c ---- openssh-8.4p1.orig/readconf.c 2020-10-06 11:23:35.244491442 +0200 -+++ openssh-8.4p1/readconf.c 2020-10-06 11:24:20.016596888 +0200 -@@ -2177,11 +2177,11 @@ +diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c +--- openssh-8.5p1.orig/readconf.c 2021-03-16 18:29:34.904457006 +0100 ++++ openssh-8.5p1/readconf.c 2021-03-16 18:30:25.482567144 +0100 +@@ -2390,11 +2390,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1816,10 +1816,10 @@ diff -Nur openssh-8.4p1.orig/readconf.c openssh-8.4p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.4p1.orig/readconf.h openssh-8.4p1/readconf.h ---- openssh-8.4p1.orig/readconf.h 2020-10-06 11:23:35.133491180 +0200 -+++ openssh-8.4p1/readconf.h 2020-10-06 11:24:20.017596890 +0200 -@@ -79,6 +79,8 @@ +diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h +--- openssh-8.5p1.orig/readconf.h 2021-03-16 18:29:34.808456797 +0100 ++++ openssh-8.5p1/readconf.h 2021-03-16 18:30:25.482567144 +0100 +@@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-8.4p1.orig/readconf.h openssh-8.4p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c ---- openssh-8.4p1.orig/servconf.c 2020-10-06 11:23:35.253491463 +0200 -+++ openssh-8.4p1/servconf.c 2020-10-06 11:24:20.017596890 +0200 +diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c +--- openssh-8.5p1.orig/servconf.c 2021-03-16 18:29:34.912457023 +0100 ++++ openssh-8.5p1/servconf.c 2021-03-16 18:30:25.483567146 +0100 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1839,7 +1839,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -137,9 +138,11 @@ +@@ -139,9 +140,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1851,7 +1851,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -313,6 +316,8 @@ +@@ -292,6 +295,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -392,13 +397,17 @@ +@@ -371,13 +376,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -530,7 +539,7 @@ +@@ -515,7 +524,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1888,10 +1888,10 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c + sUsePAM, sPermitPAMUserChange, /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, - sPermitRootLogin, sLogFacility, sLogLevel, -@@ -552,6 +561,9 @@ - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, - sHostKeyAlgorithms, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, +@@ -537,6 +546,9 @@ + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -584,8 +596,10 @@ +@@ -569,8 +581,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -634,8 +648,15 @@ +@@ -622,8 +636,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -643,8 +664,11 @@ +@@ -631,8 +652,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -714,6 +738,8 @@ +@@ -704,6 +728,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1367,6 +1393,10 @@ +@@ -1357,6 +1383,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1609,6 +1639,10 @@ +@@ -1599,6 +1629,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1617,6 +1651,10 @@ +@@ -1607,6 +1641,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1637,6 +1675,12 @@ +@@ -1627,6 +1665,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2577,6 +2621,7 @@ +@@ -2614,6 +2658,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,10 +2001,10 @@ diff -Nur openssh-8.4p1.orig/servconf.c openssh-8.4p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.4p1.orig/servconf.h openssh-8.4p1/servconf.h ---- openssh-8.4p1.orig/servconf.h 2020-10-06 11:23:35.178491286 +0200 -+++ openssh-8.4p1/servconf.h 2020-10-06 11:24:20.018596893 +0200 -@@ -143,9 +143,12 @@ +diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h +--- openssh-8.5p1.orig/servconf.h 2021-03-16 18:29:34.850456888 +0100 ++++ openssh-8.5p1/servconf.h 2021-03-16 18:30:25.483567146 +0100 +@@ -145,9 +145,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2017,7 +2017,7 @@ diff -Nur openssh-8.4p1.orig/servconf.h openssh-8.4p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -204,6 +207,7 @@ +@@ -209,6 +212,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2025,10 +2025,10 @@ diff -Nur openssh-8.4p1.orig/servconf.h openssh-8.4p1/servconf.h int permit_tun; -diff -Nur openssh-8.4p1.orig/ssh.1 openssh-8.4p1/ssh.1 ---- openssh-8.4p1.orig/ssh.1 2020-10-06 11:23:35.134491183 +0200 -+++ openssh-8.4p1/ssh.1 2020-10-06 11:24:20.019596895 +0200 -@@ -1471,6 +1471,18 @@ +diff -Nur openssh-8.5p1.orig/ssh.1 openssh-8.5p1/ssh.1 +--- openssh-8.5p1.orig/ssh.1 2021-03-16 18:29:34.810456801 +0100 ++++ openssh-8.5p1/ssh.1 2021-03-16 18:30:25.484567148 +0100 +@@ -1473,6 +1473,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-8.4p1.orig/ssh.1 openssh-8.4p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c ---- openssh-8.4p1.orig/ssh.c 2020-10-06 11:23:35.246491446 +0200 -+++ openssh-8.4p1/ssh.c 2020-10-06 11:24:20.019596895 +0200 -@@ -605,6 +605,38 @@ +diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c +--- openssh-8.5p1.orig/ssh.c 2021-03-16 18:29:34.905457008 +0100 ++++ openssh-8.5p1/ssh.c 2021-03-16 18:30:25.485567150 +0100 +@@ -575,6 +575,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2066,14 +2066,14 @@ diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2081,7 +2081,7 @@ diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_arg, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2089,9 +2089,9 @@ diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1267,8 +1299,12 @@ - /* Fill configuration defaults. */ - fill_default_options(&options); +@@ -1247,8 +1279,12 @@ + if (fill_default_options(&options) != 0) + cleanup_exit(255); - if (options.user == NULL) + if (options.user == NULL) { @@ -2103,9 +2103,9 @@ diff -Nur openssh-8.4p1.orig/ssh.c openssh-8.4p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-8.4p1.orig/ssh_config openssh-8.4p1/ssh_config ---- openssh-8.4p1.orig/ssh_config 2020-10-06 11:23:35.135491185 +0200 -+++ openssh-8.4p1/ssh_config 2020-10-06 11:24:20.020596897 +0200 +diff -Nur openssh-8.5p1.orig/ssh_config openssh-8.5p1/ssh_config +--- openssh-8.5p1.orig/ssh_config 2021-03-16 18:29:34.810456801 +0100 ++++ openssh-8.5p1/ssh_config 2021-03-16 18:30:25.485567150 +0100 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.4p1.orig/ssh_config openssh-8.4p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 ---- openssh-8.4p1.orig/ssh_config.5 2020-10-06 11:23:35.205491350 +0200 -+++ openssh-8.4p1/ssh_config.5 2020-10-06 11:24:20.020596897 +0200 +diff -Nur openssh-8.5p1.orig/ssh_config.5 openssh-8.5p1/ssh_config.5 +--- openssh-8.5p1.orig/ssh_config.5 2021-03-16 18:29:34.873456938 +0100 ++++ openssh-8.5p1/ssh_config.5 2021-03-16 18:30:25.486567152 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -776,7 +782,7 @@ +@@ -775,7 +781,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -784,12 +790,12 @@ +@@ -783,12 +789,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1330,7 +1336,7 @@ +@@ -1410,7 +1416,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-8.4p1.orig/ssh_config.5 openssh-8.4p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c ---- openssh-8.4p1.orig/sshconnect2.c 2020-10-06 11:23:35.246491446 +0200 -+++ openssh-8.4p1/sshconnect2.c 2020-10-06 11:24:20.021596900 +0200 -@@ -847,6 +847,11 @@ +diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c +--- openssh-8.5p1.orig/sshconnect2.c 2021-03-16 18:29:34.906457010 +0100 ++++ openssh-8.5p1/sshconnect2.c 2021-03-16 18:30:25.487567155 +0100 +@@ -854,6 +854,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -958,7 +963,8 @@ +@@ -965,7 +970,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1128,6 +1134,20 @@ +@@ -1136,6 +1142,20 @@ return r; } @@ -2214,19 +2214,20 @@ diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1150,6 +1170,11 @@ +@@ -1158,6 +1178,12 @@ if ((b = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); +#ifdef GSI + if (options.implicit && is_gsi_oid(gss_kex_context->oid)) -+ ssh_gssapi_buildmic(b, "", authctxt->service, "gssapi-keyex"); ++ ssh_gssapi_buildmic(b, "", authctxt->service, ++ "gssapi-keyex", ssh->kex->session_id); + else +#endif ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, - "gssapi-keyex"); + "gssapi-keyex", ssh->kex->session_id); -@@ -1163,7 +1188,9 @@ +@@ -1171,7 +1197,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2237,9 +2238,9 @@ diff -Nur openssh-8.4p1.orig/sshconnect2.c openssh-8.4p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.4p1.orig/sshd.8 openssh-8.4p1/sshd.8 ---- openssh-8.4p1.orig/sshd.8 2020-10-06 11:23:35.149491218 +0200 -+++ openssh-8.4p1/sshd.8 2020-10-06 11:24:20.022596902 +0200 +diff -Nur openssh-8.5p1.orig/sshd.8 openssh-8.5p1/sshd.8 +--- openssh-8.5p1.orig/sshd.8 2021-03-16 18:29:34.824456832 +0100 ++++ openssh-8.5p1/sshd.8 2021-03-16 18:30:25.487567155 +0100 @@ -815,6 +815,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2270,10 +2271,10 @@ diff -Nur openssh-8.4p1.orig/sshd.8 openssh-8.4p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.4p1.orig/sshd.c openssh-8.4p1/sshd.c ---- openssh-8.4p1.orig/sshd.c 2020-10-06 11:23:35.255491467 +0200 -+++ openssh-8.4p1/sshd.c 2020-10-06 11:24:20.023596904 +0200 -@@ -2384,7 +2384,7 @@ +diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c +--- openssh-8.5p1.orig/sshd.c 2021-03-16 18:29:34.914457027 +0100 ++++ openssh-8.5p1/sshd.c 2021-03-16 18:30:25.488567157 +0100 +@@ -2356,7 +2356,7 @@ #endif #ifdef GSSAPI @@ -2282,9 +2283,9 @@ diff -Nur openssh-8.4p1.orig/sshd.c openssh-8.4p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.4p1.orig/sshd_config openssh-8.4p1/sshd_config ---- openssh-8.4p1.orig/sshd_config 2020-10-06 11:23:35.168491263 +0200 -+++ openssh-8.4p1/sshd_config 2020-10-06 11:24:20.023596904 +0200 +diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config +--- openssh-8.5p1.orig/sshd_config 2021-03-16 18:29:34.841456868 +0100 ++++ openssh-8.5p1/sshd_config 2021-03-16 18:30:25.488567157 +0100 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2310,10 +2311,10 @@ diff -Nur openssh-8.4p1.orig/sshd_config openssh-8.4p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.4p1.orig/sshd_config.5 openssh-8.4p1/sshd_config.5 ---- openssh-8.4p1.orig/sshd_config.5 2020-10-06 11:23:35.206491352 +0200 -+++ openssh-8.4p1/sshd_config.5 2020-10-06 11:24:20.024596907 +0200 -@@ -633,15 +633,34 @@ +diff -Nur openssh-8.5p1.orig/sshd_config.5 openssh-8.5p1/sshd_config.5 +--- openssh-8.5p1.orig/sshd_config.5 2021-03-16 18:29:34.874456941 +0100 ++++ openssh-8.5p1/sshd_config.5 2021-03-16 18:30:25.489567159 +0100 +@@ -632,15 +632,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2349,7 +2350,7 @@ diff -Nur openssh-8.4p1.orig/sshd_config.5 openssh-8.4p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -652,7 +671,7 @@ +@@ -651,7 +670,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2358,7 +2359,7 @@ diff -Nur openssh-8.4p1.orig/sshd_config.5 openssh-8.4p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1738,6 +1757,12 @@ +@@ -1773,6 +1792,12 @@ as a non-root user. The default is .Cm no . @@ -2371,10 +2372,10 @@ diff -Nur openssh-8.4p1.orig/sshd_config.5 openssh-8.4p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.4p1.orig/sshd_config_redhat openssh-8.4p1/sshd_config_redhat ---- openssh-8.4p1.orig/sshd_config_redhat 2020-10-06 11:23:35.114491135 +0200 -+++ openssh-8.4p1/sshd_config_redhat 2020-10-06 11:24:20.024596907 +0200 -@@ -10,9 +10,6 @@ +diff -Nur openssh-8.5p1.orig/sshd_config_redhat openssh-8.5p1/sshd_config_redhat +--- openssh-8.5p1.orig/sshd_config_redhat 2021-03-16 18:29:34.796456771 +0100 ++++ openssh-8.5p1/sshd_config_redhat 2021-03-16 18:30:25.489567159 +0100 +@@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2384,9 +2385,9 @@ diff -Nur openssh-8.4p1.orig/sshd_config_redhat openssh-8.4p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.4p1.orig/ssh-gss.h openssh-8.4p1/ssh-gss.h ---- openssh-8.4p1.orig/ssh-gss.h 2020-10-06 11:23:35.146491211 +0200 -+++ openssh-8.4p1/ssh-gss.h 2020-10-06 11:24:20.025596909 +0200 +diff -Nur openssh-8.5p1.orig/ssh-gss.h openssh-8.5p1/ssh-gss.h +--- openssh-8.5p1.orig/ssh-gss.h 2021-03-16 18:29:34.821456825 +0100 ++++ openssh-8.5p1/ssh-gss.h 2021-03-16 18:30:25.490567161 +0100 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2422,12 +2423,12 @@ diff -Nur openssh-8.4p1.orig/ssh-gss.h openssh-8.4p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.4p1.orig/version.h openssh-8.4p1/version.h ---- openssh-8.4p1.orig/version.h 2020-09-27 09:25:01.000000000 +0200 -+++ openssh-8.4p1/version.h 2020-10-06 11:24:20.025596909 +0200 +diff -Nur openssh-8.5p1.orig/version.h openssh-8.5p1/version.h +--- openssh-8.5p1.orig/version.h 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/version.h 2021-03-16 18:30:25.490567161 +0100 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.4" + #define SSH_VERSION "OpenSSH_8.5" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.5p1-hpn-15.2-modified.patch b/openssh-8.5p1-hpn-15.2-modified.patch new file mode 100644 index 0000000..36b9d58 --- /dev/null +++ b/openssh-8.5p1-hpn-15.2-modified.patch @@ -0,0 +1,2587 @@ +diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c +--- openssh-8.5p1.orig/auth2.c 2021-03-16 18:30:25.470567118 +0100 ++++ openssh-8.5p1/auth2.c 2021-03-16 18:34:37.852116684 +0100 +@@ -53,6 +53,8 @@ + #include "dispatch.h" + #include "pathnames.h" + #include "ssherr.h" ++#include "canohost.h" ++ + #ifdef GSSAPI + #include "ssh-gss.h" + #endif +@@ -75,6 +77,8 @@ + extern Authmethod method_gssapi; + #endif + ++static int log_flag = 0; ++ + Authmethod *authmethods[] = { + &method_none, + &method_pubkey, +@@ -299,6 +303,11 @@ + + debug("userauth-request for user %s service %s method %s", + user[0] ? user : "", service, method); ++ if (!log_flag) { ++ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), user); ++ log_flag = 1; ++ } + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + + #ifdef WITH_SELINUX +diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c +--- openssh-8.5p1.orig/channels.c 2021-03-16 18:29:34.910457019 +0100 ++++ openssh-8.5p1/channels.c 2021-03-16 18:43:25.893265131 +0100 +@@ -220,6 +220,9 @@ + /* Setup helper */ + static void channel_handler_init(struct ssh_channels *sc); + ++static int hpn_disabled = 0; ++static int hpn_buffer_size = 2 * 1024 * 1024; ++ + /* -- channel core */ + + void +@@ -395,6 +398,7 @@ + c->local_window = window; + c->local_window_max = window; + c->local_maxpacket = maxpack; ++ c->dynamic_window = 0; + c->remote_name = xstrdup(remote_name); + c->ctl_chan = -1; + c->delayed = 1; /* prevent call to channel_post handler */ +@@ -1082,6 +1086,28 @@ + FD_SET(c->sock, writeset); + } + ++static int ++channel_tcpwinsz(struct ssh *ssh) ++{ ++ u_int32_t tcpwinsz = 0; ++ socklen_t optsz = sizeof(tcpwinsz); ++ int ret = -1; ++ ++ /* if we aren't on a socket return 128KB */ ++ if (!ssh_packet_connection_is_on_socket(ssh)) ++ return 128 * 1024; ++ ++ ret = getsockopt(ssh_packet_get_connection_in(ssh), ++ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); ++ /* return no more than SSHBUF_SIZE_MAX (currently 256MB) */ ++ if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX) ++ tcpwinsz = SSHBUF_SIZE_MAX; ++ ++ debug2("tcpwinsz: tcp connection %d, Receive window: %d", ++ ssh_packet_get_connection_in(ssh), tcpwinsz); ++ return tcpwinsz; ++} ++ + static void + channel_pre_open(struct ssh *ssh, Channel *c, + fd_set *readset, fd_set *writeset) +@@ -2120,22 +2146,31 @@ + + if (c->type == SSH_CHANNEL_OPEN && + !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && +- ((c->local_window_max - c->local_window > +- c->local_maxpacket*3) || ++ ((ssh_packet_is_interactive(ssh) && ++ c->local_window_max - c->local_window > c->local_maxpacket*3) || + c->local_window < c->local_window_max/2) && + c->local_consumed > 0) { ++ u_int addition = 0; ++ u_int32_t tcpwinsz = channel_tcpwinsz(ssh); ++ /* adjust max window size if we are in a dynamic environment */ ++ if (c->dynamic_window && (tcpwinsz > c->local_window_max)) { ++ /* grow the window somewhat aggressively to maintain pressure */ ++ addition = 1.5 * (tcpwinsz - c->local_window_max); ++ c->local_window_max += addition; ++ debug("Channel: Window growth to %d by %d bytes", c->local_window_max, addition); ++ } + if (!c->have_remote_id) + fatal_f("channel %d: no remote id", c->self); + if ((r = sshpkt_start(ssh, + SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 || + (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || +- (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || ++ (r = sshpkt_put_u32(ssh, c->local_consumed + addition)) != 0 || + (r = sshpkt_send(ssh)) != 0) { + fatal_fr(r, "channel %i", c->self); + } + debug2("channel %d: window %d sent adjust %d", c->self, +- c->local_window, c->local_consumed); +- c->local_window += c->local_consumed; ++ c->local_window, c->local_consumed + addition); ++ c->local_window += c->local_consumed + addition; + c->local_consumed = 0; + } + return 1; +@@ -3302,6 +3337,14 @@ + return addr; + } + ++void ++channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size) ++{ ++ hpn_disabled = external_hpn_disabled; ++ hpn_buffer_size = external_hpn_buffer_size; ++ debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size); ++} ++ + static int + channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, + struct Forward *fwd, int *allocated_listen_port, +@@ -3442,8 +3485,10 @@ + } + + /* Allocate a channel number for the socket. */ ++ /* explicitly test for hpn disabled option. if true use smaller window size */ + c = channel_new(ssh, "port listener", type, sock, sock, -1, +- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, ++ hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : hpn_buffer_size, ++ CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); + c->path = xstrdup(host); + c->host_port = fwd->connect_port; +@@ -4627,7 +4672,8 @@ + sock = socks[n]; + nc = channel_new(ssh, "x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, +- CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, ++ hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : hpn_buffer_size, ++ CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); + nc->single_connection = single_connection; + (*chanids)[n] = nc->self; +diff -Nur openssh-8.5p1.orig/channels.h openssh-8.5p1/channels.h +--- openssh-8.5p1.orig/channels.h 2021-03-16 18:29:34.849456886 +0100 ++++ openssh-8.5p1/channels.h 2021-03-17 12:35:59.486559703 +0100 +@@ -158,8 +158,10 @@ + u_int local_window_max; + u_int local_consumed; + u_int local_maxpacket; ++ int dynamic_window; + int extended_usage; + int single_connection; ++ u_int tcpwinsz; + + char *ctype; /* type */ + +@@ -221,7 +223,7 @@ + #define CHAN_LOCAL 0x10 + + /* Read buffer size */ +-#define CHAN_RBUF (16*1024) ++#define CHAN_RBUF CHAN_SES_PACKET_DEFAULT + + /* Maximum channel input buffer size */ + #define CHAN_INPUT_MAX (16*1024*1024) +@@ -352,4 +354,7 @@ + void chan_write_failed(struct ssh *, Channel *); + void chan_obuf_empty(struct ssh *, Channel *); + ++/* hpn handler */ ++void channel_set_hpn(int, int); ++ + #endif +diff -Nur openssh-8.5p1.orig/cipher.c openssh-8.5p1/cipher.c +--- openssh-8.5p1.orig/cipher.c 2021-03-16 18:29:34.891456977 +0100 ++++ openssh-8.5p1/cipher.c 2021-03-16 18:34:37.854116688 +0100 +@@ -48,6 +48,7 @@ + #include "sshbuf.h" + #include "ssherr.h" + #include "digest.h" ++#include "log.h" + + #include "openbsd-compat/openssl-compat.h" + +@@ -55,6 +56,9 @@ + #define EVP_CIPHER_CTX void + #endif + ++/* for multi-threaded aes-ctr cipher */ ++extern const EVP_CIPHER *evp_aes_ctr_mt(void); ++ + struct sshcipher_ctx { + int plaintext; + int encrypt; +@@ -64,7 +68,7 @@ + const struct sshcipher *cipher; + }; + +-static const struct sshcipher ciphers[] = { ++static struct sshcipher ciphers[] = { + #ifdef WITH_OPENSSL + #ifndef OPENSSL_NO_DES + { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, +@@ -133,6 +137,29 @@ + #endif + } + ++/* used to get the cipher name so when force rekeying to handle the ++ * single to multithreaded ctr cipher swap we only rekey when appropriate ++ */ ++const char * ++cipher_ctx_name(const struct sshcipher_ctx *cc) ++{ ++ return cc->cipher->name; ++} ++ ++/* in order to get around sandbox and forking issues with a threaded cipher ++ * we set the initial pre-auth aes-ctr cipher to the default OpenSSH cipher ++ * post auth we set them to the new evp as defined by cipher-ctr-mt ++ */ ++#ifdef WITH_OPENSSL ++void ++cipher_reset_multithreaded(void) ++{ ++ cipher_by_name("aes128-ctr")->evptype = evp_aes_ctr_mt; ++ cipher_by_name("aes192-ctr")->evptype = evp_aes_ctr_mt; ++ cipher_by_name("aes256-ctr")->evptype = evp_aes_ctr_mt; ++} ++#endif ++ + u_int + cipher_blocksize(const struct sshcipher *c) + { +@@ -182,10 +209,10 @@ + return cc->plaintext; + } + +-const struct sshcipher * ++struct sshcipher * + cipher_by_name(const char *name) + { +- const struct sshcipher *c; ++ struct sshcipher *c; + for (c = ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; +@@ -207,7 +234,8 @@ + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + c = cipher_by_name(p); +- if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) { ++ if (c == NULL || ((c->flags & CFLAG_INTERNAL) != 0 && ++ (c->flags & CFLAG_NONE) != 0)) { + free(cipher_list); + return 0; + } +diff -Nur openssh-8.5p1.orig/cipher-ctr-mt.c openssh-8.5p1/cipher-ctr-mt.c +--- openssh-8.5p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.5p1/cipher-ctr-mt.c 2021-03-17 14:11:10.591505532 +0100 +@@ -0,0 +1,678 @@ ++/* ++ * OpenSSH Multi-threaded AES-CTR Cipher ++ * ++ * Author: Benjamin Bennett ++ * Author: Mike Tasota ++ * Author: Chris Rapier ++ * Copyright (c) 2008-2013 Pittsburgh Supercomputing Center. All rights reserved. ++ * ++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged, ++ * Copyright (c) 2003 Markus Friedl ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#include "includes.h" ++ ++#if defined(WITH_OPENSSL) ++#include ++ ++#include ++#include ++ ++#include ++ ++#include "xmalloc.h" ++#include "log.h" ++#include ++ ++/* compatibility with old or broken OpenSSL versions */ ++#include "openbsd-compat/openssl-compat.h" ++ ++#ifndef USE_BUILTIN_RIJNDAEL ++#include ++#endif ++ ++#include ++ ++/*-------------------- TUNABLES --------------------*/ ++/* maximum number of threads and queues */ ++#define MAX_THREADS 32 ++#define MAX_NUMKQ (MAX_THREADS * 2) ++ ++/* Number of pregen threads to use */ ++int cipher_threads = 2; ++ ++/* Number of keystream queues */ ++int numkq = 4; ++ ++/* Length of a keystream queue */ ++#define KQLEN 4096 ++ ++/* Processor cacheline length */ ++#define CACHELINE_LEN 64 ++ ++/* Collect thread stats and print at cancellation when in debug mode */ ++#define CIPHER_THREAD_STATS ++ ++/* Can the system do unaligned loads natively? */ ++#if defined(__aarch64__) || \ ++ defined(__i386__) || \ ++ defined(__powerpc__) || \ ++ defined(__x86_64__) ++# define CIPHER_UNALIGNED_OK ++#endif ++#if defined(__SIZEOF_INT128__) ++# define CIPHER_INT128_OK ++#endif ++/*-------------------- END TUNABLES --------------------*/ ++ ++ ++const EVP_CIPHER *evp_aes_ctr_mt(void); ++ ++#ifdef CIPHER_THREAD_STATS ++/* ++ * Struct to collect thread stats ++ */ ++struct thread_stats { ++ u_int fills; ++ u_int skips; ++ u_int waits; ++ u_int drains; ++}; ++ ++/* ++ * Debug print the thread stats ++ * Use with pthread_cleanup_push for displaying at thread cancellation ++ */ ++static void ++thread_loop_stats(void *x) ++{ ++ struct thread_stats *s = x; ++ debug("AES-CTR MT tid %lu - %u fills, %u skips, %u waits", pthread_self(), ++ s->fills, s->skips, s->waits); ++} ++ ++# define STATS_STRUCT(s) struct thread_stats s ++# define STATS_INIT(s) { memset(&s, 0, sizeof(s)); } ++# define STATS_FILL(s) { s.fills++; } ++# define STATS_SKIP(s) { s.skips++; } ++# define STATS_WAIT(s) { s.waits++; } ++# define STATS_DRAIN(s) { s.drains++; } ++#else ++# define STATS_STRUCT(s) ++# define STATS_INIT(s) ++# define STATS_FILL(s) ++# define STATS_SKIP(s) ++# define STATS_WAIT(s) ++# define STATS_DRAIN(s) ++#endif ++ ++/* Keystream Queue state */ ++enum { ++ KQINIT, ++ KQEMPTY, ++ KQFILLING, ++ KQFULL, ++ KQDRAINING ++}; ++ ++/* Keystream Queue struct */ ++struct kq { ++ u_char keys[KQLEN][AES_BLOCK_SIZE]; ++ u_char ctr[AES_BLOCK_SIZE]; ++ u_char pad0[CACHELINE_LEN]; ++ int qstate; ++ pthread_mutex_t lock; ++ pthread_cond_t cond; ++ u_char pad1[CACHELINE_LEN]; ++}; ++ ++/* Context struct */ ++struct ssh_aes_ctr_ctx_mt ++{ ++ int struct_id; ++ struct kq q[MAX_NUMKQ]; ++ AES_KEY aes_ctx; ++ STATS_STRUCT(stats); ++ u_char aes_counter[AES_BLOCK_SIZE]; ++ pthread_t tid[MAX_THREADS]; ++ int id[MAX_THREADS]; ++ pthread_rwlock_t tid_lock; ++#ifdef __APPLE__ ++ pthread_rwlock_t stop_lock; ++ int exit_flag; ++#endif /* __APPLE__ */ ++ int state; ++ int qidx; ++ int ridx; ++}; ++ ++/* ++ * increment counter 'ctr', ++ * the counter is of size 'len' bytes and stored in network-byte-order. ++ * (LSB at ctr[len-1], MSB at ctr[0]) ++ */ ++static void ++ssh_ctr_inc(u_char *ctr, size_t len) ++{ ++ int i; ++ ++ for (i = len - 1; i >= 0; i--) ++ if (++ctr[i]) /* continue on overflow */ ++ return; ++} ++ ++/* ++ * Add num to counter 'ctr' ++ */ ++static void ++ssh_ctr_add(u_char *ctr, uint32_t num, u_int len) ++{ ++ int i; ++ uint16_t n; ++ ++ for (n = 0, i = len - 1; i >= 0 && (num || n); i--) { ++ n = ctr[i] + (num & 0xff) + n; ++ num >>= 8; ++ ctr[i] = n & 0xff; ++ n >>= 8; ++ } ++} ++ ++/* ++ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex ++ */ ++static void ++thread_loop_cleanup(void *x) ++{ ++ pthread_mutex_unlock((pthread_mutex_t *)x); ++} ++ ++#ifdef __APPLE__ ++/* Check if we should exit, we are doing both cancel and exit condition ++ * since on OSX threads seem to occasionally fail to notice when they have ++ * been cancelled. We want to have a backup to make sure that we won't hang ++ * when the main process join()-s the cancelled thread. ++ */ ++static void ++thread_loop_check_exit(struct ssh_aes_ctr_ctx_mt *c) ++{ ++ int exit_flag; ++ ++ pthread_rwlock_rdlock(&c->stop_lock); ++ exit_flag = c->exit_flag; ++ pthread_rwlock_unlock(&c->stop_lock); ++ ++ if (exit_flag) ++ pthread_exit(NULL); ++} ++#else ++# define thread_loop_check_exit(s) ++#endif /* __APPLE__ */ ++ ++/* ++ * Helper function to terminate the helper threads ++ */ ++static void ++stop_and_join_pregen_threads(struct ssh_aes_ctr_ctx_mt *c) ++{ ++ int i; ++ ++#ifdef __APPLE__ ++ /* notify threads that they should exit */ ++ pthread_rwlock_wrlock(&c->stop_lock); ++ c->exit_flag = TRUE; ++ pthread_rwlock_unlock(&c->stop_lock); ++#endif /* __APPLE__ */ ++ ++ /* Cancel pregen threads */ ++ for (i = 0; i < cipher_threads; i++) { ++ debug ("Canceled %lu (%d,%d)", c->tid[i], c->struct_id, c->id[i]); ++ pthread_cancel(c->tid[i]); ++ } ++ /* shouldn't need this - see commit logs for hpn-7_7_P1 -cjr 11/7/19*/ ++ /* for (i = 0; i < numkq; i++) { */ ++ /* pthread_mutex_lock(&c->q[i].lock); */ ++ /* pthread_cond_broadcast(&c->q[i].cond); */ ++ /* pthread_mutex_unlock(&c->q[i].lock); */ ++ /* } */ ++ for (i = 0; i < cipher_threads; i++) { ++ if (pthread_kill(c->tid[i], 0) != 0) ++ debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", c->tid[i], __FUNCTION__); ++ else { ++ debug ("Joining %lu (%d, %d)", c->tid[i], c->struct_id, c->id[i]); ++ pthread_join(c->tid[i], NULL); ++ } ++ } ++} ++ ++/* ++ * The life of a pregen thread: ++ * Find empty keystream queues and fill them using their counter. ++ * When done, update counter for the next fill. ++ */ ++static void * ++thread_loop(void *x) ++{ ++ AES_KEY key; ++ STATS_STRUCT(stats); ++ struct ssh_aes_ctr_ctx_mt *c = x; ++ struct kq *q; ++ int i; ++ int qidx; ++ pthread_t first_tid; ++ ++ /* Threads stats on cancellation */ ++ STATS_INIT(stats); ++#ifdef CIPHER_THREAD_STATS ++ pthread_cleanup_push(thread_loop_stats, &stats); ++#endif ++ ++ /* Thread local copy of AES key */ ++ memcpy(&key, &c->aes_ctx, sizeof(key)); ++ ++ pthread_rwlock_rdlock(&c->tid_lock); ++ first_tid = c->tid[0]; ++ pthread_rwlock_unlock(&c->tid_lock); ++ ++ /* ++ * Handle the special case of startup, one thread must fill ++ * the first KQ then mark it as draining. Lock held throughout. ++ */ ++ if (pthread_equal(pthread_self(), first_tid)) { ++ q = &c->q[0]; ++ pthread_mutex_lock(&q->lock); ++ if (q->qstate == KQINIT) { ++ for (i = 0; i < KQLEN; i++) { ++ AES_encrypt(q->ctr, q->keys[i], &key); ++ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE); ++ } ++ ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE); ++ q->qstate = KQDRAINING; ++ STATS_FILL(stats); ++ pthread_cond_broadcast(&q->cond); ++ } ++ pthread_mutex_unlock(&q->lock); ++ } else ++ STATS_SKIP(stats); ++ ++ /* ++ * Normal case is to find empty queues and fill them, skipping over ++ * queues already filled by other threads and stopping to wait for ++ * a draining queue to become empty. ++ * ++ * Multiple threads may be waiting on a draining queue and awoken ++ * when empty. The first thread to wake will mark it as filling, ++ * others will move on to fill, skip, or wait on the next queue. ++ */ ++ for (qidx = 1;; qidx = (qidx + 1) % numkq) { ++ /* Check if I was cancelled, also checked in cond_wait */ ++ pthread_testcancel(); ++ ++ /* Check if we should exit as well */ ++ thread_loop_check_exit(c); ++ ++ /* Lock queue and block if its draining */ ++ q = &c->q[qidx]; ++ pthread_mutex_lock(&q->lock); ++ pthread_cleanup_push(thread_loop_cleanup, &q->lock); ++ while (q->qstate == KQDRAINING || q->qstate == KQINIT) { ++ STATS_WAIT(stats); ++ thread_loop_check_exit(c); ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ pthread_cleanup_pop(0); ++ ++ /* If filling or full, somebody else got it, skip */ ++ if (q->qstate != KQEMPTY) { ++ pthread_mutex_unlock(&q->lock); ++ STATS_SKIP(stats); ++ continue; ++ } ++ ++ /* ++ * Empty, let's fill it. ++ * Queue lock is relinquished while we do this so others ++ * can see that it's being filled. ++ */ ++ q->qstate = KQFILLING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ for (i = 0; i < KQLEN; i++) { ++ AES_encrypt(q->ctr, q->keys[i], &key); ++ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE); ++ } ++ ++ /* Re-lock, mark full and signal consumer */ ++ pthread_mutex_lock(&q->lock); ++ ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE); ++ q->qstate = KQFULL; ++ STATS_FILL(stats); ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ } ++ ++#ifdef CIPHER_THREAD_STATS ++ /* Stats */ ++ pthread_cleanup_pop(1); ++#endif ++ ++ return NULL; ++} ++ ++static int ++ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, ++ LIBCRYPTO_EVP_INL_TYPE len) ++{ ++ typedef union { ++#ifdef CIPHER_INT128_OK ++ __uint128_t *u128; ++#endif ++ uint64_t *u64; ++ uint32_t *u32; ++ uint8_t *u8; ++ const uint8_t *cu8; ++ uintptr_t u; ++ } ptrs_t; ++ ptrs_t destp, srcp, bufp; ++ uintptr_t align; ++ struct ssh_aes_ctr_ctx_mt *c; ++ struct kq *q, *oldq; ++ int ridx; ++ u_char *buf; ++ ++ if (len == 0) ++ return 1; ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) ++ return 0; ++ ++ q = &c->q[c->qidx]; ++ ridx = c->ridx; ++ ++ /* src already padded to block multiple */ ++ srcp.cu8 = src; ++ destp.u8 = dest; ++ while (len > 0) { ++ buf = q->keys[ridx]; ++ bufp.u8 = buf; ++ ++ /* figure out the alignment on the fly */ ++#ifdef CIPHER_UNALIGNED_OK ++ align = 0; ++#else ++ align = destp.u | srcp.u | bufp.u; ++#endif ++ ++#ifdef CIPHER_INT128_OK ++ if ((align & 0xf) == 0) { ++ destp.u128[0] = srcp.u128[0] ^ bufp.u128[0]; ++ } else ++#endif ++ if ((align & 0x7) == 0) { ++ destp.u64[0] = srcp.u64[0] ^ bufp.u64[0]; ++ destp.u64[1] = srcp.u64[1] ^ bufp.u64[1]; ++ } else if ((align & 0x3) == 0) { ++ destp.u32[0] = srcp.u32[0] ^ bufp.u32[0]; ++ destp.u32[1] = srcp.u32[1] ^ bufp.u32[1]; ++ destp.u32[2] = srcp.u32[2] ^ bufp.u32[2]; ++ destp.u32[3] = srcp.u32[3] ^ bufp.u32[3]; ++ } else { ++ size_t i; ++ for (i = 0; i < AES_BLOCK_SIZE; ++i) ++ dest[i] = src[i] ^ buf[i]; ++ } ++ ++ destp.u += AES_BLOCK_SIZE; ++ srcp.u += AES_BLOCK_SIZE; ++ len -= AES_BLOCK_SIZE; ++ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); ++ ++ /* Increment read index, switch queues on rollover */ ++ if ((ridx = (ridx + 1) % KQLEN) == 0) { ++ oldq = q; ++ ++ /* Mark next queue draining, may need to wait */ ++ c->qidx = (c->qidx + 1) % numkq; ++ q = &c->q[c->qidx]; ++ pthread_mutex_lock(&q->lock); ++ while (q->qstate != KQFULL) { ++ STATS_WAIT(c->stats); ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ q->qstate = KQDRAINING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ ++ /* Mark consumed queue empty and signal producers */ ++ pthread_mutex_lock(&oldq->lock); ++ oldq->qstate = KQEMPTY; ++ STATS_DRAIN(c->stats); ++ pthread_cond_broadcast(&oldq->cond); ++ pthread_mutex_unlock(&oldq->lock); ++ } ++ } ++ c->ridx = ridx; ++ return 1; ++} ++ ++#define HAVE_NONE 0 ++#define HAVE_KEY 1 ++#define HAVE_IV 2 ++ ++int X = 0; ++ ++static int ++ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, ++ int enc) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ int i; ++ ++ /* get the number of cores in the system */ ++ /* if it's not linux it currently defaults to 2 */ ++ /* divide by 2 to get threads for each direction (MODE_IN||MODE_OUT) */ ++#ifdef __linux__ ++ cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; ++#endif /*__linux__*/ ++#ifdef __APPLE__ ++ cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; ++#endif /*__APPLE__*/ ++#ifdef __FREEBSD__ ++ int req[2]; ++ size_t len; ++ ++ req[0] = CTL_HW; ++ req[1] = HW_NCPU; ++ ++ len = sizeof(ncpu); ++ sysctl(req, 2, &cipher_threads, &len, NULL, 0); ++ cipher_threads = cipher_threads / 2; ++#endif /*__FREEBSD__*/ ++ ++ /* if they have less than 4 cores spin up 4 threads anyway */ ++ if (cipher_threads < 2) ++ cipher_threads = 2; ++ ++ /* assure that we aren't trying to create more threads */ ++ /* than we have in the struct. cipher_threads is half the */ ++ /* total of allowable threads hence the odd looking math here */ ++ if (cipher_threads * 2 > MAX_THREADS) ++ cipher_threads = MAX_THREADS / 2; ++ ++ /* set the number of keystream queues */ ++ numkq = cipher_threads * 2; ++ ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { ++ c = xmalloc(sizeof(*c)); ++ pthread_rwlock_init(&c->tid_lock, NULL); ++#ifdef __APPLE__ ++ pthread_rwlock_init(&c->stop_lock, NULL); ++ c->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ c->state = HAVE_NONE; ++ for (i = 0; i < numkq; i++) { ++ pthread_mutex_init(&c->q[i].lock, NULL); ++ pthread_cond_init(&c->q[i].cond, NULL); ++ } ++ ++ STATS_INIT(c->stats); ++ EVP_CIPHER_CTX_set_app_data(ctx, c); ++ } ++ ++ if (c->state == (HAVE_KEY | HAVE_IV)) { ++ /* tell the pregen threads to exit */ ++ stop_and_join_pregen_threads(c); ++ ++#ifdef __APPLE__ ++ /* reset the exit flag */ ++ c->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ /* Start over getting key & iv */ ++ c->state = HAVE_NONE; ++ } ++ ++ if (key != NULL) { ++ AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, ++ &c->aes_ctx); ++ c->state |= HAVE_KEY; ++ } ++ ++ if (iv != NULL) { ++ memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); ++ c->state |= HAVE_IV; ++ } ++ ++ if (c->state == (HAVE_KEY | HAVE_IV)) { ++ /* Clear queues */ ++ memcpy(c->q[0].ctr, c->aes_counter, AES_BLOCK_SIZE); ++ c->q[0].qstate = KQINIT; ++ for (i = 1; i < numkq; i++) { ++ memcpy(c->q[i].ctr, c->aes_counter, AES_BLOCK_SIZE); ++ ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE); ++ c->q[i].qstate = KQEMPTY; ++ } ++ c->qidx = 0; ++ c->ridx = 0; ++ ++ /* Start threads */ ++ for (i = 0; i < cipher_threads; i++) { ++ pthread_rwlock_wrlock(&c->tid_lock); ++ if (pthread_create(&c->tid[i], NULL, thread_loop, c) != 0) ++ debug ("AES-CTR MT Could not create thread in %s", __FUNCTION__); /*should die here */ ++ else { ++ if (!c->struct_id) ++ c->struct_id = X++; ++ c->id[i] = i; ++ debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]); ++ } ++ pthread_rwlock_unlock(&c->tid_lock); ++ } ++ pthread_mutex_lock(&c->q[0].lock); ++ while (c->q[0].qstate == KQINIT) ++ pthread_cond_wait(&c->q[0].cond, &c->q[0].lock); ++ pthread_mutex_unlock(&c->q[0].lock); ++ } ++ return 1; ++} ++ ++/* this function is no longer used but might prove handy in the future ++ * this comment also applies to ssh_aes_ctr_thread_reconstruction ++ */ ++void ++ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ ++ c = EVP_CIPHER_CTX_get_app_data(ctx); ++ stop_and_join_pregen_threads(c); ++} ++ ++void ++ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ int i; ++ c = EVP_CIPHER_CTX_get_app_data(ctx); ++ /* reconstruct threads */ ++ for (i = 0; i < cipher_threads; i++) { ++ pthread_rwlock_wrlock(&c->tid_lock); ++ if (pthread_create(&c->tid[i], NULL, thread_loop, c) !=0 ) ++ debug("AES-CTR MT could not create thread in %s", __FUNCTION__); ++ else { ++ c->struct_id = X++; ++ c->id[i] = i; ++ debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]); ++ debug("AES-CTR MT spawned a thread with id %lu in %s", c->tid[i], __FUNCTION__); ++ } ++ pthread_rwlock_unlock(&c->tid_lock); ++ } ++} ++ ++static int ++ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { ++#ifdef CIPHER_THREAD_STATS ++ debug("AES-CTR MT main thread: %u drains, %u waits", c->stats.drains, ++ c->stats.waits); ++#endif ++ stop_and_join_pregen_threads(c); ++ ++ memset(c, 0, sizeof(*c)); ++ free(c); ++ EVP_CIPHER_CTX_set_app_data(ctx, NULL); ++ } ++ return 1; ++} ++ ++/* */ ++const EVP_CIPHER * ++evp_aes_ctr_mt(void) ++{ ++# if OPENSSL_VERSION_NUMBER >= 0x10100000UL ++ static EVP_CIPHER *aes_ctr; ++ aes_ctr = EVP_CIPHER_meth_new(NID_undef, 16/*block*/, 16/*key*/); ++ EVP_CIPHER_meth_set_iv_length(aes_ctr, AES_BLOCK_SIZE); ++ EVP_CIPHER_meth_set_init(aes_ctr, ssh_aes_ctr_init); ++ EVP_CIPHER_meth_set_cleanup(aes_ctr, ssh_aes_ctr_cleanup); ++ EVP_CIPHER_meth_set_do_cipher(aes_ctr, ssh_aes_ctr); ++# ifndef SSH_OLD_EVP ++ EVP_CIPHER_meth_set_flags(aes_ctr, EVP_CIPH_CBC_MODE ++ | EVP_CIPH_VARIABLE_LENGTH ++ | EVP_CIPH_ALWAYS_CALL_INIT ++ | EVP_CIPH_CUSTOM_IV); ++# endif /*SSH_OLD_EVP*/ ++ return (aes_ctr); ++# else /*earlier versions of openssl*/ ++ static EVP_CIPHER aes_ctr; ++ memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); ++ aes_ctr.nid = NID_undef; ++ aes_ctr.block_size = AES_BLOCK_SIZE; ++ aes_ctr.iv_len = AES_BLOCK_SIZE; ++ aes_ctr.key_len = 16; ++ aes_ctr.init = ssh_aes_ctr_init; ++ aes_ctr.cleanup = ssh_aes_ctr_cleanup; ++ 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; ++# endif /*SSH_OLD_EVP*/ ++ return &aes_ctr; ++# endif /*OPENSSH_VERSION_NUMBER*/ ++} ++ ++#endif /* defined(WITH_OPENSSL) */ +diff -Nur openssh-8.5p1.orig/cipher.h openssh-8.5p1/cipher.h +--- openssh-8.5p1.orig/cipher.h 2021-03-16 18:29:34.891456977 +0100 ++++ openssh-8.5p1/cipher.h 2021-03-16 18:51:58.700380071 +0100 +@@ -68,7 +68,9 @@ + + struct sshcipher_ctx; + +-const struct sshcipher *cipher_by_name(const char *); ++void ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx); // defined in cipher-ctr-mt.c ++void ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx); ++struct sshcipher *cipher_by_name(const char *); + const char *cipher_warning_message(const struct sshcipher_ctx *); + int ciphers_valid(const char *); + char *cipher_alg_list(char, int); +@@ -86,6 +88,8 @@ + u_int cipher_authlen(const struct sshcipher *); + u_int cipher_ivlen(const struct sshcipher *); + u_int cipher_is_cbc(const struct sshcipher *); ++void cipher_reset_multithreaded(void); ++const char *cipher_ctx_name(const struct sshcipher_ctx *); + + u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); + +diff -Nur openssh-8.5p1.orig/clientloop.c openssh-8.5p1/clientloop.c +--- openssh-8.5p1.orig/clientloop.c 2021-03-16 18:29:34.803456786 +0100 ++++ openssh-8.5p1/clientloop.c 2021-03-16 18:58:20.875166146 +0100 +@@ -1593,7 +1593,9 @@ + return NULL; + c = channel_new(ssh, "x11", + SSH_CHANNEL_X11_OPEN, sock, sock, -1, +- CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); ++ /* again is this really necessary for X11? */ ++ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, ++ CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); + c->force_drain = 1; + return c; + } +@@ -1622,7 +1624,8 @@ + } + c = channel_new(ssh, "authentication agent connection", + SSH_CHANNEL_OPEN, sock, sock, -1, +- CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, ++ options.hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : options.hpn_buffer_size, ++ CHAN_TCP_PACKET_DEFAULT, 0, + "authentication agent connection", 1); + c->force_drain = 1; + return c; +@@ -1649,7 +1652,8 @@ + debug("Tunnel forwarding using interface %s", ifname); + + c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, +- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); ++ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, ++ CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; + + #if defined(SSH_TUN_FILTER) +diff -Nur openssh-8.5p1.orig/compat.c openssh-8.5p1/compat.c +--- openssh-8.5p1.orig/compat.c 2021-03-16 18:29:34.886456967 +0100 ++++ openssh-8.5p1/compat.c 2021-03-17 20:59:17.675130767 +0100 +@@ -150,6 +150,17 @@ + debug_f("match: %s pat %s compat 0x%08x", + version, check[i].pat, check[i].bugs); + ssh->compat = check[i].bugs; ++ /* Check to see if the remote side is OpenSSH and not HPN */ ++ /* TODO: See if we can work this into the new method for bug checks */ ++ if (strstr(version, "OpenSSH") != NULL) { ++ if (strstr(version, "hpn") == NULL) { ++ ssh->compat |= SSH_BUG_LARGEWINDOW; ++ debug("Remote is NOT HPN enabled"); ++ } else { ++ debug("Remote is HPN Enabled"); ++ } ++ } ++ debug("ssh->compat is %u", ssh->compat); + return; + } + } +diff -Nur openssh-8.5p1.orig/compat.h openssh-8.5p1/compat.h +--- openssh-8.5p1.orig/compat.h 2021-03-16 18:29:34.885456964 +0100 ++++ openssh-8.5p1/compat.h 2021-03-16 18:34:37.857116694 +0100 +@@ -57,6 +57,7 @@ + #define SSH_BUG_CURVE25519PAD 0x10000000 + #define SSH_BUG_HOSTKEYS 0x20000000 + #define SSH_BUG_DHGEX_LARGE 0x40000000 ++#define SSH_BUG_LARGEWINDOW 0x80000000 + + struct ssh; + +diff -Nur openssh-8.5p1.orig/defines.h openssh-8.5p1/defines.h +--- openssh-8.5p1.orig/defines.h 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/defines.h 2021-03-16 18:34:37.857116694 +0100 +@@ -848,7 +848,7 @@ + #endif + + #ifndef SSH_IOBUFSZ +-# define SSH_IOBUFSZ 8192 ++# define SSH_IOBUFSZ 32*1024 + #endif + + /* +diff -Nur openssh-8.5p1.orig/digest.h openssh-8.5p1/digest.h +--- openssh-8.5p1.orig/digest.h 2021-03-16 18:29:34.875456943 +0100 ++++ openssh-8.5p1/digest.h 2021-03-16 19:00:44.631455264 +0100 +@@ -27,7 +27,8 @@ + #define SSH_DIGEST_SHA256 2 + #define SSH_DIGEST_SHA384 3 + #define SSH_DIGEST_SHA512 4 +-#define SSH_DIGEST_MAX 5 ++#define SSH_DIGEST_NULL 5 ++#define SSH_DIGEST_MAX 6 + + struct sshbuf; + struct ssh_digest_ctx; +diff -Nur openssh-8.5p1.orig/digest-openssl.c openssh-8.5p1/digest-openssl.c +--- openssh-8.5p1.orig/digest-openssl.c 2021-03-16 18:29:34.875456943 +0100 ++++ openssh-8.5p1/digest-openssl.c 2021-03-16 18:34:37.858116696 +0100 +@@ -61,6 +61,7 @@ + { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, + { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, + { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, ++ { SSH_DIGEST_NULL, "NONEMAC", 0, EVP_md_null}, + { -1, NULL, 0, NULL }, + }; + +diff -Nur openssh-8.5p1.orig/HPN-README openssh-8.5p1/HPN-README +--- openssh-8.5p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.5p1/HPN-README 2021-03-17 09:11:09.298157429 +0100 +@@ -0,0 +1,153 @@ ++Notes: ++ ++MULTI-THREADED CIPHER: ++The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations ++on hosts with multiple cores to use more than one processing core during encryption. ++Tests have show significant throughput performance increases when using MTR-AES-CTR up ++to and including a full gigabit per second on quad core systems. It should be possible to ++achieve full line rate on dual core systems but OS and data management overhead makes this ++more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single ++thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal ++performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. ++The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same ++nomenclature. ++Use examples: ++ ssh -caes128-ctr you@host.com ++ scp -oCipher=aes256-ctr file you@host.com:~/file ++ ++NONE CIPHER: ++To use the NONE option you must have the NoneEnabled switch set on the server and ++you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE ++feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not ++spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will ++be disabled. ++ ++The performance increase will only be as good as the network and TCP stack tuning ++on the reciever side of the connection allows. As a rule of thumb a user will need ++at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The ++HPN-SSH home page describes this in greater detail. ++ ++http://www.psc.edu/networking/projects/hpn-ssh ++ ++NONE MAC: ++Starting with HPN 15v1 users will have the option to disable HMAC (message ++authentication ciphers) when using the NONE cipher. You must enable the following: ++NoneEnabled, NoneSwitch, and NoneMacEnabled. If all three are not enabled the None MAC ++will be automatically disabled. In tests the use of the None MAC improved throuput by ++more than 30%. ++ ++ex: scp -oNoneSwitch=yes -oNoneEnabled=yes -oNoneMacEnabled=yes file host:~ ++ ++BUFFER SIZES: ++ ++If HPN is disabled the receive buffer size will be set to the ++OpenSSH default of 2MB (for OpenSSH versions before 4.7: 64KB). ++ ++If an HPN system connects to a nonHPN system the receive buffer will ++be set to the HPNBufferSize value. The default is 2MB but user adjustable. ++ ++If an HPN to HPN connection is established a number of different things might ++happen based on the user options and conditions. ++ ++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set ++HPN Buffer Size = up to 64MB ++This is the default state. The HPN buffer size will grow to a maximum of 64MB ++as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is ++geared towards 10GigE transcontinental connections. ++ ++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set ++HPN Buffer Size = TCP receive buffer value. ++Users on non-autotuning systems should disable TCPRcvBufPoll in the ++ssh_config and sshd_config ++ ++Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set ++HPN Buffer Size = minimum of TCP receive buffer and HPNBufferSize. ++This would be the system defined TCP receive buffer (RWIN). ++ ++Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET ++HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize. ++Generally there is no need to set both. ++ ++Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set ++HPN Buffer Size = grows to HPNBufferSize ++The buffer will grow up to the maximum size specified here. ++ ++Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET ++HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize. ++Generally there is no need to set both of these, especially on autotuning ++systems. However, if the users wishes to override the autotuning this would be ++one way to do it. ++ ++Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET ++HPN Buffer Size = TCPRcvBuf. ++This will override autotuning and set the TCP recieve buffer to the user defined ++value. ++ ++ ++HPN Specific Configuration options ++ ++TcpRcvBuf=[int]KB client ++ Set the TCP socket receive buffer to n Kilobytes. It can be set up to the ++maximum socket size allowed by the system. This is useful in situations where ++the tcp receive window is set low but the maximum buffer size is set ++higher (as is typical). This works on a per TCP connection basis. You can also ++use this to artifically limit the transfer rate of the connection. In these ++cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. ++Default is the current system wide tcp receive buffer size. ++ ++TcpRcvBufPoll=[yes/no] client/server ++ Enable of disable the polling of the tcp receive buffer through the life ++of the connection. You would want to make sure that this option is enabled ++for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) ++default is yes. ++ ++NoneEnabled=[yes/no] client/server ++ Enable or disable the use of the None cipher. Care must always be used ++when enabling this as it will allow users to send data in the clear. However, ++it is important to note that authentication information remains encrypted ++even if this option is enabled. Set to no by default. ++ ++NoneMacEnabled=[yes/no] client/server ++ Enable or disable the use of the None MAC. When this is enabled ssh ++will *not* provide data integrity of any data being transmitted between hosts. Use ++with caution as it, unlike just using NoneEnabled, doesn't provide data integrity and ++protection against man-in-the-middle attacks. As with NoneEnabled all authentication ++remains encrypted and integrity is ensured. Default is no. ++ ++NoneSwitch=[yes/no] client ++ Switch the encryption cipher being used to the None cipher after ++authentication takes place. NoneEnabled must be enabled on both the client ++and server side of the connection. When the connection switches to the NONE ++cipher a warning is sent to STDERR. The connection attempt will fail with an ++error if a client requests a NoneSwitch from the server that does not explicitly ++have NoneEnabled set to yes. Note: The NONE cipher cannot be used in ++interactive (shell) sessions and it will fail silently. Set to no by default. ++ ++HPNDisabled=[yes/no] client/server ++ In some situations, such as transfers on a local area network, the impact ++of the HPN code produces a net decrease in performance. In these cases it is ++helpful to disable the HPN functionality. By default HPNDisabled is set to no. ++ ++HPNBufferSize=[int]KB client/server ++ This is the default buffer size the HPN functionality uses when interacting ++with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf ++option as applied to the internal SSH flow control. This value can range from ++1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance ++problems depending on the length of the network path. The default size of this buffer ++is 2MB. ++ ++DisableMTAES=[yes/no] client/server ++ Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher ++back to the stock single-threaded AES-CTR cipher. Useful on modern processors with ++AES-NI instructions which make the stock single-threaded AES-CTR cipher faster than ++the multithreaded MT-AES-CTR cipher. Set to no by default. ++ ++ ++Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu) ++ The majority of the actual coding for versions up to HPN12v1 was performed ++ by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was ++ implemented by Ben Bennet (ben@psc.edu) and improved by Mike Tasota ++ (tasota@gmail.com) an NSF REU grant recipient for 2013. ++ Allan Jude provided the code for the NoneMac and buffer normalization. ++ This work was financed, in part, by Cisco System, Inc., the National ++ Library of Medicine, and the National Science Foundation. +diff -Nur openssh-8.5p1.orig/kex.c openssh-8.5p1/kex.c +--- openssh-8.5p1.orig/kex.c 2021-03-16 18:29:34.902457001 +0100 ++++ openssh-8.5p1/kex.c 2021-03-16 18:34:37.859116699 +0100 +@@ -64,6 +64,7 @@ + + #include "ssherr.h" + #include "sshbuf.h" ++#include "canohost.h" + #include "digest.h" + #include "audit.h" + +@@ -969,6 +970,11 @@ + int nenc, nmac, ncomp; + u_int mode, ctos, need, dh_need, authlen; + int r, first_kex_follows; ++ int auth_flag = 0; ++ int log_flag = 0; ++ ++ auth_flag = packet_authentication_state(ssh); ++ debug("AUTH STATE IS %d", auth_flag); + + debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); + if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) +@@ -1039,11 +1045,40 @@ + peer[ncomp] = NULL; + goto out; + } ++ debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); ++ debug("REQUESTED MAC.NAME is '%s'", newkeys->mac.name); ++ if (strcmp(newkeys->enc.name, "none") == 0) { ++ if (auth_flag == 1) { ++ debug("None requested post authentication."); ++ ssh->none = 1; ++ } ++ else ++ fatal("Pre-authentication none cipher requests are not allowed."); ++ if (newkeys->mac.name != NULL && strcmp(newkeys->mac.name, "none") == 0) ++ debug("Requesting: NONEMAC. Authflag is %d", auth_flag); ++ } ++ + debug("kex: %s cipher: %s MAC: %s compression: %s", + ctos ? "client->server" : "server->client", + newkeys->enc.name, + authlen == 0 ? newkeys->mac.name : "", + newkeys->comp.name); ++ /* ++ * client starts with ctos = 0 && log flag = 0 and no log. ++ * 2nd client pass ctos = 1 and flag = 1 so no log. ++ * server starts with ctos = 1 && log_flag = 0 so log. ++ * 2nd sever pass ctos = 1 && log flag = 1 so no log. ++ * -cjr ++ */ ++ if (ctos && !log_flag) { ++ logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s", ++ ssh_remote_ipaddr(ssh), ++ ssh_remote_port(ssh), ++ newkeys->enc.name, ++ authlen == 0 ? newkeys->mac.name : "", ++ newkeys->comp.name); ++ } ++ log_flag = 1; + } + need = dh_need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { +@@ -1391,7 +1426,7 @@ + if (version_addendum != NULL && *version_addendum == '\0') + version_addendum = NULL; + if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", +- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, + version_addendum == NULL ? "" : " ", + version_addendum == NULL ? "" : version_addendum)) != 0) { + oerrno = errno; +@@ -1527,6 +1562,14 @@ + r = SSH_ERR_INVALID_FORMAT; + goto out; + } ++ ++ /* report the version information to syslog if this is the server */ ++ if (timeout_ms == -1) { /* only the server uses this value */ ++ logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ++ remote_major, remote_minor, remote_version); ++ } ++ + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + compat_banner(ssh, remote_version); +diff -Nur openssh-8.5p1.orig/log.c openssh-8.5p1/log.c +--- openssh-8.5p1.orig/log.c 2021-03-16 18:29:34.834456853 +0100 ++++ openssh-8.5p1/log.c 2021-03-16 18:34:37.859116699 +0100 +@@ -46,6 +46,11 @@ + #include + #include + #include ++#include "packet.h" /* needed for host and port look ups */ ++#ifdef HAVE_SYS_TIME_H ++# include /* to get current time */ ++#endif ++ + #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) + # include + #endif +@@ -65,6 +70,8 @@ + + extern char *__progname; + ++extern struct ssh *active_state; ++ + #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) + #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) + +diff -Nur openssh-8.5p1.orig/mac.c openssh-8.5p1/mac.c +--- openssh-8.5p1.orig/mac.c 2021-03-16 18:29:34.892456980 +0100 ++++ openssh-8.5p1/mac.c 2021-03-16 18:34:37.859116699 +0100 +@@ -63,6 +63,7 @@ + { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, + { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, + { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, ++ { "none", SSH_DIGEST, SSH_DIGEST_NULL, 0, 0, 0, 0 }, + { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, + { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, + +diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in +--- openssh-8.5p1.orig/Makefile.in 2021-03-16 18:30:25.477567133 +0100 ++++ openssh-8.5p1/Makefile.in 2021-03-16 18:34:37.860116701 +0100 +@@ -47,7 +47,7 @@ + CFLAGS_NOPIE=@CFLAGS_NOPIE@ + CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ + PICFLAG=@PICFLAG@ +-LIBS=@LIBS@ ++LIBS=@LIBS@ -lpthread + K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHDLIBS=@SSHDLIBS@ +@@ -94,7 +94,7 @@ + LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + authfd.o authfile.o \ + canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ +- cipher-ctr.o cleanup.o \ ++ cipher-ctr.o cleanup.o cipher-ctr-mt.o \ + compat.o fatal.o hostfile.o \ + log.o match.o moduli.o nchan.o packet.o \ + readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ +diff -Nur openssh-8.5p1.orig/packet.c openssh-8.5p1/packet.c +--- openssh-8.5p1.orig/packet.c 2021-03-16 18:29:34.894456984 +0100 ++++ openssh-8.5p1/packet.c 2021-03-16 18:34:37.861116703 +0100 +@@ -246,7 +246,7 @@ + TAILQ_INIT(&ssh->public_keys); + state->connection_in = -1; + state->connection_out = -1; +- state->max_packet_size = 32768; ++ state->max_packet_size = CHAN_SES_PACKET_DEFAULT; + state->packet_timeout_ms = -1; + state->p_send.packets = state->p_read.packets = 0; + state->initialized = 1; +@@ -294,7 +294,7 @@ + ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) + { + struct session_state *state; +- const struct sshcipher *none = cipher_by_name("none"); ++ struct sshcipher *none = cipher_by_name("none"); + int r; + + if (none == NULL) { +@@ -958,10 +958,19 @@ + * so enforce a 1GB limit for small blocksizes. + * See RFC4344 section 3.2. + */ +- if (enc->block_size >= 16) +- *max_blocks = (u_int64_t)1 << (enc->block_size*2); +- else +- *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; ++ ++ /* we really don't need to rekey if we are using the none cipher ++ * but there isn't a good way to disable it entirely that I can find ++ * and using a blocksize larger that 16 doesn't work (dunno why) ++ * so this seems to be a good limit for now - CJR 10/16/2020*/ ++ if (ssh->none == 1) { ++ *max_blocks = (u_int64_t)1 << (16*2); ++ } else { ++ if (enc->block_size >= 16) ++ *max_blocks = (u_int64_t)1 << (enc->block_size*2); ++ else ++ *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; ++ } + if (state->rekey_limit) + *max_blocks = MINIMUM(*max_blocks, + state->rekey_limit / enc->block_size); +@@ -970,6 +979,24 @@ + return 0; + } + ++/* this supports the forced rekeying required for the NONE cipher */ ++int rekey_requested = 0; ++void ++packet_request_rekeying(void) ++{ ++ rekey_requested = 1; ++} ++ ++/* used to determine if pre or post auth when rekeying for aes-ctr ++ * and none cipher switch */ ++int ++packet_authentication_state(const struct ssh *ssh) ++{ ++ struct session_state *state = ssh->state; ++ ++ return state->after_authentication; ++} ++ + #define MAX_PACKETS (1U<<31) + static int + ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) +@@ -996,6 +1023,13 @@ + if (state->p_send.packets == 0 && state->p_read.packets == 0) + return 0; + ++ /* used to force rekeying when called for by the none ++ * cipher switch and aes-mt-ctr methods -cjr */ ++ if (rekey_requested == 1) { ++ rekey_requested = 0; ++ return 1; ++ } ++ + /* Time-based rekeying */ + if (state->rekey_interval != 0 && + (int64_t)state->rekey_time + state->rekey_interval <= monotime()) +@@ -1333,7 +1367,7 @@ + struct session_state *state = ssh->state; + int len, r, ms_remain; + fd_set *setp; +- char buf[8192]; ++ char buf[SSH_IOBUFSZ]; + struct timeval timeout, start, *timeoutp = NULL; + + DBG(debug("packet_read()")); +@@ -1865,17 +1899,21 @@ + switch (r) { + case SSH_ERR_CONN_CLOSED: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection closed by %s", remote_id); + case SSH_ERR_CONN_TIMEOUT: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection %s %s timed out", + ssh->state->server_side ? "from" : "to", remote_id); + case SSH_ERR_DISCONNECTED: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Disconnected from %s", remote_id); + case SSH_ERR_SYSTEM_ERROR: + if (errno == ECONNRESET) { + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection reset by %s", remote_id); + } + /* FALLTHROUGH */ +@@ -1917,6 +1955,24 @@ + logdie_f("should have exited"); + } + ++/* this prints out the final log entry */ ++void ++sshpkt_final_log_entry (struct ssh *ssh) { ++ double total_time; ++ ++ if (ssh->start_time < 1) ++ /* this will produce a NaN in the output. -cjr */ ++ total_time = 0; ++ else ++ total_time = monotime_double() - ssh->start_time; ++ ++ logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ++ ssh->stdin_bytes, ssh->fdout_bytes, total_time, ++ ssh->stdin_bytes / total_time, ++ ssh->fdout_bytes / total_time); ++} ++ + /* + * Logs the error plus constructs and sends a disconnect packet, closes the + * connection, and exits. This function never returns. The error message +@@ -2789,3 +2845,10 @@ + ssh->state->extra_pad = pad; + return 0; + } ++ ++/* need this for the moment for the aes-ctr cipher */ ++void * ++ssh_packet_get_send_context(struct ssh *ssh) ++{ ++ return ssh->state->send_context; ++} +diff -Nur openssh-8.5p1.orig/packet.h openssh-8.5p1/packet.h +--- openssh-8.5p1.orig/packet.h 2021-03-16 18:29:34.895456986 +0100 ++++ openssh-8.5p1/packet.h 2021-03-16 18:34:37.861116703 +0100 +@@ -86,6 +86,14 @@ + + /* APP data */ + void *app_data; ++ ++ /* logging data for ServerLogging patch*/ ++ double start_time; ++ u_long fdout_bytes; ++ u_long stdin_bytes; ++ ++ /* track that we are in a none cipher/mac state */ ++ int none; + }; + + typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, +@@ -155,6 +163,8 @@ + int ssh_packet_set_maxsize(struct ssh *, u_int); + u_int ssh_packet_get_maxsize(struct ssh *); + ++int packet_authentication_state(const struct ssh *); ++ + int ssh_packet_get_state(struct ssh *, struct sshbuf *); + int ssh_packet_set_state(struct ssh *, struct sshbuf *); + +@@ -169,6 +179,13 @@ + + void *ssh_packet_get_input(struct ssh *); + void *ssh_packet_get_output(struct ssh *); ++void *ssh_packet_get_receive_context(struct ssh *); ++void *ssh_packet_get_send_context(struct ssh *); ++ ++/* for forced packet rekeying post auth */ ++void packet_request_rekeying(void); ++/* final log entry support */ ++void sshpkt_final_log_entry (struct ssh *); + + /* new API */ + int sshpkt_start(struct ssh *ssh, u_char type); +diff -Nur openssh-8.5p1.orig/progressmeter.c openssh-8.5p1/progressmeter.c +--- openssh-8.5p1.orig/progressmeter.c 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/progressmeter.c 2021-03-16 18:34:37.861116703 +0100 +@@ -68,6 +68,8 @@ + static off_t start_pos; /* initial position of transfer */ + static off_t end_pos; /* ending position of transfer */ + static off_t cur_pos; /* transfer position as of last refresh */ ++static off_t last_pos; ++static off_t max_delta_pos = 0; + static volatile off_t *counter; /* progress counter */ + static long stalled; /* how long we have been stalled */ + static int bytes_per_second; /* current speed in bytes per second */ +@@ -127,6 +129,7 @@ + int cur_speed; + int hours, minutes, seconds; + int file_len; ++ off_t delta_pos; + + if ((!force_update && !alarm_fired && !win_resized) || !can_output()) + return; +@@ -142,6 +145,10 @@ + now = monotime_double(); + bytes_left = end_pos - cur_pos; + ++ delta_pos = cur_pos - last_pos; ++ if (delta_pos > max_delta_pos) ++ max_delta_pos = delta_pos; ++ + if (bytes_left > 0) + elapsed = now - last_update; + else { +@@ -166,7 +173,7 @@ + + /* filename */ + buf[0] = '\0'; +- file_len = win_size - 36; ++ file_len = win_size - 45; + if (file_len > 0) { + buf[0] = '\r'; + snmprintf(buf+1, sizeof(buf)-1, &file_len, "%-*s", +@@ -191,6 +198,15 @@ + (off_t)bytes_per_second); + strlcat(buf, "/s ", win_size); + ++ /* instantaneous rate */ ++ if (bytes_left > 0) ++ format_rate(buf + strlen(buf), win_size - strlen(buf), ++ delta_pos); ++ else ++ format_rate(buf + strlen(buf), win_size - strlen(buf), ++ max_delta_pos); ++ strlcat(buf, "/s ", win_size); ++ + /* ETA */ + if (!transferred) + stalled += elapsed; +@@ -227,6 +243,7 @@ + + atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); + last_update = now; ++ last_pos = cur_pos; + } + + /*ARGSUSED*/ +diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c +--- openssh-8.5p1.orig/readconf.c 2021-03-16 18:30:25.482567144 +0100 ++++ openssh-8.5p1/readconf.c 2021-03-17 12:39:20.463992055 +0100 +@@ -67,6 +67,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "sshbuf.h" + #include "ssh-gss.h" + + /* Format of the configuration file: +@@ -169,6 +170,9 @@ + oHashKnownHosts, + oTunnel, oTunnelDevice, + oLocalCommand, oPermitLocalCommand, oRemoteCommand, ++ oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize, ++ oNoneEnabled, oNoneMacEnabled, oNoneSwitch, ++ oDisableMTAES, + oVisualHostKey, + oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, + oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, +@@ -312,6 +316,10 @@ + { "kexalgorithms", oKexAlgorithms }, + { "ipqos", oIPQoS }, + { "requesttty", oRequestTTY }, ++ { "noneenabled", oNoneEnabled }, ++ { "nonemacenabled", oNoneMacEnabled }, ++ { "noneswitch", oNoneSwitch }, ++ { "disablemtaes", oDisableMTAES }, + { "proxyusefdpass", oProxyUseFdpass }, + { "canonicaldomains", oCanonicalDomains }, + { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, +@@ -332,6 +340,11 @@ + { "securitykeyprovider", oSecurityKeyProvider }, + { "knownhostscommand", oKnownHostsCommand }, + ++ { "tcprcvbufpoll", oTcpRcvBufPoll }, ++ { "tcprcvbuf", oTcpRcvBuf }, ++ { "hpndisabled", oHPNDisabled }, ++ { "hpnbuffersize", oHPNBufferSize }, ++ + { NULL, oBadOption } + }; + +@@ -1138,6 +1151,46 @@ + intptr = &options->check_host_ip; + goto parse_flag; + ++ case oHPNDisabled: ++ intptr = &options->hpn_disabled; ++ goto parse_flag; ++ ++ case oHPNBufferSize: ++ intptr = &options->hpn_buffer_size; ++ goto parse_int; ++ ++ case oTcpRcvBufPoll: ++ intptr = &options->tcp_rcv_buf_poll; ++ goto parse_flag; ++ ++ case oNoneEnabled: ++ intptr = &options->none_enabled; ++ goto parse_flag; ++ ++ case oNoneMacEnabled: ++ intptr = &options->nonemac_enabled; ++ goto parse_flag; ++ ++ case oDisableMTAES: ++ intptr = &options->disable_multithreaded; ++ goto parse_flag; ++ ++ /* ++ * We check to see if the command comes from the command ++ * line or not. If it does then enable it otherwise fail. ++ * NONE should never be a default configuration. ++ */ ++ case oNoneSwitch: ++ if (strcmp(filename, "command-line") == 0) { ++ intptr = &options->none_switch; ++ goto parse_flag; ++ } else { ++ error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); ++ error("Continuing..."); ++ debug("NoneSwitch directive found in %.200s.", filename); ++ return 0; ++ } ++ + case oVerifyHostKeyDNS: + intptr = &options->verify_host_key_dns; + multistate_ptr = multistate_yesnoask; +@@ -1371,6 +1424,10 @@ + *intptr = value; + break; + ++ case oTcpRcvBuf: ++ intptr = &options->tcp_rcv_buf; ++ goto parse_int; ++ + case oCiphers: + arg = strdelim(&s); + if (!arg || *arg == '\0') { +@@ -2315,6 +2372,14 @@ + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->request_tty = -1; ++ options->none_switch = -1; ++ options->none_enabled = -1; ++ options->nonemac_enabled = -1; ++ options->disable_multithreaded = -1; ++ options->hpn_disabled = -1; ++ options->hpn_buffer_size = -1; ++ options->tcp_rcv_buf_poll = -1; ++ options->tcp_rcv_buf = -1; + options->proxy_use_fdpass = -1; + options->ignored_unknown = NULL; + options->num_canonical_domains = 0; +@@ -2489,6 +2554,43 @@ + options->server_alive_interval = 0; + if (options->server_alive_count_max == -1) + options->server_alive_count_max = 3; ++ if (options->hpn_disabled == -1) ++ options->hpn_disabled = 0; ++ if (options->hpn_buffer_size > -1) { ++ /* if a user tries to set the size to 0 set it to 1KB */ ++ if (options->hpn_buffer_size == 0) ++ options->hpn_buffer_size = 1; ++ /* limit the buffer to SSHBUF_SIZE_MAX (currently 256MB) */ ++ if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) { ++ options->hpn_buffer_size = SSHBUF_SIZE_MAX; ++ debug("User requested buffer larger than 256MB. Request reverted to 256MB"); ++ } else ++ options->hpn_buffer_size *= 1024; ++ debug("hpn_buffer_size set to %d", options->hpn_buffer_size); ++ } ++ if (options->tcp_rcv_buf == 0) ++ options->tcp_rcv_buf = 1; ++ if (options->tcp_rcv_buf > -1) ++ options->tcp_rcv_buf *=1024; ++ if (options->tcp_rcv_buf_poll == -1) ++ options->tcp_rcv_buf_poll = 1; ++ if (options->none_switch == -1) ++ options->none_switch = 0; ++ if (options->none_enabled == -1) ++ options->none_enabled = 0; ++ if (options->none_enabled == 0 && options->none_switch > 0) { ++ fprintf(stderr, "NoneEnabled must be enabled to use the None Switch option. None cipher disabled.\n"); ++ options->none_enabled = 0; ++ } ++ if (options->nonemac_enabled == -1) ++ options->nonemac_enabled = 0; ++ if (options->nonemac_enabled > 0 && (options->none_enabled == 0 || ++ options->none_switch == 0)) { ++ fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); ++ options->nonemac_enabled = 0; ++ } ++ if (options->disable_multithreaded == -1) ++ options->disable_multithreaded = 0; + if (options->control_master == -1) + options->control_master = 0; + if (options->control_persist == -1) { +diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h +--- openssh-8.5p1.orig/readconf.h 2021-03-16 18:30:25.482567144 +0100 ++++ openssh-8.5p1/readconf.h 2021-03-17 15:22:23.353088822 +0100 +@@ -57,6 +57,10 @@ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int tcp_keep_alive; /* Set SO_KEEPALIVE. */ ++ int tcp_rcv_buf; /* user switch to set tcp recv buffer */ ++ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ ++ int hpn_disabled; /* Switch to disable HPN buffer management */ ++ int hpn_buffer_size; /* User definable size for HPN buffer window */ + int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ + int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ + SyslogFacility log_facility; /* Facility for system logging. */ +@@ -128,7 +132,12 @@ + + int enable_ssh_keysign; + int64_t rekey_limit; ++ int none_switch; /* Use none cipher */ ++ int none_enabled; /* Allow none to be used */ ++ int nonemac_enabled; /* Allow none to be used */ ++ int disable_multithreaded; /*disable multithreaded aes-ctr*/ + int rekey_interval; ++ + int no_host_authentication_for_localhost; + int identities_only; + int server_alive_interval; +diff -Nur openssh-8.5p1.orig/regress/integrity.sh openssh-8.5p1/regress/integrity.sh +--- openssh-8.5p1.orig/regress/integrity.sh 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/regress/integrity.sh 2021-03-16 18:34:37.863116707 +0100 +@@ -21,6 +21,12 @@ + cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" + + for m in $macs; do ++ # the none mac is now valid but tests against it will succeed when we expect it to ++ # fail. so we need to explicity remove it from the list of macs returned. ++ if [ "$m" = "none" ]; then ++ continue ++ fi ++ + trace "test $tid: mac $m" + elen=0 + epad=0 +diff -Nur openssh-8.5p1.orig/sandbox-seccomp-filter.c openssh-8.5p1/sandbox-seccomp-filter.c +--- openssh-8.5p1.orig/sandbox-seccomp-filter.c 2021-03-16 18:29:34.904457006 +0100 ++++ openssh-8.5p1/sandbox-seccomp-filter.c 2021-03-16 18:34:37.864116709 +0100 +@@ -222,6 +222,9 @@ + #ifdef __NR_geteuid32 + SC_ALLOW(__NR_geteuid32), + #endif ++#ifdef __NR_getpeername /* not defined on archs that go via socketcall(2) */ ++ SC_ALLOW(__NR_getpeername), ++#endif + #ifdef __NR_getpgid + SC_ALLOW(__NR_getpgid), + #endif +@@ -315,6 +318,9 @@ + #ifdef __NR_sigprocmask + SC_ALLOW(__NR_sigprocmask), + #endif ++#ifdef __NR_socketcall ++ SC_ALLOW(__NR_socketcall), ++#endif + #ifdef __NR_time + SC_ALLOW(__NR_time), + #endif +diff -Nur openssh-8.5p1.orig/scp.c openssh-8.5p1/scp.c +--- openssh-8.5p1.orig/scp.c 2021-03-16 18:29:34.912457023 +0100 ++++ openssh-8.5p1/scp.c 2021-03-16 18:34:37.864116709 +0100 +@@ -1251,7 +1251,7 @@ + off_t size, statbytes; + unsigned long long ull; + int setimes, targisdir, wrerr; +- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; ++ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384], visbuf[16384]; + char **patterns = NULL; + size_t n, npatterns = 0; + struct timeval tv[2]; +diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c +--- openssh-8.5p1.orig/servconf.c 2021-03-16 18:30:25.483567146 +0100 ++++ openssh-8.5p1/servconf.c 2021-03-16 19:22:02.843001635 +0100 +@@ -70,6 +70,7 @@ + #include "auth.h" + #include "myproposal.h" + #include "digest.h" ++#include "sshbuf.h" + #include "ssh-gss.h" + + static void add_listen_addr(ServerOptions *, const char *, +@@ -201,6 +202,12 @@ + options->authorized_principals_file = NULL; + options->authorized_principals_command = NULL; + options->authorized_principals_command_user = NULL; ++ options->tcp_rcv_buf_poll = -1; ++ options->hpn_disabled = -1; ++ options->hpn_buffer_size = -1; ++ options->none_enabled = -1; ++ options->nonemac_enabled = -1; ++ options->disable_multithreaded = -1; + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; +@@ -291,6 +298,10 @@ + fill_default_server_options(ServerOptions *options) + { + u_int i; ++ /* needed for hpn socket tests */ ++ int sock; ++ int socksize; ++ int socksizelen = sizeof(int); + + /* Portable-specific options */ + if (options->use_pam == -1) +@@ -462,6 +473,51 @@ + } + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; ++ if (options->none_enabled == -1) ++ options->none_enabled = 0; ++ if (options->nonemac_enabled == -1) ++ options->nonemac_enabled = 0; ++ if (options->nonemac_enabled > 0 && options->none_enabled == 0) { ++ debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); ++ options->nonemac_enabled = 0; ++ } ++ if (options->disable_multithreaded == -1) ++ options->disable_multithreaded = 0; ++ if (options->hpn_disabled == -1) ++ options->hpn_disabled = 0; ++ ++ if (options->hpn_buffer_size == -1) { ++ /* option not explicitly set. Now we have to figure out */ ++ /* what value to use */ ++ if (options->hpn_disabled == 1) { ++ options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; ++ } else { ++ /* get the current RCV size and set it to that */ ++ /*create a socket but don't connect it */ ++ /* we use that the get the rcv socket size */ ++ sock = socket(AF_INET, SOCK_STREAM, 0); ++ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, ++ &socksize, &socksizelen); ++ close(sock); ++ options->hpn_buffer_size = socksize; ++ debug("HPN Buffer Size: %d", options->hpn_buffer_size); ++ } ++ } else { ++ /* we have to do this in case the user sets both values in a contradictory */ ++ /* manner. hpn_disabled overrrides hpn_buffer_size*/ ++ if (options->hpn_disabled <= 0) { ++ if (options->hpn_buffer_size == 0) ++ options->hpn_buffer_size = 1; ++ /* limit the maximum buffer to SSHBUF_SIZE_MAX (currently 256MB) */ ++ if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) { ++ options->hpn_buffer_size = SSHBUF_SIZE_MAX; ++ } else { ++ options->hpn_buffer_size *= 1024; ++ } ++ } else ++ options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT; ++ } ++ + if (options->ip_qos_interactive == -1) + options->ip_qos_interactive = IPTOS_DSCP_AF21; + if (options->ip_qos_bulk == -1) +@@ -535,6 +591,9 @@ + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, ++ sNoneEnabled, sNoneMacEnabled, ++ sDisableMTAES, ++ sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitUserEnvironment, sAllowTcpForwarding, sCompression, +@@ -734,6 +793,12 @@ + { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, + { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, + { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, ++ { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, ++ { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL }, ++ { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, ++ { "noneenabled", sNoneEnabled, SSHCFG_ALL }, ++ { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, ++ { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "include", sInclude, SSHCFG_ALL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, +@@ -792,6 +857,7 @@ + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) { ++ debug("Config token is %s", keywords[i].name); + *flags = keywords[i].flags; + return keywords[i].opcode; + } +@@ -1539,12 +1605,36 @@ + multistate_ptr = multistate_ignore_rhosts; + goto parse_multistate; + ++ case sTcpRcvBufPoll: ++ intptr = &options->tcp_rcv_buf_poll; ++ goto parse_flag; ++ ++ case sHPNDisabled: ++ intptr = &options->hpn_disabled; ++ goto parse_flag; ++ ++ case sHPNBufferSize: ++ intptr = &options->hpn_buffer_size; ++ goto parse_int; ++ + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + parse_flag: + multistate_ptr = multistate_flag; + goto parse_multistate; + ++ case sNoneEnabled: ++ intptr = &options->none_enabled; ++ goto parse_flag; ++ ++ case sNoneMacEnabled: ++ intptr = &options->nonemac_enabled; ++ goto parse_flag; ++ ++ case sDisableMTAES: ++ intptr = &options->disable_multithreaded; ++ goto parse_flag; ++ + case sHostbasedAuthentication: + intptr = &options->hostbased_authentication; + goto parse_flag; +diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h +--- openssh-8.5p1.orig/servconf.h 2021-03-16 18:30:25.483567146 +0100 ++++ openssh-8.5p1/servconf.h 2021-03-17 15:24:07.943324235 +0100 +@@ -214,6 +214,13 @@ + int use_pam; /* Enable auth via PAM */ + int permit_pam_user_change; /* Allow PAM to change user name */ + ++ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ ++ int hpn_disabled; /* disable hpn functionality. false by default */ ++ int hpn_buffer_size; /* set the hpn buffer size - default 3MB */ ++ int none_enabled; /* Enable NONE cipher switch */ ++ int disable_multithreaded; /*disable multithreaded aes-ctr cipher */ ++ int nonemac_enabled; /* Enable NONE MAC switch */ ++ + int permit_tun; + + char **permitted_opens; /* May also be one of PERMITOPEN_* */ +diff -Nur openssh-8.5p1.orig/serverloop.c openssh-8.5p1/serverloop.c +--- openssh-8.5p1.orig/serverloop.c 2021-03-16 18:29:34.913457025 +0100 ++++ openssh-8.5p1/serverloop.c 2021-03-17 14:17:22.892355940 +0100 +@@ -322,7 +322,7 @@ + process_input(struct ssh *ssh, fd_set *readset, int connection_in) + { + int r, len; +- char buf[16384]; ++ char buf[SSH_IOBUFSZ]; + + /* Read and buffer any input data from the client. */ + if (FD_ISSET(connection_in, readset)) { +@@ -343,6 +343,7 @@ + /* Buffer any received data. */ + if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) + fatal_fr(r, "ssh_packet_process_incoming"); ++ ssh->fdout_bytes += len; + } + return 0; + } +@@ -401,6 +402,7 @@ + u_int64_t rekey_timeout_ms = 0; + + debug("Entering interactive session for SSH2."); ++ ssh->start_time = monotime_double(); + + ssh_signal(SIGCHLD, sigchld_handler); + child_terminated = 0; +@@ -439,6 +441,7 @@ + + if (received_sigterm) { + logit("Exiting on signal %d", (int)received_sigterm); ++ sshpkt_final_log_entry(ssh); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } +@@ -458,6 +461,9 @@ + /* free all channels, no more reads and writes */ + channel_free_all(ssh); + ++ /* final entry must come after channels close -cjr */ ++ sshpkt_final_log_entry(ssh); ++ + /* free remaining sessions, e.g. remove wtmp entries */ + session_destroy_all(ssh, NULL); + } +@@ -608,7 +614,8 @@ + debug("Tunnel forwarding using interface %s", ifname); + + c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, +- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); ++ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, ++ CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; + #if defined(SSH_TUN_FILTER) + if (mode == SSH_TUNMODE_POINTOPOINT) +@@ -659,6 +666,8 @@ + c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, + -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, + 0, "server-session", 1); ++ if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled)) ++ c->dynamic_window = 1; + if (session_open(the_authctxt, c->self) != 1) { + debug("session open failed, free channel %d", c->self); + channel_free(ssh, c); +diff -Nur openssh-8.5p1.orig/session.c openssh-8.5p1/session.c +--- openssh-8.5p1.orig/session.c 2021-03-16 18:29:34.900456997 +0100 ++++ openssh-8.5p1/session.c 2021-03-16 18:34:37.867116716 +0100 +@@ -228,6 +228,7 @@ + goto authsock_err; + + /* Allocate a channel for the authentication agent socket. */ ++ /* this shouldn't matter if its hpn or not - cjr */ + nc = channel_new(ssh, "auth socket", + SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, +@@ -2362,7 +2363,8 @@ + channel_set_fds(ssh, s->chanid, + fdout, fdin, fderr, + ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, +- 1, is_tty, CHAN_SES_WINDOW_DEFAULT); ++ 1, is_tty, ++ options.hpn_disabled ? CHAN_SES_WINDOW_DEFAULT : options.hpn_buffer_size); + } + + /* +diff -Nur openssh-8.5p1.orig/sftp.1 openssh-8.5p1/sftp.1 +--- openssh-8.5p1.orig/sftp.1 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sftp.1 2021-03-16 18:34:37.867116716 +0100 +@@ -296,7 +296,8 @@ + Specify how many requests may be outstanding at any one time. + Increasing this may slightly improve file transfer speed + but will increase memory usage. +-The default is 64 outstanding requests. ++The default is 256 outstanding requests providing for 8MB ++of outstanding data with a 32KB buffer. + .It Fl r + Recursively copy entire directories when uploading and downloading. + Note that +diff -Nur openssh-8.5p1.orig/sftp.c openssh-8.5p1/sftp.c +--- openssh-8.5p1.orig/sftp.c 2021-03-16 18:29:34.913457025 +0100 ++++ openssh-8.5p1/sftp.c 2021-03-16 18:34:37.868116718 +0100 +@@ -71,7 +71,7 @@ + #include "sftp-client.h" + + #define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ +-#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ ++#define DEFAULT_NUM_REQUESTS 256 /* # concurrent outstanding requests */ + + /* File to read commands from */ + FILE* infile; +diff -Nur openssh-8.5p1.orig/ssh_api.c openssh-8.5p1/ssh_api.c +--- openssh-8.5p1.orig/ssh_api.c 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/ssh_api.c 2021-03-16 18:34:37.869116720 +0100 +@@ -410,7 +410,7 @@ + char *cp; + int r; + +- if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_VERSION)) != 0) ++ if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_RELEASE)) != 0) + return r; + if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) + return r; +diff -Nur openssh-8.5p1.orig/sshbuf.h openssh-8.5p1/sshbuf.h +--- openssh-8.5p1.orig/sshbuf.h 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sshbuf.h 2021-03-16 18:34:37.869116720 +0100 +@@ -28,7 +28,7 @@ + # endif /* OPENSSL_HAS_ECC */ + #endif /* WITH_OPENSSL */ + +-#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ ++#define SSHBUF_SIZE_MAX 0xF000000 /* Hard maximum size 256MB */ + #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ + #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ + #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ +diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c +--- openssh-8.5p1.orig/ssh.c 2021-03-16 18:30:25.485567150 +0100 ++++ openssh-8.5p1/ssh.c 2021-03-17 10:38:31.343325781 +0100 +@@ -1070,6 +1070,10 @@ + break; + case 'T': + options.request_tty = REQUEST_TTY_NO; ++ /* ensure that the user doesn't try to backdoor a */ ++ /* null cipher switch on an interactive session */ ++ /* so explicitly disable it no matter what */ ++ options.none_switch=0; + break; + case 'o': + line = xstrdup(optarg); +@@ -1792,6 +1796,8 @@ + setproctitle("%s [mux]", options.control_path); + } + ++extern const EVP_CIPHER *evp_aes_ctr_mt(void); ++ + /* Do fork() after authentication. Used by "ssh -f" */ + static void + fork_postauth(void) +@@ -2104,6 +2110,79 @@ + NULL, fileno(stdin), command, environ); + } + ++static void ++hpn_options_init(struct ssh *ssh) ++{ ++ /* ++ * We need to check to see if what they want to do about buffer ++ * sizes here. In a hpn to nonhpn connection we want to limit ++ * the window size to something reasonable in case the far side ++ * has the large window bug. In hpn to hpn connection we want to ++ * use the max window size but allow the user to override it ++ * lastly if they disabled hpn then use the ssh std window size. ++ * ++ * So why don't we just do a getsockopt() here and set the ++ * ssh window to that? In the case of a autotuning receive ++ * window the window would get stuck at the initial buffer ++ * size generally less than 96k. Therefore we need to set the ++ * maximum ssh window size to the maximum hpn buffer size ++ * unless the user has specifically set the tcprcvbufpoll ++ * to no. In which case we *can* just set the window to the ++ * minimum of the hpn buffer size and tcp receive buffer size. ++ */ ++ ++ if (tty_flag) ++ options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; ++ else ++ options.hpn_buffer_size = 2 * 1024 * 1024; ++ ++ if (ssh->compat & SSH_BUG_LARGEWINDOW) { ++ debug("HPN to Non-HPN connection"); ++ } else { ++ debug("HPN to HPN connection"); ++ int sock, socksize; ++ socklen_t socksizelen; ++ if (options.tcp_rcv_buf_poll <= 0) { ++ sock = socket(AF_INET, SOCK_STREAM, 0); ++ socksizelen = sizeof(socksize); ++ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, ++ &socksize, &socksizelen); ++ close(sock); ++ debug("socksize %d", socksize); ++ options.hpn_buffer_size = socksize; ++ debug("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size); ++ } else { ++ if (options.tcp_rcv_buf > 0) { ++ /* ++ * Create a socket but don't connect it: ++ * we use that the get the rcv socket size ++ */ ++ sock = socket(AF_INET, SOCK_STREAM, 0); ++ /* ++ * If they are using the tcp_rcv_buf option, ++ * attempt to set the buffer size to that. ++ */ ++ if (options.tcp_rcv_buf) { ++ socksizelen = sizeof(options.tcp_rcv_buf); ++ setsockopt(sock, SOL_SOCKET, SO_RCVBUF, ++ &options.tcp_rcv_buf, socksizelen); ++ } ++ socksizelen = sizeof(socksize); ++ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, ++ &socksize, &socksizelen); ++ close(sock); ++ debug("socksize %d", socksize); ++ options.hpn_buffer_size = socksize; ++ debug("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size); ++ } ++ } ++ } ++ ++ debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); ++ ++ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); ++} ++ + /* open new channel for a session */ + static int + ssh_session2_open(struct ssh *ssh) +@@ -2130,9 +2209,11 @@ + if (!isatty(err)) + set_nonblock(err); + +- window = CHAN_SES_WINDOW_DEFAULT; ++ window = options.hpn_buffer_size; ++ + packetmax = CHAN_SES_PACKET_DEFAULT; + if (tty_flag) { ++ window = CHAN_SES_WINDOW_DEFAULT; + window >>= 1; + packetmax >>= 1; + } +@@ -2143,6 +2224,11 @@ + + debug3_f("channel_new: %d", c->self); + ++ if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) { ++ c->dynamic_window = 1; ++ debug("Enabled Dynamic Window Scaling"); ++ } ++ + channel_send_open(ssh, c->self); + if (!no_shell_flag) + channel_register_open_confirm(ssh, c->self, +@@ -2157,6 +2243,13 @@ + int r, id = -1; + char *cp, *tun_fwd_ifname = NULL; + ++ /* ++ * We need to initialize this early because the forwarding logic below ++ * might open channels that use the hpn buffer sizes. We can't send a ++ * window of -1 (the default) to the server as it breaks things. ++ */ ++ hpn_options_init(ssh); ++ + /* XXX should be pre-session */ + if (!options.control_persist) + ssh_init_stdio_forwarding(ssh); +diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c +--- openssh-8.5p1.orig/sshconnect2.c 2021-03-16 18:30:25.487567155 +0100 ++++ openssh-8.5p1/sshconnect2.c 2021-03-16 22:46:23.496061979 +0100 +@@ -86,6 +86,13 @@ + extern Options options; + + /* ++ * tty_flag is set in ssh.c. Use this in ssh_userauth2: ++ * if it is set, then prevent the switch to the null cipher. ++ */ ++ ++extern int tty_flag; ++ ++/* + * SSH2 key exchange + */ + +@@ -212,6 +219,8 @@ + return ret; + } + ++static char *myproposal[PROPOSAL_MAX]; ++static const char *myproposal_default[PROPOSAL_MAX] = { KEX_CLIENT }; + void + ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, + const struct ssh_conn_info *cinfo) +@@ -225,6 +234,10 @@ + char *gss_host = NULL; + #endif + ++ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); ++ ++ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); ++ + xxx_host = host; + xxx_hostaddr = hostaddr; + xxx_conn_info = cinfo; +@@ -571,6 +584,53 @@ + + if (!authctxt.success) + fatal("Authentication failed."); ++ ++ /* ++ * If the user wants to use the none cipher and/or none mac, do it post authentication ++ * and only if the right conditions are met -- both of the NONE commands ++ * must be true and there must be no tty allocated. ++ */ ++ if (options.none_switch == 1 && options.none_enabled == 1) { ++ if (!tty_flag) { /* no null on tty sessions */ ++ debug("Requesting none rekeying..."); ++ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; ++ fprintf(stderr, "WARNING: ENABLED NONE CIPHER!!!\n"); ++ /* NONEMAC can only be used in context of the NONE CIPHER */ ++ if (options.nonemac_enabled == 1) { ++ myproposal[PROPOSAL_MAC_ALGS_STOC] = "none"; ++ myproposal[PROPOSAL_MAC_ALGS_CTOS] = "none"; ++ fprintf(stderr, "WARNING: ENABLED NONE MAC\n"); ++ } ++ kex_prop2buf(ssh->kex->my, myproposal); ++ packet_request_rekeying(); ++ } else { ++ /* requested NONE cipher when in a tty */ ++ debug("Cannot switch to NONE cipher with tty allocated"); ++ fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); ++ } ++ } ++ ++#ifdef WITH_OPENSSL ++ if (options.disable_multithreaded == 0) { ++ /* if we are using aes-ctr there can be issues in either a fork or sandbox ++ * so the initial aes-ctr is defined to point to the original single process ++ * evp. After authentication we'll be past the fork and the sandboxed privsep ++ * so we repoint the define to the multithreaded evp. To start the threads we ++ * then force a rekey ++ */ ++ const void *cc = ssh_packet_get_send_context(ssh); ++ ++ /* only do this for the ctr cipher. otherwise gcm mode breaks. Don't know why though */ ++ if (strstr(cipher_ctx_name(cc), "ctr")) { ++ debug("Single to Multithread CTR cipher swap - client request"); ++ cipher_reset_multithreaded(); ++ packet_request_rekeying(); ++ } ++ } ++#endif ++ + debug("Authentication succeeded (%s).", authctxt.method->name); + } + +diff -Nur openssh-8.5p1.orig/sshconnect.c openssh-8.5p1/sshconnect.c +--- openssh-8.5p1.orig/sshconnect.c 2021-03-16 18:29:34.859456908 +0100 ++++ openssh-8.5p1/sshconnect.c 2021-03-17 21:07:43.343181602 +0100 +@@ -343,6 +343,30 @@ + #endif + + /* ++ * Set TCP receive buffer if requested. ++ * Note: tuning needs to happen after the socket is ++ * created but before the connection happens ++ * so winscale is negotiated properly -cjr ++ */ ++static void ++ssh_set_socket_recvbuf(int sock) ++{ ++ void *buf = (void *)&options.tcp_rcv_buf; ++ int sz = sizeof(options.tcp_rcv_buf); ++ int socksize; ++ int socksizelen = sizeof(int); ++ ++ debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf); ++ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) { ++ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen); ++ debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize); ++ } ++ else ++ error("Couldn't set socket receive buffer to %d: %.100s", ++ options.tcp_rcv_buf, strerror(errno)); ++} ++ ++/* + * Creates a socket for use as the ssh connection. + */ + static int +@@ -364,6 +388,9 @@ + } + fcntl(sock, F_SETFD, FD_CLOEXEC); + ++ if (options.tcp_rcv_buf > 0) ++ ssh_set_socket_recvbuf(sock); ++ + /* Use interactive QOS (if specified) until authentication completed */ + if (options.ip_qos_interactive != INT_MAX) + set_sock_tos(sock, options.ip_qos_interactive); +diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c +--- openssh-8.5p1.orig/sshd.c 2021-03-16 18:30:25.488567157 +0100 ++++ openssh-8.5p1/sshd.c 2021-03-16 19:28:51.437865785 +0100 +@@ -1106,6 +1106,8 @@ + int ret, listen_sock; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; ++ int socksize; ++ int socksizelen = sizeof(int); + + for (ai = la->addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) +@@ -1151,6 +1153,11 @@ + + debug("Bind to port %s on %s.", strport, ntop); + ++ getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, ++ &socksize, &socksizelen); ++ debug("Server TCP RWIN socket size: %d", socksize); ++ debug("HPN Buffer Size: %d", options.hpn_buffer_size); ++ + /* Bind the socket to the desired port. */ + if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { + error("Bind to port %s on %s failed: %.200s.", +@@ -1828,6 +1835,19 @@ + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + ++ if (options.none_enabled == 1) { ++ char *old_ciphers = options.ciphers; ++ xasprintf(&options.ciphers, "%s,none", old_ciphers); ++ free(old_ciphers); ++ ++ /* only enable the none MAC in context of the none cipher -cjr */ ++ if (options.nonemac_enabled == 1) { ++ char *old_macs = options.macs; ++ xasprintf(&options.macs, "%s,none", old_macs); ++ free(old_macs); ++ } ++ } ++ + /* challenge-response is implemented via keyboard interactive */ + if (options.challenge_response_authentication) + options.kbd_interactive_authentication = 1; +@@ -2277,6 +2297,9 @@ + rdomain == NULL ? "" : "\""); + free(laddr); + ++ /* set the HPN options for the child */ ++ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); ++ + /* + * We don't want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is +@@ -2389,6 +2412,25 @@ + /* Try to send all our hostkeys to the client */ + notify_hostkeys(ssh); + ++#ifdef WITH_OPENSSL ++ if (options.disable_multithreaded == 0) { ++ /* if we are using aes-ctr there can be issues in either a fork or sandbox ++ * so the initial aes-ctr is defined to point ot the original single process ++ * evp. After authentication we'll be past the fork and the sandboxed privsep ++ * so we repoint the define to the multithreaded evp. To start the threads we ++ * then force a rekey ++ */ ++ const void *cc = ssh_packet_get_send_context(the_active_state); ++ ++ /* only rekey if necessary. If we don't do this gcm mode cipher breaks */ ++ if (strstr(cipher_ctx_name(cc), "ctr")) { ++ debug("Single to Multithreaded CTR cipher swap - server request"); ++ cipher_reset_multithreaded(); ++ packet_request_rekeying(); ++ } ++ } ++#endif ++ + /* Start session. */ + do_authenticated(ssh, authctxt); + +@@ -2462,6 +2504,11 @@ + struct kex *kex; + int r; + ++ if (options.none_enabled == 1) ++ debug("WARNING: None cipher enabled"); ++ if (options.nonemac_enabled == 1) ++ debug("WARNING: None MAC enabled"); ++ + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, + options.kex_algorithms); + myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, +diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config +--- openssh-8.5p1.orig/sshd_config 2021-03-16 18:30:25.488567157 +0100 ++++ openssh-8.5p1/sshd_config 2021-03-16 18:34:37.873116729 +0100 +@@ -127,6 +127,22 @@ + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + ++# the following are HPN related configuration options ++# tcp receive buffer polling. disable in non autotuning kernels ++#TcpRcvBufPoll yes ++ ++# disable hpn performance boosts ++#HPNDisabled no ++ ++# buffer size for hpn to non-hpn connections ++#HPNBufferSize 2048 ++ ++# allow the use of the none cipher ++#NoneEnabled no ++ ++# allow the use of the none MAC ++#NoneMacEnabled no ++ + # Example of overriding settings on a per-user basis + #Match User anoncvs + # X11Forwarding no +diff -Nur openssh-8.5p1.orig/version.h openssh-8.5p1/version.h +--- openssh-8.5p1.orig/version.h 2021-03-16 18:30:25.490567161 +0100 ++++ openssh-8.5p1/version.h 2021-03-17 20:59:44.602187131 +0100 +@@ -16,5 +16,6 @@ + + #define SSH_PORTABLE "p1" + #define GSI_PORTABLE "c-GSI" ++#define SSH_HPN "-hpn15v2" + #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ +- GSI_VERSION KRB5_VERSION ++ GSI_VERSION SSH_HPN KRB5_VERSION diff --git a/sources b/sources index d7fc727..5c74840 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.4p1.tar.gz) = d65275b082c46c5efe7cf3264fa6794d6e99a36d4a54b50554fc56979d6c0837381587fd5399195e1db680d2a5ad1ef0b99a180eac2b4de5637906cb7a89e9ce -SHA512 (openssh-8.4p1.tar.gz.asc) = 3d9a026db27729a5a56785db3824230ccf2a3beca4bb48ef465e44d869b944dbc5d443152a1b1be21bc9c213c465d3d7ca1f876a387d0a6b9682a0cfec3e6e32 -SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d +SHA512 (openssh-8.5p1.tar.gz) = af9c34d89170a30fc92a63973e32c766ed4a6d254bb210e317c000d46913e78d0c60c7befe62d993d659be000b828b9d4d3832fc40df1c3d33850aaa6293846f +SHA512 (openssh-8.5p1.tar.gz.asc) = 264a991c7207f2215875e2b472a649ede1a69f6486d25777bf522047c26ea77c2995d34b6917a993ea9a250b7dd5298a30f1975e20e471f079c9064ce283cec2 +SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 152f5ddac30379c11e263fbcdcb0b34a52358059 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 30 Mar 2021 10:00:53 +0200 Subject: [PATCH 095/146] Disable MTAES --- gsi-openssh.spec | 5 ++++- openssh-8.5p1-hpn-15.2-modified.patch | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index dc322ed..f5bb416 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.5p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -490,6 +490,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Mar 30 2021 Mattias Ellert - 8.5p1-3 +- Disable MTAES + * Tue Mar 16 2021 Mattias Ellert - 8.5p1-1 - Based on openssh-8.5p1-1.fc34 - Fix issue with read-only ssh buffer during gssapi key exchange diff --git a/openssh-8.5p1-hpn-15.2-modified.patch b/openssh-8.5p1-hpn-15.2-modified.patch index 36b9d58..64d4b18 100644 --- a/openssh-8.5p1-hpn-15.2-modified.patch +++ b/openssh-8.5p1-hpn-15.2-modified.patch @@ -2550,8 +2550,8 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config --- openssh-8.5p1.orig/sshd_config 2021-03-16 18:30:25.488567157 +0100 -+++ openssh-8.5p1/sshd_config 2021-03-16 18:34:37.873116729 +0100 -@@ -127,6 +127,22 @@ ++++ openssh-8.5p1/sshd_config 2021-03-30 09:54:41.725605908 +0200 +@@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2570,6 +2570,12 @@ diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config + +# allow the use of the none MAC +#NoneMacEnabled no ++ ++# Disable MT-AES-CTR cipher on server ++# * needed for GSI-OpenSSH 7.4p1 because it's broken on the server side there ++# * useful for modern processors with AES-NI instructions making the stock ++# AES-CTR cipher faster than the MT-AES-CTR cipher ++DisableMTAES yes + # Example of overriding settings on a per-user basis #Match User anoncvs From 24087bf920b6fd5ca4e102d1fb2a4e1f37fe10b8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 22 May 2021 09:07:37 +0200 Subject: [PATCH 096/146] Based on openssh-8.6p1-3.fc35 --- gsi-openssh.spec | 20 +- openssh-4.3p2-askpass-grab-info.patch | 29 +- openssh-5.1p1-askpass-progress.patch | 2 +- openssh-6.6.1p1-log-in-chroot.patch | 100 +- openssh-6.7p1-coverity.patch | 423 ++- openssh-7.6p1-audit.patch | 334 +- openssh-7.7p1-fips.patch | 183 +- openssh-7.7p1-gssapi-new-unique.patch | 242 +- openssh-7.8p1-UsePAM-warning.patch | 22 +- openssh-7.8p1-role-mls.patch | 24 +- openssh-8.0p1-crypto-policies.patch | 58 +- openssh-8.0p1-keygen-strip-doseol.patch | 12 + openssh-8.0p1-pkcs11-uri.patch | 3178 ++++++++--------- openssh-8.0p1-preserve-pam-errors.patch | 44 + openssh-8.0p1-restore-nonblock.patch | 241 ++ ...gsissh.patch => openssh-8.6p1-gsissh.patch | 294 +- ...h => openssh-8.6p1-hpn-15.2-modified.patch | 324 +- sources | 4 +- 18 files changed, 3083 insertions(+), 2451 deletions(-) create mode 100644 openssh-8.0p1-keygen-strip-doseol.patch create mode 100644 openssh-8.0p1-preserve-pam-errors.patch create mode 100644 openssh-8.0p1-restore-nonblock.patch rename openssh-8.5p1-gsissh.patch => openssh-8.6p1-gsissh.patch (89%) rename openssh-8.5p1-hpn-15.2-modified.patch => openssh-8.6p1-hpn-15.2-modified.patch (89%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f5bb416..de76c03 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,8 +27,8 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 8.5p1 -%global openssh_rel 2 +%global openssh_ver 8.6p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -147,17 +147,23 @@ Patch965: openssh-8.2p1-visibility.patch Patch966: openssh-8.2p1-x11-without-ipv6.patch # https://bugzilla.mindrot.org/show_bug.cgi?id=3213 Patch969: openssh-8.4p1-debian-compat.patch +# ssh-keygen printing fingerprint issue with Windows keys (#1901518) +Patch974: openssh-8.0p1-keygen-strip-doseol.patch +# sshd provides PAM an incorrect error code (#1879503) +Patch975: openssh-8.0p1-preserve-pam-errors.patch +# ssh incorrectly restores the blocking mode on standard output (#1942901) +Patch976: openssh-8.0p1-restore-nonblock.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 -Patch98: openssh-8.5p1-gsissh.patch +Patch98: openssh-8.6p1-gsissh.patch # This is the HPN patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-8.5p1-hpn-15.2-modified.patch +Patch99: openssh-8.6p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -294,6 +300,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 %patch969 -p0 -b .debian +%patch974 -p1 -b .keygen-strip-doseol +%patch975 -p1 -b .preserve-pam-errors +%patch976 -p1 -b .restore-nonblock %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -490,6 +499,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Sat May 22 2021 Mattias Ellert - 8.6p1-1 +- Based on openssh-8.6p1-3.fc35 + * Tue Mar 30 2021 Mattias Ellert - 8.5p1-3 - Disable MTAES diff --git a/openssh-4.3p2-askpass-grab-info.patch b/openssh-4.3p2-askpass-grab-info.patch index e9a0b0d..120ed1b 100644 --- a/openssh-4.3p2-askpass-grab-info.patch +++ b/openssh-4.3p2-askpass-grab-info.patch @@ -1,19 +1,18 @@ -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 +diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c +--- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200 ++++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200 +@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi + err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, -- "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_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)); diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index e0ecb80..ff609da 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -60,7 +60,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr if (prompt_type == PROMPT_ENTRY) { @@ -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); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 664e11a..426c172 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,7 @@ -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,...) +diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c +--- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/log.c 2021-04-19 14:43:08.544843434 +0200 +@@ -194,6 +194,11 @@ void log_init(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { @@ -13,7 +13,7 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c #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 +@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level exit(1); } @@ -26,21 +26,21 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c 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 { - const char *, void *); +diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h +--- openssh-8.6p1/log.h.log-in-chroot 2021-04-19 14:43:08.544843434 +0200 ++++ openssh-8.6p1/log.h 2021-04-19 14:56:46.931042176 +0200 +@@ -52,6 +52,7 @@ typedef enum { + typedef void (log_handler_fn)(LogLevel, int, const char *, void *); 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 -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 +diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.log-in-chroot 2021-04-19 14:43:08.526843298 +0200 ++++ openssh-8.6p1/monitor.c 2021-04-19 14:55:25.286424043 +0200 +@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; @@ -49,7 +49,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c authctxt = (Authctxt *)ssh->authctxt; memset(authctxt, 0, sizeof(*authctxt)); ssh->authctxt = authctxt; -@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p +@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh, close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; @@ -58,16 +58,16 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c 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 +@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito /* Log it */ if (log_level_name(level) == NULL) fatal_f("invalid log level %u (corrupted message?)", level); -- sshlog(file, func, line, 0, level, NULL, "%s [preauth]", msg); -+ sshlog(file, func, line, 0, level, NULL, "%s [%s]", msg, pmonitor->m_state); +- sshlogdirect(level, forced, "%s [preauth]", msg); ++ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state); sshbuf_free(logmsg); - free(file); -@@ -1719,13 +1723,28 @@ monitor_init(void) + free(msg); +@@ -1868,13 +1872,28 @@ monitor_init(void) mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); @@ -98,10 +98,10 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c } #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 { +diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.log-in-chroot 2021-04-19 14:43:08.527843305 +0200 ++++ openssh-8.6p1/monitor.h 2021-04-19 14:43:08.545843441 +0200 +@@ -80,10 +80,11 @@ struct monitor { int m_log_sendfd; struct kex **m_pkex; pid_t m_pid; @@ -114,9 +114,9 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h 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 +diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.log-in-chroot 2021-04-19 14:43:08.534843358 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:43:08.545843441 +0200 @@ -160,6 +160,7 @@ login_cap_t *lc; static int is_child = 0; @@ -125,7 +125,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) +@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -133,7 +133,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c if (options.adm_forced_command) { original_command = command; -@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) +@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con tty += 5; } @@ -144,7 +144,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c 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) +@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh) /* Stop directing logs to a high-numbered fd before we close it */ log_redirect_stderr_to(NULL); @@ -159,7 +159,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c } /* -@@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command +@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co exit(1); } @@ -168,7 +168,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command +@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -187,9 +187,9 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c 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 +diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h +--- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp.h 2021-04-19 14:43:08.545843441 +0200 @@ -97,5 +97,5 @@ struct passwd; @@ -197,10 +197,10 @@ diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h -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) +diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c +--- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server.c 2021-04-19 14:43:08.545843441 +0200 +@@ -1644,7 +1644,7 @@ sftp_server_usage(void) } int @@ -209,7 +209,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c { 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, +@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -218,7 +218,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c pw = pwcopy(user_pw); -@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, +@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv, } } @@ -227,20 +227,20 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c /* * 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) +diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c +--- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server-main.c 2021-04-19 14:43:08.545843441 +0200 +@@ -50,5 +50,5 @@ main(int argc, char **argv) return 1; } - 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) +diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:43:08.545843441 +0200 +@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct } /* New socket pair */ @@ -249,7 +249,7 @@ diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt) +@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 5b75dda..2814c6f 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,21 +1,271 @@ +diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c +--- openssh-8.5p1/addr.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/addr.c 2021-03-24 12:03:33.782968159 +0100 +@@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n + if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) + return -1; + +- if (ai == NULL || ai->ai_addr == NULL) ++ if (ai == NULL || ai->ai_addr == NULL) { ++ freeaddrinfo(ai); + return -1; ++ } + + if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, + n) == -1) { +@@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char * + if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0) + return -1; + +- if (ai == NULL || ai->ai_addr == NULL) ++ if (ai == NULL || ai->ai_addr == NULL) { ++ freeaddrinfo(ai); + return -1; ++ } + + if (sa != NULL) { +- if (slen < ai->ai_addrlen) ++ if (slen < ai->ai_addrlen) { ++ freeaddrinfo(ai); + return -1; ++ } + memcpy(sa, &ai->ai_addr, ai->ai_addrlen); + } + +diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c +--- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100 ++++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100 +@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, + umask(old_umask); + if (tmpfd == -1) { + logit("mkstemp(): %.100s", strerror(oerrno)); ++ free(ccname); + return oerrno; + } + +@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, + oerrno = errno; + logit("fchmod(): %.100s", strerror(oerrno)); + close(tmpfd); ++ free(ccname); + return oerrno; + } + /* make sure the KRB5CCNAME is set for non-standard location */ +diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c +--- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 +@@ -409,8 +409,10 @@ sshauthopt_parse(const char *opts, const + errstr = "invalid environment string"; + goto fail; + } +- if ((cp = strdup(opt)) == NULL) ++ if ((cp = strdup(opt)) == NULL) { ++ free(opt); + goto alloc_fail; ++ } + cp[tmp - opt] = '\0'; /* truncate at '=' */ + if (!valid_env_name(cp)) { + free(cp); +@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * + return r; + } + /* success */ ++ sshbuf_free(b); + return 0; + } + 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 +@@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh, + debug("channel %d: connection failed: %s", + c->self, strerror(err)); + /* Try next address, if any */ +- if ((sock = connect_next(&c->connect_ctx)) > 0) { ++ if ((sock = connect_next(&c->connect_ctx)) >= 0) { + close(c->sock); + c->sock = c->rfd = c->wfd = sock; + channel_find_maxfd(ssh->chanctxt); +@@ -3804,7 +3804,7 @@ int + channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) + { + int r, success = 0, idx = -1; +- char *host_to_connect, *listen_host, *listen_path; ++ char *host_to_connect = NULL, *listen_host = NULL, *listen_path = NULL; + int port_to_connect, listen_port; - /* 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); + /* Send the forward request to the remote side. */ +@@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct + success = 1; + if (success) { + /* Record that connection to this host/port is permitted. */ +- host_to_connect = listen_host = listen_path = NULL; + port_to_connect = listen_port = 0; + if (fwd->connect_path != NULL) { + host_to_connect = xstrdup(fwd->connect_path); +@@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct + host_to_connect, port_to_connect, + listen_host, listen_path, listen_port, NULL); } ++ free(host_to_connect); ++ free(listen_host); ++ free(listen_path); + return idx; } + +diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c +--- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100 ++++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100 +@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha + return p; + debug2_f("original KEX proposal: %s", p); + if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) ++ /* coverity[overwrite_var : FALSE] */ + if ((p = match_filter_denylist(p, + "curve25519-sha256@libssh.org")) == NULL) + fatal("match_filter_denylist failed"); + if ((ssh->compat & SSH_OLD_DHGEX) != 0) { ++ /* coverity[overwrite_var : FALSE] */ + if ((p = match_filter_denylist(p, + "diffie-hellman-group-exchange-sha256," + "diffie-hellman-group-exchange-sha1")) == NULL) +diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c +--- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 +@@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname + &hostkey_digest_len, hostkey)) { + error("Error calculating key fingerprint."); + freerrset(fingerprints); ++ free(dnskey_digest); + return -1; + } + } +diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c +--- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 ++++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 +@@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + enclen = __b64_ntop(digest, + ssh_digest_bytes(SSH_DIGEST_MD5), encoded, + ssh_digest_bytes(SSH_DIGEST_MD5) * 2); +- ++#pragma GCC diagnostic ignored "-Wstringop-overflow" + cp = strncpy(s, kex, strlen(kex)); ++#pragma pop + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && +diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c +--- openssh-8.5p1/kexgssc.c.coverity 2021-03-24 12:03:33.711967665 +0100 ++++ openssh-8.5p1/kexgssc.c 2021-03-24 12:03:33.783968166 +0100 +@@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) + default: + fatal_f("Unexpected KEX type %d", kex->kex_type); + } +- if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&ctxt); + return r; ++ } + + token_ptr = GSS_C_NO_BUFFER; + +diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c +--- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 +@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st + sshkey_free(key); + sshbuf_free(copy); + sshbuf_free(sect); ++ /* coverity[leaked_storage : FALSE] */ + return r; + } + +@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by key SHA1")); + return SSH_ERR_KEY_REVOKED; +@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by key SHA256")); + return SSH_ERR_KEY_REVOKED; +@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by explicit key")); + return SSH_ERR_KEY_REVOKED; +diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c +--- openssh-8.5p1/loginrec.c.coverity 2021-03-24 13:18:53.793225885 +0100 ++++ openssh-8.5p1/loginrec.c 2021-03-24 13:21:27.948404751 +0100 +@@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li, + */ + + /* Use strncpy because we don't necessarily want null termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_name, li->username, + MIN_SIZEOF(ut->ut_name, li->username)); + # ifdef HAVE_HOST_IN_UTMP ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_host, li->hostname, + MIN_SIZEOF(ut->ut_host, li->hostname)); + # endif +@@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con + + memset(&ut, 0, sizeof(ut)); + /* strncpy because we don't necessarily want nul termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut.ut_user, username, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); + +@@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con + ut.ut_pid = getpid(); + + /* strncpy because we don't necessarily want nul termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + + if (ssh_packet_connection_is_on_socket(ssh) && +diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c +--- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100 ++++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100 +@@ -1425,6 +1425,8 @@ sanitise_stdfd(void) + } + if (nullfd > STDERR_FILENO) + close(nullfd); ++ /* coverity[leaked_handle : FALSE]*/ ++ /* coverity[leaked_handle : FALSE]*/ + } + + char * +@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou + } + if (devnull > STDERR_FILENO) + close(devnull); ++ /* coverity[leaked_handle : FALSE]*/ + return ret; + } + +diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c +--- openssh-8.5p1/moduli.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/moduli.c 2021-03-24 12:03:33.784968173 +0100 +@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t + else + logit("failed to write to checkpoint file '%s': %s", cpfile, + strerror(errno)); ++ /* coverity[leaked_storage : FALSE] */ + } + + static unsigned long 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 @@ -28,6 +278,15 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ; if (pmonitor->m_recvfd >= 0) +@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock, + s->ptymaster = s->ptyfd; + + debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); +- ++ /* coverity[leaked_handle : FALSE] */ + return (0); + + error: diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c --- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100 +++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100 @@ -57,6 +316,17 @@ diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/open int i; if (sa == NULL) { +diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c +--- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100 ++++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100 +@@ -1847,6 +1847,7 @@ parse_pubkey_algos: + } else if (r != 0) { + error("%.200s line %d: glob failed for %s.", + filename, linenum, arg2); ++ free(arg2); + return -1; + } + free(arg2); 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 @@ -132,6 +402,24 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != (int)tun) goto done; +diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c +--- openssh-8.5p1/session.c.coverity 2021-03-24 12:03:33.777968124 +0100 ++++ openssh-8.5p1/session.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s + /* Environment specified by admin */ + for (i = 0; i < options.num_setenv; i++) { + cp = xstrdup(options.setenv[i]); ++ /* coverity[overwrite_var : FALSE] */ + if ((value = strchr(cp, '=')) == NULL) { + /* shouldn't happen; vars are checked in servconf.c */ + fatal("Invalid config SetEnv: %s", options.setenv[i]); + } + *value++ = '\0'; + child_set_env(&env, &envsize, cp, value); ++ free(cp); + } + + /* SSH_CLIENT deprecated */ 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 @@ -144,9 +432,45 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); +@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons + fflag || global_fflag) == -1) + err = -1; + } ++ free(abs_dst); ++ abs_dst = NULL; + } + + out: +@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co + if (lflag & LS_LONG_VIEW) { + if (g.gl_statv[i] == NULL) { + error("no stat information for %s", fname); ++ free(fname); + continue; + } + lname = ls_file(fname, g.gl_statv[i], 1, +diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c +--- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s + freezero(rks[i], sizeof(*rks[i])); + } + free(rks); ++ free(device); + return ret; + } + diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c --- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100 +@@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro + + if (pkcs11_uri_parse(provider, uri) != 0) { + error("Failed to parse PKCS#11 URI"); ++ pkcs11_uri_cleanup(uri); + return NULL; + } + /* validate also provider from URI */ @@ -1220,8 +1220,8 @@ main(int ac, char **av) sanitise_stdfd(); @@ -158,6 +482,17 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c platform_disable_tracing(0); /* strict=no */ +diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c +--- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100 ++++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1746,6 +1746,7 @@ control_persist_detach(void) + close(muxserver_sock); + muxserver_sock = -1; + options.control_master = SSHCTL_MASTER_NO; ++ /* coverity[leaked_handle: FALSE]*/ + muxclient(options.control_path); + /* muxclient() doesn't return on success. */ + fatal("Failed to connect to new control master"); diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c --- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100 +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 @@ -183,3 +518,67 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c } /* +@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh) + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +- ++ /* coverity[leaked_storage : FALSE]*/ + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( + ssh, list_hostkey_types()); + +@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) + + if (newstr) + myproposal[PROPOSAL_KEX_ALGS] = newstr; +- else ++ else { + fatal("No supported key exchange algorithms"); ++ free(gss); ++ } ++ /* coverity[leaked_storage: FALSE]*/ + } + #endif + +diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c +--- openssh-8.5p1/ssh-keygen.c.coverity 2021-03-24 12:03:33.780968145 +0100 ++++ openssh-8.5p1/ssh-keygen.c 2021-03-24 12:03:33.787968194 +0100 +@@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw, + r = ssh_krl_revoke_key_sha256(krl, blob, blen); + if (r != 0) + fatal_fr(r, "revoke key failed"); ++ freezero(blob, blen); ++ blob = NULL; ++ blen = 0; + } else { + if (strncasecmp(cp, "key:", 4) == 0) { + cp += 4; +@@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c + } else if (strncmp(opts[i], "start-line=", 11) == 0) { + start_lineno = strtoul(opts[i]+11, NULL, 10); + } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { ++ free(checkpoint); + checkpoint = xstrdup(opts[i]+11); + } else if (strncmp(opts[i], "generator=", 10) == 0) { + generator_wanted = (u_int32_t)strtonum( +@@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c + #else /* WITH_OPENSSL */ + fatal("Moduli screening is not supported"); + #endif /* WITH_OPENSSL */ ++ free(checkpoint); ++ if (in != stdin) ++ fclose(in); + } + + static char * +diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c +--- openssh-8.5p1/sshsig.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sshsig.c 2021-03-24 12:03:33.787968194 +0100 +@@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s + oerrno = errno; + error_f("read: %s", strerror(errno)); + ssh_digest_free(ctx); ++ ctx = NULL; + errno = oerrno; + r = SSH_ERR_SYSTEM_ERROR; + goto out; diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 85d0650..f3b1334 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,7 +1,7 @@ -diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c ---- openssh/audit-bsm.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-bsm.c 2019-04-03 17:02:20.713886041 +0200 -@@ -372,13 +372,26 @@ audit_connection_from(const char *host, +diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c +--- openssh-8.6p1/audit-bsm.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-bsm.c 2021-04-19 16:47:35.753062106 +0200 +@@ -373,13 +373,26 @@ audit_connection_from(const char *host, #endif } @@ -29,7 +29,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c audit_session_open(struct logininfo *li) { /* not implemented */ -@@ -390,6 +403,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -42,7 +42,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -451,4 +470,28 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e debug("%s: unhandled event %d", __func__, event); } } @@ -71,9 +71,9 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh/audit.c.audit openssh/audit.c ---- openssh/audit.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c +--- openssh-8.6p1/audit.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.c 2021-04-19 16:47:35.753062106 +0200 @@ -34,6 +34,12 @@ #include "log.h" #include "hostfile.h" @@ -251,9 +251,9 @@ diff -up openssh/audit.c.audit openssh/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/audit.h.audit openssh/audit.h ---- openssh/audit.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.h 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.h.audit openssh-8.6p1/audit.h +--- openssh-8.6p1/audit.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.h 2021-04-19 16:47:35.753062106 +0200 @@ -26,6 +26,7 @@ # define _SSH_AUDIT_H @@ -296,9 +296,9 @@ diff -up openssh/audit.h.audit openssh/audit.h +void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); #endif /* _SSH_AUDIT_H */ -diff -up openssh/audit-linux.c.audit openssh/audit-linux.c ---- openssh/audit-linux.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-linux.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c +--- openssh-8.6p1/audit-linux.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-linux.c 2021-04-19 16:47:35.753062106 +0200 @@ -33,27 +33,40 @@ #include "log.h" @@ -669,9 +669,9 @@ diff -up openssh/audit-linux.c.audit openssh/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh/auditstub.c.audit openssh/auditstub.c ---- openssh/auditstub.c.audit 2019-04-03 17:02:20.714886050 +0200 -+++ openssh/auditstub.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c +--- openssh-8.6p1/auditstub.c.audit 2021-04-19 16:47:35.754062114 +0200 ++++ openssh-8.6p1/auditstub.c 2021-04-19 16:47:35.754062114 +0200 @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -725,10 +725,10 @@ diff -up openssh/auditstub.c.audit openssh/auditstub.c +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh/auth2.c.audit openssh/auth2.c ---- openssh/auth2.c.audit 2019-04-03 17:02:20.651885453 +0200 -+++ openssh/auth2.c 2019-04-03 17:02:20.714886050 +0200 -@@ -303,9 +303,6 @@ input_userauth_request(int type, u_int32 +diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c +--- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200 ++++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200 +@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); @@ -738,9 +738,9 @@ diff -up openssh/auth2.c.audit openssh/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.audit 2019-04-03 17:02:20.612885083 +0200 -+++ openssh/auth2-hostbased.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c +--- openssh-8.6p1/auth2-hostbased.c.audit 2021-04-19 16:47:35.656061361 +0200 ++++ 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, @@ -771,10 +771,10 @@ diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth2-pubkey.c 2019-04-03 17:02:20.714886050 +0200 -@@ -219,7 +219,7 @@ userauth_pubkey(struct ssh *ssh) +diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c +--- openssh-8.6p1/auth2-pubkey.c.audit 2021-04-19 16:47:35.726061899 +0200 ++++ openssh-8.6p1/auth2-pubkey.c 2021-04-19 16:47:35.754062114 +0200 +@@ -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)) && @@ -783,7 +783,7 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details)) == 0) { -@@ -278,6 +278,20 @@ done: +@@ -305,6 +305,20 @@ done: return authenticated; } @@ -804,10 +804,10 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { -diff -up openssh/auth.c.audit openssh/auth.c ---- openssh/auth.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth.c 2019-04-03 17:02:20.714886050 +0200 -@@ -366,7 +366,7 @@ auth_log(struct ssh *ssh, int authentica +diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c +--- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 ++++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 +@@ -367,7 +367,7 @@ auth_log(struct ssh *ssh, int authentica # endif #endif #ifdef SSH_AUDIT_EVENTS @@ -816,7 +816,7 @@ diff -up openssh/auth.c.audit openssh/auth.c audit_event(ssh, audit_classify_auth(method)); #endif } -@@ -592,9 +592,6 @@ getpwnamallow(struct ssh *ssh, const cha +@@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -826,10 +826,10 @@ diff -up openssh/auth.c.audit openssh/auth.c return (NULL); } if (!allowed_user(ssh, pw)) -diff -up openssh/auth.h.audit openssh/auth.h ---- openssh/auth.h.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/auth.h 2019-04-03 17:02:20.714886050 +0200 -@@ -195,6 +195,8 @@ struct passwd * getpwnamallow(struct ssh +diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200 ++++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200 +@@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -838,7 +838,7 @@ diff -up openssh/auth.h.audit openssh/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -214,6 +216,8 @@ struct sshkey *get_hostkey_private_by_ty +@@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty int get_hostkey_index(struct sshkey *, int, struct ssh *); int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *); @@ -847,10 +847,10 @@ diff -up openssh/auth.h.audit openssh/auth.h /* Key / cert options linkage to auth layer */ const struct sshauthopt *auth_options(struct ssh *); -diff -up openssh/cipher.c.audit openssh/cipher.c ---- openssh/cipher.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.c 2019-04-03 17:02:20.714886050 +0200 -@@ -61,25 +61,6 @@ struct sshcipher_ctx { +diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c +--- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200 +@@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -876,7 +876,7 @@ diff -up openssh/cipher.c.audit openssh/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -410,7 +391,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) { @@ -885,10 +885,10 @@ diff -up openssh/cipher.c.audit openssh/cipher.c return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); -diff -up openssh/cipher.h.audit openssh/cipher.h ---- openssh/cipher.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.h 2019-04-03 17:02:20.714886050 +0200 -@@ -45,7 +45,25 @@ +diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h +--- openssh-8.6p1/cipher.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/cipher.h 2021-04-19 16:47:35.755062122 +0200 +@@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -915,10 +915,10 @@ diff -up openssh/cipher.h.audit openssh/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh/kex.c.audit openssh/kex.c ---- openssh/kex.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.c 2019-04-03 17:02:20.715886060 +0200 -@@ -60,6 +60,7 @@ +diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200 ++++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200 +@@ -65,6 +65,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -926,7 +926,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -758,12 +759,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -945,7 +945,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -959,7 +959,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma } static int @@ -978,7 +978,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -933,7 +946,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1002,7 +1015,7 @@ kex_choose_conf(struct ssh *ssh) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; @@ -987,7 +987,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -948,7 +961,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) peer[nmac] = NULL; goto out; } @@ -996,7 +996,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -971,6 +984,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -1040,6 +1053,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -1007,7 +1007,7 @@ diff -up openssh/kex.c.audit openssh/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1129,6 +1146,36 @@ dump_digest(const char *msg, const u_cha +@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha } #endif @@ -1044,9 +1044,9 @@ diff -up openssh/kex.c.audit openssh/kex.c /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff -up openssh/kex.h.audit openssh/kex.h ---- openssh/kex.h.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h +--- openssh-8.6p1/kex.h.audit 2021-04-19 16:47:35.683061568 +0200 ++++ openssh-8.6p1/kex.h 2021-04-19 16:47:35.756062129 +0200 @@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1056,10 +1056,10 @@ diff -up openssh/kex.h.audit openssh/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff -up openssh/mac.c.audit openssh/mac.c ---- openssh/mac.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/mac.c 2019-04-03 17:02:20.715886060 +0200 -@@ -243,6 +243,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c +--- openssh-8.6p1/mac.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.c 2021-04-19 16:47:35.756062129 +0200 +@@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1080,9 +1080,9 @@ diff -up openssh/mac.c.audit openssh/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh/mac.h.audit openssh/mac.h ---- openssh/mac.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/mac.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/mac.h.audit openssh-8.6p1/mac.h +--- openssh-8.6p1/mac.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.h 2021-04-19 16:47:35.756062129 +0200 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1090,21 +1090,21 @@ diff -up openssh/mac.h.audit openssh/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh/Makefile.in.audit openssh/Makefile.in ---- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 -+++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 -@@ -109,7 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in +--- openssh-8.6p1/Makefile.in.audit 2021-04-19 16:47:35.731061937 +0200 ++++ openssh-8.6p1/Makefile.in 2021-04-19 16:47:35.756062129 +0200 +@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o + sshbuf-io.o auditstub.o SKOBJS= ssh-sk-client.o -diff -up openssh/monitor.c.audit openssh/monitor.c ---- openssh/monitor.c.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.c 2019-04-03 17:03:17.201421405 +0200 +diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.audit 2021-04-19 16:47:35.707061753 +0200 ++++ openssh-8.6p1/monitor.c 2021-04-19 16:47:35.756062129 +0200 @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1113,7 +1113,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -107,6 +108,8 @@ extern u_char session_id[]; +@@ -107,6 +108,8 @@ extern u_int utmp_len; extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1157,7 +1157,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #endif {0, 0, NULL} }; -@@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1169,7 +1169,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1178,7 +1178,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1470,27 +1491,30 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1469,14 +1490,19 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1198,11 +1198,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c break; } if (!valid_data) - fatal_f("bad %s signature data blob", - key_blobtype == MM_USERKEY ? "userkey" : - (key_blobtype == MM_HOSTKEY ? "hostkey" : "unknown")); - - if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, +@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); @@ -1211,7 +1207,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c debug3_f("%s %p signature %s%s%s", auth_method, key, (ret == 0) ? "verified" : "unverified", (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); -@@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session +@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } static void @@ -1232,7 +1228,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c session_unused(s->self); } -@@ -1609,7 +1639,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, error: if (s != NULL) @@ -1241,7 +1237,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1628,7 +1658,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i +@@ -1668,7 +1698,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1250,7 +1246,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c sshbuf_reset(m); free(tty); return (0); -@@ -1650,6 +1680,8 @@ mm_answer_term(struct ssh *ssh, int sock +@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock sshpam_cleanup(); #endif @@ -1259,7 +1255,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1696,12 +1728,47 @@ mm_answer_audit_command(struct ssh *ssh, +@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, { char *cmd; int r; @@ -1308,7 +1304,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c free(cmd); return (0); } -@@ -1767,6 +1834,7 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1316,7 +1312,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1774,6 +1842,19 @@ mm_get_keystate(struct ssh *ssh, struct +@@ -1820,6 +1888,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1336,7 +1332,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c } -@@ -2066,3 +2147,102 @@ mm_answer_gss_updatecreds(struct ssh *ss +@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss #endif /* GSSAPI */ @@ -1439,9 +1435,9 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor.h.audit openssh/monitor.h ---- openssh/monitor.h.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.audit 2021-04-19 16:47:35.707061753 +0200 ++++ openssh-8.6p1/monitor.h 2021-04-19 16:47:35.757062137 +0200 @@ -65,7 +65,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1457,10 +1453,10 @@ diff -up openssh/monitor.h.audit openssh/monitor.h MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.c 2019-04-03 17:02:20.716886069 +0200 -@@ -513,7 +513,7 @@ mm_key_allowed(enum mm_keytype type, con +diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c +--- openssh-8.6p1/monitor_wrap.c.audit 2021-04-19 16:47:35.685061584 +0200 ++++ openssh-8.6p1/monitor_wrap.c 2021-04-19 16:47:35.757062137 +0200 +@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1469,7 +1465,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1479,7 +1475,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -547,6 +548,22 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } @@ -1502,7 +1498,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -900,11 +915,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi +@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi sshbuf_free(m); } @@ -1517,7 +1513,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -914,6 +930,30 @@ mm_audit_run_command(const char *command +@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); @@ -1548,7 +1544,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc } #endif /* GSSAPI */ @@ -1632,10 +1628,10 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.h 2019-04-03 17:02:20.716886069 +0200 -@@ -57,7 +57,9 @@ int mm_user_key_allowed(struct ssh *, st +diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h +--- openssh-8.6p1/monitor_wrap.h.audit 2021-04-19 16:47:35.685061584 +0200 ++++ openssh-8.6p1/monitor_wrap.h 2021-04-19 16:47:35.757062137 +0200 +@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *, st struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1646,7 +1642,7 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); #ifdef GSSAPI -@@ -82,7 +84,12 @@ void mm_sshpam_free_ctx(void *); +@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1660,10 +1656,10 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h #endif struct Session; -diff -up openssh/packet.c.audit openssh/packet.c ---- openssh/packet.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.c 2019-04-03 17:02:20.716886069 +0200 -@@ -77,6 +77,7 @@ +diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c +--- openssh-8.6p1/packet.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.c 2021-04-19 16:48:46.885608837 +0200 +@@ -81,6 +81,7 @@ #endif #include "xmalloc.h" @@ -1671,7 +1667,7 @@ diff -up openssh/packet.c.audit openssh/packet.c #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1685,7 +1681,7 @@ diff -up openssh/packet.c.audit openssh/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -587,22 +595,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss { struct session_state *state = ssh->state; u_int mode; @@ -1713,7 +1709,7 @@ diff -up openssh/packet.c.audit openssh/packet.c for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -636,8 +641,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1732,15 +1728,15 @@ diff -up openssh/packet.c.audit openssh/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -864,6 +879,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - (unsigned long long)state->p_send.bytes, - (unsigned long long)state->p_send.blocks); +@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); + audit_session_key_free(ssh, mode); state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2167,6 +2183,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1813,18 +1809,18 @@ diff -up openssh/packet.c.audit openssh/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh/packet.h.audit openssh/packet.h ---- openssh/packet.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.h 2019-04-03 17:02:20.716886069 +0200 -@@ -217,4 +217,5 @@ const u_char *sshpkt_ptr(struct ssh *, s +diff -up openssh-8.6p1/packet.h.audit openssh-8.6p1/packet.h +--- openssh-8.6p1/packet.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.h 2021-04-19 16:47:35.758062145 +0200 +@@ -218,4 +218,5 @@ const u_char *sshpkt_ptr(struct ssh *, s # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh/session.c.audit openssh/session.c ---- openssh/session.c.audit 2019-04-03 17:02:20.712886031 +0200 -+++ openssh/session.c 2019-04-03 17:02:20.716886069 +0200 +diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.audit 2021-04-19 16:47:35.722061868 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 16:47:35.758062145 +0200 @@ -136,7 +136,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; @@ -1834,7 +1830,7 @@ diff -up openssh/session.c.audit openssh/session.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -648,6 +648,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1849,7 +1845,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -740,15 +748,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1871,7 +1867,7 @@ diff -up openssh/session.c.audit openssh/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1556,8 +1568,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ @@ -1884,7 +1880,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1769,6 +1784,9 @@ session_unused(int id) +@@ -1763,6 +1778,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1894,7 +1890,7 @@ diff -up openssh/session.c.audit openssh/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1851,6 +1869,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1914,7 +1910,7 @@ diff -up openssh/session.c.audit openssh/session.c session_by_tty(char *tty) { int i; -@@ -2461,6 +2492,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } @@ -1947,7 +1943,7 @@ diff -up openssh/session.c.audit openssh/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2474,6 +2531,10 @@ session_close(struct ssh *ssh, Session * +@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1958,7 +1954,7 @@ diff -up openssh/session.c.audit openssh/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2549,14 +2610,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh } void @@ -1975,7 +1971,7 @@ diff -up openssh/session.c.audit openssh/session.c else session_close(ssh, s); } -@@ -2683,6 +2744,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } @@ -1991,7 +1987,7 @@ diff -up openssh/session.c.audit openssh/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2746,7 +2816,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -2000,9 +1996,9 @@ diff -up openssh/session.c.audit openssh/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh/session.h.audit openssh/session.h ---- openssh/session.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/session.h 2019-04-03 17:02:20.717886079 +0200 +diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h +--- openssh-8.6p1/session.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/session.h 2021-04-19 16:47:35.758062145 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2030,9 +2026,9 @@ diff -up openssh/session.h.audit openssh/session.h Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh/sshd.c.audit openssh/sshd.c ---- openssh/sshd.c.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/sshd.c 2019-04-03 17:02:20.717886079 +0200 +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 @@ -2041,7 +2037,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -261,8 +262,8 @@ struct sshbuf *loginmsg; +@@ -260,8 +261,8 @@ struct sshbuf *loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2052,7 +2048,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void do_ssh2_kex(struct ssh *); static char *listener_proctitle; -@@ -278,6 +279,15 @@ close_listen_socks(void) +@@ -279,6 +280,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2068,7 +2064,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void close_startup_pipes(void) { -@@ -380,18 +390,45 @@ grace_alarm_handler(int sig) +@@ -377,18 +387,45 @@ grace_alarm_handler(int sig) ssh_remote_port(the_active_state)); } @@ -2117,7 +2113,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -400,20 +437,38 @@ destroy_sensitive_data(void) +@@ -397,20 +434,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2157,7 +2153,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c } /* Certs do not need demotion */ } -@@ -442,7 +497,7 @@ reseed_prngs(void) +@@ -438,7 +493,7 @@ reseed_prngs(void) } static void @@ -2166,7 +2162,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { gid_t gidset[1]; -@@ -457,7 +512,7 @@ privsep_preauth_child(void) +@@ -453,7 +508,7 @@ privsep_preauth_child(void) reseed_prngs(); /* Demote the private keys to public keys. */ @@ -2175,7 +2171,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #ifdef WITH_SELINUX sshd_selinux_change_privsep_preauth_context(); -@@ -496,7 +551,7 @@ privsep_preauth(struct ssh *ssh) +@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2184,7 +2180,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -542,7 +597,7 @@ privsep_preauth(struct ssh *ssh) +@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); @@ -2193,7 +2189,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); -@@ -594,7 +649,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2202,7 +2198,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c reseed_prngs(); -@@ -1057,7 +1112,7 @@ server_listen(void) +@@ -1143,7 +1198,7 @@ server_listen(void) * from this function are in a forked subprocess. */ static void @@ -2211,7 +2207,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { fd_set *fdset; int i, j, ret, maxfd; -@@ -1112,6 +1167,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2219,7 +2215,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -1978,7 +2034,7 @@ main(int ac, char **av) +@@ -2098,7 +2154,7 @@ main(int ac, char **av) #endif /* Accept a connection and return in a forked child */ @@ -2228,7 +2224,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c &newsock, config_s); } -@@ -2222,6 +2278,9 @@ main(int ac, char **av) +@@ -2333,6 +2389,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2238,7 +2234,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2401,6 +2460,15 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2513,6 +2572,15 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2254,7 +2250,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2414,9 +2482,16 @@ cleanup_exit(int i) +@@ -2525,9 +2593,16 @@ cleanup_exit(int i) } } } @@ -2272,10 +2268,10 @@ diff -up openssh/sshd.c.audit openssh/sshd.c audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh/sshkey.c.audit openssh/sshkey.c ---- openssh/sshkey.c.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.c 2019-04-03 17:02:20.718886088 +0200 -@@ -331,6 +331,38 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.audit 2021-04-19 16:47:35.741062014 +0200 ++++ openssh-8.6p1/sshkey.c 2021-04-19 16:47:35.759062152 +0200 +@@ -371,6 +371,38 @@ sshkey_type_is_valid_ca(int type) } int @@ -2314,10 +2310,10 @@ diff -up openssh/sshkey.c.audit openssh/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh/sshkey.h.audit openssh/sshkey.h ---- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 -@@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h +--- openssh-8.6p1/sshkey.h.audit 2021-04-19 16:47:35.741062014 +0200 ++++ openssh-8.6p1/sshkey.h 2021-04-19 16:47:35.759062152 +0200 +@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshke int sshkey_unshield_private(struct sshkey *); int sshkey_type_from_name(const char *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index f199fb2..d2c5592 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -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 +diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c +--- openssh-8.6p1/cipher-ctr.c.fips 2021-04-19 16:53:02.994577324 +0200 ++++ openssh-8.6p1/cipher-ctr.c 2021-04-19 16:53:03.064577862 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -11,10 +11,10 @@ diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c #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 +diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200 +@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -24,10 +24,10 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c + return (dh_new_group_fallback(max)); + } + - if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { + if ((f = fopen(get_moduli_filename(), "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) + get_moduli_filename(), strerror(errno)); +@@ -502,4 +508,38 @@ dh_estimate(int bits) return 8192; } @@ -66,21 +66,21 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c +} + #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); +diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h +--- openssh-8.6p1/dh.h.fips 2021-04-19 16:53:03.064577862 +0200 ++++ openssh-8.6p1/dh.h 2021-04-19 16:59:31.951616078 +0200 +@@ -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); - -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) + 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-04-19 16:53:03.058577815 +0200 ++++ openssh-8.6p1/kex.c 2021-04-19 16:53:03.065577869 +0200 +@@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -92,9 +92,9 @@ diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c 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 +diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c +--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-04-19 16:53:03.065577869 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -103,7 +103,7 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c #include #include -@@ -113,6 +114,10 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -114,10 +114,10 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c 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 @@ +diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h +--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/myproposal.h 2021-04-19 16:53:03.065577869 +0200 +@@ -57,6 +57,20 @@ "rsa-sha2-256," \ "ssh-rsa" @@ -138,7 +138,7 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr," \ -@@ -134,6 +142,27 @@ +@@ -78,6 +92,27 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -166,10 +166,10 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ -diff -up openssh-8.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) +diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c +--- openssh-8.6p1/readconf.c.fips 2021-04-19 16:53:02.999577362 +0200 ++++ openssh-8.6p1/readconf.c 2021-04-19 16:53:03.065577869 +0200 +@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -191,10 +191,10 @@ diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c #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_ +diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-04-19 16:53:03.034577631 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-04-19 16:53:03.065577869 +0200 +@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -204,10 +204,10 @@ diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-secco #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) +diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.fips 2021-04-19 16:53:03.027577577 +0200 ++++ openssh-8.6p1/servconf.c 2021-04-19 16:53:03.066577877 +0200 +@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -229,10 +229,10 @@ diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c #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 @@ +diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.fips 2021-04-19 16:53:03.038577662 +0200 ++++ openssh-8.6p1/ssh.c 2021-04-19 16:53:03.066577877 +0200 +@@ -77,6 +77,7 @@ #include #include #endif @@ -240,21 +240,21 @@ diff -up openssh-8.0p1/ssh.c.fips openssh-8.0p1/ssh.c #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); +@@ -1516,6 +1517,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 == '$' && -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 @@ + strlen(options.sk_provider) > 1) { +diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1/sshconnect2.c.fips 2021-04-19 16:53:03.055577792 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-04-19 16:53:03.066577877 +0200 +@@ -45,6 +45,8 @@ #include #endif @@ -263,7 +263,7 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -198,36 +203,41 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -279,24 +279,6 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c - * 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; @@ -316,9 +298,24 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c + gss_host = xstrdup(host); + } + } else { -+ gss_host = xstrdup(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); + gss = ssh_gssapi_client_mechanisms(gss_host, + options.gss_client_identity, options.gss_kex_algorithms); + if (gss) { @@ -335,9 +332,9 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c } } #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 +diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200 @@ -66,6 +66,7 @@ #include #include @@ -354,7 +351,7 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1529,6 +1532,7 @@ main(int ac, char **av) +@@ -1619,6 +1621,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -362,7 +359,7 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c /* 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) +@@ -2110,6 +2113,10 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -370,10 +367,10 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c + 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) + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. +@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -392,9 +389,9 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c 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 +diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.fips 2021-04-19 16:53:03.061577838 +0200 ++++ openssh-8.6p1/sshkey.c 2021-04-19 16:53:03.067577885 +0200 @@ -34,6 +34,7 @@ #include #include @@ -411,7 +408,7 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -420,10 +417,10 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c 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 +diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 +@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } #ifdef WITH_OPENSSL @@ -436,7 +433,7 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c switch (type) { case KEY_DSA: if (*bitsp != 1024) -@@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw) +@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); } @@ -454,4 +451,4 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c - 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)); + prv_tmp, strerror(errno)); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 3b9ef3a..387b7a0 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -1,7 +1,26 @@ -diff --git a/auth-krb5.c b/auth-krb5.c -index a5a81ed2..63f877f2 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c +diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.ccache_name 2021-04-19 14:05:10.820744325 +0200 ++++ openssh-8.6p1/auth.h 2021-04-19 14:05:10.853744569 +0200 +@@ -83,6 +83,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -231,7 +232,7 @@ struct passwd *fakepw(void); + int sys_auth_passwd(struct ssh *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + #endif + + #endif /* AUTH_H */ +diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c +--- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/auth-krb5.c 2021-04-19 14:40:55.142832954 +0200 @@ -51,6 +51,7 @@ #include #include @@ -10,7 +29,7 @@ index a5a81ed2..63f877f2 100644 extern ServerOptions options; -@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -19,24 +38,18 @@ index a5a81ed2..63f877f2 100644 char *client, *platform_client; const char *errmsg; -@@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c 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; -@@ -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) +@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c goto out; #endif @@ -57,7 +70,7 @@ index a5a81ed2..63f877f2 100644 do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif -@@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c void krb5_cleanup_proc(Authctxt *authctxt) { @@ -113,7 +126,7 @@ index a5a81ed2..63f877f2 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) } } @@ -198,10 +211,7 @@ index a5a81ed2..63f877f2 100644 + return -1; +} + - krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -- int tmpfd, ret, oerrno; -- char ccname[40]; ++krb5_error_code +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { + profile_t p; + int ret = 0; @@ -222,7 +232,10 @@ index a5a81ed2..63f877f2 100644 + return ret; +} + -+krb5_error_code + krb5_error_code +-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { +- int tmpfd, ret, oerrno; +- char ccname[40]; +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno, type_len; + char *ccname = NULL; @@ -324,30 +337,41 @@ index a5a81ed2..63f877f2 100644 } #endif /* !HEIMDAL */ #endif /* KRB5 */ -diff --git a/auth.h b/auth.h -index 29491df9..fdab5040 100644 ---- a/auth.h -+++ b/auth.h -@@ -82,6 +82,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; +diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c +--- openssh-8.6p1/gss-serv.c.ccache_name 2021-04-19 14:05:10.844744503 +0200 ++++ openssh-8.6p1/gss-serv.c 2021-04-19 14:05:10.854744577 +0200 +@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void) + } -@@ -238,7 +239,7 @@ int sys_auth_passwd(struct ssh *, const char *); - int sys_auth_passwd(struct ssh *, const char *); + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } - #if defined(KRB5) && !defined(HEIMDAL) --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + /* This allows GSSAPI methods to do things to the child's environment based +@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) { + char *envstr; #endif - #endif /* AUTH_H */ -diff -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 +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); +diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c +--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/gss-serv-krb5.c 2021-04-19 14:05:10.854744577 +0200 @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ @@ -450,7 +474,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c do_pam_putenv(client->store.envvar, client->store.envval); #endif -@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->store.data = krb_context; @@ -459,43 +483,10 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c } int -diff --git a/gss-serv.c b/gss-serv.c -index 6cae720e..16e55cbc 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - } - - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } - - /* This allows GSSAPI methods to do things to the child's environment based -@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() { - char *envstr; - #endif - -- if (gssapi_client.store.filename == NULL && -- gssapi_client.store.envval == NULL && -- gssapi_client.store.envvar == NULL) -+ if (gssapi_client.store.envval == NULL) - return; - - ok = 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 +diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.c 2021-04-19 14:05:10.854744577 +0200 +@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -503,7 +494,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) +@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; @@ -512,7 +503,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -447,7 +450,8 @@ typedef enum { +@@ -506,7 +509,8 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -522,7 +513,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, -@@ -526,11 +530,13 @@ static struct { +@@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -536,7 +527,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -547,7 +538,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o) +@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -555,11 +546,10 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index db8362c6..4fa42d64 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -123,6 +123,8 @@ typedef struct { +diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h +--- openssh-8.6p1/servconf.h.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.h 2021-04-19 14:05:10.855744584 +0200 +@@ -140,6 +140,8 @@ typedef struct { * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -568,11 +558,10 @@ index db8362c6..4fa42d64 100644 int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/session.c b/session.c -index 85df6a27..480a5ead 100644 ---- a/session.c -+++ b/session.c -@@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:05:10.855744584 +0200 +@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s /* Allow any GSSAPI methods that we've used to alter * the child's environment as they see fit */ @@ -582,7 +571,7 @@ index 85df6a27..480a5ead 100644 #endif /* Set basic environment. */ -@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s } #endif #ifdef KRB5 @@ -591,33 +580,10 @@ index 85df6a27..480a5ead 100644 child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif -diff --git a/ssh-gss.h b/ssh-gss.h -index 6593e422..245178af 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -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 **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -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); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); -diff --git a/sshd.c b/sshd.c -index edbe815c..89514e8a 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2162,7 +2162,7 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:05:10.855744584 +0200 +@@ -2284,7 +2284,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -626,11 +592,10 @@ index edbe815c..89514e8a 100644 restore_uid(); } #endif -diff --git a/sshd_config.5 b/sshd_config.5 -index c0683d4a..2349f477 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache +diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-04-19 14:05:10.856744592 +0200 +@@ -939,6 +939,14 @@ Specifies whether to automatically destr file on logout. The default is .Cm yes . @@ -645,3 +610,24 @@ index c0683d4a..2349f477 100644 .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. +diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h +--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/ssh-gss.h 2021-04-19 14:05:10.855744584 +0200 +@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index d4c53db..519ee29 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,7 @@ -diff --git a/sshd.c b/sshd.c ---- a/sshd.c -+++ b/sshd.c -@@ -1701,6 +1701,10 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200 +@@ -1749,6 +1749,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, cfg, &includes, NULL); @@ -9,13 +9,13 @@ diff --git a/sshd.c b/sshd.c + 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 + #ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config +--- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200 ++++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200 +@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and ChallengeResponseAuthentication to 'no'. diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index a6c3bae..145eac0 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -179,10 +179,10 @@ diff -up openssh/misc.c.role-mls openssh/misc.c } return NULL; } -diff -up openssh/monitor.c.role-mls openssh/monitor.c ---- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200 -@@ -115,6 +115,9 @@ int mm_answer_sign(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 *); @@ -192,7 +192,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); -@@ -189,6 +192,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}, @@ -202,7 +202,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -796,6 +802,9 @@ mm_answer_pwnamallow(int sock, struct ss +@@ -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); @@ -212,7 +212,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb +@@ -877,6 +886,26 @@ key_base_type_match(const char *method, return found; } @@ -239,7 +239,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, { struct sshbuf *b; const u_char *p; @@ -248,7 +248,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c size_t len; u_char type; int r, fail = 0; -@@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i +@@ -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"); @@ -257,7 +257,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1286,7 +1317,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char { struct sshbuf *b; const u_char *p; @@ -266,11 +266,11 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c size_t len; int r, fail = 0; u_char type; -@@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data +@@ -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"); -+ if ((s = strchr(p, '/')) != NULL) ++ if ((s = strchr(cp, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 813b7ac..4baa024 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -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,14 +359,13 @@ or +diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 +--- openssh-8.6p1/ssh_config.5.crypto-policies 2021-04-19 15:18:32.071920379 +0200 ++++ openssh-8.6p1/ssh_config.5 2021-04-19 15:21:18.400179265 +0200 +@@ -368,15 +368,13 @@ or .Qq *.c.example.com domains. .It Cm CASignatureAlgorithms @@ -14,14 +14,15 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 by certificate authorities (CAs). -The default is: -.Bd -literal -offset indent --ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, --ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-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 .Xr ssh 1 will not accept host certificates signed using algorithms other than those specified. -@@ -424,20 +424,25 @@ If the option is set to +@@ -436,20 +434,25 @@ If the option is set to (the default), the check will not be executed. .It Cm Ciphers @@ -51,7 +52,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -453,13 +458,6 @@ aes256-gcm@openssh.com +@@ -465,13 +468,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .Ed .Pp @@ -65,7 +66,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 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 +@@ -826,6 +822,11 @@ command line will be passed untouched to The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -77,7 +78,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 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-, +@@ -838,10 +839,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp @@ -89,7 +90,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1149,29 +1150,25 @@ it may be zero or more of: +@@ -1169,29 +1168,25 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -128,7 +129,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .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. +@@ -1301,37 +1296,33 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -175,7 +176,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1394,37 +1387,25 @@ instead of continuing to execute and pas +@@ -1503,37 +1494,25 @@ instead of continuing to execute and pas The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -222,10 +223,10 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -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,14 +375,13 @@ If the argument is +diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.crypto-policies 2021-04-19 15:18:32.062920311 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-04-19 15:20:42.591908243 +0200 +@@ -373,15 +373,13 @@ If the argument is then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -238,14 +239,15 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 by certificate authorities (CAs). -The default is: -.Bd -literal -offset indent --ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, --ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-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 Certificates signed using other algorithms will not be accepted for public key or host-based authentication. .It Cm ChallengeResponseAuthentication -@@ -446,20 +446,25 @@ The default is +@@ -445,20 +443,25 @@ The default is indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -275,7 +277,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -486,13 +491,6 @@ aes256-gcm@openssh.com +@@ -485,13 +488,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp @@ -289,7 +291,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -681,21 +679,22 @@ For this to work +@@ -680,21 +676,22 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -322,7 +324,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased -@@ -793,26 +793,13 @@ is specified, the location of the socket +@@ -794,26 +791,13 @@ is specified, the location of the socket .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -354,7 +356,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -943,20 +931,25 @@ Specifies whether to look at .k5login fi +@@ -958,20 +942,25 @@ Specifies whether to look at .k5login fi The default is .Cm yes . .It Cm KexAlgorithms @@ -384,7 +386,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -988,15 +981,6 @@ ecdh-sha2-nistp521 +@@ -1003,15 +992,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El .Pp @@ -400,7 +402,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 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. +@@ -1097,21 +1077,26 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -431,7 +433,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1122,15 +1111,6 @@ umac-64-etm@openssh.com +@@ -1154,15 +1139,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -447,7 +449,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1480,37 +1460,25 @@ or equivalent.) +@@ -1541,37 +1517,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms diff --git a/openssh-8.0p1-keygen-strip-doseol.patch b/openssh-8.0p1-keygen-strip-doseol.patch new file mode 100644 index 0000000..3117a7a --- /dev/null +++ b/openssh-8.0p1-keygen-strip-doseol.patch @@ -0,0 +1,12 @@ +diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c +--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100 ++++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100 +@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw) + while (getline(&line, &linesize, f) != -1) { + lnum++; + cp = line; +- cp[strcspn(cp, "\n")] = '\0'; ++ cp[strcspn(cp, "\r\n")] = '\0'; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 748ab48..dc8a7d0 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,112 +1,7 @@ -commit ed3eaf7d68c083b6015ca3425b75932999dafaad -Author: Jakub Jelen -Date: Wed Apr 24 17:23:21 2019 +0200 - - PKCS#11 URI from Fedora - - * Print PKCS#11 URIs from ssh-keygen - * Accept PKCS#11 URIs in -i argument to ssh - * Allow PKCS#11 URI specification in ssh_config - * Fallback to p11-kit-proxy - * PKCS#11 URI support for ssh-add and ssh-agent - * internal representation is URI - * Allow to specify pin-value in URI to avoid interactive prompts - - Currently recognized and used parts of PKCS#11 URI: - * path (optional) - * token - * id - * manufacturer - * (library-manufacturer) - * query (optional) - * module-path - * pin-value - - Unit test for PKCS#11 URIs - - * test PKCS#11 URI parser, generator - * test percent_encodeer and decoder - - Regression tests for PKCS#11 URI support - - * soft-pkcs11.so from people.su.se/~lha/soft-pkcs11 - * Return correct CKR for unknown attributes - * Adjust and build it with regress tests (allowing agent-pkcs11 test) - * Test PKCS#11 URIs support with soft-pkcs11 - * Direct usage from commandline (URI, provider and combination) - * Usage from configuration files - * Usage in ssh-agent (add, sign, remove) - * Make sure it is built with correct paths - -diff --git a/Makefile.in b/Makefile.in -index e7549470..4511f82a 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ - ssh-ed25519-sk.o ssh-rsa.o dh.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -289,6 +289,8 @@ clean: regressclean - rm -f regress/unittests/match/test_match$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -322,6 +324,8 @@ distclean: regressclean - rm -f regress/unittests/match/test_match - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8 -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11 - (cd openbsd-compat && $(MAKE) distclean) - if test -d pkg ; then \ - rm -fr pkg ; \ -@@ -490,6 +494,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/kex - $(MKDIR_P) `pwd`/regress/unittests/match - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/sk-dummy - [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -617,6 +622,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ - # These all need to be compiled -fPIC, so they are treated differently. - SK_DUMMY_OBJS=\ - regress/misc/sk-dummy/sk-dummy.lo \ -@@ -655,6 +670,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ - regress/unittests/kex/test_kex$(EXEEXT) \ - regress/unittests/match/test_match$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - - tests: file-tests t-exec interop-tests unit - echo all tests passed -diff --git a/configure.ac b/configure.ac -index b689db4b..98d3ce4f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1911,12 +1911,14 @@ AC_LINK_IFELSE( +diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac +--- openssh-8.6p1/configure.ac.pkcs11-uri 2021-04-19 14:57:30.307370482 +0200 ++++ openssh-8.6p1/configure.ac 2021-04-19 14:57:30.315370543 +0200 +@@ -1974,12 +1974,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -121,7 +16,7 @@ index b689db4b..98d3ce4f 100644 fi ] ) -@@ -1945,6 +1947,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2008,6 +2010,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -162,7 +57,7 @@ index b689db4b..98d3ce4f 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5401,6 +5437,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5564,6 +5600,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -170,32 +65,72 @@ index b689db4b..98d3ce4f 100644 echo " U2F/FIDO support: $enable_sk" echo "" -diff --git a/regress/Makefile b/regress/Makefile -index 774c10d4..6bf3b627 100644 ---- a/regress/Makefile -+++ b/regress/Makefile -@@ -116,7 +116,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ - known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ - modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log remote_pid \ -- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ -+ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ -+ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ - rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ - scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ - sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -246,6 +247,7 @@ unit: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ -diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index fbbaea51..5d75d69f 100644 ---- a/regress/agent-pkcs11.sh -+++ b/regress/agent-pkcs11.sh +diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in +--- openssh-8.6p1/Makefile.in.pkcs11-uri 2021-04-19 14:57:30.261370134 +0200 ++++ openssh-8.6p1/Makefile.in 2021-04-19 15:14:38.916155695 +0200 +@@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -300,6 +300,8 @@ clean: regressclean + rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so +@@ -337,6 +339,8 @@ distclean: regressclean + rm -f regress/unittests/sshsig/test_sshsig + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + (cd openbsd-compat && $(MAKE) distclean) + if test -d pkg ; then \ + rm -fr pkg ; \ +@@ -511,6 +515,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/sshkey + $(MKDIR_P) `pwd`/regress/unittests/sshsig + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/sk-dummy + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -674,6 +679,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -709,6 +724,7 @@ regress-unit-binaries: regress-prep $(RE + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ + regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + + tests: file-tests t-exec interop-tests unit + echo all tests passed +diff -up openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/agent-pkcs11.sh +--- openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/agent-pkcs11.sh 2021-04-19 14:57:30.316370550 +0200 @@ -113,7 +113,7 @@ else done @@ -205,11 +140,34 @@ index fbbaea51..5d75d69f 100644 r=$? if [ $r -ne 0 ]; then fail "ssh-add -e failed: exit code $r" -diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh -new file mode 100644 -index 00000000..a91aee94 ---- /dev/null -+++ b/regress/pkcs11.sh +diff -up openssh-8.6p1/regress/Makefile.pkcs11-uri openssh-8.6p1/regress/Makefile +--- openssh-8.6p1/regress/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/Makefile 2021-04-19 15:15:44.411651410 +0200 +@@ -119,7 +119,8 @@ CLEANFILES= *.core actual agent-key.* au + known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ + modpipe netcat no_identity_config \ + pidfile putty.rsa2 ready regress.log remote_pid \ +- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ ++ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ ++ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ + rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ + sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ +@@ -249,8 +250,9 @@ unit: + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ +- $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ +- $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ ++ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ ++ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ + $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ + -d ${.CURDIR}/unittests/sshsig/testdata ; \ +diff -up openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/pkcs11.sh +--- openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri 2021-04-19 14:57:30.316370550 +0200 ++++ openssh-8.6p1/regress/pkcs11.sh 2021-04-19 14:57:30.316370550 +0200 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -560,10 +518,9 @@ index 00000000..a91aee94 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index 4e56e110..2690ebeb 100644 ---- a/regress/unittests/Makefile -+++ b/regress/unittests/Makefile +diff -up openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri openssh-8.6p1/regress/unittests/Makefile +--- openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/unittests/Makefile 2021-04-19 14:57:30.316370550 +0200 @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes @@ -572,11 +529,9 @@ index 4e56e110..2690ebeb 100644 +SUBDIR+=authopt misc sshsig pkcs11 .include -diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c -new file mode 100644 -index 00000000..b637cb13 ---- /dev/null -+++ b/regress/unittests/pkcs11/tests.c +diff -up openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.6p1/regress/unittests/pkcs11/tests.c +--- openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-04-19 14:57:30.317370558 +0200 ++++ openssh-8.6p1/regress/unittests/pkcs11/tests.c 2021-04-19 14:57:30.317370558 +0200 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat @@ -915,11 +870,10 @@ index 00000000..b637cb13 + test_parse_invalid(); + test_generate_valid(); +} -diff --git a/ssh-add.c b/ssh-add.c -index 8057eb1f..0c470e32 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -67,6 +67,7 @@ +diff -up openssh-8.6p1/ssh-add.c.pkcs11-uri openssh-8.6p1/ssh-add.c +--- openssh-8.6p1/ssh-add.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-add.c 2021-04-19 14:57:30.317370558 +0200 +@@ -68,6 +68,7 @@ #include "digest.h" #include "ssh-sk.h" #include "sk-api.h" @@ -927,7 +881,7 @@ index 8057eb1f..0c470e32 100644 /* argv0 */ extern char *__progname; -@@ -193,6 +194,32 @@ delete_all(int agent_fd, int qflag) +@@ -229,6 +230,32 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -960,7 +914,7 @@ index 8057eb1f..0c470e32 100644 static int add_file(int agent_fd, const char *filename, int key_only, int qflag, const char *skprovider) -@@ -402,12 +429,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, +@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen } static int @@ -975,7 +929,7 @@ index 8057eb1f..0c470e32 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -591,6 +617,13 @@ static int +@@ -630,6 +656,13 @@ static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, const char *skprovider) { @@ -989,7 +943,7 @@ index 8057eb1f..0c470e32 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -@@ -773,7 +806,7 @@ main(int argc, char **argv) +@@ -813,7 +846,7 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, @@ -998,11 +952,10 @@ index 8057eb1f..0c470e32 100644 ret = 1; goto done; } -diff --git a/ssh-agent.c b/ssh-agent.c -index 7eb6f0dc..27d8e4af 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -641,10 +641,72 @@ no_identities(SocketEntry *e) +diff -up openssh-8.6p1/ssh-agent.c.pkcs11-uri openssh-8.6p1/ssh-agent.c +--- openssh-8.6p1/ssh-agent.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-agent.c 2021-04-19 14:57:30.317370558 +0200 +@@ -847,10 +847,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1076,7 +1029,7 @@ index 7eb6f0dc..27d8e4af 100644 char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) +@@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e error_f("failed to parse constraints"); goto send; } @@ -1118,7 +1071,7 @@ index 7eb6f0dc..27d8e4af 100644 } id->death = death; id->confirm = confirm; -@@ -721,6 +778,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -1126,7 +1079,7 @@ index 7eb6f0dc..27d8e4af 100644 free(keys); free(comments); send_status(e, success); -@@ -729,7 +787,7 @@ send: +@@ -918,7 +976,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1135,7 +1088,7 @@ index 7eb6f0dc..27d8e4af 100644 int r, success = 0; Identity *id, *nxt; -@@ -740,30 +798,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -930,30 +988,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1172,11 +1125,185 @@ index 7eb6f0dc..27d8e4af 100644 send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 0d6ed1ff..182f4f2b 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -855,8 +855,11 @@ do_download(struct passwd *pw) +diff -up openssh-8.6p1/ssh_config.5.pkcs11-uri openssh-8.6p1/ssh_config.5 +--- openssh-8.6p1/ssh_config.5.pkcs11-uri 2021-04-19 14:57:30.269370194 +0200 ++++ openssh-8.6p1/ssh_config.5 2021-04-19 14:57:30.321370588 +0200 +@@ -1063,6 +1063,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.pkcs11-uri 2021-04-19 14:57:30.269370194 +0200 ++++ openssh-8.6p1/ssh.c 2021-04-19 15:17:05.804267447 +0200 +@@ -843,6 +843,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1695,6 +1703,7 @@ main(int ac, char **av) + #ifdef ENABLE_PKCS11 + (void)pkcs11_del_provider(options.pkcs11_provider); + #endif ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, cinfo); +@@ -2211,6 +2220,45 @@ ssh_session2(struct ssh *ssh, const stru + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2225,11 +2273,6 @@ load_public_identity_files(const struct + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys = NULL; +- char **comments = NULL; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2242,33 +2285,46 @@ load_public_identity_files(const struct + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys, &comments)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- free(comments[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = comments[i]; /* transferred */ +- n_ids++; +- } +- free(keys); +- free(comments); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +diff -up openssh-8.6p1/ssh-keygen.c.pkcs11-uri openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-04-19 14:57:30.318370565 +0200 +@@ -860,8 +860,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1190,11 +1317,10 @@ index 0d6ed1ff..182f4f2b 100644 } free(comments[i]); sshkey_free(keys[i]); -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index 8a0ffef5..ead8a562 100644 ---- a/ssh-pkcs11-client.c -+++ b/ssh-pkcs11-client.c -@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +diff -up openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-client.c +--- openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11-client.c 2021-04-19 14:57:30.318370565 +0200 +@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi u_int nkeys, i; struct sshbuf *msg; @@ -1203,7 +1329,7 @@ index 8a0ffef5..ead8a562 100644 if (fd < 0 && pkcs11_start_helper() < 0) return (-1); -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1211,11 +1337,1258 @@ index 8a0ffef5..ead8a562 100644 for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c -new file mode 100644 -index 00000000..e1a7b4e0 ---- /dev/null -+++ b/ssh-pkcs11-uri.c +diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c +--- openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11.c 2021-04-19 14:57:30.320370580 +0200 +@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -65,6 +65,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -75,6 +82,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug("pkcs11_provider_finalize: %p refcount %d valid %d", +- p, p->refcount, p->valid); +- if (!p->valid) ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug_f("%p refcount %d", m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error_f("%p still valid", m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared libarary, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -135,13 +178,11 @@ pkcs11_provider_finalize(struct pkcs11_p + static void + pkcs11_provider_unref(struct pkcs11_provider *p) + { +- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); ++ debug_f("%p refcount %d", p, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error("pkcs11_provider_unref: %p still valid", p); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +200,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) + { ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ if (provider_id == NULL) ++ return 0; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) ++{ + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3_f("called with provider %s", provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +283,55 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: ++ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ break; ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: ++ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ break; ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); ++ } ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +345,7 @@ pkcs11_k11_free(void *parent, void *ptr, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +360,8 @@ pkcs11_find(struct pkcs11_provider *p, C + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -262,12 +400,12 @@ pkcs11_login_slot(struct pkcs11_provider + else { + snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug_f("no pin specified"); + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -297,13 +435,14 @@ pkcs11_login_slot(struct pkcs11_provider + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -319,13 +458,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + attr.type = type; + attr.pValue = &flag; +@@ -356,13 +496,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C + int always_auth = 0; + int did_login = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (pkcs11_login(k11, CKU_USER) < 0) { +@@ -439,8 +580,8 @@ pkcs11_rsa_private_encrypt(int flen, con + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + tlen = RSA_size(rsa); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ +@@ -484,7 +625,7 @@ pkcs11_rsa_start_wrapper(void) + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + +@@ -502,6 +643,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + RSA_set_method(rsa, rsa_method); + RSA_set_ex_data(rsa, rsa_idx, k11); + return (0); +@@ -532,8 +679,8 @@ ecdsa_do_sign(const unsigned char *dgst, + return (NULL); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + siglen = ECDSA_size(ec); + sig = xmalloc(siglen); +@@ -598,7 +745,7 @@ pkcs11_ecdsa_start_wrapper(void) + + static int + pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) + { + struct pkcs11_key *k11; + +@@ -614,6 +761,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + EC_KEY_set_method(ec, ec_key_method); + EC_KEY_set_ex_data(ec, ec_key_idx, k11); + +@@ -650,8 +803,8 @@ pkcs11_open_session(struct pkcs11_provid + CK_SESSION_HANDLE session; + int login_required, ret; + +- f = p->function_list; +- si = &p->slotinfo[slotidx]; ++ f = p->module->function_list; ++ si = &p->module->slotinfo[slotidx]; + + login_required = si->token.flags & CKF_LOGIN_REQUIRED; + +@@ -661,9 +814,9 @@ pkcs11_open_session(struct pkcs11_provid + error("pin required"); + return (-SSH_PKCS11_ERR_PIN_REQUIRED); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -699,7 +852,8 @@ static struct sshkey * + pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -713,14 +867,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; ++ key_attr[3].type = CKA_EC_PARAMS; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -731,19 +886,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, public point and curve parameters of EC key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -755,8 +910,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- attrp = key_attr[2].pValue; +- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); ++ attrp = key_attr[3].pValue; ++ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); + if (group == NULL) { + ossl_error("d2i_ECPKParameters failed"); + goto fail; +@@ -767,13 +922,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- if (key_attr[1].ulValueLen <= 2) { ++ if (key_attr[2].ulValueLen <= 2) { + error("CKA_EC_POINT too small"); + goto fail; + } + +- attrp = key_attr[1].pValue; +- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); ++ attrp = key_attr[2].pValue; ++ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); + if (octet == NULL) { + ossl_error("d2i_ASN1_OCTET_STRING failed"); + goto fail; +@@ -790,7 +945,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -806,7 +961,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + ec = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -823,7 +978,8 @@ static struct sshkey * + pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -834,14 +990,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_MODULUS; +- key_attr[2].type = CKA_PUBLIC_EXPONENT; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_MODULUS; ++ key_attr[3].type = CKA_PUBLIC_EXPONENT; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -852,19 +1009,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, modulus and public exponent of RSA key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -876,8 +1033,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + goto fail; + } + +- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) { + error("BN_bin2bn failed"); + goto fail; +@@ -886,7 +1043,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + fatal_f("set key"); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -901,7 +1058,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + rsa = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -912,7 +1069,8 @@ static int + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) + { +- CK_ATTRIBUTE cert_attr[3]; ++ CK_ATTRIBUTE cert_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -936,14 +1094,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + + memset(&cert_attr, 0, sizeof(cert_attr)); + cert_attr[0].type = CKA_ID; +- cert_attr[1].type = CKA_SUBJECT; +- cert_attr[2].type = CKA_VALUE; ++ cert_attr[1].type = CKA_LABEL; ++ cert_attr[2].type = CKA_SUBJECT; ++ cert_attr[3].type = CKA_VALUE; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return -1; +@@ -955,18 +1114,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + * XXX assumes CKA_ID is always first. + */ + if (cert_attr[1].ulValueLen == 0 || +- cert_attr[2].ulValueLen == 0) { ++ cert_attr[2].ulValueLen == 0 || ++ cert_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return -1; + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (cert_attr[i].ulValueLen > 0) + cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + + /* retrieve ID, subject and value of certificate */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto out; +@@ -980,8 +1140,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + subject = xstrdup("invalid subject"); + X509_NAME_free(x509_name); + +- cp = cert_attr[2].pValue; +- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { ++ cp = cert_attr[3].pValue; ++ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { + error("d2i_x509 failed"); + goto out; + } +@@ -1001,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1031,7 +1191,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1051,7 +1211,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + out: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1102,11 +1262,12 @@ note_key(struct pkcs11_provider *p, CK_U + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1123,10 +1284,23 @@ pkcs11_fetch_certs(struct pkcs11_provide + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1207,11 +1381,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[2]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1227,10 +1402,23 @@ pkcs11_fetch_keys(struct pkcs11_provider + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1499,16 +1687,10 @@ pkcs11_ecdsa_generate_private_key(struct + } + #endif /* WITH_PKCS11_KEYGEN */ + +-/* +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. +- */ + static int +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) + { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; + struct pkcs11_provider *p = NULL; + void *handle = NULL; +@@ -1517,164 +1699,298 @@ pkcs11_register_provider(char *provider_ + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_module *m = NULL; + +- if (providerp == NULL) ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error_f("No module path provided"); + goto fail; +- *providerp = NULL; ++#endif ++ } else { ++ provider_module = strdup(uri->module_path); ++ } + +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); + +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug_f("provider already registered: %s", provider_id); +- goto fail; ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug_f("provider module already initialized: %s", provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-library */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ ++ p->module->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { +- debug_f("provider %s returned no slots", provider_id); ++ if (m->nslots == 0) { ++ debug_f("provider %s returned no slots", provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->valid = 1; ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (u_long)i, rv); +- continue; +- } +- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "failed: %lu", provider_module, (u_long)i, rv); ++ token->flags = 0; + continue; + } + rmspace(token->label, sizeof(token->label)); + rmspace(token->manufacturerID, sizeof(token->manufacturerID)); + rmspace(token->model, sizeof(token->model)); + rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); ++ } ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return ret; ++} ++ ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) ++{ ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; ++ ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; ++ ++ if (keyp != NULL) ++ *keyp = NULL; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " ++ "provider %s slot %lu", provider_uri, (u_long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->manufacturerID, (unsigned long)i); ++ continue; ++ } + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); + /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) ++ * open session if not yet openend, login with pin and ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3_f("Trying to login as there were no keys found"); ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ uri->object = label; + } + } ++ pin = NULL; /* Will be cleaned up with URI */ + + /* now owned by caller */ + *providerp = p; + +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- ++ free(provider_uri); + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ struct pkcs11_uri *uri = NULL; ++ int r; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); ++ pkcs11_uri_cleanup(uri); ++ ++ return r; ++} ++ + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp) + { + struct pkcs11_provider *p = NULL; + int nkeys; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug_f("called, provider_uri = %s", provider_uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1683,7 +1999,37 @@ pkcs11_add_provider(char *provider_id, c + pkcs11_provider_unref(p); + } + if (nkeys == 0) +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); ++ ++ free(provider_uri); ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ ++int ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) ++{ ++ struct pkcs11_uri *uri; ++ int nkeys; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +diff -up openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11.h +--- openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11.h 2021-04-19 14:57:30.320370580 +0200 +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff -up openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.c +--- openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-04-19 14:57:30.318370565 +0200 ++++ openssh-8.6p1/ssh-pkcs11-uri.c 2021-04-19 14:57:30.318370565 +0200 @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1636,11 +3009,9 @@ index 00000000..e1a7b4e0 +} + +#endif /* ENABLE_PKCS11 */ -diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h -new file mode 100644 -index 00000000..942a5a5a ---- /dev/null -+++ b/ssh-pkcs11-uri.h +diff -up openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.h +--- openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-04-19 14:57:30.318370565 +0200 ++++ openssh-8.6p1/ssh-pkcs11-uri.h 2021-04-19 14:57:30.318370565 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1684,1430 +3055,3 @@ index 00000000..942a5a5a +struct pkcs11_uri *pkcs11_uri_init(); +char *pkcs11_uri_get(struct pkcs11_uri *uri); + -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index a302c79c..879fe917 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -54,8 +54,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -64,6 +64,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -74,6 +81,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +114,61 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); -- if (!p->valid) -+ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug_f("%p refcount %d", m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error_f("%p still valid", m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared libarary, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -135,13 +180,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) - static void - pkcs11_provider_unref(struct pkcs11_provider *p) - { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug_f("%p refcount %d", p, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); - free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); - free(p); - } - } -@@ -159,6 +202,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +230,52 @@ pkcs11_provider_lookup(char *provider_id) - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) -+{ -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) - { - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3_f("called with provider %s", provider_uri); -+ -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - static RSA_METHOD *rsa_method; -@@ -195,6 +285,55 @@ static EC_KEY_METHOD *ec_key_method; - static int ec_key_idx = 0; - #endif - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ switch (key->type) { -+ case KEY_RSA: -+ k11 = RSA_get_ex_data(key->rsa, rsa_idx); -+ break; -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: -+ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); -+ break; -+#endif -+ default: -+ error("Unknown key type %d", key->type); -+ return -1; -+ } -+ if (k11 == NULL) { -+ error("Failed to get ex_data for key type %d", key->type); -+ return (-1); -+ } -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - /* release a wrapped object */ - static void - pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); -+ free(k11->label); - free(k11); - } - -@@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -262,12 +402,12 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - else { - snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", - si->token.label); -- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { -+ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug_f("no pin specified"); - return (-1); /* bail out */ - } - } -- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, -+ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, - (pin != NULL) ? strlen(pin) : 0); - if (pin != NULL) - freezero(pin, strlen(pin)); -@@ -282,13 +422,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - static int - pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) - { -- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { -+ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || -+ k11->provider->module == NULL || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - - return pkcs11_login_slot(k11->provider, -- &k11->provider->slotinfo[k11->slotidx], type); -+ &k11->provider->module->slotinfo[k11->slotidx], type); - } - - -@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, - - *val = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - attr.type = type; - attr.pValue = &flag; -@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) - int always_auth = 0; - int did_login = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -424,8 +567,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -469,7 +612,7 @@ pkcs11_rsa_start_wrapper(void) - /* redirect private key operations for rsa key to pkcs11 token */ - static int - pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - -@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } - -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - RSA_set_method(rsa, rsa_method); - RSA_set_ex_data(rsa, rsa_idx, k11); - return (0); -@@ -517,8 +666,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - return (NULL); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - siglen = ECDSA_size(ec); - sig = xmalloc(siglen); -@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) - - static int - pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) - { - struct pkcs11_key *k11; - -@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - EC_KEY_set_method(ec, ec_key_method); - EC_KEY_set_ex_data(ec, ec_key_idx, k11); - -@@ -635,8 +790,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - CK_SESSION_HANDLE session; - int login_required, ret; - -- f = p->function_list; -- si = &p->slotinfo[slotidx]; -+ f = p->module->function_list; -+ si = &p->module->slotinfo[slotidx]; - - login_required = si->token.flags & CKF_LOGIN_REQUIRED; - -@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - error("pin required"); - return (-SSH_PKCS11_ERR_PIN_REQUIRED); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -684,7 +839,8 @@ static struct sshkey * - pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -698,14 +854,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_EC_POINT; -- key_attr[2].type = CKA_EC_PARAMS; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_EC_POINT; -+ key_attr[3].type = CKA_EC_PARAMS; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -717,19 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, public point and curve parameters of EC key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -740,8 +898,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- attrp = key_attr[2].pValue; -- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); -+ attrp = key_attr[3].pValue; -+ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); - if (group == NULL) { - ossl_error("d2i_ECPKParameters failed"); - goto fail; -@@ -752,13 +910,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- if (key_attr[1].ulValueLen <= 2) { -+ if (key_attr[2].ulValueLen <= 2) { - error("CKA_EC_POINT too small"); - goto fail; - } - -- attrp = key_attr[1].pValue; -- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); -+ attrp = key_attr[2].pValue; -+ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); - if (octet == NULL) { - ossl_error("d2i_ASN1_OCTET_STRING failed"); - goto fail; -@@ -775,7 +933,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - ec = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - if (ec) - EC_KEY_free(ec); -@@ -808,7 +966,8 @@ static struct sshkey * - pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -819,14 +978,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_MODULUS; -- key_attr[2].type = CKA_PUBLIC_EXPONENT; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_MODULUS; -+ key_attr[3].type = CKA_PUBLIC_EXPONENT; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -838,19 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, modulus and public exponent of RSA key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -861,8 +1022,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); -- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); - if (rsa_n == NULL || rsa_e == NULL) { - error("BN_bin2bn failed"); - goto fail; -@@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - fatal_f("set key"); - rsa_n = rsa_e = NULL; /* transferred */ - -- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - rsa = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - RSA_free(rsa); - -@@ -897,7 +1058,8 @@ static int - pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) - { -- CK_ATTRIBUTE cert_attr[3]; -+ CK_ATTRIBUTE cert_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -921,14 +1083,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&cert_attr, 0, sizeof(cert_attr)); - cert_attr[0].type = CKA_ID; -- cert_attr[1].type = CKA_SUBJECT; -- cert_attr[2].type = CKA_VALUE; -+ cert_attr[1].type = CKA_LABEL; -+ cert_attr[2].type = CKA_SUBJECT; -+ cert_attr[3].type = CKA_VALUE; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return -1; -@@ -940,18 +1103,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * XXX assumes CKA_ID is always first. - */ - if (cert_attr[1].ulValueLen == 0 || -- cert_attr[2].ulValueLen == 0) { -+ cert_attr[2].ulValueLen == 0 || -+ cert_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return -1; - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (cert_attr[i].ulValueLen > 0) - cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); - - /* retrieve ID, subject and value of certificate */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto out; -@@ -965,8 +1129,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - subject = xstrdup("invalid subject"); - X509_NAME_free(x509_name); - -- cp = cert_attr[2].pValue; -- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { -+ cp = cert_attr[3].pValue; -+ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { - error("d2i_x509 failed"); - goto out; - } -@@ -986,7 +1150,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - -- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1016,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1036,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - out: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(cert_attr[i].pValue); - X509_free(x509); - RSA_free(rsa); -@@ -1071,11 +1235,12 @@ have_rsa_key(const RSA *rsa) - */ - static int - pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1092,10 +1257,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1175,11 +1353,12 @@ fail: - */ - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[2]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1195,10 +1374,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1466,16 +1658,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, - } - #endif /* WITH_PKCS11_KEYGEN */ - --/* -- * register a new provider, fails if provider already exists. if -- * keyp is provided, fetch keys. -- */ - static int --pkcs11_register_provider(char *provider_id, char *pin, -- struct sshkey ***keyp, char ***labelsp, -- struct pkcs11_provider **providerp, CK_ULONG user) -+pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) - { -- int nkeys, need_finalize = 0; -+ int need_finalize = 0; - int ret = -1; - struct pkcs11_provider *p = NULL; - void *handle = NULL; -@@ -1484,164 +1670,298 @@ pkcs11_register_provider(char *provider_id, char *pin, - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -- -- if (providerp == NULL) -+ char *provider_module = NULL; -+ struct pkcs11_module *m = NULL; -+ -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error_f("No module path provided"); - goto fail; -- *providerp = NULL; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -+#endif -+ } else { -+ provider_module = strdup(uri->module_path); -+ } - -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug_f("provider already registered: %s", provider_id); -- goto fail; -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); -+ -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug_f("provider module already initialized: %s", provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } -+ - /* open shared pkcs11-library */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } -- p = xcalloc(1, sizeof(*p)); -- p->name = xstrdup(provider_id); -- p->handle = handle; -+ -+ p->module->handle = handle; - /* setup the pkcs11 callbacks */ - if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); -+ goto fail; -+ } -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -+ if (m->nslots == 0) { -- debug_f("provider %s returned no slots", provider_id); -+ debug_f("provider %s returned no slots", provider_module); - ret = -SSH_PKCS11_ERR_NO_SLOTS; - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->valid = 1; -+ for (i = 0; i < m->nslots; i++) { -+ token = &m->slotinfo[i].token; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (u_long)i, rv); -+ "failed: %lu", provider_module, (u_long)i, rv); -+ token->flags = 0; - continue; - } -+ rmspace(token->label, sizeof(token->label)); -+ rmspace(token->manufacturerID, sizeof(token->manufacturerID)); -+ rmspace(token->model, sizeof(token->model)); -+ rmspace(token->serialNumber, sizeof(token->serialNumber)); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ if (m) { -+ free(m->slotlist); -+ free(m); -+ } -+ if (p) { -+ free(p->name); -+ free(p); -+ } -+ if (handle) -+ dlclose(handle); -+ return ret; -+} -+ -+/* -+ * register a new provider, fails if provider already exists. if -+ * keyp is provided, fetch keys. -+ */ -+static int -+pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, -+ CK_ULONG user) -+{ -+ int nkeys; -+ int ret = -1; -+ struct pkcs11_provider *p = NULL; -+ CK_ULONG i; -+ CK_TOKEN_INFO *token; -+ char *provider_uri = NULL; -+ -+ if (providerp == NULL) -+ goto fail; -+ *providerp = NULL; -+ -+ if (keyp != NULL) -+ *keyp = NULL; -+ -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; -+ } -+ -+ provider_uri = pkcs11_uri_get(uri); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; -+ } -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; - if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { - debug2_f("ignoring uninitialised token in " -- "provider %s slot %lu", provider_id, (u_long)i); -+ "provider %s slot %lu", provider_uri, (u_long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2_f("ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", token->manufacturerID, (unsigned long)i); - continue; - } -- rmspace(token->label, sizeof(token->label)); -- rmspace(token->manufacturerID, sizeof(token->manufacturerID)); -- rmspace(token->model, sizeof(token->model)); -- rmspace(token->serialNumber, sizeof(token->serialNumber)); - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); - /* -- * open session, login with pin and retrieve public -- * keys (if keyp is provided) -+ * open session if not yet openend, login with pin and -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ if ((p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ - keyp == NULL) - continue; -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -- if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && - pkcs11_interactive) { - /* - * Some tokens require login before they will - * expose keys. - */ -- if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3_f("Trying to login as there were no keys found"); -+ if (pkcs11_login_slot(p, &p->module->slotinfo[i], - CKU_USER) < 0) { - error("login failed"); - continue; - } -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ } -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%s) ", -+ uri->object); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ uri->object = label; - } - } -+ pin = NULL; /* Will be cleaned up with URI */ - - /* now owned by caller */ - *providerp = p; - -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -- -+ free(provider_uri); - return (nkeys); - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); - if (ret > 0) - ret = -1; - return (ret); - } - --/* -- * register a new provider and get number of keys hold by the token, -- * fails if provider already exists -- */ -+static int -+pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) -+{ -+ struct pkcs11_uri *uri = NULL; -+ int r; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); -+ -+ return r; -+} -+ - int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, -- char ***labelsp) -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp) - { - struct pkcs11_provider *p = NULL; - int nkeys; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug_f("called, provider_uri = %s", provider_uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, -- &p, CKU_USER); -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); - - /* no keys found or some other error, de-register provider */ - if (nkeys <= 0 && p != NULL) { -@@ -1652,7 +1974,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, - pkcs11_provider_unref(p); - } - if (nkeys == 0) -- debug_f("provider %s returned no keys", provider_id); -+ debug_f("provider %s returned no keys", provider_uri); -+ -+ free(provider_uri); -+ return nkeys; -+} -+ -+/* -+ * register a new provider and get number of keys hold by the token, -+ * fails if provider already exists -+ */ -+int -+pkcs11_add_provider(char *provider_id, char *pin, -+ struct sshkey ***keyp, char ***labelsp) -+{ -+ struct pkcs11_uri *uri; -+ int nkeys; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); -+ pkcs11_uri_cleanup(uri); - - return (nkeys); - } -diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index 81f1d7c5..feaf74de 100644 ---- a/ssh-pkcs11.h -+++ b/ssh-pkcs11.h -@@ -22,10 +22,14 @@ - #define SSH_PKCS11_ERR_PIN_REQUIRED 4 - #define SSH_PKCS11_ERR_PIN_LOCKED 5 - -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - #ifdef WITH_PKCS11_KEYGEN - struct sshkey * - pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff --git a/ssh.c b/ssh.c -index 15aee569..976844cb 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -795,6 +795,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) == -1) - fprintf(stderr, "Warning: Identity file %s " -@@ -1603,6 +1611,7 @@ main(int ac, char **av) - free(options.certificate_files[i]); - options.certificate_files[i] = NULL; - } -+ pkcs11_terminate(); - - skip_connect: - exit_status = ssh_session2(ssh, cinfo); -@@ -2076,6 +2085,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2090,11 +2138,6 @@ load_public_identity_files(struct passwd *pw) - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys = NULL; -- char **comments = NULL; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2107,33 +2150,46 @@ load_public_identity_files(struct passwd *pw) - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys, &comments)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- free(comments[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = comments[i]; /* transferred */ -- n_ids++; -- } -- free(keys); -- free(comments); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); -+ -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_dollar_expand(cp, cinfo); - free(cp); - check_load(sshkey_load_public(filename, &public, NULL), -diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..4b2763bd 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -986,6 +986,21 @@ may also be used in conjunction with - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query arguments -+.Cm module-path -+and -+.Cm pin-value -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. diff --git a/openssh-8.0p1-preserve-pam-errors.patch b/openssh-8.0p1-preserve-pam-errors.patch new file mode 100644 index 0000000..dbdbe93 --- /dev/null +++ b/openssh-8.0p1-preserve-pam-errors.patch @@ -0,0 +1,44 @@ +diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c +--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200 ++++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200 +@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp) + goto auth_fail; + + if (!do_pam_account()) { +- 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) { +@@ -568,8 +572,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 +@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha + plen++; + free(msg); + break; ++ case PAM_USER_UNKNOWN: ++ case PAM_PERM_DENIED: + case PAM_ACCT_EXPIRED: ++ sshpam_account_status = 0; ++ /* FALLTHROUGH */ + case PAM_MAXTRIES: +- if (type == PAM_ACCT_EXPIRED) +- sshpam_account_status = 0; + if (type == PAM_MAXTRIES) + sshpam_set_maxtries_reached(1); + /* FALLTHROUGH */ diff --git a/openssh-8.0p1-restore-nonblock.patch b/openssh-8.0p1-restore-nonblock.patch new file mode 100644 index 0000000..9067d22 --- /dev/null +++ b/openssh-8.0p1-restore-nonblock.patch @@ -0,0 +1,241 @@ +diff -up openssh-8.6p1/channels.c.restore-nonblock openssh-8.6p1/channels.c +--- openssh-8.6p1/channels.c.restore-nonblock 2021-05-10 10:55:46.981156096 +0200 ++++ openssh-8.6p1/channels.c 2021-05-10 11:05:14.674641053 +0200 +@@ -298,32 +298,38 @@ channel_lookup(struct ssh *ssh, int id) + } + + /* +- * Register filedescriptors for a channel, used when allocating a channel or +- * when the channel consumer/producer is ready, e.g. shell exec'd ++ * Register a filedescriptor. + */ + static void +-channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, +- int extusage, int nonblock, int is_tty) ++channel_register_fd(struct ssh *ssh, int fd, int nonblock) + { + struct ssh_channels *sc = ssh->chanctxt; + + /* Update the maximum file descriptor value. */ +- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd); +- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, wfd); +- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, efd); +- +- if (rfd != -1) +- fcntl(rfd, F_SETFD, FD_CLOEXEC); +- if (wfd != -1 && wfd != rfd) +- fcntl(wfd, F_SETFD, FD_CLOEXEC); +- if (efd != -1 && efd != rfd && efd != wfd) +- fcntl(efd, F_SETFD, FD_CLOEXEC); ++ sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, fd); ++ ++ if (fd != -1) ++ fcntl(fd, F_SETFD, FD_CLOEXEC); + ++ /* enable nonblocking mode */ ++ if (nonblock && fd != -1 && !isatty(fd)) ++ set_nonblock(fd); ++} ++ ++/* ++ * Register filedescriptors for a channel, used when allocating a channel or ++ * when the channel consumer/producer is ready, e.g. shell exec'd ++ */ ++static void ++channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, ++ int extusage, int nonblock, int is_tty) ++{ + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; ++ c->nonblock = 0; + + if ((c->isatty = is_tty) != 0) + debug2("channel %d: rfd %d isatty", c->self, c->rfd); +@@ -332,14 +338,20 @@ channel_register_fds(struct ssh *ssh, Ch + c->wfd_isatty = is_tty || isatty(c->wfd); + #endif + +- /* enable nonblocking mode */ +- if (nonblock) { +- if (rfd != -1) +- set_nonblock(rfd); +- if (wfd != -1) +- set_nonblock(wfd); +- if (efd != -1) +- set_nonblock(efd); ++ if (rfd != -1) { ++ if ((fcntl(rfd, F_GETFL) & O_NONBLOCK) == 0) ++ c->nonblock |= NEED_RESTORE_STDIN_NONBLOCK; ++ channel_register_fd(ssh, rfd, nonblock); ++ } ++ if (wfd != -1 && wfd != rfd) { ++ if ((fcntl(wfd, F_GETFL) & O_NONBLOCK) == 0) ++ c->nonblock |= NEED_RESTORE_STDOUT_NONBLOCK; ++ channel_register_fd(ssh, wfd, nonblock); ++ } ++ if (efd != -1 && efd != rfd && efd != wfd) { ++ if ((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0) ++ c->nonblock |= NEED_RESTORE_STDERR_NONBLOCK; ++ channel_register_fd(ssh, efd, nonblock); + } + } + +@@ -422,11 +434,15 @@ channel_find_maxfd(struct ssh_channels * + } + + int +-channel_close_fd(struct ssh *ssh, int *fdp) ++channel_close_fd(struct ssh *ssh, int *fdp, int nonblock) + { + struct ssh_channels *sc = ssh->chanctxt; + int ret = 0, fd = *fdp; + ++ /* As the fd is duped, restoring the block mode ++ * affects the original fd */ ++ if (nonblock && fd != -1 && !isatty(fd)) ++ unset_nonblock(fd); + if (fd != -1) { + ret = close(fd); + *fdp = -1; +@@ -442,13 +458,13 @@ channel_close_fds(struct ssh *ssh, Chann + { + int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; + +- channel_close_fd(ssh, &c->sock); ++ channel_close_fd(ssh, &c->sock, 0); + if (rfd != sock) +- channel_close_fd(ssh, &c->rfd); ++ channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK); + if (wfd != sock && wfd != rfd) +- channel_close_fd(ssh, &c->wfd); ++ channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK); + if (efd != sock && efd != rfd && efd != wfd) +- channel_close_fd(ssh, &c->efd); ++ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); + } + + static void +@@ -702,7 +718,7 @@ channel_stop_listening(struct ssh *ssh) + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_UNIX_LISTENER: + case SSH_CHANNEL_RUNIX_LISTENER: +- channel_close_fd(ssh, &c->sock); ++ channel_close_fd(ssh, &c->sock, 0); + channel_free(ssh, c); + break; + } +@@ -1649,7 +1665,7 @@ channel_post_x11_listener(struct ssh *ss + if (c->single_connection) { + oerrno = errno; + debug2("single_connection: closing X11 listener."); +- channel_close_fd(ssh, &c->sock); ++ channel_close_fd(ssh, &c->sock, 0); + chan_mark_dead(ssh, c); + errno = oerrno; + } +@@ -2058,7 +2074,7 @@ channel_handle_efd_write(struct ssh *ssh + return 1; + if (len <= 0) { + debug2("channel %d: closing write-efd %d", c->self, c->efd); +- channel_close_fd(ssh, &c->efd); ++ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); + } else { + if ((r = sshbuf_consume(c->extended, len)) != 0) + fatal_fr(r, "channel %i: consume", c->self); +@@ -2087,7 +2103,7 @@ channel_handle_efd_read(struct ssh *ssh, + return 1; + if (len <= 0) { + debug2("channel %d: closing read-efd %d", c->self, c->efd); +- channel_close_fd(ssh, &c->efd); ++ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); + } else if (c->extended_usage == CHAN_EXTENDED_IGNORE) + debug3("channel %d: discard efd", c->self); + else if ((r = sshbuf_put(c->extended, buf, len)) != 0) +diff -up openssh-8.6p1/channels.h.restore-nonblock openssh-8.6p1/channels.h +--- openssh-8.6p1/channels.h.restore-nonblock 2021-05-10 10:55:46.942155788 +0200 ++++ openssh-8.6p1/channels.h 2021-05-10 11:01:41.123953937 +0200 +@@ -188,8 +188,15 @@ struct Channel { + void *mux_ctx; + int mux_pause; + int mux_downstream_id; ++ ++ /* whether non-blocking is set to descriptors */ ++ int nonblock; + }; + ++#define NEED_RESTORE_STDIN_NONBLOCK 1 ++#define NEED_RESTORE_STDOUT_NONBLOCK 2 ++#define NEED_RESTORE_STDERR_NONBLOCK 4 ++ + #define CHAN_EXTENDED_IGNORE 0 + #define CHAN_EXTENDED_READ 1 + #define CHAN_EXTENDED_WRITE 2 +@@ -266,7 +273,7 @@ void channel_register_filter(struct ssh + void channel_register_status_confirm(struct ssh *, int, + channel_confirm_cb *, channel_confirm_abandon_cb *, void *); + void channel_cancel_cleanup(struct ssh *, int); +-int channel_close_fd(struct ssh *, int *); ++int channel_close_fd(struct ssh *, int *, int); + void channel_send_window_changes(struct ssh *); + + /* mux proxy support */ +diff -up openssh-8.6p1/nchan.c.restore-nonblock openssh-8.6p1/nchan.c +--- openssh-8.6p1/nchan.c.restore-nonblock 2021-05-10 10:55:46.990156168 +0200 ++++ openssh-8.6p1/nchan.c 2021-05-10 11:03:46.679945863 +0200 +@@ -384,7 +384,7 @@ chan_shutdown_write(struct ssh *ssh, Cha + c->istate, c->ostate, strerror(errno)); + } + } else { +- if (channel_close_fd(ssh, &c->wfd) < 0) { ++ if (channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK) < 0) { + logit_f("channel %d: close() failed for " + "fd %d [i%d o%d]: %.100s", c->self, c->wfd, + c->istate, c->ostate, strerror(errno)); +@@ -412,7 +412,7 @@ chan_shutdown_read(struct ssh *ssh, Chan + c->istate, c->ostate, strerror(errno)); + } + } else { +- if (channel_close_fd(ssh, &c->rfd) < 0) { ++ if (channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK) < 0) { + logit_f("channel %d: close() failed for " + "fd %d [i%d o%d]: %.100s", c->self, c->rfd, + c->istate, c->ostate, strerror(errno)); +@@ -431,7 +431,7 @@ chan_shutdown_extended_read(struct ssh * + debug_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])", + c->self, c->istate, c->ostate, c->sock, c->rfd, c->efd, + channel_format_extended_usage(c)); +- if (channel_close_fd(ssh, &c->efd) < 0) { ++ if (channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK) < 0) { + logit_f("channel %d: close() failed for " + "extended fd %d [i%d o%d]: %.100s", c->self, c->efd, + c->istate, c->ostate, strerror(errno)); +diff -up openssh-8.6p1/ssh.c.restore-nonblock openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.restore-nonblock 2021-05-10 10:55:46.991156175 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-10 11:06:28.315222828 +0200 +@@ -2085,14 +2085,6 @@ ssh_session2_open(struct ssh *ssh) + if (in == -1 || out == -1 || err == -1) + fatal("dup() in/out/err failed"); + +- /* enable nonblocking unless tty */ +- if (!isatty(in)) +- set_nonblock(in); +- if (!isatty(out)) +- set_nonblock(out); +- if (!isatty(err)) +- set_nonblock(err); +- + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (tty_flag) { +@@ -2102,7 +2094,7 @@ ssh_session2_open(struct ssh *ssh) + c = channel_new(ssh, + "session", SSH_CHANNEL_OPENING, in, out, err, + window, packetmax, CHAN_EXTENDED_WRITE, +- "client-session", /*nonblock*/0); ++ "client-session", /*nonblock*/1); + + debug3_f("channel_new: %d", c->self); + diff --git a/openssh-8.5p1-gsissh.patch b/openssh-8.6p1-gsissh.patch similarity index 89% rename from openssh-8.5p1-gsissh.patch rename to openssh-8.6p1-gsissh.patch index 3d2a798..685dcd9 100644 --- a/openssh-8.5p1-gsissh.patch +++ b/openssh-8.6p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c ---- openssh-8.5p1.orig/auth2.c 2021-03-16 18:29:34.889456973 +0100 -+++ openssh-8.5p1/auth2.c 2021-03-16 18:30:25.470567118 +0100 +diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c +--- openssh-8.6p1.orig/auth2.c 2021-05-04 10:47:33.443951396 +0200 ++++ openssh-8.6p1/auth2.c 2021-05-04 10:48:29.601078299 +0200 @@ -277,7 +277,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -100,9 +100,9 @@ diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.5p1.orig/auth2-gss.c openssh-8.5p1/auth2-gss.c ---- openssh-8.5p1.orig/auth2-gss.c 2021-03-16 18:29:34.802456784 +0100 -+++ openssh-8.5p1/auth2-gss.c 2021-03-16 18:30:25.470567118 +0100 +diff -Nur openssh-8.6p1.orig/auth2-gss.c openssh-8.6p1/auth2-gss.c +--- openssh-8.6p1.orig/auth2-gss.c 2021-05-04 10:47:33.342951168 +0200 ++++ openssh-8.6p1/auth2-gss.c 2021-05-04 10:48:29.602078301 +0200 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -307,9 +307,9 @@ diff -Nur openssh-8.5p1.orig/auth2-gss.c openssh-8.5p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.5p1.orig/auth.c openssh-8.5p1/auth.c ---- openssh-8.5p1.orig/auth.c 2021-03-16 18:29:34.890456975 +0100 -+++ openssh-8.5p1/auth.c 2021-03-16 18:30:25.471567120 +0100 +diff -Nur openssh-8.6p1.orig/auth.c openssh-8.6p1/auth.c +--- openssh-8.6p1.orig/auth.c 2021-05-04 10:47:33.445951400 +0200 ++++ openssh-8.6p1/auth.c 2021-05-04 10:48:29.603078303 +0200 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -340,9 +340,9 @@ diff -Nur openssh-8.5p1.orig/auth.c openssh-8.5p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.5p1.orig/auth.h openssh-8.5p1/auth.h ---- openssh-8.5p1.orig/auth.h 2021-03-16 18:29:34.890456975 +0100 -+++ openssh-8.5p1/auth.h 2021-03-16 18:30:25.471567120 +0100 +diff -Nur openssh-8.6p1.orig/auth.h openssh-8.6p1/auth.h +--- openssh-8.6p1.orig/auth.h 2021-05-04 10:47:33.445951400 +0200 ++++ openssh-8.6p1/auth.h 2021-05-04 10:48:29.603078303 +0200 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +352,9 @@ diff -Nur openssh-8.5p1.orig/auth.h openssh-8.5p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c ---- openssh-8.5p1.orig/auth-pam.c 2021-03-16 18:29:34.770456714 +0100 -+++ openssh-8.5p1/auth-pam.c 2021-03-16 18:30:25.472567122 +0100 +diff -Nur openssh-8.6p1.orig/auth-pam.c openssh-8.6p1/auth-pam.c +--- openssh-8.6p1.orig/auth-pam.c 2021-05-04 10:47:33.440951389 +0200 ++++ openssh-8.6p1/auth-pam.c 2021-05-04 10:48:29.604078305 +0200 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -461,9 +461,9 @@ diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c + sshpam_authctxt->pw->pw_name); + } if (!do_pam_account()) { - sshpam_err = PAM_ACCT_EXPIRED; - goto auth_fail; -@@ -542,6 +613,13 @@ + /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN. + * Backward compatibility for other errors. */ +@@ -546,6 +617,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -477,8 +477,8 @@ diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -732,6 +810,8 @@ - xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", +@@ -738,6 +816,8 @@ + xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), sshpam_laddr, ssh_local_port(ssh)); + /* Save so allowed_user can be called later */ @@ -486,7 +486,7 @@ diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1074,6 +1154,18 @@ +@@ -1082,6 +1162,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -505,7 +505,7 @@ diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1362,6 +1454,9 @@ +@@ -1370,6 +1462,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -515,9 +515,9 @@ diff -Nur openssh-8.5p1.orig/auth-pam.c openssh-8.5p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.5p1.orig/auth-pam.h openssh-8.5p1/auth-pam.h ---- openssh-8.5p1.orig/auth-pam.h 2021-03-16 18:29:34.771456716 +0100 -+++ openssh-8.5p1/auth-pam.h 2021-03-16 18:30:25.472567122 +0100 +diff -Nur openssh-8.6p1.orig/auth-pam.h openssh-8.6p1/auth-pam.h +--- openssh-8.6p1.orig/auth-pam.h 2021-05-04 10:47:33.303951079 +0200 ++++ openssh-8.6p1/auth-pam.h 2021-05-04 10:48:29.604078305 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +525,9 @@ diff -Nur openssh-8.5p1.orig/auth-pam.h openssh-8.5p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.5p1.orig/canohost.c openssh-8.5p1/canohost.c ---- openssh-8.5p1.orig/canohost.c 2021-03-16 18:29:34.802456784 +0100 -+++ openssh-8.5p1/canohost.c 2021-03-16 18:30:25.473567125 +0100 +diff -Nur openssh-8.6p1.orig/canohost.c openssh-8.6p1/canohost.c +--- openssh-8.6p1.orig/canohost.c 2021-05-04 10:47:33.343951170 +0200 ++++ openssh-8.6p1/canohost.c 2021-05-04 10:48:29.605078308 +0200 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +570,9 @@ diff -Nur openssh-8.5p1.orig/canohost.c openssh-8.5p1/canohost.c + } + } +} -diff -Nur openssh-8.5p1.orig/canohost.h openssh-8.5p1/canohost.h ---- openssh-8.5p1.orig/canohost.h 2021-03-16 18:29:34.802456784 +0100 -+++ openssh-8.5p1/canohost.h 2021-03-16 18:30:25.473567125 +0100 +diff -Nur openssh-8.6p1.orig/canohost.h openssh-8.6p1/canohost.h +--- openssh-8.6p1.orig/canohost.h 2021-05-04 10:47:33.343951170 +0200 ++++ openssh-8.6p1/canohost.h 2021-05-04 10:48:29.605078308 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,9 +580,9 @@ diff -Nur openssh-8.5p1.orig/canohost.h openssh-8.5p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.5p1.orig/configure.ac openssh-8.5p1/configure.ac ---- openssh-8.5p1.orig/configure.ac 2021-03-16 18:29:34.879456951 +0100 -+++ openssh-8.5p1/configure.ac 2021-03-16 18:30:25.474567127 +0100 +diff -Nur openssh-8.6p1.orig/configure.ac openssh-8.6p1/configure.ac +--- openssh-8.6p1.orig/configure.ac 2021-05-04 10:47:33.430951367 +0200 ++++ openssh-8.6p1/configure.ac 2021-05-04 10:48:29.607078312 +0200 @@ -4718,6 +4718,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -639,9 +639,9 @@ diff -Nur openssh-8.5p1.orig/configure.ac openssh-8.5p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.5p1.orig/gss-genr.c openssh-8.5p1/gss-genr.c ---- openssh-8.5p1.orig/gss-genr.c 2021-03-16 18:29:34.804456788 +0100 -+++ openssh-8.5p1/gss-genr.c 2021-03-16 18:30:25.475567129 +0100 +diff -Nur openssh-8.6p1.orig/gss-genr.c openssh-8.6p1/gss-genr.c +--- openssh-8.6p1.orig/gss-genr.c 2021-05-04 10:47:33.465951446 +0200 ++++ openssh-8.6p1/gss-genr.c 2021-05-04 10:48:29.607078312 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -650,7 +650,7 @@ diff -Nur openssh-8.5p1.orig/gss-genr.c openssh-8.5p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -407,9 +408,18 @@ +@@ -408,9 +409,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -670,7 +670,7 @@ diff -Nur openssh-8.5p1.orig/gss-genr.c openssh-8.5p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -417,6 +427,7 @@ +@@ -418,6 +428,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -678,9 +678,9 @@ diff -Nur openssh-8.5p1.orig/gss-genr.c openssh-8.5p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.5p1.orig/gss-serv.c openssh-8.5p1/gss-serv.c ---- openssh-8.5p1.orig/gss-serv.c 2021-03-16 18:29:34.820456823 +0100 -+++ openssh-8.5p1/gss-serv.c 2021-03-16 18:30:25.475567129 +0100 +diff -Nur openssh-8.6p1.orig/gss-serv.c openssh-8.6p1/gss-serv.c +--- openssh-8.6p1.orig/gss-serv.c 2021-05-04 10:47:33.369951229 +0200 ++++ openssh-8.6p1/gss-serv.c 2021-05-04 10:48:29.608078315 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +961,9 @@ diff -Nur openssh-8.5p1.orig/gss-serv.c openssh-8.5p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.5p1.orig/gss-serv-gsi.c openssh-8.5p1/gss-serv-gsi.c ---- openssh-8.5p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.5p1/gss-serv-gsi.c 2021-03-16 18:30:25.476567131 +0100 +diff -Nur openssh-8.6p1.orig/gss-serv-gsi.c openssh-8.6p1/gss-serv-gsi.c +--- openssh-8.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.6p1/gss-serv-gsi.c 2021-05-04 10:48:29.609078317 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1293,9 @@ diff -Nur openssh-8.5p1.orig/gss-serv-gsi.c openssh-8.5p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.5p1.orig/gss-serv-krb5.c openssh-8.5p1/gss-serv-krb5.c ---- openssh-8.5p1.orig/gss-serv-krb5.c 2021-03-16 18:29:34.840456866 +0100 -+++ openssh-8.5p1/gss-serv-krb5.c 2021-03-16 18:30:25.476567131 +0100 +diff -Nur openssh-8.6p1.orig/gss-serv-krb5.c openssh-8.6p1/gss-serv-krb5.c +--- openssh-8.6p1.orig/gss-serv-krb5.c 2021-05-04 10:47:33.392951281 +0200 ++++ openssh-8.6p1/gss-serv-krb5.c 2021-05-04 10:48:29.609078317 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1349,9 @@ diff -Nur openssh-8.5p1.orig/gss-serv-krb5.c openssh-8.5p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c ---- openssh-8.5p1.orig/kexgsss.c 2021-03-16 18:29:34.916457032 +0100 -+++ openssh-8.5p1/kexgsss.c 2021-03-16 18:30:25.477567133 +0100 +diff -Nur openssh-8.6p1.orig/kexgsss.c openssh-8.6p1/kexgsss.c +--- openssh-8.6p1.orig/kexgsss.c 2021-05-04 10:47:33.475951468 +0200 ++++ openssh-8.6p1/kexgsss.c 2021-05-04 10:48:29.609078317 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1360,7 +1360,7 @@ diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c extern ServerOptions options; int -@@ -99,8 +100,10 @@ +@@ -96,8 +97,10 @@ debug2_f("Acquiring credentials"); @@ -1372,7 +1372,7 @@ diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c do { debug("Wait SSH2_MSG_KEXGSS_INIT"); -@@ -188,13 +191,14 @@ +@@ -195,13 +198,14 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1388,7 +1388,7 @@ diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -490,4 +494,26 @@ +@@ -479,4 +483,26 @@ sshbuf_free(shared_secret); return r; } @@ -1415,10 +1415,10 @@ diff -Nur openssh-8.5p1.orig/kexgsss.c openssh-8.5p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in ---- openssh-8.5p1.orig/Makefile.in 2021-03-16 18:29:34.892456980 +0100 -+++ openssh-8.5p1/Makefile.in 2021-03-16 18:30:25.477567133 +0100 -@@ -127,6 +127,7 @@ +diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in +--- openssh-8.6p1.orig/Makefile.in 2021-05-04 10:47:33.447951405 +0200 ++++ openssh-8.6p1/Makefile.in 2021-05-04 10:48:29.610078319 +0200 +@@ -128,6 +128,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ @@ -1426,9 +1426,9 @@ diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.5p1.orig/misc.c openssh-8.5p1/misc.c ---- openssh-8.5p1.orig/misc.c 2021-03-16 18:29:34.857456904 +0100 -+++ openssh-8.5p1/misc.c 2021-03-16 18:30:25.478567135 +0100 +diff -Nur openssh-8.6p1.orig/misc.c openssh-8.6p1/misc.c +--- openssh-8.6p1.orig/misc.c 2021-05-04 10:47:33.466951448 +0200 ++++ openssh-8.6p1/misc.c 2021-05-04 10:48:29.612078324 +0200 @@ -378,11 +378,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1488,10 +1488,10 @@ diff -Nur openssh-8.5p1.orig/misc.c openssh-8.5p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.5p1.orig/misc.h openssh-8.5p1/misc.h ---- openssh-8.5p1.orig/misc.h 2021-03-16 18:29:34.857456904 +0100 -+++ openssh-8.5p1/misc.h 2021-03-16 18:30:25.479567137 +0100 -@@ -97,6 +97,7 @@ +diff -Nur openssh-8.6p1.orig/misc.h openssh-8.6p1/misc.h +--- openssh-8.6p1.orig/misc.h 2021-05-04 10:47:33.408951317 +0200 ++++ openssh-8.6p1/misc.h 2021-05-04 10:48:29.612078324 +0200 +@@ -98,6 +98,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1499,9 +1499,9 @@ diff -Nur openssh-8.5p1.orig/misc.h openssh-8.5p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-8.5p1.orig/monitor.c openssh-8.5p1/monitor.c ---- openssh-8.5p1.orig/monitor.c 2021-03-16 18:29:34.911457021 +0100 -+++ openssh-8.5p1/monitor.c 2021-03-16 18:30:25.479567137 +0100 +diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c +--- openssh-8.6p1.orig/monitor.c 2021-05-04 10:47:33.467951450 +0200 ++++ openssh-8.6p1/monitor.c 2021-05-04 10:48:29.614078329 +0200 @@ -154,6 +154,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1570,7 +1570,7 @@ diff -Nur openssh-8.5p1.orig/monitor.c openssh-8.5p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -766,15 +778,18 @@ +@@ -762,15 +774,18 @@ debug3_f("entering"); @@ -1592,7 +1592,7 @@ diff -Nur openssh-8.5p1.orig/monitor.c openssh-8.5p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2117,6 +2132,79 @@ +@@ -2113,6 +2128,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.5p1.orig/monitor.c openssh-8.5p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.5p1.orig/monitor.h openssh-8.5p1/monitor.h ---- openssh-8.5p1.orig/monitor.h 2021-03-16 18:29:34.893456982 +0100 -+++ openssh-8.5p1/monitor.h 2021-03-16 18:30:25.480567140 +0100 +diff -Nur openssh-8.6p1.orig/monitor.h openssh-8.6p1/monitor.h +--- openssh-8.6p1.orig/monitor.h 2021-05-04 10:47:33.447951405 +0200 ++++ openssh-8.6p1/monitor.h 2021-05-04 10:48:29.614078329 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,10 +1686,10 @@ diff -Nur openssh-8.5p1.orig/monitor.h openssh-8.5p1/monitor.h }; struct ssh; -diff -Nur openssh-8.5p1.orig/monitor_wrap.c openssh-8.5p1/monitor_wrap.c ---- openssh-8.5p1.orig/monitor_wrap.c 2021-03-16 18:29:34.911457021 +0100 -+++ openssh-8.5p1/monitor_wrap.c 2021-03-16 18:30:25.480567140 +0100 -@@ -1087,6 +1087,94 @@ +diff -Nur openssh-8.6p1.orig/monitor_wrap.c openssh-8.6p1/monitor_wrap.c +--- openssh-8.6p1.orig/monitor_wrap.c 2021-05-04 10:47:33.467951450 +0200 ++++ openssh-8.6p1/monitor_wrap.c 2021-05-04 10:48:29.615078331 +0200 +@@ -1084,6 +1084,94 @@ return (authenticated); } @@ -1784,10 +1784,10 @@ diff -Nur openssh-8.5p1.orig/monitor_wrap.c openssh-8.5p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.5p1.orig/monitor_wrap.h openssh-8.5p1/monitor_wrap.h ---- openssh-8.5p1.orig/monitor_wrap.h 2021-03-16 18:29:34.899456995 +0100 -+++ openssh-8.5p1/monitor_wrap.h 2021-03-16 18:30:25.481567142 +0100 -@@ -74,6 +74,10 @@ +diff -Nur openssh-8.6p1.orig/monitor_wrap.h openssh-8.6p1/monitor_wrap.h +--- openssh-8.6p1.orig/monitor_wrap.h 2021-05-04 10:47:33.453951418 +0200 ++++ openssh-8.6p1/monitor_wrap.h 2021-05-04 10:48:29.616078333 +0200 +@@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-8.5p1.orig/monitor_wrap.h openssh-8.5p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c ---- openssh-8.5p1.orig/readconf.c 2021-03-16 18:29:34.904457006 +0100 -+++ openssh-8.5p1/readconf.c 2021-03-16 18:30:25.482567144 +0100 -@@ -2390,11 +2390,11 @@ +diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c +--- openssh-8.6p1.orig/readconf.c 2021-05-04 10:47:33.468951452 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-04 10:48:29.617078335 +0200 +@@ -2391,11 +2391,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1816,9 +1816,9 @@ diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h ---- openssh-8.5p1.orig/readconf.h 2021-03-16 18:29:34.808456797 +0100 -+++ openssh-8.5p1/readconf.h 2021-03-16 18:30:25.482567144 +0100 +diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h +--- openssh-8.6p1.orig/readconf.h 2021-05-04 10:47:33.355951197 +0200 ++++ openssh-8.6p1/readconf.h 2021-05-04 10:48:29.618078338 +0200 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c ---- openssh-8.5p1.orig/servconf.c 2021-03-16 18:29:34.912457023 +0100 -+++ openssh-8.5p1/servconf.c 2021-03-16 18:30:25.483567146 +0100 +diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c +--- openssh-8.6p1.orig/servconf.c 2021-05-04 10:47:33.469951455 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-04 10:48:29.619078340 +0200 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1860,7 +1860,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -371,13 +376,17 @@ +@@ -373,13 +378,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -515,7 +524,7 @@ +@@ -517,7 +526,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -537,6 +546,9 @@ +@@ -539,6 +548,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -569,8 +581,10 @@ +@@ -571,8 +583,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -622,8 +636,15 @@ +@@ -625,8 +639,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -631,8 +652,11 @@ +@@ -634,8 +655,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -704,6 +728,8 @@ +@@ -707,6 +731,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1357,6 +1383,10 @@ +@@ -1360,6 +1386,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1599,6 +1629,10 @@ +@@ -1606,6 +1636,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1607,6 +1641,10 @@ +@@ -1614,6 +1648,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1627,6 +1665,12 @@ +@@ -1634,6 +1672,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2614,6 +2658,7 @@ +@@ -2621,6 +2665,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,10 +2001,10 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h ---- openssh-8.5p1.orig/servconf.h 2021-03-16 18:29:34.850456888 +0100 -+++ openssh-8.5p1/servconf.h 2021-03-16 18:30:25.483567146 +0100 -@@ -145,9 +145,12 @@ +diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h +--- openssh-8.6p1.orig/servconf.h 2021-05-04 10:47:33.402951303 +0200 ++++ openssh-8.6p1/servconf.h 2021-05-04 10:48:29.620078342 +0200 +@@ -146,9 +146,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2017,7 +2017,7 @@ diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -209,6 +212,7 @@ +@@ -210,6 +213,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2025,9 +2025,9 @@ diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h int permit_tun; -diff -Nur openssh-8.5p1.orig/ssh.1 openssh-8.5p1/ssh.1 ---- openssh-8.5p1.orig/ssh.1 2021-03-16 18:29:34.810456801 +0100 -+++ openssh-8.5p1/ssh.1 2021-03-16 18:30:25.484567148 +0100 +diff -Nur openssh-8.6p1.orig/ssh.1 openssh-8.6p1/ssh.1 +--- openssh-8.6p1.orig/ssh.1 2021-05-04 10:47:33.357951202 +0200 ++++ openssh-8.6p1/ssh.1 2021-05-04 10:48:29.621078345 +0200 @@ -1473,6 +1473,18 @@ on to new connections). .It Ev USER @@ -2047,9 +2047,9 @@ diff -Nur openssh-8.5p1.orig/ssh.1 openssh-8.5p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c ---- openssh-8.5p1.orig/ssh.c 2021-03-16 18:29:34.905457008 +0100 -+++ openssh-8.5p1/ssh.c 2021-03-16 18:30:25.485567150 +0100 +diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c +--- openssh-8.6p1.orig/ssh.c 2021-05-04 10:47:33.472951462 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-04 10:48:29.622078347 +0200 @@ -575,6 +575,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2103,9 +2103,9 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-8.5p1.orig/ssh_config openssh-8.5p1/ssh_config ---- openssh-8.5p1.orig/ssh_config 2021-03-16 18:29:34.810456801 +0100 -+++ openssh-8.5p1/ssh_config 2021-03-16 18:30:25.485567150 +0100 +diff -Nur openssh-8.6p1.orig/ssh_config openssh-8.6p1/ssh_config +--- openssh-8.6p1.orig/ssh_config 2021-05-04 10:47:33.358951204 +0200 ++++ openssh-8.6p1/ssh_config 2021-05-04 10:48:29.622078347 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.5p1.orig/ssh_config openssh-8.5p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.5p1.orig/ssh_config.5 openssh-8.5p1/ssh_config.5 ---- openssh-8.5p1.orig/ssh_config.5 2021-03-16 18:29:34.873456938 +0100 -+++ openssh-8.5p1/ssh_config.5 2021-03-16 18:30:25.486567152 +0100 +diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 +--- openssh-8.6p1.orig/ssh_config.5 2021-05-04 10:47:33.424951353 +0200 ++++ openssh-8.6p1/ssh_config.5 2021-05-04 10:48:29.623078349 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2168,9 +2168,9 @@ diff -Nur openssh-8.5p1.orig/ssh_config.5 openssh-8.5p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c ---- openssh-8.5p1.orig/sshconnect2.c 2021-03-16 18:29:34.906457010 +0100 -+++ openssh-8.5p1/sshconnect2.c 2021-03-16 18:30:25.487567155 +0100 +diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1.orig/sshconnect2.c 2021-05-04 10:47:33.459951432 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-04 10:48:29.624078351 +0200 @@ -854,6 +854,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2238,9 +2238,9 @@ diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.5p1.orig/sshd.8 openssh-8.5p1/sshd.8 ---- openssh-8.5p1.orig/sshd.8 2021-03-16 18:29:34.824456832 +0100 -+++ openssh-8.5p1/sshd.8 2021-03-16 18:30:25.487567155 +0100 +diff -Nur openssh-8.6p1.orig/sshd.8 openssh-8.6p1/sshd.8 +--- openssh-8.6p1.orig/sshd.8 2021-05-04 10:47:33.375951242 +0200 ++++ openssh-8.6p1/sshd.8 2021-05-04 10:48:29.624078351 +0200 @@ -815,6 +815,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2271,10 +2271,10 @@ diff -Nur openssh-8.5p1.orig/sshd.8 openssh-8.5p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c ---- openssh-8.5p1.orig/sshd.c 2021-03-16 18:29:34.914457027 +0100 -+++ openssh-8.5p1/sshd.c 2021-03-16 18:30:25.488567157 +0100 -@@ -2356,7 +2356,7 @@ +diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c +--- openssh-8.6p1.orig/sshd.c 2021-05-04 10:47:33.472951462 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-04 10:48:29.625078353 +0200 +@@ -2364,7 +2364,7 @@ #endif #ifdef GSSAPI @@ -2283,9 +2283,9 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config ---- openssh-8.5p1.orig/sshd_config 2021-03-16 18:29:34.841456868 +0100 -+++ openssh-8.5p1/sshd_config 2021-03-16 18:30:25.488567157 +0100 +diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config +--- openssh-8.6p1.orig/sshd_config 2021-05-04 10:47:33.393951283 +0200 ++++ openssh-8.6p1/sshd_config 2021-05-04 10:48:29.626078356 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,9 +2311,9 @@ diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.5p1.orig/sshd_config.5 openssh-8.5p1/sshd_config.5 ---- openssh-8.5p1.orig/sshd_config.5 2021-03-16 18:29:34.874456941 +0100 -+++ openssh-8.5p1/sshd_config.5 2021-03-16 18:30:25.489567159 +0100 +diff -Nur openssh-8.6p1.orig/sshd_config.5 openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1.orig/sshd_config.5 2021-05-04 10:47:33.424951353 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-05-04 10:48:29.627078358 +0200 @@ -632,15 +632,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2359,7 +2359,7 @@ diff -Nur openssh-8.5p1.orig/sshd_config.5 openssh-8.5p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1773,6 +1792,12 @@ +@@ -1783,6 +1802,12 @@ as a non-root user. The default is .Cm no . @@ -2372,9 +2372,9 @@ diff -Nur openssh-8.5p1.orig/sshd_config.5 openssh-8.5p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.5p1.orig/sshd_config_redhat openssh-8.5p1/sshd_config_redhat ---- openssh-8.5p1.orig/sshd_config_redhat 2021-03-16 18:29:34.796456771 +0100 -+++ openssh-8.5p1/sshd_config_redhat 2021-03-16 18:30:25.489567159 +0100 +diff -Nur openssh-8.6p1.orig/sshd_config_redhat openssh-8.6p1/sshd_config_redhat +--- openssh-8.6p1.orig/sshd_config_redhat 2021-05-04 10:47:33.336951154 +0200 ++++ openssh-8.6p1/sshd_config_redhat 2021-05-04 10:48:29.627078358 +0200 @@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-8.5p1.orig/sshd_config_redhat openssh-8.5p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.5p1.orig/ssh-gss.h openssh-8.5p1/ssh-gss.h ---- openssh-8.5p1.orig/ssh-gss.h 2021-03-16 18:29:34.821456825 +0100 -+++ openssh-8.5p1/ssh-gss.h 2021-03-16 18:30:25.490567161 +0100 +diff -Nur openssh-8.6p1.orig/ssh-gss.h openssh-8.6p1/ssh-gss.h +--- openssh-8.6p1.orig/ssh-gss.h 2021-05-04 10:47:33.372951235 +0200 ++++ openssh-8.6p1/ssh-gss.h 2021-05-04 10:48:29.628078360 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-8.5p1.orig/ssh-gss.h openssh-8.5p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.5p1.orig/version.h openssh-8.5p1/version.h ---- openssh-8.5p1.orig/version.h 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/version.h 2021-03-16 18:30:25.490567161 +0100 +diff -Nur openssh-8.6p1.orig/version.h openssh-8.6p1/version.h +--- openssh-8.6p1.orig/version.h 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/version.h 2021-05-04 10:48:29.628078360 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.5" + #define SSH_VERSION "OpenSSH_8.6" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.5p1-hpn-15.2-modified.patch b/openssh-8.6p1-hpn-15.2-modified.patch similarity index 89% rename from openssh-8.5p1-hpn-15.2-modified.patch rename to openssh-8.6p1-hpn-15.2-modified.patch index 64d4b18..0c38562 100644 --- a/openssh-8.5p1-hpn-15.2-modified.patch +++ b/openssh-8.6p1-hpn-15.2-modified.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c ---- openssh-8.5p1.orig/auth2.c 2021-03-16 18:30:25.470567118 +0100 -+++ openssh-8.5p1/auth2.c 2021-03-16 18:34:37.852116684 +0100 +diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c +--- openssh-8.6p1.orig/auth2.c 2021-05-22 08:23:21.056175731 +0200 ++++ openssh-8.6p1/auth2.c 2021-05-22 08:24:33.539345593 +0200 @@ -53,6 +53,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -31,9 +31,9 @@ diff -Nur openssh-8.5p1.orig/auth2.c openssh-8.5p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c ---- openssh-8.5p1.orig/channels.c 2021-03-16 18:29:34.910457019 +0100 -+++ openssh-8.5p1/channels.c 2021-03-16 18:43:25.893265131 +0100 +diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c +--- openssh-8.6p1.orig/channels.c 2021-05-22 08:23:21.043175700 +0200 ++++ openssh-8.6p1/channels.c 2021-05-22 08:24:33.540345595 +0200 @@ -220,6 +220,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -44,7 +44,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c /* -- channel core */ void -@@ -395,6 +398,7 @@ +@@ -407,6 +410,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -52,7 +52,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1082,6 +1086,28 @@ +@@ -1098,6 +1102,28 @@ FD_SET(c->sock, writeset); } @@ -81,7 +81,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c, fd_set *readset, fd_set *writeset) -@@ -2120,22 +2146,31 @@ +@@ -2136,22 +2162,31 @@ if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && @@ -118,7 +118,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c c->local_consumed = 0; } return 1; -@@ -3302,6 +3337,14 @@ +@@ -3318,6 +3353,14 @@ return addr; } @@ -133,7 +133,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -@@ -3442,8 +3485,10 @@ +@@ -3458,8 +3501,10 @@ } /* Allocate a channel number for the socket. */ @@ -145,7 +145,7 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; -@@ -4627,7 +4672,8 @@ +@@ -4645,7 +4690,8 @@ sock = socks[n]; nc = channel_new(ssh, "x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, @@ -155,9 +155,9 @@ diff -Nur openssh-8.5p1.orig/channels.c openssh-8.5p1/channels.c 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; -diff -Nur openssh-8.5p1.orig/channels.h openssh-8.5p1/channels.h ---- openssh-8.5p1.orig/channels.h 2021-03-16 18:29:34.849456886 +0100 -+++ openssh-8.5p1/channels.h 2021-03-17 12:35:59.486559703 +0100 +diff -Nur openssh-8.6p1.orig/channels.h openssh-8.6p1/channels.h +--- openssh-8.6p1.orig/channels.h 2021-05-22 08:23:21.020175646 +0200 ++++ openssh-8.6p1/channels.h 2021-05-22 08:24:33.541345597 +0200 @@ -158,8 +158,10 @@ u_int local_window_max; u_int local_consumed; @@ -169,7 +169,7 @@ diff -Nur openssh-8.5p1.orig/channels.h openssh-8.5p1/channels.h char *ctype; /* type */ -@@ -221,7 +223,7 @@ +@@ -228,7 +230,7 @@ #define CHAN_LOCAL 0x10 /* Read buffer size */ @@ -178,7 +178,7 @@ diff -Nur openssh-8.5p1.orig/channels.h openssh-8.5p1/channels.h /* Maximum channel input buffer size */ #define CHAN_INPUT_MAX (16*1024*1024) -@@ -352,4 +354,7 @@ +@@ -359,4 +361,7 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); @@ -186,9 +186,9 @@ diff -Nur openssh-8.5p1.orig/channels.h openssh-8.5p1/channels.h +void channel_set_hpn(int, int); + #endif -diff -Nur openssh-8.5p1.orig/cipher.c openssh-8.5p1/cipher.c ---- openssh-8.5p1.orig/cipher.c 2021-03-16 18:29:34.891456977 +0100 -+++ openssh-8.5p1/cipher.c 2021-03-16 18:34:37.854116688 +0100 +diff -Nur openssh-8.6p1.orig/cipher.c openssh-8.6p1/cipher.c +--- openssh-8.6p1.orig/cipher.c 2021-05-22 08:23:21.024175656 +0200 ++++ openssh-8.6p1/cipher.c 2021-05-22 08:24:33.542345600 +0200 @@ -48,6 +48,7 @@ #include "sshbuf.h" #include "ssherr.h" @@ -269,9 +269,9 @@ diff -Nur openssh-8.5p1.orig/cipher.c openssh-8.5p1/cipher.c free(cipher_list); return 0; } -diff -Nur openssh-8.5p1.orig/cipher-ctr-mt.c openssh-8.5p1/cipher-ctr-mt.c ---- openssh-8.5p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.5p1/cipher-ctr-mt.c 2021-03-17 14:11:10.591505532 +0100 +diff -Nur openssh-8.6p1.orig/cipher-ctr-mt.c openssh-8.6p1/cipher-ctr-mt.c +--- openssh-8.6p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.6p1/cipher-ctr-mt.c 2021-05-22 08:24:33.543345602 +0200 @@ -0,0 +1,678 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -951,9 +951,9 @@ diff -Nur openssh-8.5p1.orig/cipher-ctr-mt.c openssh-8.5p1/cipher-ctr-mt.c +} + +#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-8.5p1.orig/cipher.h openssh-8.5p1/cipher.h ---- openssh-8.5p1.orig/cipher.h 2021-03-16 18:29:34.891456977 +0100 -+++ openssh-8.5p1/cipher.h 2021-03-16 18:51:58.700380071 +0100 +diff -Nur openssh-8.6p1.orig/cipher.h openssh-8.6p1/cipher.h +--- openssh-8.6p1.orig/cipher.h 2021-05-22 08:23:21.025175658 +0200 ++++ openssh-8.6p1/cipher.h 2021-05-22 08:24:33.543345602 +0200 @@ -68,7 +68,9 @@ struct sshcipher_ctx; @@ -974,9 +974,9 @@ diff -Nur openssh-8.5p1.orig/cipher.h openssh-8.5p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-8.5p1.orig/clientloop.c openssh-8.5p1/clientloop.c ---- openssh-8.5p1.orig/clientloop.c 2021-03-16 18:29:34.803456786 +0100 -+++ openssh-8.5p1/clientloop.c 2021-03-16 18:58:20.875166146 +0100 +diff -Nur openssh-8.6p1.orig/clientloop.c openssh-8.6p1/clientloop.c +--- openssh-8.6p1.orig/clientloop.c 2021-05-22 08:23:20.932175440 +0200 ++++ openssh-8.6p1/clientloop.c 2021-05-22 08:24:33.544345604 +0200 @@ -1593,7 +1593,9 @@ return NULL; c = channel_new(ssh, "x11", @@ -1008,9 +1008,9 @@ diff -Nur openssh-8.5p1.orig/clientloop.c openssh-8.5p1/clientloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) -diff -Nur openssh-8.5p1.orig/compat.c openssh-8.5p1/compat.c ---- openssh-8.5p1.orig/compat.c 2021-03-16 18:29:34.886456967 +0100 -+++ openssh-8.5p1/compat.c 2021-03-17 20:59:17.675130767 +0100 +diff -Nur openssh-8.6p1.orig/compat.c openssh-8.6p1/compat.c +--- openssh-8.6p1.orig/compat.c 2021-05-22 08:23:21.044175703 +0200 ++++ openssh-8.6p1/compat.c 2021-05-22 08:24:33.544345604 +0200 @@ -150,6 +150,17 @@ debug_f("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); @@ -1029,9 +1029,9 @@ diff -Nur openssh-8.5p1.orig/compat.c openssh-8.5p1/compat.c return; } } -diff -Nur openssh-8.5p1.orig/compat.h openssh-8.5p1/compat.h ---- openssh-8.5p1.orig/compat.h 2021-03-16 18:29:34.885456964 +0100 -+++ openssh-8.5p1/compat.h 2021-03-16 18:34:37.857116694 +0100 +diff -Nur openssh-8.6p1.orig/compat.h openssh-8.6p1/compat.h +--- openssh-8.6p1.orig/compat.h 2021-05-22 08:23:21.013175630 +0200 ++++ openssh-8.6p1/compat.h 2021-05-22 08:24:33.545345607 +0200 @@ -57,6 +57,7 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 @@ -1040,9 +1040,9 @@ diff -Nur openssh-8.5p1.orig/compat.h openssh-8.5p1/compat.h struct ssh; -diff -Nur openssh-8.5p1.orig/defines.h openssh-8.5p1/defines.h ---- openssh-8.5p1.orig/defines.h 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/defines.h 2021-03-16 18:34:37.857116694 +0100 +diff -Nur openssh-8.6p1.orig/defines.h openssh-8.6p1/defines.h +--- openssh-8.6p1.orig/defines.h 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/defines.h 2021-05-22 08:24:33.545345607 +0200 @@ -848,7 +848,7 @@ #endif @@ -1052,9 +1052,9 @@ diff -Nur openssh-8.5p1.orig/defines.h openssh-8.5p1/defines.h #endif /* -diff -Nur openssh-8.5p1.orig/digest.h openssh-8.5p1/digest.h ---- openssh-8.5p1.orig/digest.h 2021-03-16 18:29:34.875456943 +0100 -+++ openssh-8.5p1/digest.h 2021-03-16 19:00:44.631455264 +0100 +diff -Nur openssh-8.6p1.orig/digest.h openssh-8.6p1/digest.h +--- openssh-8.6p1.orig/digest.h 2021-05-22 08:23:21.003175607 +0200 ++++ openssh-8.6p1/digest.h 2021-05-22 08:24:33.545345607 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -1065,9 +1065,9 @@ diff -Nur openssh-8.5p1.orig/digest.h openssh-8.5p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-8.5p1.orig/digest-openssl.c openssh-8.5p1/digest-openssl.c ---- openssh-8.5p1.orig/digest-openssl.c 2021-03-16 18:29:34.875456943 +0100 -+++ openssh-8.5p1/digest-openssl.c 2021-03-16 18:34:37.858116696 +0100 +diff -Nur openssh-8.6p1.orig/digest-openssl.c openssh-8.6p1/digest-openssl.c +--- openssh-8.6p1.orig/digest-openssl.c 2021-05-22 08:23:21.003175607 +0200 ++++ openssh-8.6p1/digest-openssl.c 2021-05-22 08:24:33.546345609 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -1076,9 +1076,9 @@ diff -Nur openssh-8.5p1.orig/digest-openssl.c openssh-8.5p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-8.5p1.orig/HPN-README openssh-8.5p1/HPN-README ---- openssh-8.5p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.5p1/HPN-README 2021-03-17 09:11:09.298157429 +0100 +diff -Nur openssh-8.6p1.orig/HPN-README openssh-8.6p1/HPN-README +--- openssh-8.6p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.6p1/HPN-README 2021-05-22 08:24:33.546345609 +0200 @@ -0,0 +1,153 @@ +Notes: + @@ -1233,9 +1233,9 @@ diff -Nur openssh-8.5p1.orig/HPN-README openssh-8.5p1/HPN-README + Allan Jude provided the code for the NoneMac and buffer normalization. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. -diff -Nur openssh-8.5p1.orig/kex.c openssh-8.5p1/kex.c ---- openssh-8.5p1.orig/kex.c 2021-03-16 18:29:34.902457001 +0100 -+++ openssh-8.5p1/kex.c 2021-03-16 18:34:37.859116699 +0100 +diff -Nur openssh-8.6p1.orig/kex.c openssh-8.6p1/kex.c +--- openssh-8.6p1.orig/kex.c 2021-05-22 08:23:21.036175684 +0200 ++++ openssh-8.6p1/kex.c 2021-05-22 08:24:33.547345612 +0200 @@ -64,6 +64,7 @@ #include "ssherr.h" @@ -1301,8 +1301,8 @@ diff -Nur openssh-8.5p1.orig/kex.c openssh-8.5p1/kex.c if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", -- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, -+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, +- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, version_addendum == NULL ? "" : " ", version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; @@ -1321,9 +1321,9 @@ diff -Nur openssh-8.5p1.orig/kex.c openssh-8.5p1/kex.c debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); compat_banner(ssh, remote_version); -diff -Nur openssh-8.5p1.orig/log.c openssh-8.5p1/log.c ---- openssh-8.5p1.orig/log.c 2021-03-16 18:29:34.834456853 +0100 -+++ openssh-8.5p1/log.c 2021-03-16 18:34:37.859116699 +0100 +diff -Nur openssh-8.6p1.orig/log.c openssh-8.6p1/log.c +--- openssh-8.6p1.orig/log.c 2021-05-22 08:23:20.963175513 +0200 ++++ openssh-8.6p1/log.c 2021-05-22 08:24:33.547345612 +0200 @@ -46,6 +46,11 @@ #include #include @@ -1345,9 +1345,9 @@ diff -Nur openssh-8.5p1.orig/log.c openssh-8.5p1/log.c #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) -diff -Nur openssh-8.5p1.orig/mac.c openssh-8.5p1/mac.c ---- openssh-8.5p1.orig/mac.c 2021-03-16 18:29:34.892456980 +0100 -+++ openssh-8.5p1/mac.c 2021-03-16 18:34:37.859116699 +0100 +diff -Nur openssh-8.6p1.orig/mac.c openssh-8.6p1/mac.c +--- openssh-8.6p1.orig/mac.c 2021-05-22 08:23:21.025175658 +0200 ++++ openssh-8.6p1/mac.c 2021-05-22 08:24:33.547345612 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -1356,10 +1356,10 @@ diff -Nur openssh-8.5p1.orig/mac.c openssh-8.5p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in ---- openssh-8.5p1.orig/Makefile.in 2021-03-16 18:30:25.477567133 +0100 -+++ openssh-8.5p1/Makefile.in 2021-03-16 18:34:37.860116701 +0100 -@@ -47,7 +47,7 @@ +diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in +--- openssh-8.6p1.orig/Makefile.in 2021-05-22 08:23:21.061175742 +0200 ++++ openssh-8.6p1/Makefile.in 2021-05-22 08:24:33.548345614 +0200 +@@ -48,7 +48,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ @@ -1368,7 +1368,7 @@ diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ -@@ -94,7 +94,7 @@ +@@ -95,7 +95,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ @@ -1377,9 +1377,9 @@ diff -Nur openssh-8.5p1.orig/Makefile.in openssh-8.5p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-8.5p1.orig/packet.c openssh-8.5p1/packet.c ---- openssh-8.5p1.orig/packet.c 2021-03-16 18:29:34.894456984 +0100 -+++ openssh-8.5p1/packet.c 2021-03-16 18:34:37.861116703 +0100 +diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c +--- openssh-8.6p1.orig/packet.c 2021-05-22 08:23:21.028175665 +0200 ++++ openssh-8.6p1/packet.c 2021-05-22 08:24:33.549345616 +0200 @@ -246,7 +246,7 @@ TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; @@ -1528,9 +1528,9 @@ diff -Nur openssh-8.5p1.orig/packet.c openssh-8.5p1/packet.c +{ + return ssh->state->send_context; +} -diff -Nur openssh-8.5p1.orig/packet.h openssh-8.5p1/packet.h ---- openssh-8.5p1.orig/packet.h 2021-03-16 18:29:34.895456986 +0100 -+++ openssh-8.5p1/packet.h 2021-03-16 18:34:37.861116703 +0100 +diff -Nur openssh-8.6p1.orig/packet.h openssh-8.6p1/packet.h +--- openssh-8.6p1.orig/packet.h 2021-05-22 08:23:21.028175665 +0200 ++++ openssh-8.6p1/packet.h 2021-05-22 08:24:33.549345616 +0200 @@ -86,6 +86,14 @@ /* APP data */ @@ -1569,9 +1569,9 @@ diff -Nur openssh-8.5p1.orig/packet.h openssh-8.5p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-8.5p1.orig/progressmeter.c openssh-8.5p1/progressmeter.c ---- openssh-8.5p1.orig/progressmeter.c 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/progressmeter.c 2021-03-16 18:34:37.861116703 +0100 +diff -Nur openssh-8.6p1.orig/progressmeter.c openssh-8.6p1/progressmeter.c +--- openssh-8.6p1.orig/progressmeter.c 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/progressmeter.c 2021-05-22 08:24:33.549345616 +0200 @@ -68,6 +68,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -1633,9 +1633,9 @@ diff -Nur openssh-8.5p1.orig/progressmeter.c openssh-8.5p1/progressmeter.c } /*ARGSUSED*/ -diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c ---- openssh-8.5p1.orig/readconf.c 2021-03-16 18:30:25.482567144 +0100 -+++ openssh-8.5p1/readconf.c 2021-03-17 12:39:20.463992055 +0100 +diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c +--- openssh-8.6p1.orig/readconf.c 2021-05-22 08:23:21.064175750 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-22 08:24:33.550345619 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -1735,7 +1735,7 @@ diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c case oCiphers: arg = strdelim(&s); if (!arg || *arg == '\0') { -@@ -2315,6 +2372,14 @@ +@@ -2316,6 +2373,14 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -1750,7 +1750,7 @@ diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c options->proxy_use_fdpass = -1; options->ignored_unknown = NULL; options->num_canonical_domains = 0; -@@ -2489,6 +2554,43 @@ +@@ -2490,6 +2555,43 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -1794,9 +1794,9 @@ diff -Nur openssh-8.5p1.orig/readconf.c openssh-8.5p1/readconf.c if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { -diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h ---- openssh-8.5p1.orig/readconf.h 2021-03-16 18:30:25.482567144 +0100 -+++ openssh-8.5p1/readconf.h 2021-03-17 15:22:23.353088822 +0100 +diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h +--- openssh-8.6p1.orig/readconf.h 2021-05-22 08:23:21.064175750 +0200 ++++ openssh-8.6p1/readconf.h 2021-05-22 08:24:33.551345621 +0200 @@ -57,6 +57,10 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ @@ -1821,9 +1821,9 @@ diff -Nur openssh-8.5p1.orig/readconf.h openssh-8.5p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-8.5p1.orig/regress/integrity.sh openssh-8.5p1/regress/integrity.sh ---- openssh-8.5p1.orig/regress/integrity.sh 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/regress/integrity.sh 2021-03-16 18:34:37.863116707 +0100 +diff -Nur openssh-8.6p1.orig/regress/integrity.sh openssh-8.6p1/regress/integrity.sh +--- openssh-8.6p1.orig/regress/integrity.sh 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/integrity.sh 2021-05-22 08:24:33.551345621 +0200 @@ -21,6 +21,12 @@ cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" @@ -1837,10 +1837,10 @@ diff -Nur openssh-8.5p1.orig/regress/integrity.sh openssh-8.5p1/regress/integrit trace "test $tid: mac $m" elen=0 epad=0 -diff -Nur openssh-8.5p1.orig/sandbox-seccomp-filter.c openssh-8.5p1/sandbox-seccomp-filter.c ---- openssh-8.5p1.orig/sandbox-seccomp-filter.c 2021-03-16 18:29:34.904457006 +0100 -+++ openssh-8.5p1/sandbox-seccomp-filter.c 2021-03-16 18:34:37.864116709 +0100 -@@ -222,6 +222,9 @@ +diff -Nur openssh-8.6p1.orig/sandbox-seccomp-filter.c openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1.orig/sandbox-seccomp-filter.c 2021-05-22 08:23:21.037175686 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-22 08:24:33.552345623 +0200 +@@ -225,6 +225,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), #endif @@ -1850,7 +1850,7 @@ diff -Nur openssh-8.5p1.orig/sandbox-seccomp-filter.c openssh-8.5p1/sandbox-secc #ifdef __NR_getpgid SC_ALLOW(__NR_getpgid), #endif -@@ -315,6 +318,9 @@ +@@ -318,6 +321,9 @@ #ifdef __NR_sigprocmask SC_ALLOW(__NR_sigprocmask), #endif @@ -1860,9 +1860,9 @@ diff -Nur openssh-8.5p1.orig/sandbox-seccomp-filter.c openssh-8.5p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-8.5p1.orig/scp.c openssh-8.5p1/scp.c ---- openssh-8.5p1.orig/scp.c 2021-03-16 18:29:34.912457023 +0100 -+++ openssh-8.5p1/scp.c 2021-03-16 18:34:37.864116709 +0100 +diff -Nur openssh-8.6p1.orig/scp.c openssh-8.6p1/scp.c +--- openssh-8.6p1.orig/scp.c 2021-05-22 08:23:21.048175712 +0200 ++++ openssh-8.6p1/scp.c 2021-05-22 08:24:33.552345623 +0200 @@ -1251,7 +1251,7 @@ off_t size, statbytes; unsigned long long ull; @@ -1872,9 +1872,9 @@ diff -Nur openssh-8.5p1.orig/scp.c openssh-8.5p1/scp.c char **patterns = NULL; size_t n, npatterns = 0; struct timeval tv[2]; -diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c ---- openssh-8.5p1.orig/servconf.c 2021-03-16 18:30:25.483567146 +0100 -+++ openssh-8.5p1/servconf.c 2021-03-16 19:22:02.843001635 +0100 +diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c +--- openssh-8.6p1.orig/servconf.c 2021-05-22 08:23:21.064175750 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-22 08:24:33.553345625 +0200 @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -1907,7 +1907,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c /* Portable-specific options */ if (options->use_pam == -1) -@@ -462,6 +473,51 @@ +@@ -464,6 +475,51 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -1959,7 +1959,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -535,6 +591,9 @@ +@@ -537,6 +593,9 @@ sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -734,6 +793,12 @@ +@@ -737,6 +796,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -1982,7 +1982,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -792,6 +857,7 @@ +@@ -795,6 +860,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -1990,7 +1990,7 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1539,12 +1605,36 @@ +@@ -1546,12 +1612,36 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -2027,10 +2027,10 @@ diff -Nur openssh-8.5p1.orig/servconf.c openssh-8.5p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h ---- openssh-8.5p1.orig/servconf.h 2021-03-16 18:30:25.483567146 +0100 -+++ openssh-8.5p1/servconf.h 2021-03-17 15:24:07.943324235 +0100 -@@ -214,6 +214,13 @@ +diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h +--- openssh-8.6p1.orig/servconf.h 2021-05-22 08:23:21.065175752 +0200 ++++ openssh-8.6p1/servconf.h 2021-05-22 08:24:33.554345628 +0200 +@@ -215,6 +215,13 @@ int use_pam; /* Enable auth via PAM */ int permit_pam_user_change; /* Allow PAM to change user name */ @@ -2044,9 +2044,9 @@ diff -Nur openssh-8.5p1.orig/servconf.h openssh-8.5p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-8.5p1.orig/serverloop.c openssh-8.5p1/serverloop.c ---- openssh-8.5p1.orig/serverloop.c 2021-03-16 18:29:34.913457025 +0100 -+++ openssh-8.5p1/serverloop.c 2021-03-17 14:17:22.892355940 +0100 +diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c +--- openssh-8.6p1.orig/serverloop.c 2021-05-22 08:23:21.049175714 +0200 ++++ openssh-8.6p1/serverloop.c 2021-05-22 08:24:33.554345628 +0200 @@ -322,7 +322,7 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in) { @@ -2109,9 +2109,9 @@ diff -Nur openssh-8.5p1.orig/serverloop.c openssh-8.5p1/serverloop.c if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -diff -Nur openssh-8.5p1.orig/session.c openssh-8.5p1/session.c ---- openssh-8.5p1.orig/session.c 2021-03-16 18:29:34.900456997 +0100 -+++ openssh-8.5p1/session.c 2021-03-16 18:34:37.867116716 +0100 +diff -Nur openssh-8.6p1.orig/session.c openssh-8.6p1/session.c +--- openssh-8.6p1.orig/session.c 2021-05-22 08:23:21.050175717 +0200 ++++ openssh-8.6p1/session.c 2021-05-22 08:24:33.555345630 +0200 @@ -228,6 +228,7 @@ goto authsock_err; @@ -2120,7 +2120,7 @@ diff -Nur openssh-8.5p1.orig/session.c openssh-8.5p1/session.c nc = channel_new(ssh, "auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -2362,7 +2363,8 @@ +@@ -2364,7 +2365,8 @@ channel_set_fds(ssh, s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, @@ -2130,9 +2130,9 @@ diff -Nur openssh-8.5p1.orig/session.c openssh-8.5p1/session.c } /* -diff -Nur openssh-8.5p1.orig/sftp.1 openssh-8.5p1/sftp.1 ---- openssh-8.5p1.orig/sftp.1 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sftp.1 2021-03-16 18:34:37.867116716 +0100 +diff -Nur openssh-8.6p1.orig/sftp.1 openssh-8.6p1/sftp.1 +--- openssh-8.6p1.orig/sftp.1 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp.1 2021-05-22 08:24:33.556345633 +0200 @@ -296,7 +296,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed @@ -2143,21 +2143,21 @@ diff -Nur openssh-8.5p1.orig/sftp.1 openssh-8.5p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -diff -Nur openssh-8.5p1.orig/sftp.c openssh-8.5p1/sftp.c ---- openssh-8.5p1.orig/sftp.c 2021-03-16 18:29:34.913457025 +0100 -+++ openssh-8.5p1/sftp.c 2021-03-16 18:34:37.868116718 +0100 -@@ -71,7 +71,7 @@ - #include "sftp-client.h" +diff -Nur openssh-8.6p1.orig/sftp-client.c openssh-8.6p1/sftp-client.c +--- openssh-8.6p1.orig/sftp-client.c 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-client.c 2021-05-22 08:24:33.556345633 +0200 +@@ -65,7 +65,7 @@ + #define DEFAULT_COPY_BUFLEN 32768 - #define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ --#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ -+#define DEFAULT_NUM_REQUESTS 256 /* # concurrent outstanding requests */ + /* Default number of concurrent outstanding requests */ +-#define DEFAULT_NUM_REQUESTS 64 ++#define DEFAULT_NUM_REQUESTS 256 - /* File to read commands from */ - FILE* infile; -diff -Nur openssh-8.5p1.orig/ssh_api.c openssh-8.5p1/ssh_api.c ---- openssh-8.5p1.orig/ssh_api.c 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/ssh_api.c 2021-03-16 18:34:37.869116720 +0100 + /* Minimum amount of data to read at a time */ + #define MIN_READ_SIZE 512 +diff -Nur openssh-8.6p1.orig/ssh_api.c openssh-8.6p1/ssh_api.c +--- openssh-8.6p1.orig/ssh_api.c 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh_api.c 2021-05-22 08:24:33.557345635 +0200 @@ -410,7 +410,7 @@ char *cp; int r; @@ -2167,9 +2167,9 @@ diff -Nur openssh-8.5p1.orig/ssh_api.c openssh-8.5p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-8.5p1.orig/sshbuf.h openssh-8.5p1/sshbuf.h ---- openssh-8.5p1.orig/sshbuf.h 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sshbuf.h 2021-03-16 18:34:37.869116720 +0100 +diff -Nur openssh-8.6p1.orig/sshbuf.h openssh-8.6p1/sshbuf.h +--- openssh-8.6p1.orig/sshbuf.h 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sshbuf.h 2021-05-22 08:24:33.557345635 +0200 @@ -28,7 +28,7 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2179,9 +2179,9 @@ diff -Nur openssh-8.5p1.orig/sshbuf.h openssh-8.5p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c ---- openssh-8.5p1.orig/ssh.c 2021-03-16 18:30:25.485567150 +0100 -+++ openssh-8.5p1/ssh.c 2021-03-17 10:38:31.343325781 +0100 +diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c +--- openssh-8.6p1.orig/ssh.c 2021-05-22 08:23:21.066175754 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-22 08:24:33.558345637 +0200 @@ -1070,6 +1070,10 @@ break; case 'T': @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1792,6 +1796,8 @@ +@@ -1797,6 +1801,8 @@ setproctitle("%s [mux]", options.control_path); } @@ -2202,7 +2202,7 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) -@@ -2104,6 +2110,79 @@ +@@ -2109,6 +2115,79 @@ NULL, fileno(stdin), command, environ); } @@ -2282,9 +2282,9 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2130,9 +2209,11 @@ - if (!isatty(err)) - set_nonblock(err); +@@ -2127,9 +2206,11 @@ + if (in == -1 || out == -1 || err == -1) + fatal("dup() in/out/err failed"); - window = CHAN_SES_WINDOW_DEFAULT; + window = options.hpn_buffer_size; @@ -2295,7 +2295,7 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2143,6 +2224,11 @@ +@@ -2140,6 +2221,11 @@ debug3_f("channel_new: %d", c->self); @@ -2307,7 +2307,7 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c channel_send_open(ssh, c->self); if (!no_shell_flag) channel_register_open_confirm(ssh, c->self, -@@ -2157,6 +2243,13 @@ +@@ -2154,6 +2240,13 @@ int r, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -2321,9 +2321,9 @@ diff -Nur openssh-8.5p1.orig/ssh.c openssh-8.5p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c ---- openssh-8.5p1.orig/sshconnect2.c 2021-03-16 18:30:25.487567155 +0100 -+++ openssh-8.5p1/sshconnect2.c 2021-03-16 22:46:23.496061979 +0100 +diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1.orig/sshconnect2.c 2021-05-22 08:23:21.067175757 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-22 08:24:33.559345640 +0200 @@ -86,6 +86,13 @@ extern Options options; @@ -2412,10 +2412,10 @@ diff -Nur openssh-8.5p1.orig/sshconnect2.c openssh-8.5p1/sshconnect2.c debug("Authentication succeeded (%s).", authctxt.method->name); } -diff -Nur openssh-8.5p1.orig/sshconnect.c openssh-8.5p1/sshconnect.c ---- openssh-8.5p1.orig/sshconnect.c 2021-03-16 18:29:34.859456908 +0100 -+++ openssh-8.5p1/sshconnect.c 2021-03-17 21:07:43.343181602 +0100 -@@ -343,6 +343,30 @@ +diff -Nur openssh-8.6p1.orig/sshconnect.c openssh-8.6p1/sshconnect.c +--- openssh-8.6p1.orig/sshconnect.c 2021-05-22 08:23:20.987175569 +0200 ++++ openssh-8.6p1/sshconnect.c 2021-05-22 08:24:33.560345642 +0200 +@@ -345,6 +345,30 @@ #endif /* @@ -2446,7 +2446,7 @@ diff -Nur openssh-8.5p1.orig/sshconnect.c openssh-8.5p1/sshconnect.c * Creates a socket for use as the ssh connection. */ static int -@@ -364,6 +388,9 @@ +@@ -366,6 +390,9 @@ } fcntl(sock, F_SETFD, FD_CLOEXEC); @@ -2456,10 +2456,10 @@ diff -Nur openssh-8.5p1.orig/sshconnect.c openssh-8.5p1/sshconnect.c /* Use interactive QOS (if specified) until authentication completed */ if (options.ip_qos_interactive != INT_MAX) set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c ---- openssh-8.5p1.orig/sshd.c 2021-03-16 18:30:25.488567157 +0100 -+++ openssh-8.5p1/sshd.c 2021-03-16 19:28:51.437865785 +0100 -@@ -1106,6 +1106,8 @@ +diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c +--- openssh-8.6p1.orig/sshd.c 2021-05-22 08:23:21.068175759 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-22 08:24:33.561345644 +0200 +@@ -1107,6 +1107,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2468,7 +2468,7 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1151,6 +1153,11 @@ +@@ -1152,6 +1154,11 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -2480,7 +2480,7 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1828,6 +1835,19 @@ +@@ -1834,6 +1841,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2500,7 +2500,7 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2277,6 +2297,9 @@ +@@ -2285,6 +2305,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -2510,7 +2510,7 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -2389,6 +2412,25 @@ +@@ -2397,6 +2420,25 @@ /* Try to send all our hostkeys to the client */ notify_hostkeys(ssh); @@ -2536,7 +2536,7 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c /* Start session. */ do_authenticated(ssh, authctxt); -@@ -2462,6 +2504,11 @@ +@@ -2470,6 +2512,11 @@ struct kex *kex; int r; @@ -2548,9 +2548,9 @@ diff -Nur openssh-8.5p1.orig/sshd.c openssh-8.5p1/sshd.c myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, -diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config ---- openssh-8.5p1.orig/sshd_config 2021-03-16 18:30:25.488567157 +0100 -+++ openssh-8.5p1/sshd_config 2021-03-30 09:54:41.725605908 +0200 +diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config +--- openssh-8.6p1.orig/sshd_config 2021-05-22 08:23:21.068175759 +0200 ++++ openssh-8.6p1/sshd_config 2021-05-22 08:24:33.561345644 +0200 @@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2580,9 +2580,9 @@ diff -Nur openssh-8.5p1.orig/sshd_config openssh-8.5p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-8.5p1.orig/version.h openssh-8.5p1/version.h ---- openssh-8.5p1.orig/version.h 2021-03-16 18:30:25.490567161 +0100 -+++ openssh-8.5p1/version.h 2021-03-17 20:59:44.602187131 +0100 +diff -Nur openssh-8.6p1.orig/version.h openssh-8.6p1/version.h +--- openssh-8.6p1.orig/version.h 2021-05-22 08:23:21.069175761 +0200 ++++ openssh-8.6p1/version.h 2021-05-22 08:24:33.561345644 +0200 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" diff --git a/sources b/sources index 5c74840..cbbba40 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.5p1.tar.gz) = af9c34d89170a30fc92a63973e32c766ed4a6d254bb210e317c000d46913e78d0c60c7befe62d993d659be000b828b9d4d3832fc40df1c3d33850aaa6293846f -SHA512 (openssh-8.5p1.tar.gz.asc) = 264a991c7207f2215875e2b472a649ede1a69f6486d25777bf522047c26ea77c2995d34b6917a993ea9a250b7dd5298a30f1975e20e471f079c9064ce283cec2 +SHA512 (openssh-8.6p1.tar.gz) = 9854eda0b773c64c9f1f74844ce466b2b42ee8845f58ad062b73141d617af944fa4ebafdf72069f400106d2c2bd0a69c92fe805ec1fc26d4f0faadf06c3fbbe6 +SHA512 (openssh-8.6p1.tar.gz.asc) = ea75d7fe350fd1761ee5490b222249e9b8915b2a02a1d41979195f15d239def387e4c6467362ab9515d517087750fa66bc368f5baa15c325502f725172631967 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 3b5263e189f2b6b01152cb03ba6293a10074862d Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 21 Jun 2021 18:45:20 +0200 Subject: [PATCH 097/146] Based on openssh-8.6p1-4.fc34 --- gsi-openssh.spec | 5 +- openssh-8.0p1-restore-nonblock.patch | 357 ++++++++++++++++----------- 2 files changed, 222 insertions(+), 140 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index de76c03..cf39ddb 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.6p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -499,6 +499,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Mon Jun 21 2021 Mattias Ellert - 8.6p1-2 +- Based on openssh-8.6p1-4.fc34 + * Sat May 22 2021 Mattias Ellert - 8.6p1-1 - Based on openssh-8.6p1-3.fc35 diff --git a/openssh-8.0p1-restore-nonblock.patch b/openssh-8.0p1-restore-nonblock.patch index 9067d22..dbdf7ed 100644 --- a/openssh-8.0p1-restore-nonblock.patch +++ b/openssh-8.0p1-restore-nonblock.patch @@ -1,221 +1,300 @@ -diff -up openssh-8.6p1/channels.c.restore-nonblock openssh-8.6p1/channels.c ---- openssh-8.6p1/channels.c.restore-nonblock 2021-05-10 10:55:46.981156096 +0200 -+++ openssh-8.6p1/channels.c 2021-05-10 11:05:14.674641053 +0200 -@@ -298,32 +298,38 @@ channel_lookup(struct ssh *ssh, int id) - } - - /* -- * Register filedescriptors for a channel, used when allocating a channel or -- * when the channel consumer/producer is ready, e.g. shell exec'd -+ * Register a filedescriptor. - */ - static void --channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, -- int extusage, int nonblock, int is_tty) -+channel_register_fd(struct ssh *ssh, int fd, int nonblock) - { - struct ssh_channels *sc = ssh->chanctxt; - - /* Update the maximum file descriptor value. */ -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd); -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, wfd); -- sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, efd); -- -- if (rfd != -1) -- fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -- fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -- fcntl(efd, F_SETFD, FD_CLOEXEC); -+ sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, fd); -+ -+ if (fd != -1) -+ fcntl(fd, F_SETFD, FD_CLOEXEC); - -+ /* enable nonblocking mode */ -+ if (nonblock && fd != -1 && !isatty(fd)) -+ set_nonblock(fd); -+} -+ -+/* -+ * Register filedescriptors for a channel, used when allocating a channel or -+ * when the channel consumer/producer is ready, e.g. shell exec'd -+ */ -+static void -+channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, -+ int extusage, int nonblock, int is_tty) -+{ - c->rfd = rfd; - c->wfd = wfd; - c->sock = (rfd == wfd) ? rfd : -1; - c->efd = efd; - c->extended_usage = extusage; -+ c->nonblock = 0; - - if ((c->isatty = is_tty) != 0) - debug2("channel %d: rfd %d isatty", c->self, c->rfd); -@@ -332,14 +338,20 @@ channel_register_fds(struct ssh *ssh, Ch - c->wfd_isatty = is_tty || isatty(c->wfd); +diff --git a/channels.c b/channels.c +index 32d1f617..0024f751 100644 +--- a/channels.c ++++ b/channels.c +@@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, #endif -- /* enable nonblocking mode */ + /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -- set_nonblock(rfd); -- if (wfd != -1) -- set_nonblock(wfd); -- if (efd != -1) -- set_nonblock(efd); -+ if (rfd != -1) { -+ if ((fcntl(rfd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDIN_NONBLOCK; -+ channel_register_fd(ssh, rfd, nonblock); -+ } -+ if (wfd != -1 && wfd != rfd) { -+ if ((fcntl(wfd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDOUT_NONBLOCK; -+ channel_register_fd(ssh, wfd, nonblock); -+ } -+ if (efd != -1 && efd != rfd && efd != wfd) { -+ if ((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0) -+ c->nonblock |= NEED_RESTORE_STDERR_NONBLOCK; -+ channel_register_fd(ssh, efd, nonblock); - } - } - -@@ -422,11 +434,15 @@ channel_find_maxfd(struct ssh_channels * ++ c->restore_block = 0; ++ if (nonblock == CHANNEL_NONBLOCK_STDIO) { ++ /* ++ * Special handling for stdio file descriptors: do not set ++ * non-blocking mode if they are TTYs. Otherwise prepare to ++ * restore their blocking state on exit to avoid interfering ++ * with other programs that follow. ++ */ ++ if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_RFD; ++ set_nonblock(rfd); ++ } ++ if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_WFD; ++ set_nonblock(wfd); ++ } ++ if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) { ++ c->restore_block |= CHANNEL_RESTORE_EFD; ++ set_nonblock(efd); ++ } ++ } else if (nonblock) { + if (rfd != -1) + set_nonblock(rfd); + if (wfd != -1) +@@ -422,17 +442,23 @@ channel_find_maxfd(struct ssh_channels *sc) } int -channel_close_fd(struct ssh *ssh, int *fdp) -+channel_close_fd(struct ssh *ssh, int *fdp, int nonblock) ++channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) { struct ssh_channels *sc = ssh->chanctxt; - int ret = 0, fd = *fdp; +- int ret = 0, fd = *fdp; ++ int ret, fd = *fdp; -+ /* As the fd is duped, restoring the block mode -+ * affects the original fd */ -+ if (nonblock && fd != -1 && !isatty(fd)) -+ unset_nonblock(fd); - if (fd != -1) { - ret = close(fd); - *fdp = -1; -@@ -442,13 +458,13 @@ channel_close_fds(struct ssh *ssh, Chann +- if (fd != -1) { +- ret = close(fd); +- *fdp = -1; +- if (fd == sc->channel_max_fd) +- channel_find_maxfd(sc); +- } ++ if (fd == -1) ++ return 0; ++ ++ if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) || ++ (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) || ++ (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0)) ++ (void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */ ++ ++ ret = close(fd); ++ *fdp = -1; ++ if (fd == sc->channel_max_fd) ++ channel_find_maxfd(sc); + return ret; + } + +@@ -442,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Channel *c) { int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); if (rfd != sock) - channel_close_fd(ssh, &c->rfd); -+ channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK); ++ channel_close_fd(ssh, c, &c->rfd); if (wfd != sock && wfd != rfd) - channel_close_fd(ssh, &c->wfd); -+ channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK); ++ channel_close_fd(ssh, c, &c->wfd); if (efd != sock && efd != rfd && efd != wfd) - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } static void -@@ -702,7 +718,7 @@ channel_stop_listening(struct ssh *ssh) +@@ -702,7 +728,7 @@ channel_stop_listening(struct ssh *ssh) case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); channel_free(ssh, c); break; } -@@ -1649,7 +1665,7 @@ channel_post_x11_listener(struct ssh *ss +@@ -1491,7 +1517,8 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) + + Channel * + channel_connect_stdio_fwd(struct ssh *ssh, +- const char *host_to_connect, u_short port_to_connect, int in, int out) ++ const char *host_to_connect, u_short port_to_connect, ++ int in, int out, int nonblock) + { + Channel *c; + +@@ -1499,7 +1526,7 @@ channel_connect_stdio_fwd(struct ssh *ssh, + + c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, + -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, +- 0, "stdio-forward", /*nonblock*/0); ++ 0, "stdio-forward", nonblock); + + c->path = xstrdup(host_to_connect); + c->host_port = port_to_connect; +@@ -1649,7 +1676,7 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c, if (c->single_connection) { oerrno = errno; debug2("single_connection: closing X11 listener."); - channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, &c->sock, 0); ++ channel_close_fd(ssh, c, &c->sock); chan_mark_dead(ssh, c); errno = oerrno; } -@@ -2058,7 +2074,7 @@ channel_handle_efd_write(struct ssh *ssh +@@ -2058,7 +2085,7 @@ channel_handle_efd_write(struct ssh *ssh, Channel *c, return 1; if (len <= 0) { debug2("channel %d: closing write-efd %d", c->self, c->efd); - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } else { if ((r = sshbuf_consume(c->extended, len)) != 0) fatal_fr(r, "channel %i: consume", c->self); -@@ -2087,7 +2103,7 @@ channel_handle_efd_read(struct ssh *ssh, +@@ -2087,7 +2114,7 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c, return 1; if (len <= 0) { debug2("channel %d: closing read-efd %d", c->self, c->efd); - channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK); ++ channel_close_fd(ssh, c, &c->efd); } else if (c->extended_usage == CHAN_EXTENDED_IGNORE) debug3("channel %d: discard efd", c->self); else if ((r = sshbuf_put(c->extended, buf, len)) != 0) -diff -up openssh-8.6p1/channels.h.restore-nonblock openssh-8.6p1/channels.h ---- openssh-8.6p1/channels.h.restore-nonblock 2021-05-10 10:55:46.942155788 +0200 -+++ openssh-8.6p1/channels.h 2021-05-10 11:01:41.123953937 +0200 -@@ -188,8 +188,15 @@ struct Channel { - void *mux_ctx; - int mux_pause; - int mux_downstream_id; -+ -+ /* whether non-blocking is set to descriptors */ -+ int nonblock; - }; +diff --git a/channels.h b/channels.h +index 378d987c..6bf86b00 100644 +--- a/channels.h ++++ b/channels.h +@@ -63,6 +63,16 @@ -+#define NEED_RESTORE_STDIN_NONBLOCK 1 -+#define NEED_RESTORE_STDOUT_NONBLOCK 2 -+#define NEED_RESTORE_STDERR_NONBLOCK 4 + #define CHANNEL_CANCEL_PORT_STATIC -1 + ++/* nonblocking flags for channel_new */ ++#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */ ++#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */ ++#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */ + - #define CHAN_EXTENDED_IGNORE 0 - #define CHAN_EXTENDED_READ 1 - #define CHAN_EXTENDED_WRITE 2 -@@ -266,7 +273,7 @@ void channel_register_filter(struct ssh ++/* c->restore_block mask flags */ ++#define CHANNEL_RESTORE_RFD 0x01 ++#define CHANNEL_RESTORE_WFD 0x02 ++#define CHANNEL_RESTORE_EFD 0x04 ++ + /* TCP forwarding */ + #define FORWARD_DENY 0 + #define FORWARD_REMOTE (1) +@@ -139,6 +149,7 @@ struct Channel { + * to a matching pre-select handler. + * this way post-select handlers are not + * accidentally called if a FD gets reused */ ++ int restore_block; /* fd mask to restore blocking status */ + struct sshbuf *input; /* data read from socket, to be sent over + * encrypted connection */ + struct sshbuf *output; /* data received over encrypted connection for +@@ -266,7 +277,7 @@ void channel_register_filter(struct ssh *, int, channel_infilter_fn *, void channel_register_status_confirm(struct ssh *, int, channel_confirm_cb *, channel_confirm_abandon_cb *, void *); void channel_cancel_cleanup(struct ssh *, int); -int channel_close_fd(struct ssh *, int *); -+int channel_close_fd(struct ssh *, int *, int); ++int channel_close_fd(struct ssh *, Channel *, int *); void channel_send_window_changes(struct ssh *); /* mux proxy support */ -diff -up openssh-8.6p1/nchan.c.restore-nonblock openssh-8.6p1/nchan.c ---- openssh-8.6p1/nchan.c.restore-nonblock 2021-05-10 10:55:46.990156168 +0200 -+++ openssh-8.6p1/nchan.c 2021-05-10 11:03:46.679945863 +0200 -@@ -384,7 +384,7 @@ chan_shutdown_write(struct ssh *ssh, Cha +@@ -313,7 +324,7 @@ Channel *channel_connect_to_port(struct ssh *, const char *, u_short, + char *, char *, int *, const char **); + Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *); + Channel *channel_connect_stdio_fwd(struct ssh *, const char*, +- u_short, int, int); ++ u_short, int, int, int); + Channel *channel_connect_by_listen_address(struct ssh *, const char *, + u_short, char *, char *); + Channel *channel_connect_by_listen_path(struct ssh *, const char *, +diff --git a/clientloop.c b/clientloop.c +index 219f0e90..bdd67686 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -1405,14 +1405,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, + if (have_pty) + leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); + +- /* restore blocking io */ +- if (!isatty(fileno(stdin))) +- unset_nonblock(fileno(stdin)); +- if (!isatty(fileno(stdout))) +- unset_nonblock(fileno(stdout)); +- if (!isatty(fileno(stderr))) +- unset_nonblock(fileno(stderr)); +- + /* + * If there was no shell or command requested, there will be no remote + * exit status to be returned. In that case, clear error code if the +diff --git a/mux.c b/mux.c +index faf4ef1e..9454bfed 100644 +--- a/mux.c ++++ b/mux.c +@@ -452,14 +452,6 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error_f("tcgetattr: %s", strerror(errno)); + +- /* enable nonblocking unless tty */ +- if (!isatty(new_fd[0])) +- set_nonblock(new_fd[0]); +- if (!isatty(new_fd[1])) +- set_nonblock(new_fd[1]); +- if (!isatty(new_fd[2])) +- set_nonblock(new_fd[2]); +- + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (cctx->want_tty) { +@@ -469,7 +461,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, + + nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], window, packetmax, +- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); ++ CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); + + nc->ctl_chan = c->self; /* link session -> control channel */ + c->remote_id = nc->self; /* link control -> session channel */ +@@ -1025,13 +1017,8 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, + } + } + +- /* enable nonblocking unless tty */ +- if (!isatty(new_fd[0])) +- set_nonblock(new_fd[0]); +- if (!isatty(new_fd[1])) +- set_nonblock(new_fd[1]); +- +- nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); ++ nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1], ++ CHANNEL_NONBLOCK_STDIO); + free(chost); + + nc->ctl_chan = c->self; /* link session -> control channel */ +diff --git a/nchan.c b/nchan.c +index 4a4494b8..7ef3a350 100644 +--- a/nchan.c ++++ b/nchan.c +@@ -384,7 +384,7 @@ chan_shutdown_write(struct ssh *ssh, Channel *c) c->istate, c->ostate, strerror(errno)); } } else { - if (channel_close_fd(ssh, &c->wfd) < 0) { -+ if (channel_close_fd(ssh, &c->wfd, c->nonblock & NEED_RESTORE_STDOUT_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->wfd) < 0) { logit_f("channel %d: close() failed for " "fd %d [i%d o%d]: %.100s", c->self, c->wfd, c->istate, c->ostate, strerror(errno)); -@@ -412,7 +412,7 @@ chan_shutdown_read(struct ssh *ssh, Chan +@@ -412,7 +412,7 @@ chan_shutdown_read(struct ssh *ssh, Channel *c) c->istate, c->ostate, strerror(errno)); } } else { - if (channel_close_fd(ssh, &c->rfd) < 0) { -+ if (channel_close_fd(ssh, &c->rfd, c->nonblock & NEED_RESTORE_STDIN_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->rfd) < 0) { logit_f("channel %d: close() failed for " "fd %d [i%d o%d]: %.100s", c->self, c->rfd, c->istate, c->ostate, strerror(errno)); -@@ -431,7 +431,7 @@ chan_shutdown_extended_read(struct ssh * +@@ -431,7 +431,7 @@ chan_shutdown_extended_read(struct ssh *ssh, Channel *c) debug_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])", c->self, c->istate, c->ostate, c->sock, c->rfd, c->efd, channel_format_extended_usage(c)); - if (channel_close_fd(ssh, &c->efd) < 0) { -+ if (channel_close_fd(ssh, &c->efd, c->nonblock & NEED_RESTORE_STDERR_NONBLOCK) < 0) { ++ if (channel_close_fd(ssh, c, &c->efd) < 0) { logit_f("channel %d: close() failed for " "extended fd %d [i%d o%d]: %.100s", c->self, c->efd, c->istate, c->ostate, strerror(errno)); -diff -up openssh-8.6p1/ssh.c.restore-nonblock openssh-8.6p1/ssh.c ---- openssh-8.6p1/ssh.c.restore-nonblock 2021-05-10 10:55:46.991156175 +0200 -+++ openssh-8.6p1/ssh.c 2021-05-10 11:06:28.315222828 +0200 -@@ -2085,14 +2085,6 @@ ssh_session2_open(struct ssh *ssh) +diff --git a/ssh.c b/ssh.c +index 696dc3bc..6243db76 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -1876,9 +1876,10 @@ ssh_init_stdio_forwarding(struct ssh *ssh) + + if ((in = dup(STDIN_FILENO)) == -1 || + (out = dup(STDOUT_FILENO)) == -1) +- fatal("channel_connect_stdio_fwd: dup() in/out failed"); ++ fatal_f("dup() in/out failed"); + if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host, +- options.stdio_forward_port, in, out)) == NULL) ++ options.stdio_forward_port, in, out, ++ CHANNEL_NONBLOCK_STDIO)) == NULL) + fatal_f("channel_connect_stdio_fwd failed"); + channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); + channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); +@@ -2074,14 +2075,6 @@ ssh_session2_open(struct ssh *ssh) if (in == -1 || out == -1 || err == -1) fatal("dup() in/out/err failed"); @@ -230,12 +309,12 @@ diff -up openssh-8.6p1/ssh.c.restore-nonblock openssh-8.6p1/ssh.c window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { -@@ -2102,7 +2094,7 @@ ssh_session2_open(struct ssh *ssh) +@@ -2091,7 +2084,7 @@ ssh_session2_open(struct ssh *ssh) c = channel_new(ssh, "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, - "client-session", /*nonblock*/0); -+ "client-session", /*nonblock*/1); ++ "client-session", CHANNEL_NONBLOCK_STDIO); debug3_f("channel_new: %d", c->self); From 757dff8637c210836934934eedf0d9539b2934ff Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 21 Jun 2021 19:05:41 +0200 Subject: [PATCH 098/146] Based on openssh-8.6p1-5.fc35 --- gsi-openssh.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index cf39ddb..9a692e8 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.6p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -324,7 +324,8 @@ cp -p %{SOURCE99} . autoreconf %build -CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS +%set_build_flags +CFLAGS="$CFLAGS"; export CFLAGS %if %{pie} %ifarch s390 s390x sparc sparcv9 sparc64 CFLAGS="$CFLAGS -fPIC" @@ -499,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Mon Jun 21 2021 Mattias Ellert - 8.6p1-3 +- Based on openssh-8.6p1-5.fc35 + * Mon Jun 21 2021 Mattias Ellert - 8.6p1-2 - Based on openssh-8.6p1-4.fc34 From e6eac867a9e4eedf9a4b5c28154cae6a3335bda4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 22 Jul 2021 07:10:16 +0000 Subject: [PATCH 099/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9a692e8..afc427c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -500,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Thu Jul 22 2021 Fedora Release Engineering - 8.6p1-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Mon Jun 21 2021 Mattias Ellert - 8.6p1-3 - Based on openssh-8.6p1-5.fc35 From d614a17ecd98b5306643cab46b213d41f9bbafc1 Mon Sep 17 00:00:00 2001 From: Sahana Prasad Date: Tue, 14 Sep 2021 19:03:56 +0200 Subject: [PATCH 100/146] Rebuilt with OpenSSL 3.0.0 --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index afc427c..0d61b1f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist}.2 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -500,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Sep 14 2021 Sahana Prasad - 8.6p1-3.2 +- Rebuilt with OpenSSL 3.0.0 + * Thu Jul 22 2021 Fedora Release Engineering - 8.6p1-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From 568625900ef5c607a2c2596472fbc9f62ec571fe Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 24 Oct 2021 10:28:51 +0200 Subject: [PATCH 101/146] Based on openssh-8.7p1-2.fc35 --- gsi-openssh.spec | 22 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 8 +- openssh-6.6p1-kuserok.patch | 20 +- openssh-6.7p1-coverity.patch | 113 +++-- openssh-7.6p1-audit.patch | 17 +- openssh-7.7p1-gssapi-new-unique.patch | 12 +- openssh-7.8p1-UsePAM-warning.patch | 2 +- openssh-7.8p1-role-mls.patch | 2 +- openssh-8.0p1-crypto-policies.patch | 72 ++-- openssh-8.0p1-gssapi-keyex.patch | 88 ++-- openssh-8.0p1-pkcs11-uri.patch | 257 ++++++------ openssh-8.0p1-restore-nonblock.patch | 320 -------------- openssh-8.4p1-debian-compat.patch | 57 --- ...gsissh.patch => openssh-8.7p1-gsissh.patch | 348 ++++++++-------- ...h => openssh-8.7p1-hpn-15.2-modified.patch | 392 +++++++++--------- openssh-8.7p1-upstream-cve-2021-41617.patch | 31 ++ sources | 4 +- 17 files changed, 697 insertions(+), 1068 deletions(-) delete mode 100644 openssh-8.0p1-restore-nonblock.patch delete mode 100644 openssh-8.4p1-debian-compat.patch rename openssh-8.6p1-gsissh.patch => openssh-8.7p1-gsissh.patch (89%) rename openssh-8.6p1-hpn-15.2-modified.patch => openssh-8.7p1-hpn-15.2-modified.patch (88%) create mode 100644 openssh-8.7p1-upstream-cve-2021-41617.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 0d61b1f..5d75771 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,13 +27,13 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 8.6p1 -%global openssh_rel 3 +%global openssh_ver 8.7p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.2 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -146,24 +146,22 @@ Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 Patch966: openssh-8.2p1-x11-without-ipv6.patch # https://bugzilla.mindrot.org/show_bug.cgi?id=3213 -Patch969: openssh-8.4p1-debian-compat.patch -# ssh-keygen printing fingerprint issue with Windows keys (#1901518) Patch974: openssh-8.0p1-keygen-strip-doseol.patch # sshd provides PAM an incorrect error code (#1879503) Patch975: openssh-8.0p1-preserve-pam-errors.patch -# ssh incorrectly restores the blocking mode on standard output (#1942901) -Patch976: openssh-8.0p1-restore-nonblock.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 -Patch98: openssh-8.6p1-gsissh.patch +Patch98: openssh-8.7p1-gsissh.patch # This is the HPN patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-8.6p1-hpn-15.2-modified.patch +Patch99: openssh-8.7p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -299,10 +297,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch964 -p1 -b .openssl-kdf %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 -%patch969 -p0 -b .debian %patch974 -p1 -b .keygen-strip-doseol %patch975 -p1 -b .preserve-pam-errors -%patch976 -p1 -b .restore-nonblock +%patch978 -p1 -b .cve-2021-41617 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -500,6 +497,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Sun Oct 24 2021 Mattias Ellert - 8.7p1-1 +- Based on openssh-8.7p1-2.fc35 + * Tue Sep 14 2021 Sahana Prasad - 8.6p1-3.2 - Rebuilt with OpenSSL 3.0.0 diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 6ee2535..cccb3e0 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -28,7 +28,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + options->enable_k5users = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; + options->permit_empty_passwd = -1; @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption #endif if (options->use_kuserok == -1) @@ -72,9 +72,9 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + intptr = &options->enable_k5users; + goto parse_flag; + - case sPermitListen: - case sPermitOpen: - if (opcode == sPermitListen) { + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " @@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 407ff4c..1831f27 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -182,7 +182,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c + options->use_kuserok = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; + options->permit_empty_passwd = -1; @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption if (options->gss_kex_algorithms == NULL) options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); @@ -193,9 +193,9 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -399,7 +402,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sChallengeResponseAuthentication, @@ -217,16 +217,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions - *inc_flags &= ~SSHCFG_MATCH_ONLY; - break; - + } + break; + + case sKerberosUseKuserok: + intptr = &options->use_kuserok; + goto parse_flag; + - case sPermitListen: - case sPermitOpen: - if (opcode == sPermitListen) { + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " @@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 2814c6f..930de69 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -54,18 +54,6 @@ diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c --- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 -@@ -409,8 +409,10 @@ sshauthopt_parse(const char *opts, const - errstr = "invalid environment string"; - goto fail; - } -- if ((cp = strdup(opt)) == NULL) -+ if ((cp = strdup(opt)) == NULL) { -+ free(opt); - goto alloc_fail; -+ } - cp[tmp - opt] = '\0'; /* truncate at '=' */ - if (!valid_env_name(cp)) { - free(cp); @@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * return r; } @@ -133,13 +121,13 @@ diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c --- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 @@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname - &hostkey_digest_len, hostkey)) { - error("Error calculating key fingerprint."); - freerrset(fingerprints); + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating key fingerprint."); + freerrset(fingerprints); + free(dnskey_digest); - return -1; - } - } + return -1; + } + diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c --- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 +++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 @@ -316,6 +304,36 @@ diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/open int i; if (sa == NULL) { +diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c +--- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity 2021-08-30 16:36:11.357288009 +0200 ++++ openssh-8.7p1/openbsd-compat/bsd-pselect.c 2021-08-30 16:37:21.791897976 +0200 +@@ -113,13 +113,13 @@ pselect_notify_setup(void) + static void + pselect_notify_parent(void) + { +- if (notify_pipe[1] != -1) ++ if (notify_pipe[1] >= 0) + (void)write(notify_pipe[1], "", 1); + } + static void + pselect_notify_prepare(fd_set *readset) + { +- if (notify_pipe[0] != -1) ++ if (notify_pipe[0] >= 0) + FD_SET(notify_pipe[0], readset); + } + static void +@@ -127,8 +127,8 @@ pselect_notify_done(fd_set *readset) + { + char c; + +- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) { +- while (read(notify_pipe[0], &c, 1) != -1) ++ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) { ++ while (read(notify_pipe[0], &c, 1) >= 0) + debug2_f("reading"); + FD_CLR(notify_pipe[0], readset); + } diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c --- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100 +++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100 @@ -324,33 +342,29 @@ diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c error("%.200s line %d: glob failed for %s.", filename, linenum, arg2); + free(arg2); - return -1; + goto out; } free(arg2); -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) +diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200 ++++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200 +@@ -186,11 +186,11 @@ killchild(int signo) { if (do_cmd_pid > 1) { kill(do_cmd_pid, signo ? signo : SIGTERM); - waitpid(do_cmd_pid, NULL, 0); + (void) waitpid(do_cmd_pid, NULL, 0); } + if (do_cmd_pid2 > 1) { + kill(do_cmd_pid2, signo ? signo : SIGTERM); +- waitpid(do_cmd_pid2, NULL, 0); ++ (void) waitpid(do_cmd_pid2, NULL, 0); + } if (signo) diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 -@@ -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()); @@ -363,37 +377,10 @@ diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c } 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_f("reading"); - } - -@@ -518,7 +518,7 @@ server_request_tun(void) +diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c +--- openssh-8.7p1/serverloop.c.coverity 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/serverloop.c 2021-08-30 16:28:22.416226981 +0200 +@@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh) debug_f("invalid tun"); goto done; } diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index f3b1334..4473518 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -807,15 +807,6 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c --- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 +++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 -@@ -367,7 +367,7 @@ auth_log(struct ssh *ssh, int authentica - # endif - #endif - #ifdef SSH_AUDIT_EVENTS -- if (authenticated == 0 && !authctxt->postponed) -+ if (authenticated == 0 && !authctxt->postponed && !partial) - audit_event(ssh, audit_classify_auth(method)); - #endif - } @@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); @@ -1204,9 +1195,9 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3_f("%s %p signature %s%s%s", auth_method, key, - (ret == 0) ? "verified" : "unverified", - (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); + debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key), + (ret == 0) ? "verified" : "unverified", + (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); @@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } @@ -2065,7 +2056,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c close_startup_pipes(void) { @@ -377,18 +387,45 @@ grace_alarm_handler(int sig) - ssh_remote_port(the_active_state)); + } } -/* Destroy the host and server keys. They will no longer be needed. */ diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 387b7a0..c130022 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -504,15 +504,15 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c options->gss_authentication = 0; if (options->gss_keyex == -1) @@ -506,7 +509,8 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sChallengeResponseAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, + sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index 519ee29..8560c9f 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -18,7 +18,7 @@ diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config @@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication - # and ChallengeResponseAuthentication to 'no'. + # and KbdInteractiveAuthentication to 'no'. +# WARNING: 'UsePAM no' is not supported in Fedora and may cause several +# problems. #UsePAM no diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 145eac0..48f9f10 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -337,7 +337,7 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make --- 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-prngd.o \ port-solaris.o \ port-net.o \ - port-uw.o diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 4baa024..762825e 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 ---- openssh-8.6p1/ssh_config.5.crypto-policies 2021-04-19 15:18:32.071920379 +0200 -+++ openssh-8.6p1/ssh_config.5 2021-04-19 15:21:18.400179265 +0200 -@@ -368,15 +368,13 @@ or +diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 +--- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 ++++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 +@@ -373,17 +373,13 @@ or .Qq *.c.example.com domains. .It Cm CASignatureAlgorithms @@ -14,15 +14,17 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 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, +-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 - .Xr ssh 1 - will not accept host certificates signed using algorithms other than those - specified. -@@ -436,20 +434,25 @@ If the option is set to + If the specified list begins with a + .Sq + + character, then the specified algorithms will be appended to the default set +@@ -445,20 +441,25 @@ If the option is set to (the default), the check will not be executed. .It Cm Ciphers @@ -52,7 +54,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -465,13 +468,6 @@ aes256-gcm@openssh.com +@@ -474,13 +475,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .Ed .Pp @@ -66,7 +68,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -826,6 +822,11 @@ command line will be passed untouched to +@@ -874,6 +868,11 @@ command line will be passed untouched to The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -78,7 +80,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -838,10 +839,8 @@ gss-nistp256-sha256-, +@@ -886,10 +885,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp @@ -90,7 +92,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1169,29 +1168,25 @@ it may be zero or more of: +@@ -1219,29 +1216,25 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -129,7 +131,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1301,37 +1296,33 @@ function, and all code in the +@@ -1351,37 +1344,33 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -176,7 +178,7 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1503,37 +1494,25 @@ instead of continuing to execute and pas +@@ -1553,37 +1542,25 @@ instead of continuing to execute and pas The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -223,10 +225,10 @@ diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 ---- openssh-8.6p1/sshd_config.5.crypto-policies 2021-04-19 15:18:32.062920311 +0200 -+++ openssh-8.6p1/sshd_config.5 2021-04-19 15:20:42.591908243 +0200 -@@ -373,15 +373,13 @@ If the argument is +diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 +--- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 ++++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 +@@ -373,17 +373,13 @@ If the argument is then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -239,15 +241,17 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 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, +-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 - Certificates signed using other algorithms will not be accepted for - public key or host-based authentication. - .It Cm ChallengeResponseAuthentication -@@ -445,20 +443,25 @@ The default is + If the specified list begins with a + .Sq + + character, then the specified algorithms will be appended to the default set +@@ -450,20 +446,25 @@ The default is indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -277,7 +281,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -485,13 +488,6 @@ aes256-gcm@openssh.com +@@ -490,13 +491,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp @@ -291,7 +295,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -680,21 +676,22 @@ For this to work +@@ -685,21 +679,22 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -324,7 +328,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased -@@ -794,26 +791,13 @@ is specified, the location of the socket +@@ -799,26 +794,13 @@ is specified, the location of the socket .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -356,7 +360,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -958,20 +942,25 @@ Specifies whether to look at .k5login fi +@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi The default is .Cm yes . .It Cm KexAlgorithms @@ -386,7 +390,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1003,15 +992,6 @@ ecdh-sha2-nistp521 +@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El .Pp @@ -402,7 +406,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1097,21 +1077,26 @@ function, and all code in the +@@ -1104,21 +1082,26 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -433,7 +437,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1154,15 +1139,6 @@ umac-64-etm@openssh.com +@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -449,7 +453,7 @@ diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1541,37 +1517,25 @@ or equivalent.) +@@ -1548,37 +1522,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 2c29486..e26bebd 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -19,11 +19,10 @@ index e7549470..b68c1710 100644 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff --git a/auth.c b/auth.c -index 086b8ebb..687c57b4 100644 ---- a/auth.c -+++ b/auth.c -@@ -400,7 +400,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +diff -up a/auth.c.gsskex b/auth.c +--- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 +@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -33,18 +32,15 @@ index 086b8ebb..687c57b4 100644 return 1; break; case PERMIT_FORCED_ONLY: -@@ -724,99 +725,6 @@ fakepw(void) - return (&fake); +@@ -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 legacy rhosts-style authentication. -- * XXX is RhostsRSAAuthentication vulnerable to these? -- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) +- * attacks on based on conflation of hostnames and IP addresses. - */ - -static char * @@ -130,9 +126,10 @@ index 086b8ebb..687c57b4 100644 - 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 @@ -2913,10 +2910,9 @@ index 23ab096a..485590c1 100644 #endif #ifdef USE_PAM -diff --git a/readconf.c b/readconf.c -index f3cac6b3..da8022dd 100644 ---- a/readconf.c -+++ b/readconf.c +diff -up a/readconf.c.gsskex b/readconf.c +--- a/readconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/readconf.c 2021-08-27 12:25:42.556421509 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -2925,7 +2921,7 @@ index f3cac6b3..da8022dd 100644 /* Format of the configuration file: -@@ -160,6 +161,8 @@ typedef enum { +@@ -161,6 +162,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2934,7 +2930,7 @@ index f3cac6b3..da8022dd 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -204,10 +207,22 @@ static struct { +@@ -206,10 +209,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2957,7 +2953,7 @@ index f3cac6b3..da8022dd 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1029,10 +1044,42 @@ parse_time: +@@ -1113,10 +1128,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2986,7 +2982,7 @@ index f3cac6b3..da8022dd 100644 + goto parse_flag; + + case oGssKexAlgorithms: -+ arg = strdelim(&s); ++ arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); @@ -3000,9 +2996,9 @@ index f3cac6b3..da8022dd 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1911,7 +1958,13 @@ initialize_options(Options * options) +@@ -2306,7 +2353,13 @@ initialize_options(Options * options) + options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; - options->challenge_response_authentication = -1; options->gss_authentication = -1; + options->gss_keyex = -1; options->gss_deleg_creds = -1; @@ -3014,8 +3010,8 @@ index f3cac6b3..da8022dd 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2059,8 +2112,18 @@ fill_default_options(Options * options) - options->challenge_response_authentication = 1; +@@ -2463,8 +2516,18 @@ fill_default_options(Options * options) + options->pubkey_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) @@ -3033,7 +3029,7 @@ index f3cac6b3..da8022dd 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -2702,7 +2765,14 @@ dump_client_config(Options *o, const char *host) +@@ -3246,7 +3309,14 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3048,13 +3044,12 @@ index f3cac6b3..da8022dd 100644 #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff --git a/readconf.h b/readconf.h -index feedb3d2..a8a8870d 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -41,7 +41,13 @@ typedef struct { - int challenge_response_authentication; - /* Try S/Key or TIS, authentication. */ +diff -up a/readconf.h.gsskex b/readconf.h +--- a/readconf.h.gsskex 2021-08-27 12:05:29.248142431 +0200 ++++ b/readconf.h 2021-08-27 12:22:19.270679852 +0200 +@@ -39,7 +39,13 @@ typedef struct { + int pubkey_authentication; /* Try ssh2 pubkey authentication. */ + int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ + int gss_keyex; /* Try GSS key exchange */ int gss_deleg_creds; /* Delegate GSS credentials */ @@ -3066,11 +3061,10 @@ index feedb3d2..a8a8870d 100644 int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff --git a/servconf.c b/servconf.c -index 70f5f73f..191575a1 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -69,6 +69,7 @@ +diff -up a/servconf.c.gsskex b/servconf.c +--- a/servconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/servconf.c 2021-08-27 12:28:15.887735189 +0200 +@@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" @@ -3078,7 +3072,7 @@ index 70f5f73f..191575a1 100644 static void add_listen_addr(ServerOptions *, const char *, const char *, int); -@@ -133,8 +134,11 @@ initialize_server_options(ServerOptions *options) +@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3089,8 +3083,8 @@ index 70f5f73f..191575a1 100644 + options->gss_kex_algorithms = NULL; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; -@@ -375,10 +379,18 @@ fill_default_server_options(ServerOptions *options) + options->permit_empty_passwd = -1; +@@ -356,10 +360,18 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3109,7 +3103,7 @@ index 70f5f73f..191575a1 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -531,6 +543,7 @@ typedef enum { +@@ -506,6 +518,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3117,7 +3111,7 @@ index 70f5f73f..191575a1 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -607,12 +620,22 @@ static struct { +@@ -587,12 +600,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3139,8 +3133,8 @@ index 70f5f73f..191575a1 100644 + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, - { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1548,6 +1571,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, + { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ +@@ -1576,6 +1599,10 @@ process_server_config_line_depth(ServerO intptr = &options->gss_authentication; goto parse_flag; @@ -3151,7 +3145,7 @@ index 70f5f73f..191575a1 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1556,6 +1583,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1584,6 +1611,22 @@ process_server_config_line_depth(ServerO intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3160,7 +3154,7 @@ index 70f5f73f..191575a1 100644 + goto parse_flag; + + case sGssKexAlgorithms: -+ arg = strdelim(&cp); ++ arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); @@ -3174,7 +3168,7 @@ index 70f5f73f..191575a1 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2777,6 +2820,10 @@ dump_config(ServerOptions *o) +@@ -2892,6 +2935,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index dc8a7d0..8592607 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,7 +1,7 @@ -diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac ---- openssh-8.6p1/configure.ac.pkcs11-uri 2021-04-19 14:57:30.307370482 +0200 -+++ openssh-8.6p1/configure.ac 2021-04-19 14:57:30.315370543 +0200 -@@ -1974,12 +1974,14 @@ AC_LINK_IFELSE( +diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac +--- openssh-8.7p1/configure.ac.pkcs11-uri 2021-08-30 13:07:43.646699953 +0200 ++++ openssh-8.7p1/configure.ac 2021-08-30 13:07:43.662700088 +0200 +@@ -1985,12 +1985,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +16,7 @@ diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac fi ] ) -@@ -2008,6 +2010,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2019,6 +2021,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +57,7 @@ diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5564,6 +5600,7 @@ echo " BSD Auth support +@@ -5624,6 +5660,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,9 +65,9 @@ diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac echo " U2F/FIDO support: $enable_sk" echo "" -diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in ---- openssh-8.6p1/Makefile.in.pkcs11-uri 2021-04-19 14:57:30.261370134 +0200 -+++ openssh-8.6p1/Makefile.in 2021-04-19 15:14:38.916155695 +0200 +diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in +--- openssh-8.7p1/Makefile.in.pkcs11-uri 2021-08-30 13:07:43.571699324 +0200 ++++ openssh-8.7p1/Makefile.in 2021-08-30 13:07:43.663700096 +0200 @@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ @@ -77,7 +77,7 @@ diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -300,6 +300,8 @@ clean: regressclean +@@ -302,6 +302,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -86,7 +86,7 @@ diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -337,6 +339,8 @@ distclean: regressclean +@@ -339,6 +341,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -95,7 +95,7 @@ diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ -@@ -511,6 +515,7 @@ regress-prep: +@@ -513,6 +517,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -103,7 +103,7 @@ diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -674,6 +679,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT +@@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -120,17 +120,19 @@ diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ -@@ -709,6 +724,7 @@ regress-unit-binaries: regress-prep $(RE +@@ -711,7 +726,8 @@ regress-unit-binaries: regress-prep $(RE + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/sshsig/test_sshsig$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) \ +- regress/unittests/utf8/test_utf8$(EXEEXT) ++ regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ tests: file-tests t-exec interop-tests unit echo all tests passed -diff -up openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/agent-pkcs11.sh ---- openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/regress/agent-pkcs11.sh 2021-04-19 14:57:30.316370550 +0200 +diff -up openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/agent-pkcs11.sh +--- openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/agent-pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 @@ -113,7 +113,7 @@ else done @@ -140,10 +142,10 @@ diff -up openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/ r=$? if [ $r -ne 0 ]; then fail "ssh-add -e failed: exit code $r" -diff -up openssh-8.6p1/regress/Makefile.pkcs11-uri openssh-8.6p1/regress/Makefile ---- openssh-8.6p1/regress/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/regress/Makefile 2021-04-19 15:15:44.411651410 +0200 -@@ -119,7 +119,8 @@ CLEANFILES= *.core actual agent-key.* au +diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefile +--- openssh-8.7p1/regress/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/Makefile 2021-08-30 13:07:43.663700096 +0200 +@@ -122,7 +122,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -153,7 +155,7 @@ diff -up openssh-8.6p1/regress/Makefile.pkcs11-uri openssh-8.6p1/regress/Makefil rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -249,8 +250,9 @@ unit: +@@ -252,8 +253,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -165,9 +167,9 @@ diff -up openssh-8.6p1/regress/Makefile.pkcs11-uri openssh-8.6p1/regress/Makefil -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff -up openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/pkcs11.sh ---- openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri 2021-04-19 14:57:30.316370550 +0200 -+++ openssh-8.6p1/regress/pkcs11.sh 2021-04-19 14:57:30.316370550 +0200 +diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11.sh +--- openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri 2021-08-30 13:07:43.663700096 +0200 ++++ openssh-8.7p1/regress/pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -518,9 +520,9 @@ diff -up openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/pkcs11 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff -up openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri openssh-8.6p1/regress/unittests/Makefile ---- openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/regress/unittests/Makefile 2021-04-19 14:57:30.316370550 +0200 +diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regress/unittests/Makefile +--- openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/unittests/Makefile 2021-08-30 13:07:43.663700096 +0200 @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes @@ -529,9 +531,9 @@ diff -up openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri openssh-8.6p1/regre +SUBDIR+=authopt misc sshsig pkcs11 .include -diff -up openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.6p1/regress/unittests/pkcs11/tests.c ---- openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-04-19 14:57:30.317370558 +0200 -+++ openssh-8.6p1/regress/unittests/pkcs11/tests.c 2021-04-19 14:57:30.317370558 +0200 +diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c +--- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 ++++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat @@ -870,9 +872,9 @@ diff -up openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.6p1 + test_parse_invalid(); + test_generate_valid(); +} -diff -up openssh-8.6p1/ssh-add.c.pkcs11-uri openssh-8.6p1/ssh-add.c ---- openssh-8.6p1/ssh-add.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-add.c 2021-04-19 14:57:30.317370558 +0200 +diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c +--- openssh-8.7p1/ssh-add.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-add.c 2021-08-30 13:07:43.664700104 +0200 @@ -68,6 +68,7 @@ #include "digest.h" #include "ssh-sk.h" @@ -952,9 +954,9 @@ diff -up openssh-8.6p1/ssh-add.c.pkcs11-uri openssh-8.6p1/ssh-add.c ret = 1; goto done; } -diff -up openssh-8.6p1/ssh-agent.c.pkcs11-uri openssh-8.6p1/ssh-agent.c ---- openssh-8.6p1/ssh-agent.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-agent.c 2021-04-19 14:57:30.317370558 +0200 +diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c +--- openssh-8.7p1/ssh-agent.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-agent.c 2021-08-30 13:07:43.664700104 +0200 @@ -847,10 +847,72 @@ no_identities(SocketEntry *e) } @@ -1125,10 +1127,10 @@ diff -up openssh-8.6p1/ssh-agent.c.pkcs11-uri openssh-8.6p1/ssh-agent.c send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff -up openssh-8.6p1/ssh_config.5.pkcs11-uri openssh-8.6p1/ssh_config.5 ---- openssh-8.6p1/ssh_config.5.pkcs11-uri 2021-04-19 14:57:30.269370194 +0200 -+++ openssh-8.6p1/ssh_config.5 2021-04-19 14:57:30.321370588 +0200 -@@ -1063,6 +1063,21 @@ may also be used in conjunction with +diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 +--- openssh-8.7p1/ssh_config.5.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 ++++ openssh-8.7p1/ssh_config.5 2021-08-30 13:07:43.664700104 +0200 +@@ -1111,6 +1111,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -1150,10 +1152,10 @@ diff -up openssh-8.6p1/ssh_config.5.pkcs11-uri openssh-8.6p1/ssh_config.5 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. -diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c ---- openssh-8.6p1/ssh.c.pkcs11-uri 2021-04-19 14:57:30.269370194 +0200 -+++ openssh-8.6p1/ssh.c 2021-04-19 15:17:05.804267447 +0200 -@@ -843,6 +843,14 @@ main(int ac, char **av) +diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c +--- openssh-8.7p1/ssh.c.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 ++++ openssh-8.7p1/ssh.c 2021-08-30 13:07:43.666700121 +0200 +@@ -826,6 +826,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -1168,7 +1170,7 @@ diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1695,6 +1703,7 @@ main(int ac, char **av) +@@ -1681,6 +1689,7 @@ main(int ac, char **av) #ifdef ENABLE_PKCS11 (void)pkcs11_del_provider(options.pkcs11_provider); #endif @@ -1176,7 +1178,7 @@ diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c skip_connect: exit_status = ssh_session2(ssh, cinfo); -@@ -2211,6 +2220,45 @@ ssh_session2(struct ssh *ssh, const stru +@@ -2197,6 +2206,45 @@ ssh_session2(struct ssh *ssh, const stru options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -1222,7 +1224,7 @@ diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2225,11 +2273,6 @@ load_public_identity_files(const struct +@@ -2211,11 +2259,6 @@ load_public_identity_files(const struct char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -1234,7 +1236,7 @@ diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2242,33 +2285,46 @@ load_public_identity_files(const struct +@@ -2228,33 +2271,46 @@ load_public_identity_files(const struct sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -1300,9 +1302,9 @@ diff -up openssh-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); check_load(sshkey_load_public(filename, &public, NULL), -diff -up openssh-8.6p1/ssh-keygen.c.pkcs11-uri openssh-8.6p1/ssh-keygen.c ---- openssh-8.6p1/ssh-keygen.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-keygen.c 2021-04-19 14:57:30.318370565 +0200 +diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c +--- openssh-8.7p1/ssh-keygen.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-keygen.c 2021-08-30 13:07:43.666700121 +0200 @@ -860,8 +860,11 @@ do_download(struct passwd *pw) free(fp); } else { @@ -1317,9 +1319,9 @@ diff -up openssh-8.6p1/ssh-keygen.c.pkcs11-uri openssh-8.6p1/ssh-keygen.c } free(comments[i]); sshkey_free(keys[i]); -diff -up openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-client.c ---- openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-pkcs11-client.c 2021-04-19 14:57:30.318370565 +0200 +diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-client.c +--- openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11-client.c 2021-08-30 13:07:43.666700121 +0200 @@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi u_int nkeys, i; struct sshbuf *msg; @@ -1337,9 +1339,9 @@ diff -up openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-c for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c ---- openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-pkcs11.c 2021-04-19 14:57:30.320370580 +0200 +diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c +--- openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11.c 2021-08-30 13:12:27.709084157 +0200 @@ -55,8 +55,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1383,8 +1385,8 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_RV rv; CK_ULONG i; -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); +- debug_f("provider \"%s\" refcount %d valid %d", +- p->name, p->refcount, p->valid); - if (!p->valid) + debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); + if (!m->valid) @@ -1427,9 +1429,9 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c +} + +/* -+ * finalize a provider shared libarary, it's no longer usable. ++ * finalize a provider shared library, it's no longer usable. + * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * so the actual freeing of memory is handled by pkcs11_provider_unref(). + * this is called when a provider gets unregistered. + */ +static void @@ -1446,15 +1448,12 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c } /* -@@ -135,13 +178,11 @@ pkcs11_provider_finalize(struct pkcs11_p - static void - pkcs11_provider_unref(struct pkcs11_provider *p) +@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_prov { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug_f("%p refcount %d", p, p->refcount); + debug_f("provider \"%s\" refcount %d", p->name, p->refcount); if (--p->refcount <= 0) { - if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); +- error_f("provider \"%s\" still valid", p->name); free(p->name); - free(p->slotlist); - free(p->slotinfo); @@ -1543,7 +1542,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +283,55 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif @@ -1599,7 +1598,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c /* release a wrapped object */ static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +345,7 @@ pkcs11_k11_free(void *parent, void *ptr, +@@ -208,6 +348,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1607,7 +1606,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c free(k11); } -@@ -222,8 +360,8 @@ pkcs11_find(struct pkcs11_provider *p, C +@@ -222,8 +363,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1618,7 +1617,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -262,12 +400,12 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -262,12 +403,12 @@ pkcs11_login_slot(struct pkcs11_provider else { snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", si->token.label); @@ -1633,7 +1632,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); -@@ -297,13 +435,14 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -297,13 +438,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1650,7 +1649,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c } -@@ -319,13 +458,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs +@@ -319,13 +461,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -1668,7 +1667,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c attr.type = type; attr.pValue = &flag; -@@ -356,13 +496,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C +@@ -356,13 +499,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -1686,7 +1685,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +580,8 @@ pkcs11_rsa_private_encrypt(int flen, con +@@ -439,8 +583,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -1697,7 +1696,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +625,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -484,7 +628,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1706,7 +1705,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -502,6 +643,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * +@@ -502,6 +646,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1719,7 +1718,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -532,8 +679,8 @@ ecdsa_do_sign(const unsigned char *dgst, +@@ -532,8 +682,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -1730,7 +1729,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -598,7 +745,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -598,7 +748,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1739,7 +1738,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -614,6 +761,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider +@@ -614,6 +764,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); @@ -1752,7 +1751,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -650,8 +803,8 @@ pkcs11_open_session(struct pkcs11_provid +@@ -650,8 +806,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -1763,7 +1762,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -661,9 +814,9 @@ pkcs11_open_session(struct pkcs11_provid +@@ -661,9 +817,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -1775,7 +1774,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -699,7 +852,8 @@ static struct sshkey * +@@ -699,7 +855,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1785,7 +1784,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -713,14 +867,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -713,14 +870,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1806,7 +1805,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -731,19 +886,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -731,19 +889,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1830,7 +1829,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -755,8 +910,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -755,8 +913,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1841,7 +1840,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -767,13 +922,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -767,13 +925,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1858,7 +1857,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -790,7 +945,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -790,7 +948,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1867,7 +1866,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -806,7 +961,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -806,7 +964,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -1876,7 +1875,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -823,7 +978,8 @@ static struct sshkey * +@@ -823,7 +981,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1886,7 +1885,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -834,14 +990,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -834,14 +993,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1907,7 +1906,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -852,19 +1009,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -852,19 +1012,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1931,7 +1930,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -876,8 +1033,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -876,8 +1036,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -1942,7 +1941,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -886,7 +1043,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -886,7 +1046,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ @@ -1951,7 +1950,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -901,7 +1058,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -901,7 +1061,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -1960,7 +1959,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c free(key_attr[i].pValue); RSA_free(rsa); -@@ -912,7 +1069,8 @@ static int +@@ -912,7 +1072,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -1970,7 +1969,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -936,14 +1094,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -936,14 +1097,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -1991,7 +1990,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -955,18 +1114,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -955,18 +1117,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2014,7 +2013,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -980,8 +1140,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -980,8 +1143,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2025,7 +2024,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c error("d2i_x509 failed"); goto out; } -@@ -1001,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1001,7 +1164,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2034,7 +2033,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1031,7 +1191,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1031,7 +1194,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2043,7 +2042,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1051,7 +1211,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1051,7 +1214,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } out: @@ -2052,7 +2051,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1102,11 +1262,12 @@ note_key(struct pkcs11_provider *p, CK_U +@@ -1102,11 +1265,12 @@ note_key(struct pkcs11_provider *p, CK_U */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2067,7 +2066,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1123,10 +1284,23 @@ pkcs11_fetch_certs(struct pkcs11_provide +@@ -1123,10 +1287,23 @@ pkcs11_fetch_certs(struct pkcs11_provide key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2094,7 +2093,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1207,11 +1381,12 @@ fail: +@@ -1207,11 +1384,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2109,7 +2108,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1227,10 +1402,23 @@ pkcs11_fetch_keys(struct pkcs11_provider +@@ -1227,10 +1405,23 @@ pkcs11_fetch_keys(struct pkcs11_provider key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2127,16 +2126,16 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1499,16 +1687,10 @@ pkcs11_ecdsa_generate_private_key(struct +@@ -1499,16 +1690,10 @@ pkcs11_ecdsa_generate_private_key(struct } #endif /* WITH_PKCS11_KEYGEN */ @@ -2155,7 +2154,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1699,298 @@ pkcs11_register_provider(char *provider_ +@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2241,17 +2240,17 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ goto fail; ++ } + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { + debug_f("Skipping provider %s not matching library_manufacturer", + m->info.manufacturerID); -+ goto fail; -+ } + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", @@ -2529,7 +2528,7 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1683,7 +1999,37 @@ pkcs11_add_provider(char *provider_id, c +@@ -1683,7 +2002,37 @@ pkcs11_add_provider(char *provider_id, c pkcs11_provider_unref(p); } if (nkeys == 0) @@ -2568,9 +2567,9 @@ diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c return (nkeys); } -diff -up openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11.h ---- openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh-pkcs11.h 2021-04-19 14:57:30.320370580 +0200 +diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h +--- openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11.h 2021-08-30 13:07:43.666700121 +0200 @@ -22,10 +22,14 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 @@ -2586,9 +2585,9 @@ diff -up openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11.h #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff -up openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.c ---- openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-04-19 14:57:30.318370565 +0200 -+++ openssh-8.6p1/ssh-pkcs11-uri.c 2021-04-19 14:57:30.318370565 +0200 +diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c +--- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 ++++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3009,9 +3008,9 @@ diff -up openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri. +} + +#endif /* ENABLE_PKCS11 */ -diff -up openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.h ---- openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-04-19 14:57:30.318370565 +0200 -+++ openssh-8.6p1/ssh-pkcs11-uri.h 2021-04-19 14:57:30.318370565 +0200 +diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h +--- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 ++++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Red Hat diff --git a/openssh-8.0p1-restore-nonblock.patch b/openssh-8.0p1-restore-nonblock.patch deleted file mode 100644 index dbdf7ed..0000000 --- a/openssh-8.0p1-restore-nonblock.patch +++ /dev/null @@ -1,320 +0,0 @@ -diff --git a/channels.c b/channels.c -index 32d1f617..0024f751 100644 ---- a/channels.c -+++ b/channels.c -@@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, - #endif - - /* enable nonblocking mode */ -- if (nonblock) { -+ c->restore_block = 0; -+ if (nonblock == CHANNEL_NONBLOCK_STDIO) { -+ /* -+ * Special handling for stdio file descriptors: do not set -+ * non-blocking mode if they are TTYs. Otherwise prepare to -+ * restore their blocking state on exit to avoid interfering -+ * with other programs that follow. -+ */ -+ if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) { -+ c->restore_block |= CHANNEL_RESTORE_RFD; -+ set_nonblock(rfd); -+ } -+ if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) { -+ c->restore_block |= CHANNEL_RESTORE_WFD; -+ set_nonblock(wfd); -+ } -+ if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) { -+ c->restore_block |= CHANNEL_RESTORE_EFD; -+ set_nonblock(efd); -+ } -+ } else if (nonblock) { - if (rfd != -1) - set_nonblock(rfd); - if (wfd != -1) -@@ -422,17 +442,23 @@ channel_find_maxfd(struct ssh_channels *sc) - } - - int --channel_close_fd(struct ssh *ssh, int *fdp) -+channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) - { - struct ssh_channels *sc = ssh->chanctxt; -- int ret = 0, fd = *fdp; -+ int ret, fd = *fdp; - -- if (fd != -1) { -- ret = close(fd); -- *fdp = -1; -- if (fd == sc->channel_max_fd) -- channel_find_maxfd(sc); -- } -+ if (fd == -1) -+ return 0; -+ -+ if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) || -+ (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) || -+ (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0)) -+ (void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */ -+ -+ ret = close(fd); -+ *fdp = -1; -+ if (fd == sc->channel_max_fd) -+ channel_find_maxfd(sc); - return ret; - } - -@@ -442,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Channel *c) - { - int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; - -- channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, c, &c->sock); - if (rfd != sock) -- channel_close_fd(ssh, &c->rfd); -+ channel_close_fd(ssh, c, &c->rfd); - if (wfd != sock && wfd != rfd) -- channel_close_fd(ssh, &c->wfd); -+ channel_close_fd(ssh, c, &c->wfd); - if (efd != sock && efd != rfd && efd != wfd) -- channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, c, &c->efd); - } - - static void -@@ -702,7 +728,7 @@ channel_stop_listening(struct ssh *ssh) - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_UNIX_LISTENER: - case SSH_CHANNEL_RUNIX_LISTENER: -- channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, c, &c->sock); - channel_free(ssh, c); - break; - } -@@ -1491,7 +1517,8 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) - - Channel * - channel_connect_stdio_fwd(struct ssh *ssh, -- const char *host_to_connect, u_short port_to_connect, int in, int out) -+ const char *host_to_connect, u_short port_to_connect, -+ int in, int out, int nonblock) - { - Channel *c; - -@@ -1499,7 +1526,7 @@ channel_connect_stdio_fwd(struct ssh *ssh, - - c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, - -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, -- 0, "stdio-forward", /*nonblock*/0); -+ 0, "stdio-forward", nonblock); - - c->path = xstrdup(host_to_connect); - c->host_port = port_to_connect; -@@ -1649,7 +1676,7 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c, - if (c->single_connection) { - oerrno = errno; - debug2("single_connection: closing X11 listener."); -- channel_close_fd(ssh, &c->sock); -+ channel_close_fd(ssh, c, &c->sock); - chan_mark_dead(ssh, c); - errno = oerrno; - } -@@ -2058,7 +2085,7 @@ channel_handle_efd_write(struct ssh *ssh, Channel *c, - return 1; - if (len <= 0) { - debug2("channel %d: closing write-efd %d", c->self, c->efd); -- channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, c, &c->efd); - } else { - if ((r = sshbuf_consume(c->extended, len)) != 0) - fatal_fr(r, "channel %i: consume", c->self); -@@ -2087,7 +2114,7 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c, - return 1; - if (len <= 0) { - debug2("channel %d: closing read-efd %d", c->self, c->efd); -- channel_close_fd(ssh, &c->efd); -+ channel_close_fd(ssh, c, &c->efd); - } else if (c->extended_usage == CHAN_EXTENDED_IGNORE) - debug3("channel %d: discard efd", c->self); - else if ((r = sshbuf_put(c->extended, buf, len)) != 0) -diff --git a/channels.h b/channels.h -index 378d987c..6bf86b00 100644 ---- a/channels.h -+++ b/channels.h -@@ -63,6 +63,16 @@ - - #define CHANNEL_CANCEL_PORT_STATIC -1 - -+/* nonblocking flags for channel_new */ -+#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */ -+#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */ -+#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */ -+ -+/* c->restore_block mask flags */ -+#define CHANNEL_RESTORE_RFD 0x01 -+#define CHANNEL_RESTORE_WFD 0x02 -+#define CHANNEL_RESTORE_EFD 0x04 -+ - /* TCP forwarding */ - #define FORWARD_DENY 0 - #define FORWARD_REMOTE (1) -@@ -139,6 +149,7 @@ struct Channel { - * to a matching pre-select handler. - * this way post-select handlers are not - * accidentally called if a FD gets reused */ -+ int restore_block; /* fd mask to restore blocking status */ - struct sshbuf *input; /* data read from socket, to be sent over - * encrypted connection */ - struct sshbuf *output; /* data received over encrypted connection for -@@ -266,7 +277,7 @@ void channel_register_filter(struct ssh *, int, channel_infilter_fn *, - void channel_register_status_confirm(struct ssh *, int, - channel_confirm_cb *, channel_confirm_abandon_cb *, void *); - void channel_cancel_cleanup(struct ssh *, int); --int channel_close_fd(struct ssh *, int *); -+int channel_close_fd(struct ssh *, Channel *, int *); - void channel_send_window_changes(struct ssh *); - - /* mux proxy support */ -@@ -313,7 +324,7 @@ Channel *channel_connect_to_port(struct ssh *, const char *, u_short, - char *, char *, int *, const char **); - Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *); - Channel *channel_connect_stdio_fwd(struct ssh *, const char*, -- u_short, int, int); -+ u_short, int, int, int); - Channel *channel_connect_by_listen_address(struct ssh *, const char *, - u_short, char *, char *); - Channel *channel_connect_by_listen_path(struct ssh *, const char *, -diff --git a/clientloop.c b/clientloop.c -index 219f0e90..bdd67686 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -1405,14 +1405,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, - if (have_pty) - leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); - -- /* restore blocking io */ -- if (!isatty(fileno(stdin))) -- unset_nonblock(fileno(stdin)); -- if (!isatty(fileno(stdout))) -- unset_nonblock(fileno(stdout)); -- if (!isatty(fileno(stderr))) -- unset_nonblock(fileno(stderr)); -- - /* - * If there was no shell or command requested, there will be no remote - * exit status to be returned. In that case, clear error code if the -diff --git a/mux.c b/mux.c -index faf4ef1e..9454bfed 100644 ---- a/mux.c -+++ b/mux.c -@@ -452,14 +452,6 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, - if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) - error_f("tcgetattr: %s", strerror(errno)); - -- /* enable nonblocking unless tty */ -- if (!isatty(new_fd[0])) -- set_nonblock(new_fd[0]); -- if (!isatty(new_fd[1])) -- set_nonblock(new_fd[1]); -- if (!isatty(new_fd[2])) -- set_nonblock(new_fd[2]); -- - window = CHAN_SES_WINDOW_DEFAULT; - packetmax = CHAN_SES_PACKET_DEFAULT; - if (cctx->want_tty) { -@@ -469,7 +461,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, - - nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, - new_fd[0], new_fd[1], new_fd[2], window, packetmax, -- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); -+ CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); - - nc->ctl_chan = c->self; /* link session -> control channel */ - c->remote_id = nc->self; /* link control -> session channel */ -@@ -1025,13 +1017,8 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, - } - } - -- /* enable nonblocking unless tty */ -- if (!isatty(new_fd[0])) -- set_nonblock(new_fd[0]); -- if (!isatty(new_fd[1])) -- set_nonblock(new_fd[1]); -- -- nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); -+ nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1], -+ CHANNEL_NONBLOCK_STDIO); - free(chost); - - nc->ctl_chan = c->self; /* link session -> control channel */ -diff --git a/nchan.c b/nchan.c -index 4a4494b8..7ef3a350 100644 ---- a/nchan.c -+++ b/nchan.c -@@ -384,7 +384,7 @@ chan_shutdown_write(struct ssh *ssh, Channel *c) - c->istate, c->ostate, strerror(errno)); - } - } else { -- if (channel_close_fd(ssh, &c->wfd) < 0) { -+ if (channel_close_fd(ssh, c, &c->wfd) < 0) { - logit_f("channel %d: close() failed for " - "fd %d [i%d o%d]: %.100s", c->self, c->wfd, - c->istate, c->ostate, strerror(errno)); -@@ -412,7 +412,7 @@ chan_shutdown_read(struct ssh *ssh, Channel *c) - c->istate, c->ostate, strerror(errno)); - } - } else { -- if (channel_close_fd(ssh, &c->rfd) < 0) { -+ if (channel_close_fd(ssh, c, &c->rfd) < 0) { - logit_f("channel %d: close() failed for " - "fd %d [i%d o%d]: %.100s", c->self, c->rfd, - c->istate, c->ostate, strerror(errno)); -@@ -431,7 +431,7 @@ chan_shutdown_extended_read(struct ssh *ssh, Channel *c) - debug_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])", - c->self, c->istate, c->ostate, c->sock, c->rfd, c->efd, - channel_format_extended_usage(c)); -- if (channel_close_fd(ssh, &c->efd) < 0) { -+ if (channel_close_fd(ssh, c, &c->efd) < 0) { - logit_f("channel %d: close() failed for " - "extended fd %d [i%d o%d]: %.100s", c->self, c->efd, - c->istate, c->ostate, strerror(errno)); -diff --git a/ssh.c b/ssh.c -index 696dc3bc..6243db76 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -1876,9 +1876,10 @@ ssh_init_stdio_forwarding(struct ssh *ssh) - - if ((in = dup(STDIN_FILENO)) == -1 || - (out = dup(STDOUT_FILENO)) == -1) -- fatal("channel_connect_stdio_fwd: dup() in/out failed"); -+ fatal_f("dup() in/out failed"); - if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host, -- options.stdio_forward_port, in, out)) == NULL) -+ options.stdio_forward_port, in, out, -+ CHANNEL_NONBLOCK_STDIO)) == NULL) - fatal_f("channel_connect_stdio_fwd failed"); - channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); - channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); -@@ -2074,14 +2075,6 @@ ssh_session2_open(struct ssh *ssh) - if (in == -1 || out == -1 || err == -1) - fatal("dup() in/out/err failed"); - -- /* enable nonblocking unless tty */ -- if (!isatty(in)) -- set_nonblock(in); -- if (!isatty(out)) -- set_nonblock(out); -- if (!isatty(err)) -- set_nonblock(err); -- - window = CHAN_SES_WINDOW_DEFAULT; - packetmax = CHAN_SES_PACKET_DEFAULT; - if (tty_flag) { -@@ -2091,7 +2084,7 @@ ssh_session2_open(struct ssh *ssh) - c = channel_new(ssh, - "session", SSH_CHANNEL_OPENING, in, out, err, - window, packetmax, CHAN_EXTENDED_WRITE, -- "client-session", /*nonblock*/0); -+ "client-session", CHANNEL_NONBLOCK_STDIO); - - debug3_f("channel_new: %d", c->self); - diff --git a/openssh-8.4p1-debian-compat.patch b/openssh-8.4p1-debian-compat.patch deleted file mode 100644 index 1285979..0000000 --- a/openssh-8.4p1-debian-compat.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- 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 && (ssh->compat & SSH_BUG_SIGTYPE74))) { -+ oallowed = allowed = xstrdup(options.pubkey_accepted_algos); -+ 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; - } - - diff --git a/openssh-8.6p1-gsissh.patch b/openssh-8.7p1-gsissh.patch similarity index 89% rename from openssh-8.6p1-gsissh.patch rename to openssh-8.7p1-gsissh.patch index 685dcd9..f19161c 100644 --- a/openssh-8.6p1-gsissh.patch +++ b/openssh-8.7p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c ---- openssh-8.6p1.orig/auth2.c 2021-05-04 10:47:33.443951396 +0200 -+++ openssh-8.6p1/auth2.c 2021-05-04 10:48:29.601078299 +0200 +diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c +--- openssh-8.7p1.orig/auth2.c 2021-10-24 07:32:35.517723813 +0200 ++++ openssh-8.7p1/auth2.c 2021-10-24 07:33:38.862876709 +0200 @@ -277,7 +277,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -100,9 +100,9 @@ diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.6p1.orig/auth2-gss.c openssh-8.6p1/auth2-gss.c ---- openssh-8.6p1.orig/auth2-gss.c 2021-05-04 10:47:33.342951168 +0200 -+++ openssh-8.6p1/auth2-gss.c 2021-05-04 10:48:29.602078301 +0200 +diff -Nur openssh-8.7p1.orig/auth2-gss.c openssh-8.7p1/auth2-gss.c +--- openssh-8.7p1.orig/auth2-gss.c 2021-10-24 07:32:35.388723503 +0200 ++++ openssh-8.7p1/auth2-gss.c 2021-10-24 07:33:38.863876712 +0200 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -307,9 +307,9 @@ diff -Nur openssh-8.6p1.orig/auth2-gss.c openssh-8.6p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.6p1.orig/auth.c openssh-8.6p1/auth.c ---- openssh-8.6p1.orig/auth.c 2021-05-04 10:47:33.445951400 +0200 -+++ openssh-8.6p1/auth.c 2021-05-04 10:48:29.603078303 +0200 +diff -Nur openssh-8.7p1.orig/auth.c openssh-8.7p1/auth.c +--- openssh-8.7p1.orig/auth.c 2021-10-24 07:32:35.519723818 +0200 ++++ openssh-8.7p1/auth.c 2021-10-24 07:33:38.864876714 +0200 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -320,7 +320,7 @@ diff -Nur openssh-8.6p1.orig/auth.c openssh-8.6p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -586,13 +587,18 @@ +@@ -588,13 +589,18 @@ #endif pw = getpwnam(user); @@ -340,9 +340,9 @@ diff -Nur openssh-8.6p1.orig/auth.c openssh-8.6p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.6p1.orig/auth.h openssh-8.6p1/auth.h ---- openssh-8.6p1.orig/auth.h 2021-05-04 10:47:33.445951400 +0200 -+++ openssh-8.6p1/auth.h 2021-05-04 10:48:29.603078303 +0200 +diff -Nur openssh-8.7p1.orig/auth.h openssh-8.7p1/auth.h +--- openssh-8.7p1.orig/auth.h 2021-10-24 07:32:35.519723818 +0200 ++++ openssh-8.7p1/auth.h 2021-10-24 07:33:38.864876714 +0200 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +352,9 @@ diff -Nur openssh-8.6p1.orig/auth.h openssh-8.6p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.6p1.orig/auth-pam.c openssh-8.6p1/auth-pam.c ---- openssh-8.6p1.orig/auth-pam.c 2021-05-04 10:47:33.440951389 +0200 -+++ openssh-8.6p1/auth-pam.c 2021-05-04 10:48:29.604078305 +0200 +diff -Nur openssh-8.7p1.orig/auth-pam.c openssh-8.7p1/auth-pam.c +--- openssh-8.7p1.orig/auth-pam.c 2021-10-24 07:32:35.510723796 +0200 ++++ openssh-8.7p1/auth-pam.c 2021-10-24 07:33:38.865876716 +0200 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -515,9 +515,9 @@ diff -Nur openssh-8.6p1.orig/auth-pam.c openssh-8.6p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.6p1.orig/auth-pam.h openssh-8.6p1/auth-pam.h ---- openssh-8.6p1.orig/auth-pam.h 2021-05-04 10:47:33.303951079 +0200 -+++ openssh-8.6p1/auth-pam.h 2021-05-04 10:48:29.604078305 +0200 +diff -Nur openssh-8.7p1.orig/auth-pam.h openssh-8.7p1/auth-pam.h +--- openssh-8.7p1.orig/auth-pam.h 2021-10-24 07:32:35.356723425 +0200 ++++ openssh-8.7p1/auth-pam.h 2021-10-24 07:33:38.865876716 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +525,9 @@ diff -Nur openssh-8.6p1.orig/auth-pam.h openssh-8.6p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.6p1.orig/canohost.c openssh-8.6p1/canohost.c ---- openssh-8.6p1.orig/canohost.c 2021-05-04 10:47:33.343951170 +0200 -+++ openssh-8.6p1/canohost.c 2021-05-04 10:48:29.605078308 +0200 +diff -Nur openssh-8.7p1.orig/canohost.c openssh-8.7p1/canohost.c +--- openssh-8.7p1.orig/canohost.c 2021-10-24 07:32:35.388723503 +0200 ++++ openssh-8.7p1/canohost.c 2021-10-24 07:33:38.866876718 +0200 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +570,9 @@ diff -Nur openssh-8.6p1.orig/canohost.c openssh-8.6p1/canohost.c + } + } +} -diff -Nur openssh-8.6p1.orig/canohost.h openssh-8.6p1/canohost.h ---- openssh-8.6p1.orig/canohost.h 2021-05-04 10:47:33.343951170 +0200 -+++ openssh-8.6p1/canohost.h 2021-05-04 10:48:29.605078308 +0200 +diff -Nur openssh-8.7p1.orig/canohost.h openssh-8.7p1/canohost.h +--- openssh-8.7p1.orig/canohost.h 2021-10-24 07:32:35.388723503 +0200 ++++ openssh-8.7p1/canohost.h 2021-10-24 07:33:38.866876718 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,25 +580,25 @@ diff -Nur openssh-8.6p1.orig/canohost.h openssh-8.6p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.6p1.orig/configure.ac openssh-8.6p1/configure.ac ---- openssh-8.6p1.orig/configure.ac 2021-05-04 10:47:33.430951367 +0200 -+++ openssh-8.6p1/configure.ac 2021-05-04 10:48:29.607078312 +0200 -@@ -4718,6 +4718,14 @@ - AC_CHECK_HEADER([gssapi_krb5.h], , - [ CPPFLAGS="$oldCPP" ]) +diff -Nur openssh-8.7p1.orig/configure.ac openssh-8.7p1/configure.ac +--- openssh-8.7p1.orig/configure.ac 2021-10-24 07:32:35.498723767 +0200 ++++ openssh-8.7p1/configure.ac 2021-10-24 07:49:48.431180638 +0200 +@@ -4777,6 +4777,14 @@ + AC_CHECK_HEADER([gssapi_krb5.h], , + [ CPPFLAGS="$oldCPP" ]) -+ # If we're using some other GSSAPI -+ if test -n "$GSSAPI" ; then -+ AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Kerberos GSI.]) -+ fi -+ -+ if test -z "$GSSAPI"; then -+ GSSAPI="KRB5"; -+ fi ++ # If we're using some other GSSAPI ++ if test -n "$GSSAPI" ; then ++ AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Kerberos GSI.]) ++ fi ++ ++ if test -z "$GSSAPI"; then ++ GSSAPI="KRB5"; ++ fi + fi fi if test -n "${rpath_opt}" ; then - LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib" -@@ -4757,6 +4765,40 @@ +@@ -4817,6 +4825,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,9 +639,9 @@ diff -Nur openssh-8.6p1.orig/configure.ac openssh-8.6p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.6p1.orig/gss-genr.c openssh-8.6p1/gss-genr.c ---- openssh-8.6p1.orig/gss-genr.c 2021-05-04 10:47:33.465951446 +0200 -+++ openssh-8.6p1/gss-genr.c 2021-05-04 10:48:29.607078312 +0200 +diff -Nur openssh-8.7p1.orig/gss-genr.c openssh-8.7p1/gss-genr.c +--- openssh-8.7p1.orig/gss-genr.c 2021-10-24 07:32:35.551723895 +0200 ++++ openssh-8.7p1/gss-genr.c 2021-10-24 07:33:38.870876728 +0200 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -678,9 +678,9 @@ diff -Nur openssh-8.6p1.orig/gss-genr.c openssh-8.6p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.6p1.orig/gss-serv.c openssh-8.6p1/gss-serv.c ---- openssh-8.6p1.orig/gss-serv.c 2021-05-04 10:47:33.369951229 +0200 -+++ openssh-8.6p1/gss-serv.c 2021-05-04 10:48:29.608078315 +0200 +diff -Nur openssh-8.7p1.orig/gss-serv.c openssh-8.7p1/gss-serv.c +--- openssh-8.7p1.orig/gss-serv.c 2021-10-24 07:32:35.410723555 +0200 ++++ openssh-8.7p1/gss-serv.c 2021-10-24 07:33:38.870876728 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +961,9 @@ diff -Nur openssh-8.6p1.orig/gss-serv.c openssh-8.6p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.6p1.orig/gss-serv-gsi.c openssh-8.6p1/gss-serv-gsi.c ---- openssh-8.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.6p1/gss-serv-gsi.c 2021-05-04 10:48:29.609078317 +0200 +diff -Nur openssh-8.7p1.orig/gss-serv-gsi.c openssh-8.7p1/gss-serv-gsi.c +--- openssh-8.7p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.7p1/gss-serv-gsi.c 2021-10-24 07:33:38.871876730 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1293,9 @@ diff -Nur openssh-8.6p1.orig/gss-serv-gsi.c openssh-8.6p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.6p1.orig/gss-serv-krb5.c openssh-8.6p1/gss-serv-krb5.c ---- openssh-8.6p1.orig/gss-serv-krb5.c 2021-05-04 10:47:33.392951281 +0200 -+++ openssh-8.6p1/gss-serv-krb5.c 2021-05-04 10:48:29.609078317 +0200 +diff -Nur openssh-8.7p1.orig/gss-serv-krb5.c openssh-8.7p1/gss-serv-krb5.c +--- openssh-8.7p1.orig/gss-serv-krb5.c 2021-10-24 07:32:35.440723628 +0200 ++++ openssh-8.7p1/gss-serv-krb5.c 2021-10-24 07:33:38.871876730 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1349,9 @@ diff -Nur openssh-8.6p1.orig/gss-serv-krb5.c openssh-8.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.6p1.orig/kexgsss.c openssh-8.6p1/kexgsss.c ---- openssh-8.6p1.orig/kexgsss.c 2021-05-04 10:47:33.475951468 +0200 -+++ openssh-8.6p1/kexgsss.c 2021-05-04 10:48:29.609078317 +0200 +diff -Nur openssh-8.7p1.orig/kexgsss.c openssh-8.7p1/kexgsss.c +--- openssh-8.7p1.orig/kexgsss.c 2021-10-24 07:32:35.567723933 +0200 ++++ openssh-8.7p1/kexgsss.c 2021-10-24 07:33:38.871876730 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1415,9 +1415,9 @@ diff -Nur openssh-8.6p1.orig/kexgsss.c openssh-8.6p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in ---- openssh-8.6p1.orig/Makefile.in 2021-05-04 10:47:33.447951405 +0200 -+++ openssh-8.6p1/Makefile.in 2021-05-04 10:48:29.610078319 +0200 +diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in +--- openssh-8.7p1.orig/Makefile.in 2021-10-24 07:32:35.522723825 +0200 ++++ openssh-8.7p1/Makefile.in 2021-10-24 07:33:38.872876733 +0200 @@ -128,6 +128,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1426,10 +1426,10 @@ diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.6p1.orig/misc.c openssh-8.6p1/misc.c ---- openssh-8.6p1.orig/misc.c 2021-05-04 10:47:33.466951448 +0200 -+++ openssh-8.6p1/misc.c 2021-05-04 10:48:29.612078324 +0200 -@@ -378,11 +378,14 @@ +diff -Nur openssh-8.7p1.orig/misc.c openssh-8.7p1/misc.c +--- openssh-8.7p1.orig/misc.c 2021-10-24 07:32:35.553723900 +0200 ++++ openssh-8.7p1/misc.c 2021-10-24 07:33:38.873876735 +0200 +@@ -393,11 +393,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1445,7 +1445,7 @@ diff -Nur openssh-8.6p1.orig/misc.c openssh-8.6p1/misc.c int wspace = 0; if (*s == NULL) -@@ -390,6 +393,21 @@ +@@ -405,6 +408,21 @@ old = *s; @@ -1467,7 +1467,7 @@ diff -Nur openssh-8.6p1.orig/misc.c openssh-8.6p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -465,6 +483,20 @@ +@@ -480,6 +498,20 @@ return copy; } @@ -1488,10 +1488,10 @@ diff -Nur openssh-8.6p1.orig/misc.c openssh-8.6p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.6p1.orig/misc.h openssh-8.6p1/misc.h ---- openssh-8.6p1.orig/misc.h 2021-05-04 10:47:33.408951317 +0200 -+++ openssh-8.6p1/misc.h 2021-05-04 10:48:29.612078324 +0200 -@@ -98,6 +98,7 @@ +diff -Nur openssh-8.7p1.orig/misc.h openssh-8.7p1/misc.h +--- openssh-8.7p1.orig/misc.h 2021-10-24 07:32:35.466723690 +0200 ++++ openssh-8.7p1/misc.h 2021-10-24 07:33:38.874876737 +0200 +@@ -100,6 +100,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1499,10 +1499,10 @@ diff -Nur openssh-8.6p1.orig/misc.h openssh-8.6p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c ---- openssh-8.6p1.orig/monitor.c 2021-05-04 10:47:33.467951450 +0200 -+++ openssh-8.6p1/monitor.c 2021-05-04 10:48:29.614078329 +0200 -@@ -154,6 +154,9 @@ +diff -Nur openssh-8.7p1.orig/monitor.c openssh-8.7p1/monitor.c +--- openssh-8.7p1.orig/monitor.c 2021-10-24 07:32:35.554723902 +0200 ++++ openssh-8.7p1/monitor.c 2021-10-24 07:33:38.875876740 +0200 +@@ -152,6 +152,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1512,7 +1512,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -206,7 +209,7 @@ +@@ -204,7 +207,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1521,7 +1521,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -214,7 +217,7 @@ +@@ -212,7 +215,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1530,7 +1530,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -238,8 +241,11 @@ +@@ -236,8 +239,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1543,7 +1543,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -249,6 +255,8 @@ +@@ -247,6 +253,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1552,7 +1552,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -329,6 +337,8 @@ +@@ -327,6 +335,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1561,7 +1561,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -446,6 +456,8 @@ +@@ -444,6 +454,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1570,7 +1570,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -762,15 +774,18 @@ +@@ -760,15 +772,18 @@ debug3_f("entering"); @@ -1592,7 +1592,7 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); -@@ -2113,6 +2128,79 @@ +@@ -2109,6 +2124,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.6p1.orig/monitor.c openssh-8.6p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.6p1.orig/monitor.h openssh-8.6p1/monitor.h ---- openssh-8.6p1.orig/monitor.h 2021-05-04 10:47:33.447951405 +0200 -+++ openssh-8.6p1/monitor.h 2021-05-04 10:48:29.614078329 +0200 +diff -Nur openssh-8.7p1.orig/monitor.h openssh-8.7p1/monitor.h +--- openssh-8.7p1.orig/monitor.h 2021-10-24 07:32:35.523723828 +0200 ++++ openssh-8.7p1/monitor.h 2021-10-24 07:33:38.876876743 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,9 +1686,9 @@ diff -Nur openssh-8.6p1.orig/monitor.h openssh-8.6p1/monitor.h }; struct ssh; -diff -Nur openssh-8.6p1.orig/monitor_wrap.c openssh-8.6p1/monitor_wrap.c ---- openssh-8.6p1.orig/monitor_wrap.c 2021-05-04 10:47:33.467951450 +0200 -+++ openssh-8.6p1/monitor_wrap.c 2021-05-04 10:48:29.615078331 +0200 +diff -Nur openssh-8.7p1.orig/monitor_wrap.c openssh-8.7p1/monitor_wrap.c +--- openssh-8.7p1.orig/monitor_wrap.c 2021-10-24 07:32:35.555723904 +0200 ++++ openssh-8.7p1/monitor_wrap.c 2021-10-24 07:33:38.876876743 +0200 @@ -1084,6 +1084,94 @@ return (authenticated); } @@ -1784,9 +1784,9 @@ diff -Nur openssh-8.6p1.orig/monitor_wrap.c openssh-8.6p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.6p1.orig/monitor_wrap.h openssh-8.6p1/monitor_wrap.h ---- openssh-8.6p1.orig/monitor_wrap.h 2021-05-04 10:47:33.453951418 +0200 -+++ openssh-8.6p1/monitor_wrap.h 2021-05-04 10:48:29.616078333 +0200 +diff -Nur openssh-8.7p1.orig/monitor_wrap.h openssh-8.7p1/monitor_wrap.h +--- openssh-8.7p1.orig/monitor_wrap.h 2021-10-24 07:32:35.533723852 +0200 ++++ openssh-8.7p1/monitor_wrap.h 2021-10-24 07:33:38.877876745 +0200 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,12 +1798,12 @@ diff -Nur openssh-8.6p1.orig/monitor_wrap.h openssh-8.6p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c ---- openssh-8.6p1.orig/readconf.c 2021-05-04 10:47:33.468951452 +0200 -+++ openssh-8.6p1/readconf.c 2021-05-04 10:48:29.617078335 +0200 -@@ -2391,11 +2391,11 @@ - if (options->challenge_response_authentication == -1) - options->challenge_response_authentication = 1; +diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c +--- openssh-8.7p1.orig/readconf.c 2021-10-24 07:32:35.557723909 +0200 ++++ openssh-8.7p1/readconf.c 2021-10-24 07:33:38.878876747 +0200 +@@ -2516,11 +2516,11 @@ + if (options->pubkey_authentication == -1) + options->pubkey_authentication = 1; if (options->gss_authentication == -1) - options->gss_authentication = 0; + options->gss_authentication = 1; @@ -1816,10 +1816,10 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h ---- openssh-8.6p1.orig/readconf.h 2021-05-04 10:47:33.355951197 +0200 -+++ openssh-8.6p1/readconf.h 2021-05-04 10:48:29.618078338 +0200 -@@ -80,6 +80,8 @@ +diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h +--- openssh-8.7p1.orig/readconf.h 2021-10-24 07:32:35.395723519 +0200 ++++ openssh-8.7p1/readconf.h 2021-10-24 07:33:38.879876750 +0200 +@@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c ---- openssh-8.6p1.orig/servconf.c 2021-05-04 10:47:33.469951455 +0200 -+++ openssh-8.6p1/servconf.c 2021-05-04 10:48:29.619078340 +0200 +diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c +--- openssh-8.7p1.orig/servconf.c 2021-10-24 07:32:35.558723912 +0200 ++++ openssh-8.7p1/servconf.c 2021-10-24 07:33:38.880876752 +0200 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1851,7 +1851,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -292,6 +295,8 @@ +@@ -291,6 +294,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -373,13 +378,17 @@ +@@ -372,13 +377,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -517,7 +526,7 @@ +@@ -514,7 +523,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -539,6 +548,9 @@ +@@ -535,6 +544,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -571,8 +583,10 @@ +@@ -567,8 +579,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -625,8 +639,15 @@ +@@ -621,8 +635,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -634,8 +655,11 @@ +@@ -630,8 +651,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -707,6 +731,8 @@ +@@ -703,6 +727,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1360,6 +1386,10 @@ +@@ -1381,6 +1407,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1957,8 +1957,8 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c + /* Standard Options */ case sBadOption: - return -1; -@@ -1606,6 +1636,10 @@ + goto out; +@@ -1628,6 +1658,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1614,6 +1648,10 @@ +@@ -1636,6 +1670,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1634,6 +1672,12 @@ +@@ -1656,6 +1694,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2621,6 +2665,7 @@ +@@ -2661,6 +2705,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,9 +2001,9 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h ---- openssh-8.6p1.orig/servconf.h 2021-05-04 10:47:33.402951303 +0200 -+++ openssh-8.6p1/servconf.h 2021-05-04 10:48:29.620078342 +0200 +diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h +--- openssh-8.7p1.orig/servconf.h 2021-10-24 07:32:35.456723666 +0200 ++++ openssh-8.7p1/servconf.h 2021-10-24 07:33:38.881876754 +0200 @@ -146,9 +146,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2017,7 +2017,7 @@ diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -210,6 +213,7 @@ +@@ -209,6 +212,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2025,10 +2025,10 @@ diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h int permit_tun; -diff -Nur openssh-8.6p1.orig/ssh.1 openssh-8.6p1/ssh.1 ---- openssh-8.6p1.orig/ssh.1 2021-05-04 10:47:33.357951202 +0200 -+++ openssh-8.6p1/ssh.1 2021-05-04 10:48:29.621078345 +0200 -@@ -1473,6 +1473,18 @@ +diff -Nur openssh-8.7p1.orig/ssh.1 openssh-8.7p1/ssh.1 +--- openssh-8.7p1.orig/ssh.1 2021-10-24 07:32:35.397723524 +0200 ++++ openssh-8.7p1/ssh.1 2021-10-24 07:33:38.882876757 +0200 +@@ -1492,6 +1492,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-8.6p1.orig/ssh.1 openssh-8.6p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c ---- openssh-8.6p1.orig/ssh.c 2021-05-04 10:47:33.472951462 +0200 -+++ openssh-8.6p1/ssh.c 2021-05-04 10:48:29.622078347 +0200 -@@ -575,6 +575,38 @@ +diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c +--- openssh-8.7p1.orig/ssh.c 2021-10-24 07:32:35.562723921 +0200 ++++ openssh-8.7p1/ssh.c 2021-10-24 07:33:38.883876759 +0200 +@@ -558,6 +558,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,7 +2089,7 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1247,8 +1279,12 @@ +@@ -1236,8 +1268,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2103,9 +2103,9 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-8.6p1.orig/ssh_config openssh-8.6p1/ssh_config ---- openssh-8.6p1.orig/ssh_config 2021-05-04 10:47:33.358951204 +0200 -+++ openssh-8.6p1/ssh_config 2021-05-04 10:48:29.622078347 +0200 +diff -Nur openssh-8.7p1.orig/ssh_config openssh-8.7p1/ssh_config +--- openssh-8.7p1.orig/ssh_config 2021-10-24 07:32:35.398723526 +0200 ++++ openssh-8.7p1/ssh_config 2021-10-24 07:33:38.884876762 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.6p1.orig/ssh_config openssh-8.6p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 ---- openssh-8.6p1.orig/ssh_config.5 2021-05-04 10:47:33.424951353 +0200 -+++ openssh-8.6p1/ssh_config.5 2021-05-04 10:48:29.623078349 +0200 +diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 +--- openssh-8.7p1.orig/ssh_config.5 2021-10-24 07:32:35.489723746 +0200 ++++ openssh-8.7p1/ssh_config.5 2021-10-24 07:33:38.885876764 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -775,7 +781,7 @@ +@@ -821,7 +827,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -783,12 +789,12 @@ +@@ -829,12 +835,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1410,7 +1416,7 @@ +@@ -1458,7 +1464,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-8.6p1.orig/ssh_config.5 openssh-8.6p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c ---- openssh-8.6p1.orig/sshconnect2.c 2021-05-04 10:47:33.459951432 +0200 -+++ openssh-8.6p1/sshconnect2.c 2021-05-04 10:48:29.624078351 +0200 -@@ -854,6 +854,11 @@ +diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c +--- openssh-8.7p1.orig/sshconnect2.c 2021-10-24 07:32:35.542723873 +0200 ++++ openssh-8.7p1/sshconnect2.c 2021-10-24 07:33:38.886876767 +0200 +@@ -860,6 +860,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -965,7 +970,8 @@ +@@ -971,7 +976,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1136,6 +1142,20 @@ +@@ -1142,6 +1148,20 @@ return r; } @@ -2214,7 +2214,7 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1158,6 +1178,12 @@ +@@ -1164,6 +1184,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2227,7 +2227,7 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1171,7 +1197,9 @@ +@@ -1177,7 +1203,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2238,10 +2238,10 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.6p1.orig/sshd.8 openssh-8.6p1/sshd.8 ---- openssh-8.6p1.orig/sshd.8 2021-05-04 10:47:33.375951242 +0200 -+++ openssh-8.6p1/sshd.8 2021-05-04 10:48:29.624078351 +0200 -@@ -815,6 +815,29 @@ +diff -Nur openssh-8.7p1.orig/sshd.8 openssh-8.7p1/sshd.8 +--- openssh-8.7p1.orig/sshd.8 2021-10-24 07:32:35.418723575 +0200 ++++ openssh-8.7p1/sshd.8 2021-10-24 07:33:38.887876769 +0200 +@@ -818,6 +818,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2271,10 +2271,10 @@ diff -Nur openssh-8.6p1.orig/sshd.8 openssh-8.6p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c ---- openssh-8.6p1.orig/sshd.c 2021-05-04 10:47:33.472951462 +0200 -+++ openssh-8.6p1/sshd.c 2021-05-04 10:48:29.625078353 +0200 -@@ -2364,7 +2364,7 @@ +diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c +--- openssh-8.7p1.orig/sshd.c 2021-10-24 07:32:35.563723924 +0200 ++++ openssh-8.7p1/sshd.c 2021-10-24 07:33:38.888876772 +0200 +@@ -2380,7 +2380,7 @@ #endif #ifdef GSSAPI @@ -2283,9 +2283,9 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config ---- openssh-8.6p1.orig/sshd_config 2021-05-04 10:47:33.393951283 +0200 -+++ openssh-8.6p1/sshd_config 2021-05-04 10:48:29.626078356 +0200 +diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config +--- openssh-8.7p1.orig/sshd_config 2021-10-24 07:32:35.443723635 +0200 ++++ openssh-8.7p1/sshd_config 2021-10-24 07:33:38.889876774 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,10 +2311,10 @@ diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.6p1.orig/sshd_config.5 openssh-8.6p1/sshd_config.5 ---- openssh-8.6p1.orig/sshd_config.5 2021-05-04 10:47:33.424951353 +0200 -+++ openssh-8.6p1/sshd_config.5 2021-05-04 10:48:29.627078358 +0200 -@@ -632,15 +632,34 @@ +diff -Nur openssh-8.7p1.orig/sshd_config.5 openssh-8.7p1/sshd_config.5 +--- openssh-8.7p1.orig/sshd_config.5 2021-10-24 07:32:35.490723748 +0200 ++++ openssh-8.7p1/sshd_config.5 2021-10-24 07:33:38.890876776 +0200 +@@ -635,15 +635,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2350,7 +2350,7 @@ diff -Nur openssh-8.6p1.orig/sshd_config.5 openssh-8.6p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -651,7 +670,7 @@ +@@ -654,7 +673,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2359,7 +2359,7 @@ diff -Nur openssh-8.6p1.orig/sshd_config.5 openssh-8.6p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1783,6 +1802,12 @@ +@@ -1788,6 +1807,12 @@ as a non-root user. The default is .Cm no . @@ -2372,9 +2372,9 @@ diff -Nur openssh-8.6p1.orig/sshd_config.5 openssh-8.6p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.6p1.orig/sshd_config_redhat openssh-8.6p1/sshd_config_redhat ---- openssh-8.6p1.orig/sshd_config_redhat 2021-05-04 10:47:33.336951154 +0200 -+++ openssh-8.6p1/sshd_config_redhat 2021-05-04 10:48:29.627078358 +0200 +diff -Nur openssh-8.7p1.orig/sshd_config_redhat openssh-8.7p1/sshd_config_redhat +--- openssh-8.7p1.orig/sshd_config_redhat 2021-10-24 07:32:35.382723488 +0200 ++++ openssh-8.7p1/sshd_config_redhat 2021-10-24 07:33:38.891876779 +0200 @@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-8.6p1.orig/sshd_config_redhat openssh-8.6p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.6p1.orig/ssh-gss.h openssh-8.6p1/ssh-gss.h ---- openssh-8.6p1.orig/ssh-gss.h 2021-05-04 10:47:33.372951235 +0200 -+++ openssh-8.6p1/ssh-gss.h 2021-05-04 10:48:29.628078360 +0200 +diff -Nur openssh-8.7p1.orig/ssh-gss.h openssh-8.7p1/ssh-gss.h +--- openssh-8.7p1.orig/ssh-gss.h 2021-10-24 07:32:35.415723567 +0200 ++++ openssh-8.7p1/ssh-gss.h 2021-10-24 07:33:38.891876779 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-8.6p1.orig/ssh-gss.h openssh-8.6p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.6p1.orig/version.h openssh-8.6p1/version.h ---- openssh-8.6p1.orig/version.h 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/version.h 2021-05-04 10:48:29.628078360 +0200 +diff -Nur openssh-8.7p1.orig/version.h openssh-8.7p1/version.h +--- openssh-8.7p1.orig/version.h 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/version.h 2021-10-24 07:33:38.891876779 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.6" + #define SSH_VERSION "OpenSSH_8.7" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.6p1-hpn-15.2-modified.patch b/openssh-8.7p1-hpn-15.2-modified.patch similarity index 88% rename from openssh-8.6p1-hpn-15.2-modified.patch rename to openssh-8.7p1-hpn-15.2-modified.patch index 0c38562..75a4908 100644 --- a/openssh-8.6p1-hpn-15.2-modified.patch +++ b/openssh-8.7p1-hpn-15.2-modified.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c ---- openssh-8.6p1.orig/auth2.c 2021-05-22 08:23:21.056175731 +0200 -+++ openssh-8.6p1/auth2.c 2021-05-22 08:24:33.539345593 +0200 +diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c +--- openssh-8.7p1.orig/auth2.c 2021-10-24 07:54:36.863834186 +0200 ++++ openssh-8.7p1/auth2.c 2021-10-24 07:56:04.844029990 +0200 @@ -53,6 +53,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -31,9 +31,9 @@ diff -Nur openssh-8.6p1.orig/auth2.c openssh-8.6p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c ---- openssh-8.6p1.orig/channels.c 2021-05-22 08:23:21.043175700 +0200 -+++ openssh-8.6p1/channels.c 2021-05-22 08:24:33.540345595 +0200 +diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c +--- openssh-8.7p1.orig/channels.c 2021-10-24 07:54:36.849834155 +0200 ++++ openssh-8.7p1/channels.c 2021-10-24 07:56:04.845029992 +0200 @@ -220,6 +220,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -44,7 +44,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c /* -- channel core */ void -@@ -407,6 +410,7 @@ +@@ -415,6 +418,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -52,7 +52,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1098,6 +1102,28 @@ +@@ -1108,6 +1112,28 @@ FD_SET(c->sock, writeset); } @@ -81,7 +81,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c, fd_set *readset, fd_set *writeset) -@@ -2136,22 +2162,31 @@ +@@ -2147,22 +2173,31 @@ if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && @@ -118,7 +118,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c c->local_consumed = 0; } return 1; -@@ -3318,6 +3353,14 @@ +@@ -3329,6 +3364,14 @@ return addr; } @@ -133,7 +133,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -@@ -3458,8 +3501,10 @@ +@@ -3468,8 +3511,10 @@ } /* Allocate a channel number for the socket. */ @@ -145,7 +145,7 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; -@@ -4645,7 +4690,8 @@ +@@ -4655,7 +4700,8 @@ sock = socks[n]; nc = channel_new(ssh, "x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, @@ -155,10 +155,10 @@ diff -Nur openssh-8.6p1.orig/channels.c openssh-8.6p1/channels.c 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; -diff -Nur openssh-8.6p1.orig/channels.h openssh-8.6p1/channels.h ---- openssh-8.6p1.orig/channels.h 2021-05-22 08:23:21.020175646 +0200 -+++ openssh-8.6p1/channels.h 2021-05-22 08:24:33.541345597 +0200 -@@ -158,8 +158,10 @@ +diff -Nur openssh-8.7p1.orig/channels.h openssh-8.7p1/channels.h +--- openssh-8.7p1.orig/channels.h 2021-10-24 07:54:36.785834012 +0200 ++++ openssh-8.7p1/channels.h 2021-10-24 07:56:04.846029995 +0200 +@@ -169,8 +169,10 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; @@ -169,7 +169,7 @@ diff -Nur openssh-8.6p1.orig/channels.h openssh-8.6p1/channels.h char *ctype; /* type */ -@@ -228,7 +230,7 @@ +@@ -232,7 +234,7 @@ #define CHAN_LOCAL 0x10 /* Read buffer size */ @@ -178,7 +178,7 @@ diff -Nur openssh-8.6p1.orig/channels.h openssh-8.6p1/channels.h /* Maximum channel input buffer size */ #define CHAN_INPUT_MAX (16*1024*1024) -@@ -359,4 +361,7 @@ +@@ -363,4 +365,7 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); @@ -186,9 +186,9 @@ diff -Nur openssh-8.6p1.orig/channels.h openssh-8.6p1/channels.h +void channel_set_hpn(int, int); + #endif -diff -Nur openssh-8.6p1.orig/cipher.c openssh-8.6p1/cipher.c ---- openssh-8.6p1.orig/cipher.c 2021-05-22 08:23:21.024175656 +0200 -+++ openssh-8.6p1/cipher.c 2021-05-22 08:24:33.542345600 +0200 +diff -Nur openssh-8.7p1.orig/cipher.c openssh-8.7p1/cipher.c +--- openssh-8.7p1.orig/cipher.c 2021-10-24 07:54:36.828834108 +0200 ++++ openssh-8.7p1/cipher.c 2021-10-24 07:56:04.847029997 +0200 @@ -48,6 +48,7 @@ #include "sshbuf.h" #include "ssherr.h" @@ -269,9 +269,9 @@ diff -Nur openssh-8.6p1.orig/cipher.c openssh-8.6p1/cipher.c free(cipher_list); return 0; } -diff -Nur openssh-8.6p1.orig/cipher-ctr-mt.c openssh-8.6p1/cipher-ctr-mt.c ---- openssh-8.6p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.6p1/cipher-ctr-mt.c 2021-05-22 08:24:33.543345602 +0200 +diff -Nur openssh-8.7p1.orig/cipher-ctr-mt.c openssh-8.7p1/cipher-ctr-mt.c +--- openssh-8.7p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.7p1/cipher-ctr-mt.c 2021-10-24 07:56:04.848029999 +0200 @@ -0,0 +1,678 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -951,9 +951,9 @@ diff -Nur openssh-8.6p1.orig/cipher-ctr-mt.c openssh-8.6p1/cipher-ctr-mt.c +} + +#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-8.6p1.orig/cipher.h openssh-8.6p1/cipher.h ---- openssh-8.6p1.orig/cipher.h 2021-05-22 08:23:21.025175658 +0200 -+++ openssh-8.6p1/cipher.h 2021-05-22 08:24:33.543345602 +0200 +diff -Nur openssh-8.7p1.orig/cipher.h openssh-8.7p1/cipher.h +--- openssh-8.7p1.orig/cipher.h 2021-10-24 07:54:36.829834110 +0200 ++++ openssh-8.7p1/cipher.h 2021-10-24 07:56:04.848029999 +0200 @@ -68,7 +68,9 @@ struct sshcipher_ctx; @@ -974,10 +974,10 @@ diff -Nur openssh-8.6p1.orig/cipher.h openssh-8.6p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-8.6p1.orig/clientloop.c openssh-8.6p1/clientloop.c ---- openssh-8.6p1.orig/clientloop.c 2021-05-22 08:23:20.932175440 +0200 -+++ openssh-8.6p1/clientloop.c 2021-05-22 08:24:33.544345604 +0200 -@@ -1593,7 +1593,9 @@ +diff -Nur openssh-8.7p1.orig/clientloop.c openssh-8.7p1/clientloop.c +--- openssh-8.7p1.orig/clientloop.c 2021-10-24 07:54:36.738833908 +0200 ++++ openssh-8.7p1/clientloop.c 2021-10-24 07:56:04.849030001 +0200 +@@ -1582,7 +1582,9 @@ return NULL; c = channel_new(ssh, "x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, @@ -988,7 +988,7 @@ diff -Nur openssh-8.6p1.orig/clientloop.c openssh-8.6p1/clientloop.c c->force_drain = 1; return c; } -@@ -1622,7 +1624,8 @@ +@@ -1611,7 +1613,8 @@ } c = channel_new(ssh, "authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -998,7 +998,7 @@ diff -Nur openssh-8.6p1.orig/clientloop.c openssh-8.6p1/clientloop.c "authentication agent connection", 1); c->force_drain = 1; return c; -@@ -1649,7 +1652,8 @@ +@@ -1638,7 +1641,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, @@ -1008,10 +1008,10 @@ diff -Nur openssh-8.6p1.orig/clientloop.c openssh-8.6p1/clientloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) -diff -Nur openssh-8.6p1.orig/compat.c openssh-8.6p1/compat.c ---- openssh-8.6p1.orig/compat.c 2021-05-22 08:23:21.044175703 +0200 -+++ openssh-8.6p1/compat.c 2021-05-22 08:24:33.544345604 +0200 -@@ -150,6 +150,17 @@ +diff -Nur openssh-8.7p1.orig/compat.c openssh-8.7p1/compat.c +--- openssh-8.7p1.orig/compat.c 2021-10-24 07:54:36.849834155 +0200 ++++ openssh-8.7p1/compat.c 2021-10-24 07:56:04.850030003 +0200 +@@ -151,6 +151,17 @@ debug_f("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); ssh->compat = check[i].bugs; @@ -1029,9 +1029,9 @@ diff -Nur openssh-8.6p1.orig/compat.c openssh-8.6p1/compat.c return; } } -diff -Nur openssh-8.6p1.orig/compat.h openssh-8.6p1/compat.h ---- openssh-8.6p1.orig/compat.h 2021-05-22 08:23:21.013175630 +0200 -+++ openssh-8.6p1/compat.h 2021-05-22 08:24:33.545345607 +0200 +diff -Nur openssh-8.7p1.orig/compat.h openssh-8.7p1/compat.h +--- openssh-8.7p1.orig/compat.h 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/compat.h 2021-10-24 07:56:04.850030003 +0200 @@ -57,6 +57,7 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 @@ -1040,10 +1040,10 @@ diff -Nur openssh-8.6p1.orig/compat.h openssh-8.6p1/compat.h struct ssh; -diff -Nur openssh-8.6p1.orig/defines.h openssh-8.6p1/defines.h ---- openssh-8.6p1.orig/defines.h 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/defines.h 2021-05-22 08:24:33.545345607 +0200 -@@ -848,7 +848,7 @@ +diff -Nur openssh-8.7p1.orig/defines.h openssh-8.7p1/defines.h +--- openssh-8.7p1.orig/defines.h 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/defines.h 2021-10-24 07:56:04.851030005 +0200 +@@ -854,7 +854,7 @@ #endif #ifndef SSH_IOBUFSZ @@ -1052,9 +1052,9 @@ diff -Nur openssh-8.6p1.orig/defines.h openssh-8.6p1/defines.h #endif /* -diff -Nur openssh-8.6p1.orig/digest.h openssh-8.6p1/digest.h ---- openssh-8.6p1.orig/digest.h 2021-05-22 08:23:21.003175607 +0200 -+++ openssh-8.6p1/digest.h 2021-05-22 08:24:33.545345607 +0200 +diff -Nur openssh-8.7p1.orig/digest.h openssh-8.7p1/digest.h +--- openssh-8.7p1.orig/digest.h 2021-10-24 07:54:36.811834070 +0200 ++++ openssh-8.7p1/digest.h 2021-10-24 07:56:04.852030007 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -1065,9 +1065,9 @@ diff -Nur openssh-8.6p1.orig/digest.h openssh-8.6p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-8.6p1.orig/digest-openssl.c openssh-8.6p1/digest-openssl.c ---- openssh-8.6p1.orig/digest-openssl.c 2021-05-22 08:23:21.003175607 +0200 -+++ openssh-8.6p1/digest-openssl.c 2021-05-22 08:24:33.546345609 +0200 +diff -Nur openssh-8.7p1.orig/digest-openssl.c openssh-8.7p1/digest-openssl.c +--- openssh-8.7p1.orig/digest-openssl.c 2021-10-24 07:54:36.810834068 +0200 ++++ openssh-8.7p1/digest-openssl.c 2021-10-24 07:56:04.852030007 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -1076,9 +1076,9 @@ diff -Nur openssh-8.6p1.orig/digest-openssl.c openssh-8.6p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-8.6p1.orig/HPN-README openssh-8.6p1/HPN-README ---- openssh-8.6p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.6p1/HPN-README 2021-05-22 08:24:33.546345609 +0200 +diff -Nur openssh-8.7p1.orig/HPN-README openssh-8.7p1/HPN-README +--- openssh-8.7p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.7p1/HPN-README 2021-10-24 07:56:04.852030007 +0200 @@ -0,0 +1,153 @@ +Notes: + @@ -1233,9 +1233,9 @@ diff -Nur openssh-8.6p1.orig/HPN-README openssh-8.6p1/HPN-README + Allan Jude provided the code for the NoneMac and buffer normalization. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. -diff -Nur openssh-8.6p1.orig/kex.c openssh-8.6p1/kex.c ---- openssh-8.6p1.orig/kex.c 2021-05-22 08:23:21.036175684 +0200 -+++ openssh-8.6p1/kex.c 2021-05-22 08:24:33.547345612 +0200 +diff -Nur openssh-8.7p1.orig/kex.c openssh-8.7p1/kex.c +--- openssh-8.7p1.orig/kex.c 2021-10-24 07:54:36.841834137 +0200 ++++ openssh-8.7p1/kex.c 2021-10-24 07:56:04.853030010 +0200 @@ -64,6 +64,7 @@ #include "ssherr.h" @@ -1321,9 +1321,9 @@ diff -Nur openssh-8.6p1.orig/kex.c openssh-8.6p1/kex.c debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); compat_banner(ssh, remote_version); -diff -Nur openssh-8.6p1.orig/log.c openssh-8.6p1/log.c ---- openssh-8.6p1.orig/log.c 2021-05-22 08:23:20.963175513 +0200 -+++ openssh-8.6p1/log.c 2021-05-22 08:24:33.547345612 +0200 +diff -Nur openssh-8.7p1.orig/log.c openssh-8.7p1/log.c +--- openssh-8.7p1.orig/log.c 2021-10-24 07:54:36.769833977 +0200 ++++ openssh-8.7p1/log.c 2021-10-24 07:56:04.853030010 +0200 @@ -46,6 +46,11 @@ #include #include @@ -1345,9 +1345,9 @@ diff -Nur openssh-8.6p1.orig/log.c openssh-8.6p1/log.c #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) -diff -Nur openssh-8.6p1.orig/mac.c openssh-8.6p1/mac.c ---- openssh-8.6p1.orig/mac.c 2021-05-22 08:23:21.025175658 +0200 -+++ openssh-8.6p1/mac.c 2021-05-22 08:24:33.547345612 +0200 +diff -Nur openssh-8.7p1.orig/mac.c openssh-8.7p1/mac.c +--- openssh-8.7p1.orig/mac.c 2021-10-24 07:54:36.830834112 +0200 ++++ openssh-8.7p1/mac.c 2021-10-24 07:56:04.854030012 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -1356,9 +1356,9 @@ diff -Nur openssh-8.6p1.orig/mac.c openssh-8.6p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in ---- openssh-8.6p1.orig/Makefile.in 2021-05-22 08:23:21.061175742 +0200 -+++ openssh-8.6p1/Makefile.in 2021-05-22 08:24:33.548345614 +0200 +diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in +--- openssh-8.7p1.orig/Makefile.in 2021-10-24 07:54:36.867834195 +0200 ++++ openssh-8.7p1/Makefile.in 2021-10-24 07:56:04.854030012 +0200 @@ -48,7 +48,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ @@ -1377,9 +1377,9 @@ diff -Nur openssh-8.6p1.orig/Makefile.in openssh-8.6p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c ---- openssh-8.6p1.orig/packet.c 2021-05-22 08:23:21.028175665 +0200 -+++ openssh-8.6p1/packet.c 2021-05-22 08:24:33.549345616 +0200 +diff -Nur openssh-8.7p1.orig/packet.c openssh-8.7p1/packet.c +--- openssh-8.7p1.orig/packet.c 2021-10-24 07:54:36.832834117 +0200 ++++ openssh-8.7p1/packet.c 2021-10-24 07:56:04.855030014 +0200 @@ -246,7 +246,7 @@ TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; @@ -1461,7 +1461,7 @@ diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c /* Time-based rekeying */ if (state->rekey_interval != 0 && (int64_t)state->rekey_time + state->rekey_interval <= monotime()) -@@ -1333,7 +1367,7 @@ +@@ -1342,7 +1376,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain; fd_set *setp; @@ -1470,7 +1470,7 @@ diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c struct timeval timeout, start, *timeoutp = NULL; DBG(debug("packet_read()")); -@@ -1865,17 +1899,21 @@ +@@ -1870,17 +1904,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -1492,7 +1492,7 @@ diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -1917,6 +1955,24 @@ +@@ -1922,6 +1960,24 @@ logdie_f("should have exited"); } @@ -1517,7 +1517,7 @@ diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -2789,3 +2845,10 @@ +@@ -2794,3 +2850,10 @@ ssh->state->extra_pad = pad; return 0; } @@ -1528,9 +1528,9 @@ diff -Nur openssh-8.6p1.orig/packet.c openssh-8.6p1/packet.c +{ + return ssh->state->send_context; +} -diff -Nur openssh-8.6p1.orig/packet.h openssh-8.6p1/packet.h ---- openssh-8.6p1.orig/packet.h 2021-05-22 08:23:21.028175665 +0200 -+++ openssh-8.6p1/packet.h 2021-05-22 08:24:33.549345616 +0200 +diff -Nur openssh-8.7p1.orig/packet.h openssh-8.7p1/packet.h +--- openssh-8.7p1.orig/packet.h 2021-10-24 07:54:36.833834119 +0200 ++++ openssh-8.7p1/packet.h 2021-10-24 07:56:04.856030016 +0200 @@ -86,6 +86,14 @@ /* APP data */ @@ -1546,7 +1546,7 @@ diff -Nur openssh-8.6p1.orig/packet.h openssh-8.6p1/packet.h }; typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, -@@ -155,6 +163,8 @@ +@@ -156,6 +164,8 @@ int ssh_packet_set_maxsize(struct ssh *, u_int); u_int ssh_packet_get_maxsize(struct ssh *); @@ -1555,7 +1555,7 @@ diff -Nur openssh-8.6p1.orig/packet.h openssh-8.6p1/packet.h int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); -@@ -169,6 +179,13 @@ +@@ -170,6 +180,13 @@ void *ssh_packet_get_input(struct ssh *); void *ssh_packet_get_output(struct ssh *); @@ -1569,9 +1569,9 @@ diff -Nur openssh-8.6p1.orig/packet.h openssh-8.6p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-8.6p1.orig/progressmeter.c openssh-8.6p1/progressmeter.c ---- openssh-8.6p1.orig/progressmeter.c 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/progressmeter.c 2021-05-22 08:24:33.549345616 +0200 +diff -Nur openssh-8.7p1.orig/progressmeter.c openssh-8.7p1/progressmeter.c +--- openssh-8.7p1.orig/progressmeter.c 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/progressmeter.c 2021-10-24 07:56:04.857030018 +0200 @@ -68,6 +68,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -1633,9 +1633,9 @@ diff -Nur openssh-8.6p1.orig/progressmeter.c openssh-8.6p1/progressmeter.c } /*ARGSUSED*/ -diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c ---- openssh-8.6p1.orig/readconf.c 2021-05-22 08:23:21.064175750 +0200 -+++ openssh-8.6p1/readconf.c 2021-05-22 08:24:33.550345619 +0200 +diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c +--- openssh-8.7p1.orig/readconf.c 2021-10-24 07:54:36.870834202 +0200 ++++ openssh-8.7p1/readconf.c 2021-10-24 08:13:34.654331392 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -1652,9 +1652,9 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c + oNoneEnabled, oNoneMacEnabled, oNoneSwitch, + oDisableMTAES, oVisualHostKey, - oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, - oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, -@@ -312,6 +316,10 @@ + oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, + oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, +@@ -313,6 +317,10 @@ { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, @@ -1662,10 +1662,10 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c + { "nonemacenabled", oNoneMacEnabled }, + { "noneswitch", oNoneSwitch }, + { "disablemtaes", oDisableMTAES }, - { "proxyusefdpass", oProxyUseFdpass }, - { "canonicaldomains", oCanonicalDomains }, - { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, -@@ -332,6 +340,11 @@ + { "sessiontype", oSessionType }, + { "stdinnull", oStdinNull }, + { "forkafterauthentication", oForkAfterAuthentication }, +@@ -336,6 +344,11 @@ { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, @@ -1677,7 +1677,7 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c { NULL, oBadOption } }; -@@ -1138,6 +1151,46 @@ +@@ -1172,6 +1185,46 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -1724,7 +1724,7 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -1371,6 +1424,10 @@ +@@ -1426,6 +1479,10 @@ *intptr = value; break; @@ -1733,9 +1733,9 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c + goto parse_int; + case oCiphers: - arg = strdelim(&s); + arg = argv_next(&ac, &av); if (!arg || *arg == '\0') { -@@ -2316,6 +2373,14 @@ +@@ -2440,6 +2497,14 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -1747,10 +1747,10 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c + options->hpn_buffer_size = -1; + options->tcp_rcv_buf_poll = -1; + options->tcp_rcv_buf = -1; - options->proxy_use_fdpass = -1; - options->ignored_unknown = NULL; - options->num_canonical_domains = 0; -@@ -2490,6 +2555,43 @@ + options->session_type = -1; + options->stdin_null = -1; + options->fork_after_authentication = -1; +@@ -2615,6 +2680,43 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -1794,10 +1794,10 @@ diff -Nur openssh-8.6p1.orig/readconf.c openssh-8.6p1/readconf.c if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { -diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h ---- openssh-8.6p1.orig/readconf.h 2021-05-22 08:23:21.064175750 +0200 -+++ openssh-8.6p1/readconf.h 2021-05-22 08:24:33.551345621 +0200 -@@ -57,6 +57,10 @@ +diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h +--- openssh-8.7p1.orig/readconf.h 2021-10-24 07:54:36.870834202 +0200 ++++ openssh-8.7p1/readconf.h 2021-10-24 07:56:04.860030025 +0200 +@@ -55,6 +55,10 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ @@ -1808,7 +1808,7 @@ diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ -@@ -128,7 +132,12 @@ +@@ -126,7 +130,12 @@ int enable_ssh_keysign; int64_t rekey_limit; @@ -1821,9 +1821,9 @@ diff -Nur openssh-8.6p1.orig/readconf.h openssh-8.6p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-8.6p1.orig/regress/integrity.sh openssh-8.6p1/regress/integrity.sh ---- openssh-8.6p1.orig/regress/integrity.sh 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/regress/integrity.sh 2021-05-22 08:24:33.551345621 +0200 +diff -Nur openssh-8.7p1.orig/regress/integrity.sh openssh-8.7p1/regress/integrity.sh +--- openssh-8.7p1.orig/regress/integrity.sh 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/integrity.sh 2021-10-24 07:56:04.860030025 +0200 @@ -21,6 +21,12 @@ cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" @@ -1837,9 +1837,9 @@ diff -Nur openssh-8.6p1.orig/regress/integrity.sh openssh-8.6p1/regress/integrit trace "test $tid: mac $m" elen=0 epad=0 -diff -Nur openssh-8.6p1.orig/sandbox-seccomp-filter.c openssh-8.6p1/sandbox-seccomp-filter.c ---- openssh-8.6p1.orig/sandbox-seccomp-filter.c 2021-05-22 08:23:21.037175686 +0200 -+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-22 08:24:33.552345623 +0200 +diff -Nur openssh-8.7p1.orig/sandbox-seccomp-filter.c openssh-8.7p1/sandbox-seccomp-filter.c +--- openssh-8.7p1.orig/sandbox-seccomp-filter.c 2021-10-24 07:54:36.842834139 +0200 ++++ openssh-8.7p1/sandbox-seccomp-filter.c 2021-10-24 07:56:04.861030027 +0200 @@ -225,6 +225,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -1860,10 +1860,10 @@ diff -Nur openssh-8.6p1.orig/sandbox-seccomp-filter.c openssh-8.6p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-8.6p1.orig/scp.c openssh-8.6p1/scp.c ---- openssh-8.6p1.orig/scp.c 2021-05-22 08:23:21.048175712 +0200 -+++ openssh-8.6p1/scp.c 2021-05-22 08:24:33.552345623 +0200 -@@ -1251,7 +1251,7 @@ +diff -Nur openssh-8.7p1.orig/scp.c openssh-8.7p1/scp.c +--- openssh-8.7p1.orig/scp.c 2021-10-24 07:54:36.854834166 +0200 ++++ openssh-8.7p1/scp.c 2021-10-24 07:56:04.861030027 +0200 +@@ -1566,7 +1566,7 @@ off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerr; @@ -1872,9 +1872,9 @@ diff -Nur openssh-8.6p1.orig/scp.c openssh-8.6p1/scp.c char **patterns = NULL; size_t n, npatterns = 0; struct timeval tv[2]; -diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c ---- openssh-8.6p1.orig/servconf.c 2021-05-22 08:23:21.064175750 +0200 -+++ openssh-8.6p1/servconf.c 2021-05-22 08:24:33.553345625 +0200 +diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c +--- openssh-8.7p1.orig/servconf.c 2021-10-24 07:54:36.871834204 +0200 ++++ openssh-8.7p1/servconf.c 2021-10-24 07:56:04.863030032 +0200 @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -1883,7 +1883,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c #include "ssh-gss.h" static void add_listen_addr(ServerOptions *, const char *, -@@ -201,6 +202,12 @@ +@@ -200,6 +201,12 @@ options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; @@ -1896,7 +1896,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -291,6 +298,10 @@ +@@ -290,6 +297,10 @@ fill_default_server_options(ServerOptions *options) { u_int i; @@ -1907,7 +1907,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c /* Portable-specific options */ if (options->use_pam == -1) -@@ -464,6 +475,51 @@ +@@ -461,6 +472,51 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -1959,7 +1959,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -537,6 +593,9 @@ +@@ -533,6 +589,9 @@ sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -737,6 +796,12 @@ +@@ -733,6 +792,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -1982,7 +1982,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -795,6 +860,7 @@ +@@ -791,6 +856,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -1990,7 +1990,7 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1546,12 +1612,36 @@ +@@ -1568,12 +1634,36 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -2027,10 +2027,10 @@ diff -Nur openssh-8.6p1.orig/servconf.c openssh-8.6p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h ---- openssh-8.6p1.orig/servconf.h 2021-05-22 08:23:21.065175752 +0200 -+++ openssh-8.6p1/servconf.h 2021-05-22 08:24:33.554345628 +0200 -@@ -215,6 +215,13 @@ +diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h +--- openssh-8.7p1.orig/servconf.h 2021-10-24 07:54:36.871834204 +0200 ++++ openssh-8.7p1/servconf.h 2021-10-24 07:56:04.864030034 +0200 +@@ -214,6 +214,13 @@ int use_pam; /* Enable auth via PAM */ int permit_pam_user_change; /* Allow PAM to change user name */ @@ -2044,10 +2044,10 @@ diff -Nur openssh-8.6p1.orig/servconf.h openssh-8.6p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c ---- openssh-8.6p1.orig/serverloop.c 2021-05-22 08:23:21.049175714 +0200 -+++ openssh-8.6p1/serverloop.c 2021-05-22 08:24:33.554345628 +0200 -@@ -322,7 +322,7 @@ +diff -Nur openssh-8.7p1.orig/serverloop.c openssh-8.7p1/serverloop.c +--- openssh-8.7p1.orig/serverloop.c 2021-10-24 07:54:36.855834168 +0200 ++++ openssh-8.7p1/serverloop.c 2021-10-24 07:56:04.865030036 +0200 +@@ -266,7 +266,7 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in) { int r, len; @@ -2056,7 +2056,7 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c /* Read and buffer any input data from the client. */ if (FD_ISSET(connection_in, readset)) { -@@ -343,6 +343,7 @@ +@@ -287,6 +287,7 @@ /* Buffer any received data. */ if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) fatal_fr(r, "ssh_packet_process_incoming"); @@ -2064,15 +2064,15 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c } return 0; } -@@ -401,6 +402,7 @@ - u_int64_t rekey_timeout_ms = 0; +@@ -340,6 +341,7 @@ + sigset_t bsigset, osigset; debug("Entering interactive session for SSH2."); + ssh->start_time = monotime_double(); - ssh_signal(SIGCHLD, sigchld_handler); - child_terminated = 0; -@@ -439,6 +441,7 @@ + if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) + error_f("bsigset setup: %s", strerror(errno)); +@@ -388,6 +390,7 @@ if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); @@ -2080,7 +2080,7 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } -@@ -458,6 +461,9 @@ +@@ -409,6 +412,9 @@ /* free all channels, no more reads and writes */ channel_free_all(ssh); @@ -2090,7 +2090,7 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(ssh, NULL); } -@@ -608,7 +614,8 @@ +@@ -559,7 +565,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -2100,7 +2100,7 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) -@@ -659,6 +666,8 @@ +@@ -610,6 +617,8 @@ c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); @@ -2109,9 +2109,9 @@ diff -Nur openssh-8.6p1.orig/serverloop.c openssh-8.6p1/serverloop.c if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -diff -Nur openssh-8.6p1.orig/session.c openssh-8.6p1/session.c ---- openssh-8.6p1.orig/session.c 2021-05-22 08:23:21.050175717 +0200 -+++ openssh-8.6p1/session.c 2021-05-22 08:24:33.555345630 +0200 +diff -Nur openssh-8.7p1.orig/session.c openssh-8.7p1/session.c +--- openssh-8.7p1.orig/session.c 2021-10-24 07:54:36.855834168 +0200 ++++ openssh-8.7p1/session.c 2021-10-24 07:56:04.866030038 +0200 @@ -228,6 +228,7 @@ goto authsock_err; @@ -2120,7 +2120,7 @@ diff -Nur openssh-8.6p1.orig/session.c openssh-8.6p1/session.c nc = channel_new(ssh, "auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -2364,7 +2365,8 @@ +@@ -2363,7 +2364,8 @@ channel_set_fds(ssh, s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, @@ -2130,10 +2130,10 @@ diff -Nur openssh-8.6p1.orig/session.c openssh-8.6p1/session.c } /* -diff -Nur openssh-8.6p1.orig/sftp.1 openssh-8.6p1/sftp.1 ---- openssh-8.6p1.orig/sftp.1 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sftp.1 2021-05-22 08:24:33.556345633 +0200 -@@ -296,7 +296,8 @@ +diff -Nur openssh-8.7p1.orig/sftp.1 openssh-8.7p1/sftp.1 +--- openssh-8.7p1.orig/sftp.1 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sftp.1 2021-10-24 07:56:04.867030041 +0200 +@@ -295,7 +295,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. @@ -2143,10 +2143,10 @@ diff -Nur openssh-8.6p1.orig/sftp.1 openssh-8.6p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -diff -Nur openssh-8.6p1.orig/sftp-client.c openssh-8.6p1/sftp-client.c ---- openssh-8.6p1.orig/sftp-client.c 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sftp-client.c 2021-05-22 08:24:33.556345633 +0200 -@@ -65,7 +65,7 @@ +diff -Nur openssh-8.7p1.orig/sftp-client.c openssh-8.7p1/sftp-client.c +--- openssh-8.7p1.orig/sftp-client.c 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sftp-client.c 2021-10-24 07:56:04.868030043 +0200 +@@ -72,7 +72,7 @@ #define DEFAULT_COPY_BUFLEN 32768 /* Default number of concurrent outstanding requests */ @@ -2155,9 +2155,9 @@ diff -Nur openssh-8.6p1.orig/sftp-client.c openssh-8.6p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-8.6p1.orig/ssh_api.c openssh-8.6p1/ssh_api.c ---- openssh-8.6p1.orig/ssh_api.c 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/ssh_api.c 2021-05-22 08:24:33.557345635 +0200 +diff -Nur openssh-8.7p1.orig/ssh_api.c openssh-8.7p1/ssh_api.c +--- openssh-8.7p1.orig/ssh_api.c 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh_api.c 2021-10-24 07:56:04.869030045 +0200 @@ -410,7 +410,7 @@ char *cp; int r; @@ -2167,9 +2167,9 @@ diff -Nur openssh-8.6p1.orig/ssh_api.c openssh-8.6p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-8.6p1.orig/sshbuf.h openssh-8.6p1/sshbuf.h ---- openssh-8.6p1.orig/sshbuf.h 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sshbuf.h 2021-05-22 08:24:33.557345635 +0200 +diff -Nur openssh-8.7p1.orig/sshbuf.h openssh-8.7p1/sshbuf.h +--- openssh-8.7p1.orig/sshbuf.h 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sshbuf.h 2021-10-24 07:56:04.870030047 +0200 @@ -28,7 +28,7 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2179,10 +2179,10 @@ diff -Nur openssh-8.6p1.orig/sshbuf.h openssh-8.6p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c ---- openssh-8.6p1.orig/ssh.c 2021-05-22 08:23:21.066175754 +0200 -+++ openssh-8.6p1/ssh.c 2021-05-22 08:24:33.558345637 +0200 -@@ -1070,6 +1070,10 @@ +diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c +--- openssh-8.7p1.orig/ssh.c 2021-10-24 07:54:36.872834206 +0200 ++++ openssh-8.7p1/ssh.c 2021-10-24 07:56:04.871030049 +0200 +@@ -1056,6 +1056,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1797,6 +1801,8 @@ +@@ -1784,6 +1788,8 @@ setproctitle("%s [mux]", options.control_path); } @@ -2202,7 +2202,7 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) -@@ -2109,6 +2115,79 @@ +@@ -2101,6 +2107,79 @@ NULL, fileno(stdin), command, environ); } @@ -2282,7 +2282,7 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2127,9 +2206,11 @@ +@@ -2119,9 +2198,11 @@ if (in == -1 || out == -1 || err == -1) fatal("dup() in/out/err failed"); @@ -2295,7 +2295,7 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2140,6 +2221,11 @@ +@@ -2132,6 +2213,11 @@ debug3_f("channel_new: %d", c->self); @@ -2305,9 +2305,9 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c + } + channel_send_open(ssh, c->self); - if (!no_shell_flag) + if (options.session_type != SESSION_TYPE_NONE) channel_register_open_confirm(ssh, c->self, -@@ -2154,6 +2240,13 @@ +@@ -2146,6 +2232,13 @@ int r, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -2321,9 +2321,9 @@ diff -Nur openssh-8.6p1.orig/ssh.c openssh-8.6p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c ---- openssh-8.6p1.orig/sshconnect2.c 2021-05-22 08:23:21.067175757 +0200 -+++ openssh-8.6p1/sshconnect2.c 2021-05-22 08:24:33.559345640 +0200 +diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c +--- openssh-8.7p1.orig/sshconnect2.c 2021-10-24 07:54:36.873834208 +0200 ++++ openssh-8.7p1/sshconnect2.c 2021-10-24 08:06:47.586411958 +0200 @@ -86,6 +86,13 @@ extern Options options; @@ -2358,7 +2358,7 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -571,6 +584,53 @@ +@@ -569,6 +582,53 @@ if (!authctxt.success) fatal("Authentication failed."); @@ -2409,12 +2409,12 @@ diff -Nur openssh-8.6p1.orig/sshconnect2.c openssh-8.6p1/sshconnect2.c + } +#endif + - debug("Authentication succeeded (%s).", authctxt.method->name); - } - -diff -Nur openssh-8.6p1.orig/sshconnect.c openssh-8.6p1/sshconnect.c ---- openssh-8.6p1.orig/sshconnect.c 2021-05-22 08:23:20.987175569 +0200 -+++ openssh-8.6p1/sshconnect.c 2021-05-22 08:24:33.560345642 +0200 + if (ssh_packet_connection_is_on_socket(ssh)) { + verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), +diff -Nur openssh-8.7p1.orig/sshconnect.c openssh-8.7p1/sshconnect.c +--- openssh-8.7p1.orig/sshconnect.c 2021-10-24 07:54:36.794834032 +0200 ++++ openssh-8.7p1/sshconnect.c 2021-10-24 07:56:04.873030054 +0200 @@ -345,6 +345,30 @@ #endif @@ -2456,10 +2456,10 @@ diff -Nur openssh-8.6p1.orig/sshconnect.c openssh-8.6p1/sshconnect.c /* Use interactive QOS (if specified) until authentication completed */ if (options.ip_qos_interactive != INT_MAX) set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c ---- openssh-8.6p1.orig/sshd.c 2021-05-22 08:23:21.068175759 +0200 -+++ openssh-8.6p1/sshd.c 2021-05-22 08:24:33.561345644 +0200 -@@ -1107,6 +1107,8 @@ +diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c +--- openssh-8.7p1.orig/sshd.c 2021-10-24 07:54:36.874834211 +0200 ++++ openssh-8.7p1/sshd.c 2021-10-24 08:00:18.185586742 +0200 +@@ -1110,6 +1110,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2468,7 +2468,7 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1152,6 +1154,11 @@ +@@ -1155,6 +1157,11 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -2480,7 +2480,7 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1834,6 +1841,19 @@ +@@ -1854,6 +1861,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2497,10 +2497,10 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c + } + } + - /* challenge-response is implemented via keyboard interactive */ - if (options.challenge_response_authentication) - options.kbd_interactive_authentication = 1; -@@ -2285,6 +2305,9 @@ + /* Check that options are sensible */ + if (options.authorized_keys_command_user == NULL && + (options.authorized_keys_command != NULL && +@@ -2301,6 +2321,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -2510,7 +2510,7 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -2397,6 +2420,25 @@ +@@ -2413,6 +2436,25 @@ /* Try to send all our hostkeys to the client */ notify_hostkeys(ssh); @@ -2536,7 +2536,7 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c /* Start session. */ do_authenticated(ssh, authctxt); -@@ -2470,6 +2512,11 @@ +@@ -2486,6 +2528,11 @@ struct kex *kex; int r; @@ -2548,9 +2548,9 @@ diff -Nur openssh-8.6p1.orig/sshd.c openssh-8.6p1/sshd.c myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, -diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config ---- openssh-8.6p1.orig/sshd_config 2021-05-22 08:23:21.068175759 +0200 -+++ openssh-8.6p1/sshd_config 2021-05-22 08:24:33.561345644 +0200 +diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config +--- openssh-8.7p1.orig/sshd_config 2021-10-24 07:54:36.874834211 +0200 ++++ openssh-8.7p1/sshd_config 2021-10-24 07:56:04.875030058 +0200 @@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2580,9 +2580,9 @@ diff -Nur openssh-8.6p1.orig/sshd_config openssh-8.6p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-8.6p1.orig/version.h openssh-8.6p1/version.h ---- openssh-8.6p1.orig/version.h 2021-05-22 08:23:21.069175761 +0200 -+++ openssh-8.6p1/version.h 2021-05-22 08:24:33.561345644 +0200 +diff -Nur openssh-8.7p1.orig/version.h openssh-8.7p1/version.h +--- openssh-8.7p1.orig/version.h 2021-10-24 07:54:36.876834215 +0200 ++++ openssh-8.7p1/version.h 2021-10-24 07:56:04.876030061 +0200 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" diff --git a/openssh-8.7p1-upstream-cve-2021-41617.patch b/openssh-8.7p1-upstream-cve-2021-41617.patch new file mode 100644 index 0000000..0bca544 --- /dev/null +++ b/openssh-8.7p1-upstream-cve-2021-41617.patch @@ -0,0 +1,31 @@ +diff --git a/misc.c b/misc.c +index b8d1040d..0134d694 100644 +--- a/misc.c ++++ b/misc.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: misc.c,v 1.169 2021/08/09 23:47:44 djm Exp $ */ ++/* $OpenBSD: misc.c,v 1.170 2021/09/26 14:01:03 djm Exp $ */ + /* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2005-2020 Damien Miller. All rights reserved. +@@ -56,6 +56,7 @@ + #ifdef HAVE_PATHS_H + # include + #include ++#include + #endif + #ifdef SSH_TUN_OPENBSD + #include +@@ -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); ++ } + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { + error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, + strerror(errno)); diff --git a/sources b/sources index cbbba40..d393884 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.6p1.tar.gz) = 9854eda0b773c64c9f1f74844ce466b2b42ee8845f58ad062b73141d617af944fa4ebafdf72069f400106d2c2bd0a69c92fe805ec1fc26d4f0faadf06c3fbbe6 -SHA512 (openssh-8.6p1.tar.gz.asc) = ea75d7fe350fd1761ee5490b222249e9b8915b2a02a1d41979195f15d239def387e4c6467362ab9515d517087750fa66bc368f5baa15c325502f725172631967 +SHA512 (openssh-8.7p1.tar.gz) = 08c81024d9e1248abfda6cc874886ff5ae916669b93cd6aff640e0614ee8cbcbc3fe87a9ce47136b6443ddbb1168b114367c74e117551905994e1a7e3fa2c0c2 +SHA512 (openssh-8.7p1.tar.gz.asc) = 08b4bda855ca3ef202c271f1c0e3486082b93d1009a794d020e7ba223978bc87bf34b1fbccaae3379a47639bd849935fdaaf63bdb781d0a44625066ccf00fbfc SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 5d089cb67ff2bd39605b29df293b0261f12f0fb4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 24 Oct 2021 11:05:38 +0200 Subject: [PATCH 102/146] Based on openssh-8.7p1-3.fc36 --- gsi-openssh.spec | 11 +- openssh-8.7p1-scp-kill-switch.patch | 46 ++++++++ openssh-8.7p1-sftp-default-protocol.patch | 129 ++++++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 openssh-8.7p1-scp-kill-switch.patch create mode 100644 openssh-8.7p1-sftp-default-protocol.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 5d75771..7e7ccf0 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ %global libedit 1 %global openssh_ver 8.7p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -149,6 +149,10 @@ Patch966: openssh-8.2p1-x11-without-ipv6.patch Patch974: openssh-8.0p1-keygen-strip-doseol.patch # sshd provides PAM an incorrect error code (#1879503) Patch975: openssh-8.0p1-preserve-pam-errors.patch +# Use SFTP protocol by default for scp command +Patch976: openssh-8.7p1-sftp-default-protocol.patch +# Implement kill switch for SCP protocol +Patch977: openssh-8.7p1-scp-kill-switch.patch # CVE-2021-41617 Patch978: openssh-8.7p1-upstream-cve-2021-41617.patch @@ -299,6 +303,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch966 -p1 -b .x11-ipv6 %patch974 -p1 -b .keygen-strip-doseol %patch975 -p1 -b .preserve-pam-errors +%patch976 -p1 -b .sftp-by-default +%patch977 -p1 -b .kill-scp %patch978 -p1 -b .cve-2021-41617 %patch200 -p1 -b .audit @@ -497,6 +503,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Sun Oct 24 2021 Mattias Ellert - 8.7p1-2 +- Based on openssh-8.7p1-3.fc36 + * Sun Oct 24 2021 Mattias Ellert - 8.7p1-1 - Based on openssh-8.7p1-2.fc35 diff --git a/openssh-8.7p1-scp-kill-switch.patch b/openssh-8.7p1-scp-kill-switch.patch new file mode 100644 index 0000000..6710304 --- /dev/null +++ b/openssh-8.7p1-scp-kill-switch.patch @@ -0,0 +1,46 @@ +diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h +--- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200 ++++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200 +@@ -42,6 +42,7 @@ + #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" + #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" + #define _PATH_DH_MODULI SSHDIR "/moduli" ++#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp" + + #ifndef _PATH_SSH_PROGRAM + #define _PATH_SSH_PROGRAM "/usr/bin/ssh" +diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 +--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200 ++++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200 +@@ -278,6 +278,13 @@ to print debugging messages about their + This is helpful in + debugging connection, authentication, and configuration problems. + .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 -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200 ++++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200 +@@ -596,6 +596,14 @@ main(int argc, char **argv) + if (iamremote) + mode = MODE_SCP; + ++ 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); + diff --git a/openssh-8.7p1-sftp-default-protocol.patch b/openssh-8.7p1-sftp-default-protocol.patch new file mode 100644 index 0000000..ec25944 --- /dev/null +++ b/openssh-8.7p1-sftp-default-protocol.patch @@ -0,0 +1,129 @@ +diff --git a/scp.1 b/scp.1 +index 68aac04b..a96e95ad 100644 +--- a/scp.1 ++++ b/scp.1 +@@ -8,9 +8,9 @@ + .\" + .\" Created: Sun May 7 00:14:37 1995 ylo + .\" +-.\" $OpenBSD: scp.1,v 1.100 2021/08/11 14:07:54 naddy Exp $ ++.\" $OpenBSD: scp.1,v 1.101 2021/09/08 23:31:39 djm Exp $ + .\" +-.Dd $Mdocdate: August 11 2021 $ ++.Dd $Mdocdate: September 8 2021 $ + .Dt SCP 1 + .Os + .Sh NAME +@@ -18,7 +18,7 @@ + .Nd OpenSSH secure file copy + .Sh SYNOPSIS + .Nm scp +-.Op Fl 346ABCOpqRrsTv ++.Op Fl 346ABCOpqRrTv + .Op Fl c Ar cipher + .Op Fl D Ar sftp_server_path + .Op Fl F Ar ssh_config +@@ -37,9 +37,6 @@ It uses + .Xr ssh 1 + for data transfer, and uses the same authentication and provides the + same security as a login session. +-The scp protocol requires execution of the remote user's shell to perform +-.Xr glob 3 +-pattern matching. + .Pp + .Nm + will ask for passwords or passphrases if they are needed for +@@ -79,7 +76,9 @@ The options are as follows: + Copies between two remote hosts are transferred through the local host. + Without this option the data is copied directly between the two remote + hosts. +-Note that, when using the legacy SCP protocol (the default), this option ++Note that, when using the legacy SCP protocol (via the ++.Fl O ++flag), this option + selects batch mode for the second host as + .Nm + cannot ask for passwords or passphrases for both hosts. +@@ -146,9 +145,10 @@ Limits the used bandwidth, specified in Kbit/s. + .It Fl O + Use the legacy SCP protocol for file transfers instead of the SFTP protocol. + Forcing the use of the SCP protocol may be necessary for servers that do +-not implement SFTP or for backwards-compatibility for particular filename +-wildcard patterns. +-This mode is the default. ++not implement SFTP, for backwards-compatibility for particular filename ++wildcard patterns and for expanding paths with a ++.Sq ~ ++prefix for older SFTP servers. + .It Fl o Ar ssh_option + Can be used to pass options to + .Nm ssh +@@ -258,16 +258,6 @@ to use for the encrypted connection. + The program must understand + .Xr ssh 1 + options. +-.It Fl s +-Use the SFTP protocol for file transfers instead of the legacy SCP protocol. +-Using SFTP avoids invoking a shell on the remote side and provides +-more predictable filename handling, as the SCP protocol +-relied on the remote shell for expanding +-.Xr glob 3 +-wildcards. +-.Pp +-A near-future release of OpenSSH will make the SFTP protocol the default. +-This option will be deleted before the end of 2022. + .It Fl T + Disable strict filename checking. + By default when copying files from a remote host to a local directory +@@ -299,11 +289,23 @@ debugging connection, authentication, and configuration problems. + .Xr ssh_config 5 , + .Xr sftp-server 8 , + .Xr sshd 8 ++.Sh CAVEATS ++The original scp protocol (selected by the ++.Fl O ++flag) requires execution of the remote user's shell to perform ++.Xr glob 3 ++pattern matching. ++This requires careful quoting of any characters that have special meaning to ++the remote shell, such as quote characters. + .Sh HISTORY + .Nm + is based on the rcp program in + .Bx + source code from the Regents of the University of California. ++.Pp ++Since OpenSSH 8.8 (8.7 in Red Hat/Fedora builds), ++.Nm ++has use the SFTP protocol for transfers by default. + .Sh AUTHORS + .An Timo Rinne Aq Mt tri@iki.fi + .An Tatu Ylonen Aq Mt ylo@cs.hut.fi +diff --git a/scp.c b/scp.c +index e039350c..c7cf7529 100644 +--- a/scp.c ++++ b/scp.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: scp.c,v 1.232 2021/08/11 14:07:54 naddy Exp $ */ ++/* $OpenBSD: scp.c,v 1.233 2021/09/08 23:31:39 djm Exp $ */ + /* + * scp - secure remote copy. This is basically patched BSD rcp which + * uses ssh to do the data transfer (instead of using rcmd). +@@ -448,7 +448,7 @@ main(int argc, char **argv) + const char *errstr; + extern char *optarg; + extern int optind; +- enum scp_mode_e mode = MODE_SCP; ++ enum scp_mode_e mode = MODE_SFTP; + char *sftp_direct = NULL; + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ +@@ -1983,7 +1983,7 @@ void + usage(void) + { + (void) fprintf(stderr, +- "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" ++ "usage: scp [-346ABCOpqRrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" + " [-i identity_file] [-J destination] [-l limit]\n" + " [-o ssh_option] [-P port] [-S program] source ... target\n"); + exit(1); From 6960e6c5d77f5ad02eca98e93fa7df0013713138 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 1 Dec 2021 17:31:50 +0100 Subject: [PATCH 103/146] Based on openssh-8.8p1-1.fc36 --- gsi-openssh.spec | 14 +- openssh-6.6p1-kuserok.patch | 10 +- openssh-7.3p1-x11-max-displays.patch | 6 +- openssh-7.7p1-fips.patch | 9 +- openssh-7.7p1-gssapi-new-unique.patch | 11 +- openssh-8.0p1-crypto-policies.patch | 25 +- openssh-8.7p1-sftp-default-protocol.patch | 58 +--- openssh-8.7p1-upstream-cve-2021-41617.patch | 31 -- ...gsissh.patch => openssh-8.8p1-gsissh.patch | 268 ++++++++--------- ...h => openssh-8.8p1-hpn-15.2-modified.patch | 282 +++++++++--------- sources | 4 +- 11 files changed, 321 insertions(+), 397 deletions(-) delete mode 100644 openssh-8.7p1-upstream-cve-2021-41617.patch rename openssh-8.7p1-gsissh.patch => openssh-8.8p1-gsissh.patch (90%) rename openssh-8.7p1-hpn-15.2-modified.patch => openssh-8.8p1-hpn-15.2-modified.patch (90%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 7e7ccf0..66318cf 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,8 +27,8 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 8.7p1 -%global openssh_rel 2 +%global openssh_ver 8.8p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -153,19 +153,17 @@ Patch975: openssh-8.0p1-preserve-pam-errors.patch Patch976: openssh-8.7p1-sftp-default-protocol.patch # Implement kill switch for SCP protocol Patch977: openssh-8.7p1-scp-kill-switch.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 -Patch98: openssh-8.7p1-gsissh.patch +Patch98: openssh-8.8p1-gsissh.patch # This is the HPN patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-8.7p1-hpn-15.2-modified.patch +Patch99: openssh-8.8p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -305,7 +303,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch975 -p1 -b .preserve-pam-errors %patch976 -p1 -b .sftp-by-default %patch977 -p1 -b .kill-scp -%patch978 -p1 -b .cve-2021-41617 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -503,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Wed Dec 01 2021 Mattias Ellert - 8.8p1-1 +- Based on openssh-8.8p1-1.fc36 + * Sun Oct 24 2021 Mattias Ellert - 8.7p1-2 - Based on openssh-8.7p1-3.fc36 diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 1831f27..f3231f9 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -196,11 +196,11 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, sKerberosUniqueCCache, -+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, - sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, +- sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, ++ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, @@ -478,12 +481,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index c8a147b..5af3e3b 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -110,9 +110,9 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c options->x11_use_localhost = 1; if (options->xauth_location == NULL) @@ -419,7 +422,7 @@ typedef enum { - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index d2c5592..72bceb1 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -117,9 +117,9 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h --- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 +++ openssh-8.6p1/myproposal.h 2021-04-19 16:53:03.065577869 +0200 -@@ -57,6 +57,20 @@ - "rsa-sha2-256," \ - "ssh-rsa" +@@ -57,6 +57,19 @@ + "rsa-sha2-512," \ + "rsa-sha2-256" +#define KEX_FIPS_PK_ALG \ + "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ @@ -132,8 +132,7 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h + "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp521," \ + "rsa-sha2-512," \ -+ "rsa-sha2-256," \ -+ "ssh-rsa" ++ "rsa-sha2-256," + #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index c130022..544932b 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -503,16 +503,15 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -506,7 +509,8 @@ typedef enum { +@@ -506,7 +509,7 @@ typedef enum { sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, sChallengeResponseAuthentication, -+ sKerberosGetAFSToken, sKerberosUniqueCCache, -+ sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, +- sKerberosGetAFSToken, sPasswordAuthentication, ++ sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, @@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 762825e..2ad438c 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -2,8 +2,8 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 --- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 +++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 @@ -373,17 +373,13 @@ or - .Qq *.c.example.com - domains. + 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 . @@ -105,18 +105,18 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 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 +-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 ++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 methods (including wildcards) will be removed + 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 methods will be placed at the head of the + character, then the specified algorithms will be placed at the head of the -default set. -The default is: -.Bd -literal -offset indent @@ -178,7 +178,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1553,37 +1542,25 @@ instead of continuing to execute and pas +@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -214,12 +214,11 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, --ssh-rsa-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,ssh-rsa +-rsa-sha2-512,rsa-sha2-256 -.Ed +built-in openssh default set. .Pp @@ -373,18 +372,18 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 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 +-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 ++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 methods (including wildcards) will be removed + 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 methods will be placed at the head of the + character, then the specified algorithms will be placed at the head of the -default set. +built-in openssh default set. The supported algorithms are: diff --git a/openssh-8.7p1-sftp-default-protocol.patch b/openssh-8.7p1-sftp-default-protocol.patch index ec25944..c3527b1 100644 --- a/openssh-8.7p1-sftp-default-protocol.patch +++ b/openssh-8.7p1-sftp-default-protocol.patch @@ -2,18 +2,6 @@ diff --git a/scp.1 b/scp.1 index 68aac04b..a96e95ad 100644 --- a/scp.1 +++ b/scp.1 -@@ -8,9 +8,9 @@ - .\" - .\" Created: Sun May 7 00:14:37 1995 ylo - .\" --.\" $OpenBSD: scp.1,v 1.100 2021/08/11 14:07:54 naddy Exp $ -+.\" $OpenBSD: scp.1,v 1.101 2021/09/08 23:31:39 djm Exp $ - .\" --.Dd $Mdocdate: August 11 2021 $ -+.Dd $Mdocdate: September 8 2021 $ - .Dt SCP 1 - .Os - .Sh NAME @@ -18,7 +18,7 @@ .Nd OpenSSH secure file copy .Sh SYNOPSIS @@ -23,55 +11,31 @@ index 68aac04b..a96e95ad 100644 .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config -@@ -37,9 +37,6 @@ It uses - .Xr ssh 1 - for data transfer, and uses the same authentication and provides the - same security as a login session. --The scp protocol requires execution of the remote user's shell to perform --.Xr glob 3 --pattern matching. - .Pp - .Nm - will ask for passwords or passphrases if they are needed for @@ -79,7 +76,9 @@ The options are as follows: Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts. --Note that, when using the legacy SCP protocol (the default), this option -+Note that, when using the legacy SCP protocol (via the +-Note that, when using the original SCP protocol (the default), this option ++Note that, when using the original SCP protocol (via the +.Fl O +flag), this option selects batch mode for the second host as .Nm cannot ask for passwords or passphrases for both hosts. -@@ -146,9 +145,10 @@ Limits the used bandwidth, specified in Kbit/s. - .It Fl O - Use the legacy SCP protocol for file transfers instead of the SFTP protocol. - Forcing the use of the SCP protocol may be necessary for servers that do --not implement SFTP or for backwards-compatibility for particular filename --wildcard patterns. +@@ -146,7 +145,6 @@ Limits the used bandwidth, specified in Kbit/s. + wildcard patterns and for expanding paths with a + .Sq ~ + prefix for older SFTP servers. -This mode is the default. -+not implement SFTP, for backwards-compatibility for particular filename -+wildcard patterns and for expanding paths with a -+.Sq ~ -+prefix for older SFTP servers. .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh -@@ -258,16 +258,6 @@ to use for the encrypted connection. +@@ -258,8 +258,6 @@ to use for the encrypted connection. The program must understand .Xr ssh 1 options. -.It Fl s --Use the SFTP protocol for file transfers instead of the legacy SCP protocol. --Using SFTP avoids invoking a shell on the remote side and provides --more predictable filename handling, as the SCP protocol --relied on the remote shell for expanding --.Xr glob 3 --wildcards. --.Pp --A near-future release of OpenSSH will make the SFTP protocol the default. --This option will be deleted before the end of 2022. +-Use the SFTP protocol for transfers rather than the original scp protocol. .It Fl T Disable strict filename checking. By default when copying files from a remote host to a local directory @@ -103,12 +67,6 @@ diff --git a/scp.c b/scp.c index e039350c..c7cf7529 100644 --- a/scp.c +++ b/scp.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: scp.c,v 1.232 2021/08/11 14:07:54 naddy Exp $ */ -+/* $OpenBSD: scp.c,v 1.233 2021/09/08 23:31:39 djm Exp $ */ - /* - * scp - secure remote copy. This is basically patched BSD rcp which - * uses ssh to do the data transfer (instead of using rcmd). @@ -448,7 +448,7 @@ main(int argc, char **argv) const char *errstr; extern char *optarg; diff --git a/openssh-8.7p1-upstream-cve-2021-41617.patch b/openssh-8.7p1-upstream-cve-2021-41617.patch deleted file mode 100644 index 0bca544..0000000 --- a/openssh-8.7p1-upstream-cve-2021-41617.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/misc.c b/misc.c -index b8d1040d..0134d694 100644 ---- a/misc.c -+++ b/misc.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: misc.c,v 1.169 2021/08/09 23:47:44 djm Exp $ */ -+/* $OpenBSD: misc.c,v 1.170 2021/09/26 14:01:03 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2005-2020 Damien Miller. All rights reserved. -@@ -56,6 +56,7 @@ - #ifdef HAVE_PATHS_H - # include - #include -+#include - #endif - #ifdef SSH_TUN_OPENBSD - #include -@@ -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); -+ } - if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { - error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, - strerror(errno)); diff --git a/openssh-8.7p1-gsissh.patch b/openssh-8.8p1-gsissh.patch similarity index 90% rename from openssh-8.7p1-gsissh.patch rename to openssh-8.8p1-gsissh.patch index f19161c..04d640a 100644 --- a/openssh-8.7p1-gsissh.patch +++ b/openssh-8.8p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c ---- openssh-8.7p1.orig/auth2.c 2021-10-24 07:32:35.517723813 +0200 -+++ openssh-8.7p1/auth2.c 2021-10-24 07:33:38.862876709 +0200 +diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c +--- openssh-8.8p1.orig/auth2.c 2021-12-01 16:47:29.945987883 +0100 ++++ openssh-8.8p1/auth2.c 2021-12-01 16:48:10.374080945 +0100 @@ -277,7 +277,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -100,9 +100,9 @@ diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.7p1.orig/auth2-gss.c openssh-8.7p1/auth2-gss.c ---- openssh-8.7p1.orig/auth2-gss.c 2021-10-24 07:32:35.388723503 +0200 -+++ openssh-8.7p1/auth2-gss.c 2021-10-24 07:33:38.863876712 +0200 +diff -Nur openssh-8.8p1.orig/auth2-gss.c openssh-8.8p1/auth2-gss.c +--- openssh-8.8p1.orig/auth2-gss.c 2021-12-01 16:47:29.832987623 +0100 ++++ openssh-8.8p1/auth2-gss.c 2021-12-01 16:48:10.375080947 +0100 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -307,9 +307,9 @@ diff -Nur openssh-8.7p1.orig/auth2-gss.c openssh-8.7p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.7p1.orig/auth.c openssh-8.7p1/auth.c ---- openssh-8.7p1.orig/auth.c 2021-10-24 07:32:35.519723818 +0200 -+++ openssh-8.7p1/auth.c 2021-10-24 07:33:38.864876714 +0200 +diff -Nur openssh-8.8p1.orig/auth.c openssh-8.8p1/auth.c +--- openssh-8.8p1.orig/auth.c 2021-12-01 16:47:29.946987886 +0100 ++++ openssh-8.8p1/auth.c 2021-12-01 16:48:10.375080947 +0100 @@ -344,7 +344,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -340,9 +340,9 @@ diff -Nur openssh-8.7p1.orig/auth.c openssh-8.7p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.7p1.orig/auth.h openssh-8.7p1/auth.h ---- openssh-8.7p1.orig/auth.h 2021-10-24 07:32:35.519723818 +0200 -+++ openssh-8.7p1/auth.h 2021-10-24 07:33:38.864876714 +0200 +diff -Nur openssh-8.8p1.orig/auth.h openssh-8.8p1/auth.h +--- openssh-8.8p1.orig/auth.h 2021-12-01 16:47:29.946987886 +0100 ++++ openssh-8.8p1/auth.h 2021-12-01 16:48:10.376080950 +0100 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +352,9 @@ diff -Nur openssh-8.7p1.orig/auth.h openssh-8.7p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.7p1.orig/auth-pam.c openssh-8.7p1/auth-pam.c ---- openssh-8.7p1.orig/auth-pam.c 2021-10-24 07:32:35.510723796 +0200 -+++ openssh-8.7p1/auth-pam.c 2021-10-24 07:33:38.865876716 +0200 +diff -Nur openssh-8.8p1.orig/auth-pam.c openssh-8.8p1/auth-pam.c +--- openssh-8.8p1.orig/auth-pam.c 2021-12-01 16:47:29.937987865 +0100 ++++ openssh-8.8p1/auth-pam.c 2021-12-01 16:48:10.376080950 +0100 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -486,7 +486,7 @@ diff -Nur openssh-8.7p1.orig/auth-pam.c openssh-8.7p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1082,6 +1162,18 @@ +@@ -1083,6 +1163,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -505,7 +505,7 @@ diff -Nur openssh-8.7p1.orig/auth-pam.c openssh-8.7p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1370,6 +1462,9 @@ +@@ -1371,6 +1463,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -515,9 +515,9 @@ diff -Nur openssh-8.7p1.orig/auth-pam.c openssh-8.7p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.7p1.orig/auth-pam.h openssh-8.7p1/auth-pam.h ---- openssh-8.7p1.orig/auth-pam.h 2021-10-24 07:32:35.356723425 +0200 -+++ openssh-8.7p1/auth-pam.h 2021-10-24 07:33:38.865876716 +0200 +diff -Nur openssh-8.8p1.orig/auth-pam.h openssh-8.8p1/auth-pam.h +--- openssh-8.8p1.orig/auth-pam.h 2021-12-01 16:47:29.797987543 +0100 ++++ openssh-8.8p1/auth-pam.h 2021-12-01 16:48:10.377080952 +0100 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +525,9 @@ diff -Nur openssh-8.7p1.orig/auth-pam.h openssh-8.7p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.7p1.orig/canohost.c openssh-8.7p1/canohost.c ---- openssh-8.7p1.orig/canohost.c 2021-10-24 07:32:35.388723503 +0200 -+++ openssh-8.7p1/canohost.c 2021-10-24 07:33:38.866876718 +0200 +diff -Nur openssh-8.8p1.orig/canohost.c openssh-8.8p1/canohost.c +--- openssh-8.8p1.orig/canohost.c 2021-12-01 16:47:29.833987626 +0100 ++++ openssh-8.8p1/canohost.c 2021-12-01 16:48:10.377080952 +0100 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +570,9 @@ diff -Nur openssh-8.7p1.orig/canohost.c openssh-8.7p1/canohost.c + } + } +} -diff -Nur openssh-8.7p1.orig/canohost.h openssh-8.7p1/canohost.h ---- openssh-8.7p1.orig/canohost.h 2021-10-24 07:32:35.388723503 +0200 -+++ openssh-8.7p1/canohost.h 2021-10-24 07:33:38.866876718 +0200 +diff -Nur openssh-8.8p1.orig/canohost.h openssh-8.8p1/canohost.h +--- openssh-8.8p1.orig/canohost.h 2021-12-01 16:47:29.833987626 +0100 ++++ openssh-8.8p1/canohost.h 2021-12-01 16:48:10.377080952 +0100 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,10 +580,10 @@ diff -Nur openssh-8.7p1.orig/canohost.h openssh-8.7p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.7p1.orig/configure.ac openssh-8.7p1/configure.ac ---- openssh-8.7p1.orig/configure.ac 2021-10-24 07:32:35.498723767 +0200 -+++ openssh-8.7p1/configure.ac 2021-10-24 07:49:48.431180638 +0200 -@@ -4777,6 +4777,14 @@ +diff -Nur openssh-8.8p1.orig/configure.ac openssh-8.8p1/configure.ac +--- openssh-8.8p1.orig/configure.ac 2021-12-01 16:47:29.928987844 +0100 ++++ openssh-8.8p1/configure.ac 2021-12-01 16:48:10.378080954 +0100 +@@ -4775,6 +4775,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -598,7 +598,7 @@ diff -Nur openssh-8.7p1.orig/configure.ac openssh-8.7p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4817,6 +4825,40 @@ +@@ -4815,6 +4823,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,9 +639,9 @@ diff -Nur openssh-8.7p1.orig/configure.ac openssh-8.7p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.7p1.orig/gss-genr.c openssh-8.7p1/gss-genr.c ---- openssh-8.7p1.orig/gss-genr.c 2021-10-24 07:32:35.551723895 +0200 -+++ openssh-8.7p1/gss-genr.c 2021-10-24 07:33:38.870876728 +0200 +diff -Nur openssh-8.8p1.orig/gss-genr.c openssh-8.8p1/gss-genr.c +--- openssh-8.8p1.orig/gss-genr.c 2021-12-01 16:47:29.973987948 +0100 ++++ openssh-8.8p1/gss-genr.c 2021-12-01 16:48:10.379080957 +0100 @@ -40,6 +40,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -678,9 +678,9 @@ diff -Nur openssh-8.7p1.orig/gss-genr.c openssh-8.7p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.7p1.orig/gss-serv.c openssh-8.7p1/gss-serv.c ---- openssh-8.7p1.orig/gss-serv.c 2021-10-24 07:32:35.410723555 +0200 -+++ openssh-8.7p1/gss-serv.c 2021-10-24 07:33:38.870876728 +0200 +diff -Nur openssh-8.8p1.orig/gss-serv.c openssh-8.8p1/gss-serv.c +--- openssh-8.8p1.orig/gss-serv.c 2021-12-01 16:47:29.853987672 +0100 ++++ openssh-8.8p1/gss-serv.c 2021-12-01 16:48:10.379080957 +0100 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +961,9 @@ diff -Nur openssh-8.7p1.orig/gss-serv.c openssh-8.7p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.7p1.orig/gss-serv-gsi.c openssh-8.7p1/gss-serv-gsi.c ---- openssh-8.7p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.7p1/gss-serv-gsi.c 2021-10-24 07:33:38.871876730 +0200 +diff -Nur openssh-8.8p1.orig/gss-serv-gsi.c openssh-8.8p1/gss-serv-gsi.c +--- openssh-8.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.8p1/gss-serv-gsi.c 2021-12-01 16:48:10.380080959 +0100 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1293,9 @@ diff -Nur openssh-8.7p1.orig/gss-serv-gsi.c openssh-8.7p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.7p1.orig/gss-serv-krb5.c openssh-8.7p1/gss-serv-krb5.c ---- openssh-8.7p1.orig/gss-serv-krb5.c 2021-10-24 07:32:35.440723628 +0200 -+++ openssh-8.7p1/gss-serv-krb5.c 2021-10-24 07:33:38.871876730 +0200 +diff -Nur openssh-8.8p1.orig/gss-serv-krb5.c openssh-8.8p1/gss-serv-krb5.c +--- openssh-8.8p1.orig/gss-serv-krb5.c 2021-12-01 16:47:29.878987729 +0100 ++++ openssh-8.8p1/gss-serv-krb5.c 2021-12-01 16:48:10.380080959 +0100 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1349,9 @@ diff -Nur openssh-8.7p1.orig/gss-serv-krb5.c openssh-8.7p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.7p1.orig/kexgsss.c openssh-8.7p1/kexgsss.c ---- openssh-8.7p1.orig/kexgsss.c 2021-10-24 07:32:35.567723933 +0200 -+++ openssh-8.7p1/kexgsss.c 2021-10-24 07:33:38.871876730 +0200 +diff -Nur openssh-8.8p1.orig/kexgsss.c openssh-8.8p1/kexgsss.c +--- openssh-8.8p1.orig/kexgsss.c 2021-12-01 16:47:29.986987978 +0100 ++++ openssh-8.8p1/kexgsss.c 2021-12-01 16:48:10.380080959 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1415,9 +1415,9 @@ diff -Nur openssh-8.7p1.orig/kexgsss.c openssh-8.7p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in ---- openssh-8.7p1.orig/Makefile.in 2021-10-24 07:32:35.522723825 +0200 -+++ openssh-8.7p1/Makefile.in 2021-10-24 07:33:38.872876733 +0200 +diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in +--- openssh-8.8p1.orig/Makefile.in 2021-12-01 16:47:29.948987890 +0100 ++++ openssh-8.8p1/Makefile.in 2021-12-01 16:48:10.381080961 +0100 @@ -128,6 +128,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1426,9 +1426,9 @@ diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-8.7p1.orig/misc.c openssh-8.7p1/misc.c ---- openssh-8.7p1.orig/misc.c 2021-10-24 07:32:35.553723900 +0200 -+++ openssh-8.7p1/misc.c 2021-10-24 07:33:38.873876735 +0200 +diff -Nur openssh-8.8p1.orig/misc.c openssh-8.8p1/misc.c +--- openssh-8.8p1.orig/misc.c 2021-12-01 16:47:29.975987952 +0100 ++++ openssh-8.8p1/misc.c 2021-12-01 16:48:10.381080961 +0100 @@ -393,11 +393,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1488,9 +1488,9 @@ diff -Nur openssh-8.7p1.orig/misc.c openssh-8.7p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.7p1.orig/misc.h openssh-8.7p1/misc.h ---- openssh-8.7p1.orig/misc.h 2021-10-24 07:32:35.466723690 +0200 -+++ openssh-8.7p1/misc.h 2021-10-24 07:33:38.874876737 +0200 +diff -Nur openssh-8.8p1.orig/misc.h openssh-8.8p1/misc.h +--- openssh-8.8p1.orig/misc.h 2021-12-01 16:47:29.902987784 +0100 ++++ openssh-8.8p1/misc.h 2021-12-01 16:48:10.381080961 +0100 @@ -100,6 +100,7 @@ void sock_set_v6only(int); @@ -1499,9 +1499,9 @@ diff -Nur openssh-8.7p1.orig/misc.h openssh-8.7p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-8.7p1.orig/monitor.c openssh-8.7p1/monitor.c ---- openssh-8.7p1.orig/monitor.c 2021-10-24 07:32:35.554723902 +0200 -+++ openssh-8.7p1/monitor.c 2021-10-24 07:33:38.875876740 +0200 +diff -Nur openssh-8.8p1.orig/monitor.c openssh-8.8p1/monitor.c +--- openssh-8.8p1.orig/monitor.c 2021-12-01 16:47:29.975987952 +0100 ++++ openssh-8.8p1/monitor.c 2021-12-01 16:48:10.382080964 +0100 @@ -152,6 +152,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.7p1.orig/monitor.c openssh-8.7p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.7p1.orig/monitor.h openssh-8.7p1/monitor.h ---- openssh-8.7p1.orig/monitor.h 2021-10-24 07:32:35.523723828 +0200 -+++ openssh-8.7p1/monitor.h 2021-10-24 07:33:38.876876743 +0200 +diff -Nur openssh-8.8p1.orig/monitor.h openssh-8.8p1/monitor.h +--- openssh-8.8p1.orig/monitor.h 2021-12-01 16:47:29.951987897 +0100 ++++ openssh-8.8p1/monitor.h 2021-12-01 16:48:10.382080964 +0100 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,9 +1686,9 @@ diff -Nur openssh-8.7p1.orig/monitor.h openssh-8.7p1/monitor.h }; struct ssh; -diff -Nur openssh-8.7p1.orig/monitor_wrap.c openssh-8.7p1/monitor_wrap.c ---- openssh-8.7p1.orig/monitor_wrap.c 2021-10-24 07:32:35.555723904 +0200 -+++ openssh-8.7p1/monitor_wrap.c 2021-10-24 07:33:38.876876743 +0200 +diff -Nur openssh-8.8p1.orig/monitor_wrap.c openssh-8.8p1/monitor_wrap.c +--- openssh-8.8p1.orig/monitor_wrap.c 2021-12-01 16:47:29.976987955 +0100 ++++ openssh-8.8p1/monitor_wrap.c 2021-12-01 16:48:10.383080966 +0100 @@ -1084,6 +1084,94 @@ return (authenticated); } @@ -1784,9 +1784,9 @@ diff -Nur openssh-8.7p1.orig/monitor_wrap.c openssh-8.7p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.7p1.orig/monitor_wrap.h openssh-8.7p1/monitor_wrap.h ---- openssh-8.7p1.orig/monitor_wrap.h 2021-10-24 07:32:35.533723852 +0200 -+++ openssh-8.7p1/monitor_wrap.h 2021-10-24 07:33:38.877876745 +0200 +diff -Nur openssh-8.8p1.orig/monitor_wrap.h openssh-8.8p1/monitor_wrap.h +--- openssh-8.8p1.orig/monitor_wrap.h 2021-12-01 16:47:29.959987916 +0100 ++++ openssh-8.8p1/monitor_wrap.h 2021-12-01 16:48:10.384080968 +0100 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-8.7p1.orig/monitor_wrap.h openssh-8.7p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c ---- openssh-8.7p1.orig/readconf.c 2021-10-24 07:32:35.557723909 +0200 -+++ openssh-8.7p1/readconf.c 2021-10-24 07:33:38.878876747 +0200 -@@ -2516,11 +2516,11 @@ +diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c +--- openssh-8.8p1.orig/readconf.c 2021-12-01 16:47:29.977987957 +0100 ++++ openssh-8.8p1/readconf.c 2021-12-01 16:48:10.384080968 +0100 +@@ -2543,11 +2543,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; if (options->gss_authentication == -1) @@ -1816,9 +1816,9 @@ diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h ---- openssh-8.7p1.orig/readconf.h 2021-10-24 07:32:35.395723519 +0200 -+++ openssh-8.7p1/readconf.h 2021-10-24 07:33:38.879876750 +0200 +diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h +--- openssh-8.8p1.orig/readconf.h 2021-12-01 16:47:29.840987642 +0100 ++++ openssh-8.8p1/readconf.h 2021-12-01 16:48:10.385080970 +0100 @@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c ---- openssh-8.7p1.orig/servconf.c 2021-10-24 07:32:35.558723912 +0200 -+++ openssh-8.7p1/servconf.c 2021-10-24 07:33:38.880876752 +0200 +diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c +--- openssh-8.8p1.orig/servconf.c 2021-12-01 16:47:29.978987959 +0100 ++++ openssh-8.8p1/servconf.c 2021-12-01 16:48:10.386080973 +0100 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -535,6 +544,9 @@ +@@ -533,6 +542,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -567,8 +579,10 @@ +@@ -565,8 +577,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -621,8 +635,15 @@ +@@ -619,8 +633,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -630,8 +651,11 @@ +@@ -628,8 +649,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -703,6 +727,8 @@ +@@ -701,6 +725,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1381,6 +1407,10 @@ +@@ -1379,6 +1405,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1628,6 +1658,10 @@ +@@ -1626,6 +1656,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1636,6 +1670,10 @@ +@@ -1634,6 +1668,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1656,6 +1694,12 @@ +@@ -1654,6 +1692,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2661,6 +2705,7 @@ +@@ -2659,6 +2703,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,9 +2001,9 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h ---- openssh-8.7p1.orig/servconf.h 2021-10-24 07:32:35.456723666 +0200 -+++ openssh-8.7p1/servconf.h 2021-10-24 07:33:38.881876754 +0200 +diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h +--- openssh-8.8p1.orig/servconf.h 2021-12-01 16:47:29.894987766 +0100 ++++ openssh-8.8p1/servconf.h 2021-12-01 16:48:10.387080975 +0100 @@ -146,9 +146,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2025,10 +2025,10 @@ diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h int permit_tun; -diff -Nur openssh-8.7p1.orig/ssh.1 openssh-8.7p1/ssh.1 ---- openssh-8.7p1.orig/ssh.1 2021-10-24 07:32:35.397723524 +0200 -+++ openssh-8.7p1/ssh.1 2021-10-24 07:33:38.882876757 +0200 -@@ -1492,6 +1492,18 @@ +diff -Nur openssh-8.8p1.orig/ssh.1 openssh-8.8p1/ssh.1 +--- openssh-8.8p1.orig/ssh.1 2021-12-01 16:47:29.843987649 +0100 ++++ openssh-8.8p1/ssh.1 2021-12-01 16:48:10.387080975 +0100 +@@ -1501,6 +1501,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-8.7p1.orig/ssh.1 openssh-8.7p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c ---- openssh-8.7p1.orig/ssh.c 2021-10-24 07:32:35.562723921 +0200 -+++ openssh-8.7p1/ssh.c 2021-10-24 07:33:38.883876759 +0200 -@@ -558,6 +558,38 @@ +diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c +--- openssh-8.8p1.orig/ssh.c 2021-12-01 16:47:29.981987966 +0100 ++++ openssh-8.8p1/ssh.c 2021-12-01 16:48:10.388080977 +0100 +@@ -559,6 +559,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,7 +2089,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1236,8 +1268,12 @@ +@@ -1237,8 +1269,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2103,9 +2103,9 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-8.7p1.orig/ssh_config openssh-8.7p1/ssh_config ---- openssh-8.7p1.orig/ssh_config 2021-10-24 07:32:35.398723526 +0200 -+++ openssh-8.7p1/ssh_config 2021-10-24 07:33:38.884876762 +0200 +diff -Nur openssh-8.8p1.orig/ssh_config openssh-8.8p1/ssh_config +--- openssh-8.8p1.orig/ssh_config 2021-12-01 16:47:29.843987649 +0100 ++++ openssh-8.8p1/ssh_config 2021-12-01 16:48:10.388080977 +0100 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.7p1.orig/ssh_config openssh-8.7p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 ---- openssh-8.7p1.orig/ssh_config.5 2021-10-24 07:32:35.489723746 +0200 -+++ openssh-8.7p1/ssh_config.5 2021-10-24 07:33:38.885876764 +0200 +diff -Nur openssh-8.8p1.orig/ssh_config.5 openssh-8.8p1/ssh_config.5 +--- openssh-8.8p1.orig/ssh_config.5 2021-12-01 16:47:29.920987826 +0100 ++++ openssh-8.8p1/ssh_config.5 2021-12-01 16:48:10.389080980 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -821,7 +827,7 @@ +@@ -826,7 +832,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -829,12 +835,12 @@ +@@ -834,12 +840,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1458,7 +1464,7 @@ +@@ -1461,7 +1467,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,9 +2168,9 @@ diff -Nur openssh-8.7p1.orig/ssh_config.5 openssh-8.7p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c ---- openssh-8.7p1.orig/sshconnect2.c 2021-10-24 07:32:35.542723873 +0200 -+++ openssh-8.7p1/sshconnect2.c 2021-10-24 07:33:38.886876767 +0200 +diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c +--- openssh-8.8p1.orig/sshconnect2.c 2021-12-01 16:47:29.966987932 +0100 ++++ openssh-8.8p1/sshconnect2.c 2021-12-01 16:48:10.390080982 +0100 @@ -860,6 +860,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2238,10 +2238,10 @@ diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.7p1.orig/sshd.8 openssh-8.7p1/sshd.8 ---- openssh-8.7p1.orig/sshd.8 2021-10-24 07:32:35.418723575 +0200 -+++ openssh-8.7p1/sshd.8 2021-10-24 07:33:38.887876769 +0200 -@@ -818,6 +818,29 @@ +diff -Nur openssh-8.8p1.orig/sshd.8 openssh-8.8p1/sshd.8 +--- openssh-8.8p1.orig/sshd.8 2021-12-01 16:47:29.861987690 +0100 ++++ openssh-8.8p1/sshd.8 2021-12-01 16:48:10.390080982 +0100 +@@ -823,6 +823,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2271,9 +2271,9 @@ diff -Nur openssh-8.7p1.orig/sshd.8 openssh-8.7p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c ---- openssh-8.7p1.orig/sshd.c 2021-10-24 07:32:35.563723924 +0200 -+++ openssh-8.7p1/sshd.c 2021-10-24 07:33:38.888876772 +0200 +diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c +--- openssh-8.8p1.orig/sshd.c 2021-12-01 16:47:29.982987968 +0100 ++++ openssh-8.8p1/sshd.c 2021-12-01 16:48:10.391080984 +0100 @@ -2380,7 +2380,7 @@ #endif @@ -2283,9 +2283,9 @@ diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config ---- openssh-8.7p1.orig/sshd_config 2021-10-24 07:32:35.443723635 +0200 -+++ openssh-8.7p1/sshd_config 2021-10-24 07:33:38.889876774 +0200 +diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config +--- openssh-8.8p1.orig/sshd_config 2021-12-01 16:47:29.880987734 +0100 ++++ openssh-8.8p1/sshd_config 2021-12-01 16:48:10.392080987 +0100 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,9 +2311,9 @@ diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.7p1.orig/sshd_config.5 openssh-8.7p1/sshd_config.5 ---- openssh-8.7p1.orig/sshd_config.5 2021-10-24 07:32:35.490723748 +0200 -+++ openssh-8.7p1/sshd_config.5 2021-10-24 07:33:38.890876776 +0200 +diff -Nur openssh-8.8p1.orig/sshd_config.5 openssh-8.8p1/sshd_config.5 +--- openssh-8.8p1.orig/sshd_config.5 2021-12-01 16:47:29.920987826 +0100 ++++ openssh-8.8p1/sshd_config.5 2021-12-01 16:48:10.392080987 +0100 @@ -635,15 +635,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2372,9 +2372,9 @@ diff -Nur openssh-8.7p1.orig/sshd_config.5 openssh-8.7p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.7p1.orig/sshd_config_redhat openssh-8.7p1/sshd_config_redhat ---- openssh-8.7p1.orig/sshd_config_redhat 2021-10-24 07:32:35.382723488 +0200 -+++ openssh-8.7p1/sshd_config_redhat 2021-10-24 07:33:38.891876779 +0200 +diff -Nur openssh-8.8p1.orig/sshd_config_redhat openssh-8.8p1/sshd_config_redhat +--- openssh-8.8p1.orig/sshd_config_redhat 2021-12-01 16:47:29.826987609 +0100 ++++ openssh-8.8p1/sshd_config_redhat 2021-12-01 16:48:10.392080987 +0100 @@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-8.7p1.orig/sshd_config_redhat openssh-8.7p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.7p1.orig/ssh-gss.h openssh-8.7p1/ssh-gss.h ---- openssh-8.7p1.orig/ssh-gss.h 2021-10-24 07:32:35.415723567 +0200 -+++ openssh-8.7p1/ssh-gss.h 2021-10-24 07:33:38.891876779 +0200 +diff -Nur openssh-8.8p1.orig/ssh-gss.h openssh-8.8p1/ssh-gss.h +--- openssh-8.8p1.orig/ssh-gss.h 2021-12-01 16:47:29.857987681 +0100 ++++ openssh-8.8p1/ssh-gss.h 2021-12-01 16:48:10.393080989 +0100 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-8.7p1.orig/ssh-gss.h openssh-8.7p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.7p1.orig/version.h openssh-8.7p1/version.h ---- openssh-8.7p1.orig/version.h 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/version.h 2021-10-24 07:33:38.891876779 +0200 +diff -Nur openssh-8.8p1.orig/version.h openssh-8.8p1/version.h +--- openssh-8.8p1.orig/version.h 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/version.h 2021-12-01 16:48:10.393080989 +0100 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.7" + #define SSH_VERSION "OpenSSH_8.8" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.7p1-hpn-15.2-modified.patch b/openssh-8.8p1-hpn-15.2-modified.patch similarity index 90% rename from openssh-8.7p1-hpn-15.2-modified.patch rename to openssh-8.8p1-hpn-15.2-modified.patch index 75a4908..4f68944 100644 --- a/openssh-8.7p1-hpn-15.2-modified.patch +++ b/openssh-8.8p1-hpn-15.2-modified.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c ---- openssh-8.7p1.orig/auth2.c 2021-10-24 07:54:36.863834186 +0200 -+++ openssh-8.7p1/auth2.c 2021-10-24 07:56:04.844029990 +0200 +diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c +--- openssh-8.8p1.orig/auth2.c 2021-12-01 16:50:22.511385558 +0100 ++++ openssh-8.8p1/auth2.c 2021-12-01 16:51:00.919474114 +0100 @@ -53,6 +53,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -31,9 +31,9 @@ diff -Nur openssh-8.7p1.orig/auth2.c openssh-8.7p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c ---- openssh-8.7p1.orig/channels.c 2021-10-24 07:54:36.849834155 +0200 -+++ openssh-8.7p1/channels.c 2021-10-24 07:56:04.845029992 +0200 +diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c +--- openssh-8.8p1.orig/channels.c 2021-12-01 16:50:22.496385524 +0100 ++++ openssh-8.8p1/channels.c 2021-12-01 16:51:00.921474119 +0100 @@ -220,6 +220,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -52,7 +52,7 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1108,6 +1112,28 @@ +@@ -1110,6 +1114,28 @@ FD_SET(c->sock, writeset); } @@ -81,7 +81,7 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c, fd_set *readset, fd_set *writeset) -@@ -2147,22 +2173,31 @@ +@@ -2149,22 +2175,31 @@ if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && @@ -118,7 +118,7 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c c->local_consumed = 0; } return 1; -@@ -3329,6 +3364,14 @@ +@@ -3331,6 +3366,14 @@ return addr; } @@ -133,7 +133,7 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -@@ -3468,8 +3511,10 @@ +@@ -3470,8 +3513,10 @@ } /* Allocate a channel number for the socket. */ @@ -145,7 +145,7 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; -@@ -4655,7 +4700,8 @@ +@@ -4657,7 +4702,8 @@ sock = socks[n]; nc = channel_new(ssh, "x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, @@ -155,9 +155,9 @@ diff -Nur openssh-8.7p1.orig/channels.c openssh-8.7p1/channels.c 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; -diff -Nur openssh-8.7p1.orig/channels.h openssh-8.7p1/channels.h ---- openssh-8.7p1.orig/channels.h 2021-10-24 07:54:36.785834012 +0200 -+++ openssh-8.7p1/channels.h 2021-10-24 07:56:04.846029995 +0200 +diff -Nur openssh-8.8p1.orig/channels.h openssh-8.8p1/channels.h +--- openssh-8.8p1.orig/channels.h 2021-12-01 16:50:22.421385351 +0100 ++++ openssh-8.8p1/channels.h 2021-12-01 16:51:00.922474121 +0100 @@ -169,8 +169,10 @@ u_int local_window_max; u_int local_consumed; @@ -186,9 +186,9 @@ diff -Nur openssh-8.7p1.orig/channels.h openssh-8.7p1/channels.h +void channel_set_hpn(int, int); + #endif -diff -Nur openssh-8.7p1.orig/cipher.c openssh-8.7p1/cipher.c ---- openssh-8.7p1.orig/cipher.c 2021-10-24 07:54:36.828834108 +0200 -+++ openssh-8.7p1/cipher.c 2021-10-24 07:56:04.847029997 +0200 +diff -Nur openssh-8.8p1.orig/cipher.c openssh-8.8p1/cipher.c +--- openssh-8.8p1.orig/cipher.c 2021-12-01 16:50:22.475385475 +0100 ++++ openssh-8.8p1/cipher.c 2021-12-01 16:51:00.923474123 +0100 @@ -48,6 +48,7 @@ #include "sshbuf.h" #include "ssherr.h" @@ -269,9 +269,9 @@ diff -Nur openssh-8.7p1.orig/cipher.c openssh-8.7p1/cipher.c free(cipher_list); return 0; } -diff -Nur openssh-8.7p1.orig/cipher-ctr-mt.c openssh-8.7p1/cipher-ctr-mt.c ---- openssh-8.7p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.7p1/cipher-ctr-mt.c 2021-10-24 07:56:04.848029999 +0200 +diff -Nur openssh-8.8p1.orig/cipher-ctr-mt.c openssh-8.8p1/cipher-ctr-mt.c +--- openssh-8.8p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.8p1/cipher-ctr-mt.c 2021-12-01 16:51:00.923474123 +0100 @@ -0,0 +1,678 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -951,9 +951,9 @@ diff -Nur openssh-8.7p1.orig/cipher-ctr-mt.c openssh-8.7p1/cipher-ctr-mt.c +} + +#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-8.7p1.orig/cipher.h openssh-8.7p1/cipher.h ---- openssh-8.7p1.orig/cipher.h 2021-10-24 07:54:36.829834110 +0200 -+++ openssh-8.7p1/cipher.h 2021-10-24 07:56:04.848029999 +0200 +diff -Nur openssh-8.8p1.orig/cipher.h openssh-8.8p1/cipher.h +--- openssh-8.8p1.orig/cipher.h 2021-12-01 16:50:22.475385475 +0100 ++++ openssh-8.8p1/cipher.h 2021-12-01 16:51:00.924474126 +0100 @@ -68,7 +68,9 @@ struct sshcipher_ctx; @@ -974,10 +974,10 @@ diff -Nur openssh-8.7p1.orig/cipher.h openssh-8.7p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-8.7p1.orig/clientloop.c openssh-8.7p1/clientloop.c ---- openssh-8.7p1.orig/clientloop.c 2021-10-24 07:54:36.738833908 +0200 -+++ openssh-8.7p1/clientloop.c 2021-10-24 07:56:04.849030001 +0200 -@@ -1582,7 +1582,9 @@ +diff -Nur openssh-8.8p1.orig/clientloop.c openssh-8.8p1/clientloop.c +--- openssh-8.8p1.orig/clientloop.c 2021-12-01 16:50:22.361385212 +0100 ++++ openssh-8.8p1/clientloop.c 2021-12-01 16:51:00.925474128 +0100 +@@ -1583,7 +1583,9 @@ return NULL; c = channel_new(ssh, "x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, @@ -988,7 +988,7 @@ diff -Nur openssh-8.7p1.orig/clientloop.c openssh-8.7p1/clientloop.c c->force_drain = 1; return c; } -@@ -1611,7 +1613,8 @@ +@@ -1612,7 +1614,8 @@ } c = channel_new(ssh, "authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -998,7 +998,7 @@ diff -Nur openssh-8.7p1.orig/clientloop.c openssh-8.7p1/clientloop.c "authentication agent connection", 1); c->force_drain = 1; return c; -@@ -1638,7 +1641,8 @@ +@@ -1639,7 +1642,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, @@ -1008,10 +1008,10 @@ diff -Nur openssh-8.7p1.orig/clientloop.c openssh-8.7p1/clientloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) -diff -Nur openssh-8.7p1.orig/compat.c openssh-8.7p1/compat.c ---- openssh-8.7p1.orig/compat.c 2021-10-24 07:54:36.849834155 +0200 -+++ openssh-8.7p1/compat.c 2021-10-24 07:56:04.850030003 +0200 -@@ -151,6 +151,17 @@ +diff -Nur openssh-8.8p1.orig/compat.c openssh-8.8p1/compat.c +--- openssh-8.8p1.orig/compat.c 2021-12-01 16:50:22.497385526 +0100 ++++ openssh-8.8p1/compat.c 2021-12-01 16:51:00.925474128 +0100 +@@ -150,6 +150,17 @@ debug_f("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); ssh->compat = check[i].bugs; @@ -1029,9 +1029,9 @@ diff -Nur openssh-8.7p1.orig/compat.c openssh-8.7p1/compat.c return; } } -diff -Nur openssh-8.7p1.orig/compat.h openssh-8.7p1/compat.h ---- openssh-8.7p1.orig/compat.h 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/compat.h 2021-10-24 07:56:04.850030003 +0200 +diff -Nur openssh-8.8p1.orig/compat.h openssh-8.8p1/compat.h +--- openssh-8.8p1.orig/compat.h 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/compat.h 2021-12-01 16:51:00.926474130 +0100 @@ -57,6 +57,7 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 @@ -1040,9 +1040,9 @@ diff -Nur openssh-8.7p1.orig/compat.h openssh-8.7p1/compat.h struct ssh; -diff -Nur openssh-8.7p1.orig/defines.h openssh-8.7p1/defines.h ---- openssh-8.7p1.orig/defines.h 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/defines.h 2021-10-24 07:56:04.851030005 +0200 +diff -Nur openssh-8.8p1.orig/defines.h openssh-8.8p1/defines.h +--- openssh-8.8p1.orig/defines.h 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/defines.h 2021-12-01 16:51:00.927474132 +0100 @@ -854,7 +854,7 @@ #endif @@ -1052,9 +1052,9 @@ diff -Nur openssh-8.7p1.orig/defines.h openssh-8.7p1/defines.h #endif /* -diff -Nur openssh-8.7p1.orig/digest.h openssh-8.7p1/digest.h ---- openssh-8.7p1.orig/digest.h 2021-10-24 07:54:36.811834070 +0200 -+++ openssh-8.7p1/digest.h 2021-10-24 07:56:04.852030007 +0200 +diff -Nur openssh-8.8p1.orig/digest.h openssh-8.8p1/digest.h +--- openssh-8.8p1.orig/digest.h 2021-12-01 16:50:22.451385420 +0100 ++++ openssh-8.8p1/digest.h 2021-12-01 16:51:00.927474132 +0100 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -1065,9 +1065,9 @@ diff -Nur openssh-8.7p1.orig/digest.h openssh-8.7p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-8.7p1.orig/digest-openssl.c openssh-8.7p1/digest-openssl.c ---- openssh-8.7p1.orig/digest-openssl.c 2021-10-24 07:54:36.810834068 +0200 -+++ openssh-8.7p1/digest-openssl.c 2021-10-24 07:56:04.852030007 +0200 +diff -Nur openssh-8.8p1.orig/digest-openssl.c openssh-8.8p1/digest-openssl.c +--- openssh-8.8p1.orig/digest-openssl.c 2021-12-01 16:50:22.451385420 +0100 ++++ openssh-8.8p1/digest-openssl.c 2021-12-01 16:51:00.927474132 +0100 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -1076,9 +1076,9 @@ diff -Nur openssh-8.7p1.orig/digest-openssl.c openssh-8.7p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-8.7p1.orig/HPN-README openssh-8.7p1/HPN-README ---- openssh-8.7p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.7p1/HPN-README 2021-10-24 07:56:04.852030007 +0200 +diff -Nur openssh-8.8p1.orig/HPN-README openssh-8.8p1/HPN-README +--- openssh-8.8p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.8p1/HPN-README 2021-12-01 16:51:00.928474135 +0100 @@ -0,0 +1,153 @@ +Notes: + @@ -1233,9 +1233,9 @@ diff -Nur openssh-8.7p1.orig/HPN-README openssh-8.7p1/HPN-README + Allan Jude provided the code for the NoneMac and buffer normalization. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. -diff -Nur openssh-8.7p1.orig/kex.c openssh-8.7p1/kex.c ---- openssh-8.7p1.orig/kex.c 2021-10-24 07:54:36.841834137 +0200 -+++ openssh-8.7p1/kex.c 2021-10-24 07:56:04.853030010 +0200 +diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c +--- openssh-8.8p1.orig/kex.c 2021-12-01 16:50:22.487385503 +0100 ++++ openssh-8.8p1/kex.c 2021-12-01 16:51:00.929474137 +0100 @@ -64,6 +64,7 @@ #include "ssherr.h" @@ -1321,9 +1321,9 @@ diff -Nur openssh-8.7p1.orig/kex.c openssh-8.7p1/kex.c debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); compat_banner(ssh, remote_version); -diff -Nur openssh-8.7p1.orig/log.c openssh-8.7p1/log.c ---- openssh-8.7p1.orig/log.c 2021-10-24 07:54:36.769833977 +0200 -+++ openssh-8.7p1/log.c 2021-10-24 07:56:04.853030010 +0200 +diff -Nur openssh-8.8p1.orig/log.c openssh-8.8p1/log.c +--- openssh-8.8p1.orig/log.c 2021-12-01 16:50:22.401385305 +0100 ++++ openssh-8.8p1/log.c 2021-12-01 16:51:00.929474137 +0100 @@ -46,6 +46,11 @@ #include #include @@ -1345,9 +1345,9 @@ diff -Nur openssh-8.7p1.orig/log.c openssh-8.7p1/log.c #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) -diff -Nur openssh-8.7p1.orig/mac.c openssh-8.7p1/mac.c ---- openssh-8.7p1.orig/mac.c 2021-10-24 07:54:36.830834112 +0200 -+++ openssh-8.7p1/mac.c 2021-10-24 07:56:04.854030012 +0200 +diff -Nur openssh-8.8p1.orig/mac.c openssh-8.8p1/mac.c +--- openssh-8.8p1.orig/mac.c 2021-12-01 16:50:22.476385477 +0100 ++++ openssh-8.8p1/mac.c 2021-12-01 16:51:00.929474137 +0100 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -1356,9 +1356,9 @@ diff -Nur openssh-8.7p1.orig/mac.c openssh-8.7p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in ---- openssh-8.7p1.orig/Makefile.in 2021-10-24 07:54:36.867834195 +0200 -+++ openssh-8.7p1/Makefile.in 2021-10-24 07:56:04.854030012 +0200 +diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in +--- openssh-8.8p1.orig/Makefile.in 2021-12-01 16:50:22.516385570 +0100 ++++ openssh-8.8p1/Makefile.in 2021-12-01 16:51:00.930474139 +0100 @@ -48,7 +48,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ @@ -1377,9 +1377,9 @@ diff -Nur openssh-8.7p1.orig/Makefile.in openssh-8.7p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-8.7p1.orig/packet.c openssh-8.7p1/packet.c ---- openssh-8.7p1.orig/packet.c 2021-10-24 07:54:36.832834117 +0200 -+++ openssh-8.7p1/packet.c 2021-10-24 07:56:04.855030014 +0200 +diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c +--- openssh-8.8p1.orig/packet.c 2021-12-01 16:50:22.479385484 +0100 ++++ openssh-8.8p1/packet.c 2021-12-01 16:51:00.930474139 +0100 @@ -246,7 +246,7 @@ TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; @@ -1528,9 +1528,9 @@ diff -Nur openssh-8.7p1.orig/packet.c openssh-8.7p1/packet.c +{ + return ssh->state->send_context; +} -diff -Nur openssh-8.7p1.orig/packet.h openssh-8.7p1/packet.h ---- openssh-8.7p1.orig/packet.h 2021-10-24 07:54:36.833834119 +0200 -+++ openssh-8.7p1/packet.h 2021-10-24 07:56:04.856030016 +0200 +diff -Nur openssh-8.8p1.orig/packet.h openssh-8.8p1/packet.h +--- openssh-8.8p1.orig/packet.h 2021-12-01 16:50:22.479385484 +0100 ++++ openssh-8.8p1/packet.h 2021-12-01 16:51:00.931474142 +0100 @@ -86,6 +86,14 @@ /* APP data */ @@ -1569,9 +1569,9 @@ diff -Nur openssh-8.7p1.orig/packet.h openssh-8.7p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-8.7p1.orig/progressmeter.c openssh-8.7p1/progressmeter.c ---- openssh-8.7p1.orig/progressmeter.c 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/progressmeter.c 2021-10-24 07:56:04.857030018 +0200 +diff -Nur openssh-8.8p1.orig/progressmeter.c openssh-8.8p1/progressmeter.c +--- openssh-8.8p1.orig/progressmeter.c 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/progressmeter.c 2021-12-01 16:51:00.931474142 +0100 @@ -68,6 +68,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -1633,9 +1633,9 @@ diff -Nur openssh-8.7p1.orig/progressmeter.c openssh-8.7p1/progressmeter.c } /*ARGSUSED*/ -diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c ---- openssh-8.7p1.orig/readconf.c 2021-10-24 07:54:36.870834202 +0200 -+++ openssh-8.7p1/readconf.c 2021-10-24 08:13:34.654331392 +0200 +diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c +--- openssh-8.8p1.orig/readconf.c 2021-12-01 16:50:22.519385577 +0100 ++++ openssh-8.8p1/readconf.c 2021-12-01 16:51:00.932474144 +0100 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -1735,7 +1735,7 @@ diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c case oCiphers: arg = argv_next(&ac, &av); if (!arg || *arg == '\0') { -@@ -2440,6 +2497,14 @@ +@@ -2467,6 +2524,14 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -1750,7 +1750,7 @@ diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2615,6 +2680,43 @@ +@@ -2642,6 +2707,43 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -1794,9 +1794,9 @@ diff -Nur openssh-8.7p1.orig/readconf.c openssh-8.7p1/readconf.c if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { -diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h ---- openssh-8.7p1.orig/readconf.h 2021-10-24 07:54:36.870834202 +0200 -+++ openssh-8.7p1/readconf.h 2021-10-24 07:56:04.860030025 +0200 +diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h +--- openssh-8.8p1.orig/readconf.h 2021-12-01 16:50:22.519385577 +0100 ++++ openssh-8.8p1/readconf.h 2021-12-01 16:51:00.932474144 +0100 @@ -55,6 +55,10 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ @@ -1821,9 +1821,9 @@ diff -Nur openssh-8.7p1.orig/readconf.h openssh-8.7p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-8.7p1.orig/regress/integrity.sh openssh-8.7p1/regress/integrity.sh ---- openssh-8.7p1.orig/regress/integrity.sh 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/integrity.sh 2021-10-24 07:56:04.860030025 +0200 +diff -Nur openssh-8.8p1.orig/regress/integrity.sh openssh-8.8p1/regress/integrity.sh +--- openssh-8.8p1.orig/regress/integrity.sh 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/regress/integrity.sh 2021-12-01 16:51:00.933474146 +0100 @@ -21,6 +21,12 @@ cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" @@ -1837,9 +1837,9 @@ diff -Nur openssh-8.7p1.orig/regress/integrity.sh openssh-8.7p1/regress/integrit trace "test $tid: mac $m" elen=0 epad=0 -diff -Nur openssh-8.7p1.orig/sandbox-seccomp-filter.c openssh-8.7p1/sandbox-seccomp-filter.c ---- openssh-8.7p1.orig/sandbox-seccomp-filter.c 2021-10-24 07:54:36.842834139 +0200 -+++ openssh-8.7p1/sandbox-seccomp-filter.c 2021-10-24 07:56:04.861030027 +0200 +diff -Nur openssh-8.8p1.orig/sandbox-seccomp-filter.c openssh-8.8p1/sandbox-seccomp-filter.c +--- openssh-8.8p1.orig/sandbox-seccomp-filter.c 2021-12-01 16:50:22.489385507 +0100 ++++ openssh-8.8p1/sandbox-seccomp-filter.c 2021-12-01 16:51:00.933474146 +0100 @@ -225,6 +225,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -1860,10 +1860,10 @@ diff -Nur openssh-8.7p1.orig/sandbox-seccomp-filter.c openssh-8.7p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-8.7p1.orig/scp.c openssh-8.7p1/scp.c ---- openssh-8.7p1.orig/scp.c 2021-10-24 07:54:36.854834166 +0200 -+++ openssh-8.7p1/scp.c 2021-10-24 07:56:04.861030027 +0200 -@@ -1566,7 +1566,7 @@ +diff -Nur openssh-8.8p1.orig/scp.c openssh-8.8p1/scp.c +--- openssh-8.8p1.orig/scp.c 2021-12-01 16:50:22.502385537 +0100 ++++ openssh-8.8p1/scp.c 2021-12-01 16:51:00.934474149 +0100 +@@ -1576,7 +1576,7 @@ off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerr; @@ -1872,9 +1872,9 @@ diff -Nur openssh-8.7p1.orig/scp.c openssh-8.7p1/scp.c char **patterns = NULL; size_t n, npatterns = 0; struct timeval tv[2]; -diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c ---- openssh-8.7p1.orig/servconf.c 2021-10-24 07:54:36.871834204 +0200 -+++ openssh-8.7p1/servconf.c 2021-10-24 07:56:04.863030032 +0200 +diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c +--- openssh-8.8p1.orig/servconf.c 2021-12-01 16:50:22.520385579 +0100 ++++ openssh-8.8p1/servconf.c 2021-12-01 16:51:00.935474151 +0100 @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -1959,9 +1959,9 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -533,6 +589,9 @@ - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, +@@ -531,6 +587,9 @@ + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sNoneEnabled, sNoneMacEnabled, + sDisableMTAES, @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -733,6 +792,12 @@ +@@ -731,6 +790,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -1982,7 +1982,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -791,6 +856,7 @@ +@@ -789,6 +854,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -1990,7 +1990,7 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1568,12 +1634,36 @@ +@@ -1566,12 +1632,36 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -2027,9 +2027,9 @@ diff -Nur openssh-8.7p1.orig/servconf.c openssh-8.7p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h ---- openssh-8.7p1.orig/servconf.h 2021-10-24 07:54:36.871834204 +0200 -+++ openssh-8.7p1/servconf.h 2021-10-24 07:56:04.864030034 +0200 +diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h +--- openssh-8.8p1.orig/servconf.h 2021-12-01 16:50:22.520385579 +0100 ++++ openssh-8.8p1/servconf.h 2021-12-01 16:51:00.935474151 +0100 @@ -214,6 +214,13 @@ int use_pam; /* Enable auth via PAM */ int permit_pam_user_change; /* Allow PAM to change user name */ @@ -2044,9 +2044,9 @@ diff -Nur openssh-8.7p1.orig/servconf.h openssh-8.7p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-8.7p1.orig/serverloop.c openssh-8.7p1/serverloop.c ---- openssh-8.7p1.orig/serverloop.c 2021-10-24 07:54:36.855834168 +0200 -+++ openssh-8.7p1/serverloop.c 2021-10-24 07:56:04.865030036 +0200 +diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c +--- openssh-8.8p1.orig/serverloop.c 2021-12-01 16:50:22.503385540 +0100 ++++ openssh-8.8p1/serverloop.c 2021-12-01 16:51:00.936474153 +0100 @@ -266,7 +266,7 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in) { @@ -2109,9 +2109,9 @@ diff -Nur openssh-8.7p1.orig/serverloop.c openssh-8.7p1/serverloop.c if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -diff -Nur openssh-8.7p1.orig/session.c openssh-8.7p1/session.c ---- openssh-8.7p1.orig/session.c 2021-10-24 07:54:36.855834168 +0200 -+++ openssh-8.7p1/session.c 2021-10-24 07:56:04.866030038 +0200 +diff -Nur openssh-8.8p1.orig/session.c openssh-8.8p1/session.c +--- openssh-8.8p1.orig/session.c 2021-12-01 16:50:22.504385542 +0100 ++++ openssh-8.8p1/session.c 2021-12-01 16:51:00.936474153 +0100 @@ -228,6 +228,7 @@ goto authsock_err; @@ -2130,9 +2130,9 @@ diff -Nur openssh-8.7p1.orig/session.c openssh-8.7p1/session.c } /* -diff -Nur openssh-8.7p1.orig/sftp.1 openssh-8.7p1/sftp.1 ---- openssh-8.7p1.orig/sftp.1 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp.1 2021-10-24 07:56:04.867030041 +0200 +diff -Nur openssh-8.8p1.orig/sftp.1 openssh-8.8p1/sftp.1 +--- openssh-8.8p1.orig/sftp.1 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/sftp.1 2021-12-01 16:51:00.937474156 +0100 @@ -295,7 +295,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed @@ -2143,9 +2143,9 @@ diff -Nur openssh-8.7p1.orig/sftp.1 openssh-8.7p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -diff -Nur openssh-8.7p1.orig/sftp-client.c openssh-8.7p1/sftp-client.c ---- openssh-8.7p1.orig/sftp-client.c 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.c 2021-10-24 07:56:04.868030043 +0200 +diff -Nur openssh-8.8p1.orig/sftp-client.c openssh-8.8p1/sftp-client.c +--- openssh-8.8p1.orig/sftp-client.c 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/sftp-client.c 2021-12-01 16:51:00.937474156 +0100 @@ -72,7 +72,7 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -2155,9 +2155,9 @@ diff -Nur openssh-8.7p1.orig/sftp-client.c openssh-8.7p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-8.7p1.orig/ssh_api.c openssh-8.7p1/ssh_api.c ---- openssh-8.7p1.orig/ssh_api.c 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh_api.c 2021-10-24 07:56:04.869030045 +0200 +diff -Nur openssh-8.8p1.orig/ssh_api.c openssh-8.8p1/ssh_api.c +--- openssh-8.8p1.orig/ssh_api.c 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/ssh_api.c 2021-12-01 16:51:00.938474158 +0100 @@ -410,7 +410,7 @@ char *cp; int r; @@ -2167,9 +2167,9 @@ diff -Nur openssh-8.7p1.orig/ssh_api.c openssh-8.7p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-8.7p1.orig/sshbuf.h openssh-8.7p1/sshbuf.h ---- openssh-8.7p1.orig/sshbuf.h 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sshbuf.h 2021-10-24 07:56:04.870030047 +0200 +diff -Nur openssh-8.8p1.orig/sshbuf.h openssh-8.8p1/sshbuf.h +--- openssh-8.8p1.orig/sshbuf.h 2021-09-26 16:03:19.000000000 +0200 ++++ openssh-8.8p1/sshbuf.h 2021-12-01 16:51:00.938474158 +0100 @@ -28,7 +28,7 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2179,10 +2179,10 @@ diff -Nur openssh-8.7p1.orig/sshbuf.h openssh-8.7p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c ---- openssh-8.7p1.orig/ssh.c 2021-10-24 07:54:36.872834206 +0200 -+++ openssh-8.7p1/ssh.c 2021-10-24 07:56:04.871030049 +0200 -@@ -1056,6 +1056,10 @@ +diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c +--- openssh-8.8p1.orig/ssh.c 2021-12-01 16:50:22.521385581 +0100 ++++ openssh-8.8p1/ssh.c 2021-12-01 16:51:00.939474160 +0100 +@@ -1057,6 +1057,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1784,6 +1788,8 @@ +@@ -1785,6 +1789,8 @@ setproctitle("%s [mux]", options.control_path); } @@ -2202,7 +2202,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) -@@ -2101,6 +2107,79 @@ +@@ -2103,6 +2109,79 @@ NULL, fileno(stdin), command, environ); } @@ -2282,7 +2282,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2119,9 +2198,11 @@ +@@ -2121,9 +2200,11 @@ if (in == -1 || out == -1 || err == -1) fatal("dup() in/out/err failed"); @@ -2295,7 +2295,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2132,6 +2213,11 @@ +@@ -2134,6 +2215,11 @@ debug3_f("channel_new: %d", c->self); @@ -2307,7 +2307,7 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c channel_send_open(ssh, c->self); if (options.session_type != SESSION_TYPE_NONE) channel_register_open_confirm(ssh, c->self, -@@ -2146,6 +2232,13 @@ +@@ -2148,6 +2234,13 @@ int r, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -2321,9 +2321,9 @@ diff -Nur openssh-8.7p1.orig/ssh.c openssh-8.7p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c ---- openssh-8.7p1.orig/sshconnect2.c 2021-10-24 07:54:36.873834208 +0200 -+++ openssh-8.7p1/sshconnect2.c 2021-10-24 08:06:47.586411958 +0200 +diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c +--- openssh-8.8p1.orig/sshconnect2.c 2021-12-01 16:50:22.523385586 +0100 ++++ openssh-8.8p1/sshconnect2.c 2021-12-01 16:51:00.940474162 +0100 @@ -86,6 +86,13 @@ extern Options options; @@ -2412,9 +2412,9 @@ diff -Nur openssh-8.7p1.orig/sshconnect2.c openssh-8.7p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-8.7p1.orig/sshconnect.c openssh-8.7p1/sshconnect.c ---- openssh-8.7p1.orig/sshconnect.c 2021-10-24 07:54:36.794834032 +0200 -+++ openssh-8.7p1/sshconnect.c 2021-10-24 07:56:04.873030054 +0200 +diff -Nur openssh-8.8p1.orig/sshconnect.c openssh-8.8p1/sshconnect.c +--- openssh-8.8p1.orig/sshconnect.c 2021-12-01 16:50:22.434385381 +0100 ++++ openssh-8.8p1/sshconnect.c 2021-12-01 16:51:00.940474162 +0100 @@ -345,6 +345,30 @@ #endif @@ -2456,9 +2456,9 @@ diff -Nur openssh-8.7p1.orig/sshconnect.c openssh-8.7p1/sshconnect.c /* Use interactive QOS (if specified) until authentication completed */ if (options.ip_qos_interactive != INT_MAX) set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c ---- openssh-8.7p1.orig/sshd.c 2021-10-24 07:54:36.874834211 +0200 -+++ openssh-8.7p1/sshd.c 2021-10-24 08:00:18.185586742 +0200 +diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c +--- openssh-8.8p1.orig/sshd.c 2021-12-01 16:50:22.524385588 +0100 ++++ openssh-8.8p1/sshd.c 2021-12-01 16:51:00.941474165 +0100 @@ -1110,6 +1110,8 @@ int ret, listen_sock; struct addrinfo *ai; @@ -2548,9 +2548,9 @@ diff -Nur openssh-8.7p1.orig/sshd.c openssh-8.7p1/sshd.c myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, -diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config ---- openssh-8.7p1.orig/sshd_config 2021-10-24 07:54:36.874834211 +0200 -+++ openssh-8.7p1/sshd_config 2021-10-24 07:56:04.875030058 +0200 +diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config +--- openssh-8.8p1.orig/sshd_config 2021-12-01 16:50:22.524385588 +0100 ++++ openssh-8.8p1/sshd_config 2021-12-01 16:51:00.941474165 +0100 @@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2580,9 +2580,9 @@ diff -Nur openssh-8.7p1.orig/sshd_config openssh-8.7p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-8.7p1.orig/version.h openssh-8.7p1/version.h ---- openssh-8.7p1.orig/version.h 2021-10-24 07:54:36.876834215 +0200 -+++ openssh-8.7p1/version.h 2021-10-24 07:56:04.876030061 +0200 +diff -Nur openssh-8.8p1.orig/version.h openssh-8.8p1/version.h +--- openssh-8.8p1.orig/version.h 2021-12-01 16:50:22.525385590 +0100 ++++ openssh-8.8p1/version.h 2021-12-01 16:51:00.941474165 +0100 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" diff --git a/sources b/sources index d393884..1dadfbc 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.7p1.tar.gz) = 08c81024d9e1248abfda6cc874886ff5ae916669b93cd6aff640e0614ee8cbcbc3fe87a9ce47136b6443ddbb1168b114367c74e117551905994e1a7e3fa2c0c2 -SHA512 (openssh-8.7p1.tar.gz.asc) = 08b4bda855ca3ef202c271f1c0e3486082b93d1009a794d020e7ba223978bc87bf34b1fbccaae3379a47639bd849935fdaaf63bdb781d0a44625066ccf00fbfc +SHA512 (openssh-8.8p1.tar.gz) = d44cd04445f9c8963513b0d5a7e8348985114ff2471e119a6e344498719ef40f09c61c354888a3be9dabcb5870e5cbe5d3aafbb861dfa1d82a4952f3d233a8df +SHA512 (openssh-8.8p1.tar.gz.asc) = 165e025305902f884d04d4444fa3143e4ea1a25a1c65aafe05e113537b3d3e50f7cd5f818bc2ca3404699372ca78f69c46b7452faf2d3998c448a5b80a411ae4 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 4dc1dfc1114b065c8f7271cea52b8c29d572d9a5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 11:51:24 +0000 Subject: [PATCH 104/146] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 66318cf..168d66f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -500,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Thu Jan 20 2022 Fedora Release Engineering - 8.8p1-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Wed Dec 01 2021 Mattias Ellert - 8.8p1-1 - Based on openssh-8.8p1-1.fc36 From 9e07719d88921afc283f14bc33fcefac004d6fa4 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 8 May 2022 11:00:52 +0200 Subject: [PATCH 105/146] Based on openssh-8.8p1-2.fc37 --- gsi-openssh.spec | 11 +++++++---- openssh-7.7p1-redhat.patch | 16 ++-------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 168d66f..5f6cce1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,12 +28,12 @@ %global libedit 1 %global openssh_ver 8.8p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -407,8 +407,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/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 -m644 ssh_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ssh_config.d/50-redhat.conf +install -m644 sshd_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/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 @@ -500,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Sun May 8 2022 Mattias Ellert - 8.8p1-2 +- Based on openssh-8.8p1-2.fc37 + * Thu Jan 20 2022 Fedora Release Engineering - 8.8p1-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index fcda6c6..85ebc82 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -15,7 +15,7 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config 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 @@ +@@ -0,0 +1,15 @@ +# The options here are in the "Match final block" to be applied as the last +# options and could be potentially overwritten by the user configuration +Match final all @@ -29,12 +29,6 @@ diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat +# mode correctly we set this to yes. + ForwardX11Trusted yes + -+# 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 -up openssh/sshd_config.0.redhat openssh/sshd_config.0 @@ -86,7 +80,7 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config 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 @@ +@@ -0,0 +1,22 @@ +# 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, @@ -109,9 +103,3 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +# as it is more configurable and versatile than the built-in version. +PrintMotd no + -+# 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 -+ From f49266f739eafd9845ed619a0e007e2b2ed6e81f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 13:07:18 +0000 Subject: [PATCH 106/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 5f6cce1..58838fc 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -33,7 +33,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -500,6 +500,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Thu Jul 21 2022 Fedora Release Engineering - 8.8p1-2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Sun May 8 2022 Mattias Ellert - 8.8p1-2 - Based on openssh-8.8p1-2.fc37 From 3c863da50a9bde46bbafff231a4569d3c5474008 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 30 Aug 2022 18:31:37 +0200 Subject: [PATCH 107/146] Based on openssh-8.8p1-6.fc37 --- gsi-openssh.spec | 84 +++- openssh-6.7p1-coverity.patch | 58 +-- openssh-7.7p1-fips.patch | 230 +++++++++- openssh-8.0p1-crypto-policies.patch | 78 ++-- openssh-8.7p1-evpgenkey.patch | 110 +++++ openssh-8.7p1-gssapi-auth.patch | 20 + openssh-8.7p1-host-based-auth.patch | 151 +++++++ openssh-8.7p1-ibmca.patch | 12 + openssh-8.7p1-mem-leak.patch | 156 +++++++ openssh-8.7p1-minimize-sha1-use.patch | 207 +++++++++ openssh-8.7p1-minrsabits.patch | 437 +++++++++++++++++++ openssh-8.7p1-negotiate-supported-algs.patch | 63 +++ openssh-8.7p1-recursive-scp.patch | 174 ++++++++ openssh-8.7p1-scp-clears-file.patch | 304 +++++++++++++ openssh-8.7p1-sftpscp-dir-create.patch | 135 ++++++ openssh-8.7p1-ssh-manpage.patch | 53 +++ openssh-8.8p1-hpn-15.2-modified.patch | 16 +- openssh-8.8p1-skip-some-tests.patch | 41 ++ 18 files changed, 2223 insertions(+), 106 deletions(-) create mode 100644 openssh-8.7p1-evpgenkey.patch create mode 100644 openssh-8.7p1-gssapi-auth.patch create mode 100644 openssh-8.7p1-host-based-auth.patch create mode 100644 openssh-8.7p1-ibmca.patch create mode 100644 openssh-8.7p1-mem-leak.patch create mode 100644 openssh-8.7p1-minimize-sha1-use.patch create mode 100644 openssh-8.7p1-minrsabits.patch create mode 100644 openssh-8.7p1-negotiate-supported-algs.patch create mode 100644 openssh-8.7p1-recursive-scp.patch create mode 100644 openssh-8.7p1-scp-clears-file.patch create mode 100644 openssh-8.7p1-sftpscp-dir-create.patch create mode 100644 openssh-8.7p1-ssh-manpage.patch create mode 100644 openssh-8.8p1-skip-some-tests.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 58838fc..a7901cd 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,12 +28,12 @@ %global libedit 1 %global openssh_ver 8.8p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -145,7 +145,7 @@ Patch964: openssh-8.0p1-openssl-kdf.patch Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 Patch966: openssh-8.2p1-x11-without-ipv6.patch -# https://bugzilla.mindrot.org/show_bug.cgi?id=3213 +# ssh-keygen printing fingerprint issue with Windows keys (#1901518) Patch974: openssh-8.0p1-keygen-strip-doseol.patch # sshd provides PAM an incorrect error code (#1879503) Patch975: openssh-8.0p1-preserve-pam-errors.patch @@ -153,6 +153,62 @@ Patch975: openssh-8.0p1-preserve-pam-errors.patch Patch976: openssh-8.7p1-sftp-default-protocol.patch # Implement kill switch for SCP protocol Patch977: openssh-8.7p1-scp-kill-switch.patch +# Create non-existent directories when scp works in sftp mode and some more minor fixes +# upstream commits: +# ba61123eef9c6356d438c90c1199a57a0d7bcb0a +# 63670d4e9030bcee490d5a9cce561373ac5b3b23 +# ac7c9ec894ed0825d04ef69c55babb49bab1d32e +Patch980: openssh-8.7p1-sftpscp-dir-create.patch +# Workaround for lack of sftp_realpath in older versions of RHEL +# https://bugzilla.redhat.com/show_bug.cgi?id=2038854 +# https://github.com/openssh/openssh-portable/pull/299 +# downstream only +Patch981: openssh-8.7p1-recursive-scp.patch +# https://github.com/djmdjm/openssh-wip/pull/13 +Patch982: openssh-8.7p1-minrsabits.patch +# downstream only +Patch983: openssh-8.7p1-evpgenkey.patch +# downstream only, IBMCA tentative fix +# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 +Patch984: openssh-8.7p1-ibmca.patch + +# Minimize the use of SHA1 as a proof of possession for RSA key (#2031868) +# upstream commits: +# 291721bc7c840d113a49518f3fca70e86248b8e8 +# 0fa33683223c76289470a954404047bc762be84c +Patch1000: openssh-8.7p1-minimize-sha1-use.patch +# Fix for scp clearing file when src and dest are the same (#2056884) +# upstream commits: +# 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee +Patch1001: openssh-8.7p1-scp-clears-file.patch +# Add missing options from ssh_config into ssh manpage +# upstream bug: +# https://bugzilla.mindrot.org/show_bug.cgi?id=3455 +Patch1002: openssh-8.7p1-ssh-manpage.patch +# Always return allocated strings from the kex filtering so that we can free them +# upstream commits: +# 486c4dc3b83b4b67d663fb0fa62bc24138ec3946 +# 6c31ba10e97b6953c4f325f526f3e846dfea647a +# 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b +Patch1003: openssh-8.7p1-mem-leak.patch +# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures +# upstream MR: +# https://github.com/openssh-gsskex/openssh-gsskex/pull/21 +Patch1004: openssh-8.7p1-gssapi-auth.patch +# Fix host-based authentication with rsa keys +# upstream commits: +# 7aa7b096cf2bafe2777085abdeed5ce00581f641 +# d9dbb5d9a0326e252d3c7bc13beb9c2434f59409 +# fdb1d58d0d3888b042e5a500f6ce524486aaf782 +Patch1005: openssh-8.7p1-host-based-auth.patch +# Don't propose disallowed algorithms during hostkey negotiation +# upstream MR: +# https://github.com/openssh/openssh-portable/pull/323 +Patch1006: openssh-8.7p1-negotiate-supported-algs.patch + +# downstream only +# we skip some ssh-rsa/ssh-dss tests to make native test suite pass +Patch1100: openssh-8.8p1-skip-some-tests.patch # Fix issue with read-only ssh buffer during gssapi key exchange (#1938224) # https://github.com/openssh-gsskex/openssh-gsskex/pull/19 @@ -303,11 +359,26 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch975 -p1 -b .preserve-pam-errors %patch976 -p1 -b .sftp-by-default %patch977 -p1 -b .kill-scp +%patch980 -p1 -b .sftpdirs +%patch981 -p1 -b .scp-sftpdirs +%patch982 -p1 -b .minrsabits +%patch983 -p1 -b .evpgenrsa +%patch984 -p1 -b .ibmca %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race %patch700 -p1 -b .fips +%patch1000 -p1 -b .minimize-sha1-use +%patch1001 -p1 -b .scp-clears-file +%patch1002 -p1 -b .ssh-manpage +%patch1003 -p1 -b .mem-leak +%patch1004 -p1 -b .gssapi-auth +%patch1005 -p1 -b .host-based-auth +%patch1006 -p1 -b .negotiate-supported-algs + +%patch1100 -p1 -b .skipsshrsadsstests + %patch100 -p1 -b .coverity %patch97 -p1 -b .sshbuf-ro @@ -439,7 +510,7 @@ done perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %pre -getent group ssh_keys >/dev/null || groupadd -r ssh_keys || : +getent group ssh_keys >/dev/null || groupadd -r -g 101 ssh_keys || : %pre server getent group sshd >/dev/null || groupadd -g %{sshd_uid} -r sshd || : @@ -500,10 +571,13 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Aug 30 2022 Mattias Ellert - 8.8p1-3 +- Based on openssh-8.8p1-6.fc37 + * Thu Jul 21 2022 Fedora Release Engineering - 8.8p1-2.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild -* Sun May 8 2022 Mattias Ellert - 8.8p1-2 +* Sun May 08 2022 Mattias Ellert - 8.8p1-2 - Based on openssh-8.8p1-2.fc37 * Thu Jan 20 2022 Fedora Release Engineering - 8.8p1-1.1 diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 930de69..147d90d 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -101,22 +101,6 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c return idx; } -diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c ---- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100 -+++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100 -@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha - return p; - debug2_f("original KEX proposal: %s", p); - if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) -+ /* coverity[overwrite_var : FALSE] */ - if ((p = match_filter_denylist(p, - "curve25519-sha256@libssh.org")) == NULL) - fatal("match_filter_denylist failed"); - if ((ssh->compat & SSH_OLD_DHGEX) != 0) { -+ /* coverity[overwrite_var : FALSE] */ - if ((p = match_filter_denylist(p, - "diffie-hellman-group-exchange-sha256," - "diffie-hellman-group-exchange-sha1")) == NULL) diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c --- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 @@ -419,15 +403,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); -@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons - fflag || global_fflag) == -1) - err = -1; - } -+ free(abs_dst); -+ abs_dst = NULL; - } - - out: @@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co if (lflag & LS_LONG_VIEW) { if (g.gl_statv[i] == NULL) { @@ -436,6 +411,30 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c continue; } lname = ls_file(fname, g.gl_statv[i], 1, +diff --git a/sftp-client.c b/sftp-client.c +index 9de9afa20f..ea98d9f8d0 100644 +--- a/sftp-client.c ++++ b/sftp-client.c +@@ -2195,6 +2195,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous, + (*nreqsp)--; + } + debug3_f("done: %u outstanding replies", *nreqsp); ++ sshbuf_free(msg); + } + + int +diff --git a/sftp-server.c b/sftp-server.c +index 18d1949112..6380c4dd23 100644 +--- a/sftp-server.c ++++ b/sftp-server.c +@@ -1553,6 +1553,7 @@ process_extended_expand(u_int32_t id) + npath = xstrdup(path + 2); + free(path); + xasprintf(&path, "%s/%s", cwd, npath); ++ free(npath); + } else { + /* ~user expansions */ + if (tilde_expand(path, pw->pw_uid, &npath) != 0) { diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c --- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 @@ -505,15 +504,6 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c } /* -@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh) - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -- -+ /* coverity[leaked_storage : FALSE]*/ - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - ssh, list_hostkey_types()); - @@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) if (newstr) diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 72bceb1..cc513db 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,16 +1,3 @@ -diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c ---- openssh-8.6p1/cipher-ctr.c.fips 2021-04-19 16:53:02.994577324 +0200 -+++ openssh-8.6p1/cipher-ctr.c 2021-04-19 16:53:03.064577862 +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.6p1/dh.c.fips openssh-8.6p1/dh.c --- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 +++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200 @@ -19,7 +6,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c struct dhgroup dhg; + if (FIPS_mode()) { -+ logit("Using arbitrary primes is not allowed in FIPS mode." ++ verbose("Using arbitrary primes is not allowed in FIPS mode." + " Falling back to known groups."); + return (dh_new_group_fallback(max)); + } @@ -116,8 +103,8 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c /* generate and send 'e', client DH public key */ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h --- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/myproposal.h 2021-04-19 16:53:03.065577869 +0200 -@@ -57,6 +57,19 @@ ++++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 +@@ -57,6 +57,18 @@ "rsa-sha2-512," \ "rsa-sha2-256" @@ -127,12 +114,11 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h + "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," ++ "rsa-sha2-256" + #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ @@ -358,6 +344,20 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; +@@ -1931,6 +1931,13 @@ main(int ac, char **av) + &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) + do_log2_r(r, ll, "Unable to load host key \"%s\"", + options.host_key_files[i]); ++ 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", @@ -2110,6 +2113,10 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -407,15 +407,78 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->name == NULL || kt->type == KEY_NULL) + continue; ++ if (FIPS_mode()) { ++ switch (kt->type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ continue; ++ break; ++ default: ++ break; ++ } ++ } + if (!include_sigonly && kt->sigonly) + continue; + if ((certs_only && !kt->cert) || (plain_only && kt->cert)) +@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c + return SSH_ERR_EC_CURVE_MISMATCH; } - if (!BN_set_word(f4, RSA_F4) || - !RSA_generate_key_ex(private, bits, f4, NULL)) { -+ if (FIPS_mode()) -+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); + ++ 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 */ + ret->type = type; + if (sshkey_is_cert(ret)) { +@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA + goto out; + + if (EVP_PKEY_keygen(ctx, &res) <= 0) { ++ if (FIPS_mode()) ++ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } +@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, + break; + case KEY_ED25519_SK: + case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ /* Fallthrough */ + case KEY_ECDSA_SK_CERT: + case KEY_ECDSA_SK: + r = sshsk_sign(sk_provider, key, sigp, lenp, data, +@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, + return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); + case KEY_ED25519_SK: + case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, + compat, detailsp); + #ifdef WITH_XMSS diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c --- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 +++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 @@ -426,7 +489,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c + if (FIPS_mode()) { + if (type == KEY_DSA) + fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_ED25519) ++ if (type == KEY_ED25519 || type == KEY_ED25519_SK) + fatal("ED25519 keys are not allowed in FIPS mode"); + } switch (type) { @@ -451,3 +514,122 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); +diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c +--- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200 ++++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200 +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "sshkey.h" + #include "kex.h" +@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh) + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_keypair(kex); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_keypair(kex); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_keypair(kex); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_keypair(kex); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_dec(kex, server_blob, +- &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_dec(kex, server_blob, ++ &shared_secret); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, +- &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, ++ &shared_secret); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, +- &server_pubkey, &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, ++ &server_pubkey, &shared_secret); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c +--- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200 ++++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200 +@@ -24,6 +24,7 @@ + + #include + #include ++#include + + #include "log.h" + #include "sshbuf.h" +@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke + key->ed25519_sk == NULL || + datalen >= INT_MAX - crypto_sign_ed25519_BYTES) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + smlen = slen = datalen + crypto_sign_ed25519_BYTES; + if ((sig = malloc(slen)) == NULL) + return SSH_ERR_ALLOC_FAIL; +@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * + datalen >= INT_MAX - crypto_sign_ed25519_BYTES || + signature == NULL || signaturelen == 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(signature, signaturelen)) == NULL) + return SSH_ERR_ALLOC_FAIL; diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 2ad438c..62616aa 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,13 +1,13 @@ -diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 ---- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 -+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 -@@ -373,17 +373,13 @@ or +diff --color -ru a/ssh_config.5 b/ssh_config.5 +--- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200 ++++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200 +@@ -373,17 +373,13 @@ 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 . -+To see the defaults and how to modify this default, see manual page ++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 @@ -24,13 +24,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -445,20 +441,25 @@ If the option is set to +@@ -445,20 +441,25 @@ (the default), 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 ++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. @@ -54,7 +54,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -474,13 +475,6 @@ aes256-gcm@openssh.com +@@ -474,13 +475,6 @@ chacha20-poly1305@openssh.com .Ed .Pp @@ -68,19 +68,19 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -874,6 +868,11 @@ command line will be passed untouched to +@@ -874,6 +868,11 @@ 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 ++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 -@@ -886,10 +885,8 @@ gss-nistp256-sha256-, +@@ -886,10 +885,8 @@ gss-curve25519-sha256- .Ed .Pp @@ -92,13 +92,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1219,29 +1216,25 @@ it may be zero or more of: +@@ -1219,29 +1216,25 @@ 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 ++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. @@ -107,7 +107,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .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 ++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 - @@ -131,13 +131,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1351,37 +1344,33 @@ function, and all code in the +@@ -1351,37 +1344,33 @@ 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 . -+To see the defaults and how to modify this default, see manual page ++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 @@ -178,13 +178,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas +@@ -1553,36 +1542,25 @@ The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++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 @@ -224,16 +224,16 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 ---- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 -+++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 -@@ -373,17 +373,13 @@ If the argument is +diff --color -ru a/sshd_config.5 b/sshd_config.5 +--- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200 ++++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200 +@@ -373,17 +373,13 @@ 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 ++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 @@ -250,13 +250,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -450,20 +446,25 @@ The default is +@@ -450,20 +446,25 @@ 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 ++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. @@ -280,7 +280,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -490,13 +491,6 @@ aes256-gcm@openssh.com +@@ -490,13 +491,6 @@ chacha20-poly1305@openssh.com .El .Pp @@ -294,13 +294,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -685,21 +679,22 @@ For this to work +@@ -685,21 +679,22 @@ .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 ++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 @@ -327,13 +327,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased -@@ -799,26 +794,13 @@ is specified, the location of the socket +@@ -799,26 +794,13 @@ .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 ++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 @@ -359,13 +359,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi +@@ -965,20 +947,25 @@ 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 ++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. @@ -374,7 +374,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .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 ++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 - @@ -389,7 +389,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 +@@ -1010,15 +997,6 @@ sntrup761x25519-sha512@openssh.com .El .Pp @@ -405,13 +405,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1104,21 +1082,26 @@ function, and all code in the +@@ -1104,21 +1082,26 @@ 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 . -+To see the defaults and how to modify this default, see manual page ++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. @@ -436,7 +436,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com +@@ -1161,15 +1144,6 @@ umac-128-etm@openssh.com .El .Pp @@ -452,13 +452,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1548,37 +1522,25 @@ or equivalent.) +@@ -1548,37 +1522,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++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 diff --git a/openssh-8.7p1-evpgenkey.patch b/openssh-8.7p1-evpgenkey.patch new file mode 100644 index 0000000..1af9b49 --- /dev/null +++ b/openssh-8.7p1-evpgenkey.patch @@ -0,0 +1,110 @@ +diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c +--- openssh-8.7p1/sshkey.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-8.7p1/sshkey.c 2022-06-30 15:24:31.499641196 +0200 +@@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k) + static int + rsa_generate_private_key(u_int bits, RSA **rsap) + { +- RSA *private = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + BIGNUM *f4 = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + +@@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA + bits > SSHBUF_MAX_BIGNUM * 8) + return SSH_ERR_KEY_LENGTH; + *rsap = NULL; +- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL ++ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (!BN_set_word(f4, RSA_F4) || +- !RSA_generate_key_ex(private, bits, f4, NULL)) { ++ ++ if (EVP_PKEY_keygen_init(ctx) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { ++ ret = SSH_ERR_KEY_LENGTH; ++ goto out; ++ } ++ ++ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0) ++ goto out; ++ ++ if (EVP_PKEY_keygen(ctx, &res) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ ++ *rsap = EVP_PKEY_get1_RSA(res); ++ if (*rsap) { ++ ret = 0; ++ } else { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- *rsap = private; +- private = NULL; +- ret = 0; + out: +- RSA_free(private); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + BN_free(f4); + return ret; + } +@@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) + static int + ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) + { +- EC_KEY *private; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + + if (nid == NULL || ecdsap == NULL) +@@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i + if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) + return SSH_ERR_KEY_LENGTH; + *ecdsap = NULL; +- if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (EC_KEY_generate_key(private) != 1) { ++ ++ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0 ++ || EVP_PKEY_keygen(ctx, &res) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ ++ *ecdsap = EVP_PKEY_get1_EC_KEY(res); ++ if (*ecdsap) { ++ EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE); ++ ret = 0; ++ } else { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); +- *ecdsap = private; +- private = NULL; +- ret = 0; + out: +- EC_KEY_free(private); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + return ret; + } + # endif /* OPENSSL_HAS_ECC */ diff --git a/openssh-8.7p1-gssapi-auth.patch b/openssh-8.7p1-gssapi-auth.patch new file mode 100644 index 0000000..6908cad --- /dev/null +++ b/openssh-8.7p1-gssapi-auth.patch @@ -0,0 +1,20 @@ +diff --color -rup a/monitor.c b/monitor.c +--- a/monitor.c 2022-07-11 15:11:28.146863144 +0200 ++++ b/monitor.c 2022-07-11 15:15:35.726655877 +0200 +@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s + if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { + auth_log(ssh, authenticated, partial, + auth_method, auth_submethod); +- if (!partial && !authenticated) ++ if (!partial && !authenticated) { ++#ifdef GSSAPI ++ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled. ++ * We have to reenable it to try again for gssapi-keyex */ ++ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex) ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); ++#endif + authctxt->failures++; ++ } + if (authenticated || partial) { + auth2_update_session_info(authctxt, + auth_method, auth_submethod); diff --git a/openssh-8.7p1-host-based-auth.patch b/openssh-8.7p1-host-based-auth.patch new file mode 100644 index 0000000..23efe91 --- /dev/null +++ b/openssh-8.7p1-host-based-auth.patch @@ -0,0 +1,151 @@ +diff --color -rup a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2022-07-11 17:00:02.618575727 +0200 ++++ b/sshconnect2.c 2022-07-11 17:03:05.096085690 +0200 +@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh) + if (authctxt->sensitive->keys[i] == NULL || + authctxt->sensitive->keys[i]->type == KEY_UNSPEC) + continue; +- if (match_pattern_list( ++ if (!sshkey_match_keyname_to_sigalgs( + sshkey_ssh_name(authctxt->sensitive->keys[i]), +- authctxt->active_ktype, 0) != 1) ++ authctxt->active_ktype)) + continue; + /* we take and free the key */ + private = authctxt->sensitive->keys[i]; +@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh) + error_f("sshkey_fingerprint failed"); + goto out; + } +- debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp); ++ debug_f("trying hostkey %s %s using sigalg %s", ++ sshkey_ssh_name(private), fp, authctxt->active_ktype); + + /* figure out a name for the client host */ + lname = get_local_name(ssh_packet_get_connection_in(ssh)); +diff --color -rup a/sshkey.c b/sshkey.c +--- a/sshkey.c 2022-07-11 17:00:02.609575554 +0200 ++++ b/sshkey.c 2022-07-11 17:12:30.905976443 +0200 +@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n + return -1; + } + ++int ++sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) ++{ ++ int ktype; ++ ++ if (sigalgs == NULL || *sigalgs == '\0' || ++ (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC) ++ return 0; ++ else if (ktype == KEY_RSA) { ++ return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1; ++ } else if (ktype == KEY_RSA_CERT) { ++ return match_pattern_list("ssh-rsa-cert-v01@openssh.com", ++ sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", ++ sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", ++ sigalgs, 0) == 1; ++ } else ++ return match_pattern_list(keyname, sigalgs, 0) == 1; ++} ++ + char * + sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) + { +diff --color -rup a/sshkey.h b/sshkey.h +--- a/sshkey.h 2022-07-11 17:00:02.603575438 +0200 ++++ b/sshkey.h 2022-07-11 17:13:01.052556879 +0200 +@@ -194,6 +194,10 @@ int sshkey_is_cert(const struct sshkey + int sshkey_is_sk(const struct sshkey *); + int sshkey_type_is_cert(int); + int sshkey_type_plain(int); ++ ++/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */ ++int sshkey_match_keyname_to_sigalgs(const char *, const char *); ++ + int sshkey_to_certified(struct sshkey *); + int sshkey_drop_cert(struct sshkey *); + int sshkey_cert_copy(const struct sshkey *, struct sshkey *); +diff --color -rup a/ssh-keysign.c b/ssh-keysign.c +--- a/ssh-keysign.c 2021-08-20 06:03:49.000000000 +0200 ++++ b/ssh-keysign.c 2022-07-11 17:00:23.306973667 +0200 +@@ -62,7 +62,7 @@ + extern char *__progname; + + static int +-valid_request(struct passwd *pw, char *host, struct sshkey **ret, ++valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp, + u_char *data, size_t datalen) + { + struct sshbuf *b; +@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h + + if (ret != NULL) + *ret = NULL; ++ if (pkalgp != NULL) ++ *pkalgp = NULL; + fail = 0; + + if ((b = sshbuf_from(data, datalen)) == NULL) +@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h + fail++; + } else if (key->type != pktype) + fail++; +- free(pkalg); +- free(pkblob); + + /* client host name, handle trailing dot */ + if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) +@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h + + if (fail) + sshkey_free(key); +- else if (ret != NULL) +- *ret = key; ++ else { ++ if (ret != NULL) { ++ *ret = key; ++ key = NULL; ++ } ++ if (pkalgp != NULL) { ++ *pkalgp = pkalg; ++ pkalg = NULL; ++ } ++ } ++ sshkey_free(key); ++ free(pkalg); ++ free(pkblob); + + return (fail ? -1 : 0); + } +@@ -170,7 +181,7 @@ main(int argc, char **argv) + struct passwd *pw; + int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; + u_char *signature, *data, rver; +- char *host, *fp; ++ char *host, *fp, *pkalg; + size_t slen, dlen; + + if (pledge("stdio rpath getpw dns id", NULL) != 0) +@@ -258,7 +269,7 @@ main(int argc, char **argv) + + if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) + fatal_r(r, "%s: buffer error", __progname); +- if (valid_request(pw, host, &key, data, dlen) < 0) ++ if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0) + fatal("%s: not a valid request", __progname); + free(host); + +@@ -279,7 +290,7 @@ main(int argc, char **argv) + } + + if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, +- NULL, NULL, NULL, 0)) != 0) ++ pkalg, NULL, NULL, 0)) != 0) + fatal_r(r, "%s: sshkey_sign failed", __progname); + free(data); + diff --git a/openssh-8.7p1-ibmca.patch b/openssh-8.7p1-ibmca.patch new file mode 100644 index 0000000..c9c12ee --- /dev/null +++ b/openssh-8.7p1-ibmca.patch @@ -0,0 +1,12 @@ +--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200 ++++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200 +@@ -16,7 +16,7 @@ + + #include "includes.h" + +-#ifndef HAVE_CLOSEFROM ++#if (!defined HAVE_CLOSEFROM) || (defined __s390__) + + #include + #include + diff --git a/openssh-8.7p1-mem-leak.patch b/openssh-8.7p1-mem-leak.patch new file mode 100644 index 0000000..8c9ac80 --- /dev/null +++ b/openssh-8.7p1-mem-leak.patch @@ -0,0 +1,156 @@ +diff --color -rup a/compat.c b/compat.c +--- a/compat.c 2021-08-20 06:03:49.000000000 +0200 ++++ b/compat.c 2022-07-14 17:39:23.770268440 +0200 +@@ -157,11 +157,12 @@ compat_banner(struct ssh *ssh, const cha + debug_f("no match: %s", version); + } + ++/* Always returns pointer to allocated memory, caller must free. */ + char * + compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) + { + if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) +- return cipher_prop; ++ return xstrdup(cipher_prop); + debug2_f("original cipher proposal: %s", cipher_prop); + if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) + fatal("match_filter_denylist failed"); +@@ -171,11 +172,12 @@ compat_cipher_proposal(struct ssh *ssh, + return cipher_prop; + } + ++/* Always returns pointer to allocated memory, caller must free. */ + char * + compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) + { + if (!(ssh->compat & SSH_BUG_RSASIGMD5)) +- return pkalg_prop; ++ return xstrdup(pkalg_prop); + debug2_f("original public key proposal: %s", pkalg_prop); + if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) + fatal("match_filter_denylist failed"); +@@ -185,21 +187,26 @@ compat_pkalg_proposal(struct ssh *ssh, c + return pkalg_prop; + } + ++/* Always returns pointer to allocated memory, caller must free. */ + char * + compat_kex_proposal(struct ssh *ssh, char *p) + { ++ char *cp = NULL; ++ + if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) +- return p; ++ return xstrdup(p); + debug2_f("original KEX proposal: %s", p); + if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) + if ((p = match_filter_denylist(p, + "curve25519-sha256@libssh.org")) == NULL) + fatal("match_filter_denylist failed"); + if ((ssh->compat & SSH_OLD_DHGEX) != 0) { ++ cp = p; + if ((p = match_filter_denylist(p, + "diffie-hellman-group-exchange-sha256," + "diffie-hellman-group-exchange-sha1")) == NULL) + fatal("match_filter_denylist failed"); ++ free(cp); + } + debug2_f("compat KEX proposal: %s", p); + if (*p == '\0') +diff --color -rup a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2022-07-14 17:38:43.241496549 +0200 ++++ b/sshconnect2.c 2022-07-14 17:39:23.772268479 +0200 +@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st + { + char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + char *s, *all_key; ++ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; + int r, use_known_hosts_order = 0; + + #if defined(GSSAPI) && defined(WITH_OPENSSL) +@@ -252,10 +253,9 @@ ssh_kex2(struct ssh *ssh, char *host, st + + if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) + fatal_f("kex_names_cat"); +- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s); ++ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s); + myproposal[PROPOSAL_ENC_ALGS_CTOS] = +- compat_cipher_proposal(ssh, options.ciphers); +- myproposal[PROPOSAL_ENC_ALGS_STOC] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = + compat_cipher_proposal(ssh, options.ciphers); + myproposal[PROPOSAL_COMP_ALGS_CTOS] = + myproposal[PROPOSAL_COMP_ALGS_STOC] = +@@ -264,12 +264,12 @@ ssh_kex2(struct ssh *ssh, char *host, st + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + if (use_known_hosts_order) { + /* Query known_hosts and prefer algorithms that appear there */ +- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = + compat_pkalg_proposal(ssh, + order_hostkeyalgs(host, hostaddr, port, cinfo)); + } else { + /* Use specified HostkeyAlgorithms exactly */ +- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = + compat_pkalg_proposal(ssh, options.hostkeyalgorithms); + } + +@@ -383,6 +383,10 @@ ssh_kex2(struct ssh *ssh, char *host, st + (r = ssh_packet_write_wait(ssh)) != 0) + fatal_fr(r, "send packet"); + #endif ++ /* Free only parts of proposal that were dynamically allocated here. */ ++ free(prop_kex); ++ free(prop_enc); ++ free(prop_hostkey); + } + + /* +diff --color -rup a/sshd.c b/sshd.c +--- a/sshd.c 2022-07-14 17:38:43.242496568 +0200 ++++ b/sshd.c 2022-07-14 17:42:07.616388978 +0200 +@@ -2493,14 +2493,15 @@ do_ssh2_kex(struct ssh *ssh) + { + char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; + struct kex *kex; ++ char *hostkey_types = NULL; ++ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; + int r; + +- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, ++ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, + options.kex_algorithms); +- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, +- options.ciphers); +- myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh, +- options.ciphers); ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = ++ compat_cipher_proposal(ssh, options.ciphers); + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + +@@ -2513,8 +2514,10 @@ do_ssh2_kex(struct ssh *ssh) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); + +- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( +- ssh, list_hostkey_types()); ++ hostkey_types = list_hostkey_types(); ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = ++ compat_pkalg_proposal(ssh, hostkey_types); ++ free(hostkey_types); + + #if defined(GSSAPI) && defined(WITH_OPENSSL) + { +@@ -2606,6 +2609,9 @@ do_ssh2_kex(struct ssh *ssh) + (r = ssh_packet_write_wait(ssh)) != 0) + fatal_fr(r, "send test"); + #endif ++ free(prop_kex); ++ free(prop_enc); ++ free(prop_hostkey); + debug("KEX done"); + } + diff --git a/openssh-8.7p1-minimize-sha1-use.patch b/openssh-8.7p1-minimize-sha1-use.patch new file mode 100644 index 0000000..fc517da --- /dev/null +++ b/openssh-8.7p1-minimize-sha1-use.patch @@ -0,0 +1,207 @@ +diff --color -ru a/clientloop.c b/clientloop.c +--- a/clientloop.c 2022-06-29 16:35:06.677597259 +0200 ++++ b/clientloop.c 2022-06-29 16:40:29.737926205 +0200 +@@ -116,6 +116,9 @@ + #include "ssh-gss.h" + #endif + ++/* Permitted RSA signature algorithms for UpdateHostkeys proofs */ ++#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" ++ + /* import options */ + extern Options options; + +@@ -2110,8 +2113,10 @@ + struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; + size_t i, ndone; + struct sshbuf *signdata; +- int r, kexsigtype, use_kexsigtype; ++ int r, plaintype; + const u_char *sig; ++ const char *rsa_kexalg = NULL; ++ char *alg = NULL; + size_t siglen; + + if (ctx->nnew == 0) +@@ -2122,9 +2127,9 @@ + hostkeys_update_ctx_free(ctx); + return; + } +- kexsigtype = sshkey_type_plain( +- sshkey_type_from_name(ssh->kex->hostkey_alg)); +- ++ if (sshkey_type_plain(sshkey_type_from_name( ++ ssh->kex->hostkey_alg)) == KEY_RSA) ++ rsa_kexalg = ssh->kex->hostkey_alg; + if ((signdata = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + /* +@@ -2135,6 +2140,7 @@ + for (ndone = i = 0; i < ctx->nkeys; i++) { + if (ctx->keys_match[i]) + continue; ++ plaintype = sshkey_type_plain(ctx->keys[i]->type); + /* Prepare data to be signed: session ID, unique string, key */ + sshbuf_reset(signdata); + if ( (r = sshbuf_put_cstring(signdata, +@@ -2148,19 +2154,33 @@ + error_fr(r, "parse sig"); + goto out; + } ++ if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) { ++ error_fr(r, "server gave unintelligible signature " ++ "for %s key %zu", sshkey_type(ctx->keys[i]), i); ++ goto out; ++ } + /* +- * For RSA keys, prefer to use the signature type negotiated +- * during KEX to the default (SHA1). ++ * Special case for RSA keys: if a RSA hostkey was negotiated, ++ * then use its signature type for verification of RSA hostkey ++ * proofs. Otherwise, accept only RSA-SHA256/512 signatures. + */ +- use_kexsigtype = kexsigtype == KEY_RSA && +- sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA; +- debug3_f("verify %s key %zu using %s sigalg", +- sshkey_type(ctx->keys[i]), i, +- use_kexsigtype ? ssh->kex->hostkey_alg : "default"); ++ if (plaintype == KEY_RSA && rsa_kexalg == NULL && ++ match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) { ++ debug_f("server used untrusted RSA signature algorithm " ++ "%s for key %zu, disregarding", alg, i); ++ free(alg); ++ /* zap the key from the list */ ++ sshkey_free(ctx->keys[i]); ++ ctx->keys[i] = NULL; ++ ndone++; ++ continue; ++ } ++ debug3_f("verify %s key %zu using sigalg %s", ++ sshkey_type(ctx->keys[i]), i, alg); ++ free(alg); + if ((r = sshkey_verify(ctx->keys[i], sig, siglen, + sshbuf_ptr(signdata), sshbuf_len(signdata), +- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0, +- NULL)) != 0) { ++ plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) { + error_fr(r, "server gave bad signature for %s key %zu", + sshkey_type(ctx->keys[i]), i); + goto out; +diff --git a/hostfile.c b/hostfile.c +index a035b381..bd49e3ac 100644 +--- a/hostfile.c ++++ b/hostfile.c +@@ -642,7 +642,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, + /* Re-add the requested keys */ + want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP); + for (i = 0; i < nkeys; i++) { +- if ((want & ctx.match_keys[i]) == want) ++ if (keys[i] == NULL || (want & ctx.match_keys[i]) == want) + continue; + if ((fp = sshkey_fingerprint(keys[i], hash_alg, + SSH_FP_DEFAULT)) == NULL) { +diff --color -ru a/kex.c b/kex.c +--- a/kex.c 2022-06-29 16:35:06.775599179 +0200 ++++ b/kex.c 2022-06-29 16:42:00.839710940 +0200 +@@ -959,6 +959,18 @@ + return (1); + } + ++/* returns non-zero if proposal contains any algorithm from algs */ ++static int ++has_any_alg(const char *proposal, const char *algs) ++{ ++ char *cp; ++ ++ if ((cp = match_list(proposal, algs, NULL)) == NULL) ++ return 0; ++ free(cp); ++ return 1; ++} ++ + static int + kex_choose_conf(struct ssh *ssh) + { +@@ -994,6 +1006,16 @@ + free(ext); + } + ++ /* Check whether client supports rsa-sha2 algorithms */ ++ if (kex->server && (kex->flags & KEX_INITIAL)) { ++ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com")) ++ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED; ++ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com")) ++ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED; ++ } ++ + /* Algorithm Negotiation */ + if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], + sprop[PROPOSAL_KEX_ALGS])) != 0) { +diff --color -ru a/kex.h b/kex.h +--- a/kex.h 2022-06-29 16:35:06.766599003 +0200 ++++ b/kex.h 2022-06-29 16:42:24.199168567 +0200 +@@ -116,6 +116,8 @@ + + #define KEX_INIT_SENT 0x0001 + #define KEX_INITIAL 0x0002 ++#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ ++#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ + + struct sshenc { + char *name; +diff --color -ru a/serverloop.c b/serverloop.c +--- a/serverloop.c 2021-08-20 06:03:49.000000000 +0200 ++++ b/serverloop.c 2022-06-29 16:45:05.902336428 +0200 +@@ -684,16 +684,18 @@ + struct sshbuf *resp = NULL; + struct sshbuf *sigbuf = NULL; + struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; +- int r, ndx, kexsigtype, use_kexsigtype, success = 0; ++ int r, ndx, success = 0; + const u_char *blob; ++ const char *sigalg, *kex_rsa_sigalg = NULL; + u_char *sig = 0; + size_t blen, slen; + + if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) + fatal_f("sshbuf_new"); + +- kexsigtype = sshkey_type_plain( +- sshkey_type_from_name(ssh->kex->hostkey_alg)); ++ if (sshkey_type_plain(sshkey_type_from_name( ++ ssh->kex->hostkey_alg)) == KEY_RSA) ++ kex_rsa_sigalg = ssh->kex->hostkey_alg; + while (ssh_packet_remaining(ssh) > 0) { + sshkey_free(key); + key = NULL; +@@ -726,16 +728,24 @@ + * For RSA keys, prefer to use the signature type negotiated + * during KEX to the default (SHA1). + */ +- use_kexsigtype = kexsigtype == KEY_RSA && +- sshkey_type_plain(key->type) == KEY_RSA; ++ sigalg = NULL; ++ if (sshkey_type_plain(key->type) == KEY_RSA) { ++ if (kex_rsa_sigalg != NULL) ++ sigalg = kex_rsa_sigalg; ++ else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED) ++ sigalg = "rsa-sha2-512"; ++ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) ++ sigalg = "rsa-sha2-256"; ++ } ++ debug3_f("sign %s key (index %d) using sigalg %s", ++ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); + if ((r = sshbuf_put_cstring(sigbuf, + "hostkeys-prove-00@openssh.com")) != 0 || + (r = sshbuf_put_stringb(sigbuf, + ssh->kex->session_id)) != 0 || + (r = sshkey_puts(key, sigbuf)) != 0 || + (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen, +- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), +- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 || ++ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 || + (r = sshbuf_put_string(resp, sig, slen)) != 0) { + error_fr(r, "assemble signature"); + goto out; diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch new file mode 100644 index 0000000..107fe70 --- /dev/null +++ b/openssh-8.7p1-minrsabits.patch @@ -0,0 +1,437 @@ +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index 2ab222ed6..4e9437912 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -118,6 +118,10 @@ userauth_hostbased(struct ssh *ssh, const char *method) + "(null)" : key->cert->signature_type); + goto done; + } ++ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { ++ logit("refusing %s key", sshkey_type(key)); ++ goto done; ++ } + + if (!authctxt->valid || authctxt->user == NULL) { + debug2_f("disabled because of invalid user"); +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index daa756a01..68e7dea1f 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -172,6 +172,10 @@ userauth_pubkey(struct ssh *ssh, const char *method) + "(null)" : key->cert->signature_type); + goto done; + } ++ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { ++ logit("refusing %s key", sshkey_type(key)); ++ goto done; ++ } + key_s = format_key(key); + if (sshkey_is_cert(key)) + ca_s = format_key(key->cert->signature_key); +diff --git a/readconf.c b/readconf.c +index 5b5afa8e3..5e17abd41 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -160,7 +160,7 @@ typedef enum { + oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, + oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, + oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, +- oSecurityKeyProvider, oKnownHostsCommand, ++ oSecurityKeyProvider, oKnownHostsCommand, oRSAMinSize, + oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported + } OpCodes; + +@@ -306,6 +306,7 @@ static struct { + { "proxyjump", oProxyJump }, + { "securitykeyprovider", oSecurityKeyProvider }, + { "knownhostscommand", oKnownHostsCommand }, ++ { "rsaminsize", oRSAMinSize }, + + { NULL, oBadOption } + }; +@@ -2162,6 +2163,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, + *charptr = xstrdup(arg); + break; + ++ case oRSAMinSize: ++ intptr = &options->rsa_min_size; ++ goto parse_int; ++ + case oDeprecated: + debug("%s line %d: Deprecated option \"%s\"", + filename, linenum, keyword); +@@ -2409,6 +2414,7 @@ initialize_options(Options * options) + options->hostbased_accepted_algos = NULL; + options->pubkey_accepted_algos = NULL; + options->known_hosts_command = NULL; ++ options->rsa_min_size = -1; + } + + /* +@@ -2598,6 +2604,8 @@ fill_default_options(Options * options) + if (options->sk_provider == NULL) + options->sk_provider = xstrdup("$SSH_SK_PROVIDER"); + #endif ++ if (options->rsa_min_size == -1) ++ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE; + + /* Expand KEX name lists */ + all_cipher = cipher_alg_list(',', 0); +@@ -3287,6 +3295,7 @@ dump_client_config(Options *o, const char *host) + dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); + dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); + dump_cfg_int(oServerAliveInterval, o->server_alive_interval); ++ dump_cfg_int(oRSAMinSize, o->rsa_min_size); + + /* String options */ + dump_cfg_string(oBindAddress, o->bind_address); +diff --git a/readconf.h b/readconf.h +index f647bd42a..29db353ab 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -176,6 +176,8 @@ typedef struct { + + char *known_hosts_command; + ++ int rsa_min_size; /* minimum size of RSA keys */ ++ + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ + } Options; + +diff --git a/servconf.c b/servconf.c +index f7317a5cb..362ff5b67 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -177,6 +177,7 @@ initialize_server_options(ServerOptions *options) + options->fingerprint_hash = -1; + options->disable_forwarding = -1; + options->expose_userauth_info = -1; ++ options->rsa_min_size = -1; + } + + /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +@@ -416,6 +417,8 @@ fill_default_server_options(ServerOptions *options) + options->expose_userauth_info = 0; + if (options->sk_provider == NULL) + options->sk_provider = xstrdup("internal"); ++ if (options->rsa_min_size == -1) ++ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE; + + assemble_algorithms(options); + +@@ -489,6 +492,7 @@ typedef enum { + sStreamLocalBindMask, sStreamLocalBindUnlink, + sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, + sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, ++ sRSAMinSize, + sDeprecated, sIgnore, sUnsupported + } ServerOpCodes; + +@@ -632,6 +636,7 @@ static struct { + { "rdomain", sRDomain, SSHCFG_ALL }, + { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, + { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, ++ { "rsaminsize", sRSAMinSize, SSHCFG_ALL }, + { NULL, sBadOption, 0 } + }; + +@@ -2377,6 +2382,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, + *charptr = xstrdup(arg); + break; + ++ case sRSAMinSize: ++ intptr = &options->rsa_min_size; ++ goto parse_int; ++ + case sDeprecated: + case sIgnore: + case sUnsupported: +@@ -2549,6 +2558,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); + M_CP_INTOPT(log_level); ++ M_CP_INTOPT(rsa_min_size); + + /* + * The bind_mask is a mode_t that may be unsigned, so we can't use +@@ -2810,6 +2820,7 @@ dump_config(ServerOptions *o) + dump_cfg_int(sMaxSessions, o->max_sessions); + dump_cfg_int(sClientAliveInterval, o->client_alive_interval); + dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); ++ dump_cfg_int(sRSAMinSize, o->rsa_min_size); + dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); + + /* formatted integer arguments */ +diff --git a/servconf.h b/servconf.h +index 115db1e79..2e3486906 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -227,6 +227,7 @@ typedef struct { + int expose_userauth_info; + u_int64_t timing_secret; + char *sk_provider; ++ int rsa_min_size; /* minimum size of RSA keys */ + } ServerOptions; + + /* Information about the incoming connection as used by Match */ +diff --git a/ssh.c b/ssh.c +index a926cc007..cd13fb879 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -500,14 +500,22 @@ resolve_canonicalize(char **hostp, int port) + } + + /* +- * Check the result of hostkey loading, ignoring some errors and +- * fatal()ing for others. ++ * Check the result of hostkey loading, ignoring some errors and either ++ * discarding the key or fatal()ing for others. + */ + static void +-check_load(int r, const char *path, const char *message) ++check_load(int r, struct sshkey **k, const char *path, const char *message) + { + switch (r) { + case 0: ++ /* Check RSA keys size and discard if undersized */ ++ if (k != NULL && *k != NULL && ++ (r = sshkey_check_rsa_length(*k, ++ options.rsa_min_size)) != 0) { ++ error_r(r, "load %s \"%s\"", message, path); ++ free(*k); ++ *k = NULL; ++ } + break; + case SSH_ERR_INTERNAL_ERROR: + case SSH_ERR_ALLOC_FAIL: +@@ -1557,12 +1565,13 @@ main(int ac, char **av) + if ((o) >= sensitive_data.nkeys) \ + fatal_f("pubkey out of array bounds"); \ + check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ +- p, "pubkey"); \ ++ &(sensitive_data.keys[o]), p, "pubkey"); \ + } while (0) + #define L_CERT(p,o) do { \ + if ((o) >= sensitive_data.nkeys) \ + fatal_f("cert out of array bounds"); \ +- check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \ ++ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \ ++ &(sensitive_data.keys[o]), p, "cert"); \ + } while (0) + + if (options.hostbased_authentication == 1) { +@@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +- filename, "pubkey"); ++ &public, filename, "pubkey"); + debug("identity file %s type %d", filename, + public ? public->type : -1); + free(options.identity_files[i]); +@@ -2263,7 +2272,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + continue; + xasprintf(&cp, "%s-cert", filename); + check_load(sshkey_load_public(cp, &public, NULL), +- filename, "pubkey"); ++ &public, filename, "pubkey"); + debug("identity file %s type %d", cp, + public ? public->type : -1); + if (public == NULL) { +@@ -2294,7 +2303,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + free(cp); + + check_load(sshkey_load_public(filename, &public, NULL), +- filename, "certificate"); ++ &public, filename, "certificate"); + debug("certificate file %s type %d", filename, + public ? public->type : -1); + free(options.certificate_files[i]); +diff --git a/sshconnect2.c b/sshconnect2.c +index 67f8e0309..d050c1656 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -91,6 +91,10 @@ static const struct ssh_conn_info *xxx_conn_info; + static int + verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) + { ++ int r; ++ ++ if ((r = sshkey_check_rsa_length(hostkey, options.rsa_min_size)) != 0) ++ fatal_r(r, "Bad server host key"); + if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, + xxx_conn_info) == -1) + fatal("Host key verification failed."); +@@ -1762,6 +1762,12 @@ load_identity_file(Identity *id) + private = NULL; + quit = 1; + } ++ if (r = sshkey_check_rsa_length(private, options.rsa_min_size) != 0) { ++ debug_fr(r, "Skipping key %s", id->filename); ++ sshkey_free(private); ++ private = NULL; ++ quit = 1; ++ } + if (!quit && private != NULL && id->agent_fd == -1 && + !(id->key && id->isprivate)) + maybe_add_key_to_agent(id->filename, private, comment, +@@ -1747,6 +1751,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) + close(agent_fd); + } else { + for (j = 0; j < idlist->nkeys; j++) { ++ if ((r = sshkey_check_rsa_length(idlist->keys[j], ++ options.rsa_min_size)) != 0) { ++ debug_fr(r, "ignoring %s agent key", ++ sshkey_ssh_name(idlist->keys[j])); ++ continue; ++ } + found = 0; + TAILQ_FOREACH(id, &files, next) { + /* +diff --git a/sshd.c b/sshd.c +index d26eb86ae..5f36905a1 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1746,6 +1746,13 @@ main(int ac, char **av) + fatal_r(r, "Could not demote key: \"%s\"", + options.host_key_files[i]); + } ++ if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey, ++ options.rsa_min_size)) != 0) { ++ error_fr(r, "Host key %s", options.host_key_files[i]); ++ sshkey_free(pubkey); ++ sshkey_free(key); ++ continue; ++ } + sensitive_data.host_keys[i] = key; + sensitive_data.host_pubkeys[i] = pubkey; + +diff --git a/sshkey.c b/sshkey.c +index 47864e6d8..8bad6bd99 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -2319,18 +2319,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) + return ret; + } + +-#ifdef WITH_OPENSSL +-static int +-check_rsa_length(const RSA *rsa) ++int ++sshkey_check_rsa_length(const struct sshkey *k, int min_size) + { ++#ifdef WITH_OPENSSL + const BIGNUM *rsa_n; ++ int nbits; + +- RSA_get0_key(rsa, &rsa_n, NULL, NULL); +- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) ++ if (k == NULL || k->rsa == NULL || ++ (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) ++ return 0; ++ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); ++ nbits = BN_num_bits(rsa_n); ++ if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || ++ (min_size > 0 && nbits < min_size)) + return SSH_ERR_KEY_LENGTH; ++#endif /* WITH_OPENSSL */ + return 0; + } +-#endif + + static int + sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, +@@ -2391,7 +2397,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, + goto out; + } + rsa_n = rsa_e = NULL; /* transferred */ +- if ((ret = check_rsa_length(key->rsa)) != 0) ++ if ((ret = sshkey_check_rsa_length(key, 0)) != 0) + goto out; + #ifdef DEBUG_PK + RSA_print_fp(stderr, key->rsa, 8); +@@ -3580,7 +3586,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) + goto out; + } + rsa_p = rsa_q = NULL; /* transferred */ +- if ((r = check_rsa_length(k->rsa)) != 0) ++ if ((r = sshkey_check_rsa_length(k, 0)) != 0) + goto out; + if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) + goto out; +@@ -4566,7 +4572,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- if ((r = check_rsa_length(prv->rsa)) != 0) ++ if ((r = sshkey_check_rsa_length(prv, 0)) != 0) + goto out; + } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && + (type == KEY_UNSPEC || type == KEY_DSA)) { +diff --git a/sshkey.h b/sshkey.h +index 125cadb64..52e879456 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -267,6 +267,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, + int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, + int type, struct sshkey **pubkeyp); + ++int sshkey_check_rsa_length(const struct sshkey *, int); + /* XXX should be internal, but used by ssh-keygen */ + int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); + +diff --git a/ssh.1 b/ssh.1 +index b4956aec..b1a40ebd 100644 +--- a/ssh.1 ++++ b/ssh.1 +@@ -554,6 +554,7 @@ For full details of the options listed below, and their possible values, see + .It LogLevel + .It MACs + .It Match ++.It RSAMinSize + .It NoHostAuthenticationForLocalhost + .It NumberOfPasswordPrompts + .It PasswordAuthentication +diff --git a/ssh_config.5 b/ssh_config.5 +index 24a46460..68771e4b 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -1322,6 +1322,10 @@ The argument to this keyword must be + or + .Cm no + (the default). ++.It Cm RSAMinSize ++Provides a minimal bits requirement for RSA keys when used for signature and ++verification but not for the key generation. The default value is 1024 and ++can't be reduced. + .It Cm NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. + The argument to this keyword must be an integer. +diff --git a/sshd_config.5 b/sshd_config.5 +index 867a747d..e08811ca 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1266,6 +1266,10 @@ will refuse connection attempts with a probability of rate/100 (30%) + if there are currently start (10) unauthenticated connections. + The probability increases linearly and all connection attempts + are refused if the number of unauthenticated connections reaches full (60). ++.It Cm RSAMinSize ++Provides a minimal bits requirement for RSA keys when used for signature and ++verification but not for the key generation. The default value is 1024 and ++can't be reduced. + .It Cm ModuliFile + Specifies the + .Xr moduli 5 +diff --git a/sshkey.h b/sshkey.h +index 094815e0..2bb8cb90 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -286,6 +286,8 @@ int sshkey_private_serialize_maxsign(struct sshkey *key, + + void sshkey_sig_details_free(struct sshkey_sig_details *); + ++int ssh_set_rsa_min_bits(int minbits); ++ + #ifdef SSHKEY_INTERNAL + int ssh_rsa_sign(const struct sshkey *key, + u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch new file mode 100644 index 0000000..2fb9297 --- /dev/null +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -0,0 +1,63 @@ +diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh +--- a/regress/hostkey-agent.sh 2021-08-20 06:03:49.000000000 +0200 ++++ b/regress/hostkey-agent.sh 2022-07-14 11:58:12.172786060 +0200 +@@ -13,8 +13,12 @@ r=$? + grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig + echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig + ++PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \ ++ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"` ++SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"` ++ + 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" + ( + printf 'localhost-with-alias,127.0.0.1,::1 ' +@@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host + unset SSH_AUTH_SOCK + + for ps in yes; do +- for k in $SSH_KEYTYPES ; do ++ for k in $SSH_ACCEPTED_KEYTYPES ; do + verbose "key type $k privsep=$ps" + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy +diff --color -rup a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2022-07-14 10:10:07.262975710 +0200 ++++ b/sshconnect2.c 2022-07-14 10:10:32.068452067 +0200 +@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st + { + char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + char *s, *all_key; ++ char *hostkeyalgs = NULL, *pkalg = NULL; + char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; + int r, use_known_hosts_order = 0; + +@@ -264,14 +265,19 @@ ssh_kex2(struct ssh *ssh, char *host, st + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + if (use_known_hosts_order) { + /* Query known_hosts and prefer algorithms that appear there */ +- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = +- compat_pkalg_proposal(ssh, +- order_hostkeyalgs(host, hostaddr, port, cinfo)); ++ if ((hostkeyalgs = order_hostkeyalgs(host, hostaddr, port, cinfo)) == NULL) ++ fatal_f("order_hostkeyalgs"); ++ pkalg = match_filter_allowlist(hostkeyalgs, options.pubkey_accepted_algos); ++ free(hostkeyalgs); + } else { +- /* Use specified HostkeyAlgorithms exactly */ +- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = +- compat_pkalg_proposal(ssh, options.hostkeyalgorithms); ++ /* Use specified HostkeyAlgorithms */ ++ pkalg = match_filter_allowlist(options.hostkeyalgorithms, options.pubkey_accepted_algos); + } ++ if (pkalg == NULL) ++ fatal_f("match_filter_allowlist"); ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = ++ compat_pkalg_proposal(ssh, pkalg); ++ free(pkalg); + + #if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch new file mode 100644 index 0000000..25765fb --- /dev/null +++ b/openssh-8.7p1-recursive-scp.patch @@ -0,0 +1,174 @@ +diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100 ++++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100 +@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t + + if (src_is_dir && iamrecursive) { + if (upload_dir(conn, src, abs_dst, pflag, +- SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { ++ SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { + error("failed to upload directory %s to %s", + src, abs_dst); + errs = 1; +diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c +--- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 +@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons + + /* Implements both the realpath and expand-path operations */ + static char * +-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) ++do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) + { + struct sshbuf *msg; + u_int expected_id, count, id; +@@ -1012,9 +1012,38 @@ do_realpath_expand(struct sftp_conn *con + + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal_fr(r, "parse status"); +- error("Couldn't canonicalize: %s", fx2txt(status)); +- sshbuf_free(msg); +- return NULL; ++ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) { ++ memset(&a, '\0', sizeof(a)); ++ if ((r = do_mkdir(conn, path, &a, 0)) != 0) { ++ sshbuf_free(msg); ++ return NULL; ++ } ++ ++ 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) { ++ u_int status; ++ ++ if ((r = sshbuf_get_u32(msg, &status)) != 0) ++ fatal_fr(r, "parse status"); ++ error("Couldn't canonicalize: %s", fx2txt(status)); ++ sshbuf_free(msg); ++ return NULL; ++ } ++ } else { ++ error("Couldn't canonicalize: %s", fx2txt(status)); ++ sshbuf_free(msg); ++ return NULL; ++ } + } else if (type != SSH2_FXP_NAME) + fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", + SSH2_FXP_NAME, type); +@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con + } + + char * +-do_realpath(struct sftp_conn *conn, const char *path) ++do_realpath(struct sftp_conn *conn, const char *path, int create_dir) + { +- return do_realpath_expand(conn, path, 0); ++ return do_realpath_expand(conn, path, 0, create_dir); + } + + int +@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c + { + if (!can_expand_path(conn)) { + debug3_f("no server support, fallback to realpath"); +- return do_realpath_expand(conn, path, 0); ++ return do_realpath_expand(conn, path, 0, 0); + } +- return do_realpath_expand(conn, path, 1); ++ return do_realpath_expand(conn, path, 1, 0); + } + + int +@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con + char *src_canon; + int ret; + +- if ((src_canon = do_realpath(conn, src)) == NULL) { ++ if ((src_canon = do_realpath(conn, src, 0)) == NULL) { + error("Unable to canonicalize path \"%s\"", src); + return -1; + } +@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co + int + upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + int preserve_flag, int print_flag, int resume, int fsync_flag, +- int follow_link_flag) ++ int follow_link_flag, int create_dir) + { + char *dst_canon; + int ret; + +- if ((dst_canon = do_realpath(conn, dst)) == NULL) { ++ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { + error("Unable to canonicalize path \"%s\"", dst); + return -1; + } +@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st + char *from_path_canon; + int ret; + +- if ((from_path_canon = do_realpath(from, from_path)) == NULL) { ++ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { + error("Unable to canonicalize path \"%s\"", from_path); + return -1; + } +diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h +--- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 +@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons + int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); + + /* Canonicalise 'path' - caller must free result */ +-char *do_realpath(struct sftp_conn *, const char *); ++char *do_realpath(struct sftp_conn *, const char *, int); + + /* Canonicalisation with tilde expansion (requires server extension) */ + char *do_expand_path(struct sftp_conn *, const char *); +@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const + * times if 'pflag' is set + */ + int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, +- int, int); ++ int, int, int); + + /* + * Download a 'from_path' from the 'from' connection and upload it to +diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c +--- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100 +@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons + if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { + if (upload_dir(conn, g.gl_pathv[i], abs_dst, + pflag || global_pflag, 1, resume, +- fflag || global_fflag, 0) == -1) ++ fflag || global_fflag, 0, 0) == -1) + err = -1; + } else { + if (do_upload(conn, g.gl_pathv[i], abs_dst, +@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn + if (path1 == NULL || *path1 == '\0') + path1 = xstrdup(startdir); + path1 = make_absolute(path1, *pwd); +- if ((tmp = do_realpath(conn, path1)) == NULL) { ++ if ((tmp = do_realpath(conn, path1, 0)) == NULL) { + err = 1; + break; + } +@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn, + } + #endif /* USE_LIBEDIT */ + +- remote_path = do_realpath(conn, "."); ++ remote_path = do_realpath(conn, ".", 0); + if (remote_path == NULL) + fatal("Need cwd"); + startdir = xstrdup(remote_path); diff --git a/openssh-8.7p1-scp-clears-file.patch b/openssh-8.7p1-scp-clears-file.patch new file mode 100644 index 0000000..4c033da --- /dev/null +++ b/openssh-8.7p1-scp-clears-file.patch @@ -0,0 +1,304 @@ +diff --color -rup a/scp.c b/scp.c +--- a/scp.c 2022-07-26 14:51:40.560120817 +0200 ++++ b/scp.c 2022-07-26 14:52:37.118213004 +0200 +@@ -1324,12 +1324,12 @@ source_sftp(int argc, char *src, char *t + + if (src_is_dir && iamrecursive) { + if (upload_dir(conn, src, abs_dst, pflag, +- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { ++ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) { + error("failed to upload directory %s to %s", + src, abs_dst); + errs = 1; + } +- } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) { ++ } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) { + error("failed to upload file %s to %s", src, abs_dst); + errs = 1; + } +@@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha + debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); + if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { + if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, +- pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1) ++ pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1) + err = -1; + } else { + if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, +- pflag, 0, 0) == -1) ++ pflag, 0, 0, 1) == -1) + err = -1; + } + free(abs_dst); +diff --color -rup a/sftp.c b/sftp.c +--- a/sftp.c 2022-07-26 14:51:40.561120836 +0200 ++++ b/sftp.c 2022-07-26 14:52:37.119213023 +0200 +@@ -666,12 +666,12 @@ process_get(struct sftp_conn *conn, cons + if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { + if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, + pflag || global_pflag, 1, resume, +- fflag || global_fflag, 0) == -1) ++ fflag || global_fflag, 0, 0) == -1) + err = -1; + } else { + if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, + pflag || global_pflag, resume, +- fflag || global_fflag) == -1) ++ fflag || global_fflag, 0) == -1) + err = -1; + } + free(abs_dst); +@@ -760,12 +760,12 @@ process_put(struct sftp_conn *conn, cons + if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { + if (upload_dir(conn, g.gl_pathv[i], abs_dst, + pflag || global_pflag, 1, resume, +- fflag || global_fflag, 0, 0) == -1) ++ fflag || global_fflag, 0, 0, 0) == -1) + err = -1; + } else { + if (do_upload(conn, g.gl_pathv[i], abs_dst, + pflag || global_pflag, resume, +- fflag || global_fflag) == -1) ++ fflag || global_fflag, 0) == -1) + err = -1; + } + } +diff --color -rup a/sftp-client.c b/sftp-client.c +--- a/sftp-client.c 2022-07-26 14:51:40.561120836 +0200 ++++ b/sftp-client.c 2022-07-26 15:09:54.825295533 +0200 +@@ -1454,7 +1454,7 @@ progress_meter_path(const char *path) + int + do_download(struct sftp_conn *conn, const char *remote_path, + const char *local_path, Attrib *a, int preserve_flag, int resume_flag, +- int fsync_flag) ++ int fsync_flag, int inplace_flag) + { + struct sshbuf *msg; + u_char *handle; +@@ -1498,8 +1498,8 @@ do_download(struct sftp_conn *conn, cons + &handle, &handle_len) != 0) + return -1; + +- local_fd = open(local_path, +- O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); ++ local_fd = open(local_path, O_WRONLY | O_CREAT | ++ ((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR); + if (local_fd == -1) { + error("Couldn't open local file \"%s\" for writing: %s", + local_path, strerror(errno)); +@@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons + /* Sanity check */ + if (TAILQ_FIRST(&requests) != NULL) + fatal("Transfer complete, but requests still in queue"); +- /* Truncate at highest contiguous point to avoid holes on interrupt */ +- if (read_error || write_error || interrupted) { ++ /* ++ * Truncate at highest contiguous point to avoid holes on interrupt, ++ * or unconditionally if writing in place. ++ */ ++ if (inplace_flag || read_error || write_error || interrupted) { + if (reordered && resume_flag) { + error("Unable to resume download of \"%s\": " + "server reordered requests", local_path); +@@ -1724,7 +1727,7 @@ do_download(struct sftp_conn *conn, cons + static int + download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + int depth, Attrib *dirattrib, int preserve_flag, int print_flag, +- int resume_flag, int fsync_flag, int follow_link_flag) ++ int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag) + { + int i, ret = 0; + SFTP_DIRENT **dir_entries; +@@ -1781,7 +1784,7 @@ download_dir_internal(struct sftp_conn * + if (download_dir_internal(conn, new_src, new_dst, + depth + 1, &(dir_entries[i]->a), preserve_flag, + print_flag, resume_flag, +- fsync_flag, follow_link_flag) == -1) ++ fsync_flag, follow_link_flag, inplace_flag) == -1) + ret = -1; + } else if (S_ISREG(dir_entries[i]->a.perm) || + (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) { +@@ -1793,7 +1796,8 @@ download_dir_internal(struct sftp_conn * + if (do_download(conn, new_src, new_dst, + S_ISLNK(dir_entries[i]->a.perm) ? NULL : + &(dir_entries[i]->a), +- preserve_flag, resume_flag, fsync_flag) == -1) { ++ preserve_flag, resume_flag, fsync_flag, ++ inplace_flag) == -1) { + error("Download of file %s to %s failed", + new_src, new_dst); + ret = -1; +@@ -1831,7 +1835,7 @@ download_dir_internal(struct sftp_conn * + int + download_dir(struct sftp_conn *conn, const char *src, const char *dst, + Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, +- int fsync_flag, int follow_link_flag) ++ int fsync_flag, int follow_link_flag, int inplace_flag) + { + char *src_canon; + int ret; +@@ -1843,26 +1847,25 @@ download_dir(struct sftp_conn *conn, con + + ret = download_dir_internal(conn, src_canon, dst, 0, + dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag, +- follow_link_flag); ++ follow_link_flag, inplace_flag); + free(src_canon); + return ret; + } + + int + do_upload(struct sftp_conn *conn, const char *local_path, +- const char *remote_path, int preserve_flag, int resume, int fsync_flag) ++ const char *remote_path, int preserve_flag, int resume, ++ int fsync_flag, int inplace_flag) + { + int r, local_fd; +- u_int status = SSH2_FX_OK; +- u_int id; +- u_char type; ++ u_int openmode, id, status = SSH2_FX_OK, reordered = 0; + off_t offset, progress_counter; +- u_char *handle, *data; ++ u_char type, *handle, *data; + struct sshbuf *msg; + struct stat sb; +- Attrib a, *c = NULL; +- u_int32_t startid; +- u_int32_t ackid; ++ Attrib a, t, *c = NULL; ++ u_int32_t startid, ackid; ++ u_int64_t highwater = 0; + struct request *ack = NULL; + struct requests acks; + size_t handle_len; +@@ -1913,10 +1916,15 @@ do_upload(struct sftp_conn *conn, const + } + } + ++ openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT; ++ if (resume) ++ openmode |= SSH2_FXF_APPEND; ++ else if (!inplace_flag) ++ openmode |= SSH2_FXF_TRUNC; ++ + /* Send open request */ +- if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT| +- (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC), +- &a, &handle, &handle_len) != 0) { ++ if (send_open(conn, remote_path, "dest", openmode, &a, ++ &handle, &handle_len) != 0) { + close(local_fd); + return -1; + } +@@ -1999,6 +2007,12 @@ do_upload(struct sftp_conn *conn, const + ack->id, ack->len, (unsigned long long)ack->offset); + ++ackid; + progress_counter += ack->len; ++ if (!reordered && ack->offset <= highwater) ++ highwater = ack->offset + ack->len; ++ else if (!reordered && ack->offset > highwater) { ++ debug3_f("server reordered ACKs"); ++ reordered = 1; ++ } + free(ack); + } + offset += len; +@@ -2017,6 +2031,14 @@ do_upload(struct sftp_conn *conn, const + status = SSH2_FX_FAILURE; + } + ++ if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) { ++ debug("truncating at %llu", (unsigned long long)highwater); ++ attrib_clear(&t); ++ t.flags = SSH2_FILEXFER_ATTR_SIZE; ++ t.size = highwater; ++ do_fsetstat(conn, handle, handle_len, &t); ++ } ++ + if (close(local_fd) == -1) { + error("Couldn't close local file \"%s\": %s", local_path, + strerror(errno)); +@@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const + static int + upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + int depth, int preserve_flag, int print_flag, int resume, int fsync_flag, +- int follow_link_flag) ++ int follow_link_flag, int inplace_flag) + { + int ret = 0; + DIR *dirp; +@@ -2119,12 +2141,13 @@ upload_dir_internal(struct sftp_conn *co + + if (upload_dir_internal(conn, new_src, new_dst, + depth + 1, preserve_flag, print_flag, resume, +- fsync_flag, follow_link_flag) == -1) ++ fsync_flag, follow_link_flag, inplace_flag) == -1) + ret = -1; + } else if (S_ISREG(sb.st_mode) || + (follow_link_flag && S_ISLNK(sb.st_mode))) { + if (do_upload(conn, new_src, new_dst, +- preserve_flag, resume, fsync_flag) == -1) { ++ preserve_flag, resume, fsync_flag, ++ inplace_flag) == -1) { + error("Uploading of file %s to %s failed!", + new_src, new_dst); + ret = -1; +@@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co + int + upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + int preserve_flag, int print_flag, int resume, int fsync_flag, +- int follow_link_flag, int create_dir) ++ int follow_link_flag, int create_dir, int inplace_flag) + { + char *dst_canon; + int ret; +@@ -2155,7 +2178,7 @@ upload_dir(struct sftp_conn *conn, const + } + + ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, +- print_flag, resume, fsync_flag, follow_link_flag); ++ print_flag, resume, fsync_flag, follow_link_flag, inplace_flag); + + free(dst_canon); + return ret; +diff --color -rup a/sftp-client.h b/sftp-client.h +--- a/sftp-client.h 2022-07-26 14:51:40.561120836 +0200 ++++ b/sftp-client.h 2022-07-26 14:52:37.120213042 +0200 +@@ -138,28 +138,29 @@ int do_fsync(struct sftp_conn *conn, u_c + * Download 'remote_path' to 'local_path'. Preserve permissions and times + * if 'pflag' is set + */ +-int do_download(struct sftp_conn *, const char *, const char *, +- Attrib *, int, int, int); ++int do_download(struct sftp_conn *, const char *, const char *, Attrib *, ++ int, int, int, int); + + /* + * Recursively download 'remote_directory' to 'local_directory'. Preserve + * times if 'pflag' is set + */ +-int download_dir(struct sftp_conn *, const char *, const char *, +- Attrib *, int, int, int, int, int); ++int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, ++ int, int, int, int, int, int); + + /* + * Upload 'local_path' to 'remote_path'. Preserve permissions and times + * if 'pflag' is set + */ +-int do_upload(struct sftp_conn *, const char *, const char *, int, int, int); ++int do_upload(struct sftp_conn *, const char *, const char *, ++ int, int, int, int); + + /* + * Recursively upload 'local_directory' to 'remote_directory'. Preserve + * times if 'pflag' is set + */ +-int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, +- int, int, int); ++int upload_dir(struct sftp_conn *, const char *, const char *, ++ int, int, int, int, int, int, int); + + /* + * Download a 'from_path' from the 'from' connection and upload it to diff --git a/openssh-8.7p1-sftpscp-dir-create.patch b/openssh-8.7p1-sftpscp-dir-create.patch new file mode 100644 index 0000000..bc504f9 --- /dev/null +++ b/openssh-8.7p1-sftpscp-dir-create.patch @@ -0,0 +1,135 @@ +diff -up openssh-8.7p1/scp.c.sftpdirs openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.sftpdirs 2022-02-02 14:11:12.553447509 +0100 ++++ openssh-8.7p1/scp.c 2022-02-02 14:12:56.081316414 +0100 +@@ -130,6 +130,7 @@ + #include "misc.h" + #include "progressmeter.h" + #include "utf8.h" ++#include "sftp.h" + + #include "sftp-common.h" + #include "sftp-client.h" +@@ -1264,13 +1265,18 @@ tolocal(int argc, char **argv, enum scp_ + static char * + prepare_remote_path(struct sftp_conn *conn, const char *path) + { ++ size_t nslash; ++ + /* Handle ~ prefixed paths */ +- if (*path != '~') +- return xstrdup(path); + if (*path == '\0' || strcmp(path, "~") == 0) + return xstrdup("."); +- if (strncmp(path, "~/", 2) == 0) +- return xstrdup(path + 2); ++ if (*path != '~') ++ return xstrdup(path); ++ if (strncmp(path, "~/", 2) == 0) { ++ if ((nslash = strspn(path + 2, "/")) == strlen(path + 2)) ++ return xstrdup("."); ++ return xstrdup(path + 2 + nslash); ++ } + if (can_expand_path(conn)) + return do_expand_path(conn, path); + /* No protocol extension */ +@@ -1282,10 +1288,16 @@ void + source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) + { + char *target = NULL, *filename = NULL, *abs_dst = NULL; +- int target_is_dir; +- ++ int src_is_dir, target_is_dir; ++ Attrib a; ++ struct stat st; ++ ++ memset(&a, '\0', sizeof(a)); ++ if (stat(src, &st) != 0) ++ fatal("stat local \"%s\": %s", src, strerror(errno)); ++ src_is_dir = S_ISDIR(st.st_mode); + if ((filename = basename(src)) == NULL) +- fatal("basename %s: %s", src, strerror(errno)); ++ fatal("basename \"%s\": %s", src, strerror(errno)); + + /* + * No need to glob here - the local shell already took care of +@@ -1295,8 +1307,12 @@ source_sftp(int argc, char *src, char *t + cleanup_exit(255); + target_is_dir = remote_is_dir(conn, target); + if (targetshouldbedirectory && !target_is_dir) { +- fatal("Target is not a directory, but more files selected " +- "for upload"); ++ debug("target directory \"%s\" does not exist", target); ++ a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS; ++ a.perm = st.st_mode | 0700; /* ensure writable */ ++ if (do_mkdir(conn, target, &a, 1) != 0) ++ cleanup_exit(255); /* error already logged */ ++ target_is_dir = 1; + } + if (target_is_dir) + abs_dst = path_append(target, filename); +@@ -1306,7 +1322,7 @@ source_sftp(int argc, char *src, char *t + } + debug3_f("copying local %s to remote %s", src, abs_dst); + +- if (local_is_dir(src) && iamrecursive) { ++ if (src_is_dir && iamrecursive) { + if (upload_dir(conn, src, abs_dst, pflag, + SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { + error("failed to upload directory %s to %s", +@@ -1487,14 +1506,15 @@ sink_sftp(int argc, char *dst, const cha + char *abs_dst = NULL; + glob_t g; + char *filename, *tmp = NULL; +- int i, r, err = 0; ++ int i, r, err = 0, dst_is_dir; ++ struct stat st; + + memset(&g, 0, sizeof(g)); ++ + /* + * Here, we need remote glob as SFTP can not depend on remote shell + * expansions + */ +- + if ((abs_src = prepare_remote_path(conn, src)) == NULL) { + err = -1; + goto out; +@@ -1510,11 +1530,24 @@ sink_sftp(int argc, char *dst, const cha + goto out; + } + +- if (g.gl_matchc > 1 && !local_is_dir(dst)) { +- error("Multiple files match pattern, but destination " +- "\"%s\" is not a directory", dst); +- err = -1; +- goto out; ++ if ((r = stat(dst, &st)) != 0) ++ debug2_f("stat local \"%s\": %s", dst, strerror(errno)); ++ dst_is_dir = r == 0 && S_ISDIR(st.st_mode); ++ ++ if (g.gl_matchc > 1 && !dst_is_dir) { ++ if (r == 0) { ++ error("Multiple files match pattern, but destination " ++ "\"%s\" is not a directory", dst); ++ err = -1; ++ goto out; ++ } ++ debug2_f("creating destination \"%s\"", dst); ++ if (mkdir(dst, 0777) != 0) { ++ error("local mkdir \"%s\": %s", dst, strerror(errno)); ++ err = -1; ++ goto out; ++ } ++ dst_is_dir = 1; + } + + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { +@@ -1525,7 +1558,7 @@ sink_sftp(int argc, char *dst, const cha + goto out; + } + +- if (local_is_dir(dst)) ++ if (dst_is_dir) + abs_dst = path_append(dst, filename); + else + abs_dst = xstrdup(dst); diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch new file mode 100644 index 0000000..bd0bdb7 --- /dev/null +++ b/openssh-8.7p1-ssh-manpage.patch @@ -0,0 +1,53 @@ +diff --color -ru a/ssh.1 b/ssh.1 +--- a/ssh.1 2022-07-12 11:47:51.307295880 +0200 ++++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200 +@@ -493,6 +493,7 @@ + .It AddressFamily + .It BatchMode + .It BindAddress ++.It BindInterface + .It CanonicalDomains + .It CanonicalizeFallbackLocal + .It CanonicalizeHostname +@@ -510,6 +511,7 @@ + .It ControlPath + .It ControlPersist + .It DynamicForward ++.It EnableSSHKeysign + .It EscapeChar + .It ExitOnForwardFailure + .It FingerprintHash +@@ -538,6 +540,8 @@ + .It IdentitiesOnly + .It IdentityAgent + .It IdentityFile ++.It IgnoreUnknown ++.It Include + .It IPQoS + .It KbdInteractiveAuthentication + .It KbdInteractiveDevices +@@ -546,6 +550,7 @@ + .It LocalCommand + .It LocalForward + .It LogLevel ++.It LogVerbose + .It MACs + .It Match + .It RSAMinSize +@@ -566,6 +571,8 @@ + .It RemoteCommand + .It RemoteForward + .It RequestTTY ++.It RevokedHostKeys ++.It SecurityKeyProvider + .It SendEnv + .It ServerAliveInterval + .It ServerAliveCountMax +@@ -575,6 +582,7 @@ + .It StreamLocalBindMask + .It StreamLocalBindUnlink + .It StrictHostKeyChecking ++.It SyslogFacility + .It TCPKeepAlive + .It Tunnel + .It TunnelDevice diff --git a/openssh-8.8p1-hpn-15.2-modified.patch b/openssh-8.8p1-hpn-15.2-modified.patch index 4f68944..807c8ef 100644 --- a/openssh-8.8p1-hpn-15.2-modified.patch +++ b/openssh-8.8p1-hpn-15.2-modified.patch @@ -1517,6 +1517,14 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message +@@ -1991,6 +2047,7 @@ + return SSH_ERR_CONN_CLOSED; + if ((r = sshbuf_consume(state->output, len)) != 0) + return r; ++ ssh->stdin_bytes += len; + } + return 0; + } @@ -2794,3 +2850,10 @@ ssh->state->extra_pad = pad; return 0; @@ -1666,8 +1674,8 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, @@ -336,6 +344,11 @@ - { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, + { "rsaminsize", oRSAMinSize }, + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, @@ -2537,7 +2545,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c do_authenticated(ssh, authctxt); @@ -2486,6 +2528,11 @@ - struct kex *kex; + char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; int r; + if (options.none_enabled == 1) @@ -2545,9 +2553,9 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c + if (options.nonemac_enabled == 1) + debug("WARNING: None MAC enabled"); + - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, + myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, options.kex_algorithms); - myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, + myproposal[PROPOSAL_ENC_ALGS_CTOS] = diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config --- openssh-8.8p1.orig/sshd_config 2021-12-01 16:50:22.524385588 +0100 +++ openssh-8.8p1/sshd_config 2021-12-01 16:51:00.941474165 +0100 diff --git a/openssh-8.8p1-skip-some-tests.patch b/openssh-8.8p1-skip-some-tests.patch new file mode 100644 index 0000000..7268eb3 --- /dev/null +++ b/openssh-8.8p1-skip-some-tests.patch @@ -0,0 +1,41 @@ +diff -up openssh-8.8p1/regress/hostkey-agent.sh.redhat openssh-8.8p1/regress/hostkey-agent.sh +--- openssh-8.8p1/regress/hostkey-agent.sh.redhat 2022-08-10 15:54:42.084777662 +0200 ++++ openssh-8.8p1/regress/hostkey-agent.sh 2022-08-10 17:01:25.651269994 +0200 +@@ -36,6 +36,8 @@ unset SSH_AUTH_SOCK + + for ps in yes; do + for k in $SSH_ACCEPTED_KEYTYPES ; do ++ [ "$k" == "ssh-rsa" ] && continue ++ [ "$k" == "ssh-dss" ] && continue + verbose "key type $k privsep=$ps" + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy +diff -up openssh-8.8p1/regress/hostkey-rotate.sh.redhat openssh-8.8p1/regress/hostkey-rotate.sh +--- openssh-8.8p1/regress/hostkey-rotate.sh.redhat 2022-08-10 16:57:12.720029146 +0200 ++++ openssh-8.8p1/regress/hostkey-rotate.sh 2022-08-10 17:15:48.274923865 +0200 +@@ -40,6 +40,8 @@ trace "prepare hostkeys" + nkeys=0 + all_algs="" + for k in $SSH_HOSTKEY_TYPES; do ++ [ "$k" == "ssh-rsa" ] && continue ++ [ "$k" == "ssh-dss" ] && continue + ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" + echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig + nkeys=`expr $nkeys + 1` +@@ -87,11 +89,15 @@ dossh -oStrictHostKeyChecking=yes -oHost + # Check that other keys learned + expect_nkeys $nkeys "learn hostkeys" + for k in $SSH_HOSTKEY_TYPES; do ++ [ "$k" == "ssh-rsa" ] && continue ++ [ "$k" == "ssh-dss" ] && continue + check_key_present $k || fail "didn't learn keytype $k" + done + + # Check each key type + for k in $SSH_HOSTKEY_TYPES; do ++ [ "$k" == "ssh-rsa" ] && continue ++ [ "$k" == "ssh-dss" ] && continue + verbose "learn additional hostkeys, type=$k" + dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs + expect_nkeys $nkeys "learn hostkeys $k" + From 66cc7b96c8aabc497dc98e9443ce15a3e28cf408 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 1 Sep 2022 10:32:01 +0200 Subject: [PATCH 108/146] Based on openssh-9.0p1-3.fc38 --- gsi-openssh.spec | 44 +- openssh-5.8p2-sigpipe.patch | 10 +- openssh-6.6.1p1-log-in-chroot.patch | 4 +- openssh-6.7p1-coverity.patch | 77 ---- openssh-7.3p1-x11-max-displays.patch | 4 +- openssh-7.6p1-audit.patch | 18 +- openssh-7.7p1-fips.patch | 2 +- openssh-7.8p1-UsePAM-warning.patch | 2 +- openssh-7.8p1-role-mls.patch | 6 +- openssh-8.0p1-crypto-policies.patch | 137 +++++- openssh-8.0p1-gssapi-keyex.patch | 24 +- openssh-8.0p1-pkcs11-uri.patch | 49 ++- openssh-8.7p1-host-based-auth.patch | 151 ------- openssh-8.7p1-ibmca.patch | 7 +- openssh-8.7p1-minimize-sha1-use.patch | 207 --------- openssh-8.7p1-minrsabits.patch | 19 +- openssh-8.7p1-negotiate-supported-algs.patch | 22 +- openssh-8.7p1-recursive-scp.patch | 51 ++- openssh-8.7p1-scp-clears-file.patch | 37 +- openssh-8.7p1-sftp-default-protocol.patch | 87 ---- openssh-8.7p1-sftpscp-dir-create.patch | 135 ------ openssh-8.8p1-skip-some-tests.patch | 41 -- ...gsissh.patch => openssh-9.0p1-gsissh.patch | 324 +++++++------- ...h => openssh-9.0p1-hpn-15.2-modified.patch | 404 +++++++++--------- 24 files changed, 625 insertions(+), 1237 deletions(-) delete mode 100644 openssh-8.7p1-host-based-auth.patch delete mode 100644 openssh-8.7p1-minimize-sha1-use.patch delete mode 100644 openssh-8.7p1-sftp-default-protocol.patch delete mode 100644 openssh-8.7p1-sftpscp-dir-create.patch delete mode 100644 openssh-8.8p1-skip-some-tests.patch rename openssh-8.8p1-gsissh.patch => openssh-9.0p1-gsissh.patch (89%) rename openssh-8.8p1-hpn-15.2-modified.patch => openssh-9.0p1-hpn-15.2-modified.patch (88%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a7901cd..4c83205 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -27,8 +27,8 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 8.8p1 -%global openssh_rel 3 +%global openssh_ver 9.0p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -149,16 +149,8 @@ Patch966: openssh-8.2p1-x11-without-ipv6.patch Patch974: openssh-8.0p1-keygen-strip-doseol.patch # sshd provides PAM an incorrect error code (#1879503) Patch975: openssh-8.0p1-preserve-pam-errors.patch -# Use SFTP protocol by default for scp command -Patch976: openssh-8.7p1-sftp-default-protocol.patch # Implement kill switch for SCP protocol Patch977: openssh-8.7p1-scp-kill-switch.patch -# Create non-existent directories when scp works in sftp mode and some more minor fixes -# upstream commits: -# ba61123eef9c6356d438c90c1199a57a0d7bcb0a -# 63670d4e9030bcee490d5a9cce561373ac5b3b23 -# ac7c9ec894ed0825d04ef69c55babb49bab1d32e -Patch980: openssh-8.7p1-sftpscp-dir-create.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 @@ -172,11 +164,6 @@ Patch983: openssh-8.7p1-evpgenkey.patch # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 Patch984: openssh-8.7p1-ibmca.patch -# Minimize the use of SHA1 as a proof of possession for RSA key (#2031868) -# upstream commits: -# 291721bc7c840d113a49518f3fca70e86248b8e8 -# 0fa33683223c76289470a954404047bc762be84c -Patch1000: openssh-8.7p1-minimize-sha1-use.patch # Fix for scp clearing file when src and dest are the same (#2056884) # upstream commits: # 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee @@ -195,31 +182,21 @@ Patch1003: openssh-8.7p1-mem-leak.patch # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 Patch1004: openssh-8.7p1-gssapi-auth.patch -# Fix host-based authentication with rsa keys -# upstream commits: -# 7aa7b096cf2bafe2777085abdeed5ce00581f641 -# d9dbb5d9a0326e252d3c7bc13beb9c2434f59409 -# fdb1d58d0d3888b042e5a500f6ce524486aaf782 -Patch1005: openssh-8.7p1-host-based-auth.patch # Don't propose disallowed algorithms during hostkey negotiation # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch -# downstream only -# we skip some ssh-rsa/ssh-dss tests to make native test suite pass -Patch1100: openssh-8.8p1-skip-some-tests.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 -Patch98: openssh-8.8p1-gsissh.patch +Patch98: openssh-9.0p1-gsissh.patch # This is the HPN patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-8.8p1-hpn-15.2-modified.patch +Patch99: openssh-9.0p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -266,7 +243,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 >= 20200610-1 +Requires: crypto-policies >= 20220824-1 %package server Summary: SSH server daemon with GSI authentication @@ -275,7 +252,7 @@ Obsoletes: gsissh-server < 5.8p2-2 Requires: %{name} = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 -Requires: crypto-policies >= 20200610-1 +Requires: crypto-policies >= 20220824-1 %{?systemd_requires} %description @@ -357,9 +334,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch966 -p1 -b .x11-ipv6 %patch974 -p1 -b .keygen-strip-doseol %patch975 -p1 -b .preserve-pam-errors -%patch976 -p1 -b .sftp-by-default %patch977 -p1 -b .kill-scp -%patch980 -p1 -b .sftpdirs %patch981 -p1 -b .scp-sftpdirs %patch982 -p1 -b .minrsabits %patch983 -p1 -b .evpgenrsa @@ -369,16 +344,12 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch201 -p1 -b .audit-race %patch700 -p1 -b .fips -%patch1000 -p1 -b .minimize-sha1-use %patch1001 -p1 -b .scp-clears-file %patch1002 -p1 -b .ssh-manpage %patch1003 -p1 -b .mem-leak %patch1004 -p1 -b .gssapi-auth -%patch1005 -p1 -b .host-based-auth %patch1006 -p1 -b .negotiate-supported-algs -%patch1100 -p1 -b .skipsshrsadsstests - %patch100 -p1 -b .coverity %patch97 -p1 -b .sshbuf-ro @@ -571,6 +542,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target %changelog +* Tue Aug 30 2022 Mattias Ellert - 9.0p1-1 +- Based on openssh-9.0p1-3.fc38 + * Tue Aug 30 2022 Mattias Ellert - 8.8p1-3 - Based on openssh-8.8p1-6.fc37 diff --git a/openssh-5.8p2-sigpipe.patch b/openssh-5.8p2-sigpipe.patch index 56af045..554e346 100644 --- a/openssh-5.8p2-sigpipe.patch +++ b/openssh-5.8p2-sigpipe.patch @@ -1,12 +1,14 @@ diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c --- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 +++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 -@@ -715,6 +715,8 @@ main(int argc, char **argv) +@@ -715,6 +715,9 @@ main(int argc, char **argv) + if (maxfd > fdlim_get(0)) fdlim_set(maxfd); fdcon = xcalloc(maxfd, sizeof(con)); - ++ + signal(SIGPIPE, SIG_IGN); + - read_wait_nfdset = howmany(maxfd, NFDBITS); - read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); + read_wait = xcalloc(maxfd, sizeof(struct pollfd)); + for (j = 0; j < maxfd; j++) + read_wait[j].fd = -1; diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 426c172..941c694 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -207,8 +207,8 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c -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; + int i, r, in, out, ch, skipargs = 0, log_stderr = 0; + ssize_t len, olen; @@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 147d90d..1923ac8 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,37 +1,3 @@ -diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c ---- openssh-8.5p1/addr.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/addr.c 2021-03-24 12:03:33.782968159 +0100 -@@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n - if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) - return -1; - -- if (ai == NULL || ai->ai_addr == NULL) -+ if (ai == NULL || ai->ai_addr == NULL) { -+ freeaddrinfo(ai); - return -1; -+ } - - if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, - n) == -1) { -@@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char * - if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0) - return -1; - -- if (ai == NULL || ai->ai_addr == NULL) -+ if (ai == NULL || ai->ai_addr == NULL) { -+ freeaddrinfo(ai); - return -1; -+ } - - if (sa != NULL) { -- if (slen < ai->ai_addrlen) -+ if (slen < ai->ai_addrlen) { -+ freeaddrinfo(ai); - return -1; -+ } - memcpy(sa, &ai->ai_addr, ai->ai_addrlen); - } - diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c --- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100 +++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100 @@ -65,15 +31,6 @@ diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c 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 -@@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh, - debug("channel %d: connection failed: %s", - c->self, strerror(err)); - /* Try next address, if any */ -- if ((sock = connect_next(&c->connect_ctx)) > 0) { -+ if ((sock = connect_next(&c->connect_ctx)) >= 0) { - close(c->sock); - c->sock = c->rfd = c->wfd = sock; - channel_find_maxfd(ssh->chanctxt); @@ -3804,7 +3804,7 @@ int channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) { @@ -411,30 +368,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c continue; } lname = ls_file(fname, g.gl_statv[i], 1, -diff --git a/sftp-client.c b/sftp-client.c -index 9de9afa20f..ea98d9f8d0 100644 ---- a/sftp-client.c -+++ b/sftp-client.c -@@ -2195,6 +2195,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous, - (*nreqsp)--; - } - debug3_f("done: %u outstanding replies", *nreqsp); -+ sshbuf_free(msg); - } - - int -diff --git a/sftp-server.c b/sftp-server.c -index 18d1949112..6380c4dd23 100644 ---- a/sftp-server.c -+++ b/sftp-server.c -@@ -1553,6 +1553,7 @@ process_extended_expand(u_int32_t id) - npath = xstrdup(path + 2); - free(path); - xasprintf(&path, "%s/%s", cwd, npath); -+ free(npath); - } else { - /* ~user expansions */ - if (tilde_expand(path, pw->pw_uid, &npath) != 0) { diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c --- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 @@ -494,16 +427,6 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c return 0; } -@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so - explicit_bzero(rnd, sizeof(rnd)); - } - } -+ -+ if (fdset != NULL) -+ free(fdset); - } - - /* @@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) if (newstr) diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 5af3e3b..ad181cb 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -10,8 +10,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c +/* 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, + /* Per-channel callback for pre/post IO actions */ + typedef void chan_fn(struct ssh *, Channel *c); @@ -4228,7 +4228,7 @@ channel_send_window_changes(void) */ int diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 4473518..2d3aae9 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -729,7 +729,7 @@ diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c --- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200 +++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200 @@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 - } else { + authctxt->valid = 0; /* Invalid user, fake password information */ authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS @@ -1195,9 +1195,9 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key), + debug3_f("%s %s signature using %s %s%s%s", auth_method, + sshkey_type(key), sigalg == NULL ? "default" : sigalg, (ret == 0) ? "verified" : "unverified", - (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); @@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } @@ -2040,7 +2040,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c static char *listener_proctitle; @@ -279,6 +280,15 @@ close_listen_socks(void) - num_listen_socks = -1; + num_listen_socks = 0; } +/* @@ -2049,16 +2049,16 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c + */ +int listening_for_clients(void) +{ -+ return num_listen_socks >= 0; ++ return num_listen_socks > 0; +} + static void close_startup_pipes(void) { @@ -377,18 +387,45 @@ grace_alarm_handler(int sig) - } + ssh_remote_port(the_active_state)); } - + -/* Destroy the host and server keys. They will no longer be needed. */ +/* + * Destroy the host and server keys. They will no longer be needed. Careful, @@ -2196,8 +2196,8 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c -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) { - fd_set *fdset; - int i, j, ret, maxfd; + 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.", diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index cc513db..62468ac 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -321,7 +321,7 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c --- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200 +++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200 @@ -66,6 +66,7 @@ - #include + #endif #include #include +#include diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index 8560c9f..a94419e 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -3,7 +3,7 @@ diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c +++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200 @@ -1749,6 +1749,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, - cfg, &includes, NULL); + cfg, &includes, NULL, rexeced_flag); + /* 'UsePAM no' is not supported in Fedora */ + if (! options.use_pam) diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 48f9f10..4dc460a 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -93,7 +93,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || - (r = sshbuf_put_cstring(b, "hostbased")) != 0 || + (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c --- openssh/auth2-pubkey.c.role-mls 2018-08-22 11:14:56.816430924 +0200 @@ -240,14 +240,14 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -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 r, fail = 0; + int hostbound = 0, r, fail = 0; @@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 62616aa..d4549f0 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -92,7 +92,52 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1219,29 +1216,25 @@ +@@ -913,36 +910,25 @@ + 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 +@@ -1219,30 +1216,25 @@ and .Cm pam . .It Cm KexAlgorithms @@ -120,6 +165,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 -default set. -The default is: -.Bd -literal -offset indent +-sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -224,6 +270,17 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . +@@ -2237,7 +2207,9 @@ for those users who do not have a config + 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 --color -ru a/sshd_config.5 b/sshd_config.5 --- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200 +++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200 @@ -294,7 +351,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -685,21 +679,22 @@ +@@ -685,53 +679,43 @@ .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -326,18 +383,27 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 -gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms - Specifies the signature algorithms that will be accepted for hostbased -@@ -799,26 +794,13 @@ - .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. + 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, @@ -348,12 +414,42 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, --ssh-rsa-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,ssh-rsa +-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 . +@@ -799,25 +794,14 @@ + .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 @@ -389,12 +485,13 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1010,15 +997,6 @@ +@@ -1010,16 +997,6 @@ sntrup761x25519-sha512@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent +-sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -452,7 +549,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1548,37 +1522,25 @@ +@@ -1548,36 +1522,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -488,14 +585,24 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, --ssh-rsa-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,ssh-rsa +-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 . +@@ -2011,7 +1968,9 @@ This file should be writable by root onl + .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 diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index e26bebd..d5dfd7e 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -16,7 +16,7 @@ index e7549470..b68c1710 100644 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 \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.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 \ diff -up a/auth.c.gsskex b/auth.c @@ -135,7 +135,7 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */ + /* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -224,7 +224,7 @@ index 9351e042..d6446c0c 100644 + Authmethod method_gssapi = { "gssapi-with-mic", - userauth_gssapi, + NULL, diff --git a/auth2.c b/auth2.c index 0e776224..1c217268 100644 --- a/auth2.c @@ -375,8 +375,8 @@ index ebd0dbca..1bdac6a4 100644 +#include "ssh-gss.h" +#endif + - /* import options */ - extern Options options; + /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ + #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" @@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, break; @@ -384,7 +384,7 @@ index ebd0dbca..1bdac6a4 100644 /* Do channel operations unless rekeying in progress. */ - if (!ssh_packet_is_rekeying(ssh)) + if (!ssh_packet_is_rekeying(ssh)) { - channel_after_select(ssh, readset, writeset); + channel_after_poll(ssh, pfd, npfd_active); +#ifdef GSSAPI + if (options.gss_renewal_rekey && @@ -396,8 +396,8 @@ index ebd0dbca..1bdac6a4 100644 + } + /* Buffer input from the connection. */ - client_process_net_input(ssh, readset); - + if (conn_in_ready) + client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac index b689db4b..efafb6bd 100644 --- a/configure.ac @@ -1370,9 +1370,9 @@ index ce85f043..574c7609 100644 +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); free(kex->failed_choice); - free(kex->hostkey_alg); - free(kex->name); diff --git a/kex.h b/kex.h index a5ae6ac0..fe714141 100644 --- a/kex.h @@ -3011,7 +3011,7 @@ diff -up a/readconf.c.gsskex b/readconf.c options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; @@ -2463,8 +2516,18 @@ fill_default_options(Options * options) - options->pubkey_authentication = 1; + options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) @@ -3886,7 +3886,7 @@ index 57995ee6..fd5b7724 100644 --- a/sshkey.c +++ b/sshkey.c @@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { - KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 }, + # endif /* ENABLE_SK */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ + { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 8592607..b3295a9 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -92,9 +92,9 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in rm -f regress/unittests/utf8/test_utf8 + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11 - (cd openbsd-compat && $(MAKE) distclean) - if test -d pkg ; then \ - rm -fr pkg ; \ + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so @@ -513,6 +517,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig @@ -876,22 +876,23 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c --- openssh-8.7p1/ssh-add.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 +++ openssh-8.7p1/ssh-add.c 2021-08-30 13:07:43.664700104 +0200 @@ -68,6 +68,7 @@ - #include "digest.h" #include "ssh-sk.h" #include "sk-api.h" + #include "hostfile.h" +#include "ssh-pkcs11-uri.h" /* argv0 */ extern char *__progname; -@@ -229,6 +230,32 @@ delete_all(int agent_fd, int qflag) +@@ -229,6 +230,34 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int, char *); ++static int update_card(int, int, const char *, int, struct dest_constraint **, size_t, char *); + +int -+update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) ++update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag, ++ struct dest_constraint **dest_constraints, size_t ndest_constraints) +{ + char *pin = NULL; + struct pkcs11_uri *uri; @@ -909,19 +910,20 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c + } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, ++ dest_constraints, ndest_constraints, pin); +} +#endif + static int add_file(int agent_fd, const char *filename, int key_only, int qflag, - const char *skprovider) + const char *skprovider, struct dest_constraint **dest_constraints, @@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen - } static int --update_card(int agent_fd, int add, const char *id, int qflag) -+update_card(int agent_fd, int add, const char *id, int qflag, char *pin) + update_card(int agent_fd, int add, const char *id, int qflag, +- struct dest_constraint **dest_constraints, size_t ndest_constraints) ++ struct dest_constraint **dest_constraints, size_t ndest_constraints, char *pin) { - char *pin = NULL; int r, ret = -1; @@ -931,15 +933,16 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -630,6 +656,13 @@ static int - do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, - const char *skprovider) +@@ -630,6 +656,14 @@ static int + const char *skprovider, struct dest_constraint **dest_constraints, + size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && + strncmp(file, PKCS11_URI_SCHEME, + strlen(PKCS11_URI_SCHEME)) == 0) { -+ return update_pkcs11_uri(agent_fd, !deleting, file, qflag); ++ return update_pkcs11_uri(agent_fd, !deleting, file, qflag, ++ dest_constraints, ndest_constraints); + } +#endif if (deleting) { @@ -949,8 +952,8 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag) == -1) -+ qflag, NULL) == -1) +- qflag, dest_constraints, ndest_constraints) == -1) ++ qflag, dest_constraints, ndest_constraints, NULL) == -1) ret = 1; goto done; } @@ -1080,7 +1083,7 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c + free(sane_uri); free(keys); free(comments); - send_status(e, success); + free_dest_constraints(dest_constraints, ndest_constraints); @@ -918,7 +976,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) @@ -1544,7 +1547,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c static RSA_METHOD *rsa_method; @@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; - #endif + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +/* + * This can't be in the ssh-pkcs11-uri, becase we can not depend on @@ -1739,9 +1742,9 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c struct pkcs11_key *k11; @@ -614,6 +764,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } + if (label_attrib->ulValueLen > 0 ) { + k11->label = xmalloc(label_attrib->ulValueLen+1); + memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); diff --git a/openssh-8.7p1-host-based-auth.patch b/openssh-8.7p1-host-based-auth.patch deleted file mode 100644 index 23efe91..0000000 --- a/openssh-8.7p1-host-based-auth.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff --color -rup a/sshconnect2.c b/sshconnect2.c ---- a/sshconnect2.c 2022-07-11 17:00:02.618575727 +0200 -+++ b/sshconnect2.c 2022-07-11 17:03:05.096085690 +0200 -@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh) - if (authctxt->sensitive->keys[i] == NULL || - authctxt->sensitive->keys[i]->type == KEY_UNSPEC) - continue; -- if (match_pattern_list( -+ if (!sshkey_match_keyname_to_sigalgs( - sshkey_ssh_name(authctxt->sensitive->keys[i]), -- authctxt->active_ktype, 0) != 1) -+ authctxt->active_ktype)) - continue; - /* we take and free the key */ - private = authctxt->sensitive->keys[i]; -@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh) - error_f("sshkey_fingerprint failed"); - goto out; - } -- debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp); -+ debug_f("trying hostkey %s %s using sigalg %s", -+ sshkey_ssh_name(private), fp, authctxt->active_ktype); - - /* figure out a name for the client host */ - lname = get_local_name(ssh_packet_get_connection_in(ssh)); -diff --color -rup a/sshkey.c b/sshkey.c ---- a/sshkey.c 2022-07-11 17:00:02.609575554 +0200 -+++ b/sshkey.c 2022-07-11 17:12:30.905976443 +0200 -@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n - return -1; - } - -+int -+sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) -+{ -+ int ktype; -+ -+ if (sigalgs == NULL || *sigalgs == '\0' || -+ (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC) -+ return 0; -+ else if (ktype == KEY_RSA) { -+ return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 || -+ match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 || -+ match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1; -+ } else if (ktype == KEY_RSA_CERT) { -+ return match_pattern_list("ssh-rsa-cert-v01@openssh.com", -+ sigalgs, 0) == 1 || -+ match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", -+ sigalgs, 0) == 1 || -+ match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", -+ sigalgs, 0) == 1; -+ } else -+ return match_pattern_list(keyname, sigalgs, 0) == 1; -+} -+ - char * - sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) - { -diff --color -rup a/sshkey.h b/sshkey.h ---- a/sshkey.h 2022-07-11 17:00:02.603575438 +0200 -+++ b/sshkey.h 2022-07-11 17:13:01.052556879 +0200 -@@ -194,6 +194,10 @@ int sshkey_is_cert(const struct sshkey - int sshkey_is_sk(const struct sshkey *); - int sshkey_type_is_cert(int); - int sshkey_type_plain(int); -+ -+/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */ -+int sshkey_match_keyname_to_sigalgs(const char *, const char *); -+ - int sshkey_to_certified(struct sshkey *); - int sshkey_drop_cert(struct sshkey *); - int sshkey_cert_copy(const struct sshkey *, struct sshkey *); -diff --color -rup a/ssh-keysign.c b/ssh-keysign.c ---- a/ssh-keysign.c 2021-08-20 06:03:49.000000000 +0200 -+++ b/ssh-keysign.c 2022-07-11 17:00:23.306973667 +0200 -@@ -62,7 +62,7 @@ - extern char *__progname; - - static int --valid_request(struct passwd *pw, char *host, struct sshkey **ret, -+valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp, - u_char *data, size_t datalen) - { - struct sshbuf *b; -@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h - - if (ret != NULL) - *ret = NULL; -+ if (pkalgp != NULL) -+ *pkalgp = NULL; - fail = 0; - - if ((b = sshbuf_from(data, datalen)) == NULL) -@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h - fail++; - } else if (key->type != pktype) - fail++; -- free(pkalg); -- free(pkblob); - - /* client host name, handle trailing dot */ - if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) -@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h - - if (fail) - sshkey_free(key); -- else if (ret != NULL) -- *ret = key; -+ else { -+ if (ret != NULL) { -+ *ret = key; -+ key = NULL; -+ } -+ if (pkalgp != NULL) { -+ *pkalgp = pkalg; -+ pkalg = NULL; -+ } -+ } -+ sshkey_free(key); -+ free(pkalg); -+ free(pkblob); - - return (fail ? -1 : 0); - } -@@ -170,7 +181,7 @@ main(int argc, char **argv) - struct passwd *pw; - int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; - u_char *signature, *data, rver; -- char *host, *fp; -+ char *host, *fp, *pkalg; - size_t slen, dlen; - - if (pledge("stdio rpath getpw dns id", NULL) != 0) -@@ -258,7 +269,7 @@ main(int argc, char **argv) - - if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) - fatal_r(r, "%s: buffer error", __progname); -- if (valid_request(pw, host, &key, data, dlen) < 0) -+ if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0) - fatal("%s: not a valid request", __progname); - free(host); - -@@ -279,7 +290,7 @@ main(int argc, char **argv) - } - - if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, -- NULL, NULL, NULL, 0)) != 0) -+ pkalg, NULL, NULL, 0)) != 0) - fatal_r(r, "%s: sshkey_sign failed", __progname); - free(data); - diff --git a/openssh-8.7p1-ibmca.patch b/openssh-8.7p1-ibmca.patch index c9c12ee..88914bf 100644 --- a/openssh-8.7p1-ibmca.patch +++ b/openssh-8.7p1-ibmca.patch @@ -4,9 +4,8 @@ #include "includes.h" --#ifndef HAVE_CLOSEFROM -+#if (!defined HAVE_CLOSEFROM) || (defined __s390__) +-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) ++#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__) #include - #include - + #include diff --git a/openssh-8.7p1-minimize-sha1-use.patch b/openssh-8.7p1-minimize-sha1-use.patch deleted file mode 100644 index fc517da..0000000 --- a/openssh-8.7p1-minimize-sha1-use.patch +++ /dev/null @@ -1,207 +0,0 @@ -diff --color -ru a/clientloop.c b/clientloop.c ---- a/clientloop.c 2022-06-29 16:35:06.677597259 +0200 -+++ b/clientloop.c 2022-06-29 16:40:29.737926205 +0200 -@@ -116,6 +116,9 @@ - #include "ssh-gss.h" - #endif - -+/* Permitted RSA signature algorithms for UpdateHostkeys proofs */ -+#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -+ - /* import options */ - extern Options options; - -@@ -2110,8 +2113,10 @@ - struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; - size_t i, ndone; - struct sshbuf *signdata; -- int r, kexsigtype, use_kexsigtype; -+ int r, plaintype; - const u_char *sig; -+ const char *rsa_kexalg = NULL; -+ char *alg = NULL; - size_t siglen; - - if (ctx->nnew == 0) -@@ -2122,9 +2127,9 @@ - hostkeys_update_ctx_free(ctx); - return; - } -- kexsigtype = sshkey_type_plain( -- sshkey_type_from_name(ssh->kex->hostkey_alg)); -- -+ if (sshkey_type_plain(sshkey_type_from_name( -+ ssh->kex->hostkey_alg)) == KEY_RSA) -+ rsa_kexalg = ssh->kex->hostkey_alg; - if ((signdata = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - /* -@@ -2135,6 +2140,7 @@ - for (ndone = i = 0; i < ctx->nkeys; i++) { - if (ctx->keys_match[i]) - continue; -+ plaintype = sshkey_type_plain(ctx->keys[i]->type); - /* Prepare data to be signed: session ID, unique string, key */ - sshbuf_reset(signdata); - if ( (r = sshbuf_put_cstring(signdata, -@@ -2148,19 +2154,33 @@ - error_fr(r, "parse sig"); - goto out; - } -+ if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) { -+ error_fr(r, "server gave unintelligible signature " -+ "for %s key %zu", sshkey_type(ctx->keys[i]), i); -+ goto out; -+ } - /* -- * For RSA keys, prefer to use the signature type negotiated -- * during KEX to the default (SHA1). -+ * Special case for RSA keys: if a RSA hostkey was negotiated, -+ * then use its signature type for verification of RSA hostkey -+ * proofs. Otherwise, accept only RSA-SHA256/512 signatures. - */ -- use_kexsigtype = kexsigtype == KEY_RSA && -- sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA; -- debug3_f("verify %s key %zu using %s sigalg", -- sshkey_type(ctx->keys[i]), i, -- use_kexsigtype ? ssh->kex->hostkey_alg : "default"); -+ if (plaintype == KEY_RSA && rsa_kexalg == NULL && -+ match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) { -+ debug_f("server used untrusted RSA signature algorithm " -+ "%s for key %zu, disregarding", alg, i); -+ free(alg); -+ /* zap the key from the list */ -+ sshkey_free(ctx->keys[i]); -+ ctx->keys[i] = NULL; -+ ndone++; -+ continue; -+ } -+ debug3_f("verify %s key %zu using sigalg %s", -+ sshkey_type(ctx->keys[i]), i, alg); -+ free(alg); - if ((r = sshkey_verify(ctx->keys[i], sig, siglen, - sshbuf_ptr(signdata), sshbuf_len(signdata), -- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0, -- NULL)) != 0) { -+ plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) { - error_fr(r, "server gave bad signature for %s key %zu", - sshkey_type(ctx->keys[i]), i); - goto out; -diff --git a/hostfile.c b/hostfile.c -index a035b381..bd49e3ac 100644 ---- a/hostfile.c -+++ b/hostfile.c -@@ -642,7 +642,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, - /* Re-add the requested keys */ - want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP); - for (i = 0; i < nkeys; i++) { -- if ((want & ctx.match_keys[i]) == want) -+ if (keys[i] == NULL || (want & ctx.match_keys[i]) == want) - continue; - if ((fp = sshkey_fingerprint(keys[i], hash_alg, - SSH_FP_DEFAULT)) == NULL) { -diff --color -ru a/kex.c b/kex.c ---- a/kex.c 2022-06-29 16:35:06.775599179 +0200 -+++ b/kex.c 2022-06-29 16:42:00.839710940 +0200 -@@ -959,6 +959,18 @@ - return (1); - } - -+/* returns non-zero if proposal contains any algorithm from algs */ -+static int -+has_any_alg(const char *proposal, const char *algs) -+{ -+ char *cp; -+ -+ if ((cp = match_list(proposal, algs, NULL)) == NULL) -+ return 0; -+ free(cp); -+ return 1; -+} -+ - static int - kex_choose_conf(struct ssh *ssh) - { -@@ -994,6 +1006,16 @@ - free(ext); - } - -+ /* Check whether client supports rsa-sha2 algorithms */ -+ if (kex->server && (kex->flags & KEX_INITIAL)) { -+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com")) -+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED; -+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com")) -+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED; -+ } -+ - /* Algorithm Negotiation */ - if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], - sprop[PROPOSAL_KEX_ALGS])) != 0) { -diff --color -ru a/kex.h b/kex.h ---- a/kex.h 2022-06-29 16:35:06.766599003 +0200 -+++ b/kex.h 2022-06-29 16:42:24.199168567 +0200 -@@ -116,6 +116,8 @@ - - #define KEX_INIT_SENT 0x0001 - #define KEX_INITIAL 0x0002 -+#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ -+#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ - - struct sshenc { - char *name; -diff --color -ru a/serverloop.c b/serverloop.c ---- a/serverloop.c 2021-08-20 06:03:49.000000000 +0200 -+++ b/serverloop.c 2022-06-29 16:45:05.902336428 +0200 -@@ -684,16 +684,18 @@ - struct sshbuf *resp = NULL; - struct sshbuf *sigbuf = NULL; - struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; -- int r, ndx, kexsigtype, use_kexsigtype, success = 0; -+ int r, ndx, success = 0; - const u_char *blob; -+ const char *sigalg, *kex_rsa_sigalg = NULL; - u_char *sig = 0; - size_t blen, slen; - - if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) - fatal_f("sshbuf_new"); - -- kexsigtype = sshkey_type_plain( -- sshkey_type_from_name(ssh->kex->hostkey_alg)); -+ if (sshkey_type_plain(sshkey_type_from_name( -+ ssh->kex->hostkey_alg)) == KEY_RSA) -+ kex_rsa_sigalg = ssh->kex->hostkey_alg; - while (ssh_packet_remaining(ssh) > 0) { - sshkey_free(key); - key = NULL; -@@ -726,16 +728,24 @@ - * For RSA keys, prefer to use the signature type negotiated - * during KEX to the default (SHA1). - */ -- use_kexsigtype = kexsigtype == KEY_RSA && -- sshkey_type_plain(key->type) == KEY_RSA; -+ sigalg = NULL; -+ if (sshkey_type_plain(key->type) == KEY_RSA) { -+ if (kex_rsa_sigalg != NULL) -+ sigalg = kex_rsa_sigalg; -+ else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED) -+ sigalg = "rsa-sha2-512"; -+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) -+ sigalg = "rsa-sha2-256"; -+ } -+ debug3_f("sign %s key (index %d) using sigalg %s", -+ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); - if ((r = sshbuf_put_cstring(sigbuf, - "hostkeys-prove-00@openssh.com")) != 0 || - (r = sshbuf_put_stringb(sigbuf, - ssh->kex->session_id)) != 0 || - (r = sshkey_puts(key, sigbuf)) != 0 || - (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen, -- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), -- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 || -+ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 || - (r = sshbuf_put_string(resp, sig, slen)) != 0) { - error_fr(r, "assemble signature"); - goto out; diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index 107fe70..259129f 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -204,22 +204,25 @@ index a926cc007..cd13fb879 100644 break; case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: -@@ -1557,12 +1565,13 @@ main(int ac, char **av) +@@ -1565,7 +1573,7 @@ main(int ac, char **av) if ((o) >= sensitive_data.nkeys) \ fatal_f("pubkey out of array bounds"); \ check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ - p, "pubkey"); \ + &(sensitive_data.keys[o]), p, "pubkey"); \ - } while (0) + if (sensitive_data.keys[o] != NULL) \ + debug2("hostbased key %d: %s key from \"%s\"", o, \ + sshkey_ssh_name(sensitive_data.keys[o]), p); \ +@@ -1573,7 +1581,8 @@ main(int ac, char **av) #define L_CERT(p,o) do { \ if ((o) >= sensitive_data.nkeys) \ fatal_f("cert out of array bounds"); \ - check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \ + check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \ + &(sensitive_data.keys[o]), p, "cert"); \ - } while (0) - - if (options.hostbased_authentication == 1) { + if (sensitive_data.keys[o] != NULL) \ + debug2("hostbased key %d: %s cert from \"%s\"", o, \ + sshkey_ssh_name(sensitive_data.keys[o]), p); \ @@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); @@ -276,9 +279,9 @@ index 67f8e0309..d050c1656 100644 !(id->key && id->isprivate)) maybe_add_key_to_agent(id->filename, private, comment, @@ -1747,6 +1751,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) - close(agent_fd); - } else { - for (j = 0; j < idlist->nkeys; j++) { + /* list of keys supported by the agent */ + if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) { + for (j = 0; j < idlist->nkeys; j++) { + if ((r = sshkey_check_rsa_length(idlist->keys[j], + options.rsa_min_size)) != 0) { + debug_fr(r, "ignoring %s agent key", diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch index 2fb9297..260ddb8 100644 --- a/openssh-8.7p1-negotiate-supported-algs.patch +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -2,8 +2,8 @@ diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh --- a/regress/hostkey-agent.sh 2021-08-20 06:03:49.000000000 +0200 +++ b/regress/hostkey-agent.sh 2022-07-14 11:58:12.172786060 +0200 @@ -13,8 +13,12 @@ r=$? - grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig - echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig + + ${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 "," "|"` @@ -12,18 +12,18 @@ diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh 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" - ( - printf 'localhost-with-alias,127.0.0.1,::1 ' + ${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 || \ @@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host + unset SSH_AUTH_SOCK - for ps in yes; do -- for k in $SSH_KEYTYPES ; do -+ for k in $SSH_ACCEPTED_KEYTYPES ; do - verbose "key type $k privsep=$ps" - cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy - echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy +-for k in $SSH_KEYTYPES ; do ++for k in $SSH_ACCEPTED_KEYTYPES ; do + verbose "key type $k" + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy diff --color -rup a/sshconnect2.c b/sshconnect2.c --- a/sshconnect2.c 2022-07-14 10:10:07.262975710 +0200 +++ b/sshconnect2.c 2022-07-14 10:10:32.068452067 +0200 diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch index 25765fb..5b44d92 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -7,9 +7,9 @@ diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c if (upload_dir(conn, src, abs_dst, pflag, - SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { + SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { - error("failed to upload directory %s to %s", - src, abs_dst); - errs = 1; + error("failed to upload directory %s to %s", src, targ); + errs = 1; + } diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c --- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 +++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 @@ -22,11 +22,13 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1012,9 +1012,38 @@ do_realpath_expand(struct sftp_conn *con - - if ((r = sshbuf_get_u32(msg, &status)) != 0) +@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con + if ((r = sshbuf_get_u32(msg, &status)) != 0 || + (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); -- error("Couldn't canonicalize: %s", fx2txt(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) { @@ -35,29 +37,34 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c + 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) ++ (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) { -+ u_int status; ++ free(errmsg); + -+ if ((r = sshbuf_get_u32(msg, &status)) != 0) ++ if ((r = sshbuf_get_u32(msg, &status)) != 0 || ++ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) + fatal_fr(r, "parse status"); -+ error("Couldn't canonicalize: %s", fx2txt(status)); ++ error("%s %s: %s", expand ? "expand" : "realpath", ++ path, *errmsg == '\0' ? fx2txt(status) : errmsg); ++ free(errmsg); + sshbuf_free(msg); + return NULL; + } + } else { -+ error("Couldn't canonicalize: %s", fx2txt(status)); ++ error("%s %s: %s", expand ? "expand" : "realpath", ++ path, *errmsg == '\0' ? fx2txt(status) : errmsg); ++ free(errmsg); + sshbuf_free(msg); + return NULL; + } @@ -94,9 +101,9 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c - if ((src_canon = do_realpath(conn, src)) == NULL) { + if ((src_canon = do_realpath(conn, src, 0)) == NULL) { - error("Unable to canonicalize path \"%s\"", src); - return -1; - } + error("download \"%s\": path canonicalization failed", src); + return -1; + } @@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co int upload_dir(struct sftp_conn *conn, const char *src, const char *dst, @@ -109,18 +116,18 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c - if ((dst_canon = do_realpath(conn, dst)) == NULL) { + if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { - error("Unable to canonicalize path \"%s\"", dst); - return -1; - } + error("upload \"%s\": path canonicalization failed", dst); + return -1; + } @@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st char *from_path_canon; int ret; - if ((from_path_canon = do_realpath(from, from_path)) == NULL) { + if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { - error("Unable to canonicalize path \"%s\"", from_path); - return -1; - } + error("crossload \"%s\": path canonicalization failed", + from_path); + return -1; diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h --- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 +++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 diff --git a/openssh-8.7p1-scp-clears-file.patch b/openssh-8.7p1-scp-clears-file.patch index 4c033da..3ecff1e 100644 --- a/openssh-8.7p1-scp-clears-file.patch +++ b/openssh-8.7p1-scp-clears-file.patch @@ -1,21 +1,20 @@ diff --color -rup a/scp.c b/scp.c --- a/scp.c 2022-07-26 14:51:40.560120817 +0200 +++ b/scp.c 2022-07-26 14:52:37.118213004 +0200 -@@ -1324,12 +1324,12 @@ source_sftp(int argc, char *src, char *t - - if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, +@@ -1324,11 +1324,11 @@ source_sftp(int argc, char *src, char *t + + if (src_is_dir && iamrecursive) { + if (upload_dir(conn, src, abs_dst, pflag, - SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { + SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) { - error("failed to upload directory %s to %s", - src, abs_dst); - errs = 1; - } + error("failed to upload directory %s to %s", src, targ); + errs = 1; + } - } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) { + } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) { - error("failed to upload file %s to %s", src, abs_dst); - errs = 1; - } + error("failed to upload file %s to %s", src, targ); + errs = 1; + } @@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { @@ -83,9 +82,9 @@ diff --color -rup a/sftp-client.c b/sftp-client.c - O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); + local_fd = open(local_path, O_WRONLY | O_CREAT | + ((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR); - if (local_fd == -1) { - error("Couldn't open local file \"%s\" for writing: %s", - local_path, strerror(errno)); + if (local_fd == -1) { + error("open local \"%s\": %s", local_path, strerror(errno)); + goto fail; @@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons /* Sanity check */ if (TAILQ_FIRST(&requests) != NULL) @@ -217,8 +216,8 @@ diff --color -rup a/sftp-client.c b/sftp-client.c + } + if (close(local_fd) == -1) { - error("Couldn't close local file \"%s\": %s", local_path, - strerror(errno)); + error("close local \"%s\": %s", local_path, strerror(errno)); + status = SSH2_FX_FAILURE; @@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const static int upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, @@ -241,9 +240,9 @@ diff --color -rup a/sftp-client.c b/sftp-client.c - preserve_flag, resume, fsync_flag) == -1) { + preserve_flag, resume, fsync_flag, + inplace_flag) == -1) { - error("Uploading of file %s to %s failed!", - new_src, new_dst); - ret = -1; + error("upload \"%s\" to \"%s\" failed", + new_src, new_dst); + ret = -1; @@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co int upload_dir(struct sftp_conn *conn, const char *src, const char *dst, diff --git a/openssh-8.7p1-sftp-default-protocol.patch b/openssh-8.7p1-sftp-default-protocol.patch deleted file mode 100644 index c3527b1..0000000 --- a/openssh-8.7p1-sftp-default-protocol.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff --git a/scp.1 b/scp.1 -index 68aac04b..a96e95ad 100644 ---- a/scp.1 -+++ b/scp.1 -@@ -18,7 +18,7 @@ - .Nd OpenSSH secure file copy - .Sh SYNOPSIS - .Nm scp --.Op Fl 346ABCOpqRrsTv -+.Op Fl 346ABCOpqRrTv - .Op Fl c Ar cipher - .Op Fl D Ar sftp_server_path - .Op Fl F Ar ssh_config -@@ -79,7 +76,9 @@ The options are as follows: - Copies between two remote hosts are transferred through the local host. - Without this option the data is copied directly between the two remote - hosts. --Note that, when using the original SCP protocol (the default), this option -+Note that, when using the original SCP protocol (via the -+.Fl O -+flag), this option - selects batch mode for the second host as - .Nm - cannot ask for passwords or passphrases for both hosts. -@@ -146,7 +145,6 @@ Limits the used bandwidth, specified in Kbit/s. - wildcard patterns and for expanding paths with a - .Sq ~ - prefix for older SFTP servers. --This mode is the default. - .It Fl o Ar ssh_option - Can be used to pass options to - .Nm ssh -@@ -258,8 +258,6 @@ to use for the encrypted connection. - The program must understand - .Xr ssh 1 - options. --.It Fl s --Use the SFTP protocol for transfers rather than the original scp protocol. - .It Fl T - Disable strict filename checking. - By default when copying files from a remote host to a local directory -@@ -299,11 +289,23 @@ debugging connection, authentication, and configuration problems. - .Xr ssh_config 5 , - .Xr sftp-server 8 , - .Xr sshd 8 -+.Sh CAVEATS -+The original scp protocol (selected by the -+.Fl O -+flag) requires execution of the remote user's shell to perform -+.Xr glob 3 -+pattern matching. -+This requires careful quoting of any characters that have special meaning to -+the remote shell, such as quote characters. - .Sh HISTORY - .Nm - is based on the rcp program in - .Bx - source code from the Regents of the University of California. -+.Pp -+Since OpenSSH 8.8 (8.7 in Red Hat/Fedora builds), -+.Nm -+has use the SFTP protocol for transfers by default. - .Sh AUTHORS - .An Timo Rinne Aq Mt tri@iki.fi - .An Tatu Ylonen Aq Mt ylo@cs.hut.fi -diff --git a/scp.c b/scp.c -index e039350c..c7cf7529 100644 ---- a/scp.c -+++ b/scp.c -@@ -448,7 +448,7 @@ main(int argc, char **argv) - const char *errstr; - extern char *optarg; - extern int optind; -- enum scp_mode_e mode = MODE_SCP; -+ enum scp_mode_e mode = MODE_SFTP; - char *sftp_direct = NULL; - - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ -@@ -1983,7 +1983,7 @@ void - usage(void) - { - (void) fprintf(stderr, -- "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" -+ "usage: scp [-346ABCOpqRrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" - " [-i identity_file] [-J destination] [-l limit]\n" - " [-o ssh_option] [-P port] [-S program] source ... target\n"); - exit(1); diff --git a/openssh-8.7p1-sftpscp-dir-create.patch b/openssh-8.7p1-sftpscp-dir-create.patch deleted file mode 100644 index bc504f9..0000000 --- a/openssh-8.7p1-sftpscp-dir-create.patch +++ /dev/null @@ -1,135 +0,0 @@ -diff -up openssh-8.7p1/scp.c.sftpdirs openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.sftpdirs 2022-02-02 14:11:12.553447509 +0100 -+++ openssh-8.7p1/scp.c 2022-02-02 14:12:56.081316414 +0100 -@@ -130,6 +130,7 @@ - #include "misc.h" - #include "progressmeter.h" - #include "utf8.h" -+#include "sftp.h" - - #include "sftp-common.h" - #include "sftp-client.h" -@@ -1264,13 +1265,18 @@ tolocal(int argc, char **argv, enum scp_ - static char * - prepare_remote_path(struct sftp_conn *conn, const char *path) - { -+ size_t nslash; -+ - /* Handle ~ prefixed paths */ -- if (*path != '~') -- return xstrdup(path); - if (*path == '\0' || strcmp(path, "~") == 0) - return xstrdup("."); -- if (strncmp(path, "~/", 2) == 0) -- return xstrdup(path + 2); -+ if (*path != '~') -+ return xstrdup(path); -+ if (strncmp(path, "~/", 2) == 0) { -+ if ((nslash = strspn(path + 2, "/")) == strlen(path + 2)) -+ return xstrdup("."); -+ return xstrdup(path + 2 + nslash); -+ } - if (can_expand_path(conn)) - return do_expand_path(conn, path); - /* No protocol extension */ -@@ -1282,10 +1288,16 @@ void - source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) - { - char *target = NULL, *filename = NULL, *abs_dst = NULL; -- int target_is_dir; -- -+ int src_is_dir, target_is_dir; -+ Attrib a; -+ struct stat st; -+ -+ memset(&a, '\0', sizeof(a)); -+ if (stat(src, &st) != 0) -+ fatal("stat local \"%s\": %s", src, strerror(errno)); -+ src_is_dir = S_ISDIR(st.st_mode); - if ((filename = basename(src)) == NULL) -- fatal("basename %s: %s", src, strerror(errno)); -+ fatal("basename \"%s\": %s", src, strerror(errno)); - - /* - * No need to glob here - the local shell already took care of -@@ -1295,8 +1307,12 @@ source_sftp(int argc, char *src, char *t - cleanup_exit(255); - target_is_dir = remote_is_dir(conn, target); - if (targetshouldbedirectory && !target_is_dir) { -- fatal("Target is not a directory, but more files selected " -- "for upload"); -+ debug("target directory \"%s\" does not exist", target); -+ a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS; -+ a.perm = st.st_mode | 0700; /* ensure writable */ -+ if (do_mkdir(conn, target, &a, 1) != 0) -+ cleanup_exit(255); /* error already logged */ -+ target_is_dir = 1; - } - if (target_is_dir) - abs_dst = path_append(target, filename); -@@ -1306,7 +1322,7 @@ source_sftp(int argc, char *src, char *t - } - debug3_f("copying local %s to remote %s", src, abs_dst); - -- if (local_is_dir(src) && iamrecursive) { -+ if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, - SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { - error("failed to upload directory %s to %s", -@@ -1487,14 +1506,15 @@ sink_sftp(int argc, char *dst, const cha - char *abs_dst = NULL; - glob_t g; - char *filename, *tmp = NULL; -- int i, r, err = 0; -+ int i, r, err = 0, dst_is_dir; -+ struct stat st; - - memset(&g, 0, sizeof(g)); -+ - /* - * Here, we need remote glob as SFTP can not depend on remote shell - * expansions - */ -- - if ((abs_src = prepare_remote_path(conn, src)) == NULL) { - err = -1; - goto out; -@@ -1510,11 +1530,24 @@ sink_sftp(int argc, char *dst, const cha - goto out; - } - -- if (g.gl_matchc > 1 && !local_is_dir(dst)) { -- error("Multiple files match pattern, but destination " -- "\"%s\" is not a directory", dst); -- err = -1; -- goto out; -+ if ((r = stat(dst, &st)) != 0) -+ debug2_f("stat local \"%s\": %s", dst, strerror(errno)); -+ dst_is_dir = r == 0 && S_ISDIR(st.st_mode); -+ -+ if (g.gl_matchc > 1 && !dst_is_dir) { -+ if (r == 0) { -+ error("Multiple files match pattern, but destination " -+ "\"%s\" is not a directory", dst); -+ err = -1; -+ goto out; -+ } -+ debug2_f("creating destination \"%s\"", dst); -+ if (mkdir(dst, 0777) != 0) { -+ error("local mkdir \"%s\": %s", dst, strerror(errno)); -+ err = -1; -+ goto out; -+ } -+ dst_is_dir = 1; - } - - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { -@@ -1525,7 +1558,7 @@ sink_sftp(int argc, char *dst, const cha - goto out; - } - -- if (local_is_dir(dst)) -+ if (dst_is_dir) - abs_dst = path_append(dst, filename); - else - abs_dst = xstrdup(dst); diff --git a/openssh-8.8p1-skip-some-tests.patch b/openssh-8.8p1-skip-some-tests.patch deleted file mode 100644 index 7268eb3..0000000 --- a/openssh-8.8p1-skip-some-tests.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff -up openssh-8.8p1/regress/hostkey-agent.sh.redhat openssh-8.8p1/regress/hostkey-agent.sh ---- openssh-8.8p1/regress/hostkey-agent.sh.redhat 2022-08-10 15:54:42.084777662 +0200 -+++ openssh-8.8p1/regress/hostkey-agent.sh 2022-08-10 17:01:25.651269994 +0200 -@@ -36,6 +36,8 @@ unset SSH_AUTH_SOCK - - for ps in yes; do - for k in $SSH_ACCEPTED_KEYTYPES ; do -+ [ "$k" == "ssh-rsa" ] && continue -+ [ "$k" == "ssh-dss" ] && continue - verbose "key type $k privsep=$ps" - cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy - echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy -diff -up openssh-8.8p1/regress/hostkey-rotate.sh.redhat openssh-8.8p1/regress/hostkey-rotate.sh ---- openssh-8.8p1/regress/hostkey-rotate.sh.redhat 2022-08-10 16:57:12.720029146 +0200 -+++ openssh-8.8p1/regress/hostkey-rotate.sh 2022-08-10 17:15:48.274923865 +0200 -@@ -40,6 +40,8 @@ trace "prepare hostkeys" - nkeys=0 - all_algs="" - for k in $SSH_HOSTKEY_TYPES; do -+ [ "$k" == "ssh-rsa" ] && continue -+ [ "$k" == "ssh-dss" ] && continue - ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" - echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig - nkeys=`expr $nkeys + 1` -@@ -87,11 +89,15 @@ dossh -oStrictHostKeyChecking=yes -oHost - # Check that other keys learned - expect_nkeys $nkeys "learn hostkeys" - for k in $SSH_HOSTKEY_TYPES; do -+ [ "$k" == "ssh-rsa" ] && continue -+ [ "$k" == "ssh-dss" ] && continue - check_key_present $k || fail "didn't learn keytype $k" - done - - # Check each key type - for k in $SSH_HOSTKEY_TYPES; do -+ [ "$k" == "ssh-rsa" ] && continue -+ [ "$k" == "ssh-dss" ] && continue - verbose "learn additional hostkeys, type=$k" - dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs - expect_nkeys $nkeys "learn hostkeys $k" - diff --git a/openssh-8.8p1-gsissh.patch b/openssh-9.0p1-gsissh.patch similarity index 89% rename from openssh-8.8p1-gsissh.patch rename to openssh-9.0p1-gsissh.patch index 04d640a..0e848a9 100644 --- a/openssh-8.8p1-gsissh.patch +++ b/openssh-9.0p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c ---- openssh-8.8p1.orig/auth2.c 2021-12-01 16:47:29.945987883 +0100 -+++ openssh-8.8p1/auth2.c 2021-12-01 16:48:10.374080945 +0100 -@@ -277,7 +277,28 @@ +diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c +--- openssh-9.0p1.orig/auth2.c 2022-08-30 19:32:35.491051041 +0200 ++++ openssh-9.0p1/auth2.c 2022-08-30 19:41:39.812458921 +0200 +@@ -278,7 +278,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) goto out; @@ -31,10 +31,10 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -288,17 +309,42 @@ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; +@@ -291,11 +312,33 @@ + if (authctxt->attempt >= 1024) + auth_maxtries_exceeded(ssh); - if (authctxt->attempt++ == 0) { - /* setup auth context */ - authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); @@ -69,6 +69,7 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); } else { +@@ -303,6 +346,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -78,7 +79,7 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(ssh)); -@@ -307,6 +353,7 @@ +@@ -311,6 +357,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -86,7 +87,7 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -322,9 +369,10 @@ +@@ -326,9 +373,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -100,9 +101,9 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-8.8p1.orig/auth2-gss.c openssh-8.8p1/auth2-gss.c ---- openssh-8.8p1.orig/auth2-gss.c 2021-12-01 16:47:29.832987623 +0100 -+++ openssh-8.8p1/auth2-gss.c 2021-12-01 16:48:10.375080947 +0100 +diff -Nur openssh-9.0p1.orig/auth2-gss.c openssh-9.0p1/auth2-gss.c +--- openssh-9.0p1.orig/auth2-gss.c 2022-08-30 19:32:35.318050592 +0200 ++++ openssh-9.0p1/auth2-gss.c 2022-08-30 19:33:23.884176392 +0200 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -307,10 +308,10 @@ diff -Nur openssh-8.8p1.orig/auth2-gss.c openssh-8.8p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", userauth_gsskeyex, -diff -Nur openssh-8.8p1.orig/auth.c openssh-8.8p1/auth.c ---- openssh-8.8p1.orig/auth.c 2021-12-01 16:47:29.946987886 +0100 -+++ openssh-8.8p1/auth.c 2021-12-01 16:48:10.375080947 +0100 -@@ -344,7 +344,8 @@ +diff -Nur openssh-9.0p1.orig/auth.c openssh-9.0p1/auth.c +--- openssh-9.0p1.orig/auth.c 2022-08-30 19:32:35.492051043 +0200 ++++ openssh-9.0p1/auth.c 2022-08-30 19:33:23.884176392 +0200 +@@ -300,7 +300,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -320,7 +321,7 @@ diff -Nur openssh-8.8p1.orig/auth.c openssh-8.8p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -588,13 +589,18 @@ +@@ -544,13 +545,18 @@ #endif pw = getpwnam(user); @@ -340,9 +341,9 @@ diff -Nur openssh-8.8p1.orig/auth.c openssh-8.8p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-8.8p1.orig/auth.h openssh-8.8p1/auth.h ---- openssh-8.8p1.orig/auth.h 2021-12-01 16:47:29.946987886 +0100 -+++ openssh-8.8p1/auth.h 2021-12-01 16:48:10.376080950 +0100 +diff -Nur openssh-9.0p1.orig/auth.h openssh-9.0p1/auth.h +--- openssh-9.0p1.orig/auth.h 2022-08-30 19:32:35.493051046 +0200 ++++ openssh-9.0p1/auth.h 2022-08-30 19:33:23.885176394 +0200 @@ -83,6 +83,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -352,9 +353,9 @@ diff -Nur openssh-8.8p1.orig/auth.h openssh-8.8p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-8.8p1.orig/auth-pam.c openssh-8.8p1/auth-pam.c ---- openssh-8.8p1.orig/auth-pam.c 2021-12-01 16:47:29.937987865 +0100 -+++ openssh-8.8p1/auth-pam.c 2021-12-01 16:48:10.376080950 +0100 +diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c +--- openssh-9.0p1.orig/auth-pam.c 2022-08-30 19:32:35.455050947 +0200 ++++ openssh-9.0p1/auth-pam.c 2022-08-30 19:33:23.886176397 +0200 @@ -253,6 +253,7 @@ static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -515,9 +516,9 @@ diff -Nur openssh-8.8p1.orig/auth-pam.c openssh-8.8p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-8.8p1.orig/auth-pam.h openssh-8.8p1/auth-pam.h ---- openssh-8.8p1.orig/auth-pam.h 2021-12-01 16:47:29.797987543 +0100 -+++ openssh-8.8p1/auth-pam.h 2021-12-01 16:48:10.377080952 +0100 +diff -Nur openssh-9.0p1.orig/auth-pam.h openssh-9.0p1/auth-pam.h +--- openssh-9.0p1.orig/auth-pam.h 2022-08-30 19:32:35.267050460 +0200 ++++ openssh-9.0p1/auth-pam.h 2022-08-30 19:33:23.886176397 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -525,9 +526,9 @@ diff -Nur openssh-8.8p1.orig/auth-pam.h openssh-8.8p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-8.8p1.orig/canohost.c openssh-8.8p1/canohost.c ---- openssh-8.8p1.orig/canohost.c 2021-12-01 16:47:29.833987626 +0100 -+++ openssh-8.8p1/canohost.c 2021-12-01 16:48:10.377080952 +0100 +diff -Nur openssh-9.0p1.orig/canohost.c openssh-9.0p1/canohost.c +--- openssh-9.0p1.orig/canohost.c 2022-08-30 19:32:35.318050592 +0200 ++++ openssh-9.0p1/canohost.c 2022-08-30 19:33:23.887176400 +0200 @@ -17,6 +17,7 @@ #include #include @@ -570,9 +571,9 @@ diff -Nur openssh-8.8p1.orig/canohost.c openssh-8.8p1/canohost.c + } + } +} -diff -Nur openssh-8.8p1.orig/canohost.h openssh-8.8p1/canohost.h ---- openssh-8.8p1.orig/canohost.h 2021-12-01 16:47:29.833987626 +0100 -+++ openssh-8.8p1/canohost.h 2021-12-01 16:48:10.377080952 +0100 +diff -Nur openssh-9.0p1.orig/canohost.h openssh-9.0p1/canohost.h +--- openssh-9.0p1.orig/canohost.h 2022-08-30 19:32:35.319050595 +0200 ++++ openssh-9.0p1/canohost.h 2022-08-30 19:33:23.887176400 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -580,10 +581,10 @@ diff -Nur openssh-8.8p1.orig/canohost.h openssh-8.8p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-8.8p1.orig/configure.ac openssh-8.8p1/configure.ac ---- openssh-8.8p1.orig/configure.ac 2021-12-01 16:47:29.928987844 +0100 -+++ openssh-8.8p1/configure.ac 2021-12-01 16:48:10.378080954 +0100 -@@ -4775,6 +4775,14 @@ +diff -Nur openssh-9.0p1.orig/configure.ac openssh-9.0p1/configure.ac +--- openssh-9.0p1.orig/configure.ac 2022-08-30 19:32:35.442050914 +0200 ++++ openssh-9.0p1/configure.ac 2022-08-30 19:33:23.889176405 +0200 +@@ -4832,6 +4832,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -598,7 +599,7 @@ diff -Nur openssh-8.8p1.orig/configure.ac openssh-8.8p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4815,6 +4823,40 @@ +@@ -4872,6 +4880,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -639,10 +640,10 @@ diff -Nur openssh-8.8p1.orig/configure.ac openssh-8.8p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-8.8p1.orig/gss-genr.c openssh-8.8p1/gss-genr.c ---- openssh-8.8p1.orig/gss-genr.c 2021-12-01 16:47:29.973987948 +0100 -+++ openssh-8.8p1/gss-genr.c 2021-12-01 16:48:10.379080957 +0100 -@@ -40,6 +40,7 @@ +diff -Nur openssh-9.0p1.orig/gss-genr.c openssh-9.0p1/gss-genr.c +--- openssh-9.0p1.orig/gss-genr.c 2022-08-30 19:32:35.547051186 +0200 ++++ openssh-9.0p1/gss-genr.c 2022-08-30 19:33:23.890176408 +0200 +@@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "log.h" @@ -650,7 +651,7 @@ diff -Nur openssh-8.8p1.orig/gss-genr.c openssh-8.8p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -408,9 +409,18 @@ +@@ -409,9 +410,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -670,7 +671,7 @@ diff -Nur openssh-8.8p1.orig/gss-genr.c openssh-8.8p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -418,6 +428,7 @@ +@@ -419,6 +429,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -678,9 +679,9 @@ diff -Nur openssh-8.8p1.orig/gss-genr.c openssh-8.8p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-8.8p1.orig/gss-serv.c openssh-8.8p1/gss-serv.c ---- openssh-8.8p1.orig/gss-serv.c 2021-12-01 16:47:29.853987672 +0100 -+++ openssh-8.8p1/gss-serv.c 2021-12-01 16:48:10.379080957 +0100 +diff -Nur openssh-9.0p1.orig/gss-serv.c openssh-9.0p1/gss-serv.c +--- openssh-9.0p1.orig/gss-serv.c 2022-08-30 19:32:35.345050662 +0200 ++++ openssh-9.0p1/gss-serv.c 2022-08-30 19:33:23.891176410 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -961,9 +962,9 @@ diff -Nur openssh-8.8p1.orig/gss-serv.c openssh-8.8p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-8.8p1.orig/gss-serv-gsi.c openssh-8.8p1/gss-serv-gsi.c ---- openssh-8.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.8p1/gss-serv-gsi.c 2021-12-01 16:48:10.380080959 +0100 +diff -Nur openssh-9.0p1.orig/gss-serv-gsi.c openssh-9.0p1/gss-serv-gsi.c +--- openssh-9.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.0p1/gss-serv-gsi.c 2022-08-30 19:33:23.891176410 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1293,9 +1294,9 @@ diff -Nur openssh-8.8p1.orig/gss-serv-gsi.c openssh-8.8p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-8.8p1.orig/gss-serv-krb5.c openssh-8.8p1/gss-serv-krb5.c ---- openssh-8.8p1.orig/gss-serv-krb5.c 2021-12-01 16:47:29.878987729 +0100 -+++ openssh-8.8p1/gss-serv-krb5.c 2021-12-01 16:48:10.380080959 +0100 +diff -Nur openssh-9.0p1.orig/gss-serv-krb5.c openssh-9.0p1/gss-serv-krb5.c +--- openssh-9.0p1.orig/gss-serv-krb5.c 2022-08-30 19:32:35.377050745 +0200 ++++ openssh-9.0p1/gss-serv-krb5.c 2022-08-30 19:33:23.892176413 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1349,9 +1350,9 @@ diff -Nur openssh-8.8p1.orig/gss-serv-krb5.c openssh-8.8p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-8.8p1.orig/kexgsss.c openssh-8.8p1/kexgsss.c ---- openssh-8.8p1.orig/kexgsss.c 2021-12-01 16:47:29.986987978 +0100 -+++ openssh-8.8p1/kexgsss.c 2021-12-01 16:48:10.380080959 +0100 +diff -Nur openssh-9.0p1.orig/kexgsss.c openssh-9.0p1/kexgsss.c +--- openssh-9.0p1.orig/kexgsss.c 2022-08-30 19:32:35.566051235 +0200 ++++ openssh-9.0p1/kexgsss.c 2022-08-30 19:33:23.892176413 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1415,20 +1416,20 @@ diff -Nur openssh-8.8p1.orig/kexgsss.c openssh-8.8p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in ---- openssh-8.8p1.orig/Makefile.in 2021-12-01 16:47:29.948987890 +0100 -+++ openssh-8.8p1/Makefile.in 2021-12-01 16:48:10.381080961 +0100 -@@ -128,6 +128,7 @@ +diff -Nur openssh-9.0p1.orig/Makefile.in openssh-9.0p1/Makefile.in +--- openssh-9.0p1.orig/Makefile.in 2022-08-30 19:32:35.496051054 +0200 ++++ openssh-9.0p1/Makefile.in 2022-08-30 19:34:46.023388812 +0200 +@@ -129,6 +129,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + gss-serv-gsi.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.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 \ -diff -Nur openssh-8.8p1.orig/misc.c openssh-8.8p1/misc.c ---- openssh-8.8p1.orig/misc.c 2021-12-01 16:47:29.975987952 +0100 -+++ openssh-8.8p1/misc.c 2021-12-01 16:48:10.381080961 +0100 +diff -Nur openssh-9.0p1.orig/misc.c openssh-9.0p1/misc.c +--- openssh-9.0p1.orig/misc.c 2022-08-30 19:32:35.550051194 +0200 ++++ openssh-9.0p1/misc.c 2022-08-30 19:33:23.894176418 +0200 @@ -393,11 +393,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1488,9 +1489,9 @@ diff -Nur openssh-8.8p1.orig/misc.c openssh-8.8p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-8.8p1.orig/misc.h openssh-8.8p1/misc.h ---- openssh-8.8p1.orig/misc.h 2021-12-01 16:47:29.902987784 +0100 -+++ openssh-8.8p1/misc.h 2021-12-01 16:48:10.381080961 +0100 +diff -Nur openssh-9.0p1.orig/misc.h openssh-9.0p1/misc.h +--- openssh-9.0p1.orig/misc.h 2022-08-30 19:32:35.405050818 +0200 ++++ openssh-9.0p1/misc.h 2022-08-30 19:33:23.895176421 +0200 @@ -100,6 +100,7 @@ void sock_set_v6only(int); @@ -1499,9 +1500,9 @@ diff -Nur openssh-8.8p1.orig/misc.h openssh-8.8p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-8.8p1.orig/monitor.c openssh-8.8p1/monitor.c ---- openssh-8.8p1.orig/monitor.c 2021-12-01 16:47:29.975987952 +0100 -+++ openssh-8.8p1/monitor.c 2021-12-01 16:48:10.382080964 +0100 +diff -Nur openssh-9.0p1.orig/monitor.c openssh-9.0p1/monitor.c +--- openssh-9.0p1.orig/monitor.c 2022-08-30 19:32:35.551051196 +0200 ++++ openssh-9.0p1/monitor.c 2022-08-30 19:56:02.622691995 +0200 @@ -152,6 +152,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1561,7 +1562,7 @@ diff -Nur openssh-8.8p1.orig/monitor.c openssh-8.8p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -444,6 +454,8 @@ +@@ -451,6 +461,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1570,29 +1571,28 @@ diff -Nur openssh-8.8p1.orig/monitor.c openssh-8.8p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -760,15 +772,18 @@ +@@ -766,14 +778,17 @@ debug3_f("entering"); - if (authctxt->attempt++ != 0) - fatal_f("multiple attempts for getpwnam"); - - if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) ++ if (authctxt->user) free(authctxt->user); + if ((r = sshbuf_get_cstring(m, &authctxt->user, NULL)) != 0) fatal_fr(r, "parse"); - pwent = getpwnamallow(ssh, username); + pwent = getpwnamallow(ssh, authctxt->user); -+ if (authctxt->user) free(authctxt->user); - authctxt->user = xstrdup(username); +#ifdef USE_PAM + if (options.permit_pam_user_change) + setproctitle("%s [priv]", pwent ? "[pam]" : "unknown"); + else +#endif - setproctitle("%s [priv]", pwent ? username : "unknown"); - free(username); + setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); -@@ -2109,6 +2124,79 @@ + sshbuf_reset(m); +@@ -2130,6 +2145,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-8.8p1.orig/monitor.c openssh-8.8p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-8.8p1.orig/monitor.h openssh-8.8p1/monitor.h ---- openssh-8.8p1.orig/monitor.h 2021-12-01 16:47:29.951987897 +0100 -+++ openssh-8.8p1/monitor.h 2021-12-01 16:48:10.382080964 +0100 +diff -Nur openssh-9.0p1.orig/monitor.h openssh-9.0p1/monitor.h +--- openssh-9.0p1.orig/monitor.h 2022-08-30 19:32:35.498051059 +0200 ++++ openssh-9.0p1/monitor.h 2022-08-30 19:33:23.897176426 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,9 +1686,9 @@ diff -Nur openssh-8.8p1.orig/monitor.h openssh-8.8p1/monitor.h }; struct ssh; -diff -Nur openssh-8.8p1.orig/monitor_wrap.c openssh-8.8p1/monitor_wrap.c ---- openssh-8.8p1.orig/monitor_wrap.c 2021-12-01 16:47:29.976987955 +0100 -+++ openssh-8.8p1/monitor_wrap.c 2021-12-01 16:48:10.383080966 +0100 +diff -Nur openssh-9.0p1.orig/monitor_wrap.c openssh-9.0p1/monitor_wrap.c +--- openssh-9.0p1.orig/monitor_wrap.c 2022-08-30 19:32:35.551051196 +0200 ++++ openssh-9.0p1/monitor_wrap.c 2022-08-30 19:33:23.898176429 +0200 @@ -1084,6 +1084,94 @@ return (authenticated); } @@ -1784,9 +1784,9 @@ diff -Nur openssh-8.8p1.orig/monitor_wrap.c openssh-8.8p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-8.8p1.orig/monitor_wrap.h openssh-8.8p1/monitor_wrap.h ---- openssh-8.8p1.orig/monitor_wrap.h 2021-12-01 16:47:29.959987916 +0100 -+++ openssh-8.8p1/monitor_wrap.h 2021-12-01 16:48:10.384080968 +0100 +diff -Nur openssh-9.0p1.orig/monitor_wrap.h openssh-9.0p1/monitor_wrap.h +--- openssh-9.0p1.orig/monitor_wrap.h 2022-08-30 19:32:35.508051085 +0200 ++++ openssh-9.0p1/monitor_wrap.h 2022-08-30 19:33:23.898176429 +0200 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,12 +1798,12 @@ diff -Nur openssh-8.8p1.orig/monitor_wrap.h openssh-8.8p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c ---- openssh-8.8p1.orig/readconf.c 2021-12-01 16:47:29.977987957 +0100 -+++ openssh-8.8p1/readconf.c 2021-12-01 16:48:10.384080968 +0100 -@@ -2543,11 +2543,11 @@ +diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c +--- openssh-9.0p1.orig/readconf.c 2022-08-30 19:32:35.553051201 +0200 ++++ openssh-9.0p1/readconf.c 2022-08-30 19:33:23.899176431 +0200 +@@ -2558,11 +2558,11 @@ if (options->pubkey_authentication == -1) - options->pubkey_authentication = 1; + options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) - options->gss_authentication = 0; + options->gss_authentication = 1; @@ -1816,9 +1816,9 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h ---- openssh-8.8p1.orig/readconf.h 2021-12-01 16:47:29.840987642 +0100 -+++ openssh-8.8p1/readconf.h 2021-12-01 16:48:10.385080970 +0100 +diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h +--- openssh-9.0p1.orig/readconf.h 2022-08-30 19:32:35.469050984 +0200 ++++ openssh-9.0p1/readconf.h 2022-08-30 19:33:23.900176434 +0200 @@ -78,6 +78,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c ---- openssh-8.8p1.orig/servconf.c 2021-12-01 16:47:29.978987959 +0100 -+++ openssh-8.8p1/servconf.c 2021-12-01 16:48:10.386080973 +0100 +diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c +--- openssh-9.0p1.orig/servconf.c 2022-08-30 19:32:35.555051206 +0200 ++++ openssh-9.0p1/servconf.c 2022-08-30 19:33:23.902176439 +0200 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1851,7 +1851,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -291,6 +294,8 @@ +@@ -292,6 +295,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -372,13 +377,17 @@ +@@ -373,13 +378,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -514,7 +523,7 @@ +@@ -517,7 +526,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -533,6 +542,9 @@ +@@ -536,6 +545,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -565,8 +577,10 @@ +@@ -569,8 +581,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -619,8 +633,15 @@ +@@ -623,8 +637,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -628,8 +649,11 @@ +@@ -632,8 +653,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -701,6 +725,8 @@ +@@ -705,6 +729,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1379,6 +1405,10 @@ +@@ -1383,6 +1409,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1626,6 +1656,10 @@ +@@ -1629,6 +1659,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1634,6 +1668,10 @@ +@@ -1637,6 +1671,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1654,6 +1692,12 @@ +@@ -1657,6 +1695,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2659,6 +2703,7 @@ +@@ -2665,6 +2709,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,9 +2001,9 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h ---- openssh-8.8p1.orig/servconf.h 2021-12-01 16:47:29.894987766 +0100 -+++ openssh-8.8p1/servconf.h 2021-12-01 16:48:10.387080975 +0100 +diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h +--- openssh-9.0p1.orig/servconf.h 2022-08-30 19:32:35.471050989 +0200 ++++ openssh-9.0p1/servconf.h 2022-08-30 19:33:23.903176441 +0200 @@ -146,9 +146,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2025,10 +2025,10 @@ diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h int permit_tun; -diff -Nur openssh-8.8p1.orig/ssh.1 openssh-8.8p1/ssh.1 ---- openssh-8.8p1.orig/ssh.1 2021-12-01 16:47:29.843987649 +0100 -+++ openssh-8.8p1/ssh.1 2021-12-01 16:48:10.387080975 +0100 -@@ -1501,6 +1501,18 @@ +diff -Nur openssh-9.0p1.orig/ssh.1 openssh-9.0p1/ssh.1 +--- openssh-9.0p1.orig/ssh.1 2022-08-30 19:32:35.531051144 +0200 ++++ openssh-9.0p1/ssh.1 2022-08-30 19:33:23.903176441 +0200 +@@ -1510,6 +1510,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-8.8p1.orig/ssh.1 openssh-8.8p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c ---- openssh-8.8p1.orig/ssh.c 2021-12-01 16:47:29.981987966 +0100 -+++ openssh-8.8p1/ssh.c 2021-12-01 16:48:10.388080977 +0100 -@@ -559,6 +559,38 @@ +diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c +--- openssh-9.0p1.orig/ssh.c 2022-08-30 19:32:35.560051220 +0200 ++++ openssh-9.0p1/ssh.c 2022-08-30 19:33:23.905176447 +0200 +@@ -567,6 +567,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,7 +2089,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1237,8 +1269,12 @@ +@@ -1245,8 +1277,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2103,9 +2103,9 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-8.8p1.orig/ssh_config openssh-8.8p1/ssh_config ---- openssh-8.8p1.orig/ssh_config 2021-12-01 16:47:29.843987649 +0100 -+++ openssh-8.8p1/ssh_config 2021-12-01 16:48:10.388080977 +0100 +diff -Nur openssh-9.0p1.orig/ssh_config openssh-9.0p1/ssh_config +--- openssh-9.0p1.orig/ssh_config 2022-08-30 19:32:35.334050634 +0200 ++++ openssh-9.0p1/ssh_config 2022-08-30 19:33:23.905176447 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-8.8p1.orig/ssh_config openssh-8.8p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-8.8p1.orig/ssh_config.5 openssh-8.8p1/ssh_config.5 ---- openssh-8.8p1.orig/ssh_config.5 2021-12-01 16:47:29.920987826 +0100 -+++ openssh-8.8p1/ssh_config.5 2021-12-01 16:48:10.389080980 +0100 +diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 +--- openssh-9.0p1.orig/ssh_config.5 2022-08-30 19:32:35.478051007 +0200 ++++ openssh-9.0p1/ssh_config.5 2022-08-30 19:33:23.906176449 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2159,7 +2159,7 @@ diff -Nur openssh-8.8p1.orig/ssh_config.5 openssh-8.8p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1461,7 +1467,7 @@ +@@ -1454,7 +1460,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-8.8p1.orig/ssh_config.5 openssh-8.8p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c ---- openssh-8.8p1.orig/sshconnect2.c 2021-12-01 16:47:29.966987932 +0100 -+++ openssh-8.8p1/sshconnect2.c 2021-12-01 16:48:10.390080982 +0100 -@@ -860,6 +860,11 @@ +diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c +--- openssh-9.0p1.orig/sshconnect2.c 2022-08-30 19:32:35.541051170 +0200 ++++ openssh-9.0p1/sshconnect2.c 2022-08-30 19:33:23.908176455 +0200 +@@ -874,6 +874,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -971,7 +976,8 @@ +@@ -985,7 +990,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1142,6 +1148,20 @@ +@@ -1156,6 +1162,20 @@ return r; } @@ -2214,7 +2214,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1164,6 +1184,12 @@ +@@ -1178,6 +1198,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2227,7 +2227,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1177,7 +1203,9 @@ +@@ -1191,7 +1217,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2238,9 +2238,9 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-8.8p1.orig/sshd.8 openssh-8.8p1/sshd.8 ---- openssh-8.8p1.orig/sshd.8 2021-12-01 16:47:29.861987690 +0100 -+++ openssh-8.8p1/sshd.8 2021-12-01 16:48:10.390080982 +0100 +diff -Nur openssh-9.0p1.orig/sshd.8 openssh-9.0p1/sshd.8 +--- openssh-9.0p1.orig/sshd.8 2022-08-30 19:32:35.352050680 +0200 ++++ openssh-9.0p1/sshd.8 2022-08-30 19:33:23.909176457 +0200 @@ -823,6 +823,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2271,10 +2271,10 @@ diff -Nur openssh-8.8p1.orig/sshd.8 openssh-8.8p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c ---- openssh-8.8p1.orig/sshd.c 2021-12-01 16:47:29.982987968 +0100 -+++ openssh-8.8p1/sshd.c 2021-12-01 16:48:10.391080984 +0100 -@@ -2380,7 +2380,7 @@ +diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c +--- openssh-9.0p1.orig/sshd.c 2022-08-30 19:32:35.561051222 +0200 ++++ openssh-9.0p1/sshd.c 2022-08-30 19:33:23.910176460 +0200 +@@ -2390,7 +2390,7 @@ #endif #ifdef GSSAPI @@ -2283,9 +2283,9 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config ---- openssh-8.8p1.orig/sshd_config 2021-12-01 16:47:29.880987734 +0100 -+++ openssh-8.8p1/sshd_config 2021-12-01 16:48:10.392080987 +0100 +diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config +--- openssh-9.0p1.orig/sshd_config 2022-08-30 19:32:35.380050753 +0200 ++++ openssh-9.0p1/sshd_config 2022-08-30 19:33:23.911176462 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,9 +2311,9 @@ diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-8.8p1.orig/sshd_config.5 openssh-8.8p1/sshd_config.5 ---- openssh-8.8p1.orig/sshd_config.5 2021-12-01 16:47:29.920987826 +0100 -+++ openssh-8.8p1/sshd_config.5 2021-12-01 16:48:10.392080987 +0100 +diff -Nur openssh-9.0p1.orig/sshd_config.5 openssh-9.0p1/sshd_config.5 +--- openssh-9.0p1.orig/sshd_config.5 2022-08-30 19:32:35.479051009 +0200 ++++ openssh-9.0p1/sshd_config.5 2022-08-30 19:33:23.912176465 +0200 @@ -635,15 +635,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2359,7 +2359,7 @@ diff -Nur openssh-8.8p1.orig/sshd_config.5 openssh-8.8p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1788,6 +1807,12 @@ +@@ -1784,6 +1803,12 @@ as a non-root user. The default is .Cm no . @@ -2372,9 +2372,9 @@ diff -Nur openssh-8.8p1.orig/sshd_config.5 openssh-8.8p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-8.8p1.orig/sshd_config_redhat openssh-8.8p1/sshd_config_redhat ---- openssh-8.8p1.orig/sshd_config_redhat 2021-12-01 16:47:29.826987609 +0100 -+++ openssh-8.8p1/sshd_config_redhat 2021-12-01 16:48:10.392080987 +0100 +diff -Nur openssh-9.0p1.orig/sshd_config_redhat openssh-9.0p1/sshd_config_redhat +--- openssh-9.0p1.orig/sshd_config_redhat 2022-08-30 19:32:35.308050566 +0200 ++++ openssh-9.0p1/sshd_config_redhat 2022-08-30 19:33:23.912176465 +0200 @@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-8.8p1.orig/sshd_config_redhat openssh-8.8p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-8.8p1.orig/ssh-gss.h openssh-8.8p1/ssh-gss.h ---- openssh-8.8p1.orig/ssh-gss.h 2021-12-01 16:47:29.857987681 +0100 -+++ openssh-8.8p1/ssh-gss.h 2021-12-01 16:48:10.393080989 +0100 +diff -Nur openssh-9.0p1.orig/ssh-gss.h openssh-9.0p1/ssh-gss.h +--- openssh-9.0p1.orig/ssh-gss.h 2022-08-30 19:32:35.349050673 +0200 ++++ openssh-9.0p1/ssh-gss.h 2022-08-30 19:33:23.913176467 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-8.8p1.orig/ssh-gss.h openssh-8.8p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-8.8p1.orig/version.h openssh-8.8p1/version.h ---- openssh-8.8p1.orig/version.h 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/version.h 2021-12-01 16:48:10.393080989 +0100 +diff -Nur openssh-9.0p1.orig/version.h openssh-9.0p1/version.h +--- openssh-9.0p1.orig/version.h 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/version.h 2022-08-30 19:33:23.913176467 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_8.8" + #define SSH_VERSION "OpenSSH_9.0" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-8.8p1-hpn-15.2-modified.patch b/openssh-9.0p1-hpn-15.2-modified.patch similarity index 88% rename from openssh-8.8p1-hpn-15.2-modified.patch rename to openssh-9.0p1-hpn-15.2-modified.patch index 807c8ef..5700e43 100644 --- a/openssh-8.8p1-hpn-15.2-modified.patch +++ b/openssh-9.0p1-hpn-15.2-modified.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c ---- openssh-8.8p1.orig/auth2.c 2021-12-01 16:50:22.511385558 +0100 -+++ openssh-8.8p1/auth2.c 2021-12-01 16:51:00.919474114 +0100 +diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c +--- openssh-9.0p1.orig/auth2.c 2022-08-30 20:22:42.458819942 +0200 ++++ openssh-9.0p1/auth2.c 2022-08-30 20:23:49.877993046 +0200 @@ -53,6 +53,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -19,7 +19,7 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c Authmethod *authmethods[] = { &method_none, &method_pubkey, -@@ -299,6 +303,11 @@ +@@ -300,6 +304,11 @@ debug("userauth-request for user %s service %s method %s", user[0] ? user : "", service, method); @@ -31,10 +31,10 @@ diff -Nur openssh-8.8p1.orig/auth2.c openssh-8.8p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c ---- openssh-8.8p1.orig/channels.c 2021-12-01 16:50:22.496385524 +0100 -+++ openssh-8.8p1/channels.c 2021-12-01 16:51:00.921474119 +0100 -@@ -220,6 +220,9 @@ +diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c +--- openssh-9.0p1.orig/channels.c 2022-08-30 20:22:42.436819885 +0200 ++++ openssh-9.0p1/channels.c 2022-08-30 20:23:49.879993051 +0200 +@@ -219,6 +219,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -44,7 +44,7 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c /* -- channel core */ void -@@ -415,6 +418,7 @@ +@@ -407,6 +410,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -52,8 +52,8 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1110,6 +1114,28 @@ - FD_SET(c->sock, writeset); +@@ -1104,6 +1108,28 @@ + c->io_want = SSH_CHAN_IO_SOCK_W; } +static int @@ -79,9 +79,9 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c +} + static void - channel_pre_open(struct ssh *ssh, Channel *c, - fd_set *readset, fd_set *writeset) -@@ -2149,22 +2175,31 @@ + channel_pre_open(struct ssh *ssh, Channel *c) + { +@@ -2170,22 +2196,31 @@ if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && @@ -118,7 +118,7 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c c->local_consumed = 0; } return 1; -@@ -3331,6 +3366,14 @@ +@@ -3571,6 +3606,14 @@ return addr; } @@ -133,7 +133,7 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -@@ -3470,8 +3513,10 @@ +@@ -3710,8 +3753,10 @@ } /* Allocate a channel number for the socket. */ @@ -145,7 +145,7 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; -@@ -4657,7 +4702,8 @@ +@@ -4897,7 +4942,8 @@ sock = socks[n]; nc = channel_new(ssh, "x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, @@ -155,10 +155,10 @@ diff -Nur openssh-8.8p1.orig/channels.c openssh-8.8p1/channels.c 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; -diff -Nur openssh-8.8p1.orig/channels.h openssh-8.8p1/channels.h ---- openssh-8.8p1.orig/channels.h 2021-12-01 16:50:22.421385351 +0100 -+++ openssh-8.8p1/channels.h 2021-12-01 16:51:00.922474121 +0100 -@@ -169,8 +169,10 @@ +diff -Nur openssh-9.0p1.orig/channels.h openssh-9.0p1/channels.h +--- openssh-9.0p1.orig/channels.h 2022-08-30 20:22:42.315819575 +0200 ++++ openssh-9.0p1/channels.h 2022-08-30 20:23:49.880993054 +0200 +@@ -172,8 +172,10 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; @@ -169,16 +169,16 @@ diff -Nur openssh-8.8p1.orig/channels.h openssh-8.8p1/channels.h char *ctype; /* type */ -@@ -232,7 +234,7 @@ - #define CHAN_LOCAL 0x10 +@@ -245,7 +247,7 @@ + #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) /* Read buffer size */ -#define CHAN_RBUF (16*1024) +#define CHAN_RBUF CHAN_SES_PACKET_DEFAULT - /* Maximum channel input buffer size */ - #define CHAN_INPUT_MAX (16*1024*1024) -@@ -363,4 +365,7 @@ + /* Maximum size for direct reads to buffers */ + #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT +@@ -380,4 +382,7 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); @@ -186,9 +186,9 @@ diff -Nur openssh-8.8p1.orig/channels.h openssh-8.8p1/channels.h +void channel_set_hpn(int, int); + #endif -diff -Nur openssh-8.8p1.orig/cipher.c openssh-8.8p1/cipher.c ---- openssh-8.8p1.orig/cipher.c 2021-12-01 16:50:22.475385475 +0100 -+++ openssh-8.8p1/cipher.c 2021-12-01 16:51:00.923474123 +0100 +diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c +--- openssh-9.0p1.orig/cipher.c 2022-08-30 20:22:42.382819747 +0200 ++++ openssh-9.0p1/cipher.c 2022-08-30 20:23:49.881993056 +0200 @@ -48,6 +48,7 @@ #include "sshbuf.h" #include "ssherr.h" @@ -269,9 +269,9 @@ diff -Nur openssh-8.8p1.orig/cipher.c openssh-8.8p1/cipher.c free(cipher_list); return 0; } -diff -Nur openssh-8.8p1.orig/cipher-ctr-mt.c openssh-8.8p1/cipher-ctr-mt.c ---- openssh-8.8p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.8p1/cipher-ctr-mt.c 2021-12-01 16:51:00.923474123 +0100 +diff -Nur openssh-9.0p1.orig/cipher-ctr-mt.c openssh-9.0p1/cipher-ctr-mt.c +--- openssh-9.0p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.0p1/cipher-ctr-mt.c 2022-08-30 20:23:49.882993059 +0200 @@ -0,0 +1,678 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -951,9 +951,9 @@ diff -Nur openssh-8.8p1.orig/cipher-ctr-mt.c openssh-8.8p1/cipher-ctr-mt.c +} + +#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-8.8p1.orig/cipher.h openssh-8.8p1/cipher.h ---- openssh-8.8p1.orig/cipher.h 2021-12-01 16:50:22.475385475 +0100 -+++ openssh-8.8p1/cipher.h 2021-12-01 16:51:00.924474126 +0100 +diff -Nur openssh-9.0p1.orig/cipher.h openssh-9.0p1/cipher.h +--- openssh-9.0p1.orig/cipher.h 2022-08-30 20:22:42.382819747 +0200 ++++ openssh-9.0p1/cipher.h 2022-08-30 20:23:49.882993059 +0200 @@ -68,7 +68,9 @@ struct sshcipher_ctx; @@ -974,10 +974,10 @@ diff -Nur openssh-8.8p1.orig/cipher.h openssh-8.8p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-8.8p1.orig/clientloop.c openssh-8.8p1/clientloop.c ---- openssh-8.8p1.orig/clientloop.c 2021-12-01 16:50:22.361385212 +0100 -+++ openssh-8.8p1/clientloop.c 2021-12-01 16:51:00.925474128 +0100 -@@ -1583,7 +1583,9 @@ +diff -Nur openssh-9.0p1.orig/clientloop.c openssh-9.0p1/clientloop.c +--- openssh-9.0p1.orig/clientloop.c 2022-08-30 20:22:42.263819441 +0200 ++++ openssh-9.0p1/clientloop.c 2022-08-30 20:23:49.883993061 +0200 +@@ -1586,7 +1586,9 @@ return NULL; c = channel_new(ssh, "x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, @@ -988,8 +988,8 @@ diff -Nur openssh-8.8p1.orig/clientloop.c openssh-8.8p1/clientloop.c c->force_drain = 1; return c; } -@@ -1612,7 +1614,8 @@ - } +@@ -1621,7 +1623,8 @@ + c = channel_new(ssh, "authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, @@ -998,7 +998,7 @@ diff -Nur openssh-8.8p1.orig/clientloop.c openssh-8.8p1/clientloop.c "authentication agent connection", 1); c->force_drain = 1; return c; -@@ -1639,7 +1642,8 @@ +@@ -1648,7 +1651,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, @@ -1008,9 +1008,9 @@ diff -Nur openssh-8.8p1.orig/clientloop.c openssh-8.8p1/clientloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) -diff -Nur openssh-8.8p1.orig/compat.c openssh-8.8p1/compat.c ---- openssh-8.8p1.orig/compat.c 2021-12-01 16:50:22.497385526 +0100 -+++ openssh-8.8p1/compat.c 2021-12-01 16:51:00.925474128 +0100 +diff -Nur openssh-9.0p1.orig/compat.c openssh-9.0p1/compat.c +--- openssh-9.0p1.orig/compat.c 2022-08-30 20:22:42.423819852 +0200 ++++ openssh-9.0p1/compat.c 2022-08-30 20:23:49.884993064 +0200 @@ -150,6 +150,17 @@ debug_f("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); @@ -1029,9 +1029,9 @@ diff -Nur openssh-8.8p1.orig/compat.c openssh-8.8p1/compat.c return; } } -diff -Nur openssh-8.8p1.orig/compat.h openssh-8.8p1/compat.h ---- openssh-8.8p1.orig/compat.h 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/compat.h 2021-12-01 16:51:00.926474130 +0100 +diff -Nur openssh-9.0p1.orig/compat.h openssh-9.0p1/compat.h +--- openssh-9.0p1.orig/compat.h 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/compat.h 2022-08-30 20:23:49.884993064 +0200 @@ -57,6 +57,7 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 @@ -1040,10 +1040,10 @@ diff -Nur openssh-8.8p1.orig/compat.h openssh-8.8p1/compat.h struct ssh; -diff -Nur openssh-8.8p1.orig/defines.h openssh-8.8p1/defines.h ---- openssh-8.8p1.orig/defines.h 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/defines.h 2021-12-01 16:51:00.927474132 +0100 -@@ -854,7 +854,7 @@ +diff -Nur openssh-9.0p1.orig/defines.h openssh-9.0p1/defines.h +--- openssh-9.0p1.orig/defines.h 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/defines.h 2022-08-30 20:23:49.885993067 +0200 +@@ -889,7 +889,7 @@ #endif #ifndef SSH_IOBUFSZ @@ -1052,9 +1052,9 @@ diff -Nur openssh-8.8p1.orig/defines.h openssh-8.8p1/defines.h #endif /* -diff -Nur openssh-8.8p1.orig/digest.h openssh-8.8p1/digest.h ---- openssh-8.8p1.orig/digest.h 2021-12-01 16:50:22.451385420 +0100 -+++ openssh-8.8p1/digest.h 2021-12-01 16:51:00.927474132 +0100 +diff -Nur openssh-9.0p1.orig/digest.h openssh-9.0p1/digest.h +--- openssh-9.0p1.orig/digest.h 2022-08-30 20:22:42.344819649 +0200 ++++ openssh-9.0p1/digest.h 2022-08-30 20:23:49.886993069 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -1065,9 +1065,9 @@ diff -Nur openssh-8.8p1.orig/digest.h openssh-8.8p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-8.8p1.orig/digest-openssl.c openssh-8.8p1/digest-openssl.c ---- openssh-8.8p1.orig/digest-openssl.c 2021-12-01 16:50:22.451385420 +0100 -+++ openssh-8.8p1/digest-openssl.c 2021-12-01 16:51:00.927474132 +0100 +diff -Nur openssh-9.0p1.orig/digest-openssl.c openssh-9.0p1/digest-openssl.c +--- openssh-9.0p1.orig/digest-openssl.c 2022-08-30 20:22:42.344819649 +0200 ++++ openssh-9.0p1/digest-openssl.c 2022-08-30 20:23:49.886993069 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -1076,9 +1076,9 @@ diff -Nur openssh-8.8p1.orig/digest-openssl.c openssh-8.8p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-8.8p1.orig/HPN-README openssh-8.8p1/HPN-README ---- openssh-8.8p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-8.8p1/HPN-README 2021-12-01 16:51:00.928474135 +0100 +diff -Nur openssh-9.0p1.orig/HPN-README openssh-9.0p1/HPN-README +--- openssh-9.0p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.0p1/HPN-README 2022-08-30 20:23:49.887993072 +0200 @@ -0,0 +1,153 @@ +Notes: + @@ -1233,9 +1233,9 @@ diff -Nur openssh-8.8p1.orig/HPN-README openssh-8.8p1/HPN-README + Allan Jude provided the code for the NoneMac and buffer normalization. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. -diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c ---- openssh-8.8p1.orig/kex.c 2021-12-01 16:50:22.487385503 +0100 -+++ openssh-8.8p1/kex.c 2021-12-01 16:51:00.929474137 +0100 +diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c +--- openssh-9.0p1.orig/kex.c 2022-08-30 20:22:42.402819798 +0200 ++++ openssh-9.0p1/kex.c 2022-08-30 20:23:49.887993072 +0200 @@ -64,6 +64,7 @@ #include "ssherr.h" @@ -1244,7 +1244,7 @@ diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c #include "digest.h" #include "audit.h" -@@ -969,6 +970,11 @@ +@@ -1001,6 +1002,11 @@ int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; @@ -1256,7 +1256,7 @@ diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) -@@ -1039,11 +1045,40 @@ +@@ -1081,11 +1087,40 @@ peer[ncomp] = NULL; goto out; } @@ -1297,7 +1297,7 @@ diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { -@@ -1391,7 +1426,7 @@ +@@ -1433,7 +1468,7 @@ if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", @@ -1306,7 +1306,7 @@ diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c version_addendum == NULL ? "" : " ", version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; -@@ -1527,6 +1562,14 @@ +@@ -1569,6 +1604,14 @@ r = SSH_ERR_INVALID_FORMAT; goto out; } @@ -1321,9 +1321,9 @@ diff -Nur openssh-8.8p1.orig/kex.c openssh-8.8p1/kex.c debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); compat_banner(ssh, remote_version); -diff -Nur openssh-8.8p1.orig/log.c openssh-8.8p1/log.c ---- openssh-8.8p1.orig/log.c 2021-12-01 16:50:22.401385305 +0100 -+++ openssh-8.8p1/log.c 2021-12-01 16:51:00.929474137 +0100 +diff -Nur openssh-9.0p1.orig/log.c openssh-9.0p1/log.c +--- openssh-9.0p1.orig/log.c 2022-08-30 20:22:42.298819531 +0200 ++++ openssh-9.0p1/log.c 2022-08-30 20:23:49.888993074 +0200 @@ -46,6 +46,11 @@ #include #include @@ -1345,9 +1345,9 @@ diff -Nur openssh-8.8p1.orig/log.c openssh-8.8p1/log.c #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) -diff -Nur openssh-8.8p1.orig/mac.c openssh-8.8p1/mac.c ---- openssh-8.8p1.orig/mac.c 2021-12-01 16:50:22.476385477 +0100 -+++ openssh-8.8p1/mac.c 2021-12-01 16:51:00.929474137 +0100 +diff -Nur openssh-9.0p1.orig/mac.c openssh-9.0p1/mac.c +--- openssh-9.0p1.orig/mac.c 2022-08-30 20:22:42.384819752 +0200 ++++ openssh-9.0p1/mac.c 2022-08-30 20:23:49.888993074 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -1356,10 +1356,10 @@ diff -Nur openssh-8.8p1.orig/mac.c openssh-8.8p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in ---- openssh-8.8p1.orig/Makefile.in 2021-12-01 16:50:22.516385570 +0100 -+++ openssh-8.8p1/Makefile.in 2021-12-01 16:51:00.930474139 +0100 -@@ -48,7 +48,7 @@ +diff -Nur openssh-9.0p1.orig/Makefile.in openssh-9.0p1/Makefile.in +--- openssh-9.0p1.orig/Makefile.in 2022-08-30 20:22:42.466819962 +0200 ++++ openssh-9.0p1/Makefile.in 2022-08-30 20:23:49.889993077 +0200 +@@ -49,7 +49,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ @@ -1368,7 +1368,7 @@ diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ -@@ -95,7 +95,7 @@ +@@ -96,7 +96,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ @@ -1377,9 +1377,9 @@ diff -Nur openssh-8.8p1.orig/Makefile.in openssh-8.8p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c ---- openssh-8.8p1.orig/packet.c 2021-12-01 16:50:22.479385484 +0100 -+++ openssh-8.8p1/packet.c 2021-12-01 16:51:00.930474139 +0100 +diff -Nur openssh-9.0p1.orig/packet.c openssh-9.0p1/packet.c +--- openssh-9.0p1.orig/packet.c 2022-08-30 20:22:42.389819765 +0200 ++++ openssh-9.0p1/packet.c 2022-08-31 13:43:18.798517271 +0200 @@ -246,7 +246,7 @@ TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; @@ -1464,13 +1464,22 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c @@ -1342,7 +1376,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain; - fd_set *setp; + struct pollfd pfd; - char buf[8192]; + char buf[SSH_IOBUFSZ]; - struct timeval timeout, start, *timeoutp = NULL; + struct timeval start; + struct timespec timespec, *timespecp = NULL; - DBG(debug("packet_read()")); -@@ -1870,17 +1904,21 @@ +@@ -1822,6 +1856,8 @@ + state->packet_discard -= rlen; + return 0; + } ++ ++ ssh->fdout_bytes += rlen; + return 0; + } + +@@ -1887,17 +1923,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -1492,7 +1501,7 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -1922,6 +1960,24 @@ +@@ -1939,6 +1979,24 @@ logdie_f("should have exited"); } @@ -1517,7 +1526,7 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -1991,6 +2047,7 @@ +@@ -2008,6 +2066,7 @@ return SSH_ERR_CONN_CLOSED; if ((r = sshbuf_consume(state->output, len)) != 0) return r; @@ -1525,7 +1534,7 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c } return 0; } -@@ -2794,3 +2850,10 @@ +@@ -2799,3 +2858,10 @@ ssh->state->extra_pad = pad; return 0; } @@ -1536,9 +1545,9 @@ diff -Nur openssh-8.8p1.orig/packet.c openssh-8.8p1/packet.c +{ + return ssh->state->send_context; +} -diff -Nur openssh-8.8p1.orig/packet.h openssh-8.8p1/packet.h ---- openssh-8.8p1.orig/packet.h 2021-12-01 16:50:22.479385484 +0100 -+++ openssh-8.8p1/packet.h 2021-12-01 16:51:00.931474142 +0100 +diff -Nur openssh-9.0p1.orig/packet.h openssh-9.0p1/packet.h +--- openssh-9.0p1.orig/packet.h 2022-08-30 20:22:42.390819767 +0200 ++++ openssh-9.0p1/packet.h 2022-08-30 20:23:49.892993084 +0200 @@ -86,6 +86,14 @@ /* APP data */ @@ -1554,7 +1563,7 @@ diff -Nur openssh-8.8p1.orig/packet.h openssh-8.8p1/packet.h }; typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, -@@ -156,6 +164,8 @@ +@@ -157,6 +165,8 @@ int ssh_packet_set_maxsize(struct ssh *, u_int); u_int ssh_packet_get_maxsize(struct ssh *); @@ -1563,7 +1572,7 @@ diff -Nur openssh-8.8p1.orig/packet.h openssh-8.8p1/packet.h int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); -@@ -170,6 +180,13 @@ +@@ -171,6 +181,13 @@ void *ssh_packet_get_input(struct ssh *); void *ssh_packet_get_output(struct ssh *); @@ -1577,9 +1586,9 @@ diff -Nur openssh-8.8p1.orig/packet.h openssh-8.8p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-8.8p1.orig/progressmeter.c openssh-8.8p1/progressmeter.c ---- openssh-8.8p1.orig/progressmeter.c 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/progressmeter.c 2021-12-01 16:51:00.931474142 +0100 +diff -Nur openssh-9.0p1.orig/progressmeter.c openssh-9.0p1/progressmeter.c +--- openssh-9.0p1.orig/progressmeter.c 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/progressmeter.c 2022-08-30 20:23:49.893993087 +0200 @@ -68,6 +68,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -1641,9 +1650,9 @@ diff -Nur openssh-8.8p1.orig/progressmeter.c openssh-8.8p1/progressmeter.c } /*ARGSUSED*/ -diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c ---- openssh-8.8p1.orig/readconf.c 2021-12-01 16:50:22.519385577 +0100 -+++ openssh-8.8p1/readconf.c 2021-12-01 16:51:00.932474144 +0100 +diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c +--- openssh-9.0p1.orig/readconf.c 2022-08-30 20:22:42.471819975 +0200 ++++ openssh-9.0p1/readconf.c 2022-08-30 20:23:49.894993090 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -1673,7 +1682,7 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c { "sessiontype", oSessionType }, { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, -@@ -336,6 +344,11 @@ +@@ -337,6 +345,11 @@ { "knownhostscommand", oKnownHostsCommand }, { "rsaminsize", oRSAMinSize }, @@ -1685,7 +1694,7 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c { NULL, oBadOption } }; -@@ -1172,6 +1185,46 @@ +@@ -1183,6 +1196,46 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -1732,7 +1741,7 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -1426,6 +1479,10 @@ +@@ -1437,6 +1490,10 @@ *intptr = value; break; @@ -1743,7 +1752,7 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c case oCiphers: arg = argv_next(&ac, &av); if (!arg || *arg == '\0') { -@@ -2467,6 +2524,14 @@ +@@ -2481,6 +2538,14 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -1758,7 +1767,7 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2642,6 +2707,43 @@ +@@ -2657,6 +2722,43 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -1802,9 +1811,9 @@ diff -Nur openssh-8.8p1.orig/readconf.c openssh-8.8p1/readconf.c if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { -diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h ---- openssh-8.8p1.orig/readconf.h 2021-12-01 16:50:22.519385577 +0100 -+++ openssh-8.8p1/readconf.h 2021-12-01 16:51:00.932474144 +0100 +diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h +--- openssh-9.0p1.orig/readconf.h 2022-08-30 20:22:42.471819975 +0200 ++++ openssh-9.0p1/readconf.h 2022-08-30 20:23:49.895993092 +0200 @@ -55,6 +55,10 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ @@ -1829,9 +1838,9 @@ diff -Nur openssh-8.8p1.orig/readconf.h openssh-8.8p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-8.8p1.orig/regress/integrity.sh openssh-8.8p1/regress/integrity.sh ---- openssh-8.8p1.orig/regress/integrity.sh 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/regress/integrity.sh 2021-12-01 16:51:00.933474146 +0100 +diff -Nur openssh-9.0p1.orig/regress/integrity.sh openssh-9.0p1/regress/integrity.sh +--- openssh-9.0p1.orig/regress/integrity.sh 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/regress/integrity.sh 2022-08-30 20:23:49.895993092 +0200 @@ -21,6 +21,12 @@ cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" @@ -1845,9 +1854,9 @@ diff -Nur openssh-8.8p1.orig/regress/integrity.sh openssh-8.8p1/regress/integrit trace "test $tid: mac $m" elen=0 epad=0 -diff -Nur openssh-8.8p1.orig/sandbox-seccomp-filter.c openssh-8.8p1/sandbox-seccomp-filter.c ---- openssh-8.8p1.orig/sandbox-seccomp-filter.c 2021-12-01 16:50:22.489385507 +0100 -+++ openssh-8.8p1/sandbox-seccomp-filter.c 2021-12-01 16:51:00.933474146 +0100 +diff -Nur openssh-9.0p1.orig/sandbox-seccomp-filter.c openssh-9.0p1/sandbox-seccomp-filter.c +--- openssh-9.0p1.orig/sandbox-seccomp-filter.c 2022-08-30 20:22:42.405819806 +0200 ++++ openssh-9.0p1/sandbox-seccomp-filter.c 2022-08-30 20:23:49.896993095 +0200 @@ -225,6 +225,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -1858,7 +1867,7 @@ diff -Nur openssh-8.8p1.orig/sandbox-seccomp-filter.c openssh-8.8p1/sandbox-secc #ifdef __NR_getpgid SC_ALLOW(__NR_getpgid), #endif -@@ -318,6 +321,9 @@ +@@ -327,6 +330,9 @@ #ifdef __NR_sigprocmask SC_ALLOW(__NR_sigprocmask), #endif @@ -1868,10 +1877,10 @@ diff -Nur openssh-8.8p1.orig/sandbox-seccomp-filter.c openssh-8.8p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-8.8p1.orig/scp.c openssh-8.8p1/scp.c ---- openssh-8.8p1.orig/scp.c 2021-12-01 16:50:22.502385537 +0100 -+++ openssh-8.8p1/scp.c 2021-12-01 16:51:00.934474149 +0100 -@@ -1576,7 +1576,7 @@ +diff -Nur openssh-9.0p1.orig/scp.c openssh-9.0p1/scp.c +--- openssh-9.0p1.orig/scp.c 2022-08-30 20:22:42.444819906 +0200 ++++ openssh-9.0p1/scp.c 2022-08-30 20:23:49.897993097 +0200 +@@ -1605,7 +1605,7 @@ off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerr; @@ -1880,9 +1889,9 @@ diff -Nur openssh-8.8p1.orig/scp.c openssh-8.8p1/scp.c char **patterns = NULL; size_t n, npatterns = 0; struct timeval tv[2]; -diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c ---- openssh-8.8p1.orig/servconf.c 2021-12-01 16:50:22.520385579 +0100 -+++ openssh-8.8p1/servconf.c 2021-12-01 16:51:00.935474151 +0100 +diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c +--- openssh-9.0p1.orig/servconf.c 2022-08-30 20:22:42.473819980 +0200 ++++ openssh-9.0p1/servconf.c 2022-08-30 20:23:49.899993103 +0200 @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -1904,7 +1913,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -290,6 +297,10 @@ +@@ -291,6 +298,10 @@ fill_default_server_options(ServerOptions *options) { u_int i; @@ -1915,7 +1924,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c /* Portable-specific options */ if (options->use_pam == -1) -@@ -461,6 +472,51 @@ +@@ -462,6 +473,51 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -1967,7 +1976,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -531,6 +587,9 @@ +@@ -534,6 +590,9 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -1977,7 +1986,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -731,6 +790,12 @@ +@@ -735,6 +794,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -1990,7 +1999,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -789,6 +854,7 @@ +@@ -794,6 +859,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -1998,7 +2007,7 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1566,12 +1632,36 @@ +@@ -1569,12 +1635,36 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -2035,9 +2044,9 @@ diff -Nur openssh-8.8p1.orig/servconf.c openssh-8.8p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h ---- openssh-8.8p1.orig/servconf.h 2021-12-01 16:50:22.520385579 +0100 -+++ openssh-8.8p1/servconf.h 2021-12-01 16:51:00.935474151 +0100 +diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h +--- openssh-9.0p1.orig/servconf.h 2022-08-30 20:22:42.473819980 +0200 ++++ openssh-9.0p1/servconf.h 2022-08-30 20:23:49.900993105 +0200 @@ -214,6 +214,13 @@ int use_pam; /* Enable auth via PAM */ int permit_pam_user_change; /* Allow PAM to change user name */ @@ -2052,27 +2061,10 @@ diff -Nur openssh-8.8p1.orig/servconf.h openssh-8.8p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c ---- openssh-8.8p1.orig/serverloop.c 2021-12-01 16:50:22.503385540 +0100 -+++ openssh-8.8p1/serverloop.c 2021-12-01 16:51:00.936474153 +0100 -@@ -266,7 +266,7 @@ - process_input(struct ssh *ssh, fd_set *readset, int connection_in) - { - int r, len; -- char buf[16384]; -+ char buf[SSH_IOBUFSZ]; - - /* Read and buffer any input data from the client. */ - if (FD_ISSET(connection_in, readset)) { -@@ -287,6 +287,7 @@ - /* Buffer any received data. */ - if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) - fatal_fr(r, "ssh_packet_process_incoming"); -+ ssh->fdout_bytes += len; - } - return 0; - } -@@ -340,6 +341,7 @@ +diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c +--- openssh-9.0p1.orig/serverloop.c 2022-08-30 20:22:42.446819911 +0200 ++++ openssh-9.0p1/serverloop.c 2022-08-30 20:23:49.900993105 +0200 +@@ -342,6 +342,7 @@ sigset_t bsigset, osigset; debug("Entering interactive session for SSH2."); @@ -2080,7 +2072,7 @@ diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) error_f("bsigset setup: %s", strerror(errno)); -@@ -388,6 +390,7 @@ +@@ -388,6 +389,7 @@ if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); @@ -2088,7 +2080,7 @@ diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } -@@ -409,6 +412,9 @@ +@@ -409,6 +411,9 @@ /* free all channels, no more reads and writes */ channel_free_all(ssh); @@ -2098,7 +2090,7 @@ diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(ssh, NULL); } -@@ -559,7 +565,8 @@ +@@ -559,7 +564,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -2108,7 +2100,7 @@ diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) -@@ -610,6 +617,8 @@ +@@ -610,6 +616,8 @@ c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); @@ -2117,10 +2109,10 @@ diff -Nur openssh-8.8p1.orig/serverloop.c openssh-8.8p1/serverloop.c if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -diff -Nur openssh-8.8p1.orig/session.c openssh-8.8p1/session.c ---- openssh-8.8p1.orig/session.c 2021-12-01 16:50:22.504385542 +0100 -+++ openssh-8.8p1/session.c 2021-12-01 16:51:00.936474153 +0100 -@@ -228,6 +228,7 @@ +diff -Nur openssh-9.0p1.orig/session.c openssh-9.0p1/session.c +--- openssh-9.0p1.orig/session.c 2022-08-30 20:22:42.447819914 +0200 ++++ openssh-9.0p1/session.c 2022-08-30 20:23:49.902993110 +0200 +@@ -227,6 +227,7 @@ goto authsock_err; /* Allocate a channel for the authentication agent socket. */ @@ -2128,7 +2120,7 @@ diff -Nur openssh-8.8p1.orig/session.c openssh-8.8p1/session.c nc = channel_new(ssh, "auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -2363,7 +2364,8 @@ +@@ -2362,7 +2363,8 @@ channel_set_fds(ssh, s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, @@ -2138,9 +2130,9 @@ diff -Nur openssh-8.8p1.orig/session.c openssh-8.8p1/session.c } /* -diff -Nur openssh-8.8p1.orig/sftp.1 openssh-8.8p1/sftp.1 ---- openssh-8.8p1.orig/sftp.1 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/sftp.1 2021-12-01 16:51:00.937474156 +0100 +diff -Nur openssh-9.0p1.orig/sftp.1 openssh-9.0p1/sftp.1 +--- openssh-9.0p1.orig/sftp.1 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/sftp.1 2022-08-30 20:23:49.903993113 +0200 @@ -295,7 +295,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed @@ -2151,9 +2143,9 @@ diff -Nur openssh-8.8p1.orig/sftp.1 openssh-8.8p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -diff -Nur openssh-8.8p1.orig/sftp-client.c openssh-8.8p1/sftp-client.c ---- openssh-8.8p1.orig/sftp-client.c 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/sftp-client.c 2021-12-01 16:51:00.937474156 +0100 +diff -Nur openssh-9.0p1.orig/sftp-client.c openssh-9.0p1/sftp-client.c +--- openssh-9.0p1.orig/sftp-client.c 2022-08-30 20:22:42.417819836 +0200 ++++ openssh-9.0p1/sftp-client.c 2022-08-30 20:23:49.904993115 +0200 @@ -72,7 +72,7 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -2163,9 +2155,9 @@ diff -Nur openssh-8.8p1.orig/sftp-client.c openssh-8.8p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-8.8p1.orig/ssh_api.c openssh-8.8p1/ssh_api.c ---- openssh-8.8p1.orig/ssh_api.c 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/ssh_api.c 2021-12-01 16:51:00.938474158 +0100 +diff -Nur openssh-9.0p1.orig/ssh_api.c openssh-9.0p1/ssh_api.c +--- openssh-9.0p1.orig/ssh_api.c 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/ssh_api.c 2022-08-30 20:23:49.904993115 +0200 @@ -410,7 +410,7 @@ char *cp; int r; @@ -2175,9 +2167,9 @@ diff -Nur openssh-8.8p1.orig/ssh_api.c openssh-8.8p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-8.8p1.orig/sshbuf.h openssh-8.8p1/sshbuf.h ---- openssh-8.8p1.orig/sshbuf.h 2021-09-26 16:03:19.000000000 +0200 -+++ openssh-8.8p1/sshbuf.h 2021-12-01 16:51:00.938474158 +0100 +diff -Nur openssh-9.0p1.orig/sshbuf.h openssh-9.0p1/sshbuf.h +--- openssh-9.0p1.orig/sshbuf.h 2022-04-06 02:47:48.000000000 +0200 ++++ openssh-9.0p1/sshbuf.h 2022-08-30 20:23:49.905993118 +0200 @@ -28,7 +28,7 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2187,10 +2179,10 @@ diff -Nur openssh-8.8p1.orig/sshbuf.h openssh-8.8p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c ---- openssh-8.8p1.orig/ssh.c 2021-12-01 16:50:22.521385581 +0100 -+++ openssh-8.8p1/ssh.c 2021-12-01 16:51:00.939474160 +0100 -@@ -1057,6 +1057,10 @@ +diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c +--- openssh-9.0p1.orig/ssh.c 2022-08-30 20:22:42.475819985 +0200 ++++ openssh-9.0p1/ssh.c 2022-08-30 20:23:49.906993121 +0200 +@@ -1065,6 +1065,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -2201,7 +2193,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1785,6 +1789,8 @@ +@@ -1801,6 +1805,8 @@ setproctitle("%s [mux]", options.control_path); } @@ -2210,7 +2202,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) -@@ -2103,6 +2109,79 @@ +@@ -2118,6 +2124,79 @@ NULL, fileno(stdin), command, environ); } @@ -2290,7 +2282,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2121,9 +2200,11 @@ +@@ -2136,9 +2215,11 @@ if (in == -1 || out == -1 || err == -1) fatal("dup() in/out/err failed"); @@ -2303,7 +2295,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2134,6 +2215,11 @@ +@@ -2149,6 +2230,11 @@ debug3_f("channel_new: %d", c->self); @@ -2315,7 +2307,7 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c channel_send_open(ssh, c->self); if (options.session_type != SESSION_TYPE_NONE) channel_register_open_confirm(ssh, c->self, -@@ -2148,6 +2234,13 @@ +@@ -2163,6 +2249,13 @@ int r, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -2329,9 +2321,9 @@ diff -Nur openssh-8.8p1.orig/ssh.c openssh-8.8p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c ---- openssh-8.8p1.orig/sshconnect2.c 2021-12-01 16:50:22.523385586 +0100 -+++ openssh-8.8p1/sshconnect2.c 2021-12-01 16:51:00.940474162 +0100 +diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c +--- openssh-9.0p1.orig/sshconnect2.c 2022-08-30 20:22:42.477819991 +0200 ++++ openssh-9.0p1/sshconnect2.c 2022-08-30 20:23:49.907993123 +0200 @@ -86,6 +86,13 @@ extern Options options; @@ -2346,7 +2338,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c * SSH2 key exchange */ -@@ -212,6 +219,8 @@ +@@ -216,6 +223,8 @@ return ret; } @@ -2355,7 +2347,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c void ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, const struct ssh_conn_info *cinfo) -@@ -225,6 +234,10 @@ +@@ -231,6 +240,10 @@ char *gss_host = NULL; #endif @@ -2366,7 +2358,7 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -569,6 +582,53 @@ +@@ -583,6 +596,53 @@ if (!authctxt.success) fatal("Authentication failed."); @@ -2420,9 +2412,9 @@ diff -Nur openssh-8.8p1.orig/sshconnect2.c openssh-8.8p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-8.8p1.orig/sshconnect.c openssh-8.8p1/sshconnect.c ---- openssh-8.8p1.orig/sshconnect.c 2021-12-01 16:50:22.434385381 +0100 -+++ openssh-8.8p1/sshconnect.c 2021-12-01 16:51:00.940474162 +0100 +diff -Nur openssh-9.0p1.orig/sshconnect.c openssh-9.0p1/sshconnect.c +--- openssh-9.0p1.orig/sshconnect.c 2022-08-30 20:22:42.325819600 +0200 ++++ openssh-9.0p1/sshconnect.c 2022-08-30 20:23:49.909993128 +0200 @@ -345,6 +345,30 @@ #endif @@ -2464,10 +2456,10 @@ diff -Nur openssh-8.8p1.orig/sshconnect.c openssh-8.8p1/sshconnect.c /* Use interactive QOS (if specified) until authentication completed */ if (options.ip_qos_interactive != INT_MAX) set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c ---- openssh-8.8p1.orig/sshd.c 2021-12-01 16:50:22.524385588 +0100 -+++ openssh-8.8p1/sshd.c 2021-12-01 16:51:00.941474165 +0100 -@@ -1110,6 +1110,8 @@ +diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c +--- openssh-9.0p1.orig/sshd.c 2022-08-30 20:22:42.478819993 +0200 ++++ openssh-9.0p1/sshd.c 2022-08-30 20:23:49.910993131 +0200 +@@ -1106,6 +1106,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2476,7 +2468,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1155,6 +1157,11 @@ +@@ -1151,6 +1153,11 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -2488,7 +2480,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1854,6 +1861,19 @@ +@@ -1857,6 +1864,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2508,7 +2500,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && -@@ -2301,6 +2321,9 @@ +@@ -2311,6 +2331,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -2518,7 +2510,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -2413,6 +2436,25 @@ +@@ -2423,6 +2446,25 @@ /* Try to send all our hostkeys to the client */ notify_hostkeys(ssh); @@ -2544,7 +2536,7 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c /* Start session. */ do_authenticated(ssh, authctxt); -@@ -2486,6 +2528,11 @@ +@@ -2498,6 +2540,11 @@ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; int r; @@ -2556,9 +2548,9 @@ diff -Nur openssh-8.8p1.orig/sshd.c openssh-8.8p1/sshd.c myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = -diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config ---- openssh-8.8p1.orig/sshd_config 2021-12-01 16:50:22.524385588 +0100 -+++ openssh-8.8p1/sshd_config 2021-12-01 16:51:00.941474165 +0100 +diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config +--- openssh-9.0p1.orig/sshd_config 2022-08-30 20:22:42.478819993 +0200 ++++ openssh-9.0p1/sshd_config 2022-08-30 20:23:49.911993133 +0200 @@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2588,9 +2580,9 @@ diff -Nur openssh-8.8p1.orig/sshd_config openssh-8.8p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-8.8p1.orig/version.h openssh-8.8p1/version.h ---- openssh-8.8p1.orig/version.h 2021-12-01 16:50:22.525385590 +0100 -+++ openssh-8.8p1/version.h 2021-12-01 16:51:00.941474165 +0100 +diff -Nur openssh-9.0p1.orig/version.h openssh-9.0p1/version.h +--- openssh-9.0p1.orig/version.h 2022-08-30 20:22:42.480819998 +0200 ++++ openssh-9.0p1/version.h 2022-08-30 20:23:49.911993133 +0200 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" From 05c1b1980c7ca7460b19687a16ca6973320a7768 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 1 Sep 2022 16:16:32 +0200 Subject: [PATCH 109/146] Update sources file --- sources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources b/sources index 1dadfbc..82d7797 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-8.8p1.tar.gz) = d44cd04445f9c8963513b0d5a7e8348985114ff2471e119a6e344498719ef40f09c61c354888a3be9dabcb5870e5cbe5d3aafbb861dfa1d82a4952f3d233a8df -SHA512 (openssh-8.8p1.tar.gz.asc) = 165e025305902f884d04d4444fa3143e4ea1a25a1c65aafe05e113537b3d3e50f7cd5f818bc2ca3404699372ca78f69c46b7452faf2d3998c448a5b80a411ae4 +SHA512 (openssh-9.0p1.tar.gz) = 613ae95317e734868c6a60d9cc5af47a889baa3124bbdd2b31bb51dd6b57b136f4cfcb5604cca78a03bd500baab9b9b45eaf77e038b1ed776c86dce0437449a9 +SHA512 (openssh-9.0p1.tar.gz.asc) = 7b1445764058435d2fa8a9c7553643983650d4232036c088e46e44beeb538d32cba88f775b1be9da5f21a01d6caea59b3dc4714507781e9cb946546fa54f169f SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From a8b9dae4de38ea46bf133295cf1e486d1a0fc1cd Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 8 Oct 2022 09:55:00 +0200 Subject: [PATCH 110/146] Based on openssh-9.0p1-6.fc38 --- gsi-openssh-server-systemd-sysusers.conf | 2 + gsi-openssh-systemd-sysusers.conf | 2 + gsi-openssh.spec | 22 +- openssh-8.7p1-minrsabits.patch | 256 ++++++++++++----------- openssh-8.7p1-ssh-manpage.patch | 4 +- openssh-9.0p1-hpn-15.2-modified.patch | 4 +- 6 files changed, 151 insertions(+), 139 deletions(-) create mode 100644 gsi-openssh-server-systemd-sysusers.conf create mode 100644 gsi-openssh-systemd-sysusers.conf diff --git a/gsi-openssh-server-systemd-sysusers.conf b/gsi-openssh-server-systemd-sysusers.conf new file mode 100644 index 0000000..419c529 --- /dev/null +++ b/gsi-openssh-server-systemd-sysusers.conf @@ -0,0 +1,2 @@ +#Type Name ID GECOS Home directory Shell +u sshd 74 "Privilege-separated SSH" /usr/share/empty.sshd - diff --git a/gsi-openssh-systemd-sysusers.conf b/gsi-openssh-systemd-sysusers.conf new file mode 100644 index 0000000..1192c0b --- /dev/null +++ b/gsi-openssh-systemd-sysusers.conf @@ -0,0 +1,2 @@ +#Type Name ID +g ssh_keys 101 diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 4c83205..352c093 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -10,10 +10,6 @@ %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 @@ -28,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.0p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -48,6 +44,8 @@ Source11: gsisshd.service Source12: gsisshd-keygen@.service Source13: gsisshd-keygen Source15: gsisshd-keygen.target +Source18: %{name}-systemd-sysusers.conf +Source19: %{name}-server-systemd-sysusers.conf Source99: README.sshd-and-gsisshd #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 @@ -459,6 +457,8 @@ 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 %{SOURCE18} $RPM_BUILD_ROOT%{_sysusersdir}/%{name}.conf +install -p -D -m 0644 %{SOURCE19} $RPM_BUILD_ROOT%{_sysusersdir}/%{name}-server.conf rm $RPM_BUILD_ROOT%{_bindir}/ssh-add rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent @@ -481,13 +481,10 @@ done perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %pre -getent group ssh_keys >/dev/null || groupadd -r -g 101 ssh_keys || : +%sysusers_create_compat %{SOURCE18} %pre server -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 /usr/share/empty.sshd sshd 2> /dev/null || : +%sysusers_create_compat %{SOURCE19} %post server %systemd_post gsisshd.service gsisshd.socket @@ -508,6 +505,7 @@ getent passwd sshd >/dev/null || \ %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* +%attr(0644,root,root) %{_sysusersdir}/%{name}.conf %files clients %attr(0755,root,root) %{_bindir}/gsissh @@ -540,8 +538,12 @@ getent passwd sshd >/dev/null || \ %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 %changelog +* Tue Oct 04 2022 Mattias Ellert - 9.0p1-2 +- Based on openssh-9.0p1-5.fc38 + * Tue Aug 30 2022 Mattias Ellert - 9.0p1-1 - Based on openssh-9.0p1-3.fc38 diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index 259129f..ad91fe7 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -1,184 +1,188 @@ diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 2ab222ed6..4e9437912 100644 +index 36b9d2f5..6b517db4 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c -@@ -118,6 +118,10 @@ userauth_hostbased(struct ssh *ssh, const char *method) +@@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method) "(null)" : key->cert->signature_type); goto done; } -+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { -+ logit("refusing %s key", sshkey_type(key)); ++ if ((r = sshkey_check_rsa_length(key, ++ options.required_rsa_size)) != 0) { ++ logit_r(r, "refusing %s key", sshkey_type(key)); + goto done; + } if (!authctxt->valid || authctxt->user == NULL) { debug2_f("disabled because of invalid user"); diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index daa756a01..68e7dea1f 100644 +index 962fd342..5d59febc 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -172,6 +172,10 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method) "(null)" : key->cert->signature_type); goto done; } -+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { -+ logit("refusing %s key", sshkey_type(key)); ++ if ((r = sshkey_check_rsa_length(key, ++ options.required_rsa_size)) != 0) { ++ logit_r(r, "refusing %s key", sshkey_type(key)); + goto done; + } key_s = format_key(key); if (sshkey_is_cert(key)) ca_s = format_key(key->cert->signature_key); diff --git a/readconf.c b/readconf.c -index 5b5afa8e3..5e17abd41 100644 +index 7f26c680..42be690b 100644 --- a/readconf.c +++ b/readconf.c -@@ -160,7 +160,7 @@ typedef enum { +@@ -174,7 +174,7 @@ typedef enum { oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, - oSecurityKeyProvider, oKnownHostsCommand, -+ oSecurityKeyProvider, oKnownHostsCommand, oRSAMinSize, ++ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; -@@ -306,6 +306,7 @@ static struct { +@@ -320,6 +320,8 @@ static struct { { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, -+ { "rsaminsize", oRSAMinSize }, ++ { "requiredrsasize", oRequiredRSASize }, ++ { "rsaminsize", oRequiredRSASize }, /* alias */ { NULL, oBadOption } }; -@@ -2162,6 +2163,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, +@@ -2176,6 +2177,10 @@ parse_pubkey_algos: *charptr = xstrdup(arg); break; -+ case oRSAMinSize: -+ intptr = &options->rsa_min_size; ++ case oRequiredRSASize: ++ intptr = &options->required_rsa_size; + goto parse_int; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); -@@ -2409,6 +2414,7 @@ initialize_options(Options * options) +@@ -2423,6 +2428,7 @@ initialize_options(Options * options) options->hostbased_accepted_algos = NULL; options->pubkey_accepted_algos = NULL; options->known_hosts_command = NULL; -+ options->rsa_min_size = -1; ++ options->required_rsa_size = -1; } /* -@@ -2598,6 +2604,8 @@ fill_default_options(Options * options) +@@ -2619,6 +2625,8 @@ fill_default_options(Options * options) if (options->sk_provider == NULL) options->sk_provider = xstrdup("$SSH_SK_PROVIDER"); #endif -+ if (options->rsa_min_size == -1) -+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE; ++ if (options->required_rsa_size == -1) ++ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; /* Expand KEX name lists */ all_cipher = cipher_alg_list(',', 0); -@@ -3287,6 +3295,7 @@ dump_client_config(Options *o, const char *host) +@@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); dump_cfg_int(oServerAliveInterval, o->server_alive_interval); -+ dump_cfg_int(oRSAMinSize, o->rsa_min_size); ++ dump_cfg_int(oRequiredRSASize, o->required_rsa_size); /* String options */ dump_cfg_string(oBindAddress, o->bind_address); diff --git a/readconf.h b/readconf.h -index f647bd42a..29db353ab 100644 +index f647bd42..ffb5ec4f 100644 --- a/readconf.h +++ b/readconf.h @@ -176,6 +176,8 @@ typedef struct { char *known_hosts_command; -+ int rsa_min_size; /* minimum size of RSA keys */ ++ int required_rsa_size; /* minimum size of RSA keys */ + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; diff --git a/servconf.c b/servconf.c -index f7317a5cb..362ff5b67 100644 +index 29df0463..423772b1 100644 --- a/servconf.c +++ b/servconf.c -@@ -177,6 +177,7 @@ initialize_server_options(ServerOptions *options) +@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options) options->fingerprint_hash = -1; options->disable_forwarding = -1; options->expose_userauth_info = -1; -+ options->rsa_min_size = -1; ++ options->required_rsa_size = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -416,6 +417,8 @@ fill_default_server_options(ServerOptions *options) +@@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options) options->expose_userauth_info = 0; if (options->sk_provider == NULL) options->sk_provider = xstrdup("internal"); -+ if (options->rsa_min_size == -1) -+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE; ++ if (options->required_rsa_size == -1) ++ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; assemble_algorithms(options); -@@ -489,6 +492,7 @@ typedef enum { +@@ -517,6 +520,7 @@ typedef enum { sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, -+ sRSAMinSize, ++ sRequiredRSASize, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; -@@ -632,6 +636,7 @@ static struct { +@@ -676,6 +680,8 @@ static struct { { "rdomain", sRDomain, SSHCFG_ALL }, { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, -+ { "rsaminsize", sRSAMinSize, SSHCFG_ALL }, ++ { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, ++ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */ { NULL, sBadOption, 0 } }; -@@ -2377,6 +2382,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; -+ case sRSAMinSize: -+ intptr = &options->rsa_min_size; ++ case sRequiredRSASize: ++ intptr = &options->required_rsa_size; + goto parse_int; + case sDeprecated: case sIgnore: case sUnsupported: -@@ -2549,6 +2558,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -+ M_CP_INTOPT(rsa_min_size); ++ M_CP_INTOPT(required_rsa_size); /* * The bind_mask is a mode_t that may be unsigned, so we can't use -@@ -2810,6 +2820,7 @@ dump_config(ServerOptions *o) +@@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o) dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); -+ dump_cfg_int(sRSAMinSize, o->rsa_min_size); ++ dump_cfg_int(sRequiredRSASize, o->required_rsa_size); dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); /* formatted integer arguments */ diff --git a/servconf.h b/servconf.h -index 115db1e79..2e3486906 100644 +index 8a04463e..9346155c 100644 --- a/servconf.h +++ b/servconf.h -@@ -227,6 +227,7 @@ typedef struct { +@@ -229,6 +229,7 @@ typedef struct { int expose_userauth_info; u_int64_t timing_secret; char *sk_provider; -+ int rsa_min_size; /* minimum size of RSA keys */ ++ int required_rsa_size; /* minimum size of RSA keys */ } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/ssh.c b/ssh.c -index a926cc007..cd13fb879 100644 +index 559bf2af..25be53d5 100644 --- a/ssh.c +++ b/ssh.c -@@ -500,14 +500,22 @@ resolve_canonicalize(char **hostp, int port) +@@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port) } /* @@ -196,7 +200,7 @@ index a926cc007..cd13fb879 100644 + /* Check RSA keys size and discard if undersized */ + if (k != NULL && *k != NULL && + (r = sshkey_check_rsa_length(*k, -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + error_r(r, "load %s \"%s\"", message, path); + free(*k); + *k = NULL; @@ -204,26 +208,26 @@ index a926cc007..cd13fb879 100644 break; case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: -@@ -1565,7 +1573,7 @@ main(int ac, char **av) +@@ -1578,7 +1586,7 @@ main(int ac, char **av) if ((o) >= sensitive_data.nkeys) \ fatal_f("pubkey out of array bounds"); \ check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ - p, "pubkey"); \ + &(sensitive_data.keys[o]), p, "pubkey"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s key from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -1573,7 +1581,8 @@ main(int ac, char **av) + if (sensitive_data.keys[o] != NULL) \ + debug2("hostbased key %d: %s key from \"%s\"", o, \ + sshkey_ssh_name(sensitive_data.keys[o]), p); \ +@@ -1586,7 +1594,8 @@ main(int ac, char **av) #define L_CERT(p,o) do { \ if ((o) >= sensitive_data.nkeys) \ fatal_f("cert out of array bounds"); \ - check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \ + check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \ + &(sensitive_data.keys[o]), p, "cert"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s cert from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + if (sensitive_data.keys[o] != NULL) \ + debug2("hostbased key %d: %s cert from \"%s\"", o, \ + sshkey_ssh_name(sensitive_data.keys[o]), p); \ +@@ -2265,7 +2274,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); check_load(sshkey_load_public(filename, &public, NULL), @@ -232,7 +236,7 @@ index a926cc007..cd13fb879 100644 debug("identity file %s type %d", filename, public ? public->type : -1); free(options.identity_files[i]); -@@ -2263,7 +2272,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) continue; xasprintf(&cp, "%s-cert", filename); check_load(sshkey_load_public(cp, &public, NULL), @@ -241,7 +245,7 @@ index a926cc007..cd13fb879 100644 debug("identity file %s type %d", cp, public ? public->type : -1); if (public == NULL) { -@@ -2294,7 +2303,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) free(cp); check_load(sshkey_load_public(filename, &public, NULL), @@ -251,25 +255,27 @@ index a926cc007..cd13fb879 100644 public ? public->type : -1); free(options.certificate_files[i]); diff --git a/sshconnect2.c b/sshconnect2.c -index 67f8e0309..d050c1656 100644 +index f9bd19ea..58fe98db 100644 --- a/sshconnect2.c +++ b/sshconnect2.c -@@ -91,6 +91,10 @@ static const struct ssh_conn_info *xxx_conn_info; +@@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info; static int verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) { + int r; + -+ if ((r = sshkey_check_rsa_length(hostkey, options.rsa_min_size)) != 0) ++ if ((r = sshkey_check_rsa_length(hostkey, ++ options.required_rsa_size)) != 0) + fatal_r(r, "Bad server host key"); if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_conn_info) == -1) fatal("Host key verification failed."); -@@ -1762,6 +1762,12 @@ load_identity_file(Identity *id) +@@ -1606,6 +1611,13 @@ load_identity_file(Identity *id) private = NULL; quit = 1; } -+ if (r = sshkey_check_rsa_length(private, options.rsa_min_size) != 0) { ++ if (!quit && (r = sshkey_check_rsa_length(private, ++ options.required_rsa_size)) != 0) { + debug_fr(r, "Skipping key %s", id->filename); + sshkey_free(private); + private = NULL; @@ -278,12 +284,12 @@ index 67f8e0309..d050c1656 100644 if (!quit && private != NULL && id->agent_fd == -1 && !(id->key && id->isprivate)) maybe_add_key_to_agent(id->filename, private, comment, -@@ -1747,6 +1751,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) - /* list of keys supported by the agent */ - if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) { - for (j = 0; j < idlist->nkeys; j++) { +@@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) + /* list of keys supported by the agent */ + if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) { + for (j = 0; j < idlist->nkeys; j++) { + if ((r = sshkey_check_rsa_length(idlist->keys[j], -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + debug_fr(r, "ignoring %s agent key", + sshkey_ssh_name(idlist->keys[j])); + continue; @@ -292,15 +298,15 @@ index 67f8e0309..d050c1656 100644 TAILQ_FOREACH(id, &files, next) { /* diff --git a/sshd.c b/sshd.c -index d26eb86ae..5f36905a1 100644 +index 17eee9d8..395ef493 100644 --- a/sshd.c +++ b/sshd.c -@@ -1746,6 +1746,13 @@ main(int ac, char **av) +@@ -1870,6 +1870,13 @@ main(int ac, char **av) fatal_r(r, "Could not demote key: \"%s\"", options.host_key_files[i]); } + if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey, -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + error_fr(r, "Host key %s", options.host_key_files[i]); + sshkey_free(pubkey); + sshkey_free(key); @@ -310,10 +316,10 @@ index d26eb86ae..5f36905a1 100644 sensitive_data.host_pubkeys[i] = pubkey; diff --git a/sshkey.c b/sshkey.c -index 47864e6d8..8bad6bd99 100644 +index ed2b5dff..77093235 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -2319,18 +2319,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) +@@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) return ret; } @@ -344,7 +350,7 @@ index 47864e6d8..8bad6bd99 100644 static int sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, -@@ -2391,7 +2397,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, +@@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, goto out; } rsa_n = rsa_e = NULL; /* transferred */ @@ -353,7 +359,7 @@ index 47864e6d8..8bad6bd99 100644 goto out; #ifdef DEBUG_PK RSA_print_fp(stderr, key->rsa, 8); -@@ -3580,7 +3586,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) +@@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) goto out; } rsa_p = rsa_q = NULL; /* transferred */ @@ -362,7 +368,7 @@ index 47864e6d8..8bad6bd99 100644 goto out; if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) goto out; -@@ -4566,7 +4572,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, +@@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -372,10 +378,10 @@ index 47864e6d8..8bad6bd99 100644 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { diff --git a/sshkey.h b/sshkey.h -index 125cadb64..52e879456 100644 +index 094815e0..be254e6b 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -267,6 +267,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, +@@ -273,6 +273,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, struct sshkey **pubkeyp); @@ -384,57 +390,57 @@ index 125cadb64..52e879456 100644 int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); diff --git a/ssh.1 b/ssh.1 -index b4956aec..b1a40ebd 100644 +index b4956aec..e255b9b9 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -554,6 +554,7 @@ For full details of the options listed below, and their possible values, see - .It LogLevel - .It MACs - .It Match -+.It RSAMinSize - .It NoHostAuthenticationForLocalhost - .It NumberOfPasswordPrompts - .It PasswordAuthentication +@@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see + .It RemoteCommand + .It RemoteForward + .It RequestTTY ++.It RequiredRSASize + .It SendEnv + .It ServerAliveInterval + .It ServerAliveCountMax diff --git a/ssh_config.5 b/ssh_config.5 -index 24a46460..68771e4b 100644 +index 24a46460..d1ede18e 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -1322,6 +1322,10 @@ The argument to this keyword must be - or - .Cm no - (the default). -+.It Cm RSAMinSize -+Provides a minimal bits requirement for RSA keys when used for signature and -+verification but not for the key generation. The default value is 1024 and -+can't be reduced. - .It Cm NumberOfPasswordPrompts - Specifies the number of password prompts before giving up. - The argument to this keyword must be an integer. +@@ -1634,6 +1634,17 @@ and + .Fl T + flags for + .Xr ssh 1 . ++.It Cm RequiredRSASize ++Specifies the minimum RSA key size (in bits) that ++.Xr ssh 1 ++will accept. ++User authentication keys smaller than this limit will be ignored. ++Servers that present host keys smaller than this limit will cause the ++connection to be terminated. ++The default is ++.Cm 1024 ++bits. ++Note that this limit may only be raised from the default. + .It Cm RevokedHostKeys + Specifies revoked host public keys. + Keys listed in this file will be refused for host authentication. diff --git a/sshd_config.5 b/sshd_config.5 -index 867a747d..e08811ca 100644 +index 867a747d..f5a06637 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1266,6 +1266,10 @@ will refuse connection attempts with a probability of rate/100 (30%) - if there are currently start (10) unauthenticated connections. - The probability increases linearly and all connection attempts - are refused if the number of unauthenticated connections reaches full (60). -+.It Cm RSAMinSize -+Provides a minimal bits requirement for RSA keys when used for signature and -+verification but not for the key generation. The default value is 1024 and -+can't be reduced. - .It Cm ModuliFile - Specifies the - .Xr moduli 5 -diff --git a/sshkey.h b/sshkey.h -index 094815e0..2bb8cb90 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -286,6 +286,8 @@ int sshkey_private_serialize_maxsign(struct sshkey *key, - - void sshkey_sig_details_free(struct sshkey_sig_details *); - -+int ssh_set_rsa_min_bits(int minbits); -+ - #ifdef SSHKEY_INTERNAL - int ssh_rsa_sign(const struct sshkey *key, - u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, +@@ -1596,6 +1596,16 @@ is + .Cm default none , + which means that rekeying is performed after the cipher's default amount + of data has been sent or received and no time based rekeying is done. ++.It Cm RequiredRSASize ++Specifies the minimum RSA key size (in bits) that ++.Xr sshd 8 ++will accept. ++User and host-based authentication keys smaller than this limit will be ++refused. ++The default is ++.Cm 1024 ++bits. ++Note that this limit may only be raised from the default. + .It Cm RevokedKeys + Specifies revoked public keys file, or + .Cm none diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch index bd0bdb7..04e4c06 100644 --- a/openssh-8.7p1-ssh-manpage.patch +++ b/openssh-8.7p1-ssh-manpage.patch @@ -33,16 +33,16 @@ diff --color -ru a/ssh.1 b/ssh.1 +.It LogVerbose .It MACs .It Match - .It RSAMinSize + .It NoHostAuthenticationForLocalhost @@ -566,6 +571,8 @@ .It RemoteCommand .It RemoteForward .It RequestTTY +.It RevokedHostKeys +.It SecurityKeyProvider + .It RequiredRSASize .It SendEnv .It ServerAliveInterval - .It ServerAliveCountMax @@ -575,6 +582,7 @@ .It StreamLocalBindMask .It StreamLocalBindUnlink diff --git a/openssh-9.0p1-hpn-15.2-modified.patch b/openssh-9.0p1-hpn-15.2-modified.patch index 5700e43..24605cb 100644 --- a/openssh-9.0p1-hpn-15.2-modified.patch +++ b/openssh-9.0p1-hpn-15.2-modified.patch @@ -1683,8 +1683,8 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, @@ -337,6 +345,11 @@ - { "knownhostscommand", oKnownHostsCommand }, - { "rsaminsize", oRSAMinSize }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, From 06837d883b326eb5c42f43615bc54527db9e330b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 9 Nov 2022 13:47:29 +0100 Subject: [PATCH 111/146] Based on openssh-9.0p1-7.fc38 --- gsi-openssh.spec | 5 ++++- openssh-6.6p1-allow-ip-opts.patch | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 352c093..48a127a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.0p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -541,6 +541,9 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %attr(0644,root,root) %{_sysusersdir}/%{name}-server.conf %changelog +* Wed Nov 09 2022 Mattias Ellert - 9.0p1-3 +- Based on openssh-9.0p1-7.fc38 + * Tue Oct 04 2022 Mattias Ellert - 9.0p1-2 - Based on openssh-9.0p1-5.fc38 diff --git a/openssh-6.6p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch index 953d613..be8d340 100644 --- a/openssh-6.6p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -1,7 +1,7 @@ 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) +@@ -1507,12 +1507,32 @@ check_ip_options(struct ssh *ssh) if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, &option_size) >= 0 && option_size != 0) { @@ -21,11 +21,14 @@ diff -up openssh/sshd.c.ip-opts openssh/sshd.c + case 130: + case 133: + case 134: -+ i += opts[i + 1]; -+ break; ++ if (i + 1 < option_size && opts[i + 1] >= 2) { ++ i += opts[i + 1]; ++ break; ++ } ++ /* FALLTHROUGH */ + default: + /* Fail, fatally, if we detect either loose or strict -+ * source routing options. */ ++ * or incorrect source routing options. */ + text[0] = '\0'; + for (i = 0; i < option_size; i++) + snprintf(text + i*3, sizeof(text) - i*3, From 82ba7b5b8b4daf8b5c078c30aeb2bc57cdb88979 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 10 Jan 2023 20:54:37 +0100 Subject: [PATCH 112/146] Based on openssh-9.0p1-9.fc38 --- gsi-openssh.spec | 5 +- openssh-7.7p1-fips.patch | 98 ++++++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 48a127a..78deb92 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.0p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -541,6 +541,9 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %attr(0644,root,root) %{_sysusersdir}/%{name}-server.conf %changelog +* Tue Jan 10 2023 Mattias Ellert - 9.0p1-4 +- Based on openssh-9.0p1-9.fc38 + * Wed Nov 09 2022 Mattias Ellert - 9.0p1-3 - Based on openssh-9.0p1-7.fc38 diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 62468ac..d1e44b0 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,14 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c --- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200 ++++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 +@@ -36,6 +36,7 @@ + + #include + #include ++#include + + #include "dh.h" + #include "pathnames.h" @@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -54,8 +62,8 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c + #endif /* WITH_OPENSSL */ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h ---- openssh-8.6p1/dh.h.fips 2021-04-19 16:53:03.064577862 +0200 -+++ openssh-8.6p1/dh.h 2021-04-19 16:59:31.951616078 +0200 +--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200 ++++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200 @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); @@ -65,8 +73,16 @@ 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-04-19 16:53:03.058577815 +0200 -+++ openssh-8.6p1/kex.c 2021-04-19 16:53:03.065577869 +0200 +--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200 ++++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200 +@@ -39,6 +39,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + # ifdef HAVE_EVP_KDF_CTX_NEW_ID + # include @@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { @@ -81,12 +97,12 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c } diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c --- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/kexgexc.c 2021-04-19 16:53:03.065577869 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL -+#include ++#include #include #include @@ -152,8 +168,16 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c ---- openssh-8.6p1/readconf.c.fips 2021-04-19 16:53:02.999577362 +0200 -+++ openssh-8.6p1/readconf.c 2021-04-19 16:53:03.065577869 +0200 +--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #ifdef USE_SYSTEM_GLOB + # include + #else @@ -2538,11 +2538,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -177,8 +201,8 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c do { \ if ((r = kex_assemble_names(&options->what, \ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c ---- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-04-19 16:53:03.034577631 +0200 -+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-04-19 16:53:03.065577869 +0200 +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200 @@ -160,6 +160,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), @@ -190,8 +214,16 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco SC_DENY(__NR_openat, EACCES), #endif diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c ---- openssh-8.6p1/servconf.c.fips 2021-04-19 16:53:03.027577577 +0200 -+++ openssh-8.6p1/servconf.c 2021-04-19 16:53:03.066577877 +0200 +--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #ifdef HAVE_UTIL_H + #include + #endif @@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -215,13 +247,13 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c ---- openssh-8.6p1/ssh.c.fips 2021-04-19 16:53:03.038577662 +0200 -+++ openssh-8.6p1/ssh.c 2021-04-19 16:53:03.066577877 +0200 +--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200 @@ -77,6 +77,7 @@ #include #include #endif -+#include ++#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" @@ -237,13 +269,13 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c if (options.sk_provider != NULL && *options.sk_provider == '$' && strlen(options.sk_provider) > 1) { diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c ---- openssh-8.6p1/sshconnect2.c.fips 2021-04-19 16:53:03.055577792 +0200 -+++ openssh-8.6p1/sshconnect2.c 2021-04-19 16:53:03.066577877 +0200 +--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200 @@ -45,6 +45,8 @@ #include #endif -+#include ++#include + #include "openbsd-compat/sys-queue.h" @@ -318,8 +350,8 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c } #endif diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c ---- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200 -+++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200 +--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200 @@ -66,6 +66,7 @@ #endif #include @@ -332,7 +364,7 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c #include #include #include -+#include ++#include #include "openbsd-compat/openssl-compat.h" #endif @@ -389,13 +421,13 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c ---- openssh-8.6p1/sshkey.c.fips 2021-04-19 16:53:03.061577838 +0200 -+++ openssh-8.6p1/sshkey.c 2021-04-19 16:53:03.067577885 +0200 +--- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 @@ -34,6 +34,7 @@ #include #include #include -+#include ++#include #endif #include "crypto_api.h" @@ -480,8 +512,16 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c compat, detailsp); #ifdef WITH_XMSS diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c ---- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 -+++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 +--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + #include "openbsd-compat/openssl-compat.h" + #endif @@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } @@ -521,7 +561,7 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c #include #include #include -+#include ++#include #include "sshkey.h" #include "kex.h" @@ -607,7 +647,7 @@ diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c #include #include -+#include ++#include #include "log.h" #include "sshbuf.h" From 4e50d957c8363fc387ca938fe82a3f04872ef2ac Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 11:37:02 +0000 Subject: [PATCH 113/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 78deb92..9ffbe1b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -541,6 +541,9 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %attr(0644,root,root) %{_sysusersdir}/%{name}-server.conf %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 9.0p1-4.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Tue Jan 10 2023 Mattias Ellert - 9.0p1-4 - Based on openssh-9.0p1-9.fc38 From f21cbd932cde97351e5fea832caf6b93c2451567 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 12 Mar 2023 04:47:25 +0100 Subject: [PATCH 114/146] Based on openssh-9.0p1-12.fc38 --- gsi-openssh-systemd-sysusers.conf | 2 -- gsi-openssh.spec | 28 +++++++++++++----------- gsissh-host-keys-migration.sh | 36 +++++++++++++++++++++++++++++++ gsisshd-keygen | 3 +-- openssh-6.6p1-keyperm.patch | 31 -------------------------- 5 files changed, 53 insertions(+), 47 deletions(-) delete mode 100644 gsi-openssh-systemd-sysusers.conf create mode 100644 gsissh-host-keys-migration.sh delete mode 100644 openssh-6.6p1-keyperm.patch diff --git a/gsi-openssh-systemd-sysusers.conf b/gsi-openssh-systemd-sysusers.conf deleted file mode 100644 index 1192c0b..0000000 --- a/gsi-openssh-systemd-sysusers.conf +++ /dev/null @@ -1,2 +0,0 @@ -#Type Name ID -g ssh_keys 101 diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9ffbe1b..9e37b19 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,12 +24,12 @@ %global libedit 1 %global openssh_ver 9.0p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -44,8 +44,8 @@ Source11: gsisshd.service Source12: gsisshd-keygen@.service Source13: gsisshd-keygen Source15: gsisshd-keygen.target -Source18: %{name}-systemd-sysusers.conf Source19: %{name}-server-systemd-sysusers.conf +Source20: gsissh-host-keys-migration.sh Source99: README.sshd-and-gsisshd #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 @@ -67,8 +67,6 @@ 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 #? @@ -294,7 +292,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %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 @@ -457,8 +454,10 @@ 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 %{SOURCE18} $RPM_BUILD_ROOT%{_sysusersdir}/%{name}.conf install -p -D -m 0644 %{SOURCE19} $RPM_BUILD_ROOT%{_sysusersdir}/%{name}-server.conf +# Migration 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 rm $RPM_BUILD_ROOT%{_bindir}/ssh-add rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent @@ -480,13 +479,15 @@ done perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* -%pre -%sysusers_create_compat %{SOURCE18} - %pre server %sysusers_create_compat %{SOURCE19} %post server +if [ $1 -gt 1 ]; then + # In the case of an upgrade run the migration + # script for Fedora 38 to remove group ownership for host keys. + %{_libexecdir}/gsissh/ssh-host-keys-migration.sh +fi %systemd_post gsisshd.service gsisshd.socket %preun server @@ -503,9 +504,8 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %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(4755,root,root) %{_libexecdir}/gsissh/ssh-keysign %attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8* -%attr(0644,root,root) %{_sysusersdir}/%{name}.conf %files clients %attr(0755,root,root) %{_bindir}/gsissh @@ -539,8 +539,12 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %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(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Sat Mar 11 2023 Mattias Ellert - 9.0p1-5 +- Based on openssh-9.0p1-12.fc38 + * Thu Jan 19 2023 Fedora Release Engineering - 9.0p1-4.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/gsissh-host-keys-migration.sh b/gsissh-host-keys-migration.sh new file mode 100644 index 0000000..775cf39 --- /dev/null +++ b/gsissh-host-keys-migration.sh @@ -0,0 +1,36 @@ +#!/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" diff --git a/gsisshd-keygen b/gsisshd-keygen index af0a740..772550e 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -30,8 +30,7 @@ if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then fi # sanitize permissions -/usr/bin/chgrp ssh_keys $KEY -/usr/bin/chmod 640 $KEY +/usr/bin/chmod 600 $KEY /usr/bin/chmod 644 $KEY.pub if [[ -x /usr/sbin/restorecon ]]; then /usr/sbin/restorecon $KEY{,.pub} diff --git a/openssh-6.6p1-keyperm.patch b/openssh-6.6p1-keyperm.patch deleted file mode 100644 index 5e06940..0000000 --- a/openssh-6.6p1-keyperm.patch +++ /dev/null @@ -1,31 +0,0 @@ -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 - #include -+#include - #include - #include - #include -@@ -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("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); From b6fce45c3ea8ecb69a130a9c8dc93094c929065b Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 12 Apr 2023 13:22:12 +0200 Subject: [PATCH 115/146] C99 compatibility fixes Apply patches from the upstream portable OpenSSH project to fix C99 compatibility issues in the configure script. Related to: --- gsi-openssh.spec | 11 +++++++- openssh-configure-c99-1.patch | 26 +++++++++++++++++++ openssh-configure-c99-2.patch | 47 +++++++++++++++++++++++++++++++++++ openssh-configure-c99-3.patch | 41 ++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 openssh-configure-c99-1.patch create mode 100644 openssh-configure-c99-2.patch create mode 100644 openssh-configure-c99-3.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9e37b19..a93d8ba 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -182,6 +182,9 @@ Patch1004: openssh-8.7p1-gssapi-auth.patch # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch +Patch1007: openssh-configure-c99-1.patch +Patch1008: openssh-configure-c99-2.patch +Patch1009: openssh-configure-c99-3.patch # Fix issue with read-only ssh buffer during gssapi key exchange (#1938224) # https://github.com/openssh-gsskex/openssh-gsskex/pull/19 @@ -344,6 +347,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch1003 -p1 -b .mem-leak %patch1004 -p1 -b .gssapi-auth %patch1006 -p1 -b .negotiate-supported-algs +%patch1007 -p1 -b .configure-c99-1 +%patch1008 -p1 -b .configure-c99-2 +%patch1009 -p1 -b .configure-c99-3 %patch100 -p1 -b .coverity @@ -542,6 +548,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Wed Apr 12 2023 Florian Weimer - 9.0p1-5.1 +- C99 compatiblity fixes + * Sat Mar 11 2023 Mattias Ellert - 9.0p1-5 - Based on openssh-9.0p1-12.fc38 diff --git a/openssh-configure-c99-1.patch b/openssh-configure-c99-1.patch new file mode 100644 index 0000000..a2c69aa --- /dev/null +++ b/openssh-configure-c99-1.patch @@ -0,0 +1,26 @@ +commit 40b0a5eb6e3edfa2886b60c09c7803353b0cc7f5 +Author: Sam James +Date: Sun Nov 6 04:47:35 2022 +0000 + + configure.ac: Add include for openpty + + Another Clang 16ish fix (which makes -Wimplicit-function-declaration + an error by default). github PR#355. + + See: 2efd71da49b9cfeab7987058cf5919e473ff466b + See: be197635329feb839865fdc738e34e24afd1fca8 + +diff --git a/configure.ac b/configure.ac +index 1e77ecfc..1866aea5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2373,6 +2373,9 @@ if test ! -z "$check_for_openpty_ctty_bug"; then + #include + #include + #include ++#ifdef HAVE_PTY_H ++# include ++#endif + #include + #include + #include diff --git a/openssh-configure-c99-2.patch b/openssh-configure-c99-2.patch new file mode 100644 index 0000000..693e64f --- /dev/null +++ b/openssh-configure-c99-2.patch @@ -0,0 +1,47 @@ +commit 32fddb982fd61b11a2f218a115975a87ab126d43 +Author: Darren Tucker +Date: Mon Nov 7 10:39:01 2022 +1100 + + Fix setres*id checks to work with clang-16. + + glibc has the prototypes for setresuid and setresgid behind _GNU_SOURCE, + and clang 16 will error out on implicit function definitions, so add + _GNU_SOURCE and the required headers to the configure checks. From + sam at @gentoo.org via bz#3497. + +diff --git a/configure.ac b/configure.ac +index 4bf758ac..e172540a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -863,7 +863,8 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + check_for_openpty_ctty_bug=1 + dnl Target SUSv3/POSIX.1-2001 plus BSD specifics. + dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE +- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE" ++ dnl _GNU_SOURCE is needed for setres*id prototypes. ++ CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE" + AC_DEFINE([BROKEN_CLOSEFROM], [1], [broken in chroots on older kernels]) + AC_DEFINE([PAM_TTY_KLUDGE], [1], + [Work around problematic Linux PAM modules handling of PAM_TTY]) +@@ -2168,8 +2169,9 @@ AC_CHECK_FUNCS([setresuid], [ + AC_MSG_CHECKING([if setresuid seems to work]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +-#include + #include ++#include ++#include + ]], [[ + errno=0; + setresuid(0,0,0); +@@ -2191,8 +2193,9 @@ AC_CHECK_FUNCS([setresgid], [ + AC_MSG_CHECKING([if setresgid seems to work]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +-#include + #include ++#include ++#include + ]], [[ + errno=0; + setresgid(0,0,0); diff --git a/openssh-configure-c99-3.patch b/openssh-configure-c99-3.patch new file mode 100644 index 0000000..48ab14a --- /dev/null +++ b/openssh-configure-c99-3.patch @@ -0,0 +1,41 @@ +commit 5eb796a369c64f18d55a6ae9b1fa9b35eea237fb +Author: Harmen Stoppels +Date: Thu Oct 13 16:08:46 2022 +0200 + + Fix snprintf configure test for clang 15 + + Clang 15 -Wimplicit-int defaults to an error in C99 mode and above. + A handful of tests have "main(..." and not "int main(..." which caused + the tests to produce incorrect results. + +diff --git a/configure.ac b/configure.ac +index de60a1b1..165c49de 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -713,7 +713,7 @@ case "$host" in + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include +-main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) ++int main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + exit(0); + else + exit(1); +@@ -4259,7 +4259,7 @@ dnl test snprintf (broken on SCO w/gcc) + #include + #include + #ifdef HAVE_SNPRINTF +-main() ++int main() + { + char buf[50]; + char expected_out[50]; +@@ -4276,7 +4276,7 @@ main() + exit(0); + } + #else +-main() { exit(0); } ++int main() { exit(0); } + #endif + ]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ], + AC_MSG_WARN([cross compiling: Assuming working snprintf()]) From 1b534648ec2e097cbc7ed90dba5e596bd7434fda Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 16 Apr 2023 05:19:44 +0200 Subject: [PATCH 116/146] Based on openssh-9.0p1-17.fc39 --- gsi-openssh.spec | 22 +- openssh-6.7p1-coverity.patch | 30 -- openssh-8.7p1-CVE-2023-25136.patch | 38 +++ openssh-8.7p1-nohostsha1proof.patch | 426 +++++++++++++++++++++++ openssh-9.0p1-audit-log.patch | 119 +++++++ openssh-9.0p1-evp-fips-dh.patch | 266 +++++++++++++++ openssh-9.0p1-evp-fips-ecdh.patch | 207 ++++++++++++ openssh-9.0p1-evp-fips-sign.patch | 468 ++++++++++++++++++++++++++ openssh-9.0p1-hpn-15.2-modified.patch | 4 +- 9 files changed, 1546 insertions(+), 34 deletions(-) create mode 100644 openssh-8.7p1-CVE-2023-25136.patch create mode 100644 openssh-8.7p1-nohostsha1proof.patch create mode 100644 openssh-9.0p1-audit-log.patch create mode 100644 openssh-9.0p1-evp-fips-dh.patch create mode 100644 openssh-9.0p1-evp-fips-ecdh.patch create mode 100644 openssh-9.0p1-evp-fips-sign.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a93d8ba..7f17562 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,12 +24,12 @@ %global libedit 1 %global openssh_ver 9.0p1 -%global openssh_rel 5 +%global openssh_rel 6 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -57,6 +57,8 @@ Patch100: openssh-6.7p1-coverity.patch Patch200: openssh-7.6p1-audit.patch # Audit race condition in forked child (#1310684) Patch201: openssh-7.1p2-audit-race-condition.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2049947 +Patch202: openssh-9.0p1-audit-log.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-7.8p1-role-mls.patch @@ -186,6 +188,13 @@ Patch1007: openssh-configure-c99-1.patch Patch1008: openssh-configure-c99-2.patch Patch1009: openssh-configure-c99-3.patch +Patch1010: openssh-8.7p1-CVE-2023-25136.patch + +Patch1011: openssh-9.0p1-evp-fips-sign.patch +Patch1012: openssh-9.0p1-evp-fips-dh.patch +Patch1013: openssh-9.0p1-evp-fips-ecdh.patch +Patch1014: openssh-8.7p1-nohostsha1proof.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 @@ -340,6 +349,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race +%patch202 -p1 -b .audit-log %patch700 -p1 -b .fips %patch1001 -p1 -b .scp-clears-file @@ -350,6 +360,11 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch1007 -p1 -b .configure-c99-1 %patch1008 -p1 -b .configure-c99-2 %patch1009 -p1 -b .configure-c99-3 +%patch1010 -p1 -b .cve-2023-25136 +%patch1011 -p1 -b .evp-fips-sign +%patch1012 -p1 -b .evp-fips-dh +%patch1013 -p1 -b .evp-fips-ecdh +%patch1014 -p1 -b .nosha1hostproof %patch100 -p1 -b .coverity @@ -548,6 +563,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Sun Apr 16 2023 Mattias Ellert - 9.0p1-6 +- Based on openssh-9.0p1-17.fc39 + * Wed Apr 12 2023 Florian Weimer - 9.0p1-5.1 - C99 compatiblity fixes diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 1923ac8..08d6b99 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -28,36 +28,6 @@ diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c return 0; } -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 -@@ -3804,7 +3804,7 @@ int - channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) - { - int r, success = 0, idx = -1; -- char *host_to_connect, *listen_host, *listen_path; -+ char *host_to_connect = NULL, *listen_host = NULL, *listen_path = NULL; - int port_to_connect, listen_port; - - /* Send the forward request to the remote side. */ -@@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct - success = 1; - if (success) { - /* Record that connection to this host/port is permitted. */ -- host_to_connect = listen_host = listen_path = NULL; - port_to_connect = listen_port = 0; - if (fwd->connect_path != NULL) { - host_to_connect = xstrdup(fwd->connect_path); -@@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct - host_to_connect, port_to_connect, - listen_host, listen_path, listen_port, NULL); - } -+ free(host_to_connect); -+ free(listen_host); -+ free(listen_path); - return idx; - } - diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c --- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 diff --git a/openssh-8.7p1-CVE-2023-25136.patch b/openssh-8.7p1-CVE-2023-25136.patch new file mode 100644 index 0000000..ca661ee --- /dev/null +++ b/openssh-8.7p1-CVE-2023-25136.patch @@ -0,0 +1,38 @@ +diff --git a/compat.c b/compat.c +index 46dfe3a9c2e..478a9403eea 100644 +--- a/compat.c ++++ b/compat.c +@@ -190,26 +190,26 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) + char * + compat_kex_proposal(struct ssh *ssh, char *p) + { +- char *cp = NULL; ++ char *cp = NULL, *cp2 = NULL; + + if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) + return xstrdup(p); + debug2_f("original KEX proposal: %s", p); + if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) +- if ((p = match_filter_denylist(p, ++ if ((cp = match_filter_denylist(p, + "curve25519-sha256@libssh.org")) == NULL) + fatal("match_filter_denylist failed"); + if ((ssh->compat & SSH_OLD_DHGEX) != 0) { +- cp = p; +- if ((p = match_filter_denylist(p, ++ if ((cp2 = match_filter_denylist(cp ? cp : p, + "diffie-hellman-group-exchange-sha256," + "diffie-hellman-group-exchange-sha1")) == NULL) + fatal("match_filter_denylist failed"); + free(cp); ++ cp = cp2; + } +- debug2_f("compat KEX proposal: %s", p); +- if (*p == '\0') ++ if (cp == NULL || *cp == '\0') + fatal("No supported key exchange algorithms found"); +- return p; ++ debug2_f("compat KEX proposal: %s", cp); ++ return cp; + } + diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch new file mode 100644 index 0000000..ab51204 --- /dev/null +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -0,0 +1,426 @@ +diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c +--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100 ++++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100 +@@ -43,6 +43,7 @@ void + compat_banner(struct ssh *ssh, const char *version) + { + int i; ++ int forbid_ssh_rsa = 0; + static struct { + char *pat; + int bugs; +@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha + }; + + /* process table, return first match */ ++ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA); + ssh->compat = 0; + for (i = 0; check[i].pat; i++) { + if (match_pattern_list(version, check[i].pat, 0) == 1) { + debug_f("match: %s pat %s compat 0x%08x", + version, check[i].pat, check[i].bugs); + ssh->compat = check[i].bugs; ++ if (forbid_ssh_rsa) ++ ssh->compat |= SSH_RH_RSASIGSHA; + return; + } + } + debug_f("no match: %s", version); ++ if (forbid_ssh_rsa) ++ ssh->compat |= SSH_RH_RSASIGSHA; + } + + /* Always returns pointer to allocated memory, caller must free. */ +diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h +--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100 +@@ -30,7 +30,7 @@ + #define SSH_BUG_UTF8TTYMODE 0x00000001 + #define SSH_BUG_SIGTYPE 0x00000002 + #define SSH_BUG_SIGTYPE74 0x00000004 +-/* #define unused 0x00000008 */ ++#define SSH_RH_RSASIGSHA 0x00000008 + #define SSH_OLD_SESSIONID 0x00000010 + /* #define unused 0x00000020 */ + #define SSH_BUG_DEBUG 0x00000040 +diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c +--- openssh-8.7p1/monitor.c.sshrsacheck 2023-01-20 13:07:54.279676981 +0100 ++++ openssh-8.7p1/monitor.c 2023-01-20 15:01:07.007821379 +0100 +@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock + struct sshkey *key; + struct sshbuf *sigbuf = NULL; + u_char *p = NULL, *signature = NULL; +- char *alg = NULL; ++ char *alg = NULL, *effective_alg; + size_t datlen, siglen, alglen; + int r, is_proof = 0; + u_int keyid, compat; + const char proof_req[] = "hostkeys-prove-00@openssh.com"; ++ const char safe_rsa[] = "rsa-sha2-256"; + + debug3_f("entering"); + +@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock + } + + if ((key = get_hostkey_by_index(keyid)) != NULL) { +- if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, ++ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0 ++ && (sshkey_type_plain(key->type) == KEY_RSA)) { ++ effective_alg = safe_rsa; ++ } else { ++ effective_alg = alg; ++ } ++ if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg, + options.sk_provider, NULL, compat)) != 0) + fatal_fr(r, "sign"); + } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && + auth_sock > 0) { ++ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0 ++ && (sshkey_type_plain(key->type) == KEY_RSA)) { ++ effective_alg = safe_rsa; ++ } else { ++ effective_alg = alg; ++ } + if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, +- p, datlen, alg, compat)) != 0) ++ p, datlen, effective_alg, compat)) != 0) + fatal_fr(r, "agent sign"); + } else + fatal_f("no hostkey from index %d", keyid); + +- debug3_f("%s %s signature len=%zu", alg, ++ debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg, + is_proof ? "hostkey proof" : "KEX", siglen); + + sshbuf_reset(m); +diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh +--- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck 2023-01-25 14:26:52.885963113 +0100 ++++ openssh-8.7p1/regress/cert-userkey.sh 2023-01-25 14:27:25.757219800 +0100 +@@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us + cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +-PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` ++#ssh-dss keys are incompatible with DEFAULT crypto policy ++PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` + EXTRA_TYPES="" + rsa="" + +diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile +--- openssh-8.7p1/regress/Makefile.sshrsacheck 2023-01-20 13:07:54.169676051 +0100 ++++ openssh-8.7p1/regress/Makefile 2023-01-20 13:07:54.290677074 +0100 +@@ -2,7 +2,8 @@ + + tests: prep file-tests t-exec unit + +-REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 ++#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping ++REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12 + + # File based tests + file-tests: $(REGRESS_TARGETS) +diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh +--- openssh-8.7p1/regress/test-exec.sh.sshrsacheck 2023-01-25 14:24:54.778040819 +0100 ++++ openssh-8.7p1/regress/test-exec.sh 2023-01-25 14:26:39.500858590 +0100 +@@ -581,8 +581,9 @@ maybe_filter_sk() { + fi + } + +-SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk` +-SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk` ++#ssh-dss keys are incompatible with DEFAULT crypto policy ++SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'` ++SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'` + + for t in ${SSH_KEYTYPES}; do + # generate user key +diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c +--- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100 ++++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100 +@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, + memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); + if (kex != NULL) + kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; +- keyname = strdup(sshkey_ssh_name(private)); ++ keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ? ++ strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256"); + ASSERT_PTR_NE(keyname, NULL); + kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; + ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); +@@ -180,7 +181,7 @@ do_kex(char *kex) + { + #ifdef WITH_OPENSSL + do_kex_with_key(kex, KEY_RSA, 2048); +- do_kex_with_key(kex, KEY_DSA, 1024); ++ /* do_kex_with_key(kex, KEY_DSA, 1024); */ + #ifdef OPENSSL_HAS_ECC + do_kex_with_key(kex, KEY_ECDSA, 256); + #endif /* OPENSSL_HAS_ECC */ +diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c +--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100 +@@ -110,6 +110,7 @@ sshkey_file_tests(void) + sshkey_free(k2); + TEST_DONE(); + ++ /* Skip this test, SHA1 signatures are not supported + TEST_START("load RSA cert with SHA1 signature"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0); + ASSERT_PTR_NE(k2, NULL); +@@ -117,7 +118,7 @@ sshkey_file_tests(void) + ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); + ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa"); + sshkey_free(k2); +- TEST_DONE(); ++ TEST_DONE(); */ + + TEST_START("load RSA cert with SHA512 signature"); + ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0); +diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c +--- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck 2023-01-26 12:10:37.533168013 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c 2023-01-26 12:15:35.637631860 +0100 +@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void) + TEST_DONE(); + + #ifdef WITH_OPENSSL ++ /* Skip this test, SHA1 signatures are not supported + TEST_START("fuzz RSA sig"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1, "ssh-rsa"); + sshkey_free(k1); +- TEST_DONE(); ++ TEST_DONE();*/ + + TEST_START("fuzz RSA SHA256 sig"); + buf = load_file("rsa_1"); +@@ -357,6 +358,7 @@ sshkey_fuzz_tests(void) + sshkey_free(k1); + TEST_DONE(); + ++ /* Skip this test, SHA1 signatures are not supported + TEST_START("fuzz DSA sig"); + buf = load_file("dsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); +@@ -364,6 +366,7 @@ sshkey_fuzz_tests(void) + sig_fuzz(k1, NULL); + sshkey_free(k1); + TEST_DONE(); ++ */ + + #ifdef OPENSSL_HAS_ECC + TEST_START("fuzz ECDSA sig"); +diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c +--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100 +@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk + u_char *sigblob; + size_t siglen; + ++ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */ ++ int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0; ++ + ca_buf = sshbuf_new(); + ASSERT_PTR_NE(ca_buf, NULL); + ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); +@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk + ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ + ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ + ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, +- sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0); +- ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ ++ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected); ++ if (expected == 0) ++ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ + + free(sigblob); + sshbuf_free(ca_buf); +@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct + { + size_t len; + u_char *sig; ++ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */ ++ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0; ++ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT)) ++ expected = SSH_ERR_LIBCRYPTO_ERROR; + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, +- NULL, NULL, 0), 0); +- ASSERT_SIZE_T_GT(len, 8); +- ASSERT_PTR_NE(sig, NULL); +- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); +- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0); +- /* Fuzz test is more comprehensive, this is just a smoke test */ +- sig[len - 5] ^= 0x10; +- ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); ++ NULL, NULL, 0), expected); ++ if (expected == 0) { ++ ASSERT_SIZE_T_GT(len, 8); ++ ASSERT_PTR_NE(sig, NULL); ++ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); ++ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0); ++ /* Fuzz test is more comprehensive, this is just a smoke test */ ++ sig[len - 5] ^= 0x10; ++ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); ++ } + free(sig); + } + +@@ -514,7 +524,7 @@ sshkey_tests(void) + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, + NULL), 0); + k3 = get_private("rsa_1"); +- build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL); ++ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256"); + ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), + SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); + ASSERT_PTR_EQ(k4, NULL); +diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p1/regress/unittests/sshsig/tests.c +--- openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck 2023-01-26 12:19:23.659513651 +0100 ++++ openssh-8.7p1/regress/unittests/sshsig/tests.c 2023-01-26 12:20:28.021044803 +0100 +@@ -102,9 +102,11 @@ tests(void) + check_sig("rsa.pub", "rsa.sig", msg, namespace); + TEST_DONE(); + ++ /* Skip this test, SHA1 signatures are not supported + TEST_START("check DSA signature"); + check_sig("dsa.pub", "dsa.sig", msg, namespace); + TEST_DONE(); ++ */ + + #ifdef OPENSSL_HAS_ECC + TEST_START("check ECDSA signature"); +diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c +--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100 ++++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100 +@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * + else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) + sigalg = "rsa-sha2-256"; + } ++ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) { ++ sigalg = "rsa-sha2-512"; ++ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg); ++ } + debug3_f("sign %s key (index %d) using sigalg %s", + sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); + if ((r = sshbuf_put_cstring(sigbuf, +diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c +--- openssh-8.7p1/sshconnect2.c.sshrsacheck 2023-01-25 15:33:29.140353651 +0100 ++++ openssh-8.7p1/sshconnect2.c 2023-01-25 15:59:34.225364883 +0100 +@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha + retried = 1; + goto retry_pin; + } ++ if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) { ++ char rsa_safe_alg[] = "rsa-sha2-512"; ++ debug3_f("trying to fallback to algorithm %s", rsa_safe_alg); ++ ++ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen, ++ rsa_safe_alg, options.sk_provider, pin, compat)) != 0) ++ debug_fr(r, "sshkey_sign - RSA fallback"); ++ } + goto out; + } + +diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c +--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100 ++++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100 +@@ -1640,6 +1651,7 @@ main(int ac, char **av) + int keytype; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; ++ 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 -Nur openssh-8.7p1/ssh-keygen.c openssh-8.7p1_patched/ssh-keygen.c +--- openssh-8.7p1/ssh-keygen.c 2023-01-18 17:41:47.894515779 +0100 ++++ openssh-8.7p1_patched/ssh-keygen.c 2023-01-18 17:41:44.500488818 +0100 +@@ -491,6 +491,8 @@ + BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; + BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; + BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; ++ char rsa_safe_alg[] = "rsa-sha2-256"; ++ char *alg = NULL; + + if ((r = sshbuf_get_u32(b, &magic)) != 0) + fatal_fr(r, "parse magic"); +@@ -590,6 +592,7 @@ do_convert_private_ssh2(struct sshbuf *b + if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) + fatal_fr(r, "generate RSA parameters"); + BN_clear_free(rsa_iqmp); ++ alg = rsa_safe_alg; + break; + } + rlen = sshbuf_len(b); +@@ -598,9 +601,9 @@ do_convert_private_ssh2(struct sshbuf *b + + /* try the key */ + if (sshkey_sign(key, &sig, &slen, data, sizeof(data), +- NULL, NULL, NULL, 0) != 0 || ++ alg, NULL, NULL, 0) != 0 || + sshkey_verify(key, sig, slen, data, sizeof(data), +- NULL, 0, NULL) != 0) { ++ alg, 0, NULL) != 0) { + sshkey_free(key); + free(sig); + return NULL; +diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c +--- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100 ++++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100 +@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key, + ret = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +- if (hash_alg != want_alg) { ++ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) { ++ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg); + ret = SSH_ERR_SIGNATURE_INVALID; + goto out; + } diff --git a/openssh-9.0p1-audit-log.patch b/openssh-9.0p1-audit-log.patch new file mode 100644 index 0000000..fbf5094 --- /dev/null +++ b/openssh-9.0p1-audit-log.patch @@ -0,0 +1,119 @@ +diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c +--- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200 +@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + /* not implemented */ + } +diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c +--- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200 +@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) + void + audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) + { +- char *fp; ++ char *key_fp = NULL; ++ char *issuer_fp = NULL; ++ struct sshkey_cert *cert = NULL; + +- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); +- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { ++ cert = key->cert; ++ issuer_fp = sshkey_fingerprint(cert->signature_key, ++ options.fingerprint_hash, SSH_FP_DEFAULT); ++ } ++ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) + *rv = -SSH_ERR_INTERNAL_ERROR; +- free(fp); ++ if (key_fp) ++ free(key_fp); ++ if (issuer_fp) ++ free(issuer_fp); + } + + void +diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h +--- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200 +@@ -64,7 +64,7 @@ void audit_session_close(struct logininf + int audit_run_command(struct ssh *, const char *); + void audit_end_command(struct ssh *, int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); +-int audit_keyusage(struct ssh *, int, char *, int); ++int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); + void audit_key(struct ssh *, int, int *, const struct sshkey *); + void audit_unsupported(struct ssh *, int); + void audit_kex(struct ssh *, int, char *, char *, char *, char *); +diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c +--- openssh-9.0p1/audit-linux.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-linux.c 2022-10-24 15:21:58.165303951 +0200 +@@ -137,10 +137,12 @@ fatal_report: + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + char buf[AUDIT_LOG_SIZE]; + int audit_fd, rc, saved_errno; ++ const char *rip; ++ u_int i; + + audit_fd = audit_open(); + if (audit_fd < 0) { +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host + else + return 0; /* Must prevent login */ + } ++ rip = ssh_remote_ipaddr(ssh); + snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased"); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, +- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv); ++ buf, audit_username(), -1, NULL, rip, NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; +- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp); ++ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp); + rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL, +- ssh_remote_ipaddr(ssh), NULL, rv); ++ rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ if (cert) { ++ char *pbuf; ++ ++ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"", ++ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) { ++ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "principal %s", pbuf); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ } ++ } + out: + saved_errno = errno; + audit_close(audit_fd); diff --git a/openssh-9.0p1-evp-fips-dh.patch b/openssh-9.0p1-evp-fips-dh.patch new file mode 100644 index 0000000..7494245 --- /dev/null +++ b/openssh-9.0p1-evp-fips-dh.patch @@ -0,0 +1,266 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/dh.c ./dh.c +--- ../../openssh-8.7p1/dh.c 2023-03-01 14:26:52.504445780 +0100 ++++ ./dh.c 2023-03-01 14:20:09.823193384 +0100 +@@ -37,6 +37,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "dh.h" + #include "pathnames.h" +@@ -289,10 +292,15 @@ + int + dh_gen_key(DH *dh, int need) + { +- int pbits; +- const BIGNUM *dh_p, *pub_key; ++ const BIGNUM *dh_p, *dh_g; ++ BIGNUM *pub_key = NULL, *priv_key = NULL; ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++ int pbits, r = 0; + +- DH_get0_pqg(dh, &dh_p, NULL, NULL); ++ DH_get0_pqg(dh, &dh_p, NULL, &dh_g); + + if (need < 0 || dh_p == NULL || + (pbits = BN_num_bits(dh_p)) <= 0 || +@@ -300,19 +308,85 @@ + return SSH_ERR_INVALID_ARGUMENT; + if (need < 256) + need = 256; ++ ++ if ((param_bld = OSSL_PARAM_BLD_new()) == NULL || ++ (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) { ++ OSSL_PARAM_BLD_free(param_bld); ++ return SSH_ERR_ALLOC_FAIL; ++ } ++ ++ if (OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 || ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) { ++ error_f("Could not set p,q,g parameters"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + /* + * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), + * so double requested need here. + */ +- if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1))) +- return SSH_ERR_LIBCRYPTO_ERROR; +- +- if (DH_generate_key(dh) == 0) +- return SSH_ERR_LIBCRYPTO_ERROR; +- DH_get0_key(dh, &pub_key, NULL); +- if (!dh_pub_is_valid(dh, pub_key)) +- return SSH_ERR_INVALID_FORMAT; +- return 0; ++ if (OSSL_PARAM_BLD_push_int(param_bld, ++ OSSL_PKEY_PARAM_DH_PRIV_LEN, ++ MINIMUM(need * 2, pbits - 1)) != 1 || ++ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (EVP_PKEY_fromdata_init(ctx) != 1) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (EVP_PKEY_fromdata(ctx, &pkey, ++ EVP_PKEY_KEY_PARAMETERS, params) != 1) { ++ error_f("Failed key generation"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* reuse context for key generation */ ++ EVP_PKEY_CTX_free(ctx); ++ ctx = NULL; ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL || ++ EVP_PKEY_keygen_init(ctx) != 1) { ++ error_f("Could not create or init context"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (EVP_PKEY_generate(ctx, &pkey) != 1) { ++ error_f("Could not generate keys"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (EVP_PKEY_public_check(ctx) != 1) { ++ error_f("The public key is incorrect"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, ++ &pub_key) != 1 || ++ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, ++ &priv_key) != 1 || ++ DH_set0_key(dh, pub_key, priv_key) != 1) { ++ error_f("Could not set pub/priv keys to DH struct"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* transferred */ ++ pub_key = NULL; ++ priv_key = NULL; ++out: ++ OSSL_PARAM_free(params); ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(pkey); ++ BN_clear_free(pub_key); ++ BN_clear_free(priv_key); ++ return r; + } + + DH * +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kex.c ./kex.c +--- ../../openssh-8.7p1/kex.c 2023-03-01 14:26:52.508445832 +0100 ++++ ./kex.c 2023-02-28 14:09:27.164743771 +0100 +@@ -1602,3 +1602,47 @@ + return r; + } + ++#ifdef WITH_OPENSSL ++/* ++ * Creates an EVP_PKEY from the given parameters and keys. ++ * The private key can be omitted. ++ */ ++int ++kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q, ++ const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ int r = 0; ++ ++ /* create EVP_PKEY-DH key */ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ error_f("EVP_PKEY_CTX or PARAM_BLD init failed"); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 || ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 || ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 || ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) { ++ error_f("Failed pushing params to OSSL_PARAM_BLD"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (priv != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) { ++ error_f("Failed pushing private key to OSSL_PARAM_BLD"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ return r; ++} ++#endif /* WITH_OPENSSL */ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kexdh.c ./kexdh.c +--- ../../openssh-8.7p1/kexdh.c 2023-03-01 14:26:52.448445050 +0100 ++++ ./kexdh.c 2023-02-28 14:05:00.700902124 +0100 +@@ -35,6 +35,9 @@ + + #include "openbsd-compat/openssl-compat.h" + #include ++#include ++#include ++#include + + #include "sshkey.h" + #include "kex.h" +@@ -83,6 +86,9 @@ + 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; +@@ -106,18 +112,39 @@ + 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) { ++ ++ DH_get0_key(kex->dh, &pub, &priv); ++ DH_get0_pqg(kex->dh, &p, &q, &g); ++ /* import key */ ++ kex_create_evp_dh(&pkey, p, q, g, pub, priv); ++ /* import peer key ++ * the parameters should be the same as with pkey ++ */ ++ kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL); ++ ++ 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, kbuf, &klen) != 1 || ++ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { ++ error_f("Could not derive key"); + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + #ifdef DEBUG_KEXDH +- dump_digest("shared secret", kbuf, kout); ++ dump_digest("shared secret", kbuf, klen); + #endif + r = sshbuf_put_bignum2(out, shared_secret); + out: + freezero(kbuf, klen); + BN_clear_free(shared_secret); ++ EVP_PKEY_free(pkey); ++ EVP_PKEY_free(dh_pkey); ++ EVP_PKEY_CTX_free(ctx); + return r; + } + +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kex.h ./kex.h +--- ../../openssh-8.7p1/kex.h 2023-03-01 14:26:52.508445832 +0100 ++++ ./kex.h 2023-02-28 13:16:49.811047554 +0100 +@@ -33,6 +33,9 @@ + # include + # include + # include ++# include ++# include ++# include + # ifdef OPENSSL_HAS_ECC + # include + # else /* OPENSSL_HAS_ECC */ +@@ -278,6 +281,8 @@ + const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); ++int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *, ++ const BIGNUM *, const BIGNUM *, const BIGNUM *); + + #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) + void dump_digest(const char *, const u_char *, int); diff --git a/openssh-9.0p1-evp-fips-ecdh.patch b/openssh-9.0p1-evp-fips-ecdh.patch new file mode 100644 index 0000000..0313c6f --- /dev/null +++ b/openssh-9.0p1-evp-fips-ecdh.patch @@ -0,0 +1,207 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c +--- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200 ++++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200 +@@ -35,17 +35,57 @@ + #include + + #include ++#include ++#include ++#include ++#include + + #include "sshkey.h" + #include "kex.h" + #include "sshbuf.h" + #include "digest.h" + #include "ssherr.h" ++#include "log.h" + + static int + kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, + const EC_GROUP *, struct sshbuf **); + ++static EC_KEY * ++generate_ec_keys(int ec_nid) ++{ ++ EC_KEY *client_key = NULL; ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++ const char *group_name; ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) ++ goto out; ++ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL || ++ OSSL_PARAM_BLD_push_utf8_string(param_bld, ++ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 || ++ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { ++ error_f("Could not create OSSL_PARAM"); ++ goto out; ++ } ++ if (EVP_PKEY_keygen_init(ctx) != 1 || ++ EVP_PKEY_CTX_set_params(ctx, params) != 1 || ++ EVP_PKEY_generate(ctx, &pkey) != 1 || ++ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) { ++ error_f("Could not generate ec keys"); ++ goto out; ++ } ++out: ++ EVP_PKEY_free(pkey); ++ EVP_PKEY_CTX_free(ctx); ++ OSSL_PARAM_BLD_free(param_bld); ++ OSSL_PARAM_free(params); ++ return client_key; ++} ++ + int + kex_ecdh_keypair(struct kex *kex) + { +@@ -55,11 +95,7 @@ + struct sshbuf *buf = NULL; + int r; + +- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { +- r = SSH_ERR_ALLOC_FAIL; +- goto out; +- } +- if (EC_KEY_generate_key(client_key) != 1) { ++ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +@@ -101,11 +137,7 @@ + *server_blobp = NULL; + *shared_secretp = NULL; + +- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { +- r = SSH_ERR_ALLOC_FAIL; +- goto out; +- } +- if (EC_KEY_generate_key(server_key) != 1) { ++ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +@@ -140,11 +172,21 @@ + { + struct sshbuf *buf = NULL; + BIGNUM *shared_secret = NULL; +- EC_POINT *dh_pub = NULL; +- u_char *kbuf = NULL; +- size_t klen = 0; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *pkey = NULL, *dh_pkey = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++ u_char *kbuf = NULL, *pub = NULL; ++ size_t klen = 0, publen; ++ const char *group_name; + int r; + ++ /* import EC_KEY to EVP_PKEY */ ++ if ((r = ssh_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) { ++ error_f("Could not create EVP_PKEY"); ++ goto out; ++ } ++ + *shared_secretp = NULL; + + if ((buf = sshbuf_new()) == NULL) { +@@ -153,45 +195,82 @@ + } + if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) + goto out; +- if ((dh_pub = EC_POINT_new(group)) == NULL) { ++ ++ /* the public key is in the buffer in octet string UNCOMPRESSED ++ * format. See sshbuf_put_ec */ ++ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0) ++ goto out; ++ sshbuf_reset(buf); ++ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) { ++ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (OSSL_PARAM_BLD_push_octet_string(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 || ++ OSSL_PARAM_BLD_push_utf8_string(param_bld, ++ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 || ++ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { ++ error_f("Failed to set params for dh_pkey"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (EVP_PKEY_fromdata_init(ctx) != 1 || ++ EVP_PKEY_fromdata(ctx, &dh_pkey, ++ EVP_PKEY_PUBLIC_KEY, params) != 1 || ++ EVP_PKEY_public_check(ctx) != 1) { ++ error_f("Peer public key import failed"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- sshbuf_reset(buf); + + #ifdef DEBUG_KEXECDH + fputs("public key:\n", stderr); +- sshkey_dump_ec_point(group, dh_pub); ++ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL); + #endif +- if (sshkey_ec_validate_public(group, dh_pub) != 0) { +- r = SSH_ERR_MESSAGE_INCOMPLETE; ++ EVP_PKEY_CTX_free(ctx); ++ ctx = NULL; ++ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL || ++ EVP_PKEY_derive_init(ctx) != 1 || ++ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 || ++ EVP_PKEY_derive(ctx, NULL, &klen) != 1) { ++ error_f("Failed to get derive information"); ++ r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- klen = (EC_GROUP_get_degree(group) + 7) / 8; +- if ((kbuf = malloc(klen)) == NULL || +- (shared_secret = BN_new()) == NULL) { ++ if ((kbuf = malloc(klen)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen || +- BN_bin2bn(kbuf, klen, shared_secret) == NULL) { ++ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + #ifdef DEBUG_KEXECDH + dump_digest("shared secret", kbuf, klen); + #endif ++ if ((shared_secret = BN_new()) == NULL || ++ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) { ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0) + goto out; + *shared_secretp = buf; + buf = NULL; + out: +- EC_POINT_clear_free(dh_pub); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(pkey); ++ EVP_PKEY_free(dh_pkey); ++ OSSL_PARAM_BLD_free(param_bld); ++ OSSL_PARAM_free(params); + BN_clear_free(shared_secret); + freezero(kbuf, klen); ++ freezero(pub, publen); + sshbuf_free(buf); + return r; + } diff --git a/openssh-9.0p1-evp-fips-sign.patch b/openssh-9.0p1-evp-fips-sign.patch new file mode 100644 index 0000000..fc71678 --- /dev/null +++ b/openssh-9.0p1-evp-fips-sign.patch @@ -0,0 +1,468 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-dss.c ./ssh-dss.c +--- ../../openssh-8.7p1/ssh-dss.c 2023-03-08 15:35:14.669943335 +0100 ++++ ./ssh-dss.c 2023-03-08 15:34:33.508578129 +0100 +@@ -32,6 +32,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -72,9 +74,8 @@ + sshkey_type_plain(key->type) != KEY_DSA) + return SSH_ERR_INVALID_ARGUMENT; + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) +- return SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) ++ return ret; + ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, + data, datalen); + EVP_PKEY_free(pkey); +@@ -201,11 +202,8 @@ + goto out; + } + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) { +- ret = SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) + goto out; +- } + ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen, + sigb, slen); + EVP_PKEY_free(pkey); +@@ -221,4 +219,63 @@ + freezero(sigblob, len); + return ret; + } ++ ++int ++ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; ++ int ret = 0; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ DSA_get0_pqg(k->dsa, &p, &q, &g); ++ DSA_get0_key(k->dsa, &pub, &priv); ++ ++ if (p != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (q != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (g != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (pub != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ pub) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (priv != 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); ++ return ret; ++} + #endif /* WITH_OPENSSL */ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-ecdsa.c ./ssh-ecdsa.c +--- ../../openssh-8.7p1/ssh-ecdsa.c 2023-03-08 15:35:14.669943335 +0100 ++++ ./ssh-ecdsa.c 2023-03-08 15:40:52.628201267 +0100 +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + + #include + +@@ -72,9 +74,8 @@ + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) + return SSH_ERR_INTERNAL_ERROR; + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) +- return SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) ++ return ret; + ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, + datalen); + EVP_PKEY_free(pkey); +@@ -193,11 +194,8 @@ + goto out; + } + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) { +- ret = SSH_ERR_ALLOC_FAIL; ++ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) + goto out; +- } + ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len); + EVP_PKEY_free(pkey); + +@@ -212,4 +210,76 @@ + return ret; + } + ++int ++ssh_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; ++} + #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.c ./sshkey.c +--- ../../openssh-8.7p1/sshkey.c 2023-03-08 15:35:14.702943628 +0100 ++++ ./sshkey.c 2023-03-08 15:39:03.354082015 +0100 +@@ -35,6 +35,8 @@ + #include + #include + #include ++#include ++#include + #endif + + #include "crypto_api.h" +@@ -492,13 +494,14 @@ + { + EVP_MD_CTX *ctx = NULL; + u_char *sig = NULL; +- int ret, slen, len; ++ int ret, slen; ++ size_t len; + + if (sigp == NULL || lenp == NULL) { + return SSH_ERR_INVALID_ARGUMENT; + } + +- slen = EVP_PKEY_size(pkey); ++ slen = EVP_PKEY_get_size(pkey); + if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) + return SSH_ERR_INVALID_ARGUMENT; + +@@ -511,9 +514,10 @@ + 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) { ++ if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestSignUpdate(ctx, data, datalen) != 1 || ++ EVP_DigestSignFinal(ctx, sig, &len) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto error; + } +@@ -540,12 +544,13 @@ + 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) { ++ if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto done; + } +- ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey); ++ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen); + switch (ret) { + case 1: + ret = 0; +@@ -5038,3 +5043,27 @@ + return 0; + } + #endif /* WITH_XMSS */ ++ ++#ifdef WITH_OPENSSL ++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; ++} ++#endif /* WITH_OPENSSL */ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.h ./sshkey.h +--- ../../openssh-8.7p1/sshkey.h 2023-03-08 15:35:14.702943628 +0100 ++++ ./sshkey.h 2023-03-08 15:34:33.509578138 +0100 +@@ -31,6 +31,9 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include ++#include ++#include + # ifdef OPENSSL_HAS_ECC + # include + # include +@@ -293,6 +295,13 @@ + + void sshkey_sig_details_free(struct sshkey_sig_details *); + ++#ifdef WITH_OPENSSL ++EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *); ++int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **); ++#endif /* WITH_OPENSSL */ ++ + #ifdef SSHKEY_INTERNAL + int ssh_rsa_sign(const struct sshkey *key, + u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-rsa.c ./ssh-rsa.c +--- ../../openssh-8.7p1/ssh-rsa.c 2023-03-08 15:35:14.669943335 +0100 ++++ ./ssh-rsa.c 2023-03-08 15:34:33.509578138 +0100 +@@ -23,6 +23,8 @@ + + #include + #include ++#include ++#include + + #include + #include +@@ -172,9 +174,8 @@ + if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) +- return SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) ++ return ret; + ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, + datalen); + EVP_PKEY_free(pkey); +@@ -285,11 +286,8 @@ + len = modlen; + } + +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) { +- ret = SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) + goto out; +- } + ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey); + EVP_PKEY_free(pkey); + +@@ -306,11 +304,9 @@ + u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) + { + size_t rsasize = 0; +- const RSA *rsa; + int ret; + +- rsa = EVP_PKEY_get0_RSA(pkey); +- rsasize = RSA_size(rsa); ++ rsasize = EVP_PKEY_get_size(pkey); + if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || + siglen == 0 || siglen > rsasize) { + ret = SSH_ERR_INVALID_ARGUMENT; +@@ -323,4 +319,87 @@ + done: + return ret; + } ++ ++int ++ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ int ret = 0; ++ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL; ++ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ RSA_get0_key(k->rsa, &n, &e, &d); ++ RSA_get0_factors(k->rsa, &p, &q); ++ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); ++ ++ if (n != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (e != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (d != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* setting this to param_build makes the creation process fail */ ++ if (p != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) { ++ debug2_f("failed to add 'p' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (q != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) { ++ debug2_f("failed to add 'q' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (dmp1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) { ++ debug2_f("failed to add 'dmp1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (dmq1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) { ++ debug2_f("failed to add 'dmq1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (iqmp != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) { ++ debug2_f("failed to add 'iqmp' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ return ret; ++} + #endif /* WITH_OPENSSL */ diff --git a/openssh-9.0p1-hpn-15.2-modified.patch b/openssh-9.0p1-hpn-15.2-modified.patch index 24605cb..cf04605 100644 --- a/openssh-9.0p1-hpn-15.2-modified.patch +++ b/openssh-9.0p1-hpn-15.2-modified.patch @@ -1012,9 +1012,9 @@ diff -Nur openssh-9.0p1.orig/compat.c openssh-9.0p1/compat.c --- openssh-9.0p1.orig/compat.c 2022-08-30 20:22:42.423819852 +0200 +++ openssh-9.0p1/compat.c 2022-08-30 20:23:49.884993064 +0200 @@ -150,6 +150,17 @@ - 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; + /* Check to see if the remote side is OpenSSH and not HPN */ + /* TODO: See if we can work this into the new method for bug checks */ + if (strstr(version, "OpenSSH") != NULL) { From b26b3e1a8b4ecac2c8059dfe0e0817ff6827e7b8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 19 Jul 2023 17:05:44 +0200 Subject: [PATCH 117/146] Based on openssh-9.3p1-3.fc39 Fix keyex patch --- gsi-openssh.spec | 42 +- openssh-6.3p1-ctr-evp-fast.patch | 101 ---- openssh-6.6p1-keycat.patch | 4 +- openssh-6.7p1-coverity.patch | 88 ---- openssh-7.3p1-x11-max-displays.patch | 4 +- openssh-7.4p1-systemd.patch | 2 +- openssh-7.5p1-sandbox.patch | 2 +- openssh-7.6p1-audit.patch | 26 +- openssh-7.7p1-fips.patch | 85 ++-- openssh-8.0p1-gssapi-keyex.patch | 183 +++++-- openssh-8.0p1-openssl-evp.patch | 106 ++-- openssh-8.0p1-pkcs11-uri.patch | 106 ++-- openssh-8.7p1-CVE-2023-25136.patch | 38 -- openssh-8.7p1-evpgenkey.patch | 75 ++- openssh-8.7p1-mem-leak.patch | 156 ------ openssh-8.7p1-minrsabits.patch | 436 +--------------- openssh-8.7p1-negotiate-supported-algs.patch | 138 ++++-- openssh-8.7p1-nohostsha1proof.patch | 42 +- openssh-8.7p1-recursive-scp.patch | 18 +- openssh-8.7p1-scp-clears-file.patch | 303 ------------ openssh-8.7p1-scp-kill-switch.patch | 4 +- openssh-8.7p1-ssh-manpage.patch | 2 +- openssh-9.0p1-evp-fips-dh.patch | 80 ++- openssh-9.0p1-evp-fips-sign.patch | 96 ++-- openssh-9.0p1-evp-pkcs11.patch | 145 ++++++ openssh-9.0p1-man-hostkeyalgos.patch | 16 + ...gsissh.patch => openssh-9.3p1-gsissh.patch | 348 ++++++------- ...h => openssh-9.3p1-hpn-15.2-modified.patch | 466 +++++++++--------- openssh-configure-c99-1.patch | 26 - openssh-configure-c99-2.patch | 47 -- openssh-configure-c99-3.patch | 41 -- sources | 4 +- 32 files changed, 1166 insertions(+), 2064 deletions(-) delete mode 100644 openssh-6.3p1-ctr-evp-fast.patch delete mode 100644 openssh-8.7p1-CVE-2023-25136.patch delete mode 100644 openssh-8.7p1-mem-leak.patch delete mode 100644 openssh-8.7p1-scp-clears-file.patch create mode 100644 openssh-9.0p1-evp-pkcs11.patch create mode 100644 openssh-9.0p1-man-hostkeyalgos.patch rename openssh-9.0p1-gsissh.patch => openssh-9.3p1-gsissh.patch (88%) rename openssh-9.0p1-hpn-15.2-modified.patch => openssh-9.3p1-hpn-15.2-modified.patch (87%) delete mode 100644 openssh-configure-c99-1.patch delete mode 100644 openssh-configure-c99-2.patch delete mode 100644 openssh-configure-c99-3.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 7f17562..297581a 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,8 +23,8 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 9.0p1 -%global openssh_rel 6 +%global openssh_ver 9.3p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -86,8 +86,6 @@ Patch703: openssh-4.3p2-askpass-grab-info.patch 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 # GSSAPI Key Exchange (RFC 4462 + RFC 8732) # from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master @@ -162,20 +160,10 @@ Patch983: openssh-8.7p1-evpgenkey.patch # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 Patch984: openssh-8.7p1-ibmca.patch -# Fix for scp clearing file when src and dest are the same (#2056884) -# upstream commits: -# 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee -Patch1001: openssh-8.7p1-scp-clears-file.patch # Add missing options from ssh_config into ssh manpage # upstream bug: # https://bugzilla.mindrot.org/show_bug.cgi?id=3455 Patch1002: openssh-8.7p1-ssh-manpage.patch -# Always return allocated strings from the kex filtering so that we can free them -# upstream commits: -# 486c4dc3b83b4b67d663fb0fa62bc24138ec3946 -# 6c31ba10e97b6953c4f325f526f3e846dfea647a -# 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b -Patch1003: openssh-8.7p1-mem-leak.patch # Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 @@ -184,27 +172,26 @@ Patch1004: openssh-8.7p1-gssapi-auth.patch # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch -Patch1007: openssh-configure-c99-1.patch -Patch1008: openssh-configure-c99-2.patch -Patch1009: openssh-configure-c99-3.patch - -Patch1010: openssh-8.7p1-CVE-2023-25136.patch Patch1011: openssh-9.0p1-evp-fips-sign.patch Patch1012: openssh-9.0p1-evp-fips-dh.patch Patch1013: openssh-9.0p1-evp-fips-ecdh.patch Patch1014: openssh-8.7p1-nohostsha1proof.patch +Patch1015: openssh-9.0p1-evp-pkcs11.patch + +# clarify rhbz#2068423 on the man page of ssh_config +Patch1016: openssh-9.0p1-man-hostkeyalgos.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 -Patch98: openssh-9.0p1-gsissh.patch +Patch98: openssh-9.3p1-gsissh.patch # This is the HPN patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-9.0p1-hpn-15.2-modified.patch +Patch99: openssh-9.3p1-hpn-15.2-modified.patch License: BSD Requires: /sbin/nologin @@ -312,7 +299,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch703 -p1 -b .grab-info %patch707 -p1 -b .redhat %patch711 -p1 -b .log-usepam-no -%patch712 -p1 -b .evp-ctr %patch800 -p1 -b .gsskex %patch801 -p1 -b .force_krb @@ -352,19 +338,15 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch202 -p1 -b .audit-log %patch700 -p1 -b .fips -%patch1001 -p1 -b .scp-clears-file %patch1002 -p1 -b .ssh-manpage -%patch1003 -p1 -b .mem-leak %patch1004 -p1 -b .gssapi-auth %patch1006 -p1 -b .negotiate-supported-algs -%patch1007 -p1 -b .configure-c99-1 -%patch1008 -p1 -b .configure-c99-2 -%patch1009 -p1 -b .configure-c99-3 -%patch1010 -p1 -b .cve-2023-25136 %patch1011 -p1 -b .evp-fips-sign %patch1012 -p1 -b .evp-fips-dh %patch1013 -p1 -b .evp-fips-ecdh %patch1014 -p1 -b .nosha1hostproof +%patch1015 -p1 -b .evp-pkcs11 +%patch1016 -p1 -b .man-hostkeyalgos %patch100 -p1 -b .coverity @@ -563,6 +545,10 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Wed Jul 19 2023 Mattias Ellert - 9.3p1-1 +- Based on openssh-9.3p1-3.fc39 +- Fix keyex patch + * Sun Apr 16 2023 Mattias Ellert - 9.0p1-6 - Based on openssh-9.0p1-17.fc39 diff --git a/openssh-6.3p1-ctr-evp-fast.patch b/openssh-6.3p1-ctr-evp-fast.patch deleted file mode 100644 index ddcb7f1..0000000 --- a/openssh-6.3p1-ctr-evp-fast.patch +++ /dev/null @@ -1,101 +0,0 @@ -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); diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 2aa14bd..529b508 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -61,13 +61,13 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) - $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) + $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o + $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) @@ -321,6 +325,7 @@ install-files: $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 08d6b99..494f4c6 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -28,17 +28,6 @@ diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c return 0; } -diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c ---- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 -@@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname - &hostkey_digest, &hostkey_digest_len, hostkey)) { - error("Error calculating key fingerprint."); - freerrset(fingerprints); -+ free(dnskey_digest); - return -1; - } - diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c --- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 +++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 @@ -154,17 +143,6 @@ diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c return ret; } -diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c ---- openssh-8.5p1/moduli.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/moduli.c 2021-03-24 12:03:33.784968173 +0100 -@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t - else - logit("failed to write to checkpoint file '%s': %s", cpfile, - strerror(errno)); -+ /* coverity[leaked_storage : FALSE] */ - } - - static unsigned long 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 @@ -300,24 +278,6 @@ diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != (int)tun) goto done; -diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c ---- openssh-8.5p1/session.c.coverity 2021-03-24 12:03:33.777968124 +0100 -+++ openssh-8.5p1/session.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s - /* Environment specified by admin */ - for (i = 0; i < options.num_setenv; i++) { - cp = xstrdup(options.setenv[i]); -+ /* coverity[overwrite_var : FALSE] */ - if ((value = strchr(cp, '=')) == NULL) { - /* shouldn't happen; vars are checked in servconf.c */ - fatal("Invalid config SetEnv: %s", options.setenv[i]); - } - *value++ = '\0'; - child_set_env(&env, &envsize, cp, value); -+ free(cp); - } - - /* SSH_CLIENT deprecated */ 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 @@ -330,25 +290,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); -@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co - if (lflag & LS_LONG_VIEW) { - if (g.gl_statv[i] == NULL) { - error("no stat information for %s", fname); -+ free(fname); - continue; - } - lname = ls_file(fname, g.gl_statv[i], 1, -diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c ---- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s - freezero(rks[i], sizeof(*rks[i])); - } - free(rks); -+ free(device); - return ret; - } - 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 @@ -423,32 +364,3 @@ diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c } else { if (strncasecmp(cp, "key:", 4) == 0) { cp += 4; -@@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c - } else if (strncmp(opts[i], "start-line=", 11) == 0) { - start_lineno = strtoul(opts[i]+11, NULL, 10); - } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { -+ free(checkpoint); - checkpoint = xstrdup(opts[i]+11); - } else if (strncmp(opts[i], "generator=", 10) == 0) { - generator_wanted = (u_int32_t)strtonum( -@@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c - #else /* WITH_OPENSSL */ - fatal("Moduli screening is not supported"); - #endif /* WITH_OPENSSL */ -+ free(checkpoint); -+ if (in != stdin) -+ fclose(in); - } - - static char * -diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c ---- openssh-8.5p1/sshsig.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sshsig.c 2021-03-24 12:03:33.787968194 +0100 -@@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s - oerrno = errno; - error_f("read: %s", strerror(errno)); - ssh_digest_free(ctx); -+ ctx = NULL; - errno = oerrno; - r = SSH_ERR_SYSTEM_ERROR; - goto out; diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index ad181cb..2b702d4 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -82,7 +82,7 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h +++ 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 *, u_int); + void channel_set_x11_refuse_time(struct ssh *, time_t); 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 **); @@ -191,8 +191,8 @@ 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 diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch index 4f9e58a..1242aac 100644 --- a/openssh-7.4p1-systemd.patch +++ b/openssh-7.4p1-systemd.patch @@ -9,8 +9,8 @@ index 2ffc369..162ce92 100644 --- a/configure.ac +++ b/configure.ac @@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5], - AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) + AC_SUBST([CHANNELLIBS]) +# Check whether user wants systemd support +SYSTEMD_MSG="no" diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7217c64..90640a0 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -21,7 +21,7 @@ index ca75cc7..6e7de31 100644 + SC_ALLOW(__NR_flock), +#endif #ifdef __NR_futex - SC_ALLOW(__NR_futex), + SC_FUTEX(__NR_futex), #endif @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_gettimeofday diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 2d3aae9..748c4b6 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -802,8 +802,8 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c +} + static int - match_principals_option(const char *principal_list, struct sshkey_cert *cert) - { + match_principals_file(struct passwd *pw, char *file, + struct sshkey_cert *cert, struct sshauthopt **authoptsp) diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c --- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 +++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 @@ -820,15 +820,6 @@ diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h --- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200 +++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200 -@@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh - - char *expand_authorized_keys(const char *, struct passwd *pw); - char *authorized_principals_file(struct passwd *); -+int 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 **); - - FILE *auth_openkeyfile(const char *, struct passwd *, int); - FILE *auth_openprincipals(const char *, struct passwd *, int); @@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty int get_hostkey_index(struct sshkey *, int, struct ssh *); int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, @@ -838,6 +829,15 @@ diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h /* Key / cert options linkage to auth layer */ const struct sshauthopt *auth_options(struct ssh *); +@@ -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 *, + struct sshkey *, const char *, const char *, struct sshauthopt **); ++int 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 **); + FILE *auth_openkeyfile(const char *, struct passwd *, int); + FILE *auth_openprincipals(const char *, struct passwd *, int); + diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c --- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200 +++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200 @@ -910,9 +910,9 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c --- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200 +++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200 @@ -65,6 +65,7 @@ - #include "ssherr.h" #include "sshbuf.h" #include "digest.h" + #include "xmalloc.h" +#include "audit.h" #ifdef GSSAPI @@ -2006,7 +2006,7 @@ diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h @@ -71,10 +77,12 @@ void session_unused(int); int session_input_channel_req(struct ssh *, Channel *, const char *); void session_close_by_pid(struct ssh *ssh, pid_t, int); - void session_close_by_channel(struct ssh *, int, void *); + void session_close_by_channel(struct ssh *, int, int, void *); -void session_destroy_all(struct ssh *, void (*)(Session *)); +void session_destroy_all(struct ssh *, void (*)(struct ssh*, Session *)); void session_pty_cleanup2(Session *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index d1e44b0..180f13e 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -368,14 +368,6 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1619,6 +1621,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; @@ -1931,6 +1931,13 @@ main(int ac, char **av) &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) do_log2_r(r, ll, "Unable to load host key \"%s\"", @@ -440,11 +432,11 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #ifdef WITH_XMSS @@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai - for (kt = keytypes; kt->type != -1; kt++) { - if (kt->name == NULL || kt->type == KEY_NULL) + impl = keyimpls[i]; + if (impl->name == NULL || impl->type == KEY_NULL) continue; + if (FIPS_mode()) { -+ switch (kt->type) { ++ switch (impl->type) { + case KEY_ED25519: + case KEY_ED25519_SK: + case KEY_ED25519_CERT: @@ -455,9 +447,9 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c + break; + } + } - if (!include_sigonly && kt->sigonly) + if (!include_sigonly && impl->sigonly) continue; - if ((certs_only && !kt->cert) || (plain_only && kt->cert)) + if ((certs_only && !impl->cert) || (plain_only && impl->cert)) @@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c return SSH_ERR_EC_CURVE_MISMATCH; } @@ -477,40 +469,31 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c + break; + } /* Fill in ret from parsed key */ - ret->type = type; - if (sshkey_is_cert(ret)) { -@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA - goto out; - - if (EVP_PKEY_keygen(ctx, &res) <= 0) { -+ if (FIPS_mode()) -+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } + sshkey_free_contents(ret); + *ret = *k; @@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, - break; - case KEY_ED25519_SK: - case KEY_ED25519_SK_CERT: -+ if (FIPS_mode()) { + *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 */ - case KEY_ECDSA_SK_CERT: - case KEY_ECDSA_SK: - r = sshsk_sign(sk_provider, key, sigp, lenp, data, + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + if ((r = sshkey_unshield_private(key)) != 0) @@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, - return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); - case KEY_ED25519_SK: - case KEY_ED25519_SK_CERT: -+ if (FIPS_mode()) { + *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; + } - return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, - compat, detailsp); - #ifdef WITH_XMSS + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + return impl->funcs->verify(key, sig, siglen, data, dlen, diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c --- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 +++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 @@ -554,6 +537,26 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); +diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 +@@ -31,6 +31,7 @@ + + #include + #include ++#include + + #include + #include +@@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA + goto out; + + if (EVP_PKEY_keygen(ctx, &res) <= 0) { ++ if (FIPS_mode()) ++ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c --- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200 +++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200 @@ -663,13 +666,13 @@ diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c if ((sig = malloc(slen)) == NULL) return SSH_ERR_ALLOC_FAIL; @@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * - datalen >= INT_MAX - crypto_sign_ed25519_BYTES || - signature == NULL || signaturelen == 0) + 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(signature, signaturelen)) == NULL) + if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index d5dfd7e..3e79581 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -12,13 +12,22 @@ index e7549470..b68c1710 100644 @@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.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 \ 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 \ +@@ -523,7 +523,7 @@ regress-prep: + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile + + REGRESSLIBS=libssh.a $(LIBCOMPAT) +-TESTLIBS=$(LIBS) $(CHANNELLIBS) ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) + + regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ diff -up a/auth.c.gsskex b/auth.c --- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 +++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 @@ -151,7 +160,7 @@ index 9351e042..d6446c0c 100644 + * The 'gssapi_keyex' userauth mechanism. + */ +static int -+userauth_gsskeyex(struct ssh *ssh) ++userauth_gsskeyex(struct ssh *ssh, const char *method) +{ + Authctxt *authctxt = ssh->authctxt; + int r, authenticated = 0; @@ -212,19 +221,20 @@ index 9351e042..d6446c0c 100644 else logit("GSSAPI MIC check failed"); -@@ -326,6 +370,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -326,6 +370,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) return 0; } +Authmethod method_gsskeyex = { + "gssapi-keyex", ++ NULL, + userauth_gsskeyex, + &options.gss_authentication +}; + Authmethod method_gssapi = { "gssapi-with-mic", - NULL, + NULL, diff --git a/auth2.c b/auth2.c index 0e776224..1c217268 100644 --- a/auth2.c @@ -378,13 +388,9 @@ index ebd0dbca..1bdac6a4 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, - break; - - /* Do channel operations unless rekeying in progress. */ -- if (!ssh_packet_is_rekeying(ssh)) -+ if (!ssh_packet_is_rekeying(ssh)) { - channel_after_poll(ssh, pfd, npfd_active); +@@ -1379,6 +1383,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, + /* Do channel operations. */ + channel_after_poll(ssh, pfd, npfd_active); +#ifdef GSSAPI + if (options.gss_renewal_rekey && @@ -393,11 +399,10 @@ index ebd0dbca..1bdac6a4 100644 + need_rekeying = 1; + } +#endif -+ } + /* Buffer input from the connection. */ - if (conn_in_ready) - client_process_net_input(ssh); + if (conn_in_ready) + client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac index b689db4b..efafb6bd 100644 --- a/configure.ac @@ -1254,15 +1259,9 @@ diff --git a/kex.c b/kex.c index ce85f043..574c7609 100644 --- a/kex.c +++ b/kex.c -@@ -57,11 +57,16 @@ - #include "misc.h" - #include "dispatch.h" - #include "monitor.h" -+#include "xmalloc.h" - - #include "ssherr.h" - #include "sshbuf.h" +@@ -57,6 +57,10 @@ #include "digest.h" + #include "xmalloc.h" +#ifdef GSSAPI +#include "ssh-gss.h" @@ -1360,9 +1359,9 @@ index ce85f043..574c7609 100644 + return 1; +} + - /* put algorithm proposal into buffer */ - int - kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) + /* + * 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); @@ -1370,8 +1369,8 @@ index ce85f043..574c7609 100644 +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ - sshbuf_free(kex->initial_sig); - sshkey_free(kex->initial_hostkey); + 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 @@ -1414,9 +1413,9 @@ index a5ae6ac0..fe714141 100644 char *kex_names_cat(const char *, const char *); int kex_assemble_names(char **, const char *, const char *); +int kex_gss_names_valid(const char *); - - int kex_exchange_identification(struct ssh *, int, 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 *); @@ -1489,7 +1488,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,599 @@ +@@ -0,0 +1,600 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2088,6 +2087,7 @@ index 00000000..f6e1405e + sshbuf_free(server_host_key_blob); + return r; +} ++ +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 @@ -3496,7 +3496,7 @@ index af00fb30..03bc87eb 100644 /* @@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - char *s, *all_key; + char *s, *all_key, *hkalgs = NULL; int r, use_known_hosts_order = 0; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3508,9 +3508,10 @@ 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) - compat_pkalg_proposal(ssh, options.hostkeyalgorithms); - } - + kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers, + options.macs, compression_alg_list(options.compression), + hkalgs ? hkalgs : options.hostkeyalgorithms); ++ +#if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { + /* Add the GSSAPI mechanisms currently supported on this @@ -3546,11 +3547,10 @@ index af00fb30..03bc87eb 100644 + } + } +#endif -+ - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -@@ -224,16 +256,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + + free(hkalgs); + +@@ -224,17 +256,47 @@ 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 @@ -3568,7 +3568,7 @@ index af00fb30..03bc87eb 100644 +# endif +#endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; - ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3583,6 +3583,7 @@ index af00fb30..03bc87eb 100644 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); /* 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) @@ -3751,8 +3752,8 @@ index 60b2aaf7..d92f03aa 100644 exit(1); } @@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - ssh, list_hostkey_types()); + + free(hkalgs); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + { @@ -3885,22 +3886,98 @@ diff --git a/sshkey.c b/sshkey.c index 57995ee6..fd5b7724 100644 --- a/sshkey.c +++ b/sshkey.c +@@ -127,6 +127,75 @@ static const struct keytype keytypes[] = { + extern const struct sshkey_impl sshkey_xmss_impl; + extern const struct sshkey_impl sshkey_xmss_cert_impl; + #endif ++ ++static int ssh_gss_equal(const struct sshkey *, const struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_serialize_public(const struct sshkey *, struct sshbuf *, ++ enum sshkey_serialize_rep) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_deserialize_public(const char *, struct sshbuf *, ++ struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_serialize_private(const struct sshkey *, struct sshbuf *, ++ enum sshkey_serialize_rep) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_deserialize_private(const char *, struct sshbuf *, ++ struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_copy_public(const struct sshkey *, struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int, ++ struct sshkey_sig_details **) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static const struct sshkey_impl_funcs sshkey_gss_funcs = { ++ /* .size = */ NULL, ++ /* .alloc = */ NULL, ++ /* .cleanup = */ NULL, ++ /* .equal = */ ssh_gss_equal, ++ /* .ssh_serialize_public = */ ssh_gss_serialize_public, ++ /* .ssh_deserialize_public = */ ssh_gss_deserialize_public, ++ /* .ssh_serialize_private = */ ssh_gss_serialize_private, ++ /* .ssh_deserialize_private = */ ssh_gss_deserialize_private, ++ /* .generate = */ NULL, ++ /* .copy_public = */ ssh_gss_copy_public, ++ /* .sign = */ NULL, ++ /* .verify = */ ssh_gss_verify, ++}; ++ ++/* The struct is intentionally dummy and has no gss calls */ ++static const struct sshkey_impl sshkey_gss_kex_impl = { ++ /* .name = */ "null", ++ /* .shortname = */ "null", ++ /* .sigalg = */ NULL, ++ /* .type = */ KEY_NULL, ++ /* .nid = */ 0, ++ /* .cert = */ 0, ++ /* .sigonly = */ 0, ++ /* .keybits = */ 0, /* FIXME */ ++ /* .funcs = */ &sshkey_gss_funcs, ++}; + + const struct sshkey_impl * const keyimpls[] = { + &sshkey_ed25519_impl, @@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { - # endif /* ENABLE_SK */ - # endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ -+ { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, - { NULL, NULL, NULL, -1, -1, 0, 0 } + &sshkey_xmss_impl, + &sshkey_xmss_cert_impl, + #endif ++ &sshkey_gss_kex_impl, + NULL }; @@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) - const struct keytype *kt; - for (kt = keytypes; kt->type != -1; kt++) { -- if (kt->name == NULL) -+ if (kt->name == NULL || kt->type == KEY_NULL) + for (i = 0; keyimpls[i] != NULL; i++) { + impl = keyimpls[i]; +- if (impl->name == NULL) ++ if (impl->name == NULL || impl->type == KEY_NULL) continue; - if (!include_sigonly && kt->sigonly) + if (!include_sigonly && impl->sigonly) continue; diff --git a/sshkey.h b/sshkey.h index 71a3fddc..37a43a67 100644 diff --git a/openssh-8.0p1-openssl-evp.patch b/openssh-8.0p1-openssl-evp.patch index ade0bbb..a17dbbc 100644 --- a/openssh-8.0p1-openssl-evp.patch +++ b/openssh-8.0p1-openssl-evp.patch @@ -62,8 +62,8 @@ 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) + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { + EVP_PKEY *pkey = NULL; DSA_SIG *sig = NULL; @@ -119,14 +119,14 @@ index a23c383dc..ea45e7275 100644 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) + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { + EVP_PKEY *pkey = NULL; - DSA_SIG *sig = NULL; + DSA_SIG *dsig = 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); +- size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1); + u_char *sigblob = NULL; + size_t len, slen; int ret = SSH_ERR_INTERNAL_ERROR; @@ -136,25 +136,25 @@ index a23c383dc..ea45e7275 100644 if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA || - signature == NULL || signaturelen == 0) + sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; -- if (dlen == 0) +- if (hlen == 0) - return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ - if ((b = sshbuf_from(signature, signaturelen)) == NULL) + if ((b = sshbuf_from(sig, siglen)) == 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, +- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, - digest, sizeof(digest))) != 0) -+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) { ++ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; - -- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) { +- switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) { - case 1: - ret = 0; - break; @@ -167,7 +167,7 @@ index a23c383dc..ea45e7275 100644 - default: + } + psig = sigb; -+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) { ++ if ((slen = i2d_DSA_SIG(dsig, &psig)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -177,14 +177,14 @@ index a23c383dc..ea45e7275 100644 + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } -+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen, ++ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, + sigb, slen); + EVP_PKEY_free(pkey); + out: - explicit_bzero(digest, sizeof(digest)); + free(sigb); - DSA_SIG_free(sig); + DSA_SIG_free(dsig); BN_clear_free(sig_r); BN_clear_free(sig_s); diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c @@ -192,17 +192,17 @@ 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) + const u_char *data, size_t dlen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { + EVP_PKEY *pkey = NULL; - ECDSA_SIG *sig = NULL; + ECDSA_SIG *esig = 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; +- size_t len, hlen; + int len; struct sshbuf *b = NULL, *bb = NULL; int ret = SSH_ERR_INTERNAL_ERROR; @@ -212,25 +212,25 @@ index 599c7199d..b036796e8 100644 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) +- (hlen = 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, +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, - 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); ++ dlen); + EVP_PKEY_free(pkey); + if (ret < 0) { goto out; + } -- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) { +- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { + psig = sigb; -+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) { ++ if (d2i_ECDSA_SIG(&esig, &psig, len) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -246,17 +246,17 @@ index 599c7199d..b036796e8 100644 + free(sigb); sshbuf_free(b); sshbuf_free(bb); - ECDSA_SIG_free(sig); + ECDSA_SIG_free(esig); @@ -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) + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { + EVP_PKEY *pkey = NULL; - ECDSA_SIG *sig = NULL; + ECDSA_SIG *esig = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; - int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; -- size_t dlen; +- size_t hlen; + int hash_alg, len; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; @@ -265,11 +265,11 @@ index 599c7199d..b036796e8 100644 if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA || - signature == NULL || signaturelen == 0) + sig == NULL || siglen == 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) +- (hlen = ssh_digest_bytes(hash_alg)) == 0) + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; @@ -281,7 +281,7 @@ index 599c7199d..b036796e8 100644 - if (sshbuf_len(sigbuf) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; + /* Figure out the length */ -+ if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) { ++ if ((len = i2d_ECDSA_SIG(esig, NULL)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } @@ -289,15 +289,15 @@ index 599c7199d..b036796e8 100644 + ret = SSH_ERR_ALLOC_FAIL; goto out; } -- if ((ret = ssh_digest_memory(hash_alg, data, datalen, +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) + psig = sigb; -+ if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) { ++ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; + } -- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) { +- switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) { - case 1: - ret = 0; - break; @@ -315,7 +315,7 @@ index 599c7199d..b036796e8 100644 + ret = SSH_ERR_ALLOC_FAIL; goto out; } -+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len); ++ ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len); + EVP_PKEY_free(pkey); out: @@ -323,7 +323,7 @@ index 599c7199d..b036796e8 100644 + free(sigb); sshbuf_free(sigbuf); sshbuf_free(b); - ECDSA_SIG_free(sig); + ECDSA_SIG_free(esig); diff --git a/ssh-rsa.c b/ssh-rsa.c index 9b14f9a9a..8ef3a6aca 100644 --- a/ssh-rsa.c @@ -335,8 +335,8 @@ index 9b14f9a9a..8ef3a6aca 100644 -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) + static u_int + ssh_rsa_size(const struct sshkey *key) @@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg) return -1; } @@ -360,13 +360,13 @@ index 9b14f9a9a..8ef3a6aca 100644 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 u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - const BIGNUM *rsa_n; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; - size_t slen = 0; -- u_int dlen, len; +- u_int hlen, len; - int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; + EVP_PKEY *pkey = NULL; + u_char *sig = NULL; @@ -378,7 +378,7 @@ index 9b14f9a9a..8ef3a6aca 100644 @@ -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); + hash_alg = rsa_hash_id_from_keyname(alg); + if (key == NULL || key->rsa == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) @@ -392,7 +392,7 @@ index 9b14f9a9a..8ef3a6aca 100644 - - /* hash the data */ - nid = rsa_hash_alg_nid(hash_alg); -- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) +- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) - return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, datalen, - digest, sizeof(digest))) != 0) @@ -412,7 +412,7 @@ index 9b14f9a9a..8ef3a6aca 100644 goto out; } -- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) { +- if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } @@ -436,14 +436,14 @@ index 9b14f9a9a..8ef3a6aca 100644 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 u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { - 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, hlen; + size_t len = 0, diff, modlen; struct sshbuf *b = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; @@ -462,7 +462,7 @@ index 9b14f9a9a..8ef3a6aca 100644 explicit_bzero(sigblob, diff); len = modlen; } -- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { +- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { - ret = SSH_ERR_INTERNAL_ERROR; + + if ((pkey = EVP_PKEY_new()) == NULL || @@ -470,13 +470,13 @@ index 9b14f9a9a..8ef3a6aca 100644 + ret = SSH_ERR_ALLOC_FAIL; goto out; } -- if ((ret = ssh_digest_memory(hash_alg, data, datalen, +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) - goto out; -+ ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey); ++ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); + EVP_PKEY_free(pkey); -- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, +- ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, - key->rsa); out: freezero(sigblob, len); @@ -613,7 +613,7 @@ index 9b14f9a9a..8ef3a6aca 100644 - freezero(decrypted, rsasize); return ret; } - #endif /* WITH_OPENSSL */ + diff --git a/sshkey.c b/sshkey.c index ad1957762..b95ed0b10 100644 --- a/sshkey.c diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index b3295a9..be38500 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -76,7 +76,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ + hmac.o ed25519.o hash.o \ @@ -302,6 +302,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o @@ -105,7 +105,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile @@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) +UNITTESTS_TEST_PKCS11_OBJS=\ + regress/unittests/pkcs11/tests.o @@ -115,7 +115,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ -lssh -lopenbsd-compat -lcrypto $(LIBS) + # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ @@ -534,7 +534,7 @@ diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regre diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c --- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 +++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 -@@ -0,0 +1,337 @@ +@@ -0,0 +1,342 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -563,7 +563,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +#include "sshbuf.h" +#include "ssh-pkcs11-uri.h" + -+#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) + +/* prototypes are not public -- specify them here internally for tests */ +struct sshbuf *percent_encode(const char *, size_t, char *); @@ -596,6 +596,10 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); + else /* both should be null */ + ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); ++ if (b->serial != NULL) ++ ASSERT_STRING_EQ(a->serial, b->serial); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->serial, b->serial); +} + +void @@ -630,7 +634,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + +struct pkcs11_uri * +compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, -+ char *manuf, char *module_path, char *object, char *pin) ++ char *manuf, char *serial, char *module_path, char *object, char *pin) +{ + struct pkcs11_uri *uri = pkcs11_uri_init(); + if (id_len > 0) { @@ -641,6 +645,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + uri->token = token; + uri->lib_manuf = lib_manuf; + uri->manuf = manuf; ++ uri->serial = serial; + uri->object = object; + uri->pin = pin; + return uri; @@ -651,47 +656,47 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_parse("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:token=SSH%20Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); + check_parse("pkcs11:object=SIGN%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); + /* query arguments */ + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse("pkcs11:?pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, "123456")); + + /* combinations */ + /* ID SHOULD be percent encoded */ + check_parse("pkcs11:token=SSH%20Key;id=0", -+ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse( + "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, "CAC", ++ compose_uri(NULL, 0, NULL, NULL, "CAC", NULL, + "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse( + "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, + "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key", NULL)); + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so&pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); + + /* empty path component matches everything */ + check_parse("pkcs11:", EMPTY_URI); + + /* empty string is a valid to match against (and different from NULL) */ + check_parse("pkcs11:token=", -+ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL, NULL)); + /* Percent character needs to be percent-encoded */ + check_parse("pkcs11:token=%25", -+ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL, NULL)); +} + +static void @@ -703,7 +708,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); + /* Space MUST be percent encoded -- XXX not enforced yet */ + check_parse("pkcs11:token=SSH Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* MUST NOT contain duplicate attributes of the same name */ + check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); + /* MUST NOT contain duplicate attributes of the same name */ @@ -734,29 +739,29 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_gen("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* library-manufacturer is not implmented now */ + /*check_gen("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL));*/ ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL));*/ + check_gen("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); + check_gen("pkcs11:object=RSA%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "RSA Key", NULL)); + /* query arguments */ + check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + + /* combinations */ + check_gen("pkcs11:id=%02;token=SSH%20Keys", -+ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, "Encryption Key", NULL)); + + /* empty path component matches everything */ + check_gen("pkcs11:", EMPTY_URI); @@ -1545,7 +1550,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1587,6 +1592,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + uri.module_path = k11->provider->module->module_path; + uri.lib_manuf = k11->provider->module->info.manufacturerID; + uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; + + p = pkcs11_uri_get(&uri); + /* do not cleanup -- we do not allocate here, only reference */ @@ -2157,7 +2163,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ +@@ -1517,164 +1702,305 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2401,6 +2407,13 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + "manufacturerID (%s) specified by PKCS#11 URI in " + "slot %lu", token->manufacturerID, (unsigned long)i); + continue; ++ } ++ if (uri->serial != NULL && ++ strcmp(token->serialNumber, uri->serial) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "serialNumber (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->serialNumber, (unsigned long)i); ++ continue; + } debug("provider %s slot %lu: label <%s> manufacturerID <%s> " "model <%s> serial <%s> flags 0x%lx", @@ -2591,7 +2604,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c --- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,419 @@ +@@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -2634,13 +2647,14 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +#define PKCS11_URI_OBJECT "object" +#define PKCS11_URI_LIB_MANUF "library-manufacturer" +#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_SERIAL "serial" +#define PKCS11_URI_MODULE_PATH "module-path" +#define PKCS11_URI_PIN_VALUE "pin-value" + +/* Keyword tokens. */ +typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pPinValue, pBadOption ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pSerial, ++ pModulePath, pPinValue, pBadOption +} pkcs11uriOpCodes; + +/* Textual representation of the tokens. */ @@ -2653,6 +2667,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + { PKCS11_URI_OBJECT, pObject }, + { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, + { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_SERIAL, pSerial }, + { PKCS11_URI_MODULE_PATH, pModulePath }, + { PKCS11_URI_PIN_VALUE, pPinValue }, + { NULL, pBadOption } @@ -2811,6 +2826,16 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + goto err; + } + ++ /* Write serial */ ++ if (uri->serial) { ++ struct sshbuf *serial = percent_encode(uri->serial, ++ strlen(uri->serial), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_SERIAL, serial); ++ if (path == NULL) ++ goto err; ++ } ++ + /* Write module_path */ + if (uri->module_path) { + struct sshbuf *module = percent_encode(uri->module_path, @@ -2853,6 +2878,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + free(pkcs11->object); + free(pkcs11->lib_manuf); + free(pkcs11->manuf); ++ free(pkcs11->serial); + if (pkcs11->pin) + freezero(pkcs11->pin, strlen(pkcs11->pin)); + free(pkcs11); @@ -2948,6 +2974,11 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + charptr = &pkcs11->manuf; + goto parse_string; + ++ case pSerial: ++ /* CK_TOKEN_INFO -> serialNumber */ ++ charptr = &pkcs11->serial; ++ goto parse_string; ++ + case pLibraryManufacturer: + /* CK_INFO -> manufacturerID */ + charptr = &pkcs11->lib_manuf; @@ -3014,7 +3045,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h --- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,42 @@ +@@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3046,6 +3077,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + char *object; + char *lib_manuf; + char *manuf; ++ char *serial; + /* query */ + char *module_path; + char *pin; /* Only parsed, but not printed */ diff --git a/openssh-8.7p1-CVE-2023-25136.patch b/openssh-8.7p1-CVE-2023-25136.patch deleted file mode 100644 index ca661ee..0000000 --- a/openssh-8.7p1-CVE-2023-25136.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/compat.c b/compat.c -index 46dfe3a9c2e..478a9403eea 100644 ---- a/compat.c -+++ b/compat.c -@@ -190,26 +190,26 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) - char * - compat_kex_proposal(struct ssh *ssh, char *p) - { -- char *cp = NULL; -+ char *cp = NULL, *cp2 = NULL; - - if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) - return xstrdup(p); - debug2_f("original KEX proposal: %s", p); - if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) -- if ((p = match_filter_denylist(p, -+ if ((cp = match_filter_denylist(p, - "curve25519-sha256@libssh.org")) == NULL) - fatal("match_filter_denylist failed"); - if ((ssh->compat & SSH_OLD_DHGEX) != 0) { -- cp = p; -- if ((p = match_filter_denylist(p, -+ if ((cp2 = match_filter_denylist(cp ? cp : p, - "diffie-hellman-group-exchange-sha256," - "diffie-hellman-group-exchange-sha1")) == NULL) - fatal("match_filter_denylist failed"); - free(cp); -+ cp = cp2; - } -- debug2_f("compat KEX proposal: %s", p); -- if (*p == '\0') -+ if (cp == NULL || *cp == '\0') - fatal("No supported key exchange algorithms found"); -- return p; -+ debug2_f("compat KEX proposal: %s", cp); -+ return cp; - } - diff --git a/openssh-8.7p1-evpgenkey.patch b/openssh-8.7p1-evpgenkey.patch index 1af9b49..c8703d9 100644 --- a/openssh-8.7p1-evpgenkey.patch +++ b/openssh-8.7p1-evpgenkey.patch @@ -1,9 +1,9 @@ -diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c ---- openssh-8.7p1/sshkey.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 -+++ openssh-8.7p1/sshkey.c 2022-06-30 15:24:31.499641196 +0200 +diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 @@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k) static int - rsa_generate_private_key(u_int bits, RSA **rsap) + ssh_rsa_generate(struct sshkey *k, int bits) { - RSA *private = NULL; + EVP_PKEY_CTX *ctx = NULL; @@ -11,10 +11,10 @@ diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c BIGNUM *f4 = NULL; int ret = SSH_ERR_INTERNAL_ERROR; -@@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1667,20 +1668,42 @@ ssh_rsa_generate(u_int bits, RSA + if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_KEY_LENGTH; - *rsap = NULL; - if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { + + if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL @@ -44,14 +44,14 @@ diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c + } + + /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ *rsap = EVP_PKEY_get1_RSA(res); -+ if (*rsap) { ++ k->rsa = EVP_PKEY_get1_RSA(res); ++ if (k->rsa) { + ret = 0; + } else { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -- *rsap = private; +- k->rsa = private; - private = NULL; - ret = 0; out: @@ -61,50 +61,49 @@ diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c BN_free(f4); return ret; } +diff -up openssh-9.3p1/ssh-ecdsa.c.evpgenrsa openssh-9.3p1/ssh-ecdsa.c +--- openssh-9.3p1/ssh-ecdsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-9.3p1/ssh-ecdsa.c 2022-06-30 15:24:31.499641196 +0200 @@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) static int - ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) + ssh_ecdsa_generate(struct sshkey *k, int bits) { - EC_KEY *private; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *res = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; - if (nid == NULL || ecdsap == NULL) -@@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i - if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) + if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) return SSH_ERR_KEY_LENGTH; - *ecdsap = NULL; -- if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { +@@ -1828,15 +1829,24 @@ ssh_ecdsa_generate(u_int bits, i + + if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) + return SSH_ERR_KEY_LENGTH; +- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) + -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) + return SSH_ERR_ALLOC_FAIL; - if (EC_KEY_generate_key(private) != 1) { +- EC_KEY_free(private); +- return SSH_ERR_LIBCRYPTO_ERROR; +- } + -+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0 ++ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0 + || EVP_PKEY_keygen(ctx, &res) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); ++ return SSH_ERR_LIBCRYPTO_ERROR; + } + /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ *ecdsap = EVP_PKEY_get1_EC_KEY(res); -+ if (*ecdsap) { -+ EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE); -+ ret = 0; -+ } else { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } ++ k->ecdsa = EVP_PKEY_get1_EC_KEY(res); ++ if (k->ecdsa) ++ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE); ++ - EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); -- *ecdsap = private; -- private = NULL; -- ret = 0; - out: -- EC_KEY_free(private); +- k->ecdsa = private; +- return 0; + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(res); - return ret; ++ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR; } - # endif /* OPENSSL_HAS_ECC */ + + static int diff --git a/openssh-8.7p1-mem-leak.patch b/openssh-8.7p1-mem-leak.patch deleted file mode 100644 index 8c9ac80..0000000 --- a/openssh-8.7p1-mem-leak.patch +++ /dev/null @@ -1,156 +0,0 @@ -diff --color -rup a/compat.c b/compat.c ---- a/compat.c 2021-08-20 06:03:49.000000000 +0200 -+++ b/compat.c 2022-07-14 17:39:23.770268440 +0200 -@@ -157,11 +157,12 @@ compat_banner(struct ssh *ssh, const cha - debug_f("no match: %s", version); - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) - { - if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) -- return cipher_prop; -+ return xstrdup(cipher_prop); - debug2_f("original cipher proposal: %s", cipher_prop); - if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) - fatal("match_filter_denylist failed"); -@@ -171,11 +172,12 @@ compat_cipher_proposal(struct ssh *ssh, - return cipher_prop; - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) - { - if (!(ssh->compat & SSH_BUG_RSASIGMD5)) -- return pkalg_prop; -+ return xstrdup(pkalg_prop); - debug2_f("original public key proposal: %s", pkalg_prop); - if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) - fatal("match_filter_denylist failed"); -@@ -185,21 +187,26 @@ compat_pkalg_proposal(struct ssh *ssh, c - return pkalg_prop; - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_kex_proposal(struct ssh *ssh, char *p) - { -+ char *cp = NULL; -+ - if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) -- return p; -+ return xstrdup(p); - debug2_f("original KEX proposal: %s", p); - if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) - if ((p = match_filter_denylist(p, - "curve25519-sha256@libssh.org")) == NULL) - fatal("match_filter_denylist failed"); - if ((ssh->compat & SSH_OLD_DHGEX) != 0) { -+ cp = p; - if ((p = match_filter_denylist(p, - "diffie-hellman-group-exchange-sha256," - "diffie-hellman-group-exchange-sha1")) == NULL) - fatal("match_filter_denylist failed"); -+ free(cp); - } - debug2_f("compat KEX proposal: %s", p); - if (*p == '\0') -diff --color -rup a/sshconnect2.c b/sshconnect2.c ---- a/sshconnect2.c 2022-07-14 17:38:43.241496549 +0200 -+++ b/sshconnect2.c 2022-07-14 17:39:23.772268479 +0200 -@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st - { - char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; - char *s, *all_key; -+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; - int r, use_known_hosts_order = 0; - - #if defined(GSSAPI) && defined(WITH_OPENSSL) -@@ -252,10 +253,9 @@ ssh_kex2(struct ssh *ssh, char *host, st - - if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) - fatal_f("kex_names_cat"); -- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s); -+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s); - myproposal[PROPOSAL_ENC_ALGS_CTOS] = -- compat_cipher_proposal(ssh, options.ciphers); -- myproposal[PROPOSAL_ENC_ALGS_STOC] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = - compat_cipher_proposal(ssh, options.ciphers); - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = -@@ -264,12 +264,12 @@ ssh_kex2(struct ssh *ssh, char *host, st - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - if (use_known_hosts_order) { - /* Query known_hosts and prefer algorithms that appear there */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = - compat_pkalg_proposal(ssh, - order_hostkeyalgs(host, hostaddr, port, cinfo)); - } else { - /* Use specified HostkeyAlgorithms exactly */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = - compat_pkalg_proposal(ssh, options.hostkeyalgorithms); - } - -@@ -383,6 +383,10 @@ ssh_kex2(struct ssh *ssh, char *host, st - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send packet"); - #endif -+ /* Free only parts of proposal that were dynamically allocated here. */ -+ free(prop_kex); -+ free(prop_enc); -+ free(prop_hostkey); - } - - /* -diff --color -rup a/sshd.c b/sshd.c ---- a/sshd.c 2022-07-14 17:38:43.242496568 +0200 -+++ b/sshd.c 2022-07-14 17:42:07.616388978 +0200 -@@ -2493,14 +2493,15 @@ do_ssh2_kex(struct ssh *ssh) - { - char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; - struct kex *kex; -+ char *hostkey_types = NULL; -+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; - int r; - -- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, -+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, - options.kex_algorithms); -- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, -- options.ciphers); -- myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh, -- options.ciphers); -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = -+ compat_cipher_proposal(ssh, options.ciphers); - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - -@@ -2513,8 +2514,10 @@ do_ssh2_kex(struct ssh *ssh) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( -- ssh, list_hostkey_types()); -+ hostkey_types = list_hostkey_types(); -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = -+ compat_pkalg_proposal(ssh, hostkey_types); -+ free(hostkey_types); - - #if defined(GSSAPI) && defined(WITH_OPENSSL) - { -@@ -2606,6 +2609,9 @@ do_ssh2_kex(struct ssh *ssh) - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send test"); - #endif -+ free(prop_kex); -+ free(prop_enc); -+ free(prop_hostkey); - debug("KEX done"); - } - diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index ad91fe7..2ed59a3 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -1,446 +1,24 @@ -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 36b9d2f5..6b517db4 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method) - "(null)" : key->cert->signature_type); - goto done; - } -+ if ((r = sshkey_check_rsa_length(key, -+ options.required_rsa_size)) != 0) { -+ logit_r(r, "refusing %s key", sshkey_type(key)); -+ goto done; -+ } - - if (!authctxt->valid || authctxt->user == NULL) { - debug2_f("disabled because of invalid user"); -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 962fd342..5d59febc 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method) - "(null)" : key->cert->signature_type); - goto done; - } -+ if ((r = sshkey_check_rsa_length(key, -+ options.required_rsa_size)) != 0) { -+ logit_r(r, "refusing %s key", sshkey_type(key)); -+ goto done; -+ } - key_s = format_key(key); - if (sshkey_is_cert(key)) - ca_s = format_key(key->cert->signature_key); diff --git a/readconf.c b/readconf.c index 7f26c680..42be690b 100644 --- a/readconf.c +++ b/readconf.c -@@ -174,7 +174,7 @@ typedef enum { - oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, - oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, - oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, -- oSecurityKeyProvider, oKnownHostsCommand, -+ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, - oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported - } OpCodes; - -@@ -320,6 +320,8 @@ static struct { - { "proxyjump", oProxyJump }, +@@ -320,6 +320,7 @@ static struct { { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, -+ { "requiredrsasize", oRequiredRSASize }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ + { "enableescapecommandline", oEnableEscapeCommandline }, { NULL, oBadOption } - }; -@@ -2176,6 +2177,10 @@ parse_pubkey_algos: - *charptr = xstrdup(arg); - break; - -+ case oRequiredRSASize: -+ intptr = &options->required_rsa_size; -+ goto parse_int; -+ - case oDeprecated: - debug("%s line %d: Deprecated option \"%s\"", - filename, linenum, keyword); -@@ -2423,6 +2428,7 @@ initialize_options(Options * options) - options->hostbased_accepted_algos = NULL; - options->pubkey_accepted_algos = NULL; - options->known_hosts_command = NULL; -+ options->required_rsa_size = -1; - } - - /* -@@ -2619,6 +2625,8 @@ fill_default_options(Options * options) - if (options->sk_provider == NULL) - options->sk_provider = xstrdup("$SSH_SK_PROVIDER"); - #endif -+ if (options->required_rsa_size == -1) -+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; - - /* Expand KEX name lists */ - all_cipher = cipher_alg_list(',', 0); -@@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host) - dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); - dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); - dump_cfg_int(oServerAliveInterval, o->server_alive_interval); -+ dump_cfg_int(oRequiredRSASize, o->required_rsa_size); - - /* String options */ - dump_cfg_string(oBindAddress, o->bind_address); -diff --git a/readconf.h b/readconf.h -index f647bd42..ffb5ec4f 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -176,6 +176,8 @@ typedef struct { - - char *known_hosts_command; - -+ int required_rsa_size; /* minimum size of RSA keys */ -+ - char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ - } Options; - diff --git a/servconf.c b/servconf.c index 29df0463..423772b1 100644 --- a/servconf.c +++ b/servconf.c -@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options) - options->fingerprint_hash = -1; - options->disable_forwarding = -1; - options->expose_userauth_info = -1; -+ options->required_rsa_size = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options) - options->expose_userauth_info = 0; - if (options->sk_provider == NULL) - options->sk_provider = xstrdup("internal"); -+ if (options->required_rsa_size == -1) -+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; - - assemble_algorithms(options); - -@@ -517,6 +520,7 @@ typedef enum { - sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, - sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, -+ sRequiredRSASize, - sDeprecated, sIgnore, sUnsupported - } ServerOpCodes; - -@@ -676,6 +680,8 @@ static struct { - { "rdomain", sRDomain, SSHCFG_ALL }, +@@ -676,6 +680,7 @@ static struct { { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, -+ { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */ + { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, + { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { NULL, sBadOption, 0 } - }; - -@@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, - *charptr = xstrdup(arg); - break; - -+ case sRequiredRSASize: -+ intptr = &options->required_rsa_size; -+ goto parse_int; -+ - case sDeprecated: - case sIgnore: - case sUnsupported: -@@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) - M_CP_INTOPT(rekey_limit); - M_CP_INTOPT(rekey_interval); - M_CP_INTOPT(log_level); -+ M_CP_INTOPT(required_rsa_size); - - /* - * The bind_mask is a mode_t that may be unsigned, so we can't use -@@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o) - dump_cfg_int(sMaxSessions, o->max_sessions); - dump_cfg_int(sClientAliveInterval, o->client_alive_interval); - dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); -+ dump_cfg_int(sRequiredRSASize, o->required_rsa_size); - dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); - - /* formatted integer arguments */ -diff --git a/servconf.h b/servconf.h -index 8a04463e..9346155c 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -229,6 +229,7 @@ typedef struct { - int expose_userauth_info; - u_int64_t timing_secret; - char *sk_provider; -+ int required_rsa_size; /* minimum size of RSA keys */ - } ServerOptions; - - /* Information about the incoming connection as used by Match */ -diff --git a/ssh.c b/ssh.c -index 559bf2af..25be53d5 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port) - } - - /* -- * Check the result of hostkey loading, ignoring some errors and -- * fatal()ing for others. -+ * Check the result of hostkey loading, ignoring some errors and either -+ * discarding the key or fatal()ing for others. - */ - static void --check_load(int r, const char *path, const char *message) -+check_load(int r, struct sshkey **k, const char *path, const char *message) - { - switch (r) { - case 0: -+ /* Check RSA keys size and discard if undersized */ -+ if (k != NULL && *k != NULL && -+ (r = sshkey_check_rsa_length(*k, -+ options.required_rsa_size)) != 0) { -+ error_r(r, "load %s \"%s\"", message, path); -+ free(*k); -+ *k = NULL; -+ } - break; - case SSH_ERR_INTERNAL_ERROR: - case SSH_ERR_ALLOC_FAIL: -@@ -1578,7 +1586,7 @@ main(int ac, char **av) - if ((o) >= sensitive_data.nkeys) \ - fatal_f("pubkey out of array bounds"); \ - check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ -- p, "pubkey"); \ -+ &(sensitive_data.keys[o]), p, "pubkey"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s key from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -1586,7 +1594,8 @@ main(int ac, char **av) - #define L_CERT(p,o) do { \ - if ((o) >= sensitive_data.nkeys) \ - fatal_f("cert out of array bounds"); \ -- check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \ -+ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \ -+ &(sensitive_data.keys[o]), p, "cert"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s cert from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -2265,7 +2274,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) - filename = default_client_percent_dollar_expand(cp, cinfo); - free(cp); - check_load(sshkey_load_public(filename, &public, NULL), -- filename, "pubkey"); -+ &public, filename, "pubkey"); - debug("identity file %s type %d", filename, - public ? public->type : -1); - free(options.identity_files[i]); -@@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) - continue; - xasprintf(&cp, "%s-cert", filename); - check_load(sshkey_load_public(cp, &public, NULL), -- filename, "pubkey"); -+ &public, filename, "pubkey"); - debug("identity file %s type %d", cp, - public ? public->type : -1); - if (public == NULL) { -@@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) - free(cp); - - check_load(sshkey_load_public(filename, &public, NULL), -- filename, "certificate"); -+ &public, filename, "certificate"); - debug("certificate file %s type %d", filename, - public ? public->type : -1); - free(options.certificate_files[i]); -diff --git a/sshconnect2.c b/sshconnect2.c -index f9bd19ea..58fe98db 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info; - static int - verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) - { -+ int r; -+ -+ if ((r = sshkey_check_rsa_length(hostkey, -+ options.required_rsa_size)) != 0) -+ fatal_r(r, "Bad server host key"); - if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, - xxx_conn_info) == -1) - fatal("Host key verification failed."); -@@ -1606,6 +1611,13 @@ load_identity_file(Identity *id) - private = NULL; - quit = 1; - } -+ if (!quit && (r = sshkey_check_rsa_length(private, -+ options.required_rsa_size)) != 0) { -+ debug_fr(r, "Skipping key %s", id->filename); -+ sshkey_free(private); -+ private = NULL; -+ quit = 1; -+ } - if (!quit && private != NULL && id->agent_fd == -1 && - !(id->key && id->isprivate)) - maybe_add_key_to_agent(id->filename, private, comment, -@@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) - /* list of keys supported by the agent */ - if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) { - for (j = 0; j < idlist->nkeys; j++) { -+ if ((r = sshkey_check_rsa_length(idlist->keys[j], -+ options.required_rsa_size)) != 0) { -+ debug_fr(r, "ignoring %s agent key", -+ sshkey_ssh_name(idlist->keys[j])); -+ continue; -+ } - found = 0; - TAILQ_FOREACH(id, &files, next) { - /* -diff --git a/sshd.c b/sshd.c -index 17eee9d8..395ef493 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1870,6 +1870,13 @@ main(int ac, char **av) - fatal_r(r, "Could not demote key: \"%s\"", - options.host_key_files[i]); - } -+ if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey, -+ options.required_rsa_size)) != 0) { -+ error_fr(r, "Host key %s", options.host_key_files[i]); -+ sshkey_free(pubkey); -+ sshkey_free(key); -+ continue; -+ } - sensitive_data.host_keys[i] = key; - sensitive_data.host_pubkeys[i] = pubkey; - -diff --git a/sshkey.c b/sshkey.c -index ed2b5dff..77093235 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) - return ret; - } - --#ifdef WITH_OPENSSL --static int --check_rsa_length(const RSA *rsa) -+int -+sshkey_check_rsa_length(const struct sshkey *k, int min_size) - { -+#ifdef WITH_OPENSSL - const BIGNUM *rsa_n; -+ int nbits; - -- RSA_get0_key(rsa, &rsa_n, NULL, NULL); -- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ if (k == NULL || k->rsa == NULL || -+ (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) -+ return 0; -+ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); -+ nbits = BN_num_bits(rsa_n); -+ if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || -+ (min_size > 0 && nbits < min_size)) - return SSH_ERR_KEY_LENGTH; -+#endif /* WITH_OPENSSL */ - return 0; - } --#endif - - static int - sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, -@@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, - goto out; - } - rsa_n = rsa_e = NULL; /* transferred */ -- if ((ret = check_rsa_length(key->rsa)) != 0) -+ if ((ret = sshkey_check_rsa_length(key, 0)) != 0) - goto out; - #ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); -@@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) - goto out; - } - rsa_p = rsa_q = NULL; /* transferred */ -- if ((r = check_rsa_length(k->rsa)) != 0) -+ if ((r = sshkey_check_rsa_length(k, 0)) != 0) - goto out; - if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) - goto out; -@@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- if ((r = check_rsa_length(prv->rsa)) != 0) -+ if ((r = sshkey_check_rsa_length(prv, 0)) != 0) - goto out; - } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && - (type == KEY_UNSPEC || type == KEY_DSA)) { -diff --git a/sshkey.h b/sshkey.h -index 094815e0..be254e6b 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -273,6 +273,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, - int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, - int type, struct sshkey **pubkeyp); - -+int sshkey_check_rsa_length(const struct sshkey *, int); - /* XXX should be internal, but used by ssh-keygen */ - int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); - -diff --git a/ssh.1 b/ssh.1 -index b4956aec..e255b9b9 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see - .It RemoteCommand - .It RemoteForward - .It RequestTTY -+.It RequiredRSASize - .It SendEnv - .It ServerAliveInterval - .It ServerAliveCountMax -diff --git a/ssh_config.5 b/ssh_config.5 -index 24a46460..d1ede18e 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -1634,6 +1634,17 @@ and - .Fl T - flags for - .Xr ssh 1 . -+.It Cm RequiredRSASize -+Specifies the minimum RSA key size (in bits) that -+.Xr ssh 1 -+will accept. -+User authentication keys smaller than this limit will be ignored. -+Servers that present host keys smaller than this limit will cause the -+connection to be terminated. -+The default is -+.Cm 1024 -+bits. -+Note that this limit may only be raised from the default. - .It Cm RevokedHostKeys - Specifies revoked host public keys. - Keys listed in this file will be refused for host authentication. -diff --git a/sshd_config.5 b/sshd_config.5 -index 867a747d..f5a06637 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1596,6 +1596,16 @@ is - .Cm default none , - which means that rekeying is performed after the cipher's default amount - of data has been sent or received and no time based rekeying is done. -+.It Cm RequiredRSASize -+Specifies the minimum RSA key size (in bits) that -+.Xr sshd 8 -+will accept. -+User and host-based authentication keys smaller than this limit will be -+refused. -+The default is -+.Cm 1024 -+bits. -+Note that this limit may only be raised from the default. - .It Cm RevokedKeys - Specifies revoked public keys file, or - .Cm none diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch index 260ddb8..ee3637f 100644 --- a/openssh-8.7p1-negotiate-supported-algs.patch +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -1,63 +1,117 @@ -diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh ---- a/regress/hostkey-agent.sh 2021-08-20 06:03:49.000000000 +0200 -+++ b/regress/hostkey-agent.sh 2022-07-14 11:58:12.172786060 +0200 -@@ -13,8 +13,12 @@ r=$? +diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh +--- openssh-9.3p1/regress/hostkey-agent.sh.xxx 2023-05-29 18:15:56.311236887 +0200 ++++ openssh-9.3p1/regress/hostkey-agent.sh 2023-05-29 18:16:07.598503551 +0200 +@@ -17,8 +17,21 @@ trace "make CA key" ${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA" +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 || \ -@@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host + ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" + ${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \ + -I localhost-with-alias $OBJ/agent-key.$k.pub || \ +@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private unset SSH_AUTH_SOCK -for k in $SSH_KEYTYPES ; do +for k in $SSH_ACCEPTED_KEYTYPES ; do - verbose "key type $k" - cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy - echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy -diff --color -rup a/sshconnect2.c b/sshconnect2.c ---- a/sshconnect2.c 2022-07-14 10:10:07.262975710 +0200 -+++ b/sshconnect2.c 2022-07-14 10:10:32.068452067 +0200 -@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st + 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 +70,16 @@ for k in $SSH_KEYTYPES ; do + done + + SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'` ++SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"` + + # Prepare sshd_proxy for certificates. + 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 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> + ( 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 -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c +--- openssh-9.3p1/sshconnect2.c.xxx 2023-04-26 17:37:35.100827792 +0200 ++++ openssh-9.3p1/sshconnect2.c 2023-04-26 17:50:31.860748877 +0200 +@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st + const struct ssh_conn_info *cinfo) { - char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; - char *s, *all_key; -+ char *hostkeyalgs = NULL, *pkalg = NULL; - char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; + char *myproposal[PROPOSAL_MAX]; +- char *s, *all_key, *hkalgs = NULL; ++ char *s, *all_key, *hkalgs = NULL, *filtered_algs = NULL; int r, use_known_hosts_order = 0; -@@ -264,14 +265,19 @@ ssh_kex2(struct ssh *ssh, char *host, st - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - if (use_known_hosts_order) { - /* Query known_hosts and prefer algorithms that appear there */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = -- compat_pkalg_proposal(ssh, -- order_hostkeyalgs(host, hostaddr, port, cinfo)); -+ if ((hostkeyalgs = order_hostkeyalgs(host, hostaddr, port, cinfo)) == NULL) -+ fatal_f("order_hostkeyalgs"); -+ pkalg = match_filter_allowlist(hostkeyalgs, options.pubkey_accepted_algos); -+ free(hostkeyalgs); - } else { -- /* Use specified HostkeyAlgorithms exactly */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = -- compat_pkalg_proposal(ssh, options.hostkeyalgorithms); -+ /* Use specified HostkeyAlgorithms */ -+ pkalg = match_filter_allowlist(options.hostkeyalgorithms, options.pubkey_accepted_algos); - } -+ if (pkalg == NULL) -+ fatal_f("match_filter_allowlist"); -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = -+ compat_pkalg_proposal(ssh, pkalg); -+ free(pkalg); + #if defined(GSSAPI) && defined(WITH_OPENSSL) +@@ -260,9 +260,21 @@ ssh_kex2(struct ssh *ssh, char *host, st + 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, s, options.ciphers, + options.macs, compression_alg_list(options.compression), +- hkalgs ? hkalgs : options.hostkeyalgorithms); ++ filtered_algs); #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { +@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st + #endif + + free(hkalgs); ++ free(filtered_algs); + + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch index ab51204..7fea800 100644 --- a/openssh-8.7p1-nohostsha1proof.patch +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -295,6 +295,14 @@ diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c --- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100 +++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100 +@@ -80,6 +80,7 @@ + #include "auth-options.h" + #include "serverloop.h" + #include "ssherr.h" ++#include "compat.h" + + extern ServerOptions options; + @@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) sigalg = "rsa-sha2-256"; @@ -328,9 +336,9 @@ 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) - int keytype; Authctxt *authctxt; struct connection_info *connection_info = NULL; + sigset_t sigmask; + int forbid_ssh_rsa = 0; #ifdef HAVE_SECUREWARE @@ -379,38 +387,6 @@ diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c /* Prepare the channels layer */ channel_init_channels(ssh); channel_set_af(ssh, options.address_family); -diff -Nur openssh-8.7p1/ssh-keygen.c openssh-8.7p1_patched/ssh-keygen.c ---- openssh-8.7p1/ssh-keygen.c 2023-01-18 17:41:47.894515779 +0100 -+++ openssh-8.7p1_patched/ssh-keygen.c 2023-01-18 17:41:44.500488818 +0100 -@@ -491,6 +491,8 @@ - BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; - BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; - BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; -+ char rsa_safe_alg[] = "rsa-sha2-256"; -+ char *alg = NULL; - - if ((r = sshbuf_get_u32(b, &magic)) != 0) - fatal_fr(r, "parse magic"); -@@ -590,6 +592,7 @@ do_convert_private_ssh2(struct sshbuf *b - if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) - fatal_fr(r, "generate RSA parameters"); - BN_clear_free(rsa_iqmp); -+ alg = rsa_safe_alg; - break; - } - rlen = sshbuf_len(b); -@@ -598,9 +601,9 @@ do_convert_private_ssh2(struct sshbuf *b - - /* try the key */ - if (sshkey_sign(key, &sig, &slen, data, sizeof(data), -- NULL, NULL, NULL, 0) != 0 || -+ alg, NULL, NULL, 0) != 0 || - sshkey_verify(key, sig, slen, data, sizeof(data), -- NULL, 0, NULL) != 0) { -+ alg, 0, NULL) != 0) { - sshkey_free(key); - free(sig); - return NULL; 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 diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch index 5b44d92..f0d9b0f 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -5,8 +5,8 @@ diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c if (src_is_dir && iamrecursive) { if (upload_dir(conn, src, abs_dst, pflag, -- SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { -+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { +- 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; } @@ -108,8 +108,8 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c int upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, int print_flag, int resume, int fsync_flag, -- int follow_link_flag) -+ int follow_link_flag, int create_dir) +- int follow_link_flag, int inplace_flag) ++ int follow_link_flag, int inplace_flag, int create_dir) { char *dst_canon; int ret; @@ -143,9 +143,9 @@ diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h @@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const * times if 'pflag' is set */ - int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, -- int, int); -+ int, int, int); + int 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 @@ -156,8 +156,8 @@ diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, -- fflag || global_fflag, 0) == -1) -+ fflag || global_fflag, 0, 0) == -1) +- fflag || global_fflag, 0, 0) == -1) ++ fflag || global_fflag, 0, 0, 0) == -1) err = -1; } else { if (do_upload(conn, g.gl_pathv[i], abs_dst, diff --git a/openssh-8.7p1-scp-clears-file.patch b/openssh-8.7p1-scp-clears-file.patch deleted file mode 100644 index 3ecff1e..0000000 --- a/openssh-8.7p1-scp-clears-file.patch +++ /dev/null @@ -1,303 +0,0 @@ -diff --color -rup a/scp.c b/scp.c ---- a/scp.c 2022-07-26 14:51:40.560120817 +0200 -+++ b/scp.c 2022-07-26 14:52:37.118213004 +0200 -@@ -1324,11 +1324,11 @@ source_sftp(int argc, char *src, char *t - - if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, -- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { -+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) { - error("failed to upload directory %s to %s", src, targ); - errs = 1; - } -- } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) { -+ } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) { - error("failed to upload file %s to %s", src, targ); - errs = 1; - } -@@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha - debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); - if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { - if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, -- pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1) -+ pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1) - err = -1; - } else { - if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, -- pflag, 0, 0) == -1) -+ pflag, 0, 0, 1) == -1) - err = -1; - } - free(abs_dst); -diff --color -rup a/sftp.c b/sftp.c ---- a/sftp.c 2022-07-26 14:51:40.561120836 +0200 -+++ b/sftp.c 2022-07-26 14:52:37.119213023 +0200 -@@ -666,12 +666,12 @@ process_get(struct sftp_conn *conn, cons - if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { - if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, 1, resume, -- fflag || global_fflag, 0) == -1) -+ fflag || global_fflag, 0, 0) == -1) - err = -1; - } else { - if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, - pflag || global_pflag, resume, -- fflag || global_fflag) == -1) -+ fflag || global_fflag, 0) == -1) - err = -1; - } - free(abs_dst); -@@ -760,12 +760,12 @@ process_put(struct sftp_conn *conn, cons - if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { - if (upload_dir(conn, g.gl_pathv[i], abs_dst, - pflag || global_pflag, 1, resume, -- fflag || global_fflag, 0, 0) == -1) -+ fflag || global_fflag, 0, 0, 0) == -1) - err = -1; - } else { - if (do_upload(conn, g.gl_pathv[i], abs_dst, - pflag || global_pflag, resume, -- fflag || global_fflag) == -1) -+ fflag || global_fflag, 0) == -1) - err = -1; - } - } -diff --color -rup a/sftp-client.c b/sftp-client.c ---- a/sftp-client.c 2022-07-26 14:51:40.561120836 +0200 -+++ b/sftp-client.c 2022-07-26 15:09:54.825295533 +0200 -@@ -1454,7 +1454,7 @@ progress_meter_path(const char *path) - int - do_download(struct sftp_conn *conn, const char *remote_path, - const char *local_path, Attrib *a, int preserve_flag, int resume_flag, -- int fsync_flag) -+ int fsync_flag, int inplace_flag) - { - struct sshbuf *msg; - u_char *handle; -@@ -1498,8 +1498,8 @@ do_download(struct sftp_conn *conn, cons - &handle, &handle_len) != 0) - return -1; - -- local_fd = open(local_path, -- O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); -+ local_fd = open(local_path, O_WRONLY | O_CREAT | -+ ((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR); - if (local_fd == -1) { - error("open local \"%s\": %s", local_path, strerror(errno)); - goto fail; -@@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons - /* Sanity check */ - if (TAILQ_FIRST(&requests) != NULL) - fatal("Transfer complete, but requests still in queue"); -- /* Truncate at highest contiguous point to avoid holes on interrupt */ -- if (read_error || write_error || interrupted) { -+ /* -+ * Truncate at highest contiguous point to avoid holes on interrupt, -+ * or unconditionally if writing in place. -+ */ -+ if (inplace_flag || read_error || write_error || interrupted) { - if (reordered && resume_flag) { - error("Unable to resume download of \"%s\": " - "server reordered requests", local_path); -@@ -1724,7 +1727,7 @@ do_download(struct sftp_conn *conn, cons - static int - download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - int depth, Attrib *dirattrib, int preserve_flag, int print_flag, -- int resume_flag, int fsync_flag, int follow_link_flag) -+ int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag) - { - int i, ret = 0; - SFTP_DIRENT **dir_entries; -@@ -1781,7 +1784,7 @@ download_dir_internal(struct sftp_conn * - if (download_dir_internal(conn, new_src, new_dst, - depth + 1, &(dir_entries[i]->a), preserve_flag, - print_flag, resume_flag, -- fsync_flag, follow_link_flag) == -1) -+ fsync_flag, follow_link_flag, inplace_flag) == -1) - ret = -1; - } else if (S_ISREG(dir_entries[i]->a.perm) || - (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) { -@@ -1793,7 +1796,8 @@ download_dir_internal(struct sftp_conn * - if (do_download(conn, new_src, new_dst, - S_ISLNK(dir_entries[i]->a.perm) ? NULL : - &(dir_entries[i]->a), -- preserve_flag, resume_flag, fsync_flag) == -1) { -+ preserve_flag, resume_flag, fsync_flag, -+ inplace_flag) == -1) { - error("Download of file %s to %s failed", - new_src, new_dst); - ret = -1; -@@ -1831,7 +1835,7 @@ download_dir_internal(struct sftp_conn * - int - download_dir(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, -- int fsync_flag, int follow_link_flag) -+ int fsync_flag, int follow_link_flag, int inplace_flag) - { - char *src_canon; - int ret; -@@ -1843,26 +1847,25 @@ download_dir(struct sftp_conn *conn, con - - ret = download_dir_internal(conn, src_canon, dst, 0, - dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag, -- follow_link_flag); -+ follow_link_flag, inplace_flag); - free(src_canon); - return ret; - } - - int - do_upload(struct sftp_conn *conn, const char *local_path, -- const char *remote_path, int preserve_flag, int resume, int fsync_flag) -+ const char *remote_path, int preserve_flag, int resume, -+ int fsync_flag, int inplace_flag) - { - int r, local_fd; -- u_int status = SSH2_FX_OK; -- u_int id; -- u_char type; -+ u_int openmode, id, status = SSH2_FX_OK, reordered = 0; - off_t offset, progress_counter; -- u_char *handle, *data; -+ u_char type, *handle, *data; - struct sshbuf *msg; - struct stat sb; -- Attrib a, *c = NULL; -- u_int32_t startid; -- u_int32_t ackid; -+ Attrib a, t, *c = NULL; -+ u_int32_t startid, ackid; -+ u_int64_t highwater = 0; - struct request *ack = NULL; - struct requests acks; - size_t handle_len; -@@ -1913,10 +1916,15 @@ do_upload(struct sftp_conn *conn, const - } - } - -+ openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT; -+ if (resume) -+ openmode |= SSH2_FXF_APPEND; -+ else if (!inplace_flag) -+ openmode |= SSH2_FXF_TRUNC; -+ - /* Send open request */ -- if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT| -- (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC), -- &a, &handle, &handle_len) != 0) { -+ if (send_open(conn, remote_path, "dest", openmode, &a, -+ &handle, &handle_len) != 0) { - close(local_fd); - return -1; - } -@@ -1999,6 +2007,12 @@ do_upload(struct sftp_conn *conn, const - ack->id, ack->len, (unsigned long long)ack->offset); - ++ackid; - progress_counter += ack->len; -+ if (!reordered && ack->offset <= highwater) -+ highwater = ack->offset + ack->len; -+ else if (!reordered && ack->offset > highwater) { -+ debug3_f("server reordered ACKs"); -+ reordered = 1; -+ } - free(ack); - } - offset += len; -@@ -2017,6 +2031,14 @@ do_upload(struct sftp_conn *conn, const - status = SSH2_FX_FAILURE; - } - -+ if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) { -+ debug("truncating at %llu", (unsigned long long)highwater); -+ attrib_clear(&t); -+ t.flags = SSH2_FILEXFER_ATTR_SIZE; -+ t.size = highwater; -+ do_fsetstat(conn, handle, handle_len, &t); -+ } -+ - if (close(local_fd) == -1) { - error("close local \"%s\": %s", local_path, strerror(errno)); - status = SSH2_FX_FAILURE; -@@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const - static int - upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - int depth, int preserve_flag, int print_flag, int resume, int fsync_flag, -- int follow_link_flag) -+ int follow_link_flag, int inplace_flag) - { - int ret = 0; - DIR *dirp; -@@ -2119,12 +2141,13 @@ upload_dir_internal(struct sftp_conn *co - - if (upload_dir_internal(conn, new_src, new_dst, - depth + 1, preserve_flag, print_flag, resume, -- fsync_flag, follow_link_flag) == -1) -+ fsync_flag, follow_link_flag, inplace_flag) == -1) - ret = -1; - } else if (S_ISREG(sb.st_mode) || - (follow_link_flag && S_ISLNK(sb.st_mode))) { - if (do_upload(conn, new_src, new_dst, -- preserve_flag, resume, fsync_flag) == -1) { -+ preserve_flag, resume, fsync_flag, -+ inplace_flag) == -1) { - error("upload \"%s\" to \"%s\" failed", - new_src, new_dst); - ret = -1; -@@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co - int - upload_dir(struct sftp_conn *conn, const char *src, const char *dst, - int preserve_flag, int print_flag, int resume, int fsync_flag, -- int follow_link_flag, int create_dir) -+ int follow_link_flag, int create_dir, int inplace_flag) - { - char *dst_canon; - int ret; -@@ -2155,7 +2178,7 @@ upload_dir(struct sftp_conn *conn, const - } - - ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, -- print_flag, resume, fsync_flag, follow_link_flag); -+ print_flag, resume, fsync_flag, follow_link_flag, inplace_flag); - - free(dst_canon); - return ret; -diff --color -rup a/sftp-client.h b/sftp-client.h ---- a/sftp-client.h 2022-07-26 14:51:40.561120836 +0200 -+++ b/sftp-client.h 2022-07-26 14:52:37.120213042 +0200 -@@ -138,28 +138,29 @@ int do_fsync(struct sftp_conn *conn, u_c - * Download 'remote_path' to 'local_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_download(struct sftp_conn *, const char *, const char *, -- Attrib *, int, int, int); -+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, -+ int, int, int, int); - - /* - * Recursively download 'remote_directory' to 'local_directory'. Preserve - * times if 'pflag' is set - */ --int download_dir(struct sftp_conn *, const char *, const char *, -- Attrib *, int, int, int, int, int); -+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, -+ int, int, int, int, int, int); - - /* - * Upload 'local_path' to 'remote_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_upload(struct sftp_conn *, const char *, const char *, int, int, int); -+int do_upload(struct sftp_conn *, const char *, const char *, -+ int, int, int, int); - - /* - * Recursively upload 'local_directory' to 'remote_directory'. Preserve - * times if 'pflag' is set - */ --int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, -- int, int, int); -+int upload_dir(struct sftp_conn *, const char *, const char *, -+ int, int, int, int, int, int, int); - - /* - * Download a 'from_path' from the 'from' connection and upload it to diff --git a/openssh-8.7p1-scp-kill-switch.patch b/openssh-8.7p1-scp-kill-switch.patch index 6710304..161ab2d 100644 --- a/openssh-8.7p1-scp-kill-switch.patch +++ b/openssh-8.7p1-scp-kill-switch.patch @@ -13,8 +13,8 @@ diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 --- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200 +++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200 @@ -278,6 +278,13 @@ to print debugging messages about their - This is helpful in - debugging connection, authentication, and configuration problems. + By default a 32KB buffer is used. + .El .El +.Pp +Usage of SCP protocol can be blocked by creating a world-readable diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch index 04e4c06..c7f6f1e 100644 --- a/openssh-8.7p1-ssh-manpage.patch +++ b/openssh-8.7p1-ssh-manpage.patch @@ -14,9 +14,9 @@ diff --color -ru a/ssh.1 b/ssh.1 .It ControlPersist .It DynamicForward +.It EnableSSHKeysign + .It EnableEscapeCommandline .It EscapeChar .It ExitOnForwardFailure - .It FingerprintHash @@ -538,6 +540,8 @@ .It IdentitiesOnly .It IdentityAgent diff --git a/openssh-9.0p1-evp-fips-dh.patch b/openssh-9.0p1-evp-fips-dh.patch index 7494245..d0470d9 100644 --- a/openssh-9.0p1-evp-fips-dh.patch +++ b/openssh-9.0p1-evp-fips-dh.patch @@ -1,7 +1,7 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/dh.c ./dh.c ---- ../../openssh-8.7p1/dh.c 2023-03-01 14:26:52.504445780 +0100 -+++ ./dh.c 2023-03-01 14:20:09.823193384 +0100 -@@ -37,6 +37,9 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/dh.c openssh-9.0p1-patched/dh.c +--- openssh-9.0p1/dh.c 2023-05-25 09:24:28.730868316 +0200 ++++ openssh-9.0p1-patched/dh.c 2023-05-25 09:23:44.841379532 +0200 +@@ -37,6 +37,9 @@ #include #include #include @@ -11,7 +11,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include "dh.h" #include "pathnames.h" -@@ -289,10 +292,15 @@ +@@ -290,10 +293,15 @@ int dh_gen_key(DH *dh, int need) { @@ -30,7 +30,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x if (need < 0 || dh_p == NULL || (pbits = BN_num_bits(dh_p)) <= 0 || -@@ -300,19 +308,85 @@ +@@ -301,19 +309,85 @@ return SSH_ERR_INVALID_ARGUMENT; if (need < 256) need = 256; @@ -125,10 +125,10 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x } DH * -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kex.c ./kex.c ---- ../../openssh-8.7p1/kex.c 2023-03-01 14:26:52.508445832 +0100 -+++ ./kex.c 2023-02-28 14:09:27.164743771 +0100 -@@ -1602,3 +1602,47 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c +--- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200 ++++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200 +@@ -1623,3 +1623,47 @@ return r; } @@ -176,20 +176,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return r; +} +#endif /* WITH_OPENSSL */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kexdh.c ./kexdh.c ---- ../../openssh-8.7p1/kexdh.c 2023-03-01 14:26:52.448445050 +0100 -+++ ./kexdh.c 2023-02-28 14:05:00.700902124 +0100 -@@ -35,6 +35,9 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kexdh.c openssh-9.0p1-patched/kexdh.c +--- openssh-9.0p1/kexdh.c 2023-05-25 09:24:28.674867692 +0200 ++++ openssh-9.0p1-patched/kexdh.c 2023-05-25 09:25:28.494533889 +0200 +@@ -35,6 +35,10 @@ #include "openbsd-compat/openssl-compat.h" #include ++#include +#include +#include +#include #include "sshkey.h" #include "kex.h" -@@ -83,6 +86,9 @@ +@@ -83,9 +87,12 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) { BIGNUM *shared_secret = NULL; @@ -198,22 +199,35 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + EVP_PKEY_CTX *ctx = NULL; u_char *kbuf = NULL; size_t klen = 0; - int kout, r; -@@ -106,18 +112,39 @@ - r = SSH_ERR_ALLOC_FAIL; +- int kout, r; ++ int kout, r = 0; + + #ifdef DEBUG_KEXDH + fprintf(stderr, "dh_pub= "); +@@ -100,24 +107,59 @@ + r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } -- if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 || -- BN_bin2bn(kbuf, kout, shared_secret) == NULL) { +- klen = DH_size(kex->dh); + + DH_get0_key(kex->dh, &pub, &priv); + DH_get0_pqg(kex->dh, &p, &q, &g); + /* import key */ -+ kex_create_evp_dh(&pkey, p, q, g, pub, priv); ++ 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 + */ -+ kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL); ++ 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"); @@ -222,7 +236,19 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + } + if (EVP_PKEY_derive_init(ctx) != 1 || + EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 || -+ EVP_PKEY_derive(ctx, kbuf, &klen) != 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; @@ -242,9 +268,9 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x return r; } -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/kex.h ./kex.h ---- ../../openssh-8.7p1/kex.h 2023-03-01 14:26:52.508445832 +0100 -+++ ./kex.h 2023-02-28 13:16:49.811047554 +0100 +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.h openssh-9.0p1-patched/kex.h +--- openssh-9.0p1/kex.h 2023-05-25 09:24:28.725868260 +0200 ++++ openssh-9.0p1-patched/kex.h 2023-05-25 09:23:44.841379532 +0200 @@ -33,6 +33,9 @@ # include # include @@ -255,7 +281,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ -@@ -278,6 +281,8 @@ +@@ -283,6 +286,8 @@ const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --git a/openssh-9.0p1-evp-fips-sign.patch b/openssh-9.0p1-evp-fips-sign.patch index fc71678..40cc374 100644 --- a/openssh-9.0p1-evp-fips-sign.patch +++ b/openssh-9.0p1-evp-fips-sign.patch @@ -1,6 +1,6 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-dss.c ./ssh-dss.c ---- ../../openssh-8.7p1/ssh-dss.c 2023-03-08 15:35:14.669943335 +0100 -+++ ./ssh-dss.c 2023-03-08 15:34:33.508578129 +0100 +diff -up openssh-9.3p1/ssh-dss.c.evp-fips-sign openssh-9.3p1/ssh-dss.c +--- openssh-9.3p1/ssh-dss.c.evp-fips-sign 2023-04-27 16:46:17.115809116 +0200 ++++ openssh-9.3p1/ssh-dss.c 2023-04-27 17:07:40.117253665 +0200 @@ -32,6 +32,8 @@ #include #include @@ -10,7 +10,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include #include -@@ -72,9 +74,8 @@ +@@ -281,9 +283,8 @@ ssh_dss_sign(struct sshkey *key, sshkey_type_plain(key->type) != KEY_DSA) return SSH_ERR_INVALID_ARGUMENT; @@ -22,7 +22,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, data, datalen); EVP_PKEY_free(pkey); -@@ -201,11 +202,8 @@ +@@ -411,11 +412,8 @@ ssh_dss_verify(const struct sshkey *key, goto out; } @@ -32,14 +32,13 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) goto out; - } - ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen, + ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, sigb, slen); EVP_PKEY_free(pkey); -@@ -221,4 +219,63 @@ - freezero(sigblob, len); +@@ -432,6 +430,65 @@ ssh_dss_verify(const struct sshkey *key, return ret; } -+ + +int +ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) +{ @@ -98,10 +97,13 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + EVP_PKEY_CTX_free(ctx); + return ret; +} - #endif /* WITH_OPENSSL */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-ecdsa.c ./ssh-ecdsa.c ---- ../../openssh-8.7p1/ssh-ecdsa.c 2023-03-08 15:35:14.669943335 +0100 -+++ ./ssh-ecdsa.c 2023-03-08 15:40:52.628201267 +0100 ++ + static const struct sshkey_impl_funcs sshkey_dss_funcs = { + /* .size = */ ssh_dss_size, + /* .alloc = */ ssh_dss_alloc, +diff -up openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign openssh-9.3p1/ssh-ecdsa.c +--- openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign 2023-04-27 16:46:17.127809401 +0200 ++++ openssh-9.3p1/ssh-ecdsa.c 2023-04-27 17:08:28.557396513 +0200 @@ -34,6 +34,8 @@ #include #include @@ -111,7 +113,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include -@@ -72,9 +74,8 @@ +@@ -260,9 +262,8 @@ ssh_ecdsa_sign(struct sshkey *key, if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; @@ -121,9 +123,9 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) + return ret; ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, - datalen); + dlen); EVP_PKEY_free(pkey); -@@ -193,11 +194,8 @@ +@@ -381,11 +382,8 @@ ssh_ecdsa_verify(const struct sshkey *ke goto out; } @@ -133,10 +135,10 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) goto out; - } - ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len); + ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len); EVP_PKEY_free(pkey); -@@ -212,4 +210,76 @@ +@@ -400,6 +398,79 @@ ssh_ecdsa_verify(const struct sshkey *ke return ret; } @@ -212,10 +214,13 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + free(pub_ser); + return ret; +} - #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.c ./sshkey.c ---- ../../openssh-8.7p1/sshkey.c 2023-03-08 15:35:14.702943628 +0100 -+++ ./sshkey.c 2023-03-08 15:39:03.354082015 +0100 ++ + /* NB. not static; used by ECDSA-SK */ + const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { + /* .size = */ ssh_ecdsa_size, +diff -up openssh-9.3p1/sshkey.c.evp-fips-sign openssh-9.3p1/sshkey.c +--- openssh-9.3p1/sshkey.c.evp-fips-sign 2023-04-27 16:46:17.139809686 +0200 ++++ openssh-9.3p1/sshkey.c 2023-04-27 16:46:17.144809804 +0200 @@ -35,6 +35,8 @@ #include #include @@ -225,7 +230,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #endif #include "crypto_api.h" -@@ -492,13 +494,14 @@ +@@ -527,13 +529,14 @@ sshkey_calculate_signature(EVP_PKEY *pke { EVP_MD_CTX *ctx = NULL; u_char *sig = NULL; @@ -242,7 +247,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; -@@ -511,9 +514,10 @@ +@@ -546,9 +549,10 @@ sshkey_calculate_signature(EVP_PKEY *pke ret = SSH_ERR_ALLOC_FAIL; goto error; } @@ -256,7 +261,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x ret = SSH_ERR_LIBCRYPTO_ERROR; goto error; } -@@ -540,12 +544,13 @@ +@@ -575,12 +579,13 @@ sshkey_verify_signature(EVP_PKEY *pkey, if ((ctx = EVP_MD_CTX_new()) == NULL) { return SSH_ERR_ALLOC_FAIL; } @@ -273,7 +278,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x switch (ret) { case 1: ret = 0; -@@ -5038,3 +5043,27 @@ +@@ -3809,3 +3814,27 @@ sshkey_set_filename(struct sshkey *k, co return 0; } #endif /* WITH_XMSS */ @@ -301,9 +306,9 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return ret; +} +#endif /* WITH_OPENSSL */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.h ./sshkey.h ---- ../../openssh-8.7p1/sshkey.h 2023-03-08 15:35:14.702943628 +0100 -+++ ./sshkey.h 2023-03-08 15:34:33.509578138 +0100 +diff -up openssh-9.3p1/sshkey.h.evp-fips-sign openssh-9.3p1/sshkey.h +--- openssh-9.3p1/sshkey.h.evp-fips-sign 2023-04-27 16:46:17.133809543 +0200 ++++ openssh-9.3p1/sshkey.h 2023-04-27 16:46:17.144809804 +0200 @@ -31,6 +31,9 @@ #ifdef WITH_OPENSSL #include @@ -314,7 +319,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # include -@@ -293,6 +295,13 @@ +@@ -328,6 +331,13 @@ int sshkey_private_serialize_maxsign(st void sshkey_sig_details_free(struct sshkey_sig_details *); @@ -326,21 +331,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x +#endif /* WITH_OPENSSL */ + #ifdef SSHKEY_INTERNAL - int ssh_rsa_sign(const struct sshkey *key, - u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-rsa.c ./ssh-rsa.c ---- ../../openssh-8.7p1/ssh-rsa.c 2023-03-08 15:35:14.669943335 +0100 -+++ ./ssh-rsa.c 2023-03-08 15:34:33.509578138 +0100 + int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); + void sshkey_sk_cleanup(struct sshkey *k); +diff -up openssh-9.3p1/ssh-rsa.c.evp-fips-sign openssh-9.3p1/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c.evp-fips-sign 2023-04-27 16:46:17.139809686 +0200 ++++ openssh-9.3p1/ssh-rsa.c 2023-04-27 17:10:30.376270565 +0200 @@ -23,6 +23,8 @@ - #include #include + #include +#include +#include #include #include -@@ -172,9 +174,8 @@ +@@ -426,9 +428,8 @@ ssh_rsa_sign(struct sshkey *key, if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_KEY_LENGTH; @@ -352,7 +357,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, datalen); EVP_PKEY_free(pkey); -@@ -285,11 +286,8 @@ +@@ -540,11 +541,9 @@ ssh_rsa_verify(const struct sshkey *key, len = modlen; } @@ -362,10 +367,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) goto out; - } - ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey); ++ + ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); EVP_PKEY_free(pkey); -@@ -306,11 +304,9 @@ +@@ -561,11 +560,9 @@ openssh_RSA_verify(int hash_alg, const u u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) { size_t rsasize = 0; @@ -378,11 +384,10 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || siglen == 0 || siglen > rsasize) { ret = SSH_ERR_INVALID_ARGUMENT; -@@ -323,4 +319,87 @@ - done: +@@ -579,6 +576,89 @@ done: return ret; } -+ + +int +ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) +{ @@ -465,4 +470,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + EVP_PKEY_CTX_free(ctx); + return ret; +} - #endif /* WITH_OPENSSL */ ++ + static const struct sshkey_impl_funcs sshkey_rsa_funcs = { + /* .size = */ ssh_rsa_size, + /* .alloc = */ ssh_rsa_alloc, diff --git a/openssh-9.0p1-evp-pkcs11.patch b/openssh-9.0p1-evp-pkcs11.patch new file mode 100644 index 0000000..325332d --- /dev/null +++ b/openssh-9.0p1-evp-pkcs11.patch @@ -0,0 +1,145 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-ecdsa.c openssh-9.0p1-patched/ssh-ecdsa.c +--- openssh-9.0p1/ssh-ecdsa.c 2023-05-24 08:54:03.926443958 +0200 ++++ openssh-9.0p1-patched/ssh-ecdsa.c 2023-05-24 09:46:19.082925921 +0200 +@@ -74,8 +74,18 @@ + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) + return SSH_ERR_INTERNAL_ERROR; + +- if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) +- return ret; ++#ifdef ENABLE_PKCS11 ++ if (is_ecdsa_pkcs11(key->ecdsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 ++ } ++#endif + ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, + dlen); + EVP_PKEY_free(pkey); +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/sshkey.h openssh-9.0p1-patched/sshkey.h +--- openssh-9.0p1/sshkey.h 2023-05-24 08:54:03.926443958 +0200 ++++ openssh-9.0p1-patched/sshkey.h 2023-05-24 08:57:22.930642788 +0200 +@@ -340,6 +340,10 @@ + #endif + #endif + ++#ifdef ENABLE_PKCS11 ++int pkcs11_get_ecdsa_idx(void); ++#endif ++ + #if !defined(WITH_OPENSSL) + # undef RSA + # undef DSA +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11.c openssh-9.0p1-patched/ssh-pkcs11.c +--- openssh-9.0p1/ssh-pkcs11.c 2023-05-24 08:54:03.888443542 +0200 ++++ openssh-9.0p1-patched/ssh-pkcs11.c 2023-05-24 09:48:13.101168512 +0200 +@@ -776,8 +776,24 @@ + + return (0); + } ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ if (RSA_get_ex_data(rsa, rsa_idx) != NULL) ++ return 1; ++ return 0; ++} ++ + /* remove trailing spaces */ + static void + rmspace(u_char *buf, size_t len) +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11-client.c openssh-9.0p1-patched/ssh-pkcs11-client.c +--- openssh-9.0p1/ssh-pkcs11-client.c 2023-05-24 08:54:03.887443531 +0200 ++++ openssh-9.0p1-patched/ssh-pkcs11-client.c 2023-05-24 09:49:41.741134514 +0200 +@@ -225,8 +225,36 @@ + static RSA_METHOD *helper_rsa; + #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + static EC_KEY_METHOD *helper_ecdsa; ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ const EC_KEY_METHOD *meth; ++ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen, ++ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL; ++ ++ meth = EC_KEY_get_method(ecdsa); ++ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig); ++ if (sign_sig == ecdsa_do_sign) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ const RSA_METHOD *meth; ++ int (*priv_enc)(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) = NULL; ++ ++ meth = RSA_get_method(rsa); ++ priv_enc = RSA_meth_get_priv_enc(meth); ++ if (priv_enc == rsa_encrypt) ++ return 1; ++ return 0; ++} ++ + /* redirect private key crypto operations to the ssh-pkcs11-helper */ + static void + wrap_key(struct sshkey *k) +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11.h openssh-9.0p1-patched/ssh-pkcs11.h +--- openssh-9.0p1/ssh-pkcs11.h 2023-05-24 08:54:03.888443542 +0200 ++++ openssh-9.0p1-patched/ssh-pkcs11.h 2023-05-24 09:50:03.981376886 +0200 +@@ -39,6 +39,11 @@ + u_int32_t *); + #endif + ++#ifdef HAVE_EC_KEY_METHOD_NEW ++int is_ecdsa_pkcs11(EC_KEY *ecdsa); ++#endif ++int is_rsa_pkcs11(RSA *rsa); ++ + #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) + #undef ENABLE_PKCS11 + #endif +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-rsa.c openssh-9.0p1-patched/ssh-rsa.c +--- openssh-9.0p1/ssh-rsa.c 2023-05-24 08:54:03.927443969 +0200 ++++ openssh-9.0p1-patched/ssh-rsa.c 2023-05-24 09:51:50.358536178 +0200 +@@ -174,8 +174,18 @@ + if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; + +- if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) +- return ret; ++#ifdef ENABLE_PKCS11 ++ if (is_rsa_pkcs11(key->rsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 ++ } ++#endif + ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, + datalen); + EVP_PKEY_free(pkey); diff --git a/openssh-9.0p1-man-hostkeyalgos.patch b/openssh-9.0p1-man-hostkeyalgos.patch new file mode 100644 index 0000000..2b16c2b --- /dev/null +++ b/openssh-9.0p1-man-hostkeyalgos.patch @@ -0,0 +1,16 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh_config.5 openssh-8.7p1-patched/ssh_config.5 +--- openssh-8.7p1/ssh_config.5 2023-05-29 13:41:19.731835097 +0200 ++++ openssh-8.7p1-patched/ssh_config.5 2023-05-29 13:40:58.806604144 +0200 +@@ -989,6 +989,12 @@ + .Pp + The list of available signature algorithms may also be obtained using + .Qq ssh -Q HostKeyAlgorithms . ++.Pp ++.Xr crypto_policies 7 does not handle the list of algorithms as doing so ++would break the order given by the ++.Pa known_hosts ++file. Therefore the list is filtered by ++.Cm PubkeyAcceptedAlgorithms. + .It Cm HostKeyAlias + Specifies an alias that should be used instead of the + real host name when looking up or saving the host key diff --git a/openssh-9.0p1-gsissh.patch b/openssh-9.3p1-gsissh.patch similarity index 88% rename from openssh-9.0p1-gsissh.patch rename to openssh-9.3p1-gsissh.patch index 0e848a9..acf160d 100644 --- a/openssh-9.0p1-gsissh.patch +++ b/openssh-9.3p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c ---- openssh-9.0p1.orig/auth2.c 2022-08-30 19:32:35.491051041 +0200 -+++ openssh-9.0p1/auth2.c 2022-08-30 19:41:39.812458921 +0200 -@@ -278,7 +278,28 @@ +diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c +--- openssh-9.3p1.orig/auth2.c 2023-06-26 17:34:46.576956191 +0200 ++++ openssh-9.3p1/auth2.c 2023-06-26 17:36:05.807175554 +0200 +@@ -275,7 +275,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) goto out; @@ -31,7 +31,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -291,11 +312,33 @@ +@@ -288,11 +309,33 @@ if (authctxt->attempt >= 1024) auth_maxtries_exceeded(ssh); @@ -69,7 +69,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); } else { -@@ -303,6 +346,9 @@ +@@ -300,6 +343,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -79,7 +79,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(ssh)); -@@ -311,6 +357,7 @@ +@@ -308,6 +354,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -87,7 +87,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -326,9 +373,10 @@ +@@ -323,9 +370,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -101,9 +101,9 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-9.0p1.orig/auth2-gss.c openssh-9.0p1/auth2-gss.c ---- openssh-9.0p1.orig/auth2-gss.c 2022-08-30 19:32:35.318050592 +0200 -+++ openssh-9.0p1/auth2-gss.c 2022-08-30 19:33:23.884176392 +0200 +diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c +--- openssh-9.3p1.orig/auth2-gss.c 2023-06-26 17:34:46.462955875 +0200 ++++ openssh-9.3p1/auth2-gss.c 2023-06-26 17:36:05.808175557 +0200 @@ -50,6 +50,7 @@ extern ServerOptions options; @@ -307,11 +307,11 @@ diff -Nur openssh-9.0p1.orig/auth2-gss.c openssh-9.0p1/auth2-gss.c + Authmethod method_gsskeyex = { "gssapi-keyex", - userauth_gsskeyex, -diff -Nur openssh-9.0p1.orig/auth.c openssh-9.0p1/auth.c ---- openssh-9.0p1.orig/auth.c 2022-08-30 19:32:35.492051043 +0200 -+++ openssh-9.0p1/auth.c 2022-08-30 19:33:23.884176392 +0200 -@@ -300,7 +300,8 @@ + NULL, +diff -Nur openssh-9.3p1.orig/auth.c openssh-9.3p1/auth.c +--- openssh-9.3p1.orig/auth.c 2023-06-26 17:34:46.577956193 +0200 ++++ openssh-9.3p1/auth.c 2023-06-26 17:36:05.808175557 +0200 +@@ -299,7 +299,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -321,7 +321,7 @@ diff -Nur openssh-9.0p1.orig/auth.c openssh-9.0p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -544,13 +545,18 @@ +@@ -487,13 +488,18 @@ #endif pw = getpwnam(user); @@ -341,10 +341,10 @@ diff -Nur openssh-9.0p1.orig/auth.c openssh-9.0p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-9.0p1.orig/auth.h openssh-9.0p1/auth.h ---- openssh-9.0p1.orig/auth.h 2022-08-30 19:32:35.493051046 +0200 -+++ openssh-9.0p1/auth.h 2022-08-30 19:33:23.885176394 +0200 -@@ -83,6 +83,8 @@ +diff -Nur openssh-9.3p1.orig/auth.h openssh-9.3p1/auth.h +--- openssh-9.3p1.orig/auth.h 2023-06-26 17:34:46.578956196 +0200 ++++ openssh-9.3p1/auth.h 2023-06-26 17:36:05.809175560 +0200 +@@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; char *krb5_ccname; @@ -353,18 +353,18 @@ diff -Nur openssh-9.0p1.orig/auth.h openssh-9.0p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c ---- openssh-9.0p1.orig/auth-pam.c 2022-08-30 19:32:35.455050947 +0200 -+++ openssh-9.0p1/auth-pam.c 2022-08-30 19:33:23.886176397 +0200 -@@ -253,6 +253,7 @@ +diff -Nur openssh-9.3p1.orig/auth-pam.c openssh-9.3p1/auth-pam.c +--- openssh-9.3p1.orig/auth-pam.c 2023-06-26 17:34:46.562956152 +0200 ++++ openssh-9.3p1/auth-pam.c 2023-06-26 17:45:46.130781404 +0200 +@@ -252,6 +252,7 @@ + static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; - static char *sshpam_conninfo = NULL; +static struct ssh *sshpam_ssh = NULL; /* Some PAM implementations don't implement this */ #ifndef HAVE_PAM_GETENVLIST -@@ -301,6 +302,56 @@ +@@ -300,6 +301,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -421,7 +421,7 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c static void sshpam_password_change_required(int reqd) { -@@ -332,7 +383,7 @@ +@@ -331,7 +382,7 @@ static void import_environments(struct sshbuf *b) { @@ -430,7 +430,7 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c u_int n, i, num_env; int r; -@@ -348,6 +399,19 @@ +@@ -347,6 +398,19 @@ if ((r = sshbuf_get_u32(b, &n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshpam_password_change_required(n != 0); @@ -450,7 +450,7 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -522,6 +586,13 @@ +@@ -526,6 +590,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -464,7 +464,7 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c if (!do_pam_account()) { /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN. * Backward compatibility for other errors. */ -@@ -546,6 +617,13 @@ +@@ -550,6 +621,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -478,16 +478,16 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { -@@ -738,6 +816,8 @@ - xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d", - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), - sshpam_laddr, ssh_local_port(ssh)); +@@ -740,6 +818,8 @@ + options.use_dns)); + sshpam_laddr = get_local_ipaddr( + ssh_packet_get_connection_in(ssh)); + /* Save so allowed_user can be called later */ + sshpam_ssh = ssh; } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1083,6 +1163,18 @@ +@@ -1094,6 +1174,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -506,7 +506,7 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1371,6 +1463,9 @@ +@@ -1382,6 +1474,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -516,9 +516,9 @@ diff -Nur openssh-9.0p1.orig/auth-pam.c openssh-9.0p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-9.0p1.orig/auth-pam.h openssh-9.0p1/auth-pam.h ---- openssh-9.0p1.orig/auth-pam.h 2022-08-30 19:32:35.267050460 +0200 -+++ openssh-9.0p1/auth-pam.h 2022-08-30 19:33:23.886176397 +0200 +diff -Nur openssh-9.3p1.orig/auth-pam.h openssh-9.3p1/auth-pam.h +--- openssh-9.3p1.orig/auth-pam.h 2023-06-26 17:34:46.430955786 +0200 ++++ openssh-9.3p1/auth-pam.h 2023-06-26 17:36:05.812175568 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -526,9 +526,9 @@ diff -Nur openssh-9.0p1.orig/auth-pam.h openssh-9.0p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-9.0p1.orig/canohost.c openssh-9.0p1/canohost.c ---- openssh-9.0p1.orig/canohost.c 2022-08-30 19:32:35.318050592 +0200 -+++ openssh-9.0p1/canohost.c 2022-08-30 19:33:23.887176400 +0200 +diff -Nur openssh-9.3p1.orig/canohost.c openssh-9.3p1/canohost.c +--- openssh-9.3p1.orig/canohost.c 2023-06-26 17:34:46.463955878 +0200 ++++ openssh-9.3p1/canohost.c 2023-06-26 17:36:05.812175568 +0200 @@ -17,6 +17,7 @@ #include #include @@ -537,7 +537,7 @@ diff -Nur openssh-9.0p1.orig/canohost.c openssh-9.0p1/canohost.c #include #include -@@ -295,3 +296,33 @@ +@@ -298,3 +299,33 @@ { return get_sock_port(sock, 1); } @@ -571,9 +571,9 @@ diff -Nur openssh-9.0p1.orig/canohost.c openssh-9.0p1/canohost.c + } + } +} -diff -Nur openssh-9.0p1.orig/canohost.h openssh-9.0p1/canohost.h ---- openssh-9.0p1.orig/canohost.h 2022-08-30 19:32:35.319050595 +0200 -+++ openssh-9.0p1/canohost.h 2022-08-30 19:33:23.887176400 +0200 +diff -Nur openssh-9.3p1.orig/canohost.h openssh-9.3p1/canohost.h +--- openssh-9.3p1.orig/canohost.h 2023-06-26 17:34:46.463955878 +0200 ++++ openssh-9.3p1/canohost.h 2023-06-26 17:36:05.813175570 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -581,10 +581,10 @@ diff -Nur openssh-9.0p1.orig/canohost.h openssh-9.0p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-9.0p1.orig/configure.ac openssh-9.0p1/configure.ac ---- openssh-9.0p1.orig/configure.ac 2022-08-30 19:32:35.442050914 +0200 -+++ openssh-9.0p1/configure.ac 2022-08-30 19:33:23.889176405 +0200 -@@ -4832,6 +4832,14 @@ +diff -Nur openssh-9.3p1.orig/configure.ac openssh-9.3p1/configure.ac +--- openssh-9.3p1.orig/configure.ac 2023-06-26 17:34:46.553956127 +0200 ++++ openssh-9.3p1/configure.ac 2023-06-26 17:36:05.814175573 +0200 +@@ -4858,6 +4858,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -599,9 +599,9 @@ diff -Nur openssh-9.0p1.orig/configure.ac openssh-9.0p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4872,6 +4880,40 @@ - AC_SUBST([GSSLIBS]) +@@ -4899,6 +4907,40 @@ AC_SUBST([K5LIBS]) + AC_SUBST([CHANNELLIBS]) +# Check whether the user wants GSI (Globus) support +gsi="no" @@ -640,9 +640,9 @@ diff -Nur openssh-9.0p1.orig/configure.ac openssh-9.0p1/configure.ac # Check whether user wants systemd support SYSTEMD_MSG="no" AC_ARG_WITH(systemd, -diff -Nur openssh-9.0p1.orig/gss-genr.c openssh-9.0p1/gss-genr.c ---- openssh-9.0p1.orig/gss-genr.c 2022-08-30 19:32:35.547051186 +0200 -+++ openssh-9.0p1/gss-genr.c 2022-08-30 19:33:23.890176408 +0200 +diff -Nur openssh-9.3p1.orig/gss-genr.c openssh-9.3p1/gss-genr.c +--- openssh-9.3p1.orig/gss-genr.c 2023-06-26 17:34:46.623956321 +0200 ++++ openssh-9.3p1/gss-genr.c 2023-06-26 17:36:05.815175576 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -679,9 +679,9 @@ diff -Nur openssh-9.0p1.orig/gss-genr.c openssh-9.0p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-9.0p1.orig/gss-serv.c openssh-9.0p1/gss-serv.c ---- openssh-9.0p1.orig/gss-serv.c 2022-08-30 19:32:35.345050662 +0200 -+++ openssh-9.0p1/gss-serv.c 2022-08-30 19:33:23.891176410 +0200 +diff -Nur openssh-9.3p1.orig/gss-serv.c openssh-9.3p1/gss-serv.c +--- openssh-9.3p1.orig/gss-serv.c 2023-06-26 17:34:46.483955933 +0200 ++++ openssh-9.3p1/gss-serv.c 2023-06-26 17:36:05.816175578 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -962,9 +962,9 @@ diff -Nur openssh-9.0p1.orig/gss-serv.c openssh-9.0p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-9.0p1.orig/gss-serv-gsi.c openssh-9.0p1/gss-serv-gsi.c ---- openssh-9.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.0p1/gss-serv-gsi.c 2022-08-30 19:33:23.891176410 +0200 +diff -Nur openssh-9.3p1.orig/gss-serv-gsi.c openssh-9.3p1/gss-serv-gsi.c +--- openssh-9.3p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.3p1/gss-serv-gsi.c 2023-06-26 17:36:05.816175578 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1294,9 +1294,9 @@ diff -Nur openssh-9.0p1.orig/gss-serv-gsi.c openssh-9.0p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-9.0p1.orig/gss-serv-krb5.c openssh-9.0p1/gss-serv-krb5.c ---- openssh-9.0p1.orig/gss-serv-krb5.c 2022-08-30 19:32:35.377050745 +0200 -+++ openssh-9.0p1/gss-serv-krb5.c 2022-08-30 19:33:23.892176413 +0200 +diff -Nur openssh-9.3p1.orig/gss-serv-krb5.c openssh-9.3p1/gss-serv-krb5.c +--- openssh-9.3p1.orig/gss-serv-krb5.c 2023-06-26 17:34:46.506955997 +0200 ++++ openssh-9.3p1/gss-serv-krb5.c 2023-06-26 17:36:05.817175581 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1350,9 +1350,9 @@ diff -Nur openssh-9.0p1.orig/gss-serv-krb5.c openssh-9.0p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-9.0p1.orig/kexgsss.c openssh-9.0p1/kexgsss.c ---- openssh-9.0p1.orig/kexgsss.c 2022-08-30 19:32:35.566051235 +0200 -+++ openssh-9.0p1/kexgsss.c 2022-08-30 19:33:23.892176413 +0200 +diff -Nur openssh-9.3p1.orig/kexgsss.c openssh-9.3p1/kexgsss.c +--- openssh-9.3p1.orig/kexgsss.c 2023-06-26 17:34:46.634956351 +0200 ++++ openssh-9.3p1/kexgsss.c 2023-06-26 17:36:05.817175581 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1416,20 +1416,20 @@ diff -Nur openssh-9.0p1.orig/kexgsss.c openssh-9.0p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-9.0p1.orig/Makefile.in openssh-9.0p1/Makefile.in ---- openssh-9.0p1.orig/Makefile.in 2022-08-30 19:32:35.496051054 +0200 -+++ openssh-9.0p1/Makefile.in 2022-08-30 19:34:46.023388812 +0200 -@@ -129,6 +129,7 @@ - auth2-none.o auth2-passwd.o auth2-pubkey.o \ +diff -Nur openssh-9.3p1.orig/Makefile.in openssh-9.3p1/Makefile.in +--- openssh-9.3p1.orig/Makefile.in 2023-06-26 17:34:46.580956202 +0200 ++++ openssh-9.3p1/Makefile.in 2023-06-26 17:36:05.818175584 +0200 +@@ -130,6 +130,7 @@ + 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 kexgsss.o \ + gss-serv-gsi.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 \ -diff -Nur openssh-9.0p1.orig/misc.c openssh-9.0p1/misc.c ---- openssh-9.0p1.orig/misc.c 2022-08-30 19:32:35.550051194 +0200 -+++ openssh-9.0p1/misc.c 2022-08-30 19:33:23.894176418 +0200 +diff -Nur openssh-9.3p1.orig/misc.c openssh-9.3p1/misc.c +--- openssh-9.3p1.orig/misc.c 2023-06-26 17:34:46.625956326 +0200 ++++ openssh-9.3p1/misc.c 2023-06-26 17:36:05.819175586 +0200 @@ -393,11 +393,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1489,9 +1489,9 @@ diff -Nur openssh-9.0p1.orig/misc.c openssh-9.0p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-9.0p1.orig/misc.h openssh-9.0p1/misc.h ---- openssh-9.0p1.orig/misc.h 2022-08-30 19:32:35.405050818 +0200 -+++ openssh-9.0p1/misc.h 2022-08-30 19:33:23.895176421 +0200 +diff -Nur openssh-9.3p1.orig/misc.h openssh-9.3p1/misc.h +--- openssh-9.3p1.orig/misc.h 2023-06-26 17:34:46.526956052 +0200 ++++ openssh-9.3p1/misc.h 2023-06-26 17:36:05.820175589 +0200 @@ -100,6 +100,7 @@ void sock_set_v6only(int); @@ -1500,9 +1500,9 @@ diff -Nur openssh-9.0p1.orig/misc.h openssh-9.0p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-9.0p1.orig/monitor.c openssh-9.0p1/monitor.c ---- openssh-9.0p1.orig/monitor.c 2022-08-30 19:32:35.551051196 +0200 -+++ openssh-9.0p1/monitor.c 2022-08-30 19:56:02.622691995 +0200 +diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c +--- openssh-9.3p1.orig/monitor.c 2023-06-26 17:34:46.625956326 +0200 ++++ openssh-9.3p1/monitor.c 2023-06-26 17:36:05.821175592 +0200 @@ -152,6 +152,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1571,7 +1571,7 @@ diff -Nur openssh-9.0p1.orig/monitor.c openssh-9.0p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -766,14 +778,17 @@ +@@ -779,14 +791,17 @@ debug3_f("entering"); @@ -1592,7 +1592,7 @@ diff -Nur openssh-9.0p1.orig/monitor.c openssh-9.0p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2130,6 +2145,79 @@ +@@ -2142,6 +2157,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-9.0p1.orig/monitor.c openssh-9.0p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-9.0p1.orig/monitor.h openssh-9.0p1/monitor.h ---- openssh-9.0p1.orig/monitor.h 2022-08-30 19:32:35.498051059 +0200 -+++ openssh-9.0p1/monitor.h 2022-08-30 19:33:23.897176426 +0200 +diff -Nur openssh-9.3p1.orig/monitor.h openssh-9.3p1/monitor.h +--- openssh-9.3p1.orig/monitor.h 2023-06-26 17:34:46.581956204 +0200 ++++ openssh-9.3p1/monitor.h 2023-06-26 17:36:05.821175592 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,10 +1686,10 @@ diff -Nur openssh-9.0p1.orig/monitor.h openssh-9.0p1/monitor.h }; struct ssh; -diff -Nur openssh-9.0p1.orig/monitor_wrap.c openssh-9.0p1/monitor_wrap.c ---- openssh-9.0p1.orig/monitor_wrap.c 2022-08-30 19:32:35.551051196 +0200 -+++ openssh-9.0p1/monitor_wrap.c 2022-08-30 19:33:23.898176429 +0200 -@@ -1084,6 +1084,94 @@ +diff -Nur openssh-9.3p1.orig/monitor_wrap.c openssh-9.3p1/monitor_wrap.c +--- openssh-9.3p1.orig/monitor_wrap.c 2023-06-26 17:34:46.626956329 +0200 ++++ openssh-9.3p1/monitor_wrap.c 2023-06-26 17:36:05.822175594 +0200 +@@ -1085,6 +1085,94 @@ return (authenticated); } @@ -1784,9 +1784,9 @@ diff -Nur openssh-9.0p1.orig/monitor_wrap.c openssh-9.0p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-9.0p1.orig/monitor_wrap.h openssh-9.0p1/monitor_wrap.h ---- openssh-9.0p1.orig/monitor_wrap.h 2022-08-30 19:32:35.508051085 +0200 -+++ openssh-9.0p1/monitor_wrap.h 2022-08-30 19:33:23.898176429 +0200 +diff -Nur openssh-9.3p1.orig/monitor_wrap.h openssh-9.3p1/monitor_wrap.h +--- openssh-9.3p1.orig/monitor_wrap.h 2023-06-26 17:34:46.588956224 +0200 ++++ openssh-9.3p1/monitor_wrap.h 2023-06-26 17:36:05.823175597 +0200 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-9.0p1.orig/monitor_wrap.h openssh-9.0p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c ---- openssh-9.0p1.orig/readconf.c 2022-08-30 19:32:35.553051201 +0200 -+++ openssh-9.0p1/readconf.c 2022-08-30 19:33:23.899176431 +0200 -@@ -2558,11 +2558,11 @@ +diff -Nur openssh-9.3p1.orig/readconf.c openssh-9.3p1/readconf.c +--- openssh-9.3p1.orig/readconf.c 2023-06-26 17:34:46.627956332 +0200 ++++ openssh-9.3p1/readconf.c 2023-06-26 17:36:05.824175600 +0200 +@@ -2554,11 +2554,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1816,10 +1816,10 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h ---- openssh-9.0p1.orig/readconf.h 2022-08-30 19:32:35.469050984 +0200 -+++ openssh-9.0p1/readconf.h 2022-08-30 19:33:23.900176434 +0200 -@@ -78,6 +78,8 @@ +diff -Nur openssh-9.3p1.orig/readconf.h openssh-9.3p1/readconf.h +--- openssh-9.3p1.orig/readconf.h 2023-06-26 17:34:46.470955897 +0200 ++++ openssh-9.3p1/readconf.h 2023-06-26 17:36:05.825175603 +0200 +@@ -79,6 +79,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1828,9 +1828,9 @@ diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c ---- openssh-9.0p1.orig/servconf.c 2022-08-30 19:32:35.555051206 +0200 -+++ openssh-9.0p1/servconf.c 2022-08-30 19:33:23.902176439 +0200 +diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c +--- openssh-9.3p1.orig/servconf.c 2023-06-26 17:34:46.628956335 +0200 ++++ openssh-9.3p1/servconf.c 2023-06-26 17:36:05.826175605 +0200 @@ -93,6 +93,7 @@ /* Portable-specific options */ @@ -1851,7 +1851,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -292,6 +295,8 @@ +@@ -295,6 +298,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -373,13 +378,17 @@ +@@ -376,13 +381,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -517,7 +526,7 @@ +@@ -529,7 +538,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -536,6 +545,9 @@ +@@ -548,6 +557,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -569,8 +581,10 @@ +@@ -581,8 +593,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -623,8 +637,15 @@ +@@ -635,8 +649,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -632,8 +653,11 @@ +@@ -644,8 +665,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -705,6 +729,8 @@ +@@ -717,6 +741,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1383,6 +1409,10 @@ +@@ -1450,6 +1476,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1629,6 +1659,10 @@ +@@ -1696,6 +1726,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1637,6 +1671,10 @@ +@@ -1704,6 +1738,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1657,6 +1695,12 @@ +@@ -1724,6 +1762,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2665,6 +2709,7 @@ +@@ -2776,6 +2820,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,9 +2001,9 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h ---- openssh-9.0p1.orig/servconf.h 2022-08-30 19:32:35.471050989 +0200 -+++ openssh-9.0p1/servconf.h 2022-08-30 19:33:23.903176441 +0200 +diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h +--- openssh-9.3p1.orig/servconf.h 2023-06-26 17:34:46.519956033 +0200 ++++ openssh-9.3p1/servconf.h 2023-06-26 17:36:05.827175608 +0200 @@ -146,9 +146,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2025,10 +2025,10 @@ diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h int permit_tun; -diff -Nur openssh-9.0p1.orig/ssh.1 openssh-9.0p1/ssh.1 ---- openssh-9.0p1.orig/ssh.1 2022-08-30 19:32:35.531051144 +0200 -+++ openssh-9.0p1/ssh.1 2022-08-30 19:33:23.903176441 +0200 -@@ -1510,6 +1510,18 @@ +diff -Nur openssh-9.3p1.orig/ssh.1 openssh-9.3p1/ssh.1 +--- openssh-9.3p1.orig/ssh.1 2023-06-26 17:34:46.606956274 +0200 ++++ openssh-9.3p1/ssh.1 2023-06-26 17:36:05.828175611 +0200 +@@ -1514,6 +1514,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-9.0p1.orig/ssh.1 openssh-9.0p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c ---- openssh-9.0p1.orig/ssh.c 2022-08-30 19:32:35.560051220 +0200 -+++ openssh-9.0p1/ssh.c 2022-08-30 19:33:23.905176447 +0200 -@@ -567,6 +567,38 @@ +diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c +--- openssh-9.3p1.orig/ssh.c 2023-06-26 17:34:46.630956340 +0200 ++++ openssh-9.3p1/ssh.c 2023-06-26 17:36:05.829175614 +0200 +@@ -571,6 +571,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,7 +2089,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1245,8 +1277,12 @@ +@@ -1251,8 +1283,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2103,9 +2103,9 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-9.0p1.orig/ssh_config openssh-9.0p1/ssh_config ---- openssh-9.0p1.orig/ssh_config 2022-08-30 19:32:35.334050634 +0200 -+++ openssh-9.0p1/ssh_config 2022-08-30 19:33:23.905176447 +0200 +diff -Nur openssh-9.3p1.orig/ssh_config openssh-9.3p1/ssh_config +--- openssh-9.3p1.orig/ssh_config 2023-06-26 17:34:46.473955906 +0200 ++++ openssh-9.3p1/ssh_config 2023-06-26 17:36:05.830175617 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2119,9 +2119,9 @@ diff -Nur openssh-9.0p1.orig/ssh_config openssh-9.0p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes -diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 ---- openssh-9.0p1.orig/ssh_config.5 2022-08-30 19:32:35.478051007 +0200 -+++ openssh-9.0p1/ssh_config.5 2022-08-30 19:33:23.906176449 +0200 +diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 +--- openssh-9.3p1.orig/ssh_config.5 2023-06-26 17:34:46.544956102 +0200 ++++ openssh-9.3p1/ssh_config.5 2023-06-26 17:36:05.831175620 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -826,7 +832,7 @@ +@@ -832,7 +838,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -834,12 +840,12 @@ +@@ -840,12 +846,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1454,7 +1460,7 @@ +@@ -1471,7 +1477,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-9.0p1.orig/ssh_config.5 openssh-9.0p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c ---- openssh-9.0p1.orig/sshconnect2.c 2022-08-30 19:32:35.541051170 +0200 -+++ openssh-9.0p1/sshconnect2.c 2022-08-30 19:33:23.908176455 +0200 -@@ -874,6 +874,11 @@ +diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c +--- openssh-9.3p1.orig/sshconnect2.c 2023-06-26 17:34:46.619956310 +0200 ++++ openssh-9.3p1/sshconnect2.c 2023-06-26 17:36:05.832175622 +0200 +@@ -861,6 +861,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -985,7 +990,8 @@ +@@ -972,7 +977,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1156,6 +1162,20 @@ +@@ -1139,6 +1145,20 @@ return r; } @@ -2214,7 +2214,7 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1178,6 +1198,12 @@ +@@ -1161,6 +1181,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2227,7 +2227,7 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1191,7 +1217,9 @@ +@@ -1174,7 +1200,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2238,10 +2238,10 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-9.0p1.orig/sshd.8 openssh-9.0p1/sshd.8 ---- openssh-9.0p1.orig/sshd.8 2022-08-30 19:32:35.352050680 +0200 -+++ openssh-9.0p1/sshd.8 2022-08-30 19:33:23.909176457 +0200 -@@ -823,6 +823,29 @@ +diff -Nur openssh-9.3p1.orig/sshd.8 openssh-9.3p1/sshd.8 +--- openssh-9.3p1.orig/sshd.8 2023-06-26 17:34:46.488955947 +0200 ++++ openssh-9.3p1/sshd.8 2023-06-26 17:36:05.833175625 +0200 +@@ -839,6 +839,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2271,10 +2271,10 @@ diff -Nur openssh-9.0p1.orig/sshd.8 openssh-9.0p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c ---- openssh-9.0p1.orig/sshd.c 2022-08-30 19:32:35.561051222 +0200 -+++ openssh-9.0p1/sshd.c 2022-08-30 19:33:23.910176460 +0200 -@@ -2390,7 +2390,7 @@ +diff -Nur openssh-9.3p1.orig/sshd.c openssh-9.3p1/sshd.c +--- openssh-9.3p1.orig/sshd.c 2023-06-26 17:34:46.631956343 +0200 ++++ openssh-9.3p1/sshd.c 2023-06-26 17:36:05.835175630 +0200 +@@ -2438,7 +2438,7 @@ #endif #ifdef GSSAPI @@ -2283,9 +2283,9 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config ---- openssh-9.0p1.orig/sshd_config 2022-08-30 19:32:35.380050753 +0200 -+++ openssh-9.0p1/sshd_config 2022-08-30 19:33:23.911176462 +0200 +diff -Nur openssh-9.3p1.orig/sshd_config openssh-9.3p1/sshd_config +--- openssh-9.3p1.orig/sshd_config 2023-06-26 17:34:46.508956002 +0200 ++++ openssh-9.3p1/sshd_config 2023-06-26 17:36:05.835175630 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,10 +2311,10 @@ diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-9.0p1.orig/sshd_config.5 openssh-9.0p1/sshd_config.5 ---- openssh-9.0p1.orig/sshd_config.5 2022-08-30 19:32:35.479051009 +0200 -+++ openssh-9.0p1/sshd_config.5 2022-08-30 19:33:23.912176465 +0200 -@@ -635,15 +635,34 @@ +diff -Nur openssh-9.3p1.orig/sshd_config.5 openssh-9.3p1/sshd_config.5 +--- openssh-9.3p1.orig/sshd_config.5 2023-06-26 17:34:46.545956105 +0200 ++++ openssh-9.3p1/sshd_config.5 2023-06-26 17:36:05.836175633 +0200 +@@ -716,15 +716,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2350,7 +2350,7 @@ diff -Nur openssh-9.0p1.orig/sshd_config.5 openssh-9.0p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -654,7 +673,7 @@ +@@ -735,7 +754,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2359,7 +2359,7 @@ diff -Nur openssh-9.0p1.orig/sshd_config.5 openssh-9.0p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1784,6 +1803,12 @@ +@@ -1900,6 +1919,12 @@ as a non-root user. The default is .Cm no . @@ -2372,9 +2372,9 @@ diff -Nur openssh-9.0p1.orig/sshd_config.5 openssh-9.0p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-9.0p1.orig/sshd_config_redhat openssh-9.0p1/sshd_config_redhat ---- openssh-9.0p1.orig/sshd_config_redhat 2022-08-30 19:32:35.308050566 +0200 -+++ openssh-9.0p1/sshd_config_redhat 2022-08-30 19:33:23.912176465 +0200 +diff -Nur openssh-9.3p1.orig/sshd_config_redhat openssh-9.3p1/sshd_config_redhat +--- openssh-9.3p1.orig/sshd_config_redhat 2023-06-26 17:34:46.457955861 +0200 ++++ openssh-9.3p1/sshd_config_redhat 2023-06-26 17:36:05.837175636 +0200 @@ -9,9 +9,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-9.0p1.orig/sshd_config_redhat openssh-9.0p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-9.0p1.orig/ssh-gss.h openssh-9.0p1/ssh-gss.h ---- openssh-9.0p1.orig/ssh-gss.h 2022-08-30 19:32:35.349050673 +0200 -+++ openssh-9.0p1/ssh-gss.h 2022-08-30 19:33:23.913176467 +0200 +diff -Nur openssh-9.3p1.orig/ssh-gss.h openssh-9.3p1/ssh-gss.h +--- openssh-9.3p1.orig/ssh-gss.h 2023-06-26 17:34:46.486955941 +0200 ++++ openssh-9.3p1/ssh-gss.h 2023-06-26 17:36:05.837175636 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-9.0p1.orig/ssh-gss.h openssh-9.0p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-9.0p1.orig/version.h openssh-9.0p1/version.h ---- openssh-9.0p1.orig/version.h 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/version.h 2022-08-30 19:33:23.913176467 +0200 +diff -Nur openssh-9.3p1.orig/version.h openssh-9.3p1/version.h +--- openssh-9.3p1.orig/version.h 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/version.h 2023-06-26 17:36:05.838175639 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_9.0" + #define SSH_VERSION "OpenSSH_9.3" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-9.0p1-hpn-15.2-modified.patch b/openssh-9.3p1-hpn-15.2-modified.patch similarity index 87% rename from openssh-9.0p1-hpn-15.2-modified.patch rename to openssh-9.3p1-hpn-15.2-modified.patch index cf04605..d348911 100644 --- a/openssh-9.0p1-hpn-15.2-modified.patch +++ b/openssh-9.3p1-hpn-15.2-modified.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c ---- openssh-9.0p1.orig/auth2.c 2022-08-30 20:22:42.458819942 +0200 -+++ openssh-9.0p1/auth2.c 2022-08-30 20:23:49.877993046 +0200 -@@ -53,6 +53,8 @@ +diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c +--- openssh-9.3p1.orig/auth2.c 2023-06-26 17:56:58.794634874 +0200 ++++ openssh-9.3p1/auth2.c 2023-06-26 17:59:24.993036944 +0200 +@@ -52,6 +52,8 @@ #include "dispatch.h" #include "pathnames.h" #include "ssherr.h" @@ -10,7 +10,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c #ifdef GSSAPI #include "ssh-gss.h" #endif -@@ -75,6 +77,8 @@ +@@ -74,6 +76,8 @@ extern Authmethod method_gssapi; #endif @@ -19,7 +19,7 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c Authmethod *authmethods[] = { &method_none, &method_pubkey, -@@ -300,6 +304,11 @@ +@@ -297,6 +301,11 @@ debug("userauth-request for user %s service %s method %s", user[0] ? user : "", service, method); @@ -31,10 +31,10 @@ diff -Nur openssh-9.0p1.orig/auth2.c openssh-9.0p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c ---- openssh-9.0p1.orig/channels.c 2022-08-30 20:22:42.436819885 +0200 -+++ openssh-9.0p1/channels.c 2022-08-30 20:23:49.879993051 +0200 -@@ -219,6 +219,9 @@ +diff -Nur openssh-9.3p1.orig/channels.c openssh-9.3p1/channels.c +--- openssh-9.3p1.orig/channels.c 2023-06-26 17:56:58.689634585 +0200 ++++ openssh-9.3p1/channels.c 2023-06-26 18:26:41.719517151 +0200 +@@ -229,6 +229,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -44,7 +44,7 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c /* -- channel core */ void -@@ -407,6 +410,7 @@ +@@ -495,6 +498,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -52,7 +52,7 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1104,6 +1108,28 @@ +@@ -1203,6 +1207,28 @@ c->io_want = SSH_CHAN_IO_SOCK_W; } @@ -81,7 +81,7 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c) { -@@ -2170,22 +2196,31 @@ +@@ -2305,22 +2331,31 @@ if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && @@ -118,7 +118,7 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c c->local_consumed = 0; } return 1; -@@ -3571,6 +3606,14 @@ +@@ -3717,6 +3752,14 @@ return addr; } @@ -133,21 +133,21 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -@@ -3710,8 +3753,10 @@ +@@ -3856,8 +3899,10 @@ } /* Allocate a channel number for the socket. */ + /* explicitly test for hpn disabled option. if true use smaller window size */ - c = channel_new(ssh, "port listener", type, sock, sock, -1, + c = channel_new(ssh, "port-listener", type, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : hpn_buffer_size, + CHAN_TCP_PACKET_DEFAULT, 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; -@@ -4897,7 +4942,8 @@ +@@ -5041,7 +5086,8 @@ sock = socks[n]; - nc = channel_new(ssh, "x11 listener", + nc = channel_new(ssh, "x11-listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : hpn_buffer_size, @@ -155,10 +155,10 @@ diff -Nur openssh-9.0p1.orig/channels.c openssh-9.0p1/channels.c 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; -diff -Nur openssh-9.0p1.orig/channels.h openssh-9.0p1/channels.h ---- openssh-9.0p1.orig/channels.h 2022-08-30 20:22:42.315819575 +0200 -+++ openssh-9.0p1/channels.h 2022-08-30 20:23:49.880993054 +0200 -@@ -172,8 +172,10 @@ +diff -Nur openssh-9.3p1.orig/channels.h openssh-9.3p1/channels.h +--- openssh-9.3p1.orig/channels.h 2023-06-26 17:56:58.638634445 +0200 ++++ openssh-9.3p1/channels.h 2023-06-26 17:59:24.996036952 +0200 +@@ -173,8 +173,10 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; @@ -167,9 +167,9 @@ diff -Nur openssh-9.0p1.orig/channels.h openssh-9.0p1/channels.h int single_connection; + u_int tcpwinsz; - char *ctype; /* type */ - -@@ -245,7 +247,7 @@ + char *ctype; /* const type - NB. not freed on channel_free */ + char *xctype; /* extended type */ +@@ -254,7 +256,7 @@ #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) /* Read buffer size */ @@ -178,7 +178,7 @@ diff -Nur openssh-9.0p1.orig/channels.h openssh-9.0p1/channels.h /* Maximum size for direct reads to buffers */ #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -380,4 +382,7 @@ +@@ -396,4 +398,7 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); @@ -186,9 +186,9 @@ diff -Nur openssh-9.0p1.orig/channels.h openssh-9.0p1/channels.h +void channel_set_hpn(int, int); + #endif -diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c ---- openssh-9.0p1.orig/cipher.c 2022-08-30 20:22:42.382819747 +0200 -+++ openssh-9.0p1/cipher.c 2022-08-30 20:23:49.881993056 +0200 +diff -Nur openssh-9.3p1.orig/cipher.c openssh-9.3p1/cipher.c +--- openssh-9.3p1.orig/cipher.c 2023-06-26 17:56:58.717634662 +0200 ++++ openssh-9.3p1/cipher.c 2023-06-26 17:59:24.997036955 +0200 @@ -48,6 +48,7 @@ #include "sshbuf.h" #include "ssherr.h" @@ -216,7 +216,7 @@ diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, -@@ -133,6 +137,29 @@ +@@ -131,6 +135,29 @@ #endif } @@ -246,7 +246,7 @@ diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c u_int cipher_blocksize(const struct sshcipher *c) { -@@ -182,10 +209,10 @@ +@@ -180,10 +207,10 @@ return cc->plaintext; } @@ -259,7 +259,7 @@ diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c for (c = ciphers; c->name != NULL; c++) if (strcmp(c->name, name) == 0) return c; -@@ -207,7 +234,8 @@ +@@ -205,7 +232,8 @@ for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); @@ -269,9 +269,9 @@ diff -Nur openssh-9.0p1.orig/cipher.c openssh-9.0p1/cipher.c free(cipher_list); return 0; } -diff -Nur openssh-9.0p1.orig/cipher-ctr-mt.c openssh-9.0p1/cipher-ctr-mt.c ---- openssh-9.0p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.0p1/cipher-ctr-mt.c 2022-08-30 20:23:49.882993059 +0200 +diff -Nur openssh-9.3p1.orig/cipher-ctr-mt.c openssh-9.3p1/cipher-ctr-mt.c +--- openssh-9.3p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.3p1/cipher-ctr-mt.c 2023-06-26 17:59:24.998036958 +0200 @@ -0,0 +1,678 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -951,9 +951,9 @@ diff -Nur openssh-9.0p1.orig/cipher-ctr-mt.c openssh-9.0p1/cipher-ctr-mt.c +} + +#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-9.0p1.orig/cipher.h openssh-9.0p1/cipher.h ---- openssh-9.0p1.orig/cipher.h 2022-08-30 20:22:42.382819747 +0200 -+++ openssh-9.0p1/cipher.h 2022-08-30 20:23:49.882993059 +0200 +diff -Nur openssh-9.3p1.orig/cipher.h openssh-9.3p1/cipher.h +--- openssh-9.3p1.orig/cipher.h 2023-06-26 17:56:58.717634662 +0200 ++++ openssh-9.3p1/cipher.h 2023-06-26 17:59:24.999036961 +0200 @@ -68,7 +68,9 @@ struct sshcipher_ctx; @@ -974,10 +974,10 @@ diff -Nur openssh-9.0p1.orig/cipher.h openssh-9.0p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-9.0p1.orig/clientloop.c openssh-9.0p1/clientloop.c ---- openssh-9.0p1.orig/clientloop.c 2022-08-30 20:22:42.263819441 +0200 -+++ openssh-9.0p1/clientloop.c 2022-08-30 20:23:49.883993061 +0200 -@@ -1586,7 +1586,9 @@ +diff -Nur openssh-9.3p1.orig/clientloop.c openssh-9.3p1/clientloop.c +--- openssh-9.3p1.orig/clientloop.c 2023-06-26 17:56:58.584634296 +0200 ++++ openssh-9.3p1/clientloop.c 2023-06-26 17:59:25.000036964 +0200 +@@ -1646,7 +1646,9 @@ return NULL; c = channel_new(ssh, "x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, @@ -988,7 +988,7 @@ diff -Nur openssh-9.0p1.orig/clientloop.c openssh-9.0p1/clientloop.c c->force_drain = 1; return c; } -@@ -1621,7 +1623,8 @@ +@@ -1681,7 +1683,8 @@ c = channel_new(ssh, "authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -998,7 +998,7 @@ diff -Nur openssh-9.0p1.orig/clientloop.c openssh-9.0p1/clientloop.c "authentication agent connection", 1); c->force_drain = 1; return c; -@@ -1648,7 +1651,8 @@ +@@ -1708,7 +1711,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, @@ -1008,10 +1008,10 @@ diff -Nur openssh-9.0p1.orig/clientloop.c openssh-9.0p1/clientloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) -diff -Nur openssh-9.0p1.orig/compat.c openssh-9.0p1/compat.c ---- openssh-9.0p1.orig/compat.c 2022-08-30 20:22:42.423819852 +0200 -+++ openssh-9.0p1/compat.c 2022-08-30 20:23:49.884993064 +0200 -@@ -150,6 +150,17 @@ +diff -Nur openssh-9.3p1.orig/compat.c openssh-9.3p1/compat.c +--- openssh-9.3p1.orig/compat.c 2023-06-26 17:56:58.764634791 +0200 ++++ openssh-9.3p1/compat.c 2023-06-26 17:59:25.001036966 +0200 +@@ -135,6 +135,17 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) ssh->compat |= SSH_RH_RSASIGSHA; @@ -1029,9 +1029,9 @@ diff -Nur openssh-9.0p1.orig/compat.c openssh-9.0p1/compat.c return; } } -diff -Nur openssh-9.0p1.orig/compat.h openssh-9.0p1/compat.h ---- openssh-9.0p1.orig/compat.h 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/compat.h 2022-08-30 20:23:49.884993064 +0200 +diff -Nur openssh-9.3p1.orig/compat.h openssh-9.3p1/compat.h +--- openssh-9.3p1.orig/compat.h 2023-06-26 17:56:58.765634794 +0200 ++++ openssh-9.3p1/compat.h 2023-06-26 17:59:25.001036966 +0200 @@ -57,6 +57,7 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 @@ -1040,9 +1040,9 @@ diff -Nur openssh-9.0p1.orig/compat.h openssh-9.0p1/compat.h struct ssh; -diff -Nur openssh-9.0p1.orig/defines.h openssh-9.0p1/defines.h ---- openssh-9.0p1.orig/defines.h 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/defines.h 2022-08-30 20:23:49.885993067 +0200 +diff -Nur openssh-9.3p1.orig/defines.h openssh-9.3p1/defines.h +--- openssh-9.3p1.orig/defines.h 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/defines.h 2023-06-26 17:59:25.002036969 +0200 @@ -889,7 +889,7 @@ #endif @@ -1052,9 +1052,9 @@ diff -Nur openssh-9.0p1.orig/defines.h openssh-9.0p1/defines.h #endif /* -diff -Nur openssh-9.0p1.orig/digest.h openssh-9.0p1/digest.h ---- openssh-9.0p1.orig/digest.h 2022-08-30 20:22:42.344819649 +0200 -+++ openssh-9.0p1/digest.h 2022-08-30 20:23:49.886993069 +0200 +diff -Nur openssh-9.3p1.orig/digest.h openssh-9.3p1/digest.h +--- openssh-9.3p1.orig/digest.h 2023-06-26 17:56:58.672634538 +0200 ++++ openssh-9.3p1/digest.h 2023-06-26 17:59:25.002036969 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -1065,9 +1065,9 @@ diff -Nur openssh-9.0p1.orig/digest.h openssh-9.0p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-9.0p1.orig/digest-openssl.c openssh-9.0p1/digest-openssl.c ---- openssh-9.0p1.orig/digest-openssl.c 2022-08-30 20:22:42.344819649 +0200 -+++ openssh-9.0p1/digest-openssl.c 2022-08-30 20:23:49.886993069 +0200 +diff -Nur openssh-9.3p1.orig/digest-openssl.c openssh-9.3p1/digest-openssl.c +--- openssh-9.3p1.orig/digest-openssl.c 2023-06-26 17:56:58.672634538 +0200 ++++ openssh-9.3p1/digest-openssl.c 2023-06-26 17:59:25.002036969 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -1076,9 +1076,9 @@ diff -Nur openssh-9.0p1.orig/digest-openssl.c openssh-9.0p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-9.0p1.orig/HPN-README openssh-9.0p1/HPN-README ---- openssh-9.0p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.0p1/HPN-README 2022-08-30 20:23:49.887993072 +0200 +diff -Nur openssh-9.3p1.orig/HPN-README openssh-9.3p1/HPN-README +--- openssh-9.3p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.3p1/HPN-README 2023-06-26 17:59:25.003036972 +0200 @@ -0,0 +1,153 @@ +Notes: + @@ -1233,18 +1233,18 @@ diff -Nur openssh-9.0p1.orig/HPN-README openssh-9.0p1/HPN-README + Allan Jude provided the code for the NoneMac and buffer normalization. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. -diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c ---- openssh-9.0p1.orig/kex.c 2022-08-30 20:22:42.402819798 +0200 -+++ openssh-9.0p1/kex.c 2022-08-30 20:23:49.887993072 +0200 -@@ -64,6 +64,7 @@ +diff -Nur openssh-9.3p1.orig/kex.c openssh-9.3p1/kex.c +--- openssh-9.3p1.orig/kex.c 2023-06-26 17:56:58.759634778 +0200 ++++ openssh-9.3p1/kex.c 2023-06-26 17:59:25.004036975 +0200 +@@ -65,6 +65,7 @@ #include "ssherr.h" #include "sshbuf.h" +#include "canohost.h" #include "digest.h" + #include "xmalloc.h" #include "audit.h" - -@@ -1001,6 +1002,11 @@ +@@ -1061,6 +1062,11 @@ int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; @@ -1256,7 +1256,7 @@ diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) -@@ -1081,11 +1087,40 @@ +@@ -1141,11 +1147,40 @@ peer[ncomp] = NULL; goto out; } @@ -1297,7 +1297,7 @@ diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { -@@ -1433,7 +1468,7 @@ +@@ -1493,7 +1528,7 @@ if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", @@ -1306,7 +1306,7 @@ diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c version_addendum == NULL ? "" : " ", version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; -@@ -1569,6 +1604,14 @@ +@@ -1629,6 +1664,14 @@ r = SSH_ERR_INVALID_FORMAT; goto out; } @@ -1321,9 +1321,9 @@ diff -Nur openssh-9.0p1.orig/kex.c openssh-9.0p1/kex.c debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); compat_banner(ssh, remote_version); -diff -Nur openssh-9.0p1.orig/log.c openssh-9.0p1/log.c ---- openssh-9.0p1.orig/log.c 2022-08-30 20:22:42.298819531 +0200 -+++ openssh-9.0p1/log.c 2022-08-30 20:23:49.888993074 +0200 +diff -Nur openssh-9.3p1.orig/log.c openssh-9.3p1/log.c +--- openssh-9.3p1.orig/log.c 2023-06-26 17:56:58.620634395 +0200 ++++ openssh-9.3p1/log.c 2023-06-26 17:59:25.005036978 +0200 @@ -46,6 +46,11 @@ #include #include @@ -1345,9 +1345,9 @@ diff -Nur openssh-9.0p1.orig/log.c openssh-9.0p1/log.c #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) -diff -Nur openssh-9.0p1.orig/mac.c openssh-9.0p1/mac.c ---- openssh-9.0p1.orig/mac.c 2022-08-30 20:22:42.384819752 +0200 -+++ openssh-9.0p1/mac.c 2022-08-30 20:23:49.888993074 +0200 +diff -Nur openssh-9.3p1.orig/mac.c openssh-9.3p1/mac.c +--- openssh-9.3p1.orig/mac.c 2023-06-26 17:56:58.719634668 +0200 ++++ openssh-9.3p1/mac.c 2023-06-26 17:59:25.005036978 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -1356,30 +1356,30 @@ diff -Nur openssh-9.0p1.orig/mac.c openssh-9.0p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-9.0p1.orig/Makefile.in openssh-9.0p1/Makefile.in ---- openssh-9.0p1.orig/Makefile.in 2022-08-30 20:22:42.466819962 +0200 -+++ openssh-9.0p1/Makefile.in 2022-08-30 20:23:49.889993077 +0200 +diff -Nur openssh-9.3p1.orig/Makefile.in openssh-9.3p1/Makefile.in +--- openssh-9.3p1.orig/Makefile.in 2023-06-26 17:56:58.801634893 +0200 ++++ openssh-9.3p1/Makefile.in 2023-06-26 18:05:19.227009623 +0200 @@ -49,7 +49,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ -LIBS=@LIBS@ +LIBS=@LIBS@ -lpthread + CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ - SSHDLIBS=@SSHDLIBS@ -@@ -96,7 +96,7 @@ +@@ -97,7 +97,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ -- cipher-ctr.o cleanup.o \ -+ cipher-ctr.o cleanup.o cipher-ctr-mt.o \ +- cleanup.o \ ++ cipher-ctr-mt.o cleanup.o \ compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-9.0p1.orig/packet.c openssh-9.0p1/packet.c ---- openssh-9.0p1.orig/packet.c 2022-08-30 20:22:42.389819765 +0200 -+++ openssh-9.0p1/packet.c 2022-08-31 13:43:18.798517271 +0200 +diff -Nur openssh-9.3p1.orig/packet.c openssh-9.3p1/packet.c +--- openssh-9.3p1.orig/packet.c 2023-06-26 17:56:58.723634679 +0200 ++++ openssh-9.3p1/packet.c 2023-06-26 17:59:25.007036983 +0200 @@ -246,7 +246,7 @@ TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; @@ -1463,7 +1463,7 @@ diff -Nur openssh-9.0p1.orig/packet.c openssh-9.0p1/packet.c (int64_t)state->rekey_time + state->rekey_interval <= monotime()) @@ -1342,7 +1376,7 @@ struct session_state *state = ssh->state; - int len, r, ms_remain; + int len, r, ms_remain = 0; struct pollfd pfd; - char buf[8192]; + char buf[SSH_IOBUFSZ]; @@ -1545,9 +1545,9 @@ diff -Nur openssh-9.0p1.orig/packet.c openssh-9.0p1/packet.c +{ + return ssh->state->send_context; +} -diff -Nur openssh-9.0p1.orig/packet.h openssh-9.0p1/packet.h ---- openssh-9.0p1.orig/packet.h 2022-08-30 20:22:42.390819767 +0200 -+++ openssh-9.0p1/packet.h 2022-08-30 20:23:49.892993084 +0200 +diff -Nur openssh-9.3p1.orig/packet.h openssh-9.3p1/packet.h +--- openssh-9.3p1.orig/packet.h 2023-06-26 17:56:58.724634681 +0200 ++++ openssh-9.3p1/packet.h 2023-06-26 17:59:25.008036986 +0200 @@ -86,6 +86,14 @@ /* APP data */ @@ -1586,10 +1586,10 @@ diff -Nur openssh-9.0p1.orig/packet.h openssh-9.0p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-9.0p1.orig/progressmeter.c openssh-9.0p1/progressmeter.c ---- openssh-9.0p1.orig/progressmeter.c 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/progressmeter.c 2022-08-30 20:23:49.893993087 +0200 -@@ -68,6 +68,8 @@ +diff -Nur openssh-9.3p1.orig/progressmeter.c openssh-9.3p1/progressmeter.c +--- openssh-9.3p1.orig/progressmeter.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/progressmeter.c 2023-07-05 10:45:57.895329810 +0200 +@@ -67,6 +67,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ @@ -1598,15 +1598,15 @@ diff -Nur openssh-9.0p1.orig/progressmeter.c openssh-9.0p1/progressmeter.c static volatile off_t *counter; /* progress counter */ static long stalled; /* how long we have been stalled */ static int bytes_per_second; /* current speed in bytes per second */ -@@ -127,6 +129,7 @@ +@@ -133,6 +135,7 @@ int cur_speed; int hours, minutes, seconds; - int file_len; + int file_len, cols; + off_t delta_pos; if ((!force_update && !alarm_fired && !win_resized) || !can_output()) return; -@@ -142,6 +145,10 @@ +@@ -148,6 +151,10 @@ now = monotime_double(); bytes_left = end_pos - cur_pos; @@ -1617,42 +1617,38 @@ diff -Nur openssh-9.0p1.orig/progressmeter.c openssh-9.0p1/progressmeter.c if (bytes_left > 0) elapsed = now - last_update; else { -@@ -166,7 +173,7 @@ +@@ -171,13 +178,14 @@ + bytes_per_second = cur_speed; + + last_update = now; ++ last_pos = cur_pos; + + /* Don't bother if we can't even display the completion percentage */ + if (win_size < 4) + return; /* filename */ - buf[0] = '\0'; -- file_len = win_size - 36; -+ file_len = win_size - 45; +- file_len = cols = win_size - 36; ++ file_len = cols = win_size - 45; if (file_len > 0) { - buf[0] = '\r'; - snmprintf(buf+1, sizeof(buf)-1, &file_len, "%-*s", -@@ -191,6 +198,15 @@ - (off_t)bytes_per_second); - strlcat(buf, "/s ", win_size); + asmprintf(&buf, INT_MAX, &cols, "%-*s", file_len, file); + /* If we used fewer columns than expected then pad */ +@@ -194,6 +202,12 @@ + xextendf(&buf, NULL, " %3d%% %s %s/s ", percent, format_size(cur_pos), + format_rate((off_t)bytes_per_second)); + /* instantaneous rate */ + if (bytes_left > 0) -+ format_rate(buf + strlen(buf), win_size - strlen(buf), -+ delta_pos); ++ xextendf(&buf, NULL, "%s/s ", format_rate(delta_pos)); + else -+ format_rate(buf + strlen(buf), win_size - strlen(buf), -+ max_delta_pos); -+ strlcat(buf, "/s ", win_size); ++ xextendf(&buf, NULL, "%s/s ", format_rate(max_delta_pos)); + /* ETA */ if (!transferred) stalled += elapsed; -@@ -227,6 +243,7 @@ - - atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); - last_update = now; -+ last_pos = cur_pos; - } - - /*ARGSUSED*/ -diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c ---- openssh-9.0p1.orig/readconf.c 2022-08-30 20:22:42.471819975 +0200 -+++ openssh-9.0p1/readconf.c 2022-08-30 20:23:49.894993090 +0200 +diff -Nur openssh-9.3p1.orig/readconf.c openssh-9.3p1/readconf.c +--- openssh-9.3p1.orig/readconf.c 2023-06-26 17:56:58.806634907 +0200 ++++ openssh-9.3p1/readconf.c 2023-06-26 17:59:25.011036994 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -1671,7 +1667,7 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, -@@ -313,6 +317,10 @@ +@@ -314,6 +318,10 @@ { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, @@ -1682,9 +1678,9 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c { "sessiontype", oSessionType }, { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, -@@ -337,6 +345,11 @@ - { "requiredrsasize", oRequiredRSASize }, +@@ -340,6 +348,11 @@ { "rsaminsize", oRequiredRSASize }, /* alias */ + { "enableescapecommandline", oEnableEscapeCommandline }, + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, @@ -1694,7 +1690,7 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c { NULL, oBadOption } }; -@@ -1183,6 +1196,46 @@ +@@ -1182,6 +1195,46 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -1741,7 +1737,7 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -1437,6 +1490,10 @@ +@@ -1436,6 +1489,10 @@ *intptr = value; break; @@ -1752,7 +1748,7 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c case oCiphers: arg = argv_next(&ac, &av); if (!arg || *arg == '\0') { -@@ -2481,6 +2538,14 @@ +@@ -2476,6 +2533,14 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -1767,7 +1763,7 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2657,6 +2722,43 @@ +@@ -2653,6 +2718,43 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -1811,10 +1807,10 @@ diff -Nur openssh-9.0p1.orig/readconf.c openssh-9.0p1/readconf.c if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { -diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h ---- openssh-9.0p1.orig/readconf.h 2022-08-30 20:22:42.471819975 +0200 -+++ openssh-9.0p1/readconf.h 2022-08-30 20:23:49.895993092 +0200 -@@ -55,6 +55,10 @@ +diff -Nur openssh-9.3p1.orig/readconf.h openssh-9.3p1/readconf.h +--- openssh-9.3p1.orig/readconf.h 2023-06-26 17:56:58.806634907 +0200 ++++ openssh-9.3p1/readconf.h 2023-06-26 17:59:25.012036996 +0200 +@@ -56,6 +56,10 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ @@ -1825,7 +1821,7 @@ diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ -@@ -126,7 +130,12 @@ +@@ -127,7 +131,12 @@ int enable_ssh_keysign; int64_t rekey_limit; @@ -1838,11 +1834,11 @@ diff -Nur openssh-9.0p1.orig/readconf.h openssh-9.0p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-9.0p1.orig/regress/integrity.sh openssh-9.0p1/regress/integrity.sh ---- openssh-9.0p1.orig/regress/integrity.sh 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/regress/integrity.sh 2022-08-30 20:23:49.895993092 +0200 +diff -Nur openssh-9.3p1.orig/regress/integrity.sh openssh-9.3p1/regress/integrity.sh +--- openssh-9.3p1.orig/regress/integrity.sh 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/regress/integrity.sh 2023-06-26 17:59:25.013036999 +0200 @@ -21,6 +21,12 @@ - cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" + cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy" for m in $macs; do + # the none mac is now valid but tests against it will succeed when we expect it to @@ -1854,10 +1850,10 @@ diff -Nur openssh-9.0p1.orig/regress/integrity.sh openssh-9.0p1/regress/integrit trace "test $tid: mac $m" elen=0 epad=0 -diff -Nur openssh-9.0p1.orig/sandbox-seccomp-filter.c openssh-9.0p1/sandbox-seccomp-filter.c ---- openssh-9.0p1.orig/sandbox-seccomp-filter.c 2022-08-30 20:22:42.405819806 +0200 -+++ openssh-9.0p1/sandbox-seccomp-filter.c 2022-08-30 20:23:49.896993095 +0200 -@@ -225,6 +225,9 @@ +diff -Nur openssh-9.3p1.orig/sandbox-seccomp-filter.c openssh-9.3p1/sandbox-seccomp-filter.c +--- openssh-9.3p1.orig/sandbox-seccomp-filter.c 2023-06-26 17:56:58.742634731 +0200 ++++ openssh-9.3p1/sandbox-seccomp-filter.c 2023-06-26 17:59:25.013036999 +0200 +@@ -295,6 +295,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), #endif @@ -1867,7 +1863,7 @@ diff -Nur openssh-9.0p1.orig/sandbox-seccomp-filter.c openssh-9.0p1/sandbox-secc #ifdef __NR_getpgid SC_ALLOW(__NR_getpgid), #endif -@@ -327,6 +330,9 @@ +@@ -413,6 +416,9 @@ #ifdef __NR_sigprocmask SC_ALLOW(__NR_sigprocmask), #endif @@ -1877,10 +1873,10 @@ diff -Nur openssh-9.0p1.orig/sandbox-seccomp-filter.c openssh-9.0p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-9.0p1.orig/scp.c openssh-9.0p1/scp.c ---- openssh-9.0p1.orig/scp.c 2022-08-30 20:22:42.444819906 +0200 -+++ openssh-9.0p1/scp.c 2022-08-30 20:23:49.897993097 +0200 -@@ -1605,7 +1605,7 @@ +diff -Nur openssh-9.3p1.orig/scp.c openssh-9.3p1/scp.c +--- openssh-9.3p1.orig/scp.c 2023-06-26 17:56:58.782634841 +0200 ++++ openssh-9.3p1/scp.c 2023-06-26 17:59:25.015037005 +0200 +@@ -1670,7 +1670,7 @@ off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerr; @@ -1889,9 +1885,9 @@ diff -Nur openssh-9.0p1.orig/scp.c openssh-9.0p1/scp.c char **patterns = NULL; size_t n, npatterns = 0; struct timeval tv[2]; -diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c ---- openssh-9.0p1.orig/servconf.c 2022-08-30 20:22:42.473819980 +0200 -+++ openssh-9.0p1/servconf.c 2022-08-30 20:23:49.899993103 +0200 +diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c +--- openssh-9.3p1.orig/servconf.c 2023-06-26 17:56:58.807634910 +0200 ++++ openssh-9.3p1/servconf.c 2023-06-26 17:59:25.016037008 +0200 @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -1913,7 +1909,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -291,6 +298,10 @@ +@@ -294,6 +301,10 @@ fill_default_server_options(ServerOptions *options) { u_int i; @@ -1924,7 +1920,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c /* Portable-specific options */ if (options->use_pam == -1) -@@ -462,6 +473,51 @@ +@@ -465,6 +476,51 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -1976,7 +1972,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -534,6 +590,9 @@ +@@ -546,6 +602,9 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -1986,7 +1982,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -735,6 +794,12 @@ +@@ -747,6 +806,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -1999,7 +1995,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -794,6 +859,7 @@ +@@ -809,6 +874,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -2007,7 +2003,7 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1569,12 +1635,36 @@ +@@ -1636,12 +1702,36 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -2044,9 +2040,9 @@ diff -Nur openssh-9.0p1.orig/servconf.c openssh-9.0p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h ---- openssh-9.0p1.orig/servconf.h 2022-08-30 20:22:42.473819980 +0200 -+++ openssh-9.0p1/servconf.h 2022-08-30 20:23:49.900993105 +0200 +diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h +--- openssh-9.3p1.orig/servconf.h 2023-06-26 17:56:58.808634912 +0200 ++++ openssh-9.3p1/servconf.h 2023-06-26 17:59:25.017037010 +0200 @@ -214,6 +214,13 @@ int use_pam; /* Enable auth via PAM */ int permit_pam_user_change; /* Allow PAM to change user name */ @@ -2061,10 +2057,10 @@ diff -Nur openssh-9.0p1.orig/servconf.h openssh-9.0p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c ---- openssh-9.0p1.orig/serverloop.c 2022-08-30 20:22:42.446819911 +0200 -+++ openssh-9.0p1/serverloop.c 2022-08-30 20:23:49.900993105 +0200 -@@ -342,6 +342,7 @@ +diff -Nur openssh-9.3p1.orig/serverloop.c openssh-9.3p1/serverloop.c +--- openssh-9.3p1.orig/serverloop.c 2023-06-26 17:56:58.784634846 +0200 ++++ openssh-9.3p1/serverloop.c 2023-06-26 17:59:25.018037013 +0200 +@@ -347,6 +347,7 @@ sigset_t bsigset, osigset; debug("Entering interactive session for SSH2."); @@ -2072,7 +2068,7 @@ diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) error_f("bsigset setup: %s", strerror(errno)); -@@ -388,6 +389,7 @@ +@@ -386,6 +387,7 @@ if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); @@ -2080,7 +2076,7 @@ diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } -@@ -409,6 +411,9 @@ +@@ -406,6 +408,9 @@ /* free all channels, no more reads and writes */ channel_free_all(ssh); @@ -2090,7 +2086,7 @@ diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(ssh, NULL); } -@@ -559,7 +564,8 @@ +@@ -556,7 +561,8 @@ debug("Tunnel forwarding using interface %s", ifname); c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, @@ -2100,7 +2096,7 @@ diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c c->datagram = 1; #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) -@@ -610,6 +616,8 @@ +@@ -607,6 +613,8 @@ c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); @@ -2109,18 +2105,18 @@ diff -Nur openssh-9.0p1.orig/serverloop.c openssh-9.0p1/serverloop.c if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -diff -Nur openssh-9.0p1.orig/session.c openssh-9.0p1/session.c ---- openssh-9.0p1.orig/session.c 2022-08-30 20:22:42.447819914 +0200 -+++ openssh-9.0p1/session.c 2022-08-30 20:23:49.902993110 +0200 -@@ -227,6 +227,7 @@ +diff -Nur openssh-9.3p1.orig/session.c openssh-9.3p1/session.c +--- openssh-9.3p1.orig/session.c 2023-06-26 17:56:58.732634703 +0200 ++++ openssh-9.3p1/session.c 2023-07-05 10:50:50.184150123 +0200 +@@ -226,6 +226,7 @@ goto authsock_err; /* Allocate a channel for the authentication agent socket. */ + /* this shouldn't matter if its hpn or not - cjr */ - nc = channel_new(ssh, "auth socket", + nc = channel_new(ssh, "auth-listener", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -2362,7 +2363,8 @@ +@@ -2369,7 +2370,8 @@ channel_set_fds(ssh, s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, @@ -2130,10 +2126,10 @@ diff -Nur openssh-9.0p1.orig/session.c openssh-9.0p1/session.c } /* -diff -Nur openssh-9.0p1.orig/sftp.1 openssh-9.0p1/sftp.1 ---- openssh-9.0p1.orig/sftp.1 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/sftp.1 2022-08-30 20:23:49.903993113 +0200 -@@ -295,7 +295,8 @@ +diff -Nur openssh-9.3p1.orig/sftp.1 openssh-9.3p1/sftp.1 +--- openssh-9.3p1.orig/sftp.1 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/sftp.1 2023-06-26 17:59:25.021037021 +0200 +@@ -299,7 +299,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. @@ -2143,21 +2139,21 @@ diff -Nur openssh-9.0p1.orig/sftp.1 openssh-9.0p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -diff -Nur openssh-9.0p1.orig/sftp-client.c openssh-9.0p1/sftp-client.c ---- openssh-9.0p1.orig/sftp-client.c 2022-08-30 20:22:42.417819836 +0200 -+++ openssh-9.0p1/sftp-client.c 2022-08-30 20:23:49.904993115 +0200 +diff -Nur openssh-9.3p1.orig/sftp-client.c openssh-9.3p1/sftp-client.c +--- openssh-9.3p1.orig/sftp-client.c 2023-06-26 17:56:58.702634621 +0200 ++++ openssh-9.3p1/sftp-client.c 2023-06-26 18:01:56.954454674 +0200 @@ -72,7 +72,7 @@ #define DEFAULT_COPY_BUFLEN 32768 - /* Default number of concurrent outstanding requests */ + /* Default number of concurrent xfer requests (fix sftp.1 scp.1 if changed) */ -#define DEFAULT_NUM_REQUESTS 64 +#define DEFAULT_NUM_REQUESTS 256 /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-9.0p1.orig/ssh_api.c openssh-9.0p1/ssh_api.c ---- openssh-9.0p1.orig/ssh_api.c 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/ssh_api.c 2022-08-30 20:23:49.904993115 +0200 +diff -Nur openssh-9.3p1.orig/ssh_api.c openssh-9.3p1/ssh_api.c +--- openssh-9.3p1.orig/ssh_api.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/ssh_api.c 2023-06-26 17:59:25.024037030 +0200 @@ -410,7 +410,7 @@ char *cp; int r; @@ -2167,9 +2163,9 @@ diff -Nur openssh-9.0p1.orig/ssh_api.c openssh-9.0p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-9.0p1.orig/sshbuf.h openssh-9.0p1/sshbuf.h ---- openssh-9.0p1.orig/sshbuf.h 2022-04-06 02:47:48.000000000 +0200 -+++ openssh-9.0p1/sshbuf.h 2022-08-30 20:23:49.905993118 +0200 +diff -Nur openssh-9.3p1.orig/sshbuf.h openssh-9.3p1/sshbuf.h +--- openssh-9.3p1.orig/sshbuf.h 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1/sshbuf.h 2023-06-26 17:59:25.024037030 +0200 @@ -28,7 +28,7 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2179,10 +2175,10 @@ diff -Nur openssh-9.0p1.orig/sshbuf.h openssh-9.0p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c ---- openssh-9.0p1.orig/ssh.c 2022-08-30 20:22:42.475819985 +0200 -+++ openssh-9.0p1/ssh.c 2022-08-30 20:23:49.906993121 +0200 -@@ -1065,6 +1065,10 @@ +diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c +--- openssh-9.3p1.orig/ssh.c 2023-06-26 17:56:58.809634915 +0200 ++++ openssh-9.3p1/ssh.c 2023-06-26 17:59:25.025037033 +0200 +@@ -1069,6 +1069,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -2193,7 +2189,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1801,6 +1805,8 @@ +@@ -1815,6 +1819,8 @@ setproctitle("%s [mux]", options.control_path); } @@ -2202,7 +2198,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) -@@ -2118,6 +2124,79 @@ +@@ -2132,6 +2138,79 @@ NULL, fileno(stdin), command, environ); } @@ -2282,7 +2278,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2136,9 +2215,11 @@ +@@ -2150,9 +2229,11 @@ if (in == -1 || out == -1 || err == -1) fatal("dup() in/out/err failed"); @@ -2295,7 +2291,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2149,6 +2230,11 @@ +@@ -2163,6 +2244,11 @@ debug3_f("channel_new: %d", c->self); @@ -2307,7 +2303,7 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c channel_send_open(ssh, c->self); if (options.session_type != SESSION_TYPE_NONE) channel_register_open_confirm(ssh, c->self, -@@ -2163,6 +2249,13 @@ +@@ -2177,6 +2263,13 @@ int r, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -2321,10 +2317,18 @@ diff -Nur openssh-9.0p1.orig/ssh.c openssh-9.0p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c ---- openssh-9.0p1.orig/sshconnect2.c 2022-08-30 20:22:42.477819991 +0200 -+++ openssh-9.0p1/sshconnect2.c 2022-08-30 20:23:49.907993123 +0200 -@@ -86,6 +86,13 @@ +diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c +--- openssh-9.3p1.orig/sshconnect2.c 2023-06-26 17:56:58.811634921 +0200 ++++ openssh-9.3p1/sshconnect2.c 2023-07-05 04:58:43.822783207 +0200 +@@ -76,6 +76,7 @@ + #include "utf8.h" + #include "ssh-sk.h" + #include "sk-api.h" ++#include "myproposal.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -85,6 +86,13 @@ extern Options options; /* @@ -2338,7 +2342,7 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c * SSH2 key exchange */ -@@ -216,6 +223,8 @@ +@@ -216,6 +224,8 @@ return ret; } @@ -2347,18 +2351,16 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c void ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, const struct ssh_conn_info *cinfo) -@@ -231,6 +240,10 @@ +@@ -229,6 +239,8 @@ char *gss_host = NULL; #endif -+ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); -+ + memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); + xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -583,6 +596,53 @@ +@@ -577,6 +589,53 @@ if (!authctxt.success) fatal("Authentication failed."); @@ -2412,10 +2414,10 @@ diff -Nur openssh-9.0p1.orig/sshconnect2.c openssh-9.0p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-9.0p1.orig/sshconnect.c openssh-9.0p1/sshconnect.c ---- openssh-9.0p1.orig/sshconnect.c 2022-08-30 20:22:42.325819600 +0200 -+++ openssh-9.0p1/sshconnect.c 2022-08-30 20:23:49.909993128 +0200 -@@ -345,6 +345,30 @@ +diff -Nur openssh-9.3p1.orig/sshconnect.c openssh-9.3p1/sshconnect.c +--- openssh-9.3p1.orig/sshconnect.c 2023-06-26 17:56:58.650634478 +0200 ++++ openssh-9.3p1/sshconnect.c 2023-06-26 17:59:25.028037041 +0200 +@@ -344,6 +344,30 @@ #endif /* @@ -2446,9 +2448,9 @@ diff -Nur openssh-9.0p1.orig/sshconnect.c openssh-9.0p1/sshconnect.c * Creates a socket for use as the ssh connection. */ static int -@@ -366,6 +390,9 @@ +@@ -365,6 +389,9 @@ } - fcntl(sock, F_SETFD, FD_CLOEXEC); + (void)fcntl(sock, F_SETFD, FD_CLOEXEC); + if (options.tcp_rcv_buf > 0) + ssh_set_socket_recvbuf(sock); @@ -2456,10 +2458,10 @@ diff -Nur openssh-9.0p1.orig/sshconnect.c openssh-9.0p1/sshconnect.c /* Use interactive QOS (if specified) until authentication completed */ if (options.ip_qos_interactive != INT_MAX) set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c ---- openssh-9.0p1.orig/sshd.c 2022-08-30 20:22:42.478819993 +0200 -+++ openssh-9.0p1/sshd.c 2022-08-30 20:23:49.910993131 +0200 -@@ -1106,6 +1106,8 @@ +diff -Nur openssh-9.3p1.orig/sshd.c openssh-9.3p1/sshd.c +--- openssh-9.3p1.orig/sshd.c 2023-06-26 17:56:58.812634923 +0200 ++++ openssh-9.3p1/sshd.c 2023-07-05 11:08:30.843125617 +0200 +@@ -1093,6 +1093,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2468,7 +2470,7 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1151,6 +1153,11 @@ +@@ -1138,6 +1140,11 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -2480,7 +2482,7 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1857,6 +1864,19 @@ +@@ -1876,6 +1883,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -2500,7 +2502,7 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && -@@ -2311,6 +2331,9 @@ +@@ -2359,6 +2379,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -2510,7 +2512,7 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -2423,6 +2446,25 @@ +@@ -2471,6 +2494,25 @@ /* Try to send all our hostkeys to the client */ notify_hostkeys(ssh); @@ -2536,8 +2538,8 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c /* Start session. */ do_authenticated(ssh, authctxt); -@@ -2498,6 +2540,11 @@ - char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; +@@ -2545,6 +2587,11 @@ + struct kex *kex; int r; + if (options.none_enabled == 1) @@ -2545,12 +2547,12 @@ diff -Nur openssh-9.0p1.orig/sshd.c openssh-9.0p1/sshd.c + if (options.nonemac_enabled == 1) + debug("WARNING: None MAC enabled"); + - myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, - options.kex_algorithms); - myproposal[PROPOSAL_ENC_ALGS_CTOS] = -diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config ---- openssh-9.0p1.orig/sshd_config 2022-08-30 20:22:42.478819993 +0200 -+++ openssh-9.0p1/sshd_config 2022-08-30 20:23:49.911993133 +0200 + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +diff -Nur openssh-9.3p1.orig/sshd_config openssh-9.3p1/sshd_config +--- openssh-9.3p1.orig/sshd_config 2023-06-26 17:56:58.813634926 +0200 ++++ openssh-9.3p1/sshd_config 2023-06-26 17:59:25.030037046 +0200 @@ -127,6 +127,28 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -2580,9 +2582,9 @@ diff -Nur openssh-9.0p1.orig/sshd_config openssh-9.0p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-9.0p1.orig/version.h openssh-9.0p1/version.h ---- openssh-9.0p1.orig/version.h 2022-08-30 20:22:42.480819998 +0200 -+++ openssh-9.0p1/version.h 2022-08-30 20:23:49.911993133 +0200 +diff -Nur openssh-9.3p1.orig/version.h openssh-9.3p1/version.h +--- openssh-9.3p1.orig/version.h 2023-06-26 17:56:58.814634929 +0200 ++++ openssh-9.3p1/version.h 2023-06-26 17:59:25.031037049 +0200 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" diff --git a/openssh-configure-c99-1.patch b/openssh-configure-c99-1.patch deleted file mode 100644 index a2c69aa..0000000 --- a/openssh-configure-c99-1.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 40b0a5eb6e3edfa2886b60c09c7803353b0cc7f5 -Author: Sam James -Date: Sun Nov 6 04:47:35 2022 +0000 - - configure.ac: Add include for openpty - - Another Clang 16ish fix (which makes -Wimplicit-function-declaration - an error by default). github PR#355. - - See: 2efd71da49b9cfeab7987058cf5919e473ff466b - See: be197635329feb839865fdc738e34e24afd1fca8 - -diff --git a/configure.ac b/configure.ac -index 1e77ecfc..1866aea5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2373,6 +2373,9 @@ if test ! -z "$check_for_openpty_ctty_bug"; then - #include - #include - #include -+#ifdef HAVE_PTY_H -+# include -+#endif - #include - #include - #include diff --git a/openssh-configure-c99-2.patch b/openssh-configure-c99-2.patch deleted file mode 100644 index 693e64f..0000000 --- a/openssh-configure-c99-2.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit 32fddb982fd61b11a2f218a115975a87ab126d43 -Author: Darren Tucker -Date: Mon Nov 7 10:39:01 2022 +1100 - - Fix setres*id checks to work with clang-16. - - glibc has the prototypes for setresuid and setresgid behind _GNU_SOURCE, - and clang 16 will error out on implicit function definitions, so add - _GNU_SOURCE and the required headers to the configure checks. From - sam at @gentoo.org via bz#3497. - -diff --git a/configure.ac b/configure.ac -index 4bf758ac..e172540a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -863,7 +863,8 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - check_for_openpty_ctty_bug=1 - dnl Target SUSv3/POSIX.1-2001 plus BSD specifics. - dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE -- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE" -+ dnl _GNU_SOURCE is needed for setres*id prototypes. -+ CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE" - AC_DEFINE([BROKEN_CLOSEFROM], [1], [broken in chroots on older kernels]) - AC_DEFINE([PAM_TTY_KLUDGE], [1], - [Work around problematic Linux PAM modules handling of PAM_TTY]) -@@ -2168,8 +2169,9 @@ AC_CHECK_FUNCS([setresuid], [ - AC_MSG_CHECKING([if setresuid seems to work]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ --#include - #include -+#include -+#include - ]], [[ - errno=0; - setresuid(0,0,0); -@@ -2191,8 +2193,9 @@ AC_CHECK_FUNCS([setresgid], [ - AC_MSG_CHECKING([if setresgid seems to work]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ --#include - #include -+#include -+#include - ]], [[ - errno=0; - setresgid(0,0,0); diff --git a/openssh-configure-c99-3.patch b/openssh-configure-c99-3.patch deleted file mode 100644 index 48ab14a..0000000 --- a/openssh-configure-c99-3.patch +++ /dev/null @@ -1,41 +0,0 @@ -commit 5eb796a369c64f18d55a6ae9b1fa9b35eea237fb -Author: Harmen Stoppels -Date: Thu Oct 13 16:08:46 2022 +0200 - - Fix snprintf configure test for clang 15 - - Clang 15 -Wimplicit-int defaults to an error in C99 mode and above. - A handful of tests have "main(..." and not "int main(..." which caused - the tests to produce incorrect results. - -diff --git a/configure.ac b/configure.ac -index de60a1b1..165c49de 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -713,7 +713,7 @@ case "$host" in - AC_RUN_IFELSE([AC_LANG_SOURCE([[ - #include - #include --main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) -+int main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - exit(0); - else - exit(1); -@@ -4259,7 +4259,7 @@ dnl test snprintf (broken on SCO w/gcc) - #include - #include - #ifdef HAVE_SNPRINTF --main() -+int main() - { - char buf[50]; - char expected_out[50]; -@@ -4276,7 +4276,7 @@ main() - exit(0); - } - #else --main() { exit(0); } -+int main() { exit(0); } - #endif - ]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ], - AC_MSG_WARN([cross compiling: Assuming working snprintf()]) diff --git a/sources b/sources index 82d7797..c322d35 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-9.0p1.tar.gz) = 613ae95317e734868c6a60d9cc5af47a889baa3124bbdd2b31bb51dd6b57b136f4cfcb5604cca78a03bd500baab9b9b45eaf77e038b1ed776c86dce0437449a9 -SHA512 (openssh-9.0p1.tar.gz.asc) = 7b1445764058435d2fa8a9c7553643983650d4232036c088e46e44beeb538d32cba88f775b1be9da5f21a01d6caea59b3dc4714507781e9cb946546fa54f169f +SHA512 (openssh-9.3p1.tar.gz) = 087ff6fe5f6caab4c6c3001d906399e02beffad7277280f11187420c2939fd4befdcb14643862a657ce4cad2f115b82a0a1a2c99df6ee54dcd76b53647637c19 +SHA512 (openssh-9.3p1.tar.gz.asc) = 6222378eb24a445c6c1db255392b405f5369b1af0e92f558d4ba05b0d83ab0d084cb8f4b91d7ae8636f333d970638a6635e2bc7af885135dd34992d87f2ef1f4 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 0172aacf0aecee61b3b7d2ca8bfb9e0dcff4edda Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 23 Jul 2023 08:40:50 +0200 Subject: [PATCH 118/146] Based on openssh-9.3p1-5.fc39.1 --- gsi-openssh.spec | 139 +-- openssh-7.7p1-fips.patch | 12 +- openssh-8.0p1-crypto-policies.patch | 78 +- openssh-8.0p1-gssapi-keyex.patch | 17 + openssh-8.0p1-openssl-evp.patch | 720 ----------- openssh-8.0p1-pkcs11-uri.patch | 100 +- openssh-8.7p1-evpgenkey.patch | 109 -- openssh-8.7p1-gssapi-auth.patch | 20 - openssh-9.0p1-evp-fips-sign.patch | 476 -------- openssh-9.0p1-evp-pkcs11.patch | 145 --- openssh-9.0p1-man-hostkeyalgos.patch | 16 - openssh-9.3p1-merged-openssl-evp.patch | 1220 +++++++++++++++++++ openssh-9.3p1-upstream-cve-2023-38408.patch | 130 ++ 13 files changed, 1525 insertions(+), 1657 deletions(-) delete mode 100644 openssh-8.0p1-openssl-evp.patch delete mode 100644 openssh-8.7p1-evpgenkey.patch delete mode 100644 openssh-8.7p1-gssapi-auth.patch delete mode 100644 openssh-9.0p1-evp-fips-sign.patch delete mode 100644 openssh-9.0p1-evp-pkcs11.patch delete mode 100644 openssh-9.0p1-man-hostkeyalgos.patch create mode 100644 openssh-9.3p1-merged-openssl-evp.patch create mode 100644 openssh-9.3p1-upstream-cve-2023-38408.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 297581a..0bd49a9 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -89,6 +89,10 @@ Patch711: openssh-7.8p1-UsePAM-warning.patch # GSSAPI Key Exchange (RFC 4462 + RFC 8732) # from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master +# and +# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures +# upstream MR: +# https://github.com/openssh-gsskex/openssh-gsskex/pull/21 Patch800: openssh-8.0p1-gssapi-keyex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html Patch801: openssh-6.6p1-force_krb.patch @@ -132,9 +136,11 @@ Patch951: openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch # Mention crypto-policies in manual pages (#1668325) +# clarify rhbz#2068423 on the man page of ssh_config Patch962: openssh-8.0p1-crypto-policies.patch # Use OpenSSL high-level API to produce and verify signatures (#1707485) -Patch963: openssh-8.0p1-openssl-evp.patch +# TODO fix the comment above ^ +Patch963: openssh-9.3p1-merged-openssl-evp.patch # Use OpenSSL KDF (#1631761) Patch964: openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work @@ -154,8 +160,6 @@ Patch977: openssh-8.7p1-scp-kill-switch.patch Patch981: openssh-8.7p1-recursive-scp.patch # https://github.com/djmdjm/openssh-wip/pull/13 Patch982: openssh-8.7p1-minrsabits.patch -# downstream only -Patch983: openssh-8.7p1-evpgenkey.patch # downstream only, IBMCA tentative fix # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 Patch984: openssh-8.7p1-ibmca.patch @@ -164,23 +168,15 @@ Patch984: openssh-8.7p1-ibmca.patch # upstream bug: # https://bugzilla.mindrot.org/show_bug.cgi?id=3455 Patch1002: openssh-8.7p1-ssh-manpage.patch -# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures -# upstream MR: -# https://github.com/openssh-gsskex/openssh-gsskex/pull/21 -Patch1004: openssh-8.7p1-gssapi-auth.patch # Don't propose disallowed algorithms during hostkey negotiation # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch -Patch1011: openssh-9.0p1-evp-fips-sign.patch Patch1012: openssh-9.0p1-evp-fips-dh.patch Patch1013: openssh-9.0p1-evp-fips-ecdh.patch Patch1014: openssh-8.7p1-nohostsha1proof.patch -Patch1015: openssh-9.0p1-evp-pkcs11.patch - -# clarify rhbz#2068423 on the man page of ssh_config -Patch1016: openssh-9.0p1-man-hostkeyalgos.patch +Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch # Fix issue with read-only ssh buffer during gssapi key exchange (#1938224) # https://github.com/openssh-gsskex/openssh-gsskex/pull/19 @@ -285,74 +281,70 @@ This version of OpenSSH has been modified to support GSI authentication. gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %setup -q -n openssh-%{version} -%patch400 -p1 -b .role-mls -%patch404 -p1 -b .privsep-selinux +%patch -P 400 -p1 -b .role-mls +%patch -P 404 -p1 -b .privsep-selinux -%patch502 -p1 -b .keycat +%patch -P 502 -p1 -b .keycat -%patch601 -p1 -b .ip-opts -%patch606 -p1 -b .ipv6man -%patch607 -p1 -b .sigpipe -%patch609 -p1 -b .x11 +%patch -P 601 -p1 -b .ip-opts +%patch -P 606 -p1 -b .ipv6man +%patch -P 607 -p1 -b .sigpipe +%patch -P 609 -p1 -b .x11 -%patch702 -p1 -b .progress -%patch703 -p1 -b .grab-info -%patch707 -p1 -b .redhat -%patch711 -p1 -b .log-usepam-no +%patch -P 702 -p1 -b .progress +%patch -P 703 -p1 -b .grab-info +%patch -P 707 -p1 -b .redhat +%patch -P 711 -p1 -b .log-usepam-no -%patch800 -p1 -b .gsskex -%patch801 -p1 -b .force_krb -%patch804 -p1 -b .ccache_name -%patch805 -p1 -b .k5login +%patch -P 800 -p1 -b .gsskex +%patch -P 801 -p1 -b .force_krb +%patch -P 804 -p1 -b .ccache_name +%patch -P 805 -p1 -b .k5login -%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 -%patch962 -p1 -b .crypto-policies -%patch963 -p1 -b .openssl-evp -%patch964 -p1 -b .openssl-kdf -%patch965 -p1 -b .visibility -%patch966 -p1 -b .x11-ipv6 -%patch974 -p1 -b .keygen-strip-doseol -%patch975 -p1 -b .preserve-pam-errors -%patch977 -p1 -b .kill-scp -%patch981 -p1 -b .scp-sftpdirs -%patch982 -p1 -b .minrsabits -%patch983 -p1 -b .evpgenrsa -%patch984 -p1 -b .ibmca +%patch -P 901 -p1 -b .kuserok +%patch -P 906 -p1 -b .fromto-remote +%patch -P 916 -p1 -b .contexts +%patch -P 918 -p1 -b .log-in-chroot +%patch -P 919 -p1 -b .scp +%patch -P 802 -p1 -b .GSSAPIEnablek5users +%patch -P 922 -p1 -b .sshdt +%patch -P 926 -p1 -b .sftp-force-mode +%patch -P 939 -p1 -b .s390-dev +%patch -P 944 -p1 -b .x11max +%patch -P 948 -p1 -b .systemd +%patch -P 949 -p1 -b .refactor +%patch -P 950 -p1 -b .sandbox +%patch -P 951 -p1 -b .pkcs11-uri +%patch -P 953 -p1 -b .scp-ipv6 +%patch -P 962 -p1 -b .crypto-policies +%patch -P 963 -p1 -b .openssl-evp +%patch -P 964 -p1 -b .openssl-kdf +%patch -P 965 -p1 -b .visibility +%patch -P 966 -p1 -b .x11-ipv6 +%patch -P 974 -p1 -b .keygen-strip-doseol +%patch -P 975 -p1 -b .preserve-pam-errors +%patch -P 977 -p1 -b .kill-scp +%patch -P 981 -p1 -b .scp-sftpdirs +%patch -P 982 -p1 -b .minrsabits +%patch -P 984 -p1 -b .ibmca -%patch200 -p1 -b .audit -%patch201 -p1 -b .audit-race -%patch202 -p1 -b .audit-log -%patch700 -p1 -b .fips +%patch -P 200 -p1 -b .audit +%patch -P 201 -p1 -b .audit-race +%patch -P 202 -p1 -b .audit-log +%patch -P 700 -p1 -b .fips -%patch1002 -p1 -b .ssh-manpage -%patch1004 -p1 -b .gssapi-auth -%patch1006 -p1 -b .negotiate-supported-algs -%patch1011 -p1 -b .evp-fips-sign -%patch1012 -p1 -b .evp-fips-dh -%patch1013 -p1 -b .evp-fips-ecdh -%patch1014 -p1 -b .nosha1hostproof -%patch1015 -p1 -b .evp-pkcs11 -%patch1016 -p1 -b .man-hostkeyalgos +%patch -P 1002 -p1 -b .ssh-manpage +%patch -P 1006 -p1 -b .negotiate-supported-algs +%patch -P 1012 -p1 -b .evp-fips-dh +%patch -P 1013 -p1 -b .evp-fips-ecdh +%patch -P 1014 -p1 -b .nosha1hostproof +%patch -P 1015 -p1 -b .cve-2023-38408 -%patch100 -p1 -b .coverity +%patch -P 100 -p1 -b .coverity -%patch97 -p1 -b .sshbuf-ro -%patch98 -p1 -b .gsi -%patch99 -p1 -b .hpn +%patch -P 97 -p1 -b .sshbuf-ro +%patch -P 98 -p1 -b .gsi +%patch -P 99 -p1 -b .hpn sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in @@ -545,6 +537,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Sun Jul 23 2023 Mattias Ellert - 9.3p1-2 +- Based on openssh-9.3p1-5.fc39.1 + * Wed Jul 19 2023 Mattias Ellert - 9.3p1-1 - Based on openssh-9.3p1-3.fc39 - Fix keyex patch diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 180f13e..5351571 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -415,10 +415,10 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c --- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 +++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 -@@ -34,6 +34,7 @@ - #include - #include +@@ -36,6 +36,7 @@ #include + #include + #include +#include #endif @@ -540,10 +540,10 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c --- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 +++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 -@@ -31,6 +31,7 @@ - - #include +@@ -33,6 +33,7 @@ #include + #include + #include +#include #include diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index d4549f0..86c08db 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -diff --color -ru a/ssh_config.5 b/ssh_config.5 ---- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200 -+++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200 -@@ -373,17 +373,13 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh_config.5 openssh-9.3p1-patched/ssh_config.5 +--- openssh-9.3p1/ssh_config.5 2023-06-07 10:26:48.284590156 +0200 ++++ openssh-9.3p1-patched/ssh_config.5 2023-06-07 10:26:00.623052194 +0200 +@@ -378,17 +378,13 @@ causes no CNAMEs to be considered for canonicalization. This is the default behaviour. .It Cm CASignatureAlgorithms @@ -24,7 +24,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -445,20 +441,25 @@ +@@ -450,20 +446,25 @@ (the default), the check will not be executed. .It Cm Ciphers @@ -54,7 +54,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -474,13 +475,6 @@ +@@ -479,13 +480,6 @@ chacha20-poly1305@openssh.com .Ed .Pp @@ -68,7 +68,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -874,6 +868,11 @@ +@@ -885,6 +879,11 @@ The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -80,7 +80,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -886,10 +885,8 @@ +@@ -897,10 +896,8 @@ gss-curve25519-sha256- .Ed .Pp @@ -92,7 +92,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -913,36 +910,25 @@ +@@ -919,36 +916,25 @@ but may be manually hashed using .Xr ssh-keygen 1 . .It Cm HostbasedAcceptedAlgorithms @@ -137,7 +137,25 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The .Fl Q -@@ -1219,30 +1216,25 @@ +@@ -1001,6 +987,17 @@ + .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 +@@ -1232,30 +1229,25 @@ and .Cm pam . .It Cm KexAlgorithms @@ -177,7 +195,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1351,37 +1344,33 @@ +@@ -1365,37 +1357,33 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -224,7 +242,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1553,36 +1542,25 @@ +@@ -1567,39 +1555,31 @@ The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -270,7 +288,13 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2237,7 +2207,9 @@ for those users who do not have a config ++.Pp ++This option affects also ++.Cm HostKeyAlgorithms + .It Cm PubkeyAuthentication + Specifies whether to try public key authentication. + The argument to this keyword must be +@@ -2265,7 +2245,9 @@ This file must be world-readable. .El .Sh SEE ALSO @@ -281,10 +305,10 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free -diff --color -ru a/sshd_config.5 b/sshd_config.5 ---- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200 -+++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200 -@@ -373,17 +373,13 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshd_config.5 openssh-9.3p1-patched/sshd_config.5 +--- openssh-9.3p1/sshd_config.5 2023-06-07 10:26:48.277590077 +0200 ++++ openssh-9.3p1-patched/sshd_config.5 2023-06-07 10:26:00.592051845 +0200 +@@ -379,17 +379,13 @@ then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -307,7 +331,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -450,20 +446,25 @@ +@@ -525,20 +521,25 @@ indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -337,7 +361,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -490,13 +491,6 @@ +@@ -565,13 +566,6 @@ chacha20-poly1305@openssh.com .El .Pp @@ -351,7 +375,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -685,53 +679,43 @@ +@@ -766,53 +760,43 @@ .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -424,7 +448,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostbasedAcceptedAlgorithms . -@@ -799,25 +794,14 @@ +@@ -879,25 +863,14 @@ .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -455,7 +479,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -965,20 +947,25 @@ +@@ -1044,20 +1017,25 @@ The default is .Cm yes . .It Cm KexAlgorithms @@ -485,7 +509,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1010,16 +997,6 @@ +@@ -1089,16 +1067,6 @@ sntrup761x25519-sha512@openssh.com .El .Pp @@ -502,7 +526,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1104,21 +1082,26 @@ +@@ -1184,21 +1152,26 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -533,7 +557,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1161,15 +1144,6 @@ +@@ -1241,15 +1214,6 @@ umac-128-etm@openssh.com .El .Pp @@ -549,7 +573,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1548,36 +1522,25 @@ +@@ -1633,36 +1597,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -595,7 +619,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2011,7 +1968,9 @@ This file should be writable by root onl +@@ -2131,7 +2084,9 @@ .El .Sh SEE ALSO .Xr sftp-server 8 , diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 3e79581..d1d914d 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -2612,6 +2612,23 @@ index 2ce89fe9..ebf76c7f 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { +@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s + if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { + auth_log(ssh, authenticated, partial, + auth_method, auth_submethod); +- if (!partial && !authenticated) ++ if (!partial && !authenticated) { ++#ifdef GSSAPI ++ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled. ++ * We have to reenable it to try again for gssapi-keyex */ ++ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex) ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); ++#endif + authctxt->failures++; ++ } + if (authenticated || partial) { + auth2_update_session_info(authctxt, + auth_method, auth_submethod); @@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); diff --git a/openssh-8.0p1-openssl-evp.patch b/openssh-8.0p1-openssl-evp.patch deleted file mode 100644 index a17dbbc..0000000 --- a/openssh-8.0p1-openssl-evp.patch +++ /dev/null @@ -1,720 +0,0 @@ -From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -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 -+/* 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 - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, 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 *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -+ EVP_PKEY *pkey = NULL; - DSA_SIG *dsig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; -- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; -- size_t len, hlen = 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; -- if (hlen == 0) -- return SSH_ERR_INTERNAL_ERROR; - - /* fetch signature */ - if ((b = sshbuf_from(sig, siglen)) == 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, dlen, -- digest, sizeof(digest))) != 0) -+ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; -- -- switch (DSA_do_verify(digest, hlen, dsig, 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(dsig, &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, dlen, -+ sigb, slen); -+ EVP_PKEY_free(pkey); -+ - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - DSA_SIG_free(dsig); - 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 - const u_char *data, size_t dlen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) - { -+ EVP_PKEY *pkey = NULL; - ECDSA_SIG *esig = 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, hlen; -+ 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 || -- (hlen = 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, dlen, -- 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, -+ dlen); -+ EVP_PKEY_free(pkey); -+ if (ret < 0) { - goto out; -+ } - -- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { -+ psig = sigb; -+ if (d2i_ECDSA_SIG(&esig, &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(esig); -@@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key, - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -+ EVP_PKEY *pkey = NULL; - ECDSA_SIG *esig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; -- int hash_alg; -- u_char digest[SSH_DIGEST_MAX_LENGTH]; -- size_t hlen; -+ 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - -- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || -- (hlen = 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(esig, 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, dlen, -- digest, sizeof(digest))) != 0) -+ psig = sigb; -+ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; -+ } - -- switch (ECDSA_do_verify(digest, hlen, esig, 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, dlen, sigb, len); -+ EVP_PKEY_free(pkey); - - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - sshbuf_free(sigbuf); - sshbuf_free(b); - ECDSA_SIG_free(esig); -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 u_int - ssh_rsa_size(const struct sshkey *key) -@@ -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 - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) - { -- const BIGNUM *rsa_n; -- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; -- size_t slen = 0; -- u_int hlen, 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); -+ - 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 ((hlen = 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, hlen, 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 *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -- 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, hlen; -+ 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 ((hlen = 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, dlen, -- digest, sizeof(digest))) != 0) -- goto out; -+ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); -+ EVP_PKEY_free(pkey); - -- ret = openssh_RSA_verify(hash_alg, digest, hlen, 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; - } - -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 **); - diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index be38500..affdd72 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -534,7 +534,7 @@ diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regre diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c --- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 +++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 -@@ -0,0 +1,342 @@ +@@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -563,7 +563,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +#include "sshbuf.h" +#include "ssh-pkcs11-uri.h" + -+#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) + +/* prototypes are not public -- specify them here internally for tests */ +struct sshbuf *percent_encode(const char *, size_t, char *); @@ -596,10 +596,6 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); + else /* both should be null */ + ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); -+ if (b->serial != NULL) -+ ASSERT_STRING_EQ(a->serial, b->serial); -+ else /* both should be null */ -+ ASSERT_PTR_EQ(a->serial, b->serial); +} + +void @@ -634,7 +630,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + +struct pkcs11_uri * +compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, -+ char *manuf, char *serial, char *module_path, char *object, char *pin) ++ char *manuf, char *module_path, char *object, char *pin) +{ + struct pkcs11_uri *uri = pkcs11_uri_init(); + if (id_len > 0) { @@ -645,7 +641,6 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + uri->token = token; + uri->lib_manuf = lib_manuf; + uri->manuf = manuf; -+ uri->serial = serial; + uri->object = object; + uri->pin = pin; + return uri; @@ -656,47 +651,47 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_parse("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:token=SSH%20Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL)); + check_parse("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); + check_parse("pkcs11:object=SIGN%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); + /* query arguments */ + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse("pkcs11:?pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "123456")); + + /* combinations */ + /* ID SHOULD be percent encoded */ + check_parse("pkcs11:token=SSH%20Key;id=0", -+ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL)); + check_parse( + "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, "CAC", NULL, ++ compose_uri(NULL, 0, NULL, NULL, "CAC", + "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse( + "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, ++ compose_uri(NULL, 0, NULL, NULL, NULL, + "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key", NULL)); + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so&pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); + + /* empty path component matches everything */ + check_parse("pkcs11:", EMPTY_URI); + + /* empty string is a valid to match against (and different from NULL) */ + check_parse("pkcs11:token=", -+ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL)); + /* Percent character needs to be percent-encoded */ + check_parse("pkcs11:token=%25", -+ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL)); +} + +static void @@ -708,7 +703,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); + /* Space MUST be percent encoded -- XXX not enforced yet */ + check_parse("pkcs11:token=SSH Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); + /* MUST NOT contain duplicate attributes of the same name */ + check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); + /* MUST NOT contain duplicate attributes of the same name */ @@ -739,29 +734,29 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_gen("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); + /* library-manufacturer is not implmented now */ + /*check_gen("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL));*/ ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL));*/ + check_gen("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); + check_gen("pkcs11:object=RSA%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "RSA Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key", NULL)); + /* query arguments */ + check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + + /* combinations */ + check_gen("pkcs11:id=%02;token=SSH%20Keys", -+ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, "Encryption Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key", NULL)); + + /* empty path component matches everything */ + check_gen("pkcs11:", EMPTY_URI); @@ -1550,7 +1545,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1592,7 +1587,6 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + uri.module_path = k11->provider->module->module_path; + uri.lib_manuf = k11->provider->module->info.manufacturerID; + uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; + + p = pkcs11_uri_get(&uri); + /* do not cleanup -- we do not allocate here, only reference */ @@ -2163,7 +2157,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1702,305 @@ pkcs11_register_provider(char *provider_ +@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2407,13 +2401,6 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + "manufacturerID (%s) specified by PKCS#11 URI in " + "slot %lu", token->manufacturerID, (unsigned long)i); + continue; -+ } -+ if (uri->serial != NULL && -+ strcmp(token->serialNumber, uri->serial) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "serialNumber (%s) specified by PKCS#11 URI in " -+ "slot %lu", token->serialNumber, (unsigned long)i); -+ continue; + } debug("provider %s slot %lu: label <%s> manufacturerID <%s> " "model <%s> serial <%s> flags 0x%lx", @@ -2604,7 +2591,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c --- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,437 @@ +@@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -2647,14 +2634,13 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +#define PKCS11_URI_OBJECT "object" +#define PKCS11_URI_LIB_MANUF "library-manufacturer" +#define PKCS11_URI_MANUF "manufacturer" -+#define PKCS11_URI_SERIAL "serial" +#define PKCS11_URI_MODULE_PATH "module-path" +#define PKCS11_URI_PIN_VALUE "pin-value" + +/* Keyword tokens. */ +typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pSerial, -+ pModulePath, pPinValue, pBadOption ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pPinValue, pBadOption +} pkcs11uriOpCodes; + +/* Textual representation of the tokens. */ @@ -2667,7 +2653,6 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + { PKCS11_URI_OBJECT, pObject }, + { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, + { PKCS11_URI_MANUF, pManufacturer }, -+ { PKCS11_URI_SERIAL, pSerial }, + { PKCS11_URI_MODULE_PATH, pModulePath }, + { PKCS11_URI_PIN_VALUE, pPinValue }, + { NULL, pBadOption } @@ -2826,16 +2811,6 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + goto err; + } + -+ /* Write serial */ -+ if (uri->serial) { -+ struct sshbuf *serial = percent_encode(uri->serial, -+ strlen(uri->serial), PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_SERIAL, serial); -+ if (path == NULL) -+ goto err; -+ } -+ + /* Write module_path */ + if (uri->module_path) { + struct sshbuf *module = percent_encode(uri->module_path, @@ -2878,7 +2853,6 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + free(pkcs11->object); + free(pkcs11->lib_manuf); + free(pkcs11->manuf); -+ free(pkcs11->serial); + if (pkcs11->pin) + freezero(pkcs11->pin, strlen(pkcs11->pin)); + free(pkcs11); @@ -2974,11 +2948,6 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + charptr = &pkcs11->manuf; + goto parse_string; + -+ case pSerial: -+ /* CK_TOKEN_INFO -> serialNumber */ -+ charptr = &pkcs11->serial; -+ goto parse_string; -+ + case pLibraryManufacturer: + /* CK_INFO -> manufacturerID */ + charptr = &pkcs11->lib_manuf; @@ -3045,7 +3014,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h --- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,43 @@ +@@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3077,7 +3046,6 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + char *object; + char *lib_manuf; + char *manuf; -+ char *serial; + /* query */ + char *module_path; + char *pin; /* Only parsed, but not printed */ diff --git a/openssh-8.7p1-evpgenkey.patch b/openssh-8.7p1-evpgenkey.patch deleted file mode 100644 index c8703d9..0000000 --- a/openssh-8.7p1-evpgenkey.patch +++ /dev/null @@ -1,109 +0,0 @@ -diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c ---- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 -+++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 -@@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k) - static int - ssh_rsa_generate(struct sshkey *k, int bits) - { -- RSA *private = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *res = NULL; - BIGNUM *f4 = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; - -@@ -1667,20 +1668,42 @@ ssh_rsa_generate(u_int bits, RSA - if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || - bits > SSHBUF_MAX_BIGNUM * 8) - return SSH_ERR_KEY_LENGTH; -- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { -+ -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL -+ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (!BN_set_word(f4, RSA_F4) || -- !RSA_generate_key_ex(private, bits, f4, NULL)) { -+ -+ if (EVP_PKEY_keygen_init(ctx) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { -+ ret = SSH_ERR_KEY_LENGTH; -+ goto out; -+ } -+ -+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0) -+ goto out; -+ -+ if (EVP_PKEY_keygen(ctx, &res) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ k->rsa = EVP_PKEY_get1_RSA(res); -+ if (k->rsa) { -+ ret = 0; -+ } else { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- k->rsa = private; -- private = NULL; -- ret = 0; - out: -- RSA_free(private); -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); - BN_free(f4); - return ret; - } -diff -up openssh-9.3p1/ssh-ecdsa.c.evpgenrsa openssh-9.3p1/ssh-ecdsa.c ---- openssh-9.3p1/ssh-ecdsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 -+++ openssh-9.3p1/ssh-ecdsa.c 2022-06-30 15:24:31.499641196 +0200 -@@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) - static int - ssh_ecdsa_generate(struct sshkey *k, int bits) - { -- EC_KEY *private; -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *res = NULL; - - if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) - return SSH_ERR_KEY_LENGTH; -@@ -1828,15 +1829,24 @@ ssh_ecdsa_generate(u_int bits, i - - if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) - return SSH_ERR_KEY_LENGTH; -- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) -+ -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if (EC_KEY_generate_key(private) != 1) { -- EC_KEY_free(private); -- return SSH_ERR_LIBCRYPTO_ERROR; -- } -+ -+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0 -+ || EVP_PKEY_keygen(ctx, &res) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ k->ecdsa = EVP_PKEY_get1_EC_KEY(res); -+ if (k->ecdsa) -+ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE); -+ -- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); -- k->ecdsa = private; -- return 0; -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); -+ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR; - } - - static int diff --git a/openssh-8.7p1-gssapi-auth.patch b/openssh-8.7p1-gssapi-auth.patch deleted file mode 100644 index 6908cad..0000000 --- a/openssh-8.7p1-gssapi-auth.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --color -rup a/monitor.c b/monitor.c ---- a/monitor.c 2022-07-11 15:11:28.146863144 +0200 -+++ b/monitor.c 2022-07-11 15:15:35.726655877 +0200 -@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s - if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { - auth_log(ssh, authenticated, partial, - auth_method, auth_submethod); -- if (!partial && !authenticated) -+ if (!partial && !authenticated) { -+#ifdef GSSAPI -+ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled. -+ * We have to reenable it to try again for gssapi-keyex */ -+ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex) -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); -+#endif - authctxt->failures++; -+ } - if (authenticated || partial) { - auth2_update_session_info(authctxt, - auth_method, auth_submethod); diff --git a/openssh-9.0p1-evp-fips-sign.patch b/openssh-9.0p1-evp-fips-sign.patch deleted file mode 100644 index 40cc374..0000000 --- a/openssh-9.0p1-evp-fips-sign.patch +++ /dev/null @@ -1,476 +0,0 @@ -diff -up openssh-9.3p1/ssh-dss.c.evp-fips-sign openssh-9.3p1/ssh-dss.c ---- openssh-9.3p1/ssh-dss.c.evp-fips-sign 2023-04-27 16:46:17.115809116 +0200 -+++ openssh-9.3p1/ssh-dss.c 2023-04-27 17:07:40.117253665 +0200 -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -281,9 +283,8 @@ ssh_dss_sign(struct sshkey *key, - sshkey_type_plain(key->type) != KEY_DSA) - return SSH_ERR_INVALID_ARGUMENT; - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) -- return SSH_ERR_ALLOC_FAIL; -+ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) -+ return ret; - ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, - data, datalen); - EVP_PKEY_free(pkey); -@@ -411,11 +412,8 @@ ssh_dss_verify(const struct sshkey *key, - goto out; - } - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) { -- ret = SSH_ERR_ALLOC_FAIL; -+ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) - goto out; -- } - ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, - sigb, slen); - EVP_PKEY_free(pkey); -@@ -432,6 +430,65 @@ ssh_dss_verify(const struct sshkey *key, - return ret; - } - -+int -+ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) -+{ -+ OSSL_PARAM_BLD *param_bld = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; -+ int ret = 0; -+ -+ if (k == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ DSA_get0_pqg(k->dsa, &p, &q, &g); -+ DSA_get0_key(k->dsa, &pub, &priv); -+ -+ if (p != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (q != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (g != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (pub != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, -+ OSSL_PKEY_PARAM_PUB_KEY, -+ pub) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (priv != 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); -+ return ret; -+} -+ - static const struct sshkey_impl_funcs sshkey_dss_funcs = { - /* .size = */ ssh_dss_size, - /* .alloc = */ ssh_dss_alloc, -diff -up openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign openssh-9.3p1/ssh-ecdsa.c ---- openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign 2023-04-27 16:46:17.127809401 +0200 -+++ openssh-9.3p1/ssh-ecdsa.c 2023-04-27 17:08:28.557396513 +0200 -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -260,9 +262,8 @@ ssh_ecdsa_sign(struct sshkey *key, - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) - return SSH_ERR_INTERNAL_ERROR; - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) -- return SSH_ERR_ALLOC_FAIL; -+ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) -+ return ret; - ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, - dlen); - EVP_PKEY_free(pkey); -@@ -381,11 +382,8 @@ ssh_ecdsa_verify(const struct sshkey *ke - goto out; - } - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) { -- ret = SSH_ERR_ALLOC_FAIL; -+ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) - goto out; -- } - ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len); - EVP_PKEY_free(pkey); - -@@ -400,6 +398,79 @@ ssh_ecdsa_verify(const struct sshkey *ke - return ret; - } - -+int -+ssh_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; -+} -+ - /* NB. not static; used by ECDSA-SK */ - const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { - /* .size = */ ssh_ecdsa_size, -diff -up openssh-9.3p1/sshkey.c.evp-fips-sign openssh-9.3p1/sshkey.c ---- openssh-9.3p1/sshkey.c.evp-fips-sign 2023-04-27 16:46:17.139809686 +0200 -+++ openssh-9.3p1/sshkey.c 2023-04-27 16:46:17.144809804 +0200 -@@ -35,6 +35,8 @@ - #include - #include - #include -+#include -+#include - #endif - - #include "crypto_api.h" -@@ -527,13 +529,14 @@ sshkey_calculate_signature(EVP_PKEY *pke - { - EVP_MD_CTX *ctx = NULL; - u_char *sig = NULL; -- int ret, slen, len; -+ int ret, slen; -+ size_t len; - - if (sigp == NULL || lenp == NULL) { - return SSH_ERR_INVALID_ARGUMENT; - } - -- slen = EVP_PKEY_size(pkey); -+ slen = EVP_PKEY_get_size(pkey); - if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) - return SSH_ERR_INVALID_ARGUMENT; - -@@ -546,9 +549,10 @@ sshkey_calculate_signature(EVP_PKEY *pke - 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) { -+ if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg), -+ NULL, pkey) != 1 || -+ EVP_DigestSignUpdate(ctx, data, datalen) != 1 || -+ EVP_DigestSignFinal(ctx, sig, &len) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto error; - } -@@ -575,12 +579,13 @@ sshkey_verify_signature(EVP_PKEY *pkey, - 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) { -+ if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg), -+ NULL, pkey) != 1 || -+ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto done; - } -- ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey); -+ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen); - switch (ret) { - case 1: - ret = 0; -@@ -3809,3 +3814,27 @@ sshkey_set_filename(struct sshkey *k, co - return 0; - } - #endif /* WITH_XMSS */ -+ -+#ifdef WITH_OPENSSL -+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; -+} -+#endif /* WITH_OPENSSL */ -diff -up openssh-9.3p1/sshkey.h.evp-fips-sign openssh-9.3p1/sshkey.h ---- openssh-9.3p1/sshkey.h.evp-fips-sign 2023-04-27 16:46:17.133809543 +0200 -+++ openssh-9.3p1/sshkey.h 2023-04-27 16:46:17.144809804 +0200 -@@ -31,6 +31,9 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include -+#include -+#include - # ifdef OPENSSL_HAS_ECC - # include - # include -@@ -328,6 +331,13 @@ int sshkey_private_serialize_maxsign(st - - void sshkey_sig_details_free(struct sshkey_sig_details *); - -+#ifdef WITH_OPENSSL -+EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *); -+int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **); -+int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **); -+int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **); -+#endif /* WITH_OPENSSL */ -+ - #ifdef SSHKEY_INTERNAL - int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); - void sshkey_sk_cleanup(struct sshkey *k); -diff -up openssh-9.3p1/ssh-rsa.c.evp-fips-sign openssh-9.3p1/ssh-rsa.c ---- openssh-9.3p1/ssh-rsa.c.evp-fips-sign 2023-04-27 16:46:17.139809686 +0200 -+++ openssh-9.3p1/ssh-rsa.c 2023-04-27 17:10:30.376270565 +0200 -@@ -23,6 +23,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -426,9 +428,8 @@ ssh_rsa_sign(struct sshkey *key, - if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) -- return SSH_ERR_ALLOC_FAIL; -+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) -+ return ret; - ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, - datalen); - EVP_PKEY_free(pkey); -@@ -540,11 +541,9 @@ ssh_rsa_verify(const struct sshkey *key, - len = modlen; - } - -- if ((pkey = EVP_PKEY_new()) == NULL || -- EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) { -- ret = SSH_ERR_ALLOC_FAIL; -+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) - goto out; -- } -+ - ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); - EVP_PKEY_free(pkey); - -@@ -561,11 +560,9 @@ openssh_RSA_verify(int hash_alg, const u - u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) - { - size_t rsasize = 0; -- const RSA *rsa; - int ret; - -- rsa = EVP_PKEY_get0_RSA(pkey); -- rsasize = RSA_size(rsa); -+ rsasize = EVP_PKEY_get_size(pkey); - if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || - siglen == 0 || siglen > rsasize) { - ret = SSH_ERR_INVALID_ARGUMENT; -@@ -579,6 +576,89 @@ done: - return ret; - } - -+int -+ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) -+{ -+ OSSL_PARAM_BLD *param_bld = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ int ret = 0; -+ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL; -+ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; -+ -+ if (k == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ RSA_get0_key(k->rsa, &n, &e, &d); -+ RSA_get0_factors(k->rsa, &p, &q); -+ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); -+ -+ if (n != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (e != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (d != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ /* setting this to param_build makes the creation process fail */ -+ if (p != NULL && -+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) { -+ debug2_f("failed to add 'p' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (q != NULL && -+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) { -+ debug2_f("failed to add 'q' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (dmp1 != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) { -+ debug2_f("failed to add 'dmp1' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (dmq1 != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) { -+ debug2_f("failed to add 'dmq1' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (iqmp != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) { -+ debug2_f("failed to add 'iqmp' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+out: -+ OSSL_PARAM_BLD_free(param_bld); -+ EVP_PKEY_CTX_free(ctx); -+ return ret; -+} -+ - static const struct sshkey_impl_funcs sshkey_rsa_funcs = { - /* .size = */ ssh_rsa_size, - /* .alloc = */ ssh_rsa_alloc, diff --git a/openssh-9.0p1-evp-pkcs11.patch b/openssh-9.0p1-evp-pkcs11.patch deleted file mode 100644 index 325332d..0000000 --- a/openssh-9.0p1-evp-pkcs11.patch +++ /dev/null @@ -1,145 +0,0 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-ecdsa.c openssh-9.0p1-patched/ssh-ecdsa.c ---- openssh-9.0p1/ssh-ecdsa.c 2023-05-24 08:54:03.926443958 +0200 -+++ openssh-9.0p1-patched/ssh-ecdsa.c 2023-05-24 09:46:19.082925921 +0200 -@@ -74,8 +74,18 @@ - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) - return SSH_ERR_INTERNAL_ERROR; - -- if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) -- return ret; -+#ifdef ENABLE_PKCS11 -+ if (is_ecdsa_pkcs11(key->ecdsa)) { -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) -+ return SSH_ERR_ALLOC_FAIL; -+ } else { -+#endif -+ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) -+ return ret; -+#ifdef ENABLE_PKCS11 -+ } -+#endif - ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, - dlen); - EVP_PKEY_free(pkey); -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/sshkey.h openssh-9.0p1-patched/sshkey.h ---- openssh-9.0p1/sshkey.h 2023-05-24 08:54:03.926443958 +0200 -+++ openssh-9.0p1-patched/sshkey.h 2023-05-24 08:57:22.930642788 +0200 -@@ -340,6 +340,10 @@ - #endif - #endif - -+#ifdef ENABLE_PKCS11 -+int pkcs11_get_ecdsa_idx(void); -+#endif -+ - #if !defined(WITH_OPENSSL) - # undef RSA - # undef DSA -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11.c openssh-9.0p1-patched/ssh-pkcs11.c ---- openssh-9.0p1/ssh-pkcs11.c 2023-05-24 08:54:03.888443542 +0200 -+++ openssh-9.0p1-patched/ssh-pkcs11.c 2023-05-24 09:48:13.101168512 +0200 -@@ -776,8 +776,24 @@ - - return (0); - } -+ -+int -+is_ecdsa_pkcs11(EC_KEY *ecdsa) -+{ -+ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL) -+ return 1; -+ return 0; -+} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -+int -+is_rsa_pkcs11(RSA *rsa) -+{ -+ if (RSA_get_ex_data(rsa, rsa_idx) != NULL) -+ return 1; -+ return 0; -+} -+ - /* remove trailing spaces */ - static void - rmspace(u_char *buf, size_t len) -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11-client.c openssh-9.0p1-patched/ssh-pkcs11-client.c ---- openssh-9.0p1/ssh-pkcs11-client.c 2023-05-24 08:54:03.887443531 +0200 -+++ openssh-9.0p1-patched/ssh-pkcs11-client.c 2023-05-24 09:49:41.741134514 +0200 -@@ -225,8 +225,36 @@ - static RSA_METHOD *helper_rsa; - #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - static EC_KEY_METHOD *helper_ecdsa; -+ -+int -+is_ecdsa_pkcs11(EC_KEY *ecdsa) -+{ -+ const EC_KEY_METHOD *meth; -+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen, -+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL; -+ -+ meth = EC_KEY_get_method(ecdsa); -+ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig); -+ if (sign_sig == ecdsa_do_sign) -+ return 1; -+ return 0; -+} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -+int -+is_rsa_pkcs11(RSA *rsa) -+{ -+ const RSA_METHOD *meth; -+ int (*priv_enc)(int flen, const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding) = NULL; -+ -+ meth = RSA_get_method(rsa); -+ priv_enc = RSA_meth_get_priv_enc(meth); -+ if (priv_enc == rsa_encrypt) -+ return 1; -+ return 0; -+} -+ - /* redirect private key crypto operations to the ssh-pkcs11-helper */ - static void - wrap_key(struct sshkey *k) -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-pkcs11.h openssh-9.0p1-patched/ssh-pkcs11.h ---- openssh-9.0p1/ssh-pkcs11.h 2023-05-24 08:54:03.888443542 +0200 -+++ openssh-9.0p1-patched/ssh-pkcs11.h 2023-05-24 09:50:03.981376886 +0200 -@@ -39,6 +39,11 @@ - u_int32_t *); - #endif - -+#ifdef HAVE_EC_KEY_METHOD_NEW -+int is_ecdsa_pkcs11(EC_KEY *ecdsa); -+#endif -+int is_rsa_pkcs11(RSA *rsa); -+ - #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) - #undef ENABLE_PKCS11 - #endif -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/ssh-rsa.c openssh-9.0p1-patched/ssh-rsa.c ---- openssh-9.0p1/ssh-rsa.c 2023-05-24 08:54:03.927443969 +0200 -+++ openssh-9.0p1-patched/ssh-rsa.c 2023-05-24 09:51:50.358536178 +0200 -@@ -174,8 +174,18 @@ - if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - -- if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) -- return ret; -+#ifdef ENABLE_PKCS11 -+ if (is_rsa_pkcs11(key->rsa)) { -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) -+ return SSH_ERR_ALLOC_FAIL; -+ } else { -+#endif -+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) -+ return ret; -+#ifdef ENABLE_PKCS11 -+ } -+#endif - ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, - datalen); - EVP_PKEY_free(pkey); diff --git a/openssh-9.0p1-man-hostkeyalgos.patch b/openssh-9.0p1-man-hostkeyalgos.patch deleted file mode 100644 index 2b16c2b..0000000 --- a/openssh-9.0p1-man-hostkeyalgos.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh_config.5 openssh-8.7p1-patched/ssh_config.5 ---- openssh-8.7p1/ssh_config.5 2023-05-29 13:41:19.731835097 +0200 -+++ openssh-8.7p1-patched/ssh_config.5 2023-05-29 13:40:58.806604144 +0200 -@@ -989,6 +989,12 @@ - .Pp - The list of available signature algorithms may also be obtained using - .Qq ssh -Q HostKeyAlgorithms . -+.Pp -+.Xr crypto_policies 7 does not handle the list of algorithms as doing so -+would break the order given by the -+.Pa known_hosts -+file. Therefore the list is filtered by -+.Cm PubkeyAcceptedAlgorithms. - .It Cm HostKeyAlias - Specifies an alias that should be used instead of the - real host name when looking up or saving the host key diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch new file mode 100644 index 0000000..28d281c --- /dev/null +++ b/openssh-9.3p1-merged-openssl-evp.patch @@ -0,0 +1,1220 @@ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest.h openssh-9.3p1-patched/digest.h +--- openssh-9.3p1/digest.h 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/digest.h 2023-06-06 15:52:25.602551466 +0200 +@@ -32,6 +32,12 @@ + struct sshbuf; + struct ssh_digest_ctx; + ++#ifdef WITH_OPENSSL ++#include ++/* 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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest-openssl.c openssh-9.3p1-patched/digest-openssl.c +--- openssh-9.3p1/digest-openssl.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/digest-openssl.c 2023-06-06 15:52:25.601551454 +0200 +@@ -64,6 +64,22 @@ + { -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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-dss.c openssh-9.3p1-patched/ssh-dss.c +--- openssh-9.3p1/ssh-dss.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-dss.c 2023-06-06 15:52:25.624551743 +0200 +@@ -32,6 +32,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -261,11 +263,15 @@ + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, 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) +@@ -276,17 +282,23 @@ + 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 ((ret = ssh_create_evp_dss(key, &pkey)) != 0) ++ return ret; ++ 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); +@@ -319,7 +331,7 @@ + *lenp = len; + ret = 0; + out: +- explicit_bzero(digest, sizeof(digest)); ++ free(sigb); + DSA_SIG_free(sig); + sshbuf_free(b); + return ret; +@@ -331,20 +343,20 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) + { ++ EVP_PKEY *pkey = NULL; + DSA_SIG *dsig = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; +- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; +- size_t len, hlen = 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 || + sig == NULL || siglen == 0) + return SSH_ERR_INVALID_ARGUMENT; +- if (hlen == 0) +- return SSH_ERR_INTERNAL_ERROR; + + /* fetch signature */ + if ((b = sshbuf_from(sig, siglen)) == NULL) +@@ -386,25 +398,28 @@ + } + sig_r = sig_s = NULL; /* transferred */ + +- /* sha1 the data */ +- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, +- digest, sizeof(digest))) != 0) ++ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; +- +- switch (DSA_do_verify(digest, hlen, dsig, 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(dsig, &psig)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + ++ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) ++ goto out; ++ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, ++ sigb, slen); ++ EVP_PKEY_free(pkey); ++ + out: +- explicit_bzero(digest, sizeof(digest)); ++ free(sigb); + DSA_SIG_free(dsig); + BN_clear_free(sig_r); + BN_clear_free(sig_s); +@@ -415,6 +430,65 @@ + return ret; + } + ++int ++ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; ++ int ret = 0; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ DSA_get0_pqg(k->dsa, &p, &q, &g); ++ DSA_get0_key(k->dsa, &pub, &priv); ++ ++ if (p != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (q != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (g != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (pub != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ pub) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (priv != 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); ++ return ret; ++} ++ + static const struct sshkey_impl_funcs sshkey_dss_funcs = { + /* .size = */ ssh_dss_size, + /* .alloc = */ ssh_dss_alloc, +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-ecdsa.c openssh-9.3p1-patched/ssh-ecdsa.c +--- openssh-9.3p1/ssh-ecdsa.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-ecdsa.c 2023-06-06 15:52:25.626551768 +0200 +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + + #include + +@@ -126,19 +128,29 @@ + static int + ssh_ecdsa_generate(struct sshkey *k, int bits) + { +- EC_KEY *private; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + + if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) + return SSH_ERR_KEY_LENGTH; +- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) + return SSH_ERR_ALLOC_FAIL; +- if (EC_KEY_generate_key(private) != 1) { +- EC_KEY_free(private); ++ ++ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0 ++ || EVP_PKEY_keygen(ctx, &res) <= 0) { ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + return SSH_ERR_LIBCRYPTO_ERROR; + } +- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); +- k->ecdsa = private; +- return 0; ++ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ ++ k->ecdsa = EVP_PKEY_get1_EC_KEY(res); ++ if (k->ecdsa) ++ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE); ++ ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); ++ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR; + } + + static int +@@ -228,11 +240,13 @@ + const u_char *data, size_t dlen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) + { ++ EVP_PKEY *pkey = NULL; + ECDSA_SIG *esig = 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, hlen; ++ int len; + struct sshbuf *b = NULL, *bb = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + +@@ -245,18 +259,33 @@ + 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 || +- (hlen = 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, dlen, +- digest, sizeof(digest))) != 0) ++ ++#ifdef ENABLE_PKCS11 ++ if (is_ecdsa_pkcs11(key->ecdsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 ++ } ++#endif ++ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, ++ dlen); ++ EVP_PKEY_free(pkey); ++ if (ret < 0) { + goto out; ++ } + +- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { ++ psig = sigb; ++ if (d2i_ECDSA_SIG(&esig, &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; +@@ -280,7 +309,7 @@ + *lenp = len; + ret = 0; + out: +- explicit_bzero(digest, sizeof(digest)); ++ free(sigb); + sshbuf_free(b); + sshbuf_free(bb); + ECDSA_SIG_free(esig); +@@ -293,22 +322,21 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) + { ++ EVP_PKEY *pkey = NULL; + ECDSA_SIG *esig = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; +- int hash_alg; +- u_char digest[SSH_DIGEST_MAX_LENGTH]; +- size_t hlen; ++ 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 || + sig == NULL || siglen == 0) + return SSH_ERR_INVALID_ARGUMENT; + +- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || +- (hlen = 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 */ +@@ -344,28 +372,33 @@ + } + 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(esig, NULL)) == 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, +- digest, sizeof(digest))) != 0) +- goto out; +- +- switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) { +- case 1: +- ret = 0; +- break; +- case 0: +- ret = SSH_ERR_SIGNATURE_INVALID; ++ if ((sigb = malloc(len)) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; + goto out; +- default: ++ } ++ psig = sigb; ++ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + ++ if (sshbuf_len(sigbuf) != 0) { ++ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; ++ goto out; ++ } ++ ++ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) ++ goto out; ++ ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len); ++ EVP_PKEY_free(pkey); ++ + out: +- explicit_bzero(digest, sizeof(digest)); ++ free(sigb); + sshbuf_free(sigbuf); + sshbuf_free(b); + ECDSA_SIG_free(esig); +@@ -375,6 +408,79 @@ + return ret; + } + ++int ++ssh_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; ++} ++ + /* NB. not static; used by ECDSA-SK */ + const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { + /* .size = */ ssh_ecdsa_size, +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.c openssh-9.3p1-patched/sshkey.c +--- openssh-9.3p1/sshkey.c 2023-06-06 15:53:36.608444190 +0200 ++++ openssh-9.3p1-patched/sshkey.c 2023-06-06 15:52:25.625551756 +0200 +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + #endif + + #include "crypto_api.h" +@@ -575,6 +577,86 @@ + } + + #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; ++ size_t len; ++ ++ if (sigp == NULL || lenp == NULL) { ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ ++ slen = EVP_PKEY_get_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_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestSignUpdate(ctx, data, datalen) != 1 || ++ EVP_DigestSignFinal(ctx, sig, &len) != 1) { ++ 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_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto done; ++ } ++ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen); ++ 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) +@@ -3763,3 +3845,27 @@ + return 0; + } + #endif /* WITH_XMSS */ ++ ++#ifdef WITH_OPENSSL ++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; ++} ++#endif /* WITH_OPENSSL */ +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.h openssh-9.3p1-patched/sshkey.h +--- openssh-9.3p1/sshkey.h 2023-06-06 15:53:36.608444190 +0200 ++++ openssh-9.3p1-patched/sshkey.h 2023-06-06 15:52:25.626551768 +0200 +@@ -31,6 +31,9 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include ++#include ++#include + # ifdef OPENSSL_HAS_ECC + # include + # include +@@ -268,6 +271,10 @@ + 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 **); +@@ -324,6 +331,13 @@ + + void sshkey_sig_details_free(struct sshkey_sig_details *); + ++#ifdef WITH_OPENSSL ++EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *); ++int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **); ++#endif /* WITH_OPENSSL */ ++ + #ifdef SSHKEY_INTERNAL + int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); + void sshkey_sk_cleanup(struct sshkey *k); +@@ -338,6 +352,10 @@ + #endif + #endif + ++#ifdef ENABLE_PKCS11 ++int pkcs11_get_ecdsa_idx(void); ++#endif ++ + #if !defined(WITH_OPENSSL) + # undef RSA + # undef DSA +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.c openssh-9.3p1-patched/ssh-pkcs11.c +--- openssh-9.3p1/ssh-pkcs11.c 2023-06-06 15:53:36.592443989 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11.c 2023-06-06 15:52:25.626551768 +0200 +@@ -777,8 +777,24 @@ + + return (0); + } ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ if (RSA_get_ex_data(rsa, rsa_idx) != NULL) ++ return 1; ++ return 0; ++} ++ + /* remove trailing spaces */ + static void + rmspace(u_char *buf, size_t len) +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c +--- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200 +@@ -225,8 +225,36 @@ + static RSA_METHOD *helper_rsa; + #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + static EC_KEY_METHOD *helper_ecdsa; ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ const EC_KEY_METHOD *meth; ++ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen, ++ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL; ++ ++ meth = EC_KEY_get_method(ecdsa); ++ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig); ++ if (sign_sig == ecdsa_do_sign) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ const RSA_METHOD *meth; ++ int (*priv_enc)(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) = NULL; ++ ++ meth = RSA_get_method(rsa); ++ priv_enc = RSA_meth_get_priv_enc(meth); ++ if (priv_enc == rsa_encrypt) ++ return 1; ++ return 0; ++} ++ + /* redirect private key crypto operations to the ssh-pkcs11-helper */ + static void + wrap_key(struct sshkey *k) +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.h openssh-9.3p1-patched/ssh-pkcs11.h +--- openssh-9.3p1/ssh-pkcs11.h 2023-06-06 15:53:36.592443989 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11.h 2023-06-06 15:52:25.626551768 +0200 +@@ -39,6 +39,11 @@ + u_int32_t *); + #endif + ++#ifdef HAVE_EC_KEY_METHOD_NEW ++int is_ecdsa_pkcs11(EC_KEY *ecdsa); ++#endif ++int is_rsa_pkcs11(RSA *rsa); ++ + #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) + #undef ENABLE_PKCS11 + #endif +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-rsa.c openssh-9.3p1-patched/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-rsa.c 2023-06-06 15:52:25.627551781 +0200 +@@ -23,6 +23,8 @@ + + #include + #include ++#include ++#include + + #include + #include +@@ -36,7 +38,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 u_int + ssh_rsa_size(const struct sshkey *key) +@@ -131,27 +133,50 @@ + static int + ssh_rsa_generate(struct sshkey *k, int bits) + { +- RSA *private = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + BIGNUM *f4 = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + + if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || + bits > SSHBUF_MAX_BIGNUM * 8) + return SSH_ERR_KEY_LENGTH; +- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL ++ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if (!BN_set_word(f4, RSA_F4) || +- !RSA_generate_key_ex(private, bits, f4, NULL)) { ++ ++ if (EVP_PKEY_keygen_init(ctx) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { ++ ret = SSH_ERR_KEY_LENGTH; ++ goto out; ++ } ++ ++ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0) ++ goto out; ++ ++ if (EVP_PKEY_keygen(ctx, &res) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ ++ k->rsa = EVP_PKEY_get1_RSA(res); ++ if (k->rsa) { ++ ret = 0; ++ } else { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- k->rsa = private; +- private = NULL; +- ret = 0; + out: +- RSA_free(private); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + BN_free(f4); + return ret; + } +@@ -317,21 +342,6 @@ + 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) + { +@@ -393,11 +403,10 @@ + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) + { +- const BIGNUM *rsa_n; +- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; +- size_t slen = 0; +- u_int hlen, 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) +@@ -409,33 +418,33 @@ + hash_alg = SSH_DIGEST_SHA1; + else + hash_alg = rsa_hash_id_from_keyname(alg); ++ + 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 ((hlen = 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; +- goto out; ++#ifdef ENABLE_PKCS11 ++ if (is_rsa_pkcs11(key->rsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 + } +- +- if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { +- ret = SSH_ERR_LIBCRYPTO_ERROR; ++#endif ++ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, ++ datalen); ++ EVP_PKEY_free(pkey); ++ if (ret < 0) { + goto out; + } ++ + if (len < slen) { + size_t diff = slen - len; + memmove(sig + diff, sig, len); +@@ -444,6 +453,7 @@ + ret = SSH_ERR_INTERNAL_ERROR; + goto out; + } ++ + /* encode signature */ + if ((b = sshbuf_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; +@@ -464,7 +474,6 @@ + *lenp = len; + ret = 0; + out: +- explicit_bzero(digest, sizeof(digest)); + freezero(sig, slen); + sshbuf_free(b); + return ret; +@@ -476,10 +485,10 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) + { +- 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, hlen; ++ size_t len = 0, diff, modlen; + struct sshbuf *b = NULL; + u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; + +@@ -487,8 +496,7 @@ + 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) +@@ -540,16 +548,13 @@ + explicit_bzero(sigblob, diff); + len = modlen; + } +- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { +- ret = SSH_ERR_INTERNAL_ERROR; +- goto out; +- } +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, +- digest, sizeof(digest))) != 0) ++ ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) + goto out; + +- ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, +- key->rsa); ++ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); ++ EVP_PKEY_free(pkey); ++ + out: + freezero(sigblob, len); + free(sigtype); +@@ -558,125 +563,110 @@ + 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; ++ 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; +- } +- rsasize = RSA_size(rsa); ++ rsasize = EVP_PKEY_get_size(pkey); + 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; + } + ++int ++ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ int ret = 0; ++ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL; ++ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ RSA_get0_key(k->rsa, &n, &e, &d); ++ RSA_get0_factors(k->rsa, &p, &q); ++ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); ++ ++ if (n != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (e != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (d != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++ /* setting this to param_build makes the creation process fail */ ++ if (p != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) { ++ debug2_f("failed to add 'p' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (q != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) { ++ debug2_f("failed to add 'q' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (dmp1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) { ++ debug2_f("failed to add 'dmp1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (dmq1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) { ++ debug2_f("failed to add 'dmq1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (iqmp != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) { ++ debug2_f("failed to add 'iqmp' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ return ret; ++} ++ + static const struct sshkey_impl_funcs sshkey_rsa_funcs = { + /* .size = */ ssh_rsa_size, + /* .alloc = */ ssh_rsa_alloc, diff --git a/openssh-9.3p1-upstream-cve-2023-38408.patch b/openssh-9.3p1-upstream-cve-2023-38408.patch new file mode 100644 index 0000000..e9ac2ae --- /dev/null +++ b/openssh-9.3p1-upstream-cve-2023-38408.patch @@ -0,0 +1,130 @@ +diff --git a/ssh-agent.c b/ssh-agent.c +index 618bb198..8ea831f4 100644 +diff -up openssh-9.3p1/ssh-agent.c.cve openssh-9.3p1/ssh-agent.c +--- openssh-9.3p1/ssh-agent.c.cve 2023-07-21 15:38:13.237276580 +0200 ++++ openssh-9.3p1/ssh-agent.c 2023-07-21 15:41:30.269943569 +0200 +@@ -169,6 +169,12 @@ char socket_dir[PATH_MAX]; + /* Pattern-list of allowed PKCS#11/Security key paths */ + static char *allowed_providers; + ++/* ++ * Allows PKCS11 providers or SK keys that use non-internal providers to ++ * be added over a remote connection (identified by session-bind@openssh.com). ++ */ ++static int remote_add_provider; ++ + /* locking */ + #define LOCK_SIZE 32 + #define LOCK_SALT_SIZE 16 +@@ -1228,6 +1234,12 @@ process_add_identity(SocketEntry *e) + if (strcasecmp(sk_provider, "internal") == 0) { + debug_f("internal provider"); + } else { ++ if (e->nsession_ids != 0 && !remote_add_provider) { ++ verbose("failed add of SK provider \"%.100s\": " ++ "remote addition of providers is disabled", ++ sk_provider); ++ goto out; ++ } + if (realpath(sk_provider, canonical_provider) == NULL) { + verbose("failed provider \"%.100s\": " + "realpath: %s", sk_provider, +@@ -1368,7 +1380,7 @@ no_identities(SocketEntry *e) + + #ifdef ENABLE_PKCS11 + static char * +-sanitize_pkcs11_provider(const char *provider) ++sanitize_pkcs11_provider(SocketEntry *e, const char *provider) + { + struct pkcs11_uri *uri = NULL; + char *sane_uri, *module_path = NULL; /* default path */ +@@ -1399,6 +1411,11 @@ sanitize_pkcs11_provider(const char *pro + module_path = strdup(provider); /* simple path */ + + if (module_path != NULL) { /* do not validate default NULL path in URI */ ++ if (e->nsession_ids != 0 && !remote_add_provider) { ++ verbose("failed PKCS#11 add of \"%.100s\": remote addition of " ++ "providers is disabled", provider); ++ return NULL; ++ } + if (realpath(module_path, canonical_provider) == NULL) { + verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", + module_path, strerror(errno)); +@@ -1455,7 +1472,7 @@ process_add_smartcard_key(SocketEntry *e + goto send; + } + +- sane_uri = sanitize_pkcs11_provider(provider); ++ sane_uri = sanitize_pkcs11_provider(e, provider); + if (sane_uri == NULL) + goto send; + +@@ -1516,7 +1533,7 @@ process_remove_smartcard_key(SocketEntry + } + free(pin); + +- sane_uri = sanitize_pkcs11_provider(provider); ++ sane_uri = sanitize_pkcs11_provider(e, provider); + if (sane_uri == NULL) + goto send; + +@@ -2108,7 +2125,9 @@ main(int ac, char **av) + break; + case 'O': + if (strcmp(optarg, "no-restrict-websafe") == 0) +- restrict_websafe = 0; ++ restrict_websafe = 0; ++ else if (strcmp(optarg, "allow-remote-pkcs11") == 0) ++ remote_add_provider = 1; + else + fatal("Unknown -O option"); + break; +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index 6be647ec..ebddf6c3 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -1537,10 +1537,8 @@ pkcs11_register_provider(char *provider_id, char *pin, + error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } +- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { +- error("dlsym(C_GetFunctionList) failed: %s", dlerror()); +- goto fail; +- } ++ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) ++ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); + + p->module->handle = handle; + /* setup the pkcs11 callbacks */ +--- a/ssh-agent.1 2023-03-15 22:28:19.000000000 +0100 ++++ b/ssh-agent.1 2023-07-19 21:39:17.981406432 +0200 +@@ -107,9 +107,27 @@ + .It Fl O Ar option + Specify an option when starting + .Nm . +-Currently only one option is supported: ++Currently two options are supported: ++.Cm allow-remote-pkcs11 ++and + .Cm no-restrict-websafe . +-This instructs ++.Pp ++The ++.Cm allow-remote-pkcs11 ++option allows clients of a forwarded ++.Nm ++to load PKCS#11 or FIDO provider libraries. ++By default only local clients may perform this operation. ++Note that signalling that a ++.Nm ++client remote is performed by ++.Xr ssh 1 , ++and use of other tools to forward access to the agent socket may circumvent ++this restriction. ++.Pp ++The ++.Cm no-restrict-websafe , ++instructs + .Nm + to permit signatures using FIDO keys that might be web authentication + requests. From c0e4707d7b711c6463c6f38aa8839d0833ca7c5e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 11 Aug 2023 21:46:58 +0200 Subject: [PATCH 119/146] Based on openssh-9.3p1-8.fc39 --- gsi-openssh.spec | 17 ++++++++----- gsisshd.socket | 11 -------- openssh-6.6p1-kuserok.patch | 4 +-- openssh-7.7p1-redhat.patch | 20 +++++++++------ openssh-9.3p1-openssl-compat.patch | 40 ++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 27 deletions(-) delete mode 100644 gsisshd.socket create mode 100644 openssh-9.3p1-openssl-compat.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 0bd49a9..696734d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -39,7 +39,6 @@ Source2: gsisshd.pam Source3: gpgkey-736060BA.gpg Source7: gsisshd.sysconfig Source9: gsisshd@.service -Source10: gsisshd.socket Source11: gsisshd.service Source12: gsisshd-keygen@.service Source13: gsisshd-keygen @@ -177,6 +176,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.3p1-upstream-cve-2023-38408.patch +# upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237 +Patch1016: openssh-9.3p1-openssl-compat.patch # Fix issue with read-only ssh buffer during gssapi key exchange (#1938224) # https://github.com/openssh-gsskex/openssh-gsskex/pull/19 @@ -339,6 +340,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 1013 -p1 -b .evp-fips-ecdh %patch -P 1014 -p1 -b .nosha1hostproof %patch -P 1015 -p1 -b .cve-2023-38408 +%patch -P 1016 -p1 -b .ossl-version %patch -P 100 -p1 -b .coverity @@ -440,10 +442,10 @@ 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 -d -m755 $RPM_BUILD_ROOT/%{_unitdir} install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd@.service -install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.socket 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 @@ -483,10 +485,10 @@ if [ $1 -gt 1 ]; then # script for Fedora 38 to remove group ownership for host keys. %{_libexecdir}/gsissh/ssh-host-keys-migration.sh fi -%systemd_post gsisshd.service gsisshd.socket +%systemd_post gsisshd.service %preun server -%systemd_preun gsisshd.service gsisshd.socket +%systemd_preun gsisshd.service %postun server %systemd_postun_with_restart gsisshd.service @@ -525,18 +527,21 @@ 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 %attr(0644,root,root) %{_unitdir}/gsisshd.service %attr(0644,root,root) %{_unitdir}/gsisshd@.service -%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(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Fri Aug 11 2023 Mattias Ellert - 9.3p1-3 +- Based on openssh-9.3p1-8.fc39 + * Sun Jul 23 2023 Mattias Ellert - 9.3p1-2 - Based on openssh-9.3p1-5.fc39.1 diff --git a/gsisshd.socket b/gsisshd.socket deleted file mode 100644 index 28e40d1..0000000 --- a/gsisshd.socket +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=gsissh Server Socket -Documentation=man:gsisshd(8) man:gsisshd_config(5) -Conflicts=gsisshd.service - -[Socket] -ListenStream=22 -Accept=yes - -[Install] -WantedBy=sockets.target diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index f3231f9..eaf4453 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -155,8 +155,8 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c * 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 (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists) -+ && k5login_exists) { ++ 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); diff --git a/openssh-7.7p1-redhat.patch b/openssh-7.7p1-redhat.patch index 85ebc82..1d77f90 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-7.7p1-redhat.patch @@ -80,14 +80,7 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config 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,22 @@ -+# 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 -+ +@@ -0,0 +1,15 @@ +SyslogFacility AUTHPRIV + +ChallengeResponseAuthentication no @@ -103,3 +96,14 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +# as it is more configurable and versatile than the built-in version. +PrintMotd no + +diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +--- openssh/sshd_config_redhat_cp.redhat 2020-02-13 18:14:02.268006439 +0100 ++++ openssh/sshd_config_redhat_cp 2020-02-13 18:19:20.765035947 +0100 +@@ -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 ++ diff --git a/openssh-9.3p1-openssl-compat.patch b/openssh-9.3p1-openssl-compat.patch new file mode 100644 index 0000000..cf512ef --- /dev/null +++ b/openssh-9.3p1-openssl-compat.patch @@ -0,0 +1,40 @@ +--- openssh-9.3p1/openbsd-compat/openssl-compat.c 2023-03-15 22:28:19.000000000 +0100 ++++ /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat/openssl-compat.c 2023-05-25 14:19:42.870841944 +0200 +@@ -33,10 +33,10 @@ + + /* + * OpenSSL version numbers: MNNFFPPS: major minor fix patch status +- * We match major, minor, fix and status (not patch) for <1.0.0. +- * After that, we acceptable compatible fix versions (so we +- * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed +- * within a patch series. ++ * Versions >=3 require only major versions to match. ++ * For versions <3, we accept compatible fix versions (so we allow 1.0.1 ++ * to work with 1.0.0). Going backwards is only allowed within a patch series. ++ * See https://www.openssl.org/policies/releasestrat.html + */ + + int +@@ -48,15 +48,17 @@ + if (headerver == libver) + return 1; + +- /* for versions < 1.0.0, major,minor,fix,status must match */ +- if (headerver < 0x1000000f) { +- mask = 0xfffff00fL; /* major,minor,fix,status */ ++ /* ++ * For versions >= 3.0, only the major and status must match. ++ */ ++ if (headerver >= 0x3000000f) { ++ mask = 0xf000000fL; /* major,status */ + return (headerver & mask) == (libver & mask); + } + + /* +- * For versions >= 1.0.0, major,minor,status must match and library +- * fix version must be equal to or newer than the header. ++ * For versions >= 1.0.0, but <3, major,minor,status must match and ++ * library fix version must be equal to or newer than the header. + */ + mask = 0xfff0000fL; /* major,minor,status */ + hfix = (headerver & 0x000ff000) >> 12; From 5b20a7546c07743d80cc27bdbc1c113f31d8bc0a Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 17 Oct 2023 03:14:46 +0200 Subject: [PATCH 120/146] Based on openssh-9.3p1-9.fc39 --- gsi-openssh.spec | 12 +++++++++--- gsisshd.socket | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 gsisshd.socket diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 696734d..4c3bc2f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -39,6 +39,7 @@ Source2: gsisshd.pam Source3: gpgkey-736060BA.gpg Source7: gsisshd.sysconfig Source9: gsisshd@.service +Source10: gsisshd.socket Source11: gsisshd.service Source12: gsisshd-keygen@.service Source13: gsisshd-keygen @@ -446,6 +447,7 @@ install -m644 sshd_config_redhat_cp $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/sshd_co install -m644 sshd_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/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 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 @@ -485,10 +487,10 @@ if [ $1 -gt 1 ]; then # script for Fedora 38 to remove group ownership for host keys. %{_libexecdir}/gsissh/ssh-host-keys-migration.sh fi -%systemd_post gsisshd.service +%systemd_post gsisshd.service gsisshd.socket %preun server -%systemd_preun gsisshd.service +%systemd_preun gsisshd.service gsisshd.socket %postun server %systemd_postun_with_restart gsisshd.service @@ -533,12 +535,16 @@ fi %attr(0640,root,root) %config(noreplace) /etc/sysconfig/gsisshd %attr(0644,root,root) %{_unitdir}/gsisshd.service %attr(0644,root,root) %{_unitdir}/gsisshd@.service +%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(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Tue Oct 17 2023 Mattias Ellert - 9.3p1-4 +- Based on openssh-9.3p1-9.fc39 + * Fri Aug 11 2023 Mattias Ellert - 9.3p1-3 - Based on openssh-9.3p1-8.fc39 diff --git a/gsisshd.socket b/gsisshd.socket new file mode 100644 index 0000000..28e40d1 --- /dev/null +++ b/gsisshd.socket @@ -0,0 +1,11 @@ +[Unit] +Description=gsissh Server Socket +Documentation=man:gsisshd(8) man:gsisshd_config(5) +Conflicts=gsisshd.service + +[Socket] +ListenStream=22 +Accept=yes + +[Install] +WantedBy=sockets.target From 78f4185f33440a45a1d05042c222ac0288f4a309 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 17 Oct 2023 07:01:51 +0200 Subject: [PATCH 121/146] Based on openssh-9.3p1-12.fc40 --- gsi-openssh.spec | 7 +- openssh-8.0p1-pkcs11-uri.patch | 178 +++++++++++++++++-------- openssh-9.3p1-merged-openssl-evp.patch | 22 ++- 3 files changed, 145 insertions(+), 62 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 4c3bc2f..a73bd43 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 4 +%global openssh_rel 5 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -191,7 +191,7 @@ Patch98: openssh-9.3p1-gsissh.patch # Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ Patch99: openssh-9.3p1-hpn-15.2-modified.patch -License: BSD +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 BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel @@ -542,6 +542,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Tue Oct 17 2023 Mattias Ellert - 9.3p1-5 +- Based on openssh-9.3p1-12.fc40 + * Tue Oct 17 2023 Mattias Ellert - 9.3p1-4 - Based on openssh-9.3p1-9.fc39 diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index affdd72..551351c 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -68,7 +68,7 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in --- openssh-8.7p1/Makefile.in.pkcs11-uri 2021-08-30 13:07:43.571699324 +0200 +++ openssh-8.7p1/Makefile.in 2021-08-30 13:07:43.663700096 +0200 -@@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -105,7 +105,7 @@ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ @@ -103,7 +103,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT +@@ -685,6 +690,16 @@ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -534,7 +534,7 @@ diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regre diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c --- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 +++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 -@@ -0,0 +1,337 @@ +@@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -563,7 +563,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +#include "sshbuf.h" +#include "ssh-pkcs11-uri.h" + -+#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) + +/* prototypes are not public -- specify them here internally for tests */ +struct sshbuf *percent_encode(const char *, size_t, char *); @@ -596,6 +596,10 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); + else /* both should be null */ + ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); ++ if (b->serial != NULL) ++ ASSERT_STRING_EQ(a->serial, b->serial); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->serial, b->serial); +} + +void @@ -630,7 +634,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + +struct pkcs11_uri * +compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, -+ char *manuf, char *module_path, char *object, char *pin) ++ char *manuf, char *serial, char *module_path, char *object, char *pin) +{ + struct pkcs11_uri *uri = pkcs11_uri_init(); + if (id_len > 0) { @@ -641,6 +645,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + uri->token = token; + uri->lib_manuf = lib_manuf; + uri->manuf = manuf; ++ uri->serial = serial; + uri->object = object; + uri->pin = pin; + return uri; @@ -651,47 +656,49 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_parse("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:token=SSH%20Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:serial=IamSerial", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "IamSerial", NULL, NULL, NULL)); + check_parse("pkcs11:object=SIGN%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); + /* query arguments */ + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse("pkcs11:?pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, "123456")); + + /* combinations */ + /* ID SHOULD be percent encoded */ + check_parse("pkcs11:token=SSH%20Key;id=0", -+ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse( + "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, "CAC", ++ compose_uri(NULL, 0, NULL, NULL, "CAC", NULL, + "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse( + "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, + "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key", NULL)); + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so&pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); + + /* empty path component matches everything */ + check_parse("pkcs11:", EMPTY_URI); + + /* empty string is a valid to match against (and different from NULL) */ + check_parse("pkcs11:token=", -+ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL, NULL)); + /* Percent character needs to be percent-encoded */ + check_parse("pkcs11:token=%25", -+ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL, NULL)); +} + +static void @@ -703,7 +710,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); + /* Space MUST be percent encoded -- XXX not enforced yet */ + check_parse("pkcs11:token=SSH Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* MUST NOT contain duplicate attributes of the same name */ + check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); + /* MUST NOT contain duplicate attributes of the same name */ @@ -734,29 +741,31 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_gen("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* library-manufacturer is not implmented now */ + /*check_gen("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL));*/ ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL));*/ + check_gen("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:serial=IamSerial", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "IamSerial", NULL, NULL, NULL)); + check_gen("pkcs11:object=RSA%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "RSA Key", NULL)); + /* query arguments */ + check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + + /* combinations */ + check_gen("pkcs11:id=%02;token=SSH%20Keys", -+ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, "Encryption Key", NULL)); + + /* empty path component matches everything */ + check_gen("pkcs11:", EMPTY_URI); @@ -1545,7 +1554,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1587,6 +1596,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + uri.module_path = k11->provider->module->module_path; + uri.lib_manuf = k11->provider->module->info.manufacturerID; + uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; + + p = pkcs11_uri_get(&uri); + /* do not cleanup -- we do not allocate here, only reference */ @@ -1620,9 +1630,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -262,12 +403,12 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -260,14 +403,14 @@ pkcs11_login_slot(struct pkcs11_provider + if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + verbose("Deferring PIN entry to reader keypad."); else { - snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", +- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", ++ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", si->token.label); - if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { + if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { @@ -1754,6 +1767,27 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); +@@ -622,7 +779,8 @@ + } + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + +-/* remove trailing spaces */ ++/* remove trailing spaces. Note, that this does NOT guarantee the buffer ++ * will be null terminated if there are no trailing spaces! */ + static void + rmspace(u_char *buf, size_t len) + { +@@ -630,8 +788,8 @@ + + if (!len) + return; +- for (i = len - 1; i > 0; i--) +- if (i == len - 1 || buf[i] == ' ') ++ for (i = len - 1; i > 0; i--) ++ if (buf[i] == ' ') + buf[i] = '\0'; + else + break; @@ -650,8 +806,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -2157,7 +2191,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ +@@ -1517,164 +1702,305 @@ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2243,20 +2277,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); -+ goto fail; -+ } -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); goto fail; } - rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); - rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", +- debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" +- " libraryDescription <%s> libraryVersion %d.%d", - provider_id, - p->info.manufacturerID, - p->info.cryptokiVersion.major, @@ -2265,6 +2291,16 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c - p->info.libraryVersion.major, - p->info.libraryVersion.minor); - if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); ++ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" ++ " libraryDescription <%.32s> libraryVersion %d.%d", + provider_module, + m->info.manufacturerID, + m->info.cryptokiVersion.major, @@ -2321,6 +2357,9 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c rmspace(token->manufacturerID, sizeof(token->manufacturerID)); rmspace(token->model, sizeof(token->model)); rmspace(token->serialNumber, sizeof(token->serialNumber)); +- debug("provider %s slot %lu: label <%s> manufacturerID <%s> " +- "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, + } + m->module_path = provider_module; + provider_module = NULL; @@ -2389,22 +2428,28 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + continue; + } + if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2_f("ignoring token not matching label (%s) " ++ strncmp(token->label, uri->token, 32) != 0) { ++ debug2_f("ignoring token not matching label (%.32s) " + "specified by PKCS#11 URI in slot %lu", + token->label, (unsigned long)i); + continue; + } + if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { + debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "manufacturerID (%.32s) specified by PKCS#11 URI in " + "slot %lu", token->manufacturerID, (unsigned long)i); + continue; + } - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, ++ if (uri->serial != NULL && ++ strncmp(token->serialNumber, uri->serial, 16) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "serialNumber (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->serialNumber, (unsigned long)i); ++ continue; ++ } ++ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " ++ "model <%.16s> serial <%.16s> flags 0x%lx", + provider_uri, (unsigned long)i, token->label, token->manufacturerID, token->model, token->serialNumber, token->flags); @@ -2443,7 +2488,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } + if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%s) ", ++ debug3_f("No keys found. Retrying without label (%.32s) ", + uri->object); + /* Try once more without the label filter */ + char *label = uri->object; @@ -2531,7 +2576,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1683,7 +2002,37 @@ pkcs11_add_provider(char *provider_id, c +@@ -1684,7 +2012,37 @@ pkcs11_add_provider(char *provider_id, c pkcs11_provider_unref(p); } if (nkeys == 0) @@ -2591,7 +2636,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c --- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,419 @@ +@@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -2634,13 +2679,14 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +#define PKCS11_URI_OBJECT "object" +#define PKCS11_URI_LIB_MANUF "library-manufacturer" +#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_SERIAL "serial" +#define PKCS11_URI_MODULE_PATH "module-path" +#define PKCS11_URI_PIN_VALUE "pin-value" + +/* Keyword tokens. */ +typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pPinValue, pBadOption ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pSerial, ++ pModulePath, pPinValue, pBadOption +} pkcs11uriOpCodes; + +/* Textual representation of the tokens. */ @@ -2653,6 +2699,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + { PKCS11_URI_OBJECT, pObject }, + { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, + { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_SERIAL, pSerial }, + { PKCS11_URI_MODULE_PATH, pModulePath }, + { PKCS11_URI_PIN_VALUE, pPinValue }, + { NULL, pBadOption } @@ -2811,6 +2858,16 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + goto err; + } + ++ /* Write serial */ ++ if (uri->serial) { ++ struct sshbuf *serial = percent_encode(uri->serial, ++ strlen(uri->serial), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_SERIAL, serial); ++ if (path == NULL) ++ goto err; ++ } ++ + /* Write module_path */ + if (uri->module_path) { + struct sshbuf *module = percent_encode(uri->module_path, @@ -2853,6 +2910,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + free(pkcs11->object); + free(pkcs11->lib_manuf); + free(pkcs11->manuf); ++ free(pkcs11->serial); + if (pkcs11->pin) + freezero(pkcs11->pin, strlen(pkcs11->pin)); + free(pkcs11); @@ -2948,6 +3006,11 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + charptr = &pkcs11->manuf; + goto parse_string; + ++ case pSerial: ++ /* CK_TOKEN_INFO -> serialNumber */ ++ charptr = &pkcs11->serial; ++ goto parse_string; ++ + case pLibraryManufacturer: + /* CK_INFO -> manufacturerID */ + charptr = &pkcs11->lib_manuf; @@ -3014,7 +3077,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h --- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 +++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,42 @@ +@@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3046,6 +3109,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + char *object; + char *lib_manuf; + char *manuf; ++ char *serial; + /* query */ + char *module_path; + char *pin; /* Only parsed, but not printed */ diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch index 28d281c..95d86c3 100644 --- a/openssh-9.3p1-merged-openssl-evp.patch +++ b/openssh-9.3p1-merged-openssl-evp.patch @@ -252,6 +252,16 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include +@@ -44,6 +44,9 @@ + #include "digest.h" + #define SSHKEY_INTERNAL + #include "sshkey.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif + + #include "openbsd-compat/openssl-compat.h" + @@ -126,19 +128,29 @@ static int ssh_ecdsa_generate(struct sshkey *k, int bits) @@ -710,9 +720,9 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 0; +} + - /* remove trailing spaces */ + /* remove trailing spaces. Note, that this does NOT guarantee the buffer + * will be null terminated if there are no trailing spaces! */ static void - rmspace(u_char *buf, size_t len) diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c --- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200 +++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200 @@ -780,7 +790,13 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include #include -@@ -36,7 +38,7 @@ +@@ -36,10 +36,13 @@ + #include "sshkey.h" + #include "digest.h" + #include "log.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif #include "openbsd-compat/openssl-compat.h" From 76c16c6e5ab1f892f8ff94b99ccd957d22fb7a6e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 24 Oct 2023 21:25:00 +0200 Subject: [PATCH 122/146] Based on openssh-9.3p1-13.fc40 Drop patch openssh-8.0p1-sshbuf-readonly.patch (now included in openssh-8.0p1-gssapi-keyex.patch) --- gsi-openssh.spec | 11 +- openssh-6.7p1-coverity.patch | 15 --- openssh-8.0p1-gssapi-keyex.patch | 70 ++++++++----- openssh-8.0p1-sshbuf-readonly.patch | 152 ---------------------------- 4 files changed, 51 insertions(+), 197 deletions(-) delete mode 100644 openssh-8.0p1-sshbuf-readonly.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a73bd43..c9f44fd 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 5 +%global openssh_rel 6 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -180,9 +180,6 @@ Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch # upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237 Patch1016: openssh-9.3p1-openssl-compat.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 Patch98: openssh-9.3p1-gsissh.patch @@ -345,7 +342,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 100 -p1 -b .coverity -%patch -P 97 -p1 -b .sshbuf-ro %patch -P 98 -p1 -b .gsi %patch -P 99 -p1 -b .hpn @@ -542,6 +538,11 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Tue Oct 24 2023 Mattias Ellert - 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 - 9.3p1-5 - Based on openssh-9.3p1-12.fc40 diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 494f4c6..1dca99c 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -42,21 +42,6 @@ diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (sshbuf_len(buf) != 0 && -diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c ---- openssh-8.5p1/kexgssc.c.coverity 2021-03-24 12:03:33.711967665 +0100 -+++ openssh-8.5p1/kexgssc.c 2021-03-24 12:03:33.783968166 +0100 -@@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) - default: - fatal_f("Unexpected KEX type %d", kex->kex_type); - } -- if (r != 0) -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&ctxt); - return r; -+ } - - token_ptr = GSS_C_NO_BUFFER; - diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c --- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index d1d914d..0bc509f 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1488,7 +1488,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,600 @@ +@@ -0,0 +1,612 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1589,8 +1589,10 @@ index 00000000..f6e1405e + default: + fatal_f("Unexpected KEX type %d", kex->kex_type); + } -+ if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&ctxt); + return r; ++ } + + token_ptr = GSS_C_NO_BUFFER; + @@ -1653,11 +1655,16 @@ index 00000000..f6e1405e + 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); + @@ -1944,11 +1951,16 @@ index 00000000..f6e1405e + 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); + @@ -2094,7 +2106,7 @@ new file mode 100644 index 00000000..60bc02de --- /dev/null +++ b/kexgsss.c -@@ -0,0 +1,474 @@ +@@ -0,0 +1,482 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2161,7 +2173,7 @@ index 00000000..60bc02de + */ + + 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; @@ -2201,7 +2213,7 @@ index 00000000..60bc02de + 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 || @@ -2232,6 +2244,31 @@ index 00000000..60bc02de + 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, @@ -2253,7 +2290,7 @@ index 00000000..60bc02de + 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) { @@ -2282,23 +2319,6 @@ index 00000000..60bc02de + 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"); + diff --git a/openssh-8.0p1-sshbuf-readonly.patch b/openssh-8.0p1-sshbuf-readonly.patch deleted file mode 100644 index edc8bec..0000000 --- a/openssh-8.0p1-sshbuf-readonly.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 063e1a255b53abde1147522f9aceccfd2a7ceb9b Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -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"); - From 4a1597c64d7dd1837f9c7ddfb598bac5c5aaf169 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sat, 20 Jan 2024 21:35:29 +0000 Subject: [PATCH 123/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index c9f44fd..03c2dd7 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -538,6 +538,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Sat Jan 20 2024 Fedora Release Engineering - 9.3p1-6.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Oct 24 2023 Mattias Ellert - 9.3p1-6 - Based on openssh-9.3p1-13.fc40 - Drop patch openssh-8.0p1-sshbuf-readonly.patch (now included in From 3e94785b283e6aaa92116943b140356d4ff06cbd Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sat, 20 Jan 2024 22:54:58 +0100 Subject: [PATCH 124/146] Based on openssh-9.3p1-13.fc40.1 --- gsi-openssh.spec | 7 +++++-- openssh-8.0p1-gssapi-keyex.patch | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 03c2dd7..5e4ca1f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,12 +24,12 @@ %global libedit 1 %global openssh_ver 9.3p1 -%global openssh_rel 6 +%global openssh_rel 7 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -538,6 +538,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Sat Jan 20 2024 Mattias Ellert - 9.3p1-7 +- Based on openssh-9.3p1-13.fc40.1 + * Sat Jan 20 2024 Fedora Release Engineering - 9.3p1-6.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 0bc509f..89bcd0d 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1655,7 +1655,7 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ char *tmp = NULL; ++ u_char *tmp = NULL; + size_t tmp_len = 0; + + debug("Received KEXGSS_HOSTKEY"); @@ -1951,7 +1951,7 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ char *tmp = NULL; ++ u_char *tmp = NULL; + size_t tmp_len = 0; + + debug("Received KEXGSS_HOSTKEY"); From ed01b0a2c59b718ecb4ebcc266968fe5b898ecc8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jan 2024 21:07:00 +0000 Subject: [PATCH 125/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 5e4ca1f..f9bc019 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -538,6 +538,9 @@ fi %attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh %changelog +* Wed Jan 24 2024 Fedora Release Engineering - 9.3p1-7.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Sat Jan 20 2024 Mattias Ellert - 9.3p1-7 - Based on openssh-9.3p1-13.fc40.1 From bd1630068088d4ad544ca714f306122b79c62835 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 10 Jul 2024 15:35:42 +0200 Subject: [PATCH 126/146] Based on openssh-9.6p1-1.fc40.4 --- gsi-openssh.spec | 43 +- gsissh-host-keys-migration.service | 15 + gsisshd.service | 3 + gsisshd@.service | 3 + openssh-6.6.1p1-selinux-contexts.patch | 22 +- openssh-6.7p1-coverity.patch | 87 - openssh-7.2p2-x11.patch | 24 +- openssh-7.8p1-role-mls.patch | 10 +- openssh-8.0p1-gssapi-keyex.patch | 56 +- openssh-8.0p1-pkcs11-uri.patch | 469 +- openssh-8.7p1-minrsabits.patch | 22 +- openssh-8.7p1-recursive-scp.patch | 167 +- openssh-9.3p1-hpn-15.2-modified.patch | 2595 --- openssh-9.3p1-merged-openssl-evp.patch | 55 +- openssh-9.3p1-openssl-compat.patch | 40 - openssh-9.3p1-upstream-cve-2023-38408.patch | 130 - openssh-9.6p1-cve-2024-6387.patch | 35 + ...gsissh.patch => openssh-9.6p1-gsissh.patch | 370 +- openssh-9.6p1-hpn-18.3.1.patch | 14718 ++++++++++++++++ sources | 4 +- 20 files changed, 15422 insertions(+), 3446 deletions(-) create mode 100644 gsissh-host-keys-migration.service delete mode 100644 openssh-9.3p1-hpn-15.2-modified.patch delete mode 100644 openssh-9.3p1-openssl-compat.patch delete mode 100644 openssh-9.3p1-upstream-cve-2023-38408.patch create mode 100644 openssh-9.6p1-cve-2024-6387.patch rename openssh-9.3p1-gsissh.patch => openssh-9.6p1-gsissh.patch (88%) create mode 100644 openssh-9.6p1-hpn-18.3.1.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f9bc019..49140db 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,13 +23,13 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 9.3p1 -%global openssh_rel 7 +%global openssh_ver 9.6p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -46,6 +46,7 @@ Source13: gsisshd-keygen 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=2581 @@ -176,17 +177,18 @@ Patch1006: openssh-8.7p1-negotiate-supported-algs.patch Patch1012: openssh-9.0p1-evp-fips-dh.patch Patch1013: openssh-9.0p1-evp-fips-ecdh.patch Patch1014: openssh-8.7p1-nohostsha1proof.patch -Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch -# upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237 -Patch1016: openssh-9.3p1-openssl-compat.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=2294879 +# Merged in OpenSSH 9.8 +Patch1016: openssh-9.6p1-cve-2024-6387.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-9.3p1-gsissh.patch +Patch98: openssh-9.6p1-gsissh.patch # This is the HPN patch -# Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v2%208.5p1/ -Patch99: openssh-9.3p1-hpn-15.2-modified.patch +# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.3.1 +Patch99: openssh-9.6p1-hpn-18.3.1.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 @@ -337,8 +339,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 .cve-2023-38408 -%patch -P 1016 -p1 -b .ossl-version +%patch -P 1016 -p1 -b .cve-2024-6387 %patch -P 100 -p1 -b .coverity @@ -450,9 +451,13 @@ 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 script for Fedora 38 change to remove group ownership for standard host keys +# 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 rm $RPM_BUILD_ROOT%{_bindir}/ssh-add rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent @@ -472,6 +477,9 @@ for f in $RPM_BUILD_ROOT%{_bindir}/* \ mv $f `dirname $f`/gsi`basename $f` done +# Add symlink with alternative name for scp binary +ln -s gsiscp $RPM_BUILD_ROOT%{_bindir}/hpnscp + perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %pre server @@ -479,9 +487,12 @@ perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %post server if [ $1 -gt 1 ]; then - # In the case of an upgrade run the migration + # 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 @@ -506,6 +517,7 @@ fi %attr(0755,root,root) %{_bindir}/gsissh %attr(0644,root,root) %{_mandir}/man1/gsissh.1* %attr(0755,root,root) %{_bindir}/gsiscp +%{_bindir}/hpnscp %attr(0644,root,root) %{_mandir}/man1/gsiscp.1* %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config %dir %attr(0755,root,root) %{_sysconfdir}/gsissh/ssh_config.d/ @@ -535,9 +547,14 @@ fi %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 %changelog +* Sat Jul 06 2024 Mattias Ellert - 9.6p1-1 +- Based on openssh-9.6p1-1.fc40.4 + * Wed Jan 24 2024 Fedora Release Engineering - 9.3p1-7.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/gsissh-host-keys-migration.service b/gsissh-host-keys-migration.service new file mode 100644 index 0000000..db91516 --- /dev/null +++ b/gsissh-host-keys-migration.service @@ -0,0 +1,15 @@ +[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 diff --git a/gsisshd.service b/gsisshd.service index afe165d..6272ced 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -3,6 +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 diff --git a/gsisshd@.service b/gsisshd@.service index 3f5ecbd..8a3fff2 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -3,6 +3,9 @@ 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] EnvironmentFile=-/etc/sysconfig/gsisshd diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index fa9d591..eab724a 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -93,19 +93,17 @@ index 8f32464..18a2ca4 100644 #endif diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 22ea8ef..1fc963d 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) - strlcpy(newctx + len, newname, newlen - len); - if ((cx = index(cx + 1, ':'))) - strlcat(newctx, cx, newlen); -- debug3("%s: setting context from '%s' to '%s'", __func__, -+ debug_f("setting context from '%s' to '%s'", - oldctx, newctx); +--- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/openbsd-compat/port-linux.c (date 1703108053912) +@@ -207,7 +207,7 @@ + xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx, + newname, cx2 == NULL ? "" : cx2); + +- debug3_f("setting context from '%s' to '%s'", oldctx, newctx); ++ debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) - do_log2(log_level, "%s: setcon %s from %s failed with %s", - __func__, newctx, oldctx, strerror(errno)); + do_log2_f(log_level, "setcon %s from %s failed with %s", + newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 1dca99c..01a061b 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -17,17 +17,6 @@ diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c return oerrno; } /* make sure the KRB5CCNAME is set for non-standard location */ -diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c ---- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 -@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * - return r; - } - /* success */ -+ sshbuf_free(b); - return 0; - } - diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c --- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 +++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 @@ -45,14 +34,6 @@ diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c --- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 -@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st - sshkey_free(key); - sshbuf_free(copy); - sshbuf_free(sect); -+ /* coverity[leaked_storage : FALSE] */ - return r; - } - @@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); @@ -149,23 +130,6 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c return (0); error: -diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100 -@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, - if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || - (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error_f("cannot allocate fds for pty"); -- if (tmp1 > 0) -+ if (tmp1 >= 0) - close(tmp1); -- if (tmp2 > 0) -- close(tmp2); -+ /*DEAD CODE if (tmp2 >= 0) -+ close(tmp2);*/ - return 0; - } - close(tmp1); diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c --- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100 @@ -219,23 +183,6 @@ diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c goto out; } free(arg2); -diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200 -+++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200 -@@ -186,11 +186,11 @@ killchild(int signo) - { - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid, NULL, 0); -+ (void) waitpid(do_cmd_pid, NULL, 0); - } - if (do_cmd_pid2 > 1) { - kill(do_cmd_pid2, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid2, NULL, 0); -+ (void) waitpid(do_cmd_pid2, NULL, 0); - } - - if (signo) diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 @@ -263,18 +210,6 @@ diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c 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 @@ -286,28 +221,6 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c return NULL; } /* validate also provider from URI */ -@@ -1220,8 +1220,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - platform_disable_tracing(0); /* strict=no */ - -diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c ---- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100 -+++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1746,6 +1746,7 @@ control_persist_detach(void) - close(muxserver_sock); - muxserver_sock = -1; - options.control_master = SSHCTL_MASTER_NO; -+ /* coverity[leaked_handle: FALSE]*/ - muxclient(options.control_path); - /* muxclient() doesn't return on success. */ - fatal("Failed to connect to new control master"); diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c --- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100 +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index 0a19ecb..b27d7c4 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -1,21 +1,23 @@ -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_ +diff --git a/channels.c b/channels.c +--- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/channels.c (date 1703026069921) +@@ -5075,11 +5075,13 @@ } - + static int -connect_local_xsocket_path(const char *pathname) +connect_local_xsocket_path(const char *pathname, int len) { int sock; struct sockaddr_un addr; - -+ if (len <= 0) -+ return -1; + ++ if (len <= 0) ++ return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) + if (sock == -1) { error("socket: %.100s", strerror(errno)); +@@ -5087,11 +5089,12 @@ + } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); @@ -29,8 +31,8 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } - -@@ -4012,8 +4015,18 @@ static int + +@@ -5099,8 +5102,18 @@ connect_local_xsocket(u_int dnr) { char buf[1024]; diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 4dc460a..347766d 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -23,7 +23,7 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32 +@@ -314,8 +314,15 @@ input_userauth_request(int type, u_int32 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -34,12 +34,12 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c + if (use_privsep) { mm_inform_authserv(service, style); +#ifdef WITH_SELINUX -+ mm_inform_authrole(role); ++ mm_inform_authrole(role); +#endif -+ } ++ } userauth_banner(ssh); - if (auth2_setup_methods_lists(authctxt) != 0) - ssh_packet_disconnect(ssh, + if ((r = kex_server_update_ext_info(ssh)) != 0) + fatal_fr(r, "kex_server_update_ext_info failed"); diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c --- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 89bcd0d..3e5ccec 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -144,8 +144,8 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ - + /* $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. @@ -1268,7 +1268,7 @@ index ce85f043..574c7609 100644 +#endif + /* prototype */ - static int kex_choose_conf(struct ssh *); + static int kex_choose_conf(struct ssh *, uint32_t seq); static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -3400,7 +3400,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -579,6 +585,8 @@ flag), +@@ -624,6 +624,8 @@ (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3408,7 +3408,7 @@ index 60de6087..db5c65bc 100644 +(GSSAPI key exchange algorithms), .Ar key (key types), - .Ar key-cert + .Ar key-ca-sign diff --git a/ssh.c b/ssh.c index 15aee569..110cf9c1 100644 --- a/ssh.c @@ -3444,7 +3444,7 @@ index 5e8ef548..1ff999b6 100644 +# GSSAPIKeyExchange no +# GSSAPITrustDNS no # BatchMode no - # CheckHostIP yes + # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..3f490697 100644 @@ -4028,3 +4028,47 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; +diff --git a/packet.h b/packet.h +--- a/packet.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.h (date 1703172586447) +@@ -124,6 +124,7 @@ + int ssh_packet_send2(struct ssh *); + + 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); +diff --git a/packet.c b/packet.c +--- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.c (date 1703172586447) +@@ -1425,6 +1416,29 @@ + return type; + } + ++/* ++ * Waits until a packet has been received, verifies that its type matches ++ * that given, and gives a fatal error and exits if there is a mismatch. ++ */ ++ ++int ++ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) ++{ ++ int r; ++ u_char type; ++ ++ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) ++ return r; ++ if (type != expected_type) { ++ if ((r = sshpkt_disconnect(ssh, ++ "Protocol error: expected packet type %d, got %d", ++ expected_type, type)) != 0) ++ return r; ++ return SSH_ERR_PROTOCOL_ERROR; ++ } ++ return 0; ++} ++ + static int + ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + { diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 551351c..1e7940d 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,7 +1,7 @@ -diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac ---- openssh-8.7p1/configure.ac.pkcs11-uri 2021-08-30 13:07:43.646699953 +0200 -+++ openssh-8.7p1/configure.ac 2021-08-30 13:07:43.662700088 +0200 -@@ -1985,12 +1985,14 @@ AC_LINK_IFELSE( +diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac +--- openssh-9.6p1/configure.ac.pkcs11-uri 2024-01-12 14:25:25.228942213 +0100 ++++ openssh-9.6p1/configure.ac 2024-01-12 14:25:25.233942336 +0100 +@@ -2066,12 +2066,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +16,7 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac fi ] ) -@@ -2019,6 +2021,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2095,6 +2097,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +57,7 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5624,6 +5660,7 @@ echo " BSD Auth support +@@ -5708,6 +5744,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,10 +65,10 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac echo " U2F/FIDO support: $enable_sk" echo "" -diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in ---- openssh-8.7p1/Makefile.in.pkcs11-uri 2021-08-30 13:07:43.571699324 +0200 -+++ openssh-8.7p1/Makefile.in 2021-08-30 13:07:43.663700096 +0200 -@@ -105,7 +105,7 @@ +diff -up openssh-9.6p1/Makefile.in.pkcs11-uri openssh-9.6p1/Makefile.in +--- openssh-9.6p1/Makefile.in.pkcs11-uri 2024-01-12 14:25:25.204941622 +0100 ++++ openssh-9.6p1/Makefile.in 2024-01-12 14:25:25.233942336 +0100 +@@ -105,7 +105,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ @@ -77,7 +77,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ -@@ -302,6 +302,8 @@ clean: regressclean +@@ -299,6 +299,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -86,15 +86,15 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -339,6 +341,8 @@ distclean: regressclean +@@ -336,6 +338,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so @@ -513,6 +517,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig @@ -103,7 +103,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -685,6 +690,16 @@ +@@ -685,6 +690,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -120,7 +120,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ -@@ -711,7 +726,8 @@ regress-unit-binaries: regress-prep $(RE +@@ -720,7 +735,8 @@ regress-unit-binaries: regress-prep $(RE regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/sshsig/test_sshsig$(EXEEXT) \ @@ -128,24 +128,12 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - tests: file-tests t-exec interop-tests unit + tests: file-tests t-exec interop-tests extra-tests unit echo all tests passed -diff -up openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/agent-pkcs11.sh ---- openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/agent-pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 -@@ -113,7 +113,7 @@ else - done - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefile ---- openssh-8.7p1/regress/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/Makefile 2021-08-30 13:07:43.663700096 +0200 -@@ -122,7 +122,8 @@ CLEANFILES= *.core actual agent-key.* au +diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefile +--- openssh-9.6p1/regress/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -134,7 +134,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -155,7 +143,7 @@ diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefil rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -252,8 +253,9 @@ unit: +@@ -273,8 +274,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -167,9 +155,9 @@ diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefil -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11.sh ---- openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri 2021-08-30 13:07:43.663700096 +0200 -+++ openssh-8.7p1/regress/pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 +diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11.sh +--- openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/pkcs11.sh 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -520,20 +508,20 @@ diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regress/unittests/Makefile ---- openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/unittests/Makefile 2021-08-30 13:07:43.663700096 +0200 -@@ -2,6 +2,6 @@ +diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regress/unittests/Makefile +--- openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/unittests/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -1,6 +1,6 @@ + # $OpenBSD: Makefile,v 1.13 2023/09/24 08:14:13 claudio Exp $ - REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion -SUBDIR+=authopt misc sshsig +SUBDIR+=authopt misc sshsig pkcs11 .include -diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c ---- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 -+++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 +diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1/regress/unittests/pkcs11/tests.c +--- openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/unittests/pkcs11/tests.c 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat @@ -881,10 +869,10 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + test_parse_invalid(); + test_generate_valid(); +} -diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c ---- openssh-8.7p1/ssh-add.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-add.c 2021-08-30 13:07:43.664700104 +0200 -@@ -68,6 +68,7 @@ +diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c +--- openssh-9.6p1/ssh-add.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-add.c 2024-01-12 14:25:25.233942336 +0100 +@@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" #include "hostfile.h" @@ -892,12 +880,16 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c /* argv0 */ extern char *__progname; -@@ -229,6 +230,34 @@ delete_all(int agent_fd, int qflag) +@@ -240,6 +241,38 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int, struct dest_constraint **, size_t, char *); ++static int ++update_card(int agent_fd, int add, const char *id, int qflag, ++ int key_only, int cert_only, ++ struct dest_constraint **dest_constraints, size_t ndest_constraints, ++ struct sshkey **certs, size_t ncerts, char *pin); + +int +update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag, @@ -919,32 +911,35 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c + } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, -+ dest_constraints, ndest_constraints, pin); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, 1, 0, ++ dest_constraints, ndest_constraints, NULL, 0, pin); +} +#endif + static int - add_file(int agent_fd, const char *filename, int key_only, int qflag, - const char *skprovider, struct dest_constraint **dest_constraints, -@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen - - static int + add_file(int agent_fd, const char *filename, int key_only, int cert_only, + int qflag, const char *skprovider, +@@ -460,15 +489,14 @@ static int update_card(int agent_fd, int add, const char *id, int qflag, -- struct dest_constraint **dest_constraints, size_t ndest_constraints) -+ struct dest_constraint **dest_constraints, size_t ndest_constraints, char *pin) + int key_only, int cert_only, + struct dest_constraint **dest_constraints, size_t ndest_constraints, +- struct sshkey **certs, size_t ncerts) ++ struct sshkey **certs, size_t ncerts, char *pin) { - char *pin = NULL; int r, ret = -1; + if (key_only) + ncerts = 0; + - if (add) { + if (add && pin == NULL) { if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -630,6 +656,14 @@ static int - const char *skprovider, struct dest_constraint **dest_constraints, - size_t ndest_constraints) +@@ -656,6 +684,14 @@ do_file(int agent_fd, int deleting, int + char *file, int qflag, const char *skprovider, + struct dest_constraint **dest_constraints, size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && @@ -955,21 +950,21 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c + } +#endif if (deleting) { - if (delete_file(agent_fd, file, key_only, qflag) == -1) - return -1; -@@ -813,7 +846,7 @@ main(int argc, char **argv) - } - if (pkcs11provider != NULL) { + if (delete_file(agent_fd, file, key_only, + cert_only, qflag) == -1) +@@ -999,7 +1035,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag, dest_constraints, ndest_constraints) == -1) -+ qflag, dest_constraints, ndest_constraints, NULL) == -1) + qflag, key_only, cert_only, + dest_constraints, ndest_constraints, +- certs, ncerts) == -1) ++ certs, ncerts, NULL) == -1) ret = 1; goto done; } -diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c ---- openssh-8.7p1/ssh-agent.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-agent.c 2021-08-30 13:07:43.664700104 +0200 -@@ -847,10 +847,72 @@ no_identities(SocketEntry *e) +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 } #ifdef ENABLE_PKCS11 @@ -1043,25 +1038,23 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e - error_f("failed to parse constraints"); +@@ -1581,25 +1643,18 @@ process_add_smartcard_key(SocketEntry *e + "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); -- goto send; -- } -- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { -- verbose("refusing PKCS#11 add of \"%.100s\": " -- "provider not allowed", canonical_provider); -+ + sane_uri = sanitize_pkcs11_provider(provider); + if (sane_uri == NULL) goto send; - } +- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { +- verbose("refusing PKCS#11 add of \"%.100s\": " +- "provider not allowed", canonical_provider); +- goto send; +- } - debug_f("add %.100s", canonical_provider); -+ if (lifetime && !death) death = monotime() + lifetime; @@ -1069,31 +1062,38 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c + debug_f("add %.100s", sane_uri); + count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { - k = keys[i]; - if (lookup_identity(k) == NULL) { - id = xcalloc(1, sizeof(Identity)); - id->key = k; - keys[i] = NULL; /* transferred */ -- id->provider = xstrdup(canonical_provider); -+ id->provider = xstrdup(sane_uri); - if (*comments[i] != '\0') { - id->comment = comments[i]; - comments[i] = NULL; /* transferred */ - } else { -- id->comment = xstrdup(canonical_provider); -+ id->comment = xstrdup(sane_uri); - } - id->death = death; - id->confirm = confirm; -@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e + if (comments[i] == NULL || comments[i][0] == '\0') { + free(comments[i]); +- comments[i] = xstrdup(canonical_provider); ++ comments[i] = xstrdup(sane_uri); + } + for (j = 0; j < ncerts; j++) { + if (!sshkey_is_cert(certs[j])) +@@ -1609,13 +1664,13 @@ process_add_smartcard_key(SocketEntry *e + if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) + continue; + add_p11_identity(k, xstrdup(comments[i]), +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + success = 1; + } + if (!cert_only && lookup_identity(keys[i]) == NULL) { + add_p11_identity(keys[i], comments[i], +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + keys[i] = NULL; /* transferred */ + comments[i] = NULL; /* transferred */ +@@ -1628,6 +1683,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); + free(sane_uri); free(keys); free(comments); - free_dest_constraints(dest_constraints, ndest_constraints); -@@ -918,7 +976,7 @@ send: + free_dest_constraints(dest_constraints, ndest_constraints); +@@ -1640,7 +1696,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1102,7 +1102,7 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c int r, success = 0; Identity *id, *nxt; -@@ -930,30 +988,29 @@ process_remove_smartcard_key(SocketEntry +@@ -1652,30 +1708,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1139,10 +1139,10 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 ---- openssh-8.7p1/ssh_config.5.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 -+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:07:43.664700104 +0200 -@@ -1111,6 +1111,21 @@ may also be used in conjunction with +diff -up openssh-9.6p1/ssh_config.5.pkcs11-uri openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1/ssh_config.5.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh_config.5 2024-01-12 14:25:25.234942360 +0100 +@@ -1216,6 +1216,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -1164,10 +1164,10 @@ diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. -diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c ---- openssh-8.7p1/ssh.c.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 -+++ openssh-8.7p1/ssh.c 2021-08-30 13:07:43.666700121 +0200 -@@ -826,6 +826,14 @@ main(int ac, char **av) +diff -up openssh-9.6p1/ssh.c.pkcs11-uri openssh-9.6p1/ssh.c +--- openssh-9.6p1/ssh.c.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh.c 2024-01-12 14:25:25.234942360 +0100 +@@ -882,6 +882,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -1182,7 +1182,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1681,6 +1689,7 @@ main(int ac, char **av) +@@ -1784,6 +1792,7 @@ main(int ac, char **av) #ifdef ENABLE_PKCS11 (void)pkcs11_del_provider(options.pkcs11_provider); #endif @@ -1190,7 +1190,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c skip_connect: exit_status = ssh_session2(ssh, cinfo); -@@ -2197,6 +2206,45 @@ ssh_session2(struct ssh *ssh, const stru +@@ -2307,6 +2316,45 @@ ssh_session2(struct ssh *ssh, const stru options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -1236,7 +1236,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2211,11 +2259,6 @@ load_public_identity_files(const struct +@@ -2321,11 +2369,6 @@ load_public_identity_files(const struct char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -1248,7 +1248,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2228,33 +2271,46 @@ load_public_identity_files(const struct +@@ -2338,33 +2381,46 @@ load_public_identity_files(const struct sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -1314,10 +1314,10 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); check_load(sshkey_load_public(filename, &public, NULL), -diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c ---- openssh-8.7p1/ssh-keygen.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-keygen.c 2021-08-30 13:07:43.666700121 +0200 -@@ -860,8 +860,11 @@ do_download(struct passwd *pw) +diff -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c +--- openssh-9.6p1/ssh-keygen.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-keygen.c 2024-01-12 14:25:25.234942360 +0100 +@@ -862,8 +862,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1331,19 +1331,19 @@ diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c } free(comments[i]); sshkey_free(keys[i]); -diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-client.c ---- openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11-client.c 2021-08-30 13:07:43.666700121 +0200 -@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi - u_int nkeys, i; +diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-client.c +--- openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11-client.c 2024-01-12 14:25:25.234942360 +0100 +@@ -592,6 +592,8 @@ pkcs11_add_provider(char *name, char *pi struct sshbuf *msg; + struct helper *helper; + debug_f("called, name = %s", name); + - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); - -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi + if ((helper = helper_by_provider(name)) == NULL && + (helper = pkcs11_start_helper(name)) == NULL) + return -1; +@@ -612,6 +614,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1351,9 +1351,9 @@ diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-c for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c ---- openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11.c 2021-08-30 13:12:27.709084157 +0200 +diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c +--- openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.c 2024-01-12 14:28:09.170975480 +0100 @@ -55,8 +55,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1537,10 +1537,10 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c struct pkcs11_provider *p; + int rv = -1; + char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug3_f("called with provider %s", provider_uri); - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3_f("called with provider %s", provider_uri); -+ + if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); pkcs11_provider_finalize(p); @@ -1611,7 +1611,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c /* release a wrapped object */ static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +348,7 @@ pkcs11_k11_free(void *parent, void *ptr, +@@ -208,6 +349,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1619,7 +1619,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(k11); } -@@ -222,8 +363,8 @@ pkcs11_find(struct pkcs11_provider *p, C +@@ -222,8 +364,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1630,7 +1630,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -260,14 +403,14 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -260,14 +402,14 @@ pkcs11_login_slot(struct pkcs11_provider if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) verbose("Deferring PIN entry to reader keypad."); else { @@ -1648,7 +1648,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); -@@ -297,13 +438,14 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -297,13 +439,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1665,7 +1665,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } -@@ -319,13 +461,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs +@@ -319,13 +462,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -1683,7 +1683,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c attr.type = type; attr.pValue = &flag; -@@ -356,13 +499,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C +@@ -356,13 +500,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -1701,7 +1701,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +583,8 @@ pkcs11_rsa_private_encrypt(int flen, con +@@ -439,8 +584,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -1712,7 +1712,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +628,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -484,7 +629,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1721,7 +1721,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -502,6 +646,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * +@@ -502,6 +647,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1734,7 +1734,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -532,8 +682,8 @@ ecdsa_do_sign(const unsigned char *dgst, +@@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -1745,7 +1745,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -598,7 +748,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -598,7 +749,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1754,10 +1754,10 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -614,6 +764,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider +@@ -615,6 +766,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } + } + if (label_attrib->ulValueLen > 0 ) { + k11->label = xmalloc(label_attrib->ulValueLen+1); + memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); @@ -1767,28 +1767,17 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -622,7 +779,8 @@ +@@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider } #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ -/* remove trailing spaces */ +/* remove trailing spaces. Note, that this does NOT guarantee the buffer + * will be null terminated if there are no trailing spaces! */ - static void + static char * rmspace(u_char *buf, size_t len) { -@@ -630,8 +788,8 @@ - - if (!len) - return; -- for (i = len - 1; i > 0; i--) -- if (i == len - 1 || buf[i] == ' ') -+ for (i = len - 1; i > 0; i--) -+ if (buf[i] == ' ') - buf[i] = '\0'; - else - break; -@@ -650,8 +806,8 @@ pkcs11_open_session(struct pkcs11_provid +@@ -654,8 +812,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -1799,7 +1788,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -661,9 +817,9 @@ pkcs11_open_session(struct pkcs11_provid +@@ -665,9 +823,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -1811,7 +1800,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -699,7 +855,8 @@ static struct sshkey * +@@ -703,7 +861,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1821,7 +1810,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -713,14 +870,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -717,14 +876,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1842,7 +1831,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -731,19 +889,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -735,19 +895,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1866,7 +1855,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -755,8 +913,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -759,8 +919,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1877,7 +1866,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -767,13 +925,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -771,13 +931,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1894,7 +1883,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -790,7 +948,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -794,7 +954,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1903,7 +1892,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -806,7 +964,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -1912,7 +1901,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -823,7 +981,8 @@ static struct sshkey * +@@ -827,7 +987,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1922,7 +1911,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -834,14 +993,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -838,14 +999,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1943,7 +1932,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -852,19 +1012,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -856,19 +1018,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1967,7 +1956,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -876,8 +1036,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -880,8 +1042,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -1978,7 +1967,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -886,7 +1046,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -890,7 +1052,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ @@ -1987,7 +1976,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -901,7 +1061,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -1996,7 +1985,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(key_attr[i].pValue); RSA_free(rsa); -@@ -912,7 +1072,8 @@ static int +@@ -916,7 +1078,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -2006,7 +1995,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -936,14 +1097,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -940,14 +1103,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2027,7 +2016,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -955,18 +1117,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -959,18 +1123,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2050,7 +2039,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -980,8 +1143,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -984,8 +1149,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2061,7 +2050,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c error("d2i_x509 failed"); goto out; } -@@ -1001,7 +1164,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1005,7 +1170,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2070,7 +2059,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1031,7 +1194,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1035,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2079,7 +2068,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1051,7 +1214,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1055,7 +1220,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } out: @@ -2088,7 +2077,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1102,11 +1265,12 @@ note_key(struct pkcs11_provider *p, CK_U +@@ -1106,11 +1271,12 @@ note_key(struct pkcs11_provider *p, CK_U */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2103,7 +2092,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1123,10 +1287,23 @@ pkcs11_fetch_certs(struct pkcs11_provide +@@ -1127,10 +1293,23 @@ pkcs11_fetch_certs(struct pkcs11_provide key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2121,16 +2110,16 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1207,11 +1384,12 @@ fail: +@@ -1211,11 +1390,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2145,7 +2134,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1227,10 +1405,23 @@ pkcs11_fetch_keys(struct pkcs11_provider +@@ -1231,10 +1411,23 @@ pkcs11_fetch_keys(struct pkcs11_provider key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2163,16 +2152,16 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ + session = p->module->slotinfo[slotidx].session; + f = p->module->function_list; -+ + +- rv = f->C_FindObjectsInit(session, key_attr, 1); + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1499,16 +1690,10 @@ pkcs11_ecdsa_generate_private_key(struct +@@ -1503,16 +1696,10 @@ pkcs11_ecdsa_generate_private_key(struct } #endif /* WITH_PKCS11_KEYGEN */ @@ -2191,7 +2180,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1702,305 @@ +@@ -1521,162 +1708,309 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2199,28 +2188,35 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + struct pkcs11_module *m = NULL; - if (providerp == NULL) +- goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; + /* if no provider specified, fallback to p11-kit */ + if (uri->module_path == NULL) { +#ifdef PKCS11_DEFAULT_PROVIDER + provider_module = strdup(PKCS11_DEFAULT_PROVIDER); +#else + error_f("No module path provided"); - goto fail; -- *providerp = NULL; ++ goto fail; +#endif + } else { + provider_module = strdup(uri->module_path); + } - -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; + p = xcalloc(1, sizeof(*p)); + p->name = pkcs11_uri_get(uri); - if (pkcs11_provider_lookup(provider_id) != NULL) { - debug_f("provider already registered: %s", provider_id); ++ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { ++ error("provider %s is not a PKCS11 library", provider_module); + goto fail; + } +- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { +- error("provider %s is not a PKCS11 library", provider_id); - goto fail; + if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL + && m->valid) { @@ -2247,14 +2243,11 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + error("dlopen %s failed: %s", provider_module, dlerror()); goto fail; } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) + fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); - p = xcalloc(1, sizeof(*p)); - p->name = xstrdup(provider_id); - p->handle = handle; -+ + p->module->handle = handle; /* setup the pkcs11 callbacks */ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { @@ -2279,15 +2272,13 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + provider_module, rv); goto fail; } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -- debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" -- " libraryDescription <%s> libraryVersion %d.%d", +- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" +- " libraryDescription <%.*s> libraryVersion %d.%d", - provider_id, -- p->info.manufacturerID, +- RMSPACE(p->info.manufacturerID), - p->info.cryptokiVersion.major, - p->info.cryptokiVersion.minor, -- p->info.libraryDescription, +- RMSPACE(p->info.libraryDescription), - p->info.libraryVersion.major, - p->info.libraryVersion.minor); - if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { @@ -2331,12 +2322,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; } - p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); p->valid = 1; - nkeys = 0; - for (i = 0; i < p->nslots; i++) { - token = &p->slotinfo[i].token; - if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); + m->valid = 1; + for (i = 0; i < m->nslots; i++) { + token = &m->slotinfo[i].token; @@ -2353,23 +2344,25 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + token->flags = 0; continue; } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); -- debug("provider %s slot %lu: label <%s> manufacturerID <%s> " -- "model <%s> serial <%s> flags 0x%lx", + debug("provider %s slot %lu: label <%.*s> " + "manufacturerID <%.*s> model <%.*s> serial <%.*s> " + "flags 0x%lx", - provider_id, (unsigned long)i, ++ provider_module, (unsigned long)i, + RMSPACE(token->label), RMSPACE(token->manufacturerID), + RMSPACE(token->model), RMSPACE(token->serialNumber), + token->flags); + } + m->module_path = provider_module; + provider_module = NULL; + -+ /* insert unconditionally -- remove if there will be no keys later */ ++ /* now owned by caller */ ++ *providerp = p; ++ + TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); + p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; + ++ return 0; +fail: + if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize for provider %s failed: %lu", @@ -2385,7 +2378,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + } + if (handle) + dlclose(handle); -+ return ret; ++ return (ret); +} + +/* @@ -2451,12 +2444,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " + "model <%.16s> serial <%.16s> flags 0x%lx", + provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); ++ token->label, token->manufacturerID, token->model, ++ token->serialNumber, token->flags); /* - * open session, login with pin and retrieve public - * keys (if keyp is provided) -+ * open session if not yet openend, login with pin and ++ * open session if not yet opened, login with pin and + * retrieve public keys (if keyp is provided) */ - if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || @@ -2517,8 +2510,8 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c - free(p->slotlist); - free(p->slotinfo); - free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); } - if (handle) - dlclose(handle); @@ -2576,7 +2569,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1684,7 +2012,37 @@ pkcs11_add_provider(char *provider_id, c +@@ -1685,7 +2019,37 @@ pkcs11_add_provider(char *provider_id, c pkcs11_provider_unref(p); } if (nkeys == 0) @@ -2615,9 +2608,9 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c return (nkeys); } -diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h ---- openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11.h 2021-08-30 13:07:43.666700121 +0200 +diff -up openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11.h +--- openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.h 2024-01-12 14:25:25.235942385 +0100 @@ -22,10 +22,14 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 @@ -2633,9 +2626,9 @@ diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c ---- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 -+++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 +diff -up openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.c +--- openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.c 2024-01-12 14:25:25.235942385 +0100 @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3074,9 +3067,9 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +} + +#endif /* ENABLE_PKCS11 */ -diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h ---- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 -+++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 +diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.h +--- openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.h 2024-01-12 14:25:25.235942385 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index 2ed59a3..479b55d 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -1,23 +1,21 @@ diff --git a/readconf.c b/readconf.c -index 7f26c680..42be690b 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -320,6 +320,7 @@ static struct { +--- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/readconf.c (date 1703169891147) +@@ -326,6 +326,7 @@ { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, - { "requiredrsasize", oRequiredRSASize }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, - - { NULL, oBadOption } + { "obscurekeystroketiming", oObscureKeystrokeTiming }, + { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index 29df0463..423772b1 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -676,6 +680,7 @@ static struct { +--- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/servconf.c (date 1703169891148) +@@ -691,6 +691,7 @@ { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, - { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */ { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch index f0d9b0f..17c340e 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -1,28 +1,28 @@ -diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100 -+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100 -@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t - +diff --git a/scp.c b/scp.c +--- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/scp.c (date 1703111453316) +@@ -1372,7 +1372,7 @@ + if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, + 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 -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c ---- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 -@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons - + error("failed to upload directory %s to %s", src, targ); + errs = 1; + } +diff --git a/sftp-client.c b/sftp-client.c +--- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.c (date 1703169614263) +@@ -1003,7 +1003,7 @@ + /* Implements both the realpath and expand-path operations */ static char * --do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) -+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) +-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; -@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con +@@ -1049,11 +1049,43 @@ if ((r = sshbuf_get_u32(msg, &status)) != 0 || (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); @@ -33,7 +33,7 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c - return NULL; + if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) { + memset(&a, '\0', sizeof(a)); -+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) { ++ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) { + sshbuf_free(msg); + return NULL; + } @@ -71,111 +71,112 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con +@@ -1078,9 +1110,9 @@ } - + char * --do_realpath(struct sftp_conn *conn, const char *path) -+do_realpath(struct sftp_conn *conn, const char *path, int create_dir) +-sftp_realpath(struct sftp_conn *conn, const char *path) ++sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir) { -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, create_dir); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, create_dir); } - + int -@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c +@@ -1094,9 +1126,9 @@ { - if (!can_expand_path(conn)) { + if (!sftp_can_expand_path(conn)) { debug3_f("no server support, fallback to realpath"); -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, 0); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, 0); } -- return do_realpath_expand(conn, path, 1); -+ return do_realpath_expand(conn, path, 1, 0); +- return sftp_realpath_expand(conn, path, 1); ++ return sftp_realpath_expand(conn, path, 1, 0); } - + int -@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con +@@ -2016,7 +2048,7 @@ char *src_canon; int ret; - -- if ((src_canon = do_realpath(conn, src)) == NULL) { -+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) { - error("download \"%s\": path canonicalization failed", src); - return -1; - } -@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co + +- 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; + } +@@ -2365,12 +2397,12 @@ int - upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + 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 = do_realpath(conn, dst)) == NULL) { -+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { - error("upload \"%s\": path canonicalization failed", dst); - return -1; - } -@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st + +- 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; + } +@@ -2825,7 +2857,7 @@ char *from_path_canon; int ret; - -- if ((from_path_canon = do_realpath(from, from_path)) == NULL) { -+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { - error("crossload \"%s\": path canonicalization failed", - from_path); - return -1; -diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h ---- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 -@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons - int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); - + +- 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 +--- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.h (date 1703111691284) +@@ -111,7 +111,7 @@ + int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); + /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, const char *); -+char *do_realpath(struct sftp_conn *, const char *, int); - +-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 *do_expand_path(struct sftp_conn *, const char *); -@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const + char *sftp_expand_path(struct sftp_conn *, const char *); +@@ -163,7 +163,7 @@ * times if 'pflag' is set */ - int upload_dir(struct sftp_conn *, const char *, const char *, + 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 -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c ---- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100 -@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons - if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { - if (upload_dir(conn, g.gl_pathv[i], abs_dst, + +diff --git a/sftp.c b/sftp.c +--- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp.c (date 1703168795365) +@@ -807,7 +807,7 @@ + (rflag || global_rflag)) { + if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, - fflag || global_fflag, 0, 0) == -1) + fflag || global_fflag, 0, 0, 0) == -1) err = -1; } else { - if (do_upload(conn, g.gl_pathv[i], abs_dst, -@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn + if (sftp_upload(conn, g.gl_pathv[i], abs_dst, +@@ -1642,7 +1642,7 @@ if (path1 == NULL || *path1 == '\0') path1 = xstrdup(startdir); - path1 = make_absolute(path1, *pwd); -- if ((tmp = do_realpath(conn, path1)) == NULL) { -+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) { + path1 = sftp_make_absolute(path1, *pwd); +- if ((tmp = sftp_realpath(conn, path1)) == NULL) { ++ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) { err = 1; break; } -@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn, +@@ -2247,7 +2247,7 @@ } #endif /* USE_LIBEDIT */ - -- remote_path = do_realpath(conn, "."); -+ remote_path = do_realpath(conn, ".", 0); - if (remote_path == NULL) + +- if ((remote_path = sftp_realpath(conn, ".")) == NULL) ++ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL) fatal("Need cwd"); startdir = xstrdup(remote_path); + diff --git a/openssh-9.3p1-hpn-15.2-modified.patch b/openssh-9.3p1-hpn-15.2-modified.patch deleted file mode 100644 index d348911..0000000 --- a/openssh-9.3p1-hpn-15.2-modified.patch +++ /dev/null @@ -1,2595 +0,0 @@ -diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c ---- openssh-9.3p1.orig/auth2.c 2023-06-26 17:56:58.794634874 +0200 -+++ openssh-9.3p1/auth2.c 2023-06-26 17:59:24.993036944 +0200 -@@ -52,6 +52,8 @@ - #include "dispatch.h" - #include "pathnames.h" - #include "ssherr.h" -+#include "canohost.h" -+ - #ifdef GSSAPI - #include "ssh-gss.h" - #endif -@@ -74,6 +76,8 @@ - extern Authmethod method_gssapi; - #endif - -+static int log_flag = 0; -+ - Authmethod *authmethods[] = { - &method_none, - &method_pubkey, -@@ -297,6 +301,11 @@ - - debug("userauth-request for user %s service %s method %s", - user[0] ? user : "", service, method); -+ if (!log_flag) { -+ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", -+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), user); -+ log_flag = 1; -+ } - debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); - - #ifdef WITH_SELINUX -diff -Nur openssh-9.3p1.orig/channels.c openssh-9.3p1/channels.c ---- openssh-9.3p1.orig/channels.c 2023-06-26 17:56:58.689634585 +0200 -+++ openssh-9.3p1/channels.c 2023-06-26 18:26:41.719517151 +0200 -@@ -229,6 +229,9 @@ - /* Setup helper */ - static void channel_handler_init(struct ssh_channels *sc); - -+static int hpn_disabled = 0; -+static int hpn_buffer_size = 2 * 1024 * 1024; -+ - /* -- channel core */ - - void -@@ -495,6 +498,7 @@ - c->local_window = window; - c->local_window_max = window; - c->local_maxpacket = maxpack; -+ c->dynamic_window = 0; - c->remote_name = xstrdup(remote_name); - c->ctl_chan = -1; - c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1203,6 +1207,28 @@ - c->io_want = SSH_CHAN_IO_SOCK_W; - } - -+static int -+channel_tcpwinsz(struct ssh *ssh) -+{ -+ u_int32_t tcpwinsz = 0; -+ socklen_t optsz = sizeof(tcpwinsz); -+ int ret = -1; -+ -+ /* if we aren't on a socket return 128KB */ -+ if (!ssh_packet_connection_is_on_socket(ssh)) -+ return 128 * 1024; -+ -+ ret = getsockopt(ssh_packet_get_connection_in(ssh), -+ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); -+ /* return no more than SSHBUF_SIZE_MAX (currently 256MB) */ -+ if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX) -+ tcpwinsz = SSHBUF_SIZE_MAX; -+ -+ debug2("tcpwinsz: tcp connection %d, Receive window: %d", -+ ssh_packet_get_connection_in(ssh), tcpwinsz); -+ return tcpwinsz; -+} -+ - static void - channel_pre_open(struct ssh *ssh, Channel *c) - { -@@ -2305,22 +2331,31 @@ - - if (c->type == SSH_CHANNEL_OPEN && - !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && -- ((c->local_window_max - c->local_window > -- c->local_maxpacket*3) || -+ ((ssh_packet_is_interactive(ssh) && -+ c->local_window_max - c->local_window > c->local_maxpacket*3) || - c->local_window < c->local_window_max/2) && - c->local_consumed > 0) { -+ u_int addition = 0; -+ u_int32_t tcpwinsz = channel_tcpwinsz(ssh); -+ /* adjust max window size if we are in a dynamic environment */ -+ if (c->dynamic_window && (tcpwinsz > c->local_window_max)) { -+ /* grow the window somewhat aggressively to maintain pressure */ -+ addition = 1.5 * (tcpwinsz - c->local_window_max); -+ c->local_window_max += addition; -+ debug("Channel: Window growth to %d by %d bytes", c->local_window_max, addition); -+ } - if (!c->have_remote_id) - fatal_f("channel %d: no remote id", c->self); - if ((r = sshpkt_start(ssh, - SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 || - (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || -- (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || -+ (r = sshpkt_put_u32(ssh, c->local_consumed + addition)) != 0 || - (r = sshpkt_send(ssh)) != 0) { - fatal_fr(r, "channel %i", c->self); - } - debug2("channel %d: window %d sent adjust %d", c->self, -- c->local_window, c->local_consumed); -- c->local_window += c->local_consumed; -+ c->local_window, c->local_consumed + addition); -+ c->local_window += c->local_consumed + addition; - c->local_consumed = 0; - } - return 1; -@@ -3717,6 +3752,14 @@ - return addr; - } - -+void -+channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size) -+{ -+ hpn_disabled = external_hpn_disabled; -+ hpn_buffer_size = external_hpn_buffer_size; -+ debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size); -+} -+ - static int - channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, - struct Forward *fwd, int *allocated_listen_port, -@@ -3856,8 +3899,10 @@ - } - - /* Allocate a channel number for the socket. */ -+ /* explicitly test for hpn disabled option. if true use smaller window size */ - c = channel_new(ssh, "port-listener", type, sock, sock, -1, -- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, -+ hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : hpn_buffer_size, -+ CHAN_TCP_PACKET_DEFAULT, - 0, "port listener", 1); - c->path = xstrdup(host); - c->host_port = fwd->connect_port; -@@ -5041,7 +5086,8 @@ - sock = socks[n]; - nc = channel_new(ssh, "x11-listener", - SSH_CHANNEL_X11_LISTENER, sock, sock, -1, -- CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -+ hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : hpn_buffer_size, -+ CHAN_X11_PACKET_DEFAULT, - 0, "X11 inet listener", 1); - nc->single_connection = single_connection; - (*chanids)[n] = nc->self; -diff -Nur openssh-9.3p1.orig/channels.h openssh-9.3p1/channels.h ---- openssh-9.3p1.orig/channels.h 2023-06-26 17:56:58.638634445 +0200 -+++ openssh-9.3p1/channels.h 2023-06-26 17:59:24.996036952 +0200 -@@ -173,8 +173,10 @@ - u_int local_window_max; - u_int local_consumed; - u_int local_maxpacket; -+ int dynamic_window; - int extended_usage; - int single_connection; -+ u_int tcpwinsz; - - char *ctype; /* const type - NB. not freed on channel_free */ - char *xctype; /* extended type */ -@@ -254,7 +256,7 @@ - #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) - - /* Read buffer size */ --#define CHAN_RBUF (16*1024) -+#define CHAN_RBUF CHAN_SES_PACKET_DEFAULT - - /* Maximum size for direct reads to buffers */ - #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -396,4 +398,7 @@ - void chan_write_failed(struct ssh *, Channel *); - void chan_obuf_empty(struct ssh *, Channel *); - -+/* hpn handler */ -+void channel_set_hpn(int, int); -+ - #endif -diff -Nur openssh-9.3p1.orig/cipher.c openssh-9.3p1/cipher.c ---- openssh-9.3p1.orig/cipher.c 2023-06-26 17:56:58.717634662 +0200 -+++ openssh-9.3p1/cipher.c 2023-06-26 17:59:24.997036955 +0200 -@@ -48,6 +48,7 @@ - #include "sshbuf.h" - #include "ssherr.h" - #include "digest.h" -+#include "log.h" - - #include "openbsd-compat/openssl-compat.h" - -@@ -55,6 +56,9 @@ - #define EVP_CIPHER_CTX void - #endif - -+/* for multi-threaded aes-ctr cipher */ -+extern const EVP_CIPHER *evp_aes_ctr_mt(void); -+ - struct sshcipher_ctx { - int plaintext; - int encrypt; -@@ -64,7 +68,7 @@ - const struct sshcipher *cipher; - }; - --static const struct sshcipher ciphers[] = { -+static struct sshcipher ciphers[] = { - #ifdef WITH_OPENSSL - #ifndef OPENSSL_NO_DES - { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, -@@ -131,6 +135,29 @@ - #endif - } - -+/* used to get the cipher name so when force rekeying to handle the -+ * single to multithreaded ctr cipher swap we only rekey when appropriate -+ */ -+const char * -+cipher_ctx_name(const struct sshcipher_ctx *cc) -+{ -+ return cc->cipher->name; -+} -+ -+/* in order to get around sandbox and forking issues with a threaded cipher -+ * we set the initial pre-auth aes-ctr cipher to the default OpenSSH cipher -+ * post auth we set them to the new evp as defined by cipher-ctr-mt -+ */ -+#ifdef WITH_OPENSSL -+void -+cipher_reset_multithreaded(void) -+{ -+ cipher_by_name("aes128-ctr")->evptype = evp_aes_ctr_mt; -+ cipher_by_name("aes192-ctr")->evptype = evp_aes_ctr_mt; -+ cipher_by_name("aes256-ctr")->evptype = evp_aes_ctr_mt; -+} -+#endif -+ - u_int - cipher_blocksize(const struct sshcipher *c) - { -@@ -180,10 +207,10 @@ - return cc->plaintext; - } - --const struct sshcipher * -+struct sshcipher * - cipher_by_name(const char *name) - { -- const struct sshcipher *c; -+ struct sshcipher *c; - for (c = ciphers; c->name != NULL; c++) - if (strcmp(c->name, name) == 0) - return c; -@@ -205,7 +232,8 @@ - for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; - (p = strsep(&cp, CIPHER_SEP))) { - c = cipher_by_name(p); -- if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) { -+ if (c == NULL || ((c->flags & CFLAG_INTERNAL) != 0 && -+ (c->flags & CFLAG_NONE) != 0)) { - free(cipher_list); - return 0; - } -diff -Nur openssh-9.3p1.orig/cipher-ctr-mt.c openssh-9.3p1/cipher-ctr-mt.c ---- openssh-9.3p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.3p1/cipher-ctr-mt.c 2023-06-26 17:59:24.998036958 +0200 -@@ -0,0 +1,678 @@ -+/* -+ * OpenSSH Multi-threaded AES-CTR Cipher -+ * -+ * Author: Benjamin Bennett -+ * Author: Mike Tasota -+ * Author: Chris Rapier -+ * Copyright (c) 2008-2013 Pittsburgh Supercomputing Center. All rights reserved. -+ * -+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged, -+ * Copyright (c) 2003 Markus Friedl -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+#include "includes.h" -+ -+#if defined(WITH_OPENSSL) -+#include -+ -+#include -+#include -+ -+#include -+ -+#include "xmalloc.h" -+#include "log.h" -+#include -+ -+/* compatibility with old or broken OpenSSL versions */ -+#include "openbsd-compat/openssl-compat.h" -+ -+#ifndef USE_BUILTIN_RIJNDAEL -+#include -+#endif -+ -+#include -+ -+/*-------------------- TUNABLES --------------------*/ -+/* maximum number of threads and queues */ -+#define MAX_THREADS 32 -+#define MAX_NUMKQ (MAX_THREADS * 2) -+ -+/* Number of pregen threads to use */ -+int cipher_threads = 2; -+ -+/* Number of keystream queues */ -+int numkq = 4; -+ -+/* Length of a keystream queue */ -+#define KQLEN 4096 -+ -+/* Processor cacheline length */ -+#define CACHELINE_LEN 64 -+ -+/* Collect thread stats and print at cancellation when in debug mode */ -+#define CIPHER_THREAD_STATS -+ -+/* Can the system do unaligned loads natively? */ -+#if defined(__aarch64__) || \ -+ defined(__i386__) || \ -+ defined(__powerpc__) || \ -+ defined(__x86_64__) -+# define CIPHER_UNALIGNED_OK -+#endif -+#if defined(__SIZEOF_INT128__) -+# define CIPHER_INT128_OK -+#endif -+/*-------------------- END TUNABLES --------------------*/ -+ -+ -+const EVP_CIPHER *evp_aes_ctr_mt(void); -+ -+#ifdef CIPHER_THREAD_STATS -+/* -+ * Struct to collect thread stats -+ */ -+struct thread_stats { -+ u_int fills; -+ u_int skips; -+ u_int waits; -+ u_int drains; -+}; -+ -+/* -+ * Debug print the thread stats -+ * Use with pthread_cleanup_push for displaying at thread cancellation -+ */ -+static void -+thread_loop_stats(void *x) -+{ -+ struct thread_stats *s = x; -+ debug("AES-CTR MT tid %lu - %u fills, %u skips, %u waits", pthread_self(), -+ s->fills, s->skips, s->waits); -+} -+ -+# define STATS_STRUCT(s) struct thread_stats s -+# define STATS_INIT(s) { memset(&s, 0, sizeof(s)); } -+# define STATS_FILL(s) { s.fills++; } -+# define STATS_SKIP(s) { s.skips++; } -+# define STATS_WAIT(s) { s.waits++; } -+# define STATS_DRAIN(s) { s.drains++; } -+#else -+# define STATS_STRUCT(s) -+# define STATS_INIT(s) -+# define STATS_FILL(s) -+# define STATS_SKIP(s) -+# define STATS_WAIT(s) -+# define STATS_DRAIN(s) -+#endif -+ -+/* Keystream Queue state */ -+enum { -+ KQINIT, -+ KQEMPTY, -+ KQFILLING, -+ KQFULL, -+ KQDRAINING -+}; -+ -+/* Keystream Queue struct */ -+struct kq { -+ u_char keys[KQLEN][AES_BLOCK_SIZE]; -+ u_char ctr[AES_BLOCK_SIZE]; -+ u_char pad0[CACHELINE_LEN]; -+ int qstate; -+ pthread_mutex_t lock; -+ pthread_cond_t cond; -+ u_char pad1[CACHELINE_LEN]; -+}; -+ -+/* Context struct */ -+struct ssh_aes_ctr_ctx_mt -+{ -+ int struct_id; -+ struct kq q[MAX_NUMKQ]; -+ AES_KEY aes_ctx; -+ STATS_STRUCT(stats); -+ u_char aes_counter[AES_BLOCK_SIZE]; -+ pthread_t tid[MAX_THREADS]; -+ int id[MAX_THREADS]; -+ pthread_rwlock_t tid_lock; -+#ifdef __APPLE__ -+ pthread_rwlock_t stop_lock; -+ int exit_flag; -+#endif /* __APPLE__ */ -+ int state; -+ int qidx; -+ int ridx; -+}; -+ -+/* -+ * increment counter 'ctr', -+ * the counter is of size 'len' bytes and stored in network-byte-order. -+ * (LSB at ctr[len-1], MSB at ctr[0]) -+ */ -+static void -+ssh_ctr_inc(u_char *ctr, size_t len) -+{ -+ int i; -+ -+ for (i = len - 1; i >= 0; i--) -+ if (++ctr[i]) /* continue on overflow */ -+ return; -+} -+ -+/* -+ * Add num to counter 'ctr' -+ */ -+static void -+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len) -+{ -+ int i; -+ uint16_t n; -+ -+ for (n = 0, i = len - 1; i >= 0 && (num || n); i--) { -+ n = ctr[i] + (num & 0xff) + n; -+ num >>= 8; -+ ctr[i] = n & 0xff; -+ n >>= 8; -+ } -+} -+ -+/* -+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex -+ */ -+static void -+thread_loop_cleanup(void *x) -+{ -+ pthread_mutex_unlock((pthread_mutex_t *)x); -+} -+ -+#ifdef __APPLE__ -+/* Check if we should exit, we are doing both cancel and exit condition -+ * since on OSX threads seem to occasionally fail to notice when they have -+ * been cancelled. We want to have a backup to make sure that we won't hang -+ * when the main process join()-s the cancelled thread. -+ */ -+static void -+thread_loop_check_exit(struct ssh_aes_ctr_ctx_mt *c) -+{ -+ int exit_flag; -+ -+ pthread_rwlock_rdlock(&c->stop_lock); -+ exit_flag = c->exit_flag; -+ pthread_rwlock_unlock(&c->stop_lock); -+ -+ if (exit_flag) -+ pthread_exit(NULL); -+} -+#else -+# define thread_loop_check_exit(s) -+#endif /* __APPLE__ */ -+ -+/* -+ * Helper function to terminate the helper threads -+ */ -+static void -+stop_and_join_pregen_threads(struct ssh_aes_ctr_ctx_mt *c) -+{ -+ int i; -+ -+#ifdef __APPLE__ -+ /* notify threads that they should exit */ -+ pthread_rwlock_wrlock(&c->stop_lock); -+ c->exit_flag = TRUE; -+ pthread_rwlock_unlock(&c->stop_lock); -+#endif /* __APPLE__ */ -+ -+ /* Cancel pregen threads */ -+ for (i = 0; i < cipher_threads; i++) { -+ debug ("Canceled %lu (%d,%d)", c->tid[i], c->struct_id, c->id[i]); -+ pthread_cancel(c->tid[i]); -+ } -+ /* shouldn't need this - see commit logs for hpn-7_7_P1 -cjr 11/7/19*/ -+ /* for (i = 0; i < numkq; i++) { */ -+ /* pthread_mutex_lock(&c->q[i].lock); */ -+ /* pthread_cond_broadcast(&c->q[i].cond); */ -+ /* pthread_mutex_unlock(&c->q[i].lock); */ -+ /* } */ -+ for (i = 0; i < cipher_threads; i++) { -+ if (pthread_kill(c->tid[i], 0) != 0) -+ debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", c->tid[i], __FUNCTION__); -+ else { -+ debug ("Joining %lu (%d, %d)", c->tid[i], c->struct_id, c->id[i]); -+ pthread_join(c->tid[i], NULL); -+ } -+ } -+} -+ -+/* -+ * The life of a pregen thread: -+ * Find empty keystream queues and fill them using their counter. -+ * When done, update counter for the next fill. -+ */ -+static void * -+thread_loop(void *x) -+{ -+ AES_KEY key; -+ STATS_STRUCT(stats); -+ struct ssh_aes_ctr_ctx_mt *c = x; -+ struct kq *q; -+ int i; -+ int qidx; -+ pthread_t first_tid; -+ -+ /* Threads stats on cancellation */ -+ STATS_INIT(stats); -+#ifdef CIPHER_THREAD_STATS -+ pthread_cleanup_push(thread_loop_stats, &stats); -+#endif -+ -+ /* Thread local copy of AES key */ -+ memcpy(&key, &c->aes_ctx, sizeof(key)); -+ -+ pthread_rwlock_rdlock(&c->tid_lock); -+ first_tid = c->tid[0]; -+ pthread_rwlock_unlock(&c->tid_lock); -+ -+ /* -+ * Handle the special case of startup, one thread must fill -+ * the first KQ then mark it as draining. Lock held throughout. -+ */ -+ if (pthread_equal(pthread_self(), first_tid)) { -+ q = &c->q[0]; -+ pthread_mutex_lock(&q->lock); -+ if (q->qstate == KQINIT) { -+ for (i = 0; i < KQLEN; i++) { -+ AES_encrypt(q->ctr, q->keys[i], &key); -+ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE); -+ } -+ ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE); -+ q->qstate = KQDRAINING; -+ STATS_FILL(stats); -+ pthread_cond_broadcast(&q->cond); -+ } -+ pthread_mutex_unlock(&q->lock); -+ } else -+ STATS_SKIP(stats); -+ -+ /* -+ * Normal case is to find empty queues and fill them, skipping over -+ * queues already filled by other threads and stopping to wait for -+ * a draining queue to become empty. -+ * -+ * Multiple threads may be waiting on a draining queue and awoken -+ * when empty. The first thread to wake will mark it as filling, -+ * others will move on to fill, skip, or wait on the next queue. -+ */ -+ for (qidx = 1;; qidx = (qidx + 1) % numkq) { -+ /* Check if I was cancelled, also checked in cond_wait */ -+ pthread_testcancel(); -+ -+ /* Check if we should exit as well */ -+ thread_loop_check_exit(c); -+ -+ /* Lock queue and block if its draining */ -+ q = &c->q[qidx]; -+ pthread_mutex_lock(&q->lock); -+ pthread_cleanup_push(thread_loop_cleanup, &q->lock); -+ while (q->qstate == KQDRAINING || q->qstate == KQINIT) { -+ STATS_WAIT(stats); -+ thread_loop_check_exit(c); -+ pthread_cond_wait(&q->cond, &q->lock); -+ } -+ pthread_cleanup_pop(0); -+ -+ /* If filling or full, somebody else got it, skip */ -+ if (q->qstate != KQEMPTY) { -+ pthread_mutex_unlock(&q->lock); -+ STATS_SKIP(stats); -+ continue; -+ } -+ -+ /* -+ * Empty, let's fill it. -+ * Queue lock is relinquished while we do this so others -+ * can see that it's being filled. -+ */ -+ q->qstate = KQFILLING; -+ pthread_cond_broadcast(&q->cond); -+ pthread_mutex_unlock(&q->lock); -+ for (i = 0; i < KQLEN; i++) { -+ AES_encrypt(q->ctr, q->keys[i], &key); -+ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE); -+ } -+ -+ /* Re-lock, mark full and signal consumer */ -+ pthread_mutex_lock(&q->lock); -+ ssh_ctr_add(q->ctr, KQLEN * (numkq - 1), AES_BLOCK_SIZE); -+ q->qstate = KQFULL; -+ STATS_FILL(stats); -+ pthread_cond_broadcast(&q->cond); -+ pthread_mutex_unlock(&q->lock); -+ } -+ -+#ifdef CIPHER_THREAD_STATS -+ /* Stats */ -+ pthread_cleanup_pop(1); -+#endif -+ -+ return NULL; -+} -+ -+static int -+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, -+ LIBCRYPTO_EVP_INL_TYPE len) -+{ -+ typedef union { -+#ifdef CIPHER_INT128_OK -+ __uint128_t *u128; -+#endif -+ uint64_t *u64; -+ uint32_t *u32; -+ uint8_t *u8; -+ const uint8_t *cu8; -+ uintptr_t u; -+ } ptrs_t; -+ ptrs_t destp, srcp, bufp; -+ uintptr_t align; -+ struct ssh_aes_ctr_ctx_mt *c; -+ struct kq *q, *oldq; -+ int ridx; -+ u_char *buf; -+ -+ if (len == 0) -+ return 1; -+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) -+ return 0; -+ -+ q = &c->q[c->qidx]; -+ ridx = c->ridx; -+ -+ /* src already padded to block multiple */ -+ srcp.cu8 = src; -+ destp.u8 = dest; -+ while (len > 0) { -+ buf = q->keys[ridx]; -+ bufp.u8 = buf; -+ -+ /* figure out the alignment on the fly */ -+#ifdef CIPHER_UNALIGNED_OK -+ align = 0; -+#else -+ align = destp.u | srcp.u | bufp.u; -+#endif -+ -+#ifdef CIPHER_INT128_OK -+ if ((align & 0xf) == 0) { -+ destp.u128[0] = srcp.u128[0] ^ bufp.u128[0]; -+ } else -+#endif -+ if ((align & 0x7) == 0) { -+ destp.u64[0] = srcp.u64[0] ^ bufp.u64[0]; -+ destp.u64[1] = srcp.u64[1] ^ bufp.u64[1]; -+ } else if ((align & 0x3) == 0) { -+ destp.u32[0] = srcp.u32[0] ^ bufp.u32[0]; -+ destp.u32[1] = srcp.u32[1] ^ bufp.u32[1]; -+ destp.u32[2] = srcp.u32[2] ^ bufp.u32[2]; -+ destp.u32[3] = srcp.u32[3] ^ bufp.u32[3]; -+ } else { -+ size_t i; -+ for (i = 0; i < AES_BLOCK_SIZE; ++i) -+ dest[i] = src[i] ^ buf[i]; -+ } -+ -+ destp.u += AES_BLOCK_SIZE; -+ srcp.u += AES_BLOCK_SIZE; -+ len -= AES_BLOCK_SIZE; -+ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); -+ -+ /* Increment read index, switch queues on rollover */ -+ if ((ridx = (ridx + 1) % KQLEN) == 0) { -+ oldq = q; -+ -+ /* Mark next queue draining, may need to wait */ -+ c->qidx = (c->qidx + 1) % numkq; -+ q = &c->q[c->qidx]; -+ pthread_mutex_lock(&q->lock); -+ while (q->qstate != KQFULL) { -+ STATS_WAIT(c->stats); -+ pthread_cond_wait(&q->cond, &q->lock); -+ } -+ q->qstate = KQDRAINING; -+ pthread_cond_broadcast(&q->cond); -+ pthread_mutex_unlock(&q->lock); -+ -+ /* Mark consumed queue empty and signal producers */ -+ pthread_mutex_lock(&oldq->lock); -+ oldq->qstate = KQEMPTY; -+ STATS_DRAIN(c->stats); -+ pthread_cond_broadcast(&oldq->cond); -+ pthread_mutex_unlock(&oldq->lock); -+ } -+ } -+ c->ridx = ridx; -+ return 1; -+} -+ -+#define HAVE_NONE 0 -+#define HAVE_KEY 1 -+#define HAVE_IV 2 -+ -+int X = 0; -+ -+static int -+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, -+ int enc) -+{ -+ struct ssh_aes_ctr_ctx_mt *c; -+ int i; -+ -+ /* get the number of cores in the system */ -+ /* if it's not linux it currently defaults to 2 */ -+ /* divide by 2 to get threads for each direction (MODE_IN||MODE_OUT) */ -+#ifdef __linux__ -+ cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; -+#endif /*__linux__*/ -+#ifdef __APPLE__ -+ cipher_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; -+#endif /*__APPLE__*/ -+#ifdef __FREEBSD__ -+ int req[2]; -+ size_t len; -+ -+ req[0] = CTL_HW; -+ req[1] = HW_NCPU; -+ -+ len = sizeof(ncpu); -+ sysctl(req, 2, &cipher_threads, &len, NULL, 0); -+ cipher_threads = cipher_threads / 2; -+#endif /*__FREEBSD__*/ -+ -+ /* if they have less than 4 cores spin up 4 threads anyway */ -+ if (cipher_threads < 2) -+ cipher_threads = 2; -+ -+ /* assure that we aren't trying to create more threads */ -+ /* than we have in the struct. cipher_threads is half the */ -+ /* total of allowable threads hence the odd looking math here */ -+ if (cipher_threads * 2 > MAX_THREADS) -+ cipher_threads = MAX_THREADS / 2; -+ -+ /* set the number of keystream queues */ -+ numkq = cipher_threads * 2; -+ -+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { -+ c = xmalloc(sizeof(*c)); -+ pthread_rwlock_init(&c->tid_lock, NULL); -+#ifdef __APPLE__ -+ pthread_rwlock_init(&c->stop_lock, NULL); -+ c->exit_flag = FALSE; -+#endif /* __APPLE__ */ -+ -+ c->state = HAVE_NONE; -+ for (i = 0; i < numkq; i++) { -+ pthread_mutex_init(&c->q[i].lock, NULL); -+ pthread_cond_init(&c->q[i].cond, NULL); -+ } -+ -+ STATS_INIT(c->stats); -+ EVP_CIPHER_CTX_set_app_data(ctx, c); -+ } -+ -+ if (c->state == (HAVE_KEY | HAVE_IV)) { -+ /* tell the pregen threads to exit */ -+ stop_and_join_pregen_threads(c); -+ -+#ifdef __APPLE__ -+ /* reset the exit flag */ -+ c->exit_flag = FALSE; -+#endif /* __APPLE__ */ -+ -+ /* Start over getting key & iv */ -+ c->state = HAVE_NONE; -+ } -+ -+ if (key != NULL) { -+ AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, -+ &c->aes_ctx); -+ c->state |= HAVE_KEY; -+ } -+ -+ if (iv != NULL) { -+ memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); -+ c->state |= HAVE_IV; -+ } -+ -+ if (c->state == (HAVE_KEY | HAVE_IV)) { -+ /* Clear queues */ -+ memcpy(c->q[0].ctr, c->aes_counter, AES_BLOCK_SIZE); -+ c->q[0].qstate = KQINIT; -+ for (i = 1; i < numkq; i++) { -+ memcpy(c->q[i].ctr, c->aes_counter, AES_BLOCK_SIZE); -+ ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE); -+ c->q[i].qstate = KQEMPTY; -+ } -+ c->qidx = 0; -+ c->ridx = 0; -+ -+ /* Start threads */ -+ for (i = 0; i < cipher_threads; i++) { -+ pthread_rwlock_wrlock(&c->tid_lock); -+ if (pthread_create(&c->tid[i], NULL, thread_loop, c) != 0) -+ debug ("AES-CTR MT Could not create thread in %s", __FUNCTION__); /*should die here */ -+ else { -+ if (!c->struct_id) -+ c->struct_id = X++; -+ c->id[i] = i; -+ debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]); -+ } -+ pthread_rwlock_unlock(&c->tid_lock); -+ } -+ pthread_mutex_lock(&c->q[0].lock); -+ while (c->q[0].qstate == KQINIT) -+ pthread_cond_wait(&c->q[0].cond, &c->q[0].lock); -+ pthread_mutex_unlock(&c->q[0].lock); -+ } -+ return 1; -+} -+ -+/* this function is no longer used but might prove handy in the future -+ * this comment also applies to ssh_aes_ctr_thread_reconstruction -+ */ -+void -+ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx) -+{ -+ struct ssh_aes_ctr_ctx_mt *c; -+ -+ c = EVP_CIPHER_CTX_get_app_data(ctx); -+ stop_and_join_pregen_threads(c); -+} -+ -+void -+ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx) -+{ -+ struct ssh_aes_ctr_ctx_mt *c; -+ int i; -+ c = EVP_CIPHER_CTX_get_app_data(ctx); -+ /* reconstruct threads */ -+ for (i = 0; i < cipher_threads; i++) { -+ pthread_rwlock_wrlock(&c->tid_lock); -+ if (pthread_create(&c->tid[i], NULL, thread_loop, c) !=0 ) -+ debug("AES-CTR MT could not create thread in %s", __FUNCTION__); -+ else { -+ c->struct_id = X++; -+ c->id[i] = i; -+ debug ("AES-CTR MT spawned a thread with id %lu in %s (%d, %d)", c->tid[i], __FUNCTION__, c->struct_id, c->id[i]); -+ debug("AES-CTR MT spawned a thread with id %lu in %s", c->tid[i], __FUNCTION__); -+ } -+ pthread_rwlock_unlock(&c->tid_lock); -+ } -+} -+ -+static int -+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) -+{ -+ struct ssh_aes_ctr_ctx_mt *c; -+ -+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { -+#ifdef CIPHER_THREAD_STATS -+ debug("AES-CTR MT main thread: %u drains, %u waits", c->stats.drains, -+ c->stats.waits); -+#endif -+ stop_and_join_pregen_threads(c); -+ -+ memset(c, 0, sizeof(*c)); -+ free(c); -+ EVP_CIPHER_CTX_set_app_data(ctx, NULL); -+ } -+ return 1; -+} -+ -+/* */ -+const EVP_CIPHER * -+evp_aes_ctr_mt(void) -+{ -+# if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+ static EVP_CIPHER *aes_ctr; -+ aes_ctr = EVP_CIPHER_meth_new(NID_undef, 16/*block*/, 16/*key*/); -+ EVP_CIPHER_meth_set_iv_length(aes_ctr, AES_BLOCK_SIZE); -+ EVP_CIPHER_meth_set_init(aes_ctr, ssh_aes_ctr_init); -+ EVP_CIPHER_meth_set_cleanup(aes_ctr, ssh_aes_ctr_cleanup); -+ EVP_CIPHER_meth_set_do_cipher(aes_ctr, ssh_aes_ctr); -+# ifndef SSH_OLD_EVP -+ EVP_CIPHER_meth_set_flags(aes_ctr, EVP_CIPH_CBC_MODE -+ | EVP_CIPH_VARIABLE_LENGTH -+ | EVP_CIPH_ALWAYS_CALL_INIT -+ | EVP_CIPH_CUSTOM_IV); -+# endif /*SSH_OLD_EVP*/ -+ return (aes_ctr); -+# else /*earlier versions of openssl*/ -+ static EVP_CIPHER aes_ctr; -+ memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); -+ aes_ctr.nid = NID_undef; -+ aes_ctr.block_size = AES_BLOCK_SIZE; -+ aes_ctr.iv_len = AES_BLOCK_SIZE; -+ aes_ctr.key_len = 16; -+ aes_ctr.init = ssh_aes_ctr_init; -+ aes_ctr.cleanup = ssh_aes_ctr_cleanup; -+ 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; -+# endif /*SSH_OLD_EVP*/ -+ return &aes_ctr; -+# endif /*OPENSSH_VERSION_NUMBER*/ -+} -+ -+#endif /* defined(WITH_OPENSSL) */ -diff -Nur openssh-9.3p1.orig/cipher.h openssh-9.3p1/cipher.h ---- openssh-9.3p1.orig/cipher.h 2023-06-26 17:56:58.717634662 +0200 -+++ openssh-9.3p1/cipher.h 2023-06-26 17:59:24.999036961 +0200 -@@ -68,7 +68,9 @@ - - struct sshcipher_ctx; - --const struct sshcipher *cipher_by_name(const char *); -+void ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx); // defined in cipher-ctr-mt.c -+void ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx); -+struct sshcipher *cipher_by_name(const char *); - const char *cipher_warning_message(const struct sshcipher_ctx *); - int ciphers_valid(const char *); - char *cipher_alg_list(char, int); -@@ -86,6 +88,8 @@ - u_int cipher_authlen(const struct sshcipher *); - u_int cipher_ivlen(const struct sshcipher *); - u_int cipher_is_cbc(const struct sshcipher *); -+void cipher_reset_multithreaded(void); -+const char *cipher_ctx_name(const struct sshcipher_ctx *); - - u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); - -diff -Nur openssh-9.3p1.orig/clientloop.c openssh-9.3p1/clientloop.c ---- openssh-9.3p1.orig/clientloop.c 2023-06-26 17:56:58.584634296 +0200 -+++ openssh-9.3p1/clientloop.c 2023-06-26 17:59:25.000036964 +0200 -@@ -1646,7 +1646,9 @@ - return NULL; - c = channel_new(ssh, "x11", - SSH_CHANNEL_X11_OPEN, sock, sock, -1, -- CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); -+ /* again is this really necessary for X11? */ -+ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, -+ CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); - c->force_drain = 1; - return c; - } -@@ -1681,7 +1683,8 @@ - - c = channel_new(ssh, "authentication agent connection", - SSH_CHANNEL_OPEN, sock, sock, -1, -- CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, -+ options.hpn_disabled ? CHAN_X11_WINDOW_DEFAULT : options.hpn_buffer_size, -+ CHAN_TCP_PACKET_DEFAULT, 0, - "authentication agent connection", 1); - c->force_drain = 1; - return c; -@@ -1708,7 +1711,8 @@ - debug("Tunnel forwarding using interface %s", ifname); - - c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, -- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); -+ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, -+ CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); - c->datagram = 1; - - #if defined(SSH_TUN_FILTER) -diff -Nur openssh-9.3p1.orig/compat.c openssh-9.3p1/compat.c ---- openssh-9.3p1.orig/compat.c 2023-06-26 17:56:58.764634791 +0200 -+++ openssh-9.3p1/compat.c 2023-06-26 17:59:25.001036966 +0200 -@@ -135,6 +135,17 @@ - ssh->compat = check[i].bugs; - if (forbid_ssh_rsa) - ssh->compat |= SSH_RH_RSASIGSHA; -+ /* Check to see if the remote side is OpenSSH and not HPN */ -+ /* TODO: See if we can work this into the new method for bug checks */ -+ if (strstr(version, "OpenSSH") != NULL) { -+ if (strstr(version, "hpn") == NULL) { -+ ssh->compat |= SSH_BUG_LARGEWINDOW; -+ debug("Remote is NOT HPN enabled"); -+ } else { -+ debug("Remote is HPN Enabled"); -+ } -+ } -+ debug("ssh->compat is %u", ssh->compat); - return; - } - } -diff -Nur openssh-9.3p1.orig/compat.h openssh-9.3p1/compat.h ---- openssh-9.3p1.orig/compat.h 2023-06-26 17:56:58.765634794 +0200 -+++ openssh-9.3p1/compat.h 2023-06-26 17:59:25.001036966 +0200 -@@ -57,6 +57,7 @@ - #define SSH_BUG_CURVE25519PAD 0x10000000 - #define SSH_BUG_HOSTKEYS 0x20000000 - #define SSH_BUG_DHGEX_LARGE 0x40000000 -+#define SSH_BUG_LARGEWINDOW 0x80000000 - - struct ssh; - -diff -Nur openssh-9.3p1.orig/defines.h openssh-9.3p1/defines.h ---- openssh-9.3p1.orig/defines.h 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/defines.h 2023-06-26 17:59:25.002036969 +0200 -@@ -889,7 +889,7 @@ - #endif - - #ifndef SSH_IOBUFSZ --# define SSH_IOBUFSZ 8192 -+# define SSH_IOBUFSZ 32*1024 - #endif - - /* -diff -Nur openssh-9.3p1.orig/digest.h openssh-9.3p1/digest.h ---- openssh-9.3p1.orig/digest.h 2023-06-26 17:56:58.672634538 +0200 -+++ openssh-9.3p1/digest.h 2023-06-26 17:59:25.002036969 +0200 -@@ -27,7 +27,8 @@ - #define SSH_DIGEST_SHA256 2 - #define SSH_DIGEST_SHA384 3 - #define SSH_DIGEST_SHA512 4 --#define SSH_DIGEST_MAX 5 -+#define SSH_DIGEST_NULL 5 -+#define SSH_DIGEST_MAX 6 - - struct sshbuf; - struct ssh_digest_ctx; -diff -Nur openssh-9.3p1.orig/digest-openssl.c openssh-9.3p1/digest-openssl.c ---- openssh-9.3p1.orig/digest-openssl.c 2023-06-26 17:56:58.672634538 +0200 -+++ openssh-9.3p1/digest-openssl.c 2023-06-26 17:59:25.002036969 +0200 -@@ -61,6 +61,7 @@ - { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, - { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, - { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, -+ { SSH_DIGEST_NULL, "NONEMAC", 0, EVP_md_null}, - { -1, NULL, 0, NULL }, - }; - -diff -Nur openssh-9.3p1.orig/HPN-README openssh-9.3p1/HPN-README ---- openssh-9.3p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.3p1/HPN-README 2023-06-26 17:59:25.003036972 +0200 -@@ -0,0 +1,153 @@ -+Notes: -+ -+MULTI-THREADED CIPHER: -+The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations -+on hosts with multiple cores to use more than one processing core during encryption. -+Tests have show significant throughput performance increases when using MTR-AES-CTR up -+to and including a full gigabit per second on quad core systems. It should be possible to -+achieve full line rate on dual core systems but OS and data management overhead makes this -+more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single -+thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal -+performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. -+The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same -+nomenclature. -+Use examples: -+ ssh -caes128-ctr you@host.com -+ scp -oCipher=aes256-ctr file you@host.com:~/file -+ -+NONE CIPHER: -+To use the NONE option you must have the NoneEnabled switch set on the server and -+you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE -+feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not -+spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will -+be disabled. -+ -+The performance increase will only be as good as the network and TCP stack tuning -+on the reciever side of the connection allows. As a rule of thumb a user will need -+at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The -+HPN-SSH home page describes this in greater detail. -+ -+http://www.psc.edu/networking/projects/hpn-ssh -+ -+NONE MAC: -+Starting with HPN 15v1 users will have the option to disable HMAC (message -+authentication ciphers) when using the NONE cipher. You must enable the following: -+NoneEnabled, NoneSwitch, and NoneMacEnabled. If all three are not enabled the None MAC -+will be automatically disabled. In tests the use of the None MAC improved throuput by -+more than 30%. -+ -+ex: scp -oNoneSwitch=yes -oNoneEnabled=yes -oNoneMacEnabled=yes file host:~ -+ -+BUFFER SIZES: -+ -+If HPN is disabled the receive buffer size will be set to the -+OpenSSH default of 2MB (for OpenSSH versions before 4.7: 64KB). -+ -+If an HPN system connects to a nonHPN system the receive buffer will -+be set to the HPNBufferSize value. The default is 2MB but user adjustable. -+ -+If an HPN to HPN connection is established a number of different things might -+happen based on the user options and conditions. -+ -+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set -+HPN Buffer Size = up to 64MB -+This is the default state. The HPN buffer size will grow to a maximum of 64MB -+as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is -+geared towards 10GigE transcontinental connections. -+ -+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set -+HPN Buffer Size = TCP receive buffer value. -+Users on non-autotuning systems should disable TCPRcvBufPoll in the -+ssh_config and sshd_config -+ -+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set -+HPN Buffer Size = minimum of TCP receive buffer and HPNBufferSize. -+This would be the system defined TCP receive buffer (RWIN). -+ -+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET -+HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize. -+Generally there is no need to set both. -+ -+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set -+HPN Buffer Size = grows to HPNBufferSize -+The buffer will grow up to the maximum size specified here. -+ -+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET -+HPN Buffer Size = minimum of TCPRcvBuf and HPNBufferSize. -+Generally there is no need to set both of these, especially on autotuning -+systems. However, if the users wishes to override the autotuning this would be -+one way to do it. -+ -+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET -+HPN Buffer Size = TCPRcvBuf. -+This will override autotuning and set the TCP recieve buffer to the user defined -+value. -+ -+ -+HPN Specific Configuration options -+ -+TcpRcvBuf=[int]KB client -+ Set the TCP socket receive buffer to n Kilobytes. It can be set up to the -+maximum socket size allowed by the system. This is useful in situations where -+the tcp receive window is set low but the maximum buffer size is set -+higher (as is typical). This works on a per TCP connection basis. You can also -+use this to artifically limit the transfer rate of the connection. In these -+cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. -+Default is the current system wide tcp receive buffer size. -+ -+TcpRcvBufPoll=[yes/no] client/server -+ Enable of disable the polling of the tcp receive buffer through the life -+of the connection. You would want to make sure that this option is enabled -+for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) -+default is yes. -+ -+NoneEnabled=[yes/no] client/server -+ Enable or disable the use of the None cipher. Care must always be used -+when enabling this as it will allow users to send data in the clear. However, -+it is important to note that authentication information remains encrypted -+even if this option is enabled. Set to no by default. -+ -+NoneMacEnabled=[yes/no] client/server -+ Enable or disable the use of the None MAC. When this is enabled ssh -+will *not* provide data integrity of any data being transmitted between hosts. Use -+with caution as it, unlike just using NoneEnabled, doesn't provide data integrity and -+protection against man-in-the-middle attacks. As with NoneEnabled all authentication -+remains encrypted and integrity is ensured. Default is no. -+ -+NoneSwitch=[yes/no] client -+ Switch the encryption cipher being used to the None cipher after -+authentication takes place. NoneEnabled must be enabled on both the client -+and server side of the connection. When the connection switches to the NONE -+cipher a warning is sent to STDERR. The connection attempt will fail with an -+error if a client requests a NoneSwitch from the server that does not explicitly -+have NoneEnabled set to yes. Note: The NONE cipher cannot be used in -+interactive (shell) sessions and it will fail silently. Set to no by default. -+ -+HPNDisabled=[yes/no] client/server -+ In some situations, such as transfers on a local area network, the impact -+of the HPN code produces a net decrease in performance. In these cases it is -+helpful to disable the HPN functionality. By default HPNDisabled is set to no. -+ -+HPNBufferSize=[int]KB client/server -+ This is the default buffer size the HPN functionality uses when interacting -+with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf -+option as applied to the internal SSH flow control. This value can range from -+1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance -+problems depending on the length of the network path. The default size of this buffer -+is 2MB. -+ -+DisableMTAES=[yes/no] client/server -+ Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher -+back to the stock single-threaded AES-CTR cipher. Useful on modern processors with -+AES-NI instructions which make the stock single-threaded AES-CTR cipher faster than -+the multithreaded MT-AES-CTR cipher. Set to no by default. -+ -+ -+Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu) -+ The majority of the actual coding for versions up to HPN12v1 was performed -+ by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was -+ implemented by Ben Bennet (ben@psc.edu) and improved by Mike Tasota -+ (tasota@gmail.com) an NSF REU grant recipient for 2013. -+ Allan Jude provided the code for the NoneMac and buffer normalization. -+ This work was financed, in part, by Cisco System, Inc., the National -+ Library of Medicine, and the National Science Foundation. -diff -Nur openssh-9.3p1.orig/kex.c openssh-9.3p1/kex.c ---- openssh-9.3p1.orig/kex.c 2023-06-26 17:56:58.759634778 +0200 -+++ openssh-9.3p1/kex.c 2023-06-26 17:59:25.004036975 +0200 -@@ -65,6 +65,7 @@ - - #include "ssherr.h" - #include "sshbuf.h" -+#include "canohost.h" - #include "digest.h" - #include "xmalloc.h" - #include "audit.h" -@@ -1061,6 +1062,11 @@ - int nenc, nmac, ncomp; - u_int mode, ctos, need, dh_need, authlen; - int r, first_kex_follows; -+ int auth_flag = 0; -+ int log_flag = 0; -+ -+ auth_flag = packet_authentication_state(ssh); -+ debug("AUTH STATE IS %d", auth_flag); - - debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); - if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) -@@ -1141,11 +1147,40 @@ - peer[ncomp] = NULL; - goto out; - } -+ debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); -+ debug("REQUESTED MAC.NAME is '%s'", newkeys->mac.name); -+ if (strcmp(newkeys->enc.name, "none") == 0) { -+ if (auth_flag == 1) { -+ debug("None requested post authentication."); -+ ssh->none = 1; -+ } -+ else -+ fatal("Pre-authentication none cipher requests are not allowed."); -+ if (newkeys->mac.name != NULL && strcmp(newkeys->mac.name, "none") == 0) -+ debug("Requesting: NONEMAC. Authflag is %d", auth_flag); -+ } -+ - debug("kex: %s cipher: %s MAC: %s compression: %s", - ctos ? "client->server" : "server->client", - newkeys->enc.name, - authlen == 0 ? newkeys->mac.name : "", - newkeys->comp.name); -+ /* -+ * client starts with ctos = 0 && log flag = 0 and no log. -+ * 2nd client pass ctos = 1 and flag = 1 so no log. -+ * server starts with ctos = 1 && log_flag = 0 so log. -+ * 2nd sever pass ctos = 1 && log flag = 1 so no log. -+ * -cjr -+ */ -+ if (ctos && !log_flag) { -+ logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s", -+ ssh_remote_ipaddr(ssh), -+ ssh_remote_port(ssh), -+ newkeys->enc.name, -+ authlen == 0 ? newkeys->mac.name : "", -+ newkeys->comp.name); -+ } -+ log_flag = 1; - } - need = dh_need = 0; - for (mode = 0; mode < MODE_MAX; mode++) { -@@ -1493,7 +1528,7 @@ - if (version_addendum != NULL && *version_addendum == '\0') - version_addendum = NULL; - if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", -- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, -+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, - version_addendum == NULL ? "" : " ", - version_addendum == NULL ? "" : version_addendum)) != 0) { - oerrno = errno; -@@ -1629,6 +1664,14 @@ - r = SSH_ERR_INVALID_FORMAT; - goto out; - } -+ -+ /* report the version information to syslog if this is the server */ -+ if (timeout_ms == -1) { /* only the server uses this value */ -+ logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s", -+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -+ remote_major, remote_minor, remote_version); -+ } -+ - debug("Remote protocol version %d.%d, remote software version %.100s", - remote_major, remote_minor, remote_version); - compat_banner(ssh, remote_version); -diff -Nur openssh-9.3p1.orig/log.c openssh-9.3p1/log.c ---- openssh-9.3p1.orig/log.c 2023-06-26 17:56:58.620634395 +0200 -+++ openssh-9.3p1/log.c 2023-06-26 17:59:25.005036978 +0200 -@@ -46,6 +46,11 @@ - #include - #include - #include -+#include "packet.h" /* needed for host and port look ups */ -+#ifdef HAVE_SYS_TIME_H -+# include /* to get current time */ -+#endif -+ - #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) - # include - #endif -@@ -65,6 +70,8 @@ - - extern char *__progname; - -+extern struct ssh *active_state; -+ - #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) - #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) - -diff -Nur openssh-9.3p1.orig/mac.c openssh-9.3p1/mac.c ---- openssh-9.3p1.orig/mac.c 2023-06-26 17:56:58.719634668 +0200 -+++ openssh-9.3p1/mac.c 2023-06-26 17:59:25.005036978 +0200 -@@ -63,6 +63,7 @@ - { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, - { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, - { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, -+ { "none", SSH_DIGEST, SSH_DIGEST_NULL, 0, 0, 0, 0 }, - { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, - { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, - -diff -Nur openssh-9.3p1.orig/Makefile.in openssh-9.3p1/Makefile.in ---- openssh-9.3p1.orig/Makefile.in 2023-06-26 17:56:58.801634893 +0200 -+++ openssh-9.3p1/Makefile.in 2023-06-26 18:05:19.227009623 +0200 -@@ -49,7 +49,7 @@ - CFLAGS_NOPIE=@CFLAGS_NOPIE@ - CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ - PICFLAG=@PICFLAG@ --LIBS=@LIBS@ -+LIBS=@LIBS@ -lpthread - CHANNELLIBS=@CHANNELLIBS@ - K5LIBS=@K5LIBS@ - GSSLIBS=@GSSLIBS@ -@@ -97,7 +97,7 @@ - LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - authfd.o authfile.o \ - canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ -- cleanup.o \ -+ cipher-ctr-mt.o cleanup.o \ - compat.o fatal.o hostfile.o \ - log.o match.o moduli.o nchan.o packet.o \ - readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -diff -Nur openssh-9.3p1.orig/packet.c openssh-9.3p1/packet.c ---- openssh-9.3p1.orig/packet.c 2023-06-26 17:56:58.723634679 +0200 -+++ openssh-9.3p1/packet.c 2023-06-26 17:59:25.007036983 +0200 -@@ -246,7 +246,7 @@ - TAILQ_INIT(&ssh->public_keys); - state->connection_in = -1; - state->connection_out = -1; -- state->max_packet_size = 32768; -+ state->max_packet_size = CHAN_SES_PACKET_DEFAULT; - state->packet_timeout_ms = -1; - state->p_send.packets = state->p_read.packets = 0; - state->initialized = 1; -@@ -294,7 +294,7 @@ - ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) - { - struct session_state *state; -- const struct sshcipher *none = cipher_by_name("none"); -+ struct sshcipher *none = cipher_by_name("none"); - int r; - - if (none == NULL) { -@@ -958,10 +958,19 @@ - * so enforce a 1GB limit for small blocksizes. - * See RFC4344 section 3.2. - */ -- if (enc->block_size >= 16) -- *max_blocks = (u_int64_t)1 << (enc->block_size*2); -- else -- *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; -+ -+ /* we really don't need to rekey if we are using the none cipher -+ * but there isn't a good way to disable it entirely that I can find -+ * and using a blocksize larger that 16 doesn't work (dunno why) -+ * so this seems to be a good limit for now - CJR 10/16/2020*/ -+ if (ssh->none == 1) { -+ *max_blocks = (u_int64_t)1 << (16*2); -+ } else { -+ if (enc->block_size >= 16) -+ *max_blocks = (u_int64_t)1 << (enc->block_size*2); -+ else -+ *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; -+ } - if (state->rekey_limit) - *max_blocks = MINIMUM(*max_blocks, - state->rekey_limit / enc->block_size); -@@ -970,6 +979,24 @@ - return 0; - } - -+/* this supports the forced rekeying required for the NONE cipher */ -+int rekey_requested = 0; -+void -+packet_request_rekeying(void) -+{ -+ rekey_requested = 1; -+} -+ -+/* used to determine if pre or post auth when rekeying for aes-ctr -+ * and none cipher switch */ -+int -+packet_authentication_state(const struct ssh *ssh) -+{ -+ struct session_state *state = ssh->state; -+ -+ return state->after_authentication; -+} -+ - #define MAX_PACKETS (1U<<31) - static int - ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) -@@ -996,6 +1023,13 @@ - if (state->p_send.packets == 0 && state->p_read.packets == 0) - return 0; - -+ /* used to force rekeying when called for by the none -+ * cipher switch and aes-mt-ctr methods -cjr */ -+ if (rekey_requested == 1) { -+ rekey_requested = 0; -+ return 1; -+ } -+ - /* Time-based rekeying */ - if (state->rekey_interval != 0 && - (int64_t)state->rekey_time + state->rekey_interval <= monotime()) -@@ -1342,7 +1376,7 @@ - struct session_state *state = ssh->state; - int len, r, ms_remain = 0; - struct pollfd pfd; -- char buf[8192]; -+ char buf[SSH_IOBUFSZ]; - struct timeval start; - struct timespec timespec, *timespecp = NULL; - -@@ -1822,6 +1856,8 @@ - state->packet_discard -= rlen; - return 0; - } -+ -+ ssh->fdout_bytes += rlen; - return 0; - } - -@@ -1887,17 +1923,21 @@ - switch (r) { - case SSH_ERR_CONN_CLOSED: - ssh_packet_clear_keys(ssh); -+ sshpkt_final_log_entry(ssh); - logdie("Connection closed by %s", remote_id); - case SSH_ERR_CONN_TIMEOUT: - ssh_packet_clear_keys(ssh); -+ sshpkt_final_log_entry(ssh); - logdie("Connection %s %s timed out", - ssh->state->server_side ? "from" : "to", remote_id); - case SSH_ERR_DISCONNECTED: - ssh_packet_clear_keys(ssh); -+ sshpkt_final_log_entry(ssh); - logdie("Disconnected from %s", remote_id); - case SSH_ERR_SYSTEM_ERROR: - if (errno == ECONNRESET) { - ssh_packet_clear_keys(ssh); -+ sshpkt_final_log_entry(ssh); - logdie("Connection reset by %s", remote_id); - } - /* FALLTHROUGH */ -@@ -1939,6 +1979,24 @@ - logdie_f("should have exited"); - } - -+/* this prints out the final log entry */ -+void -+sshpkt_final_log_entry (struct ssh *ssh) { -+ double total_time; -+ -+ if (ssh->start_time < 1) -+ /* this will produce a NaN in the output. -cjr */ -+ total_time = 0; -+ else -+ total_time = monotime_double() - ssh->start_time; -+ -+ logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f", -+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -+ ssh->stdin_bytes, ssh->fdout_bytes, total_time, -+ ssh->stdin_bytes / total_time, -+ ssh->fdout_bytes / total_time); -+} -+ - /* - * Logs the error plus constructs and sends a disconnect packet, closes the - * connection, and exits. This function never returns. The error message -@@ -2008,6 +2066,7 @@ - return SSH_ERR_CONN_CLOSED; - if ((r = sshbuf_consume(state->output, len)) != 0) - return r; -+ ssh->stdin_bytes += len; - } - return 0; - } -@@ -2799,3 +2858,10 @@ - ssh->state->extra_pad = pad; - return 0; - } -+ -+/* need this for the moment for the aes-ctr cipher */ -+void * -+ssh_packet_get_send_context(struct ssh *ssh) -+{ -+ return ssh->state->send_context; -+} -diff -Nur openssh-9.3p1.orig/packet.h openssh-9.3p1/packet.h ---- openssh-9.3p1.orig/packet.h 2023-06-26 17:56:58.724634681 +0200 -+++ openssh-9.3p1/packet.h 2023-06-26 17:59:25.008036986 +0200 -@@ -86,6 +86,14 @@ - - /* APP data */ - void *app_data; -+ -+ /* logging data for ServerLogging patch*/ -+ double start_time; -+ u_long fdout_bytes; -+ u_long stdin_bytes; -+ -+ /* track that we are in a none cipher/mac state */ -+ int none; - }; - - typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, -@@ -157,6 +165,8 @@ - int ssh_packet_set_maxsize(struct ssh *, u_int); - u_int ssh_packet_get_maxsize(struct ssh *); - -+int packet_authentication_state(const struct ssh *); -+ - int ssh_packet_get_state(struct ssh *, struct sshbuf *); - int ssh_packet_set_state(struct ssh *, struct sshbuf *); - -@@ -171,6 +181,13 @@ - - void *ssh_packet_get_input(struct ssh *); - void *ssh_packet_get_output(struct ssh *); -+void *ssh_packet_get_receive_context(struct ssh *); -+void *ssh_packet_get_send_context(struct ssh *); -+ -+/* for forced packet rekeying post auth */ -+void packet_request_rekeying(void); -+/* final log entry support */ -+void sshpkt_final_log_entry (struct ssh *); - - /* new API */ - int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-9.3p1.orig/progressmeter.c openssh-9.3p1/progressmeter.c ---- openssh-9.3p1.orig/progressmeter.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/progressmeter.c 2023-07-05 10:45:57.895329810 +0200 -@@ -67,6 +67,8 @@ - static off_t start_pos; /* initial position of transfer */ - static off_t end_pos; /* ending position of transfer */ - static off_t cur_pos; /* transfer position as of last refresh */ -+static off_t last_pos; -+static off_t max_delta_pos = 0; - static volatile off_t *counter; /* progress counter */ - static long stalled; /* how long we have been stalled */ - static int bytes_per_second; /* current speed in bytes per second */ -@@ -133,6 +135,7 @@ - int cur_speed; - int hours, minutes, seconds; - int file_len, cols; -+ off_t delta_pos; - - if ((!force_update && !alarm_fired && !win_resized) || !can_output()) - return; -@@ -148,6 +151,10 @@ - now = monotime_double(); - bytes_left = end_pos - cur_pos; - -+ delta_pos = cur_pos - last_pos; -+ if (delta_pos > max_delta_pos) -+ max_delta_pos = delta_pos; -+ - if (bytes_left > 0) - elapsed = now - last_update; - else { -@@ -171,13 +178,14 @@ - bytes_per_second = cur_speed; - - last_update = now; -+ last_pos = cur_pos; - - /* Don't bother if we can't even display the completion percentage */ - if (win_size < 4) - return; - - /* filename */ -- file_len = cols = win_size - 36; -+ file_len = cols = win_size - 45; - if (file_len > 0) { - asmprintf(&buf, INT_MAX, &cols, "%-*s", file_len, file); - /* If we used fewer columns than expected then pad */ -@@ -194,6 +202,12 @@ - xextendf(&buf, NULL, " %3d%% %s %s/s ", percent, format_size(cur_pos), - format_rate((off_t)bytes_per_second)); - -+ /* instantaneous rate */ -+ if (bytes_left > 0) -+ xextendf(&buf, NULL, "%s/s ", format_rate(delta_pos)); -+ else -+ xextendf(&buf, NULL, "%s/s ", format_rate(max_delta_pos)); -+ - /* ETA */ - if (!transferred) - stalled += elapsed; -diff -Nur openssh-9.3p1.orig/readconf.c openssh-9.3p1/readconf.c ---- openssh-9.3p1.orig/readconf.c 2023-06-26 17:56:58.806634907 +0200 -+++ openssh-9.3p1/readconf.c 2023-06-26 17:59:25.011036994 +0200 -@@ -67,6 +67,7 @@ - #include "uidswap.h" - #include "myproposal.h" - #include "digest.h" -+#include "sshbuf.h" - #include "ssh-gss.h" - - /* Format of the configuration file: -@@ -169,6 +170,9 @@ - oHashKnownHosts, - oTunnel, oTunnelDevice, - oLocalCommand, oPermitLocalCommand, oRemoteCommand, -+ oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize, -+ oNoneEnabled, oNoneMacEnabled, oNoneSwitch, -+ oDisableMTAES, - oVisualHostKey, - oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, - oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, -@@ -314,6 +318,10 @@ - { "kexalgorithms", oKexAlgorithms }, - { "ipqos", oIPQoS }, - { "requesttty", oRequestTTY }, -+ { "noneenabled", oNoneEnabled }, -+ { "nonemacenabled", oNoneMacEnabled }, -+ { "noneswitch", oNoneSwitch }, -+ { "disablemtaes", oDisableMTAES }, - { "sessiontype", oSessionType }, - { "stdinnull", oStdinNull }, - { "forkafterauthentication", oForkAfterAuthentication }, -@@ -340,6 +348,11 @@ - { "rsaminsize", oRequiredRSASize }, /* alias */ - { "enableescapecommandline", oEnableEscapeCommandline }, - -+ { "tcprcvbufpoll", oTcpRcvBufPoll }, -+ { "tcprcvbuf", oTcpRcvBuf }, -+ { "hpndisabled", oHPNDisabled }, -+ { "hpnbuffersize", oHPNBufferSize }, -+ - { NULL, oBadOption } - }; - -@@ -1182,6 +1195,46 @@ - intptr = &options->check_host_ip; - goto parse_flag; - -+ case oHPNDisabled: -+ intptr = &options->hpn_disabled; -+ goto parse_flag; -+ -+ case oHPNBufferSize: -+ intptr = &options->hpn_buffer_size; -+ goto parse_int; -+ -+ case oTcpRcvBufPoll: -+ intptr = &options->tcp_rcv_buf_poll; -+ goto parse_flag; -+ -+ case oNoneEnabled: -+ intptr = &options->none_enabled; -+ goto parse_flag; -+ -+ case oNoneMacEnabled: -+ intptr = &options->nonemac_enabled; -+ goto parse_flag; -+ -+ case oDisableMTAES: -+ intptr = &options->disable_multithreaded; -+ goto parse_flag; -+ -+ /* -+ * We check to see if the command comes from the command -+ * line or not. If it does then enable it otherwise fail. -+ * NONE should never be a default configuration. -+ */ -+ case oNoneSwitch: -+ if (strcmp(filename, "command-line") == 0) { -+ intptr = &options->none_switch; -+ goto parse_flag; -+ } else { -+ error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); -+ error("Continuing..."); -+ debug("NoneSwitch directive found in %.200s.", filename); -+ return 0; -+ } -+ - case oVerifyHostKeyDNS: - intptr = &options->verify_host_key_dns; - multistate_ptr = multistate_yesnoask; -@@ -1436,6 +1489,10 @@ - *intptr = value; - break; - -+ case oTcpRcvBuf: -+ intptr = &options->tcp_rcv_buf; -+ goto parse_int; -+ - case oCiphers: - arg = argv_next(&ac, &av); - if (!arg || *arg == '\0') { -@@ -2476,6 +2533,14 @@ - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->request_tty = -1; -+ options->none_switch = -1; -+ options->none_enabled = -1; -+ options->nonemac_enabled = -1; -+ options->disable_multithreaded = -1; -+ options->hpn_disabled = -1; -+ options->hpn_buffer_size = -1; -+ options->tcp_rcv_buf_poll = -1; -+ options->tcp_rcv_buf = -1; - options->session_type = -1; - options->stdin_null = -1; - options->fork_after_authentication = -1; -@@ -2653,6 +2718,43 @@ - options->server_alive_interval = 0; - if (options->server_alive_count_max == -1) - options->server_alive_count_max = 3; -+ if (options->hpn_disabled == -1) -+ options->hpn_disabled = 0; -+ if (options->hpn_buffer_size > -1) { -+ /* if a user tries to set the size to 0 set it to 1KB */ -+ if (options->hpn_buffer_size == 0) -+ options->hpn_buffer_size = 1; -+ /* limit the buffer to SSHBUF_SIZE_MAX (currently 256MB) */ -+ if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) { -+ options->hpn_buffer_size = SSHBUF_SIZE_MAX; -+ debug("User requested buffer larger than 256MB. Request reverted to 256MB"); -+ } else -+ options->hpn_buffer_size *= 1024; -+ debug("hpn_buffer_size set to %d", options->hpn_buffer_size); -+ } -+ if (options->tcp_rcv_buf == 0) -+ options->tcp_rcv_buf = 1; -+ if (options->tcp_rcv_buf > -1) -+ options->tcp_rcv_buf *=1024; -+ if (options->tcp_rcv_buf_poll == -1) -+ options->tcp_rcv_buf_poll = 1; -+ if (options->none_switch == -1) -+ options->none_switch = 0; -+ if (options->none_enabled == -1) -+ options->none_enabled = 0; -+ if (options->none_enabled == 0 && options->none_switch > 0) { -+ fprintf(stderr, "NoneEnabled must be enabled to use the None Switch option. None cipher disabled.\n"); -+ options->none_enabled = 0; -+ } -+ if (options->nonemac_enabled == -1) -+ options->nonemac_enabled = 0; -+ if (options->nonemac_enabled > 0 && (options->none_enabled == 0 || -+ options->none_switch == 0)) { -+ fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); -+ options->nonemac_enabled = 0; -+ } -+ if (options->disable_multithreaded == -1) -+ options->disable_multithreaded = 0; - if (options->control_master == -1) - options->control_master = 0; - if (options->control_persist == -1) { -diff -Nur openssh-9.3p1.orig/readconf.h openssh-9.3p1/readconf.h ---- openssh-9.3p1.orig/readconf.h 2023-06-26 17:56:58.806634907 +0200 -+++ openssh-9.3p1/readconf.h 2023-06-26 17:59:25.012036996 +0200 -@@ -56,6 +56,10 @@ - int strict_host_key_checking; /* Strict host key checking. */ - int compression; /* Compress packets in both directions. */ - int tcp_keep_alive; /* Set SO_KEEPALIVE. */ -+ int tcp_rcv_buf; /* user switch to set tcp recv buffer */ -+ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ -+ int hpn_disabled; /* Switch to disable HPN buffer management */ -+ int hpn_buffer_size; /* User definable size for HPN buffer window */ - int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ - int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ - SyslogFacility log_facility; /* Facility for system logging. */ -@@ -127,7 +131,12 @@ - - int enable_ssh_keysign; - int64_t rekey_limit; -+ int none_switch; /* Use none cipher */ -+ int none_enabled; /* Allow none to be used */ -+ int nonemac_enabled; /* Allow none to be used */ -+ int disable_multithreaded; /*disable multithreaded aes-ctr*/ - int rekey_interval; -+ - int no_host_authentication_for_localhost; - int identities_only; - int server_alive_interval; -diff -Nur openssh-9.3p1.orig/regress/integrity.sh openssh-9.3p1/regress/integrity.sh ---- openssh-9.3p1.orig/regress/integrity.sh 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/regress/integrity.sh 2023-06-26 17:59:25.013036999 +0200 -@@ -21,6 +21,12 @@ - cmd="$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" sh ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy" - - for m in $macs; do -+ # the none mac is now valid but tests against it will succeed when we expect it to -+ # fail. so we need to explicity remove it from the list of macs returned. -+ if [ "$m" = "none" ]; then -+ continue -+ fi -+ - trace "test $tid: mac $m" - elen=0 - epad=0 -diff -Nur openssh-9.3p1.orig/sandbox-seccomp-filter.c openssh-9.3p1/sandbox-seccomp-filter.c ---- openssh-9.3p1.orig/sandbox-seccomp-filter.c 2023-06-26 17:56:58.742634731 +0200 -+++ openssh-9.3p1/sandbox-seccomp-filter.c 2023-06-26 17:59:25.013036999 +0200 -@@ -295,6 +295,9 @@ - #ifdef __NR_geteuid32 - SC_ALLOW(__NR_geteuid32), - #endif -+#ifdef __NR_getpeername /* not defined on archs that go via socketcall(2) */ -+ SC_ALLOW(__NR_getpeername), -+#endif - #ifdef __NR_getpgid - SC_ALLOW(__NR_getpgid), - #endif -@@ -413,6 +416,9 @@ - #ifdef __NR_sigprocmask - SC_ALLOW(__NR_sigprocmask), - #endif -+#ifdef __NR_socketcall -+ SC_ALLOW(__NR_socketcall), -+#endif - #ifdef __NR_time - SC_ALLOW(__NR_time), - #endif -diff -Nur openssh-9.3p1.orig/scp.c openssh-9.3p1/scp.c ---- openssh-9.3p1.orig/scp.c 2023-06-26 17:56:58.782634841 +0200 -+++ openssh-9.3p1/scp.c 2023-06-26 17:59:25.015037005 +0200 -@@ -1670,7 +1670,7 @@ - off_t size, statbytes; - unsigned long long ull; - int setimes, targisdir, wrerr; -- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; -+ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384], visbuf[16384]; - char **patterns = NULL; - size_t n, npatterns = 0; - struct timeval tv[2]; -diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c ---- openssh-9.3p1.orig/servconf.c 2023-06-26 17:56:58.807634910 +0200 -+++ openssh-9.3p1/servconf.c 2023-06-26 17:59:25.016037008 +0200 -@@ -70,6 +70,7 @@ - #include "auth.h" - #include "myproposal.h" - #include "digest.h" -+#include "sshbuf.h" - #include "ssh-gss.h" - - static void add_listen_addr(ServerOptions *, const char *, -@@ -200,6 +201,12 @@ - options->authorized_principals_file = NULL; - options->authorized_principals_command = NULL; - options->authorized_principals_command_user = NULL; -+ options->tcp_rcv_buf_poll = -1; -+ options->hpn_disabled = -1; -+ options->hpn_buffer_size = -1; -+ options->none_enabled = -1; -+ options->nonemac_enabled = -1; -+ options->disable_multithreaded = -1; - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->version_addendum = NULL; -@@ -294,6 +301,10 @@ - fill_default_server_options(ServerOptions *options) - { - u_int i; -+ /* needed for hpn socket tests */ -+ int sock; -+ int socksize; -+ int socksizelen = sizeof(int); - - /* Portable-specific options */ - if (options->use_pam == -1) -@@ -465,6 +476,51 @@ - } - if (options->permit_tun == -1) - options->permit_tun = SSH_TUNMODE_NO; -+ if (options->none_enabled == -1) -+ options->none_enabled = 0; -+ if (options->nonemac_enabled == -1) -+ options->nonemac_enabled = 0; -+ if (options->nonemac_enabled > 0 && options->none_enabled == 0) { -+ debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); -+ options->nonemac_enabled = 0; -+ } -+ if (options->disable_multithreaded == -1) -+ options->disable_multithreaded = 0; -+ if (options->hpn_disabled == -1) -+ options->hpn_disabled = 0; -+ -+ if (options->hpn_buffer_size == -1) { -+ /* option not explicitly set. Now we have to figure out */ -+ /* what value to use */ -+ if (options->hpn_disabled == 1) { -+ options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; -+ } else { -+ /* get the current RCV size and set it to that */ -+ /*create a socket but don't connect it */ -+ /* we use that the get the rcv socket size */ -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, -+ &socksize, &socksizelen); -+ close(sock); -+ options->hpn_buffer_size = socksize; -+ debug("HPN Buffer Size: %d", options->hpn_buffer_size); -+ } -+ } else { -+ /* we have to do this in case the user sets both values in a contradictory */ -+ /* manner. hpn_disabled overrrides hpn_buffer_size*/ -+ if (options->hpn_disabled <= 0) { -+ if (options->hpn_buffer_size == 0) -+ options->hpn_buffer_size = 1; -+ /* limit the maximum buffer to SSHBUF_SIZE_MAX (currently 256MB) */ -+ if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) { -+ options->hpn_buffer_size = SSHBUF_SIZE_MAX; -+ } else { -+ options->hpn_buffer_size *= 1024; -+ } -+ } else -+ options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT; -+ } -+ - if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_DSCP_AF21; - if (options->ip_qos_bulk == -1) -@@ -546,6 +602,9 @@ - sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, -+ sNoneEnabled, sNoneMacEnabled, -+ sDisableMTAES, -+ sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, - sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, - sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, - sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -747,6 +806,12 @@ - { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, - { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, - { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, -+ { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, -+ { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL }, -+ { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, -+ { "noneenabled", sNoneEnabled, SSHCFG_ALL }, -+ { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, -+ { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, - { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, - { "include", sInclude, SSHCFG_ALL }, - { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -809,6 +874,7 @@ - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) { -+ debug("Config token is %s", keywords[i].name); - *flags = keywords[i].flags; - return keywords[i].opcode; - } -@@ -1636,12 +1702,36 @@ - multistate_ptr = multistate_ignore_rhosts; - goto parse_multistate; - -+ case sTcpRcvBufPoll: -+ intptr = &options->tcp_rcv_buf_poll; -+ goto parse_flag; -+ -+ case sHPNDisabled: -+ intptr = &options->hpn_disabled; -+ goto parse_flag; -+ -+ case sHPNBufferSize: -+ intptr = &options->hpn_buffer_size; -+ goto parse_int; -+ - case sIgnoreUserKnownHosts: - intptr = &options->ignore_user_known_hosts; - parse_flag: - multistate_ptr = multistate_flag; - goto parse_multistate; - -+ case sNoneEnabled: -+ intptr = &options->none_enabled; -+ goto parse_flag; -+ -+ case sNoneMacEnabled: -+ intptr = &options->nonemac_enabled; -+ goto parse_flag; -+ -+ case sDisableMTAES: -+ intptr = &options->disable_multithreaded; -+ goto parse_flag; -+ - case sHostbasedAuthentication: - intptr = &options->hostbased_authentication; - goto parse_flag; -diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h ---- openssh-9.3p1.orig/servconf.h 2023-06-26 17:56:58.808634912 +0200 -+++ openssh-9.3p1/servconf.h 2023-06-26 17:59:25.017037010 +0200 -@@ -214,6 +214,13 @@ - int use_pam; /* Enable auth via PAM */ - int permit_pam_user_change; /* Allow PAM to change user name */ - -+ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ -+ int hpn_disabled; /* disable hpn functionality. false by default */ -+ int hpn_buffer_size; /* set the hpn buffer size - default 3MB */ -+ int none_enabled; /* Enable NONE cipher switch */ -+ int disable_multithreaded; /*disable multithreaded aes-ctr cipher */ -+ int nonemac_enabled; /* Enable NONE MAC switch */ -+ - int permit_tun; - - char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-9.3p1.orig/serverloop.c openssh-9.3p1/serverloop.c ---- openssh-9.3p1.orig/serverloop.c 2023-06-26 17:56:58.784634846 +0200 -+++ openssh-9.3p1/serverloop.c 2023-06-26 17:59:25.018037013 +0200 -@@ -347,6 +347,7 @@ - sigset_t bsigset, osigset; - - debug("Entering interactive session for SSH2."); -+ ssh->start_time = monotime_double(); - - if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) - error_f("bsigset setup: %s", strerror(errno)); -@@ -386,6 +387,7 @@ - - if (received_sigterm) { - logit("Exiting on signal %d", (int)received_sigterm); -+ sshpkt_final_log_entry(ssh); - /* Clean up sessions, utmp, etc. */ - cleanup_exit(255); - } -@@ -406,6 +408,9 @@ - /* free all channels, no more reads and writes */ - channel_free_all(ssh); - -+ /* final entry must come after channels close -cjr */ -+ sshpkt_final_log_entry(ssh); -+ - /* free remaining sessions, e.g. remove wtmp entries */ - session_destroy_all(ssh, NULL); - } -@@ -556,7 +561,8 @@ - debug("Tunnel forwarding using interface %s", ifname); - - c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, -- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); -+ options.hpn_disabled ? CHAN_TCP_WINDOW_DEFAULT : options.hpn_buffer_size, -+ CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); - c->datagram = 1; - #if defined(SSH_TUN_FILTER) - if (mode == SSH_TUNMODE_POINTOPOINT) -@@ -607,6 +613,8 @@ - c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, - -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, - 0, "server-session", 1); -+ if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled)) -+ c->dynamic_window = 1; - if (session_open(the_authctxt, c->self) != 1) { - debug("session open failed, free channel %d", c->self); - channel_free(ssh, c); -diff -Nur openssh-9.3p1.orig/session.c openssh-9.3p1/session.c ---- openssh-9.3p1.orig/session.c 2023-06-26 17:56:58.732634703 +0200 -+++ openssh-9.3p1/session.c 2023-07-05 10:50:50.184150123 +0200 -@@ -226,6 +226,7 @@ - goto authsock_err; - - /* Allocate a channel for the authentication agent socket. */ -+ /* this shouldn't matter if its hpn or not - cjr */ - nc = channel_new(ssh, "auth-listener", - SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -2369,7 +2370,8 @@ - channel_set_fds(ssh, s->chanid, - fdout, fdin, fderr, - ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, -- 1, is_tty, CHAN_SES_WINDOW_DEFAULT); -+ 1, is_tty, -+ options.hpn_disabled ? CHAN_SES_WINDOW_DEFAULT : options.hpn_buffer_size); - } - - /* -diff -Nur openssh-9.3p1.orig/sftp.1 openssh-9.3p1/sftp.1 ---- openssh-9.3p1.orig/sftp.1 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/sftp.1 2023-06-26 17:59:25.021037021 +0200 -@@ -299,7 +299,8 @@ - Specify how many requests may be outstanding at any one time. - Increasing this may slightly improve file transfer speed - but will increase memory usage. --The default is 64 outstanding requests. -+The default is 256 outstanding requests providing for 8MB -+of outstanding data with a 32KB buffer. - .It Fl r - Recursively copy entire directories when uploading and downloading. - Note that -diff -Nur openssh-9.3p1.orig/sftp-client.c openssh-9.3p1/sftp-client.c ---- openssh-9.3p1.orig/sftp-client.c 2023-06-26 17:56:58.702634621 +0200 -+++ openssh-9.3p1/sftp-client.c 2023-06-26 18:01:56.954454674 +0200 -@@ -72,7 +72,7 @@ - #define DEFAULT_COPY_BUFLEN 32768 - - /* Default number of concurrent xfer requests (fix sftp.1 scp.1 if changed) */ --#define DEFAULT_NUM_REQUESTS 64 -+#define DEFAULT_NUM_REQUESTS 256 - - /* Minimum amount of data to read at a time */ - #define MIN_READ_SIZE 512 -diff -Nur openssh-9.3p1.orig/ssh_api.c openssh-9.3p1/ssh_api.c ---- openssh-9.3p1.orig/ssh_api.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/ssh_api.c 2023-06-26 17:59:25.024037030 +0200 -@@ -410,7 +410,7 @@ - char *cp; - int r; - -- if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_VERSION)) != 0) -+ if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_RELEASE)) != 0) - return r; - if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) - return r; -diff -Nur openssh-9.3p1.orig/sshbuf.h openssh-9.3p1/sshbuf.h ---- openssh-9.3p1.orig/sshbuf.h 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/sshbuf.h 2023-06-26 17:59:25.024037030 +0200 -@@ -28,7 +28,7 @@ - # endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ - --#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ -+#define SSHBUF_SIZE_MAX 0xF000000 /* Hard maximum size 256MB */ - #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ - #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ - #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c ---- openssh-9.3p1.orig/ssh.c 2023-06-26 17:56:58.809634915 +0200 -+++ openssh-9.3p1/ssh.c 2023-06-26 17:59:25.025037033 +0200 -@@ -1069,6 +1069,10 @@ - break; - case 'T': - options.request_tty = REQUEST_TTY_NO; -+ /* ensure that the user doesn't try to backdoor a */ -+ /* null cipher switch on an interactive session */ -+ /* so explicitly disable it no matter what */ -+ options.none_switch=0; - break; - case 'o': - line = xstrdup(optarg); -@@ -1815,6 +1819,8 @@ - setproctitle("%s [mux]", options.control_path); - } - -+extern const EVP_CIPHER *evp_aes_ctr_mt(void); -+ - /* Do fork() after authentication. Used by "ssh -f" */ - static void - fork_postauth(void) -@@ -2132,6 +2138,79 @@ - NULL, fileno(stdin), command, environ); - } - -+static void -+hpn_options_init(struct ssh *ssh) -+{ -+ /* -+ * We need to check to see if what they want to do about buffer -+ * sizes here. In a hpn to nonhpn connection we want to limit -+ * the window size to something reasonable in case the far side -+ * has the large window bug. In hpn to hpn connection we want to -+ * use the max window size but allow the user to override it -+ * lastly if they disabled hpn then use the ssh std window size. -+ * -+ * So why don't we just do a getsockopt() here and set the -+ * ssh window to that? In the case of a autotuning receive -+ * window the window would get stuck at the initial buffer -+ * size generally less than 96k. Therefore we need to set the -+ * maximum ssh window size to the maximum hpn buffer size -+ * unless the user has specifically set the tcprcvbufpoll -+ * to no. In which case we *can* just set the window to the -+ * minimum of the hpn buffer size and tcp receive buffer size. -+ */ -+ -+ if (tty_flag) -+ options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; -+ else -+ options.hpn_buffer_size = 2 * 1024 * 1024; -+ -+ if (ssh->compat & SSH_BUG_LARGEWINDOW) { -+ debug("HPN to Non-HPN connection"); -+ } else { -+ debug("HPN to HPN connection"); -+ int sock, socksize; -+ socklen_t socksizelen; -+ if (options.tcp_rcv_buf_poll <= 0) { -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ socksizelen = sizeof(socksize); -+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, -+ &socksize, &socksizelen); -+ close(sock); -+ debug("socksize %d", socksize); -+ options.hpn_buffer_size = socksize; -+ debug("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size); -+ } else { -+ if (options.tcp_rcv_buf > 0) { -+ /* -+ * Create a socket but don't connect it: -+ * we use that the get the rcv socket size -+ */ -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ /* -+ * If they are using the tcp_rcv_buf option, -+ * attempt to set the buffer size to that. -+ */ -+ if (options.tcp_rcv_buf) { -+ socksizelen = sizeof(options.tcp_rcv_buf); -+ setsockopt(sock, SOL_SOCKET, SO_RCVBUF, -+ &options.tcp_rcv_buf, socksizelen); -+ } -+ socksizelen = sizeof(socksize); -+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, -+ &socksize, &socksizelen); -+ close(sock); -+ debug("socksize %d", socksize); -+ options.hpn_buffer_size = socksize; -+ debug("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size); -+ } -+ } -+ } -+ -+ debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); -+ -+ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); -+} -+ - /* open new channel for a session */ - static int - ssh_session2_open(struct ssh *ssh) -@@ -2150,9 +2229,11 @@ - if (in == -1 || out == -1 || err == -1) - fatal("dup() in/out/err failed"); - -- window = CHAN_SES_WINDOW_DEFAULT; -+ window = options.hpn_buffer_size; -+ - packetmax = CHAN_SES_PACKET_DEFAULT; - if (tty_flag) { -+ window = CHAN_SES_WINDOW_DEFAULT; - window >>= 1; - packetmax >>= 1; - } -@@ -2163,6 +2244,11 @@ - - debug3_f("channel_new: %d", c->self); - -+ if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) { -+ c->dynamic_window = 1; -+ debug("Enabled Dynamic Window Scaling"); -+ } -+ - channel_send_open(ssh, c->self); - if (options.session_type != SESSION_TYPE_NONE) - channel_register_open_confirm(ssh, c->self, -@@ -2177,6 +2263,13 @@ - int r, id = -1; - char *cp, *tun_fwd_ifname = NULL; - -+ /* -+ * We need to initialize this early because the forwarding logic below -+ * might open channels that use the hpn buffer sizes. We can't send a -+ * window of -1 (the default) to the server as it breaks things. -+ */ -+ hpn_options_init(ssh); -+ - /* XXX should be pre-session */ - if (!options.control_persist) - ssh_init_stdio_forwarding(ssh); -diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c ---- openssh-9.3p1.orig/sshconnect2.c 2023-06-26 17:56:58.811634921 +0200 -+++ openssh-9.3p1/sshconnect2.c 2023-07-05 04:58:43.822783207 +0200 -@@ -76,6 +76,7 @@ - #include "utf8.h" - #include "ssh-sk.h" - #include "sk-api.h" -+#include "myproposal.h" - - #ifdef GSSAPI - #include "ssh-gss.h" -@@ -85,6 +86,13 @@ - extern Options options; - - /* -+ * tty_flag is set in ssh.c. Use this in ssh_userauth2: -+ * if it is set, then prevent the switch to the null cipher. -+ */ -+ -+extern int tty_flag; -+ -+/* - * SSH2 key exchange - */ - -@@ -216,6 +224,8 @@ - return ret; - } - -+static char *myproposal[PROPOSAL_MAX]; -+static const char *myproposal_default[PROPOSAL_MAX] = { KEX_CLIENT }; - void - ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - const struct ssh_conn_info *cinfo) -@@ -229,6 +239,8 @@ - char *gss_host = NULL; - #endif - -+ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); -+ - xxx_host = host; - xxx_hostaddr = hostaddr; - xxx_conn_info = cinfo; -@@ -577,6 +589,53 @@ - - if (!authctxt.success) - fatal("Authentication failed."); -+ -+ /* -+ * If the user wants to use the none cipher and/or none mac, do it post authentication -+ * and only if the right conditions are met -- both of the NONE commands -+ * must be true and there must be no tty allocated. -+ */ -+ if (options.none_switch == 1 && options.none_enabled == 1) { -+ if (!tty_flag) { /* no null on tty sessions */ -+ debug("Requesting none rekeying..."); -+ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; -+ fprintf(stderr, "WARNING: ENABLED NONE CIPHER!!!\n"); -+ /* NONEMAC can only be used in context of the NONE CIPHER */ -+ if (options.nonemac_enabled == 1) { -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = "none"; -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = "none"; -+ fprintf(stderr, "WARNING: ENABLED NONE MAC\n"); -+ } -+ kex_prop2buf(ssh->kex->my, myproposal); -+ packet_request_rekeying(); -+ } else { -+ /* requested NONE cipher when in a tty */ -+ debug("Cannot switch to NONE cipher with tty allocated"); -+ fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); -+ } -+ } -+ -+#ifdef WITH_OPENSSL -+ if (options.disable_multithreaded == 0) { -+ /* if we are using aes-ctr there can be issues in either a fork or sandbox -+ * so the initial aes-ctr is defined to point to the original single process -+ * evp. After authentication we'll be past the fork and the sandboxed privsep -+ * so we repoint the define to the multithreaded evp. To start the threads we -+ * then force a rekey -+ */ -+ const void *cc = ssh_packet_get_send_context(ssh); -+ -+ /* only do this for the ctr cipher. otherwise gcm mode breaks. Don't know why though */ -+ if (strstr(cipher_ctx_name(cc), "ctr")) { -+ debug("Single to Multithread CTR cipher swap - client request"); -+ cipher_reset_multithreaded(); -+ packet_request_rekeying(); -+ } -+ } -+#endif -+ - if (ssh_packet_connection_is_on_socket(ssh)) { - verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-9.3p1.orig/sshconnect.c openssh-9.3p1/sshconnect.c ---- openssh-9.3p1.orig/sshconnect.c 2023-06-26 17:56:58.650634478 +0200 -+++ openssh-9.3p1/sshconnect.c 2023-06-26 17:59:25.028037041 +0200 -@@ -344,6 +344,30 @@ - #endif - - /* -+ * Set TCP receive buffer if requested. -+ * Note: tuning needs to happen after the socket is -+ * created but before the connection happens -+ * so winscale is negotiated properly -cjr -+ */ -+static void -+ssh_set_socket_recvbuf(int sock) -+{ -+ void *buf = (void *)&options.tcp_rcv_buf; -+ int sz = sizeof(options.tcp_rcv_buf); -+ int socksize; -+ int socksizelen = sizeof(int); -+ -+ debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf); -+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) { -+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen); -+ debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize); -+ } -+ else -+ error("Couldn't set socket receive buffer to %d: %.100s", -+ options.tcp_rcv_buf, strerror(errno)); -+} -+ -+/* - * Creates a socket for use as the ssh connection. - */ - static int -@@ -365,6 +389,9 @@ - } - (void)fcntl(sock, F_SETFD, FD_CLOEXEC); - -+ if (options.tcp_rcv_buf > 0) -+ ssh_set_socket_recvbuf(sock); -+ - /* Use interactive QOS (if specified) until authentication completed */ - if (options.ip_qos_interactive != INT_MAX) - set_sock_tos(sock, options.ip_qos_interactive); -diff -Nur openssh-9.3p1.orig/sshd.c openssh-9.3p1/sshd.c ---- openssh-9.3p1.orig/sshd.c 2023-06-26 17:56:58.812634923 +0200 -+++ openssh-9.3p1/sshd.c 2023-07-05 11:08:30.843125617 +0200 -@@ -1093,6 +1093,8 @@ - int ret, listen_sock; - struct addrinfo *ai; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; -+ int socksize; -+ int socksizelen = sizeof(int); - - for (ai = la->addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1138,6 +1140,11 @@ - - debug("Bind to port %s on %s.", strport, ntop); - -+ getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, -+ &socksize, &socksizelen); -+ debug("Server TCP RWIN socket size: %d", socksize); -+ debug("HPN Buffer Size: %d", options.hpn_buffer_size); -+ - /* Bind the socket to the desired port. */ - if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { - error("Bind to port %s on %s failed: %.200s.", -@@ -1876,6 +1883,19 @@ - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - -+ if (options.none_enabled == 1) { -+ char *old_ciphers = options.ciphers; -+ xasprintf(&options.ciphers, "%s,none", old_ciphers); -+ free(old_ciphers); -+ -+ /* only enable the none MAC in context of the none cipher -cjr */ -+ if (options.nonemac_enabled == 1) { -+ char *old_macs = options.macs; -+ xasprintf(&options.macs, "%s,none", old_macs); -+ free(old_macs); -+ } -+ } -+ - /* Check that options are sensible */ - if (options.authorized_keys_command_user == NULL && - (options.authorized_keys_command != NULL && -@@ -2359,6 +2379,9 @@ - rdomain == NULL ? "" : "\""); - free(laddr); - -+ /* set the HPN options for the child */ -+ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); -+ - /* - * We don't want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is -@@ -2471,6 +2494,25 @@ - /* Try to send all our hostkeys to the client */ - notify_hostkeys(ssh); - -+#ifdef WITH_OPENSSL -+ if (options.disable_multithreaded == 0) { -+ /* if we are using aes-ctr there can be issues in either a fork or sandbox -+ * so the initial aes-ctr is defined to point ot the original single process -+ * evp. After authentication we'll be past the fork and the sandboxed privsep -+ * so we repoint the define to the multithreaded evp. To start the threads we -+ * then force a rekey -+ */ -+ const void *cc = ssh_packet_get_send_context(the_active_state); -+ -+ /* only rekey if necessary. If we don't do this gcm mode cipher breaks */ -+ if (strstr(cipher_ctx_name(cc), "ctr")) { -+ debug("Single to Multithreaded CTR cipher swap - server request"); -+ cipher_reset_multithreaded(); -+ packet_request_rekeying(); -+ } -+ } -+#endif -+ - /* Start session. */ - do_authenticated(ssh, authctxt); - -@@ -2545,6 +2587,11 @@ - struct kex *kex; - int r; - -+ if (options.none_enabled == 1) -+ debug("WARNING: None cipher enabled"); -+ if (options.nonemac_enabled == 1) -+ debug("WARNING: None MAC enabled"); -+ - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -diff -Nur openssh-9.3p1.orig/sshd_config openssh-9.3p1/sshd_config ---- openssh-9.3p1.orig/sshd_config 2023-06-26 17:56:58.813634926 +0200 -+++ openssh-9.3p1/sshd_config 2023-06-26 17:59:25.030037046 +0200 -@@ -127,6 +127,28 @@ - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - -+# the following are HPN related configuration options -+# tcp receive buffer polling. disable in non autotuning kernels -+#TcpRcvBufPoll yes -+ -+# disable hpn performance boosts -+#HPNDisabled no -+ -+# buffer size for hpn to non-hpn connections -+#HPNBufferSize 2048 -+ -+# allow the use of the none cipher -+#NoneEnabled no -+ -+# allow the use of the none MAC -+#NoneMacEnabled no -+ -+# Disable MT-AES-CTR cipher on server -+# * needed for GSI-OpenSSH 7.4p1 because it's broken on the server side there -+# * useful for modern processors with AES-NI instructions making the stock -+# AES-CTR cipher faster than the MT-AES-CTR cipher -+DisableMTAES yes -+ - # Example of overriding settings on a per-user basis - #Match User anoncvs - # X11Forwarding no -diff -Nur openssh-9.3p1.orig/version.h openssh-9.3p1/version.h ---- openssh-9.3p1.orig/version.h 2023-06-26 17:56:58.814634929 +0200 -+++ openssh-9.3p1/version.h 2023-06-26 17:59:25.031037049 +0200 -@@ -16,5 +16,6 @@ - - #define SSH_PORTABLE "p1" - #define GSI_PORTABLE "c-GSI" -+#define SSH_HPN "-hpn15v2" - #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ -- GSI_VERSION KRB5_VERSION -+ GSI_VERSION SSH_HPN KRB5_VERSION diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch index 95d86c3..6a30485 100644 --- a/openssh-9.3p1-merged-openssl-evp.patch +++ b/openssh-9.3p1-merged-openssl-evp.patch @@ -659,15 +659,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # include -@@ -268,6 +271,10 @@ +@@ -266,6 +266,10 @@ const char *sshkey_ssh_name_plain(const struct sshkey *); - int sshkey_names_valid2(const char *, int); + int sshkey_names_valid2(const char *, int, 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 **); @@ -324,6 +331,13 @@ @@ -695,11 +695,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #if !defined(WITH_OPENSSL) # undef RSA # undef DSA -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.c openssh-9.3p1-patched/ssh-pkcs11.c ---- openssh-9.3p1/ssh-pkcs11.c 2023-06-06 15:53:36.592443989 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11.c 2023-06-06 15:52:25.626551768 +0200 -@@ -777,8 +777,24 @@ - +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +--- a/ssh-pkcs11.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.c (date 1703110934679) +@@ -620,8 +620,24 @@ + return (0); } + @@ -711,7 +711,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 0; +} #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -722,14 +722,14 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + /* remove trailing spaces. Note, that this does NOT guarantee the buffer * will be null terminated if there are no trailing spaces! */ - static void -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c ---- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200 -@@ -225,8 +225,36 @@ - static RSA_METHOD *helper_rsa; - #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - static EC_KEY_METHOD *helper_ecdsa; + static char * +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +--- a/ssh-pkcs11-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11-client.c (date 1703110830967) +@@ -402,8 +402,36 @@ + if (helper->nrsa == 0 && helper->nec == 0) + helper_terminate(helper); + } + +int +is_ecdsa_pkcs11(EC_KEY *ecdsa) @@ -744,8 +744,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 1; + return 0; +} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + #endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -762,14 +762,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + /* redirect private key crypto operations to the ssh-pkcs11-helper */ static void - wrap_key(struct sshkey *k) -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.h openssh-9.3p1-patched/ssh-pkcs11.h ---- openssh-9.3p1/ssh-pkcs11.h 2023-06-06 15:53:36.592443989 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11.h 2023-06-06 15:52:25.626551768 +0200 -@@ -39,6 +39,11 @@ - u_int32_t *); - #endif - + wrap_key(struct helper *helper, struct sshkey *k) +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +--- a/ssh-pkcs11.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.h (date 1703111023334) +@@ -38,6 +38,12 @@ + /* Only available in ssh-pkcs11-client.c so far */ + int pkcs11_make_cert(const struct sshkey *, + const struct sshkey *, struct sshkey **); ++ +#ifdef HAVE_EC_KEY_METHOD_NEW +int is_ecdsa_pkcs11(EC_KEY *ecdsa); +#endif diff --git a/openssh-9.3p1-openssl-compat.patch b/openssh-9.3p1-openssl-compat.patch deleted file mode 100644 index cf512ef..0000000 --- a/openssh-9.3p1-openssl-compat.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- openssh-9.3p1/openbsd-compat/openssl-compat.c 2023-03-15 22:28:19.000000000 +0100 -+++ /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat/openssl-compat.c 2023-05-25 14:19:42.870841944 +0200 -@@ -33,10 +33,10 @@ - - /* - * OpenSSL version numbers: MNNFFPPS: major minor fix patch status -- * We match major, minor, fix and status (not patch) for <1.0.0. -- * After that, we acceptable compatible fix versions (so we -- * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed -- * within a patch series. -+ * Versions >=3 require only major versions to match. -+ * For versions <3, we accept compatible fix versions (so we allow 1.0.1 -+ * to work with 1.0.0). Going backwards is only allowed within a patch series. -+ * See https://www.openssl.org/policies/releasestrat.html - */ - - int -@@ -48,15 +48,17 @@ - if (headerver == libver) - return 1; - -- /* for versions < 1.0.0, major,minor,fix,status must match */ -- if (headerver < 0x1000000f) { -- mask = 0xfffff00fL; /* major,minor,fix,status */ -+ /* -+ * For versions >= 3.0, only the major and status must match. -+ */ -+ if (headerver >= 0x3000000f) { -+ mask = 0xf000000fL; /* major,status */ - return (headerver & mask) == (libver & mask); - } - - /* -- * For versions >= 1.0.0, major,minor,status must match and library -- * fix version must be equal to or newer than the header. -+ * For versions >= 1.0.0, but <3, major,minor,status must match and -+ * library fix version must be equal to or newer than the header. - */ - mask = 0xfff0000fL; /* major,minor,status */ - hfix = (headerver & 0x000ff000) >> 12; diff --git a/openssh-9.3p1-upstream-cve-2023-38408.patch b/openssh-9.3p1-upstream-cve-2023-38408.patch deleted file mode 100644 index e9ac2ae..0000000 --- a/openssh-9.3p1-upstream-cve-2023-38408.patch +++ /dev/null @@ -1,130 +0,0 @@ -diff --git a/ssh-agent.c b/ssh-agent.c -index 618bb198..8ea831f4 100644 -diff -up openssh-9.3p1/ssh-agent.c.cve openssh-9.3p1/ssh-agent.c ---- openssh-9.3p1/ssh-agent.c.cve 2023-07-21 15:38:13.237276580 +0200 -+++ openssh-9.3p1/ssh-agent.c 2023-07-21 15:41:30.269943569 +0200 -@@ -169,6 +169,12 @@ char socket_dir[PATH_MAX]; - /* Pattern-list of allowed PKCS#11/Security key paths */ - static char *allowed_providers; - -+/* -+ * Allows PKCS11 providers or SK keys that use non-internal providers to -+ * be added over a remote connection (identified by session-bind@openssh.com). -+ */ -+static int remote_add_provider; -+ - /* locking */ - #define LOCK_SIZE 32 - #define LOCK_SALT_SIZE 16 -@@ -1228,6 +1234,12 @@ process_add_identity(SocketEntry *e) - if (strcasecmp(sk_provider, "internal") == 0) { - debug_f("internal provider"); - } else { -+ if (e->nsession_ids != 0 && !remote_add_provider) { -+ verbose("failed add of SK provider \"%.100s\": " -+ "remote addition of providers is disabled", -+ sk_provider); -+ goto out; -+ } - if (realpath(sk_provider, canonical_provider) == NULL) { - verbose("failed provider \"%.100s\": " - "realpath: %s", sk_provider, -@@ -1368,7 +1380,7 @@ no_identities(SocketEntry *e) - - #ifdef ENABLE_PKCS11 - static char * --sanitize_pkcs11_provider(const char *provider) -+sanitize_pkcs11_provider(SocketEntry *e, const char *provider) - { - struct pkcs11_uri *uri = NULL; - char *sane_uri, *module_path = NULL; /* default path */ -@@ -1399,6 +1411,11 @@ sanitize_pkcs11_provider(const char *pro - module_path = strdup(provider); /* simple path */ - - if (module_path != NULL) { /* do not validate default NULL path in URI */ -+ if (e->nsession_ids != 0 && !remote_add_provider) { -+ verbose("failed PKCS#11 add of \"%.100s\": remote addition of " -+ "providers is disabled", provider); -+ return NULL; -+ } - if (realpath(module_path, canonical_provider) == NULL) { - verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", - module_path, strerror(errno)); -@@ -1455,7 +1472,7 @@ process_add_smartcard_key(SocketEntry *e - goto send; - } - -- sane_uri = sanitize_pkcs11_provider(provider); -+ sane_uri = sanitize_pkcs11_provider(e, provider); - if (sane_uri == NULL) - goto send; - -@@ -1516,7 +1533,7 @@ process_remove_smartcard_key(SocketEntry - } - free(pin); - -- sane_uri = sanitize_pkcs11_provider(provider); -+ sane_uri = sanitize_pkcs11_provider(e, provider); - if (sane_uri == NULL) - goto send; - -@@ -2108,7 +2125,9 @@ main(int ac, char **av) - break; - case 'O': - if (strcmp(optarg, "no-restrict-websafe") == 0) -- restrict_websafe = 0; -+ restrict_websafe = 0; -+ else if (strcmp(optarg, "allow-remote-pkcs11") == 0) -+ remote_add_provider = 1; - else - fatal("Unknown -O option"); - break; -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 6be647ec..ebddf6c3 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -1537,10 +1537,8 @@ pkcs11_register_provider(char *provider_id, char *pin, - error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } -- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { -- error("dlsym(C_GetFunctionList) failed: %s", dlerror()); -- goto fail; -- } -+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) -+ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); - - p->module->handle = handle; - /* setup the pkcs11 callbacks */ ---- a/ssh-agent.1 2023-03-15 22:28:19.000000000 +0100 -+++ b/ssh-agent.1 2023-07-19 21:39:17.981406432 +0200 -@@ -107,9 +107,27 @@ - .It Fl O Ar option - Specify an option when starting - .Nm . --Currently only one option is supported: -+Currently two options are supported: -+.Cm allow-remote-pkcs11 -+and - .Cm no-restrict-websafe . --This instructs -+.Pp -+The -+.Cm allow-remote-pkcs11 -+option allows clients of a forwarded -+.Nm -+to load PKCS#11 or FIDO provider libraries. -+By default only local clients may perform this operation. -+Note that signalling that a -+.Nm -+client remote is performed by -+.Xr ssh 1 , -+and use of other tools to forward access to the agent socket may circumvent -+this restriction. -+.Pp -+The -+.Cm no-restrict-websafe , -+instructs - .Nm - to permit signatures using FIDO keys that might be web authentication - requests. diff --git a/openssh-9.6p1-cve-2024-6387.patch b/openssh-9.6p1-cve-2024-6387.patch new file mode 100644 index 0000000..646cf7c --- /dev/null +++ b/openssh-9.6p1-cve-2024-6387.patch @@ -0,0 +1,35 @@ +diff --git a/log.c b/log.c +index 9fc1a2e2e..191ff4a5a 100644 +--- a/log.c ++++ b/log.c +@@ -451,12 +451,14 @@ void + sshsigdie(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, ...) + { ++#ifdef SYSLOG_R_SAFE_IN_SIGHAND + va_list args; + + va_start(args, fmt); + sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL, + suffix, fmt, args); + va_end(args); ++#endif + _exit(1); + } + +diff --git a/clientloop.c b/clientloop.c +index 8ec36af94..6dcd6c853 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -608,8 +608,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, + if (timespeccmp(&now, &chaff_until, >=)) { + /* Stop if there have been no keystrokes for a while */ + stop_reason = "chaff time expired"; +- } else if (timespeccmp(&now, &next_interval, >=)) { +- /* Otherwise if we were due to send, then send chaff */ ++ } else if (timespeccmp(&now, &next_interval, >=) && ++ !ssh_packet_have_data_to_write(ssh)) { ++ /* If due to send but have no data, then send chaff */ + if (send_chaff(ssh)) + nchaff++; + } diff --git a/openssh-9.3p1-gsissh.patch b/openssh-9.6p1-gsissh.patch similarity index 88% rename from openssh-9.3p1-gsissh.patch rename to openssh-9.6p1-gsissh.patch index acf160d..4929e40 100644 --- a/openssh-9.3p1-gsissh.patch +++ b/openssh-9.6p1-gsissh.patch @@ -1,7 +1,7 @@ -diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c ---- openssh-9.3p1.orig/auth2.c 2023-06-26 17:34:46.576956191 +0200 -+++ openssh-9.3p1/auth2.c 2023-06-26 17:36:05.807175554 +0200 -@@ -275,7 +275,28 @@ +diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c +--- openssh-9.6p1.orig/auth2.c 2024-07-06 07:19:36.958049782 +0200 ++++ openssh-9.6p1/auth2.c 2024-07-06 07:20:29.705200575 +0200 +@@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) goto out; @@ -31,7 +31,7 @@ diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -288,11 +309,33 @@ +@@ -299,11 +320,33 @@ if (authctxt->attempt >= 1024) auth_maxtries_exceeded(ssh); @@ -69,7 +69,7 @@ diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); } else { -@@ -300,6 +343,9 @@ +@@ -311,6 +354,9 @@ /* Invalid user, fake password information */ authctxt->pw = fakepw(); } @@ -79,7 +79,7 @@ diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(ssh)); -@@ -308,6 +354,7 @@ +@@ -319,6 +365,7 @@ authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); @@ -87,7 +87,7 @@ diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -323,9 +370,10 @@ +@@ -336,9 +383,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -101,10 +101,10 @@ diff -Nur openssh-9.3p1.orig/auth2.c openssh-9.3p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c ---- openssh-9.3p1.orig/auth2-gss.c 2023-06-26 17:34:46.462955875 +0200 -+++ openssh-9.3p1/auth2-gss.c 2023-06-26 17:36:05.808175557 +0200 -@@ -50,6 +50,7 @@ +diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c +--- openssh-9.6p1.orig/auth2-gss.c 2024-07-06 07:19:36.850049473 +0200 ++++ openssh-9.6p1/auth2-gss.c 2024-07-06 07:20:29.705200575 +0200 +@@ -52,6 +52,7 @@ extern ServerOptions options; @@ -112,7 +112,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); 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); -@@ -63,8 +64,8 @@ +@@ -65,8 +66,8 @@ { Authctxt *authctxt = ssh->authctxt; int r, authenticated = 0; @@ -123,7 +123,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c u_char *p; size_t len; -@@ -75,6 +76,9 @@ +@@ -77,6 +78,9 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -133,7 +133,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c mic.value = p; mic.length = len; -@@ -85,13 +89,29 @@ +@@ -87,13 +91,29 @@ fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); @@ -166,7 +166,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -146,7 +166,9 @@ +@@ -152,7 +172,9 @@ return (0); } @@ -177,7 +177,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c debug2_f("disabled because of invalid user"); free(doid); return (0); -@@ -184,7 +206,7 @@ +@@ -190,7 +212,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -186,7 +186,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c u_char *p; size_t len; int r; -@@ -205,6 +227,7 @@ +@@ -211,6 +233,7 @@ free(p); if (GSS_ERROR(maj_status)) { @@ -194,7 +194,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c if (send_tok.length != 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || -@@ -279,6 +302,34 @@ +@@ -285,6 +308,34 @@ return 0; } @@ -229,7 +229,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -289,12 +340,14 @@ +@@ -295,12 +346,14 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -245,7 +245,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -303,8 +356,11 @@ +@@ -309,8 +362,11 @@ if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); @@ -259,7 +259,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -356,11 +412,17 @@ +@@ -362,11 +418,17 @@ fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); @@ -281,7 +281,7 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c sshbuf_free(b); if (micuser != authctxt->user) -@@ -380,6 +442,26 @@ +@@ -386,6 +448,26 @@ return 0; } @@ -308,9 +308,9 @@ diff -Nur openssh-9.3p1.orig/auth2-gss.c openssh-9.3p1/auth2-gss.c Authmethod method_gsskeyex = { "gssapi-keyex", NULL, -diff -Nur openssh-9.3p1.orig/auth.c openssh-9.3p1/auth.c ---- openssh-9.3p1.orig/auth.c 2023-06-26 17:34:46.577956193 +0200 -+++ openssh-9.3p1/auth.c 2023-06-26 17:36:05.808175557 +0200 +diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c +--- openssh-9.6p1.orig/auth.c 2024-07-06 07:19:36.958049782 +0200 ++++ openssh-9.6p1/auth.c 2024-07-06 07:20:29.706200578 +0200 @@ -299,7 +299,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -341,9 +341,9 @@ diff -Nur openssh-9.3p1.orig/auth.c openssh-9.3p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-9.3p1.orig/auth.h openssh-9.3p1/auth.h ---- openssh-9.3p1.orig/auth.h 2023-06-26 17:34:46.578956196 +0200 -+++ openssh-9.3p1/auth.h 2023-06-26 17:36:05.809175560 +0200 +diff -Nur openssh-9.6p1.orig/auth.h openssh-9.6p1/auth.h +--- openssh-9.6p1.orig/auth.h 2024-07-06 07:19:36.959049785 +0200 ++++ openssh-9.6p1/auth.h 2024-07-06 07:20:29.706200578 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -353,9 +353,9 @@ diff -Nur openssh-9.3p1.orig/auth.h openssh-9.3p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-9.3p1.orig/auth-pam.c openssh-9.3p1/auth-pam.c ---- openssh-9.3p1.orig/auth-pam.c 2023-06-26 17:34:46.562956152 +0200 -+++ openssh-9.3p1/auth-pam.c 2023-06-26 17:45:46.130781404 +0200 +diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c +--- openssh-9.6p1.orig/auth-pam.c 2024-07-06 07:19:36.944049742 +0200 ++++ openssh-9.6p1/auth-pam.c 2024-07-06 07:20:29.707200580 +0200 @@ -252,6 +252,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; @@ -487,7 +487,7 @@ diff -Nur openssh-9.3p1.orig/auth-pam.c openssh-9.3p1/auth-pam.c } if (sshpam_rhost != NULL) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); -@@ -1094,6 +1174,18 @@ +@@ -1096,6 +1176,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -506,7 +506,7 @@ diff -Nur openssh-9.3p1.orig/auth-pam.c openssh-9.3p1/auth-pam.c if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1382,6 +1474,9 @@ +@@ -1384,6 +1476,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -516,9 +516,9 @@ diff -Nur openssh-9.3p1.orig/auth-pam.c openssh-9.3p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-9.3p1.orig/auth-pam.h openssh-9.3p1/auth-pam.h ---- openssh-9.3p1.orig/auth-pam.h 2023-06-26 17:34:46.430955786 +0200 -+++ openssh-9.3p1/auth-pam.h 2023-06-26 17:36:05.812175568 +0200 +diff -Nur openssh-9.6p1.orig/auth-pam.h openssh-9.6p1/auth-pam.h +--- openssh-9.6p1.orig/auth-pam.h 2024-07-06 07:19:36.818049382 +0200 ++++ openssh-9.6p1/auth-pam.h 2024-07-06 07:20:29.708200583 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -526,9 +526,9 @@ diff -Nur openssh-9.3p1.orig/auth-pam.h openssh-9.3p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-9.3p1.orig/canohost.c openssh-9.3p1/canohost.c ---- openssh-9.3p1.orig/canohost.c 2023-06-26 17:34:46.463955878 +0200 -+++ openssh-9.3p1/canohost.c 2023-06-26 17:36:05.812175568 +0200 +diff -Nur openssh-9.6p1.orig/canohost.c openssh-9.6p1/canohost.c +--- openssh-9.6p1.orig/canohost.c 2024-07-06 07:19:36.850049473 +0200 ++++ openssh-9.6p1/canohost.c 2024-07-06 07:20:29.708200583 +0200 @@ -17,6 +17,7 @@ #include #include @@ -537,7 +537,7 @@ diff -Nur openssh-9.3p1.orig/canohost.c openssh-9.3p1/canohost.c #include #include -@@ -298,3 +299,33 @@ +@@ -300,3 +301,33 @@ { return get_sock_port(sock, 1); } @@ -571,9 +571,9 @@ diff -Nur openssh-9.3p1.orig/canohost.c openssh-9.3p1/canohost.c + } + } +} -diff -Nur openssh-9.3p1.orig/canohost.h openssh-9.3p1/canohost.h ---- openssh-9.3p1.orig/canohost.h 2023-06-26 17:34:46.463955878 +0200 -+++ openssh-9.3p1/canohost.h 2023-06-26 17:36:05.813175570 +0200 +diff -Nur openssh-9.6p1.orig/canohost.h openssh-9.6p1/canohost.h +--- openssh-9.6p1.orig/canohost.h 2024-07-06 07:19:36.850049473 +0200 ++++ openssh-9.6p1/canohost.h 2024-07-06 07:20:29.709200586 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -581,10 +581,10 @@ diff -Nur openssh-9.3p1.orig/canohost.h openssh-9.3p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-9.3p1.orig/configure.ac openssh-9.3p1/configure.ac ---- openssh-9.3p1.orig/configure.ac 2023-06-26 17:34:46.553956127 +0200 -+++ openssh-9.3p1/configure.ac 2023-06-26 17:36:05.814175573 +0200 -@@ -4858,6 +4858,14 @@ +diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac +--- openssh-9.6p1.orig/configure.ac 2024-07-06 07:19:36.936049719 +0200 ++++ openssh-9.6p1/configure.ac 2024-07-06 07:20:29.710200589 +0200 +@@ -4865,6 +4865,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -599,9 +599,9 @@ diff -Nur openssh-9.3p1.orig/configure.ac openssh-9.3p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4899,6 +4907,40 @@ - AC_SUBST([K5LIBS]) - AC_SUBST([CHANNELLIBS]) +@@ -4930,6 +4938,40 @@ + ) + +# Check whether the user wants GSI (Globus) support +gsi="no" @@ -637,12 +637,12 @@ diff -Nur openssh-9.3p1.orig/configure.ac openssh-9.3p1/configure.ac + AC_CHECK_FUNCS(globus_gss_assist_map_and_authorize) +fi + - # Check whether user wants systemd support - SYSTEMD_MSG="no" - AC_ARG_WITH(systemd, -diff -Nur openssh-9.3p1.orig/gss-genr.c openssh-9.3p1/gss-genr.c ---- openssh-9.3p1.orig/gss-genr.c 2023-06-26 17:34:46.623956321 +0200 -+++ openssh-9.3p1/gss-genr.c 2023-06-26 17:36:05.815175576 +0200 + # Looking for programs, paths and files + + PRIVSEP_PATH=/var/empty +diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c +--- openssh-9.6p1.orig/gss-genr.c 2024-07-06 07:19:37.001049905 +0200 ++++ openssh-9.6p1/gss-genr.c 2024-07-06 07:20:29.711200592 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -679,9 +679,9 @@ diff -Nur openssh-9.3p1.orig/gss-genr.c openssh-9.3p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-9.3p1.orig/gss-serv.c openssh-9.3p1/gss-serv.c ---- openssh-9.3p1.orig/gss-serv.c 2023-06-26 17:34:46.483955933 +0200 -+++ openssh-9.3p1/gss-serv.c 2023-06-26 17:36:05.816175578 +0200 +diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c +--- openssh-9.6p1.orig/gss-serv.c 2024-07-06 07:19:36.870049530 +0200 ++++ openssh-9.6p1/gss-serv.c 2024-07-06 07:20:29.712200595 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -962,9 +962,9 @@ diff -Nur openssh-9.3p1.orig/gss-serv.c openssh-9.3p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-9.3p1.orig/gss-serv-gsi.c openssh-9.3p1/gss-serv-gsi.c ---- openssh-9.3p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.3p1/gss-serv-gsi.c 2023-06-26 17:36:05.816175578 +0200 +diff -Nur openssh-9.6p1.orig/gss-serv-gsi.c openssh-9.6p1/gss-serv-gsi.c +--- openssh-9.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/gss-serv-gsi.c 2024-07-06 07:20:29.712200595 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1294,9 +1294,9 @@ diff -Nur openssh-9.3p1.orig/gss-serv-gsi.c openssh-9.3p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-9.3p1.orig/gss-serv-krb5.c openssh-9.3p1/gss-serv-krb5.c ---- openssh-9.3p1.orig/gss-serv-krb5.c 2023-06-26 17:34:46.506955997 +0200 -+++ openssh-9.3p1/gss-serv-krb5.c 2023-06-26 17:36:05.817175581 +0200 +diff -Nur openssh-9.6p1.orig/gss-serv-krb5.c openssh-9.6p1/gss-serv-krb5.c +--- openssh-9.6p1.orig/gss-serv-krb5.c 2024-07-06 07:19:36.892049593 +0200 ++++ openssh-9.6p1/gss-serv-krb5.c 2024-07-06 07:20:29.713200598 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1350,9 +1350,9 @@ diff -Nur openssh-9.3p1.orig/gss-serv-krb5.c openssh-9.3p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-9.3p1.orig/kexgsss.c openssh-9.3p1/kexgsss.c ---- openssh-9.3p1.orig/kexgsss.c 2023-06-26 17:34:46.634956351 +0200 -+++ openssh-9.3p1/kexgsss.c 2023-06-26 17:36:05.817175581 +0200 +diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c +--- openssh-9.6p1.orig/kexgsss.c 2024-07-06 07:19:36.855049488 +0200 ++++ openssh-9.6p1/kexgsss.c 2024-07-06 07:20:29.713200598 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1416,9 +1416,9 @@ diff -Nur openssh-9.3p1.orig/kexgsss.c openssh-9.3p1/kexgsss.c + } +} #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-9.3p1.orig/Makefile.in openssh-9.3p1/Makefile.in ---- openssh-9.3p1.orig/Makefile.in 2023-06-26 17:34:46.580956202 +0200 -+++ openssh-9.3p1/Makefile.in 2023-06-26 17:36:05.818175584 +0200 +diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in +--- openssh-9.6p1.orig/Makefile.in 2024-07-06 07:19:36.961049790 +0200 ++++ openssh-9.6p1/Makefile.in 2024-07-06 07:20:29.713200598 +0200 @@ -130,6 +130,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1427,10 +1427,10 @@ diff -Nur openssh-9.3p1.orig/Makefile.in openssh-9.3p1/Makefile.in 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 \ -diff -Nur openssh-9.3p1.orig/misc.c openssh-9.3p1/misc.c ---- openssh-9.3p1.orig/misc.c 2023-06-26 17:34:46.625956326 +0200 -+++ openssh-9.3p1/misc.c 2023-06-26 17:36:05.819175586 +0200 -@@ -393,11 +393,14 @@ +diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c +--- openssh-9.6p1.orig/misc.c 2024-07-06 07:19:37.002049908 +0200 ++++ openssh-9.6p1/misc.c 2024-07-06 07:20:29.714200600 +0200 +@@ -419,11 +419,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1446,7 +1446,7 @@ diff -Nur openssh-9.3p1.orig/misc.c openssh-9.3p1/misc.c int wspace = 0; if (*s == NULL) -@@ -405,6 +408,21 @@ +@@ -431,6 +434,21 @@ old = *s; @@ -1468,7 +1468,7 @@ diff -Nur openssh-9.3p1.orig/misc.c openssh-9.3p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -480,6 +498,20 @@ +@@ -506,6 +524,20 @@ return copy; } @@ -1489,10 +1489,10 @@ diff -Nur openssh-9.3p1.orig/misc.c openssh-9.3p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-9.3p1.orig/misc.h openssh-9.3p1/misc.h ---- openssh-9.3p1.orig/misc.h 2023-06-26 17:34:46.526956052 +0200 -+++ openssh-9.3p1/misc.h 2023-06-26 17:36:05.820175589 +0200 -@@ -100,6 +100,7 @@ +diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h +--- openssh-9.6p1.orig/misc.h 2024-07-06 07:19:36.911049648 +0200 ++++ openssh-9.6p1/misc.h 2024-07-06 07:20:29.715200603 +0200 +@@ -103,6 +103,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1500,10 +1500,10 @@ diff -Nur openssh-9.3p1.orig/misc.h openssh-9.3p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c ---- openssh-9.3p1.orig/monitor.c 2023-06-26 17:34:46.625956326 +0200 -+++ openssh-9.3p1/monitor.c 2023-06-26 17:36:05.821175592 +0200 -@@ -152,6 +152,9 @@ +diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c +--- openssh-9.6p1.orig/monitor.c 2024-07-06 07:19:37.002049908 +0200 ++++ openssh-9.6p1/monitor.c 2024-07-06 07:20:29.716200606 +0200 +@@ -149,6 +149,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1513,7 +1513,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -204,7 +207,7 @@ +@@ -201,7 +204,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1522,7 +1522,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -212,7 +215,7 @@ +@@ -209,7 +212,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1531,7 +1531,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -236,8 +239,11 @@ +@@ -233,8 +236,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1544,7 +1544,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c #endif {0, 0, NULL} }; -@@ -247,6 +253,8 @@ +@@ -244,6 +250,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1553,7 +1553,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -327,6 +335,8 @@ +@@ -324,6 +332,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1562,7 +1562,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -451,6 +461,8 @@ +@@ -453,6 +463,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1571,7 +1571,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -779,14 +791,17 @@ +@@ -781,14 +793,17 @@ debug3_f("entering"); @@ -1592,7 +1592,7 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2142,6 +2157,79 @@ +@@ -2144,6 +2159,79 @@ } int @@ -1672,9 +1672,9 @@ diff -Nur openssh-9.3p1.orig/monitor.c openssh-9.3p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-9.3p1.orig/monitor.h openssh-9.3p1/monitor.h ---- openssh-9.3p1.orig/monitor.h 2023-06-26 17:34:46.581956204 +0200 -+++ openssh-9.3p1/monitor.h 2023-06-26 17:36:05.821175592 +0200 +diff -Nur openssh-9.6p1.orig/monitor.h openssh-9.6p1/monitor.h +--- openssh-9.6p1.orig/monitor.h 2024-07-06 07:19:36.962049793 +0200 ++++ openssh-9.6p1/monitor.h 2024-07-06 07:20:29.716200606 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1686,10 +1686,10 @@ diff -Nur openssh-9.3p1.orig/monitor.h openssh-9.3p1/monitor.h }; struct ssh; -diff -Nur openssh-9.3p1.orig/monitor_wrap.c openssh-9.3p1/monitor_wrap.c ---- openssh-9.3p1.orig/monitor_wrap.c 2023-06-26 17:34:46.626956329 +0200 -+++ openssh-9.3p1/monitor_wrap.c 2023-06-26 17:36:05.822175594 +0200 -@@ -1085,6 +1085,94 @@ +diff -Nur openssh-9.6p1.orig/monitor_wrap.c openssh-9.6p1/monitor_wrap.c +--- openssh-9.6p1.orig/monitor_wrap.c 2024-07-06 07:19:36.968049810 +0200 ++++ openssh-9.6p1/monitor_wrap.c 2024-07-06 07:20:29.716200606 +0200 +@@ -1083,6 +1083,94 @@ return (authenticated); } @@ -1784,9 +1784,9 @@ diff -Nur openssh-9.3p1.orig/monitor_wrap.c openssh-9.3p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-9.3p1.orig/monitor_wrap.h openssh-9.3p1/monitor_wrap.h ---- openssh-9.3p1.orig/monitor_wrap.h 2023-06-26 17:34:46.588956224 +0200 -+++ openssh-9.3p1/monitor_wrap.h 2023-06-26 17:36:05.823175597 +0200 +diff -Nur openssh-9.6p1.orig/monitor_wrap.h openssh-9.6p1/monitor_wrap.h +--- openssh-9.6p1.orig/monitor_wrap.h 2024-07-06 07:19:36.968049810 +0200 ++++ openssh-9.6p1/monitor_wrap.h 2024-07-06 07:20:29.717200609 +0200 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1798,10 +1798,10 @@ diff -Nur openssh-9.3p1.orig/monitor_wrap.h openssh-9.3p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-9.3p1.orig/readconf.c openssh-9.3p1/readconf.c ---- openssh-9.3p1.orig/readconf.c 2023-06-26 17:34:46.627956332 +0200 -+++ openssh-9.3p1/readconf.c 2023-06-26 17:36:05.824175600 +0200 -@@ -2554,11 +2554,11 @@ +diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c +--- openssh-9.6p1.orig/readconf.c 2024-07-06 07:19:37.004049913 +0200 ++++ openssh-9.6p1/readconf.c 2024-07-06 07:20:29.718200612 +0200 +@@ -2723,11 +2723,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1816,10 +1816,10 @@ diff -Nur openssh-9.3p1.orig/readconf.c openssh-9.3p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-9.3p1.orig/readconf.h openssh-9.3p1/readconf.h ---- openssh-9.3p1.orig/readconf.h 2023-06-26 17:34:46.470955897 +0200 -+++ openssh-9.3p1/readconf.h 2023-06-26 17:36:05.825175603 +0200 -@@ -79,6 +79,8 @@ +diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h +--- openssh-9.6p1.orig/readconf.h 2024-07-06 07:19:36.858049496 +0200 ++++ openssh-9.6p1/readconf.h 2024-07-06 07:20:29.718200612 +0200 +@@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1828,10 +1828,10 @@ diff -Nur openssh-9.3p1.orig/readconf.h openssh-9.3p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c ---- openssh-9.3p1.orig/servconf.c 2023-06-26 17:34:46.628956335 +0200 -+++ openssh-9.3p1/servconf.c 2023-06-26 17:36:05.826175605 +0200 -@@ -93,6 +93,7 @@ +diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c +--- openssh-9.6p1.orig/servconf.c 2024-07-06 07:19:37.004049913 +0200 ++++ openssh-9.6p1/servconf.c 2024-07-06 07:20:29.719200615 +0200 +@@ -92,6 +92,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1839,7 +1839,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -139,9 +140,11 @@ +@@ -138,9 +139,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1851,7 +1851,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -295,6 +298,8 @@ +@@ -294,6 +297,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1860,7 +1860,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -376,13 +381,17 @@ +@@ -375,13 +380,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1880,7 +1880,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -529,7 +538,7 @@ +@@ -528,7 +537,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1889,7 +1889,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -548,6 +557,9 @@ +@@ -547,6 +556,9 @@ sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1899,7 +1899,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -581,8 +593,10 @@ +@@ -580,8 +592,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1910,7 +1910,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -635,8 +649,15 @@ +@@ -634,8 +648,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1926,7 +1926,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -644,8 +665,11 @@ +@@ -643,8 +664,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1938,7 +1938,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -717,6 +741,8 @@ +@@ -716,6 +740,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1947,7 +1947,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1450,6 +1476,10 @@ +@@ -1418,6 +1444,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1958,7 +1958,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1696,6 +1726,10 @@ +@@ -1669,6 +1699,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1969,7 +1969,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1704,6 +1738,10 @@ +@@ -1677,6 +1711,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1980,7 +1980,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1724,6 +1762,12 @@ +@@ -1697,6 +1735,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1993,7 +1993,7 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2776,6 +2820,7 @@ +@@ -2806,6 +2850,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2001,10 +2001,10 @@ diff -Nur openssh-9.3p1.orig/servconf.c openssh-9.3p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h ---- openssh-9.3p1.orig/servconf.h 2023-06-26 17:34:46.519956033 +0200 -+++ openssh-9.3p1/servconf.h 2023-06-26 17:36:05.827175608 +0200 -@@ -146,9 +146,12 @@ +diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h +--- openssh-9.6p1.orig/servconf.h 2024-07-06 07:19:36.904049628 +0200 ++++ openssh-9.6p1/servconf.h 2024-07-06 07:20:29.719200615 +0200 +@@ -144,9 +144,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2017,7 +2017,7 @@ diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -209,6 +212,7 @@ +@@ -207,6 +210,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -2025,10 +2025,10 @@ diff -Nur openssh-9.3p1.orig/servconf.h openssh-9.3p1/servconf.h int permit_tun; -diff -Nur openssh-9.3p1.orig/ssh.1 openssh-9.3p1/ssh.1 ---- openssh-9.3p1.orig/ssh.1 2023-06-26 17:34:46.606956274 +0200 -+++ openssh-9.3p1/ssh.1 2023-06-26 17:36:05.828175611 +0200 -@@ -1514,6 +1514,18 @@ +diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 +--- openssh-9.6p1.orig/ssh.1 2024-07-06 07:19:36.983049853 +0200 ++++ openssh-9.6p1/ssh.1 2024-07-06 07:20:29.720200618 +0200 +@@ -1528,6 +1528,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2047,10 +2047,10 @@ diff -Nur openssh-9.3p1.orig/ssh.1 openssh-9.3p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c ---- openssh-9.3p1.orig/ssh.c 2023-06-26 17:34:46.630956340 +0200 -+++ openssh-9.3p1/ssh.c 2023-06-26 17:36:05.829175614 +0200 -@@ -571,6 +571,38 @@ +diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c +--- openssh-9.6p1.orig/ssh.c 2024-07-06 07:19:36.977049836 +0200 ++++ openssh-9.6p1/ssh.c 2024-07-06 07:20:29.720200618 +0200 +@@ -573,6 +573,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2089,7 +2089,7 @@ diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1251,8 +1283,12 @@ +@@ -1299,8 +1331,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2103,9 +2103,9 @@ diff -Nur openssh-9.3p1.orig/ssh.c openssh-9.3p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-9.3p1.orig/ssh_config openssh-9.3p1/ssh_config ---- openssh-9.3p1.orig/ssh_config 2023-06-26 17:34:46.473955906 +0200 -+++ openssh-9.3p1/ssh_config 2023-06-26 17:36:05.830175617 +0200 +diff -Nur openssh-9.6p1.orig/ssh_config openssh-9.6p1/ssh_config +--- openssh-9.6p1.orig/ssh_config 2024-07-06 07:19:36.860049502 +0200 ++++ openssh-9.6p1/ssh_config 2024-07-06 07:20:29.721200620 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2118,10 +2118,10 @@ diff -Nur openssh-9.3p1.orig/ssh_config openssh-9.3p1/ssh_config +# GSSAPIKeyExchange yes # GSSAPITrustDNS no # BatchMode no - # CheckHostIP yes -diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 ---- openssh-9.3p1.orig/ssh_config.5 2023-06-26 17:34:46.544956102 +0200 -+++ openssh-9.3p1/ssh_config.5 2023-06-26 17:36:05.831175620 +0200 + # CheckHostIP no +diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1.orig/ssh_config.5 2024-07-06 07:19:36.928049696 +0200 ++++ openssh-9.6p1/ssh_config.5 2024-07-06 07:20:29.721200620 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2135,7 +2135,7 @@ diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -832,7 +838,7 @@ +@@ -921,7 +927,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2144,7 +2144,7 @@ diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -840,12 +846,12 @@ +@@ -929,12 +935,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2159,7 +2159,7 @@ diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1471,7 +1477,7 @@ +@@ -1582,7 +1588,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2168,10 +2168,10 @@ diff -Nur openssh-9.3p1.orig/ssh_config.5 openssh-9.3p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c ---- openssh-9.3p1.orig/sshconnect2.c 2023-06-26 17:34:46.619956310 +0200 -+++ openssh-9.3p1/sshconnect2.c 2023-06-26 17:36:05.832175622 +0200 -@@ -861,6 +861,11 @@ +diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c +--- openssh-9.6p1.orig/sshconnect2.c 2024-07-06 07:19:36.995049888 +0200 ++++ openssh-9.6p1/sshconnect2.c 2024-07-06 07:20:29.722200623 +0200 +@@ -863,6 +863,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2183,7 +2183,7 @@ diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -972,7 +977,8 @@ +@@ -971,7 +976,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2193,7 +2193,7 @@ diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1139,6 +1145,20 @@ +@@ -1138,6 +1144,20 @@ return r; } @@ -2214,7 +2214,7 @@ diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1161,6 +1181,12 @@ +@@ -1160,6 +1180,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2227,7 +2227,7 @@ diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1174,7 +1200,9 @@ +@@ -1173,7 +1199,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2238,9 +2238,9 @@ diff -Nur openssh-9.3p1.orig/sshconnect2.c openssh-9.3p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-9.3p1.orig/sshd.8 openssh-9.3p1/sshd.8 ---- openssh-9.3p1.orig/sshd.8 2023-06-26 17:34:46.488955947 +0200 -+++ openssh-9.3p1/sshd.8 2023-06-26 17:36:05.833175625 +0200 +diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 +--- openssh-9.6p1.orig/sshd.8 2024-07-06 07:19:36.875049545 +0200 ++++ openssh-9.6p1/sshd.8 2024-07-06 07:20:29.722200623 +0200 @@ -839,6 +839,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2271,9 +2271,9 @@ diff -Nur openssh-9.3p1.orig/sshd.8 openssh-9.3p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-9.3p1.orig/sshd.c openssh-9.3p1/sshd.c ---- openssh-9.3p1.orig/sshd.c 2023-06-26 17:34:46.631956343 +0200 -+++ openssh-9.3p1/sshd.c 2023-06-26 17:36:05.835175630 +0200 +diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c +--- openssh-9.6p1.orig/sshd.c 2024-07-06 07:19:37.006049919 +0200 ++++ openssh-9.6p1/sshd.c 2024-07-06 07:20:29.723200626 +0200 @@ -2438,7 +2438,7 @@ #endif @@ -2283,9 +2283,9 @@ diff -Nur openssh-9.3p1.orig/sshd.c openssh-9.3p1/sshd.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-9.3p1.orig/sshd_config openssh-9.3p1/sshd_config ---- openssh-9.3p1.orig/sshd_config 2023-06-26 17:34:46.508956002 +0200 -+++ openssh-9.3p1/sshd_config 2023-06-26 17:36:05.835175630 +0200 +diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config +--- openssh-9.6p1.orig/sshd_config 2024-07-06 07:19:36.894049599 +0200 ++++ openssh-9.6p1/sshd_config 2024-07-06 07:20:29.723200626 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2311,9 +2311,9 @@ diff -Nur openssh-9.3p1.orig/sshd_config openssh-9.3p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-9.3p1.orig/sshd_config.5 openssh-9.3p1/sshd_config.5 ---- openssh-9.3p1.orig/sshd_config.5 2023-06-26 17:34:46.545956105 +0200 -+++ openssh-9.3p1/sshd_config.5 2023-06-26 17:36:05.836175633 +0200 +diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 +--- openssh-9.6p1.orig/sshd_config.5 2024-07-06 07:19:36.928049696 +0200 ++++ openssh-9.6p1/sshd_config.5 2024-07-06 07:20:29.724200629 +0200 @@ -716,15 +716,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2372,10 +2372,10 @@ diff -Nur openssh-9.3p1.orig/sshd_config.5 openssh-9.3p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-9.3p1.orig/sshd_config_redhat openssh-9.3p1/sshd_config_redhat ---- openssh-9.3p1.orig/sshd_config_redhat 2023-06-26 17:34:46.457955861 +0200 -+++ openssh-9.3p1/sshd_config_redhat 2023-06-26 17:36:05.837175636 +0200 -@@ -9,9 +9,6 @@ +diff -Nur openssh-9.6p1.orig/sshd_config_redhat openssh-9.6p1/sshd_config_redhat +--- openssh-9.6p1.orig/sshd_config_redhat 2024-07-06 07:19:36.845049459 +0200 ++++ openssh-9.6p1/sshd_config_redhat 2024-07-06 07:20:29.724200629 +0200 +@@ -2,9 +2,6 @@ ChallengeResponseAuthentication no @@ -2385,9 +2385,9 @@ diff -Nur openssh-9.3p1.orig/sshd_config_redhat openssh-9.3p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-9.3p1.orig/ssh-gss.h openssh-9.3p1/ssh-gss.h ---- openssh-9.3p1.orig/ssh-gss.h 2023-06-26 17:34:46.486955941 +0200 -+++ openssh-9.3p1/ssh-gss.h 2023-06-26 17:36:05.837175636 +0200 +diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h +--- openssh-9.6p1.orig/ssh-gss.h 2024-07-06 07:19:36.873049539 +0200 ++++ openssh-9.6p1/ssh-gss.h 2024-07-06 07:20:29.724200629 +0200 @@ -97,12 +97,14 @@ } ssh_gssapi_ccache; @@ -2423,12 +2423,12 @@ diff -Nur openssh-9.3p1.orig/ssh-gss.h openssh-9.3p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-9.3p1.orig/version.h openssh-9.3p1/version.h ---- openssh-9.3p1.orig/version.h 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1/version.h 2023-06-26 17:36:05.838175639 +0200 +diff -Nur openssh-9.6p1.orig/version.h openssh-9.6p1/version.h +--- openssh-9.6p1.orig/version.h 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/version.h 2024-07-06 07:20:29.725200632 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_9.3" + #define SSH_VERSION "OpenSSH_9.6" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-9.6p1-hpn-18.3.1.patch b/openssh-9.6p1-hpn-18.3.1.patch new file mode 100644 index 0000000..e9a43f8 --- /dev/null +++ b/openssh-9.6p1-hpn-18.3.1.patch @@ -0,0 +1,14718 @@ +diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c +--- openssh-9.6p1.orig/auth2.c 2024-07-10 13:32:39.592111791 +0200 ++++ openssh-9.6p1/auth2.c 2024-07-10 13:38:36.540172663 +0200 +@@ -52,6 +52,8 @@ + #include "dispatch.h" + #include "pathnames.h" + #include "ssherr.h" ++#include "canohost.h" ++ + #ifdef GSSAPI + #include "ssh-gss.h" + #endif +@@ -75,6 +77,8 @@ + extern Authmethod method_gssapi; + #endif + ++static int log_flag = 0; ++ + Authmethod *authmethods[] = { + &method_none, + &method_pubkey, +@@ -104,6 +108,9 @@ + #define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */ + static int list_starts_with(const char *, const char *, const char *); + ++/* read the user banner from the path in sshd_config ++ * this isn't to read it on the client side but to read ++ * it into what we are going to send on the server side */ + char * + auth2_read_banner(void) + { +@@ -308,6 +315,11 @@ + + debug("userauth-request for user %s service %s method %s", + user[0] ? user : "", service, method); ++ if (!log_flag) { ++ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), user); ++ log_flag = 1; ++ } + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + + #ifdef WITH_SELINUX +diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +--- openssh-9.6p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/binn.c 2024-07-10 13:34:02.707358556 +0200 +@@ -0,0 +1,3496 @@ ++#include ++#include ++#include ++#include ++#include ++#include "binn.h" ++ ++#define UNUSED(x) (void)(x) ++#define roundval(dbl) dbl >= 0.0 ? (int)(dbl + 0.5) : ((dbl - (double)(int)dbl) <= -0.5 ? (int)dbl : (int)(dbl - 0.5)) ++ ++#define BINN_MAGIC 0x1F22B11F ++ ++#define MAX_BINN_HEADER 9 ++#define MIN_BINN_SIZE 3 ++#define CHUNK_SIZE 256 ++ ++#define BINN_STRUCT 1 ++#define BINN_BUFFER 2 ++ ++void* (*malloc_fn)(size_t len) = 0; ++void* (*realloc_fn)(void *ptr, size_t len) = 0; ++void (*free_fn)(void *ptr) = 0; ++ ++/***************************************************************************/ ++ ++#if defined(__alpha__) || defined(__hppa__) || defined(__mips__) || defined(__powerpc__) || defined(__sparc__) ++#define BINN_ONLY_ALIGNED_ACCESS ++#elif ( defined(__arm__) || defined(__aarch64__) ) && !defined(__ARM_FEATURE_UNALIGNED) ++#define BINN_ONLY_ALIGNED_ACCESS ++#endif ++ ++#if defined(_WIN32) ++#define BIG_ENDIAN 0x1000 ++#define LITTLE_ENDIAN 0x0001 ++#define BYTE_ORDER LITTLE_ENDIAN ++#elif defined(__APPLE__) ++/* macros already defined */ ++#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) ++#include ++#elif defined(_AIX) ++#include ++#else ++#include ++#endif ++ ++#ifndef BYTE_ORDER ++#error "BYTE_ORDER not defined" ++#endif ++#ifndef BIG_ENDIAN ++#error "BIG_ENDIAN not defined" ++#endif ++#ifndef LITTLE_ENDIAN ++#error "LITTLE_ENDIAN not defined" ++#endif ++#if BIG_ENDIAN == LITTLE_ENDIAN ++#error "BIG_ENDIAN == LITTLE_ENDIAN" ++#endif ++#if BYTE_ORDER!=BIG_ENDIAN && BYTE_ORDER!=LITTLE_ENDIAN ++#error "BYTE_ORDER not supported" ++#endif ++ ++typedef unsigned short int u16; ++typedef unsigned int u32; ++typedef unsigned long long int u64; ++ ++BINN_PRIVATE void copy_be16(u16 *pdest, u16 *psource) { ++#if BYTE_ORDER == LITTLE_ENDIAN ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ dest[0] = source[1]; ++ dest[1] = source[0]; ++#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#ifdef BINN_ONLY_ALIGNED_ACCESS ++ if ((uintptr_t)psource % 2 == 0){ /* address aligned to 16 bit */ ++ *pdest = *psource; ++ } else { ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ dest[0] = source[0]; /* indexes are the same */ ++ dest[1] = source[1]; ++ } ++#else ++ *pdest = *psource; ++#endif ++#endif ++} ++ ++BINN_PRIVATE void copy_be32(u32 *pdest, u32 *psource) { ++#if BYTE_ORDER == LITTLE_ENDIAN ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ dest[0] = source[3]; ++ dest[1] = source[2]; ++ dest[2] = source[1]; ++ dest[3] = source[0]; ++#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#ifdef BINN_ONLY_ALIGNED_ACCESS ++ if ((uintptr_t)psource % 4 == 0){ /* address aligned to 32 bit */ ++ *pdest = *psource; ++ } else { ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ dest[0] = source[0]; /* indexes are the same */ ++ dest[1] = source[1]; ++ dest[2] = source[2]; ++ dest[3] = source[3]; ++ } ++#else ++ *pdest = *psource; ++#endif ++#endif ++} ++ ++BINN_PRIVATE void copy_be64(u64 *pdest, u64 *psource) { ++#if BYTE_ORDER == LITTLE_ENDIAN ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ int i; ++ for (i=0; i < 8; i++) { ++ dest[i] = source[7-i]; ++ } ++#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#ifdef BINN_ONLY_ALIGNED_ACCESS ++ if ((uintptr_t)psource % 8 == 0){ /* address aligned to 64 bit */ ++ *pdest = *psource; ++ } else { ++ unsigned char *source = (unsigned char *) psource; ++ unsigned char *dest = (unsigned char *) pdest; ++ int i; ++ for (i=0; i < 8; i++) { ++ dest[i] = source[i]; /* indexes are the same */ ++ } ++ } ++#else ++ *pdest = *psource; ++#endif ++#endif ++} ++ ++/***************************************************************************/ ++ ++#ifndef _MSC_VER ++#define stricmp strcasecmp ++#define strnicmp strncasecmp ++#endif ++ ++BINN_PRIVATE BOOL IsValidBinnHeader(void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize); ++ ++/***************************************************************************/ ++ ++char * APIENTRY binn_version() { ++ return BINN_VERSION; ++} ++ ++/***************************************************************************/ ++ ++void APIENTRY binn_set_alloc_functions(void* (*new_malloc)(size_t), void* (*new_realloc)(void*,size_t), void (*new_free)(void*)) { ++ ++ malloc_fn = new_malloc; ++ realloc_fn = new_realloc; ++ free_fn = new_free; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE void check_alloc_functions() { ++ ++ if (malloc_fn == 0) malloc_fn = &malloc; ++ if (realloc_fn == 0) realloc_fn = &realloc; ++ if (free_fn == 0) free_fn = &free; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE void * binn_malloc(int size) { ++ check_alloc_functions(); ++ return malloc_fn(size); ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE void * binn_memdup(void *src, int size) { ++ void *dest; ++ ++ if (src == NULL || size <= 0) return NULL; ++ dest = binn_malloc(size); ++ if (dest == NULL) return NULL; ++ memcpy(dest, src, size); ++ return dest; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE size_t strlen2(char *str) { ++ ++ if (str == NULL) return 0; ++ return strlen(str); ++ ++} ++ ++/***************************************************************************/ ++ ++int APIENTRY binn_create_type(int storage_type, int data_type_index) { ++ if (data_type_index < 0) return -1; ++ if ((storage_type < BINN_STORAGE_MIN) || (storage_type > BINN_STORAGE_MAX)) return -1; ++ if (data_type_index < 16) ++ return storage_type | data_type_index; ++ else if (data_type_index < 4096) { ++ storage_type |= BINN_STORAGE_HAS_MORE; ++ storage_type <<= 8; ++ data_type_index >>= 4; ++ return storage_type | data_type_index; ++ } else ++ return -1; ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_get_type_info(int long_type, int *pstorage_type, int *pextra_type) { ++ int storage_type, extra_type; ++ BOOL retval=TRUE; ++ ++again: ++ ++ if (long_type < 0) { ++ goto loc_invalid; ++ } else if (long_type <= 0xff) { ++ storage_type = long_type & BINN_STORAGE_MASK; ++ extra_type = long_type & BINN_TYPE_MASK; ++ } else if (long_type <= 0xffff) { ++ storage_type = long_type & BINN_STORAGE_MASK16; ++ storage_type >>= 8; ++ extra_type = long_type & BINN_TYPE_MASK16; ++ extra_type >>= 4; ++ } else if (long_type & BINN_STORAGE_VIRTUAL) { ++ /* storage_type = BINN_STORAGE_VIRTUAL; */ ++ /* extra_type = xxx; */ ++ long_type &= 0xffff; ++ goto again; ++ } else { ++loc_invalid: ++ storage_type = -1; ++ extra_type = -1; ++ retval = FALSE; ++ } ++ ++ if (pstorage_type) *pstorage_type = storage_type; ++ if (pextra_type) *pextra_type = extra_type; ++ ++ return retval; ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_create(binn *item, int type, int size, void *pointer) { ++ BOOL retval=FALSE; ++ ++ switch (type) { ++ case BINN_LIST: ++ case BINN_MAP: ++ case BINN_OBJECT: ++ break; ++ default: ++ goto loc_exit; ++ } ++ ++ if ((item == NULL) || (size < 0)) goto loc_exit; ++ if (size < MIN_BINN_SIZE) { ++ if (pointer) goto loc_exit; ++ else size = 0; ++ } ++ ++ memset(item, 0, sizeof(binn)); ++ ++ if (pointer) { ++ item->pre_allocated = TRUE; ++ item->pbuf = pointer; ++ item->alloc_size = size; ++ } else { ++ item->pre_allocated = FALSE; ++ if (size == 0) size = CHUNK_SIZE; ++ pointer = binn_malloc(size); ++ if (pointer == 0) return INVALID_BINN; ++ item->pbuf = pointer; ++ item->alloc_size = size; ++ } ++ ++ item->header = BINN_MAGIC; ++ /* item->allocated = FALSE; -- already zeroed */ ++ item->writable = TRUE; ++ item->used_size = MAX_BINN_HEADER; /* save space for the header */ ++ item->type = type; ++ /* item->count = 0; -- already zeroed */ ++ item->dirty = TRUE; /* the header is not written to the buffer */ ++ ++ retval = TRUE; ++ ++loc_exit: ++ return retval; ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_new(int type, int size, void *pointer) { ++ binn *item; ++ ++ item = (binn*) binn_malloc(sizeof(binn)); ++ ++ if (binn_create(item, type, size, pointer) == FALSE) { ++ free_fn(item); ++ return NULL; ++ } ++ ++ item->allocated = TRUE; ++ return item; ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_create_list(binn *list) { ++ ++ return binn_create(list, BINN_LIST, 0, NULL); ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_create_map(binn *map) { ++ ++ return binn_create(map, BINN_MAP, 0, NULL); ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_create_object(binn *object) { ++ ++ return binn_create(object, BINN_OBJECT, 0, NULL); ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_list() { ++ return binn_new(BINN_LIST, 0, 0); ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_map() { ++ return binn_new(BINN_MAP, 0, 0); ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_object() { ++ return binn_new(BINN_OBJECT, 0, 0); ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_copy(void *old) { ++ int type, count, size, header_size; ++ unsigned char *old_ptr = binn_ptr(old); ++ binn *item; ++ ++ size = 0; ++ if (!IsValidBinnHeader(old_ptr, &type, &count, &size, &header_size)) return NULL; ++ ++ item = binn_new(type, size - header_size + MAX_BINN_HEADER, NULL); ++ if( item ){ ++ unsigned char *dest; ++ dest = ((unsigned char *) item->pbuf) + MAX_BINN_HEADER; ++ memcpy(dest, old_ptr + header_size, size - header_size); ++ item->used_size = MAX_BINN_HEADER + size - header_size; ++ item->count = count; ++ } ++ return item; ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_load(void *data, binn *value) { ++ ++ if ((data == NULL) || (value == NULL)) return FALSE; ++ memset(value, 0, sizeof(binn)); ++ value->header = BINN_MAGIC; ++ /* value->allocated = FALSE; -- already zeroed */ ++ /* value->writable = FALSE; */ ++ ++ if (binn_is_valid(data, &value->type, &value->count, &value->size) == FALSE) return FALSE; ++ value->ptr = data; ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++binn * APIENTRY binn_open(void *data) { ++ binn *item; ++ ++ item = (binn*) binn_malloc(sizeof(binn)); ++ ++ if (binn_load(data, item) == FALSE) { ++ free_fn(item); ++ return NULL; ++ } ++ ++ item->allocated = TRUE; ++ return item; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int binn_get_ptr_type(void *ptr) { ++ ++ if (ptr == NULL) return 0; ++ ++ switch (*(unsigned int *)ptr) { ++ case BINN_MAGIC: ++ return BINN_STRUCT; ++ default: ++ return BINN_BUFFER; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_is_struct(void *ptr) { ++ ++ if (ptr == NULL) return FALSE; ++ ++ if ((*(unsigned int *)ptr) == BINN_MAGIC) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int CalcAllocation(int needed_size, int alloc_size) { ++ int calc_size; ++ ++ calc_size = alloc_size; ++ while (calc_size < needed_size) { ++ calc_size <<= 1; /* same as *= 2 */ ++ /* calc_size += CHUNK_SIZE; -- this is slower than the above line, because there are more reallocations */ ++ } ++ return calc_size; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL CheckAllocation(binn *item, int add_size) { ++ int alloc_size; ++ void *ptr; ++ ++ if (item->used_size + add_size > item->alloc_size) { ++ if (item->pre_allocated) return FALSE; ++ alloc_size = CalcAllocation(item->used_size + add_size, item->alloc_size); ++ ptr = realloc_fn(item->pbuf, alloc_size); ++ if (ptr == NULL) return FALSE; ++ item->pbuf = ptr; ++ item->alloc_size = alloc_size; ++ } ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++#if BYTE_ORDER == BIG_ENDIAN ++ ++BINN_PRIVATE int get_storage_size(int storage_type) { ++ ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ return 0; ++ case BINN_STORAGE_BYTE: ++ return 1; ++ case BINN_STORAGE_WORD: ++ return 2; ++ case BINN_STORAGE_DWORD: ++ return 4; ++ case BINN_STORAGE_QWORD: ++ return 8; ++ default: ++ return 0; ++ } ++ ++} ++ ++#endif ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE unsigned char * AdvanceDataPos(unsigned char *p, unsigned char *plimit) { ++ unsigned char byte; ++ int storage_type, DataSize; ++ ++ if (p > plimit) return 0; ++ ++ byte = *p; p++; ++ storage_type = byte & BINN_STORAGE_MASK; ++ if (byte & BINN_STORAGE_HAS_MORE) p++; ++ ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ /* p += 0; */ ++ break; ++ case BINN_STORAGE_BYTE: ++ p ++; ++ break; ++ case BINN_STORAGE_WORD: ++ p += 2; ++ break; ++ case BINN_STORAGE_DWORD: ++ p += 4; ++ break; ++ case BINN_STORAGE_QWORD: ++ p += 8; ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ if (p > plimit) return 0; ++ DataSize = *((unsigned char*)p); ++ if (DataSize & 0x80) { ++ if (p + sizeof(int) - 1 > plimit) return 0; ++ copy_be32((u32*)&DataSize, (u32*)p); ++ DataSize &= 0x7FFFFFFF; ++ p+=4; ++ } else { ++ p++; ++ } ++ p += DataSize; ++ if (storage_type == BINN_STORAGE_STRING) { ++ p++; /* null terminator. */ ++ } ++ break; ++ case BINN_STORAGE_CONTAINER: ++ if (p > plimit) return 0; ++ DataSize = *((unsigned char*)p); ++ if (DataSize & 0x80) { ++ if (p + sizeof(int) - 1 > plimit) return 0; ++ copy_be32((u32*)&DataSize, (u32*)p); ++ DataSize &= 0x7FFFFFFF; ++ } ++ DataSize--; /* remove the type byte already added before */ ++ p += DataSize; ++ break; ++ default: ++ return 0; ++ } ++ ++ if (p > plimit) return 0; ++ ++ return p; ++ ++} ++ ++/***************************************************************************/ ++ ++/* ++ ++The id can be stored with 1 to 5 bytes ++ ++S = signal bit ++X = bit part of id ++ ++ 0SXX XXXX ++ 100S XXXX + 1 byte ++ 101S XXXX + 2 bytes ++ 110S XXXX + 3 bytes ++ 1110 0000 + 4 bytes ++ ++*/ ++BINN_PRIVATE int read_map_id(unsigned char **pp, unsigned char *plimit) { ++ unsigned char *p, c, sign, type; ++ int id, extra_bytes; ++ ++ p = *pp; ++ ++ c = *p++; ++ ++ if (c & 0x80) { ++ extra_bytes = ((c & 0x60) >> 5) + 1; ++ if (p + extra_bytes > plimit ) { ++ *pp = p + extra_bytes; ++ return 0; ++ } ++ } ++ ++ type = c & 0xE0; ++ sign = c & 0x10; ++ ++ if ((c & 0x80) == 0) { ++ sign = c & 0x40; ++ id = c & 0x3F; ++ } else if (type == 0x80) { ++ id = c & 0x0F; ++ id = (id << 8) | *p++; ++ } else if (type == 0xA0) { ++ id = c & 0x0F; ++ id = (id << 8) | *p++; ++ id = (id << 8) | *p++; ++ } else if (type == 0xC0) { ++ id = c & 0x0F; ++ id = (id << 8) | *p++; ++ id = (id << 8) | *p++; ++ id = (id << 8) | *p++; ++ } else if (type == 0xE0) { ++ copy_be32((u32*)&id, (u32*)p); ++ p += 4; ++ } else { ++ *pp = plimit + 2; ++ return 0; ++ } ++ ++ if (sign) id = -id; ++ ++ *pp = p; ++ ++ return id; ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE unsigned char * SearchForID(unsigned char *p, int header_size, int size, int numitems, int id) { ++ unsigned char *plimit, *base; ++ int i, int32; ++ ++ base = p; ++ plimit = p + size - 1; ++ p += header_size; ++ ++ /* search for the ID in all the arguments. */ ++ for (i = 0; i < numitems; i++) { ++ int32 = read_map_id(&p, plimit); ++ if (p > plimit) break; ++ /* Compare if the IDs are equal. */ ++ if (int32 == id) return p; ++ /* xxx */ ++ p = AdvanceDataPos(p, plimit); ++ if ((p == 0) || (p < base)) break; ++ } ++ ++ return NULL; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE unsigned char * SearchForKey(unsigned char *p, int header_size, int size, int numitems, const char *key) { ++ unsigned char len, *plimit, *base; ++ int i, keylen; ++ ++ base = p; ++ plimit = p + size - 1; ++ p += header_size; ++ ++ keylen = strlen(key); ++ ++ /* search for the key in all the arguments. */ ++ for (i = 0; i < numitems; i++) { ++ len = *((unsigned char *)p); ++ p++; ++ if (p > plimit) break; ++ /* Compare if the strings are equal. */ ++ if (len > 0) { ++ if (strnicmp((char*)p, key, len) == 0) { /* note that there is no null terminator here */ ++ if (keylen == len) { ++ p += len; ++ return p; ++ } ++ } ++ p += len; ++ if (p > plimit) break; ++ } else if (len == keylen) { /* in the case of empty string: "" */ ++ return p; ++ } ++ /* xxx */ ++ p = AdvanceDataPos(p, plimit); ++ if ((p == 0) || (p < base)) break; ++ } ++ ++ return NULL; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL AddValue(binn *item, int type, void *pvalue, int size); ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_list_add_raw(binn *item, int type, void *pvalue, int size) { ++ ++ if ((item == NULL) || (item->type != BINN_LIST) || (item->writable == FALSE)) return FALSE; ++ ++ /* if (CheckAllocation(item, 4) == FALSE) return FALSE; // 4 bytes used for data_store and data_format. */ ++ ++ if (AddValue(item, type, pvalue, size) == FALSE) return FALSE; ++ ++ item->count++; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_object_set_raw(binn *item, const char *key, int type, void *pvalue, int size) { ++ unsigned char *p, len; ++ int int32; ++ ++ if ((item == NULL) || (item->type != BINN_OBJECT) || (item->writable == FALSE)) return FALSE; ++ ++ if (key == NULL) return FALSE; ++ int32 = strlen(key); ++ if (int32 > 255) return FALSE; ++ ++ /* is the key already in it? */ ++ p = SearchForKey(item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, key); ++ if (p) return FALSE; ++ ++ /* start adding it */ ++ ++ if (CheckAllocation(item, 1 + int32) == FALSE) return FALSE; /* bytes used for the key size and the key itself. */ ++ ++ p = ((unsigned char *) item->pbuf) + item->used_size; ++ len = int32; ++ *p = len; ++ p++; ++ memcpy(p, key, int32); ++ int32++; /* now contains the strlen + 1 byte for the len */ ++ item->used_size += int32; ++ ++ if (AddValue(item, type, pvalue, size) == FALSE) { ++ item->used_size -= int32; ++ return FALSE; ++ } ++ ++ item->count++; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_map_set_raw(binn *item, int id, int type, void *pvalue, int size) { ++ unsigned char *base, *p, sign; ++ int id_size; ++ ++ if ((item == NULL) || (item->type != BINN_MAP) || (item->writable == FALSE)) return FALSE; ++ ++ /* is the ID already in it? */ ++ p = SearchForID(item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, id); ++ if (p) return FALSE; ++ ++ /* start adding it */ ++ ++ if (CheckAllocation(item, 5) == FALSE) return FALSE; /* max 5 bytes used for the id. */ ++ ++ p = base = ((unsigned char *) item->pbuf) + item->used_size; ++ ++ sign = (id < 0); ++ if (sign) id = -id; ++ ++ if (id <= 0x3F) { ++ *p++ = (sign << 6) | id; ++ } else if (id <= 0xFFF) { ++ *p++ = 0x80 | (sign << 4) | ((id & 0xF00) >> 8); ++ *p++ = id & 0xFF; ++ } else if (id <= 0xFFFFF) { ++ *p++ = 0xA0 | (sign << 4) | ((id & 0xF0000) >> 16); ++ *p++ = (id & 0xFF00) >> 8; ++ *p++ = id & 0xFF; ++ } else if (id <= 0xFFFFFFF) { ++ *p++ = 0xC0 | (sign << 4) | ((id & 0xF000000) >> 24); ++ *p++ = (id & 0xFF0000) >> 16; ++ *p++ = (id & 0xFF00) >> 8; ++ *p++ = id & 0xFF; ++ } else { ++ *p++ = 0xE0; ++ if (sign) id = -id; ++ copy_be32((u32*)p, (u32*)&id); ++ p += 4; ++ } ++ ++ id_size = (p - base); ++ item->used_size += id_size; ++ ++ if (AddValue(item, type, pvalue, size) == FALSE) { ++ item->used_size -= id_size; ++ return FALSE; ++ } ++ ++ item->count++; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE void * compress_int(int *pstorage_type, int *ptype, void *psource) { ++ int storage_type, storage_type2, type, type2=0; ++ int64 vint = 0; ++ uint64 vuint; ++ char *pvalue; ++#if BYTE_ORDER == BIG_ENDIAN ++ int size1, size2; ++#endif ++ ++ storage_type = *pstorage_type; ++ if (storage_type == BINN_STORAGE_BYTE) return psource; ++ ++ type = *ptype; ++ ++ switch (type) { ++ case BINN_INT64: ++ vint = *(int64*)psource; ++ goto loc_signed; ++ case BINN_INT32: ++ vint = *(int*)psource; ++ goto loc_signed; ++ case BINN_INT16: ++ vint = *(short*)psource; ++ goto loc_signed; ++ case BINN_UINT64: ++ vuint = *(uint64*)psource; ++ goto loc_positive; ++ case BINN_UINT32: ++ vuint = *(unsigned int*)psource; ++ goto loc_positive; ++ case BINN_UINT16: ++ vuint = *(unsigned short*)psource; ++ goto loc_positive; ++ } ++ ++loc_signed: ++ ++ if (vint >= 0) { ++ vuint = vint; ++ goto loc_positive; ++ } ++ ++/* loc_negative: */ ++ ++ if (vint >= INT8_MIN) { ++ type2 = BINN_INT8; ++ } else ++ if (vint >= INT16_MIN) { ++ type2 = BINN_INT16; ++ } else ++ if (vint >= INT32_MIN) { ++ type2 = BINN_INT32; ++ } ++ goto loc_exit; ++ ++loc_positive: ++ ++ if (vuint <= UINT8_MAX) { ++ type2 = BINN_UINT8; ++ } else ++ if (vuint <= UINT16_MAX) { ++ type2 = BINN_UINT16; ++ } else ++ if (vuint <= UINT32_MAX) { ++ type2 = BINN_UINT32; ++ } ++ ++loc_exit: ++ ++ pvalue = (char *) psource; ++ ++ if ((type2) && (type2 != type)) { ++ *ptype = type2; ++ storage_type2 = binn_get_write_storage(type2); ++ *pstorage_type = storage_type2; ++#if BYTE_ORDER == BIG_ENDIAN ++ size1 = get_storage_size(storage_type); ++ size2 = get_storage_size(storage_type2); ++ pvalue += (size1 - size2); ++#endif ++ } ++ ++ return pvalue; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int type_family(int type); ++ ++BINN_PRIVATE BOOL AddValue(binn *item, int type, void *pvalue, int size) { ++ int int32, ArgSize, storage_type, extra_type; ++ unsigned char *p; ++ ++ binn_get_type_info(type, &storage_type, &extra_type); ++ ++ if (pvalue == NULL) { ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ if (size == 0) break; /* the 2 above are allowed to have 0 length */ ++ /* fall through */ ++ default: ++ return FALSE; ++ } ++ } ++ ++ if ((type_family(type) == BINN_FAMILY_INT) && (item->disable_int_compression == FALSE)) ++ pvalue = compress_int(&storage_type, &type, pvalue); ++ ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ size = 0; ++ ArgSize = size; ++ break; ++ case BINN_STORAGE_BYTE: ++ size = 1; ++ ArgSize = size; ++ break; ++ case BINN_STORAGE_WORD: ++ size = 2; ++ ArgSize = size; ++ break; ++ case BINN_STORAGE_DWORD: ++ size = 4; ++ ArgSize = size; ++ break; ++ case BINN_STORAGE_QWORD: ++ size = 8; ++ ArgSize = size; ++ break; ++ case BINN_STORAGE_BLOB: ++ if (size < 0) return FALSE; ++ /* if (size == 0) ... */ ++ ArgSize = size + 4; /* at least this size */ ++ break; ++ case BINN_STORAGE_STRING: ++ if (size < 0) return FALSE; ++ if (size == 0) size = strlen2( (char *) pvalue); ++ ArgSize = size + 5; /* at least this size */ ++ break; ++ case BINN_STORAGE_CONTAINER: ++ if (size <= 0) return FALSE; ++ ArgSize = size; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ ArgSize += 2; /* at least 2 bytes used for data_type. */ ++ if (CheckAllocation(item, ArgSize) == FALSE) return FALSE; ++ ++ /* Gets the pointer to the next place in buffer */ ++ p = ((unsigned char *) item->pbuf) + item->used_size; ++ ++ /* If the data is not a container, store the data type */ ++ if (storage_type != BINN_STORAGE_CONTAINER) { ++ if (type > 255) { ++ u16 type16 = type; ++ copy_be16((u16*)p, (u16*)&type16); ++ p += 2; ++ item->used_size += 2; ++ } else { ++ *p = type; ++ p++; ++ item->used_size++; ++ } ++ } ++ ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ /* Nothing to do. */ ++ break; ++ case BINN_STORAGE_BYTE: ++ *((char *) p) = *((char *) pvalue); ++ item->used_size += 1; ++ break; ++ case BINN_STORAGE_WORD: ++ copy_be16((u16*)p, (u16*)pvalue); ++ item->used_size += 2; ++ break; ++ case BINN_STORAGE_DWORD: ++ copy_be32((u32*)p, (u32*)pvalue); ++ item->used_size += 4; ++ break; ++ case BINN_STORAGE_QWORD: ++ copy_be64((u64*)p, (u64*)pvalue); ++ item->used_size += 8; ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ if (size > 127) { ++ int32 = size | 0x80000000; ++ copy_be32((u32*)p, (u32*)&int32); ++ p += 4; ++ item->used_size += 4; ++ } else { ++ *((unsigned char *) p) = size; ++ p++; ++ item->used_size++; ++ } ++ memcpy(p, pvalue, size); ++ if (storage_type == BINN_STORAGE_STRING) { ++ p += size; ++ *((char *) p) = (char) 0; ++ size++; /* null terminator */ ++ } ++ item->used_size += size; ++ break; ++ case BINN_STORAGE_CONTAINER: ++ memcpy(p, pvalue, size); ++ item->used_size += size; ++ break; ++ } ++ ++ item->dirty = TRUE; ++ ++ return TRUE; ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_save_header(binn *item) { ++ unsigned char byte, *p; ++ int int32, size; ++ ++ if (item == NULL) return FALSE; ++ ++#ifndef BINN_DISABLE_SMALL_HEADER ++ ++ p = ((unsigned char *) item->pbuf) + MAX_BINN_HEADER; ++ size = item->used_size - MAX_BINN_HEADER + 3; /* at least 3 bytes for the header */ ++ ++ /* write the count */ ++ if (item->count > 127) { ++ p -= 4; ++ size += 3; ++ int32 = item->count | 0x80000000; ++ copy_be32((u32*)p, (u32*)&int32); ++ } else { ++ p--; ++ *p = (unsigned char) item->count; ++ } ++ ++ /* write the size */ ++ if (size > 127) { ++ p -= 4; ++ size += 3; ++ int32 = size | 0x80000000; ++ copy_be32((u32*)p, (u32*)&int32); ++ } else { ++ p--; ++ *p = (unsigned char) size; ++ } ++ ++ /* write the type. */ ++ p--; ++ *p = (unsigned char) item->type; ++ ++ /* set the values */ ++ item->ptr = p; ++ item->size = size; ++ ++ UNUSED(byte); ++ ++#else ++ ++ p = (unsigned char *) item->pbuf; ++ ++ /* write the type. */ ++ byte = item->type; ++ *p = byte; p++; ++ /* write the size */ ++ int32 = item->used_size | 0x80000000; ++ copy_be32((u32*)p, (u32*)&int32); ++ p+=4; ++ /* write the count */ ++ int32 = item->count | 0x80000000; ++ copy_be32((u32*)p, (u32*)&int32); ++ ++ item->ptr = item->pbuf; ++ item->size = item->used_size; ++ ++#endif ++ ++ item->dirty = FALSE; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++void APIENTRY binn_free(binn *item) { ++ ++ if (item == NULL) return; ++ ++ if ((item->writable) && (item->pre_allocated == FALSE)) { ++ free_fn(item->pbuf); ++ } ++ ++ if (item->freefn) item->freefn(item->ptr); ++ ++ if (item->allocated) { ++ free_fn(item); ++ } else { ++ memset(item, 0, sizeof(binn)); ++ item->header = BINN_MAGIC; ++ } ++ ++} ++ ++/***************************************************************************/ ++/* free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later */ ++void * APIENTRY binn_release(binn *item) { ++ void *data; ++ ++ if (item == NULL) return NULL; ++ ++ data = binn_ptr(item); ++ ++ if (data > item->pbuf) { ++ memmove(item->pbuf, data, item->size); ++ data = item->pbuf; ++ } ++ ++ if (item->allocated) { ++ free_fn(item); ++ } else { ++ memset(item, 0, sizeof(binn)); ++ item->header = BINN_MAGIC; ++ } ++ ++ return data; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL IsValidBinnHeader(void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize) { ++ unsigned char byte, *p, *plimit=0; ++ int int32, type, size, count; ++ ++ if (pbuf == NULL) return FALSE; ++ ++ p = (unsigned char *) pbuf; ++ ++ if (psize && *psize > 0) { ++ plimit = p + *psize - 1; ++ } ++ ++ /* get the type */ ++ byte = *p; p++; ++ if ((byte & BINN_STORAGE_MASK) != BINN_STORAGE_CONTAINER) return FALSE; ++ if (byte & BINN_STORAGE_HAS_MORE) return FALSE; ++ type = byte; ++ ++ switch (type) { ++ case BINN_LIST: ++ case BINN_MAP: ++ case BINN_OBJECT: ++ break; ++ default: ++ return FALSE; ++ } ++ ++ /* get the size */ ++ if (plimit && p > plimit) return FALSE; ++ int32 = *((unsigned char*)p); ++ if (int32 & 0x80) { ++ if (plimit && p + sizeof(int) - 1 > plimit) return FALSE; ++ copy_be32((u32*)&int32, (u32*)p); ++ int32 &= 0x7FFFFFFF; ++ p+=4; ++ } else { ++ p++; ++ } ++ size = int32; ++ ++ /* get the count */ ++ if (plimit && p > plimit) return FALSE; ++ int32 = *((unsigned char*)p); ++ if (int32 & 0x80) { ++ if (plimit && p + sizeof(int) - 1 > plimit) return FALSE; ++ copy_be32((u32*)&int32, (u32*)p); ++ int32 &= 0x7FFFFFFF; ++ p+=4; ++ } else { ++ p++; ++ } ++ count = int32; ++ ++#if 0 ++ /* get the size */ ++ copy_be32((u32*)&size, (u32*)p); ++ size &= 0x7FFFFFFF; ++ p+=4; ++ ++ /* get the count */ ++ copy_be32((u32*)&count, (u32*)p); ++ count &= 0x7FFFFFFF; ++ p+=4; ++#endif ++ ++ if ((size < MIN_BINN_SIZE) || (count < 0)) return FALSE; ++ ++ /* return the values */ ++ if (ptype) *ptype = type; ++ if (pcount) *pcount = count; ++ if (psize && *psize==0) *psize = size; ++ if (pheadersize) *pheadersize = (int) (p - (unsigned char*)pbuf); ++ return TRUE; ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int binn_buf_type(void *pbuf) { ++ int type; ++ ++ if (!IsValidBinnHeader(pbuf, &type, NULL, NULL, NULL)) return INVALID_BINN; ++ ++ return type; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int binn_buf_count(void *pbuf) { ++ int nitems; ++ ++ if (!IsValidBinnHeader(pbuf, NULL, &nitems, NULL, NULL)) return 0; ++ ++ return nitems; ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE int binn_buf_size(void *pbuf) { ++ int size=0; ++ ++ if (!IsValidBinnHeader(pbuf, NULL, NULL, &size, NULL)) return 0; ++ ++ return size; ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_ptr(void *ptr) { ++ binn *item; ++ ++ switch (binn_get_ptr_type(ptr)) { ++ case BINN_STRUCT: ++ item = (binn*) ptr; ++ if (item->writable && item->dirty) { ++ binn_save_header(item); ++ } ++ return item->ptr; ++ case BINN_BUFFER: ++ return ptr; ++ default: ++ return NULL; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++int APIENTRY binn_size(void *ptr) { ++ binn *item; ++ ++ switch (binn_get_ptr_type(ptr)) { ++ case BINN_STRUCT: ++ item = (binn*) ptr; ++ if (item->writable && item->dirty) { ++ binn_save_header(item); ++ } ++ return item->size; ++ case BINN_BUFFER: ++ return binn_buf_size(ptr); ++ default: ++ return 0; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++int APIENTRY binn_type(void *ptr) { ++ binn *item; ++ ++ switch (binn_get_ptr_type(ptr)) { ++ case BINN_STRUCT: ++ item = (binn*) ptr; ++ return item->type; ++ case BINN_BUFFER: ++ return binn_buf_type(ptr); ++ default: ++ return -1; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++int APIENTRY binn_count(void *ptr) { ++ binn *item; ++ ++ switch (binn_get_ptr_type(ptr)) { ++ case BINN_STRUCT: ++ item = (binn*) ptr; ++ return item->count; ++ case BINN_BUFFER: ++ return binn_buf_count(ptr); ++ default: ++ return -1; ++ } ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_is_valid_ex(void *ptr, int *ptype, int *pcount, int *psize) { ++ int i, type, count, size, header_size; ++ unsigned char *p, *plimit, *base, len; ++ void *pbuf; ++ ++ pbuf = binn_ptr(ptr); ++ if (pbuf == NULL) return FALSE; ++ ++ /* is there an informed size? */ ++ if (psize && *psize > 0) { ++ size = *psize; ++ } else { ++ size = 0; ++ } ++ ++ if (!IsValidBinnHeader(pbuf, &type, &count, &size, &header_size)) return FALSE; ++ ++ /* is there an informed size? */ ++ if (psize && *psize > 0) { ++ /* is it the same as the one in the buffer? */ ++ if (size != *psize) return FALSE; ++ } ++ /* is there an informed count? */ ++ if (pcount && *pcount > 0) { ++ /* is it the same as the one in the buffer? */ ++ if (count != *pcount) return FALSE; ++ } ++ /* is there an informed type? */ ++ if (ptype && *ptype != 0) { ++ /* is it the same as the one in the buffer? */ ++ if (type != *ptype) return FALSE; ++ } ++ ++ /* it could compare the content size with the size informed on the header */ ++ ++ p = (unsigned char *)pbuf; ++ base = p; ++ plimit = p + size; ++ ++ p += header_size; ++ ++ /* process all the arguments. */ ++ for (i = 0; i < count; i++) { ++ switch (type) { ++ case BINN_OBJECT: ++ /* gets the string size (argument name) */ ++ len = *p; ++ p++; ++ /* if (len == 0) goto Invalid; */ ++ /* increment the used space */ ++ p += len; ++ break; ++ case BINN_MAP: ++ /* increment the used space */ ++ read_map_id(&p, plimit); ++ break; ++ /* case BINN_LIST: */ ++ /* break; */ ++ } ++ /* xxx */ ++ p = AdvanceDataPos(p, plimit); ++ if ((p == 0) || (p < base)) goto Invalid; ++ } ++ ++ if (ptype && *ptype==0) *ptype = type; ++ if (pcount && *pcount==0) *pcount = count; ++ if (psize && *psize==0) *psize = size; ++ return TRUE; ++ ++Invalid: ++ return FALSE; ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_is_valid(void *ptr, int *ptype, int *pcount, int *psize) { ++ ++ if (ptype) *ptype = 0; ++ if (pcount) *pcount = 0; ++ if (psize) *psize = 0; ++ ++ return binn_is_valid_ex(ptr, ptype, pcount, psize); ++ ++} ++ ++/***************************************************************************/ ++/*** INTERNAL FUNCTIONS ****************************************************/ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL GetValue(unsigned char *p, binn *value) { ++ unsigned char byte; ++ int data_type, storage_type; /* , extra_type; */ ++ int DataSize; ++ void *p2; ++ ++ if (value == NULL) return FALSE; ++ memset(value, 0, sizeof(binn)); ++ value->header = BINN_MAGIC; ++ /* value->allocated = FALSE; -- already zeroed */ ++ /* value->writable = FALSE; */ ++ ++ /* saves for use with BINN_STORAGE_CONTAINER */ ++ p2 = p; ++ ++ /* read the data type */ ++ byte = *p; p++; ++ storage_type = byte & BINN_STORAGE_MASK; ++ if (byte & BINN_STORAGE_HAS_MORE) { ++ data_type = byte << 8; ++ byte = *p; p++; ++ data_type |= byte; ++ /* extra_type = data_type & BINN_TYPE_MASK16; */ ++ } else { ++ data_type = byte; ++ /* extra_type = byte & BINN_TYPE_MASK; */ ++ } ++ ++ /* value->storage_type = storage_type; */ ++ value->type = data_type; ++ ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ break; ++ case BINN_STORAGE_BYTE: ++ value->vuint8 = *((unsigned char *) p); ++ value->ptr = p; /* value->ptr = &value->vuint8; */ ++ break; ++ case BINN_STORAGE_WORD: ++ copy_be16((u16*)&value->vint16, (u16*)p); ++ value->ptr = &value->vint16; ++ break; ++ case BINN_STORAGE_DWORD: ++ copy_be32((u32*)&value->vint32, (u32*)p); ++ value->ptr = &value->vint32; ++ break; ++ case BINN_STORAGE_QWORD: ++ copy_be64((u64*)&value->vint64, (u64*)p); ++ value->ptr = &value->vint64; ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ DataSize = *((unsigned char*)p); ++ if (DataSize & 0x80) { ++ copy_be32((u32*)&DataSize, (u32*)p); ++ DataSize &= 0x7FFFFFFF; ++ p+=4; ++ } else { ++ p++; ++ } ++ value->size = DataSize; ++ value->ptr = p; ++ break; ++ case BINN_STORAGE_CONTAINER: ++ value->ptr = p2; /* <-- it returns the pointer to the container, not the data */ ++ if (IsValidBinnHeader(p2, NULL, &value->count, &value->size, NULL) == FALSE) return FALSE; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ /* convert the returned value, if needed */ ++ ++ switch (value->type) { ++ case BINN_TRUE: ++ value->type = BINN_BOOL; ++ value->vbool = TRUE; ++ value->ptr = &value->vbool; ++ break; ++ case BINN_FALSE: ++ value->type = BINN_BOOL; ++ value->vbool = FALSE; ++ value->ptr = &value->vbool; ++ break; ++#ifdef BINN_EXTENDED ++ case BINN_SINGLE_STR: ++ value->type = BINN_SINGLE; ++ value->vfloat = (float) atof((const char*)value->ptr); /* converts from string to double, and then to float */ ++ value->ptr = &value->vfloat; ++ break; ++ case BINN_DOUBLE_STR: ++ value->type = BINN_DOUBLE; ++ value->vdouble = atof((const char*)value->ptr); /* converts from string to double */ ++ value->ptr = &value->vdouble; ++ break; ++#endif ++ /* ++ case BINN_DECIMAL: ++ case BINN_CURRENCYSTR: ++ case BINN_DATE: ++ case BINN_DATETIME: ++ case BINN_TIME: ++ */ ++ } ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++#if BYTE_ORDER == LITTLE_ENDIAN ++ ++/* on little-endian devices we store the value so we can return a pointer to integers. */ ++/* it's valid only for single-threaded apps. multi-threaded apps must use the _get_ functions instead. */ ++ ++binn local_value; ++ ++BINN_PRIVATE void * store_value(binn *value) { ++ ++ memcpy(&local_value, value, sizeof(binn)); ++ ++ switch (binn_get_read_storage(value->type)) { ++ case BINN_STORAGE_NOBYTES: ++ /* return a valid pointer */ ++ case BINN_STORAGE_WORD: ++ case BINN_STORAGE_DWORD: ++ case BINN_STORAGE_QWORD: ++ return &local_value.vint32; /* returns the pointer to the converted value, from big-endian to little-endian */ ++ } ++ ++ return value->ptr; /* returns from the on stack value to be thread-safe (for list, map, object, string and blob) */ ++ ++} ++ ++#endif ++ ++/***************************************************************************/ ++/*** READ FUNCTIONS ********************************************************/ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_object_get_value(void *ptr, const char *key, binn *value) { ++ int type, count, size=0, header_size; ++ unsigned char *p; ++ ++ ptr = binn_ptr(ptr); ++ if ((ptr == 0) || (key == 0) || (value == 0)) return FALSE; ++ ++ /* check the header */ ++ if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; ++ ++ if (type != BINN_OBJECT) return FALSE; ++ if (count == 0) return FALSE; ++ ++ p = (unsigned char *) ptr; ++ p = SearchForKey(p, header_size, size, count, key); ++ if (p == FALSE) return FALSE; ++ ++ return GetValue(p, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_map_get_value(void* ptr, int id, binn *value) { ++ int type, count, size=0, header_size; ++ unsigned char *p; ++ ++ ptr = binn_ptr(ptr); ++ if ((ptr == 0) || (value == 0)) return FALSE; ++ ++ /* check the header */ ++ if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; ++ ++ if (type != BINN_MAP) return FALSE; ++ if (count == 0) return FALSE; ++ ++ p = (unsigned char *) ptr; ++ p = SearchForID(p, header_size, size, count, id); ++ if (p == FALSE) return FALSE; ++ ++ return GetValue(p, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_list_get_value(void* ptr, int pos, binn *value) { ++ int i, type, count, size=0, header_size; ++ unsigned char *p, *plimit, *base; ++ ++ ptr = binn_ptr(ptr); ++ if ((ptr == 0) || (value == 0)) return FALSE; ++ ++ /* check the header */ ++ if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; ++ ++ if (type != BINN_LIST) return FALSE; ++ if (count == 0) return FALSE; ++ if ((pos <= 0) | (pos > count)) return FALSE; ++ pos--; /* convert from base 1 to base 0 */ ++ ++ p = (unsigned char *) ptr; ++ base = p; ++ plimit = p + size; ++ p += header_size; ++ ++ for (i = 0; i < pos; i++) { ++ p = AdvanceDataPos(p, plimit); ++ if ((p == 0) || (p < base)) return FALSE; ++ } ++ ++ return GetValue(p, value); ++ ++} ++ ++/***************************************************************************/ ++/*** READ PAIR BY POSITION *************************************************/ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_read_pair(int expected_type, void *ptr, int pos, int *pid, char *pkey, binn *value) { ++ int type, count, size=0, header_size; ++ int i, int32, id = 0, counter=0; ++ unsigned char *p, *plimit, *base, *key = NULL, len = 0; ++ ++ ptr = binn_ptr(ptr); ++ ++ /* check the header */ ++ if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; ++ ++ if ((type != expected_type) || (count == 0) || (pos < 1) || (pos > count)) return FALSE; ++ ++ p = (unsigned char *) ptr; ++ base = p; ++ plimit = p + size - 1; ++ p += header_size; ++ ++ for (i = 0; i < count; i++) { ++ switch (type) { ++ case BINN_MAP: ++ int32 = read_map_id(&p, plimit); ++ if (p > plimit) return FALSE; ++ id = int32; ++ break; ++ case BINN_OBJECT: ++ len = *((unsigned char *)p); p++; ++ if (p > plimit) return FALSE; ++ key = p; ++ p += len; ++ if (p > plimit) return FALSE; ++ break; ++ } ++ counter++; ++ if (counter == pos) goto found; ++ /* */ ++ p = AdvanceDataPos(p, plimit); ++ if ((p == 0) || (p < base)) return FALSE; ++ } ++ ++ return FALSE; ++ ++found: ++ ++ switch (type) { ++ case BINN_MAP: ++ if (pid) *pid = id; ++ break; ++ case BINN_OBJECT: ++ if (pkey) { ++ memcpy(pkey, key, len); ++ pkey[len] = 0; ++ } ++ break; ++ } ++ ++ return GetValue(p, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_map_get_pair(void *ptr, int pos, int *pid, binn *value) { ++ ++ return binn_read_pair(BINN_MAP, ptr, pos, pid, NULL, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_object_get_pair(void *ptr, int pos, char *pkey, binn *value) { ++ ++ return binn_read_pair(BINN_OBJECT, ptr, pos, NULL, pkey, value); ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_map_pair(void *map, int pos, int *pid) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_read_pair(BINN_MAP, map, pos, pid, NULL, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_object_pair(void *obj, int pos, char *pkey) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_read_pair(BINN_OBJECT, obj, pos, NULL, pkey, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++void * APIENTRY binn_map_read_pair(void *ptr, int pos, int *pid, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_map_get_pair(ptr, pos, pid, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_object_read_pair(void *ptr, int pos, char *pkey, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_object_get_pair(ptr, pos, pkey, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++/*** SEQUENTIAL READ FUNCTIONS *********************************************/ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_iter_init(binn_iter *iter, void *ptr, int expected_type) { ++ int type, count, size=0, header_size; ++ ++ ptr = binn_ptr(ptr); ++ if ((ptr == 0) || (iter == 0)) return FALSE; ++ memset(iter, 0, sizeof(binn_iter)); ++ ++ /* check the header */ ++ if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; ++ ++ if (type != expected_type) return FALSE; ++ /* if (count == 0) return FALSE; -- should not be used */ ++ ++ iter->plimit = (unsigned char *)ptr + size - 1; ++ iter->pnext = (unsigned char *)ptr + header_size; ++ iter->count = count; ++ iter->current = 0; ++ iter->type = type; ++ ++ return TRUE; ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_list_next(binn_iter *iter, binn *value) { ++ unsigned char *pnow; ++ ++ if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != BINN_LIST)) return FALSE; ++ ++ iter->current++; ++ if (iter->current > iter->count) return FALSE; ++ ++ pnow = iter->pnext; ++ iter->pnext = AdvanceDataPos(pnow, iter->plimit); ++ if (iter->pnext != 0 && iter->pnext < pnow) return FALSE; ++ ++ return GetValue(pnow, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BINN_PRIVATE BOOL binn_read_next_pair(int expected_type, binn_iter *iter, int *pid, char *pkey, binn *value) { ++ int int32, id; ++ unsigned char *p, *key; ++ unsigned short len; ++ ++ if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != expected_type)) return FALSE; ++ ++ iter->current++; ++ if (iter->current > iter->count) return FALSE; ++ ++ p = iter->pnext; ++ ++ switch (expected_type) { ++ case BINN_MAP: ++ int32 = read_map_id(&p, iter->plimit); ++ if (p > iter->plimit) return FALSE; ++ id = int32; ++ if (pid) *pid = id; ++ break; ++ case BINN_OBJECT: ++ len = *((unsigned char *)p); p++; ++ key = p; ++ p += len; ++ if (p > iter->plimit) return FALSE; ++ if (pkey) { ++ memcpy(pkey, key, len); ++ pkey[len] = 0; ++ } ++ break; ++ } ++ ++ iter->pnext = AdvanceDataPos(p, iter->plimit); ++ if (iter->pnext != 0 && iter->pnext < p) return FALSE; ++ ++ return GetValue(p, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_map_next(binn_iter *iter, int *pid, binn *value) { ++ ++ return binn_read_next_pair(BINN_MAP, iter, pid, NULL, value); ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_object_next(binn_iter *iter, char *pkey, binn *value) { ++ ++ return binn_read_next_pair(BINN_OBJECT, iter, NULL, pkey, value); ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_list_next_value(binn_iter *iter) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_list_next(iter, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_map_next_value(binn_iter *iter, int *pid) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_map_next(iter, pid, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++ ++binn * APIENTRY binn_object_next_value(binn_iter *iter, char *pkey) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_object_next(iter, pkey, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++void * APIENTRY binn_list_read_next(binn_iter *iter, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_list_next(iter, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_map_read_next(binn_iter *iter, int *pid, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_map_next(iter, pid, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_object_read_next(binn_iter *iter, char *pkey, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_object_next(iter, pkey, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/*************************************************************************************/ ++/****** EXTENDED INTERFACE ***********************************************************/ ++/****** none of the functions above call the functions below *************************/ ++/*************************************************************************************/ ++ ++int APIENTRY binn_get_write_storage(int type) { ++ int storage_type; ++ ++ switch (type) { ++ case BINN_SINGLE_STR: ++ case BINN_DOUBLE_STR: ++ return BINN_STORAGE_STRING; ++ ++ case BINN_BOOL: ++ return BINN_STORAGE_NOBYTES; ++ ++ default: ++ binn_get_type_info(type, &storage_type, NULL); ++ return storage_type; ++ } ++ ++} ++ ++/*************************************************************************************/ ++ ++int APIENTRY binn_get_read_storage(int type) { ++ int storage_type; ++ ++ switch (type) { ++#ifdef BINN_EXTENDED ++ case BINN_SINGLE_STR: ++ return BINN_STORAGE_DWORD; ++ case BINN_DOUBLE_STR: ++ return BINN_STORAGE_QWORD; ++#endif ++ case BINN_BOOL: ++ case BINN_TRUE: ++ case BINN_FALSE: ++ return BINN_STORAGE_DWORD; ++ default: ++ binn_get_type_info(type, &storage_type, NULL); ++ return storage_type; ++ } ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL GetWriteConvertedData(int *ptype, void **ppvalue, int *psize) { ++ int type; ++ float f1; ++ double d1; ++ char pstr[128]; ++ ++ UNUSED(pstr); ++ UNUSED(d1); ++ UNUSED(f1); ++ ++ type = *ptype; ++ ++ if (*ppvalue == NULL) { ++ switch (type) { ++ case BINN_NULL: ++ case BINN_TRUE: ++ case BINN_FALSE: ++ break; ++ case BINN_STRING: ++ case BINN_BLOB: ++ if (*psize == 0) break; ++ /* fall through */ ++ default: ++ return FALSE; ++ } ++ } ++ ++ switch (type) { ++#ifdef BINN_EXTENDED ++ case BINN_SINGLE: ++ f1 = **(float**)ppvalue; ++ d1 = f1; /* convert from float (32bits) to double (64bits) */ ++ type = BINN_SINGLE_STR; ++ goto conv_double; ++ case BINN_DOUBLE: ++ d1 = **(double**)ppvalue; ++ type = BINN_DOUBLE_STR; ++conv_double: ++ /* the '%.17e' is more precise than the '%g' */ ++ snprintf(pstr, 127, "%.17e", d1); ++ *ppvalue = pstr; ++ *ptype = type; ++ break; ++#endif ++ case BINN_DECIMAL: ++ case BINN_CURRENCYSTR: ++ /* ++ if (binn_malloc_extptr(128) == NULL) return FALSE; ++ snprintf(sptr, 127, "%E", **ppvalue); ++ *ppvalue = sptr; ++ */ ++ return TRUE; /* ! temporary */ ++ break; ++ ++ case BINN_DATE: ++ case BINN_DATETIME: ++ case BINN_TIME: ++ return TRUE; /* ! temporary */ ++ break; ++ ++ case BINN_BOOL: ++ if (**((BOOL**)ppvalue) == FALSE) { ++ type = BINN_FALSE; ++ } else { ++ type = BINN_TRUE; ++ } ++ *ptype = type; ++ break; ++ ++ } ++ ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE int type_family(int type) { ++ ++ switch (type) { ++ case BINN_LIST: ++ case BINN_MAP: ++ case BINN_OBJECT: ++ return BINN_FAMILY_BINN; ++ ++ case BINN_INT8: ++ case BINN_INT16: ++ case BINN_INT32: ++ case BINN_INT64: ++ case BINN_UINT8: ++ case BINN_UINT16: ++ case BINN_UINT32: ++ case BINN_UINT64: ++ return BINN_FAMILY_INT; ++ ++ case BINN_FLOAT32: ++ case BINN_FLOAT64: ++ /* case BINN_SINGLE: */ ++ case BINN_SINGLE_STR: ++ /* case BINN_DOUBLE: */ ++ case BINN_DOUBLE_STR: ++ return BINN_FAMILY_FLOAT; ++ ++ case BINN_STRING: ++ case BINN_HTML: ++ case BINN_CSS: ++ case BINN_XML: ++ case BINN_JSON: ++ case BINN_JAVASCRIPT: ++ return BINN_FAMILY_STRING; ++ ++ case BINN_BLOB: ++ case BINN_JPEG: ++ case BINN_GIF: ++ case BINN_PNG: ++ case BINN_BMP: ++ return BINN_FAMILY_BLOB; ++ ++ case BINN_DECIMAL: ++ case BINN_CURRENCY: ++ case BINN_DATE: ++ case BINN_TIME: ++ case BINN_DATETIME: ++ return BINN_FAMILY_STRING; ++ ++ case BINN_BOOL: ++ return BINN_FAMILY_BOOL; ++ ++ case BINN_NULL: ++ return BINN_FAMILY_NULL; ++ ++ default: ++ /* if it wasn't found */ ++ return BINN_FAMILY_NONE; ++ } ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE int int_type(int type) { ++ ++ switch (type) { ++ case BINN_INT8: ++ case BINN_INT16: ++ case BINN_INT32: ++ case BINN_INT64: ++ return BINN_SIGNED_INT; ++ ++ case BINN_UINT8: ++ case BINN_UINT16: ++ case BINN_UINT32: ++ case BINN_UINT64: ++ return BINN_UNSIGNED_INT; ++ ++ default: ++ return 0; ++ } ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL copy_raw_value(void *psource, void *pdest, int data_store) { ++ ++ switch (data_store) { ++ case BINN_STORAGE_NOBYTES: ++ break; ++ case BINN_STORAGE_BYTE: ++ *((char *) pdest) = *(char *)psource; ++ break; ++ case BINN_STORAGE_WORD: ++ *((short *) pdest) = *(short *)psource; ++ break; ++ case BINN_STORAGE_DWORD: ++ *((int *) pdest) = *(int *)psource; ++ break; ++ case BINN_STORAGE_QWORD: ++ *((uint64 *) pdest) = *(uint64 *)psource; ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ case BINN_STORAGE_CONTAINER: ++ *((char **) pdest) = (char *)psource; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL copy_int_value(void *psource, void *pdest, int source_type, int dest_type) { ++ uint64 vuint64 = 0; int64 vint64 = 0; ++ ++ switch (source_type) { ++ case BINN_INT8: ++ vint64 = *(signed char *)psource; ++ break; ++ case BINN_INT16: ++ vint64 = *(short *)psource; ++ break; ++ case BINN_INT32: ++ vint64 = *(int *)psource; ++ break; ++ case BINN_INT64: ++ vint64 = *(int64 *)psource; ++ break; ++ ++ case BINN_UINT8: ++ vuint64 = *(unsigned char *)psource; ++ break; ++ case BINN_UINT16: ++ vuint64 = *(unsigned short *)psource; ++ break; ++ case BINN_UINT32: ++ vuint64 = *(unsigned int *)psource; ++ break; ++ case BINN_UINT64: ++ vuint64 = *(uint64 *)psource; ++ break; ++ ++ default: ++ return FALSE; ++ } ++ ++ ++ /* copy from int64 to uint64, if possible */ ++ ++ if ((int_type(source_type) == BINN_UNSIGNED_INT) && (int_type(dest_type) == BINN_SIGNED_INT)) { ++ if (vuint64 > INT64_MAX) return FALSE; ++ vint64 = vuint64; ++ } else if ((int_type(source_type) == BINN_SIGNED_INT) && (int_type(dest_type) == BINN_UNSIGNED_INT)) { ++ if (vint64 < 0) return FALSE; ++ vuint64 = vint64; ++ } ++ ++ ++ switch (dest_type) { ++ case BINN_INT8: ++ if ((vint64 < INT8_MIN) || (vint64 > INT8_MAX)) return FALSE; ++ *(signed char *)pdest = (signed char) vint64; ++ break; ++ case BINN_INT16: ++ if ((vint64 < INT16_MIN) || (vint64 > INT16_MAX)) return FALSE; ++ *(short *)pdest = (short) vint64; ++ break; ++ case BINN_INT32: ++ if ((vint64 < INT32_MIN) || (vint64 > INT32_MAX)) return FALSE; ++ *(int *)pdest = (int) vint64; ++ break; ++ case BINN_INT64: ++ *(int64 *)pdest = vint64; ++ break; ++ ++ case BINN_UINT8: ++ if (vuint64 > UINT8_MAX) return FALSE; ++ *(unsigned char *)pdest = (unsigned char) vuint64; ++ break; ++ case BINN_UINT16: ++ if (vuint64 > UINT16_MAX) return FALSE; ++ *(unsigned short *)pdest = (unsigned short) vuint64; ++ break; ++ case BINN_UINT32: ++ if (vuint64 > UINT32_MAX) return FALSE; ++ *(unsigned int *)pdest = (unsigned int) vuint64; ++ break; ++ case BINN_UINT64: ++ *(uint64 *)pdest = vuint64; ++ break; ++ ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL copy_float_value(void *psource, void *pdest, int source_type) { ++ ++ switch (source_type) { ++ case BINN_FLOAT32: ++ *(double *)pdest = *(float *)psource; ++ break; ++ case BINN_FLOAT64: ++ *(float *)pdest = (float) *(double *)psource; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE void zero_value(void *pvalue, int type) { ++ /* int size=0; */ ++ ++ switch (binn_get_read_storage(type)) { ++ case BINN_STORAGE_NOBYTES: ++ break; ++ case BINN_STORAGE_BYTE: ++ *((char *) pvalue) = 0; ++ /* size=1; */ ++ break; ++ case BINN_STORAGE_WORD: ++ *((short *) pvalue) = 0; ++ /* size=2; */ ++ break; ++ case BINN_STORAGE_DWORD: ++ *((int *) pvalue) = 0; ++ /* size=4; */ ++ break; ++ case BINN_STORAGE_QWORD: ++ *((uint64 *) pvalue) = 0; ++ /* size=8; */ ++ break; ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_STRING: ++ case BINN_STORAGE_CONTAINER: ++ *(char **)pvalue = NULL; ++ break; ++ } ++ ++ /* if (size>0) memset(pvalue, 0, size); */ ++ ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL copy_value(void *psource, void *pdest, int source_type, int dest_type, int data_store) { ++ ++ if (type_family(source_type) != type_family(dest_type)) return FALSE; ++ ++ if ((type_family(source_type) == BINN_FAMILY_INT) && (source_type != dest_type)) { ++ return copy_int_value(psource, pdest, source_type, dest_type); ++ } else if ((type_family(source_type) == BINN_FAMILY_FLOAT) && (source_type != dest_type)) { ++ return copy_float_value(psource, pdest, source_type); ++ } else { ++ return copy_raw_value(psource, pdest, data_store); ++ } ++ ++} ++ ++/*************************************************************************************/ ++/*** WRITE FUNCTIONS *****************************************************************/ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_list_add(binn *list, int type, void *pvalue, int size) { ++ ++ if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; ++ ++ return binn_list_add_raw(list, type, pvalue, size); ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_map_set(binn *map, int id, int type, void *pvalue, int size) { ++ ++ if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; ++ ++ return binn_map_set_raw(map, id, type, pvalue, size); ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_object_set(binn *obj, const char *key, int type, void *pvalue, int size) { ++ ++ if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; ++ ++ return binn_object_set_raw(obj, key, type, pvalue, size); ++ ++} ++ ++/*************************************************************************************/ ++ ++/* this function is used by the wrappers */ ++BOOL APIENTRY binn_add_value(binn *item, int binn_type, int id, char *name, int type, void *pvalue, int size) { ++ ++ switch (binn_type) { ++ case BINN_LIST: ++ return binn_list_add(item, type, pvalue, size); ++ case BINN_MAP: ++ return binn_map_set(item, id, type, pvalue, size); ++ case BINN_OBJECT: ++ return binn_object_set(item, name, type, pvalue, size); ++ default: ++ return FALSE; ++ } ++ ++} ++ ++/*************************************************************************************/ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_list_add_new(binn *list, binn *value) { ++ BOOL retval; ++ ++ retval = binn_list_add_value(list, value); ++ if (value) free_fn(value); ++ return retval; ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_map_set_new(binn *map, int id, binn *value) { ++ BOOL retval; ++ ++ retval = binn_map_set_value(map, id, value); ++ if (value) free_fn(value); ++ return retval; ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_object_set_new(binn *obj, const char *key, binn *value) { ++ BOOL retval; ++ ++ retval = binn_object_set_value(obj, key, value); ++ if (value) free_fn(value); ++ return retval; ++ ++} ++ ++/*************************************************************************************/ ++/*** READ FUNCTIONS ******************************************************************/ ++/*************************************************************************************/ ++ ++binn * APIENTRY binn_list_value(void *ptr, int pos) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_list_get_value(ptr, pos, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/*************************************************************************************/ ++ ++binn * APIENTRY binn_map_value(void *ptr, int id) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_map_get_value(ptr, id, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/*************************************************************************************/ ++ ++binn * APIENTRY binn_object_value(void *ptr, const char *key) { ++ binn *value; ++ ++ value = (binn *) binn_malloc(sizeof(binn)); ++ ++ if (binn_object_get_value(ptr, key, value) == FALSE) { ++ free_fn(value); ++ return NULL; ++ } ++ ++ value->allocated = TRUE; ++ return value; ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++void * APIENTRY binn_list_read(void *list, int pos, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_list_get_value(list, pos, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_map_read(void *map, int id, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_map_get_value(map, id, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++ ++void * APIENTRY binn_object_read(void *obj, const char *key, int *ptype, int *psize) { ++ binn value; ++ ++ if (binn_object_get_value(obj, key, &value) == FALSE) return NULL; ++ if (ptype) *ptype = value.type; ++ if (psize) *psize = value.size; ++#if BYTE_ORDER == LITTLE_ENDIAN ++ return store_value(&value); ++#else ++ return value.ptr; ++#endif ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_list_get(void *ptr, int pos, int type, void *pvalue, int *psize) { ++ binn value; ++ int storage_type; ++ ++ storage_type = binn_get_read_storage(type); ++ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ ++ zero_value(pvalue, type); ++ ++ if (binn_list_get_value(ptr, pos, &value) == FALSE) return FALSE; ++ ++ if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; ++ ++ if (psize) *psize = value.size; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_map_get(void *ptr, int id, int type, void *pvalue, int *psize) { ++ binn value; ++ int storage_type; ++ ++ storage_type = binn_get_read_storage(type); ++ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ ++ zero_value(pvalue, type); ++ ++ if (binn_map_get_value(ptr, id, &value) == FALSE) return FALSE; ++ ++ if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; ++ ++ if (psize) *psize = value.size; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++ ++/* if (binn_object_get(obj, "multiplier", BINN_INT32, &multiplier, NULL) == FALSE) xxx; */ ++ ++BOOL APIENTRY binn_object_get(void *ptr, const char *key, int type, void *pvalue, int *psize) { ++ binn value; ++ int storage_type; ++ ++ storage_type = binn_get_read_storage(type); ++ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ ++ zero_value(pvalue, type); ++ ++ if (binn_object_get_value(ptr, key, &value) == FALSE) return FALSE; ++ ++ if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; ++ ++ if (psize) *psize = value.size; ++ ++ return TRUE; ++ ++} ++ ++/***************************************************************************/ ++/***************************************************************************/ ++ ++/* these functions below may not be implemented as inline functions, because */ ++/* they use a lot of space, even for the variable. so they will be exported. */ ++ ++/* but what about using as static? */ ++/* is there any problem with wrappers? can these wrappers implement these functions using the header? */ ++/* if as static, will they be present even on modules that don't use the functions? */ ++ ++signed char APIENTRY binn_list_int8(void *list, int pos) { ++ signed char value; ++ ++ binn_list_get(list, pos, BINN_INT8, &value, NULL); ++ ++ return value; ++} ++ ++short APIENTRY binn_list_int16(void *list, int pos) { ++ short value; ++ ++ binn_list_get(list, pos, BINN_INT16, &value, NULL); ++ ++ return value; ++} ++ ++int APIENTRY binn_list_int32(void *list, int pos) { ++ int value; ++ ++ binn_list_get(list, pos, BINN_INT32, &value, NULL); ++ ++ return value; ++} ++ ++int64 APIENTRY binn_list_int64(void *list, int pos) { ++ int64 value; ++ ++ binn_list_get(list, pos, BINN_INT64, &value, NULL); ++ ++ return value; ++} ++ ++unsigned char APIENTRY binn_list_uint8(void *list, int pos) { ++ unsigned char value; ++ ++ binn_list_get(list, pos, BINN_UINT8, &value, NULL); ++ ++ return value; ++} ++ ++unsigned short APIENTRY binn_list_uint16(void *list, int pos) { ++ unsigned short value; ++ ++ binn_list_get(list, pos, BINN_UINT16, &value, NULL); ++ ++ return value; ++} ++ ++unsigned int APIENTRY binn_list_uint32(void *list, int pos) { ++ unsigned int value; ++ ++ binn_list_get(list, pos, BINN_UINT32, &value, NULL); ++ ++ return value; ++} ++ ++uint64 APIENTRY binn_list_uint64(void *list, int pos) { ++ uint64 value; ++ ++ binn_list_get(list, pos, BINN_UINT64, &value, NULL); ++ ++ return value; ++} ++ ++float APIENTRY binn_list_float(void *list, int pos) { ++ float value; ++ ++ binn_list_get(list, pos, BINN_FLOAT32, &value, NULL); ++ ++ return value; ++} ++ ++double APIENTRY binn_list_double(void *list, int pos) { ++ double value; ++ ++ binn_list_get(list, pos, BINN_FLOAT64, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_list_bool(void *list, int pos) { ++ BOOL value; ++ ++ binn_list_get(list, pos, BINN_BOOL, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_list_null(void *list, int pos) { ++ ++ return binn_list_get(list, pos, BINN_NULL, NULL, NULL); ++ ++} ++ ++char * APIENTRY binn_list_str(void *list, int pos) { ++ char *value; ++ ++ binn_list_get(list, pos, BINN_STRING, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_list_blob(void *list, int pos, int *psize) { ++ void *value; ++ ++ binn_list_get(list, pos, BINN_BLOB, &value, psize); ++ ++ return value; ++} ++ ++void * APIENTRY binn_list_list(void *list, int pos) { ++ void *value; ++ ++ binn_list_get(list, pos, BINN_LIST, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_list_map(void *list, int pos) { ++ void *value; ++ ++ binn_list_get(list, pos, BINN_MAP, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_list_object(void *list, int pos) { ++ void *value; ++ ++ binn_list_get(list, pos, BINN_OBJECT, &value, NULL); ++ ++ return value; ++} ++ ++/***************************************************************************/ ++ ++signed char APIENTRY binn_map_int8(void *map, int id) { ++ signed char value; ++ ++ binn_map_get(map, id, BINN_INT8, &value, NULL); ++ ++ return value; ++} ++ ++short APIENTRY binn_map_int16(void *map, int id) { ++ short value; ++ ++ binn_map_get(map, id, BINN_INT16, &value, NULL); ++ ++ return value; ++} ++ ++int APIENTRY binn_map_int32(void *map, int id) { ++ int value; ++ ++ binn_map_get(map, id, BINN_INT32, &value, NULL); ++ ++ return value; ++} ++ ++int64 APIENTRY binn_map_int64(void *map, int id) { ++ int64 value; ++ ++ binn_map_get(map, id, BINN_INT64, &value, NULL); ++ ++ return value; ++} ++ ++unsigned char APIENTRY binn_map_uint8(void *map, int id) { ++ unsigned char value; ++ ++ binn_map_get(map, id, BINN_UINT8, &value, NULL); ++ ++ return value; ++} ++ ++unsigned short APIENTRY binn_map_uint16(void *map, int id) { ++ unsigned short value; ++ ++ binn_map_get(map, id, BINN_UINT16, &value, NULL); ++ ++ return value; ++} ++ ++unsigned int APIENTRY binn_map_uint32(void *map, int id) { ++ unsigned int value; ++ ++ binn_map_get(map, id, BINN_UINT32, &value, NULL); ++ ++ return value; ++} ++ ++uint64 APIENTRY binn_map_uint64(void *map, int id) { ++ uint64 value; ++ ++ binn_map_get(map, id, BINN_UINT64, &value, NULL); ++ ++ return value; ++} ++ ++float APIENTRY binn_map_float(void *map, int id) { ++ float value; ++ ++ binn_map_get(map, id, BINN_FLOAT32, &value, NULL); ++ ++ return value; ++} ++ ++double APIENTRY binn_map_double(void *map, int id) { ++ double value; ++ ++ binn_map_get(map, id, BINN_FLOAT64, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_map_bool(void *map, int id) { ++ BOOL value; ++ ++ binn_map_get(map, id, BINN_BOOL, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_map_null(void *map, int id) { ++ ++ return binn_map_get(map, id, BINN_NULL, NULL, NULL); ++ ++} ++ ++char * APIENTRY binn_map_str(void *map, int id) { ++ char *value; ++ ++ binn_map_get(map, id, BINN_STRING, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_map_blob(void *map, int id, int *psize) { ++ void *value; ++ ++ binn_map_get(map, id, BINN_BLOB, &value, psize); ++ ++ return value; ++} ++ ++void * APIENTRY binn_map_list(void *map, int id) { ++ void *value; ++ ++ binn_map_get(map, id, BINN_LIST, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_map_map(void *map, int id) { ++ void *value; ++ ++ binn_map_get(map, id, BINN_MAP, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_map_object(void *map, int id) { ++ void *value; ++ ++ binn_map_get(map, id, BINN_OBJECT, &value, NULL); ++ ++ return value; ++} ++ ++/***************************************************************************/ ++ ++signed char APIENTRY binn_object_int8(void *obj, const char *key) { ++ signed char value; ++ ++ binn_object_get(obj, key, BINN_INT8, &value, NULL); ++ ++ return value; ++} ++ ++short APIENTRY binn_object_int16(void *obj, const char *key) { ++ short value; ++ ++ binn_object_get(obj, key, BINN_INT16, &value, NULL); ++ ++ return value; ++} ++ ++int APIENTRY binn_object_int32(void *obj, const char *key) { ++ int value; ++ ++ binn_object_get(obj, key, BINN_INT32, &value, NULL); ++ ++ return value; ++} ++ ++int64 APIENTRY binn_object_int64(void *obj, const char *key) { ++ int64 value; ++ ++ binn_object_get(obj, key, BINN_INT64, &value, NULL); ++ ++ return value; ++} ++ ++unsigned char APIENTRY binn_object_uint8(void *obj, const char *key) { ++ unsigned char value; ++ ++ binn_object_get(obj, key, BINN_UINT8, &value, NULL); ++ ++ return value; ++} ++ ++unsigned short APIENTRY binn_object_uint16(void *obj, const char *key) { ++ unsigned short value; ++ ++ binn_object_get(obj, key, BINN_UINT16, &value, NULL); ++ ++ return value; ++} ++ ++unsigned int APIENTRY binn_object_uint32(void *obj, const char *key) { ++ unsigned int value; ++ ++ binn_object_get(obj, key, BINN_UINT32, &value, NULL); ++ ++ return value; ++} ++ ++uint64 APIENTRY binn_object_uint64(void *obj, const char *key) { ++ uint64 value; ++ ++ binn_object_get(obj, key, BINN_UINT64, &value, NULL); ++ ++ return value; ++} ++ ++float APIENTRY binn_object_float(void *obj, const char *key) { ++ float value; ++ ++ binn_object_get(obj, key, BINN_FLOAT32, &value, NULL); ++ ++ return value; ++} ++ ++double APIENTRY binn_object_double(void *obj, const char *key) { ++ double value; ++ ++ binn_object_get(obj, key, BINN_FLOAT64, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_object_bool(void *obj, const char *key) { ++ BOOL value; ++ ++ binn_object_get(obj, key, BINN_BOOL, &value, NULL); ++ ++ return value; ++} ++ ++BOOL APIENTRY binn_object_null(void *obj, const char *key) { ++ ++ return binn_object_get(obj, key, BINN_NULL, NULL, NULL); ++ ++} ++ ++char * APIENTRY binn_object_str(void *obj, const char *key) { ++ char *value; ++ ++ binn_object_get(obj, key, BINN_STRING, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_object_blob(void *obj, const char *key, int *psize) { ++ void *value; ++ ++ binn_object_get(obj, key, BINN_BLOB, &value, psize); ++ ++ return value; ++} ++ ++void * APIENTRY binn_object_list(void *obj, const char *key) { ++ void *value; ++ ++ binn_object_get(obj, key, BINN_LIST, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_object_map(void *obj, const char *key) { ++ void *value; ++ ++ binn_object_get(obj, key, BINN_MAP, &value, NULL); ++ ++ return value; ++} ++ ++void * APIENTRY binn_object_object(void *obj, const char *key) { ++ void *value; ++ ++ binn_object_get(obj, key, BINN_OBJECT, &value, NULL); ++ ++ return value; ++} ++ ++/*************************************************************************************/ ++/*************************************************************************************/ ++ ++BINN_PRIVATE binn * binn_alloc_item() { ++ binn *item; ++ item = (binn *) binn_malloc(sizeof(binn)); ++ if (item) { ++ memset(item, 0, sizeof(binn)); ++ item->header = BINN_MAGIC; ++ item->allocated = TRUE; ++ /* item->writable = FALSE; -- already zeroed */ ++ } ++ return item; ++} ++ ++/*************************************************************************************/ ++ ++binn * APIENTRY binn_value(int type, void *pvalue, int size, binn_mem_free freefn) { ++ int storage_type; ++ binn *item = binn_alloc_item(); ++ if (item) { ++ item->type = type; ++ binn_get_type_info(type, &storage_type, NULL); ++ switch (storage_type) { ++ case BINN_STORAGE_NOBYTES: ++ break; ++ case BINN_STORAGE_STRING: ++ if (size == 0) size = strlen((char*)pvalue) + 1; ++ /* fall through */ ++ case BINN_STORAGE_BLOB: ++ case BINN_STORAGE_CONTAINER: ++ if (freefn == BINN_TRANSIENT) { ++ item->ptr = binn_memdup(pvalue, size); ++ if (item->ptr == NULL) { ++ free_fn(item); ++ return NULL; ++ } ++ item->freefn = free_fn; ++ if (storage_type == BINN_STORAGE_STRING) size--; ++ } else { ++ item->ptr = pvalue; ++ item->freefn = freefn; ++ } ++ item->size = size; ++ break; ++ default: ++ item->ptr = &item->vint32; ++ copy_raw_value(pvalue, item->ptr, storage_type); ++ } ++ } ++ return item; ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_set_string(binn *item, char *str, binn_mem_free pfree) { ++ ++ if (item == NULL || str == NULL) return FALSE; ++ ++ if (pfree == BINN_TRANSIENT) { ++ item->ptr = binn_memdup(str, strlen(str) + 1); ++ if (item->ptr == NULL) return FALSE; ++ item->freefn = free_fn; ++ } else { ++ item->ptr = str; ++ item->freefn = pfree; ++ } ++ ++ item->type = BINN_STRING; ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_set_blob(binn *item, void *ptr, int size, binn_mem_free pfree) { ++ ++ if (item == NULL || ptr == NULL) return FALSE; ++ ++ if (pfree == BINN_TRANSIENT) { ++ item->ptr = binn_memdup(ptr, size); ++ if (item->ptr == NULL) return FALSE; ++ item->freefn = free_fn; ++ } else { ++ item->ptr = ptr; ++ item->freefn = pfree; ++ } ++ ++ item->type = BINN_BLOB; ++ item->size = size; ++ return TRUE; ++ ++} ++ ++/*************************************************************************************/ ++/*** READ CONVERTED VALUE ************************************************************/ ++/*************************************************************************************/ ++ ++#ifdef _MSC_VER ++#define atoi64 _atoi64 ++#else ++int64 atoi64(char *str) { ++ int64 retval; ++ int is_negative=0; ++ ++ if (*str == '-') { ++ is_negative = 1; ++ str++; ++ } ++ retval = 0; ++ for (; *str; str++) { ++ retval = 10 * retval + (*str - '0'); ++ } ++ if (is_negative) retval *= -1; ++ return retval; ++} ++#endif ++ ++/*****************************************************************************/ ++ ++BINN_PRIVATE BOOL is_integer(char *p) { ++ BOOL retval; ++ ++ if (p == NULL) return FALSE; ++ if (*p == '-') p++; ++ if (*p == 0) return FALSE; ++ ++ retval = TRUE; ++ ++ for (; *p; p++) { ++ if ( (*p < '0') || (*p > '9') ) { ++ retval = FALSE; ++ } ++ } ++ ++ return retval; ++} ++ ++/*****************************************************************************/ ++ ++BINN_PRIVATE BOOL is_float(char *p) { ++ BOOL retval, number_found=FALSE; ++ ++ if (p == NULL) return FALSE; ++ if (*p == '-') p++; ++ if (*p == 0) return FALSE; ++ ++ retval = TRUE; ++ ++ for (; *p; p++) { ++ if ((*p == '.') || (*p == ',')) { ++ if (!number_found) retval = FALSE; ++ } else if ( (*p >= '0') && (*p <= '9') ) { ++ number_found = TRUE; ++ } else { ++ return FALSE; ++ } ++ } ++ ++ return retval; ++} ++ ++/*************************************************************************************/ ++ ++BINN_PRIVATE BOOL is_bool_str(char *str, BOOL *pbool) { ++ int64 vint; ++ double vdouble; ++ ++ if (str == NULL || pbool == NULL) return FALSE; ++ ++ if (stricmp(str, "true") == 0) goto loc_true; ++ if (stricmp(str, "yes") == 0) goto loc_true; ++ if (stricmp(str, "on") == 0) goto loc_true; ++ /* if (stricmp(str, "1") == 0) goto loc_true; */ ++ ++ if (stricmp(str, "false") == 0) goto loc_false; ++ if (stricmp(str, "no") == 0) goto loc_false; ++ if (stricmp(str, "off") == 0) goto loc_false; ++ /* if (stricmp(str, "0") == 0) goto loc_false; */ ++ ++ if (is_integer(str)) { ++ vint = atoi64(str); ++ *pbool = (vint != 0) ? TRUE : FALSE; ++ return TRUE; ++ } else if (is_float(str)) { ++ vdouble = atof(str); ++ *pbool = (vdouble != 0) ? TRUE : FALSE; ++ return TRUE; ++ } ++ ++ return FALSE; ++ ++loc_true: ++ *pbool = TRUE; ++ return TRUE; ++ ++loc_false: ++ *pbool = FALSE; ++ return TRUE; ++ ++} ++ ++/* these three functions are used to ++ * suppress warnings about implicit conversions ++ * in binn_get_int32 and binn_get_int64 ++ * CJR 2/9/2023 ++ */ ++ ++float ++binn_cvt_int2float (int value) { ++ return (float)value; ++} ++ ++float ++binn_cvt_long2float (long int value) { ++ return (float)value; ++} ++ ++float ++binn_cvt_long2dbl (long int value) { ++ return (long long int)value; ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_get_int32(binn *value, int *pint) { ++ ++ if (value == NULL || pint == NULL) return FALSE; ++ ++ if (type_family(value->type) == BINN_FAMILY_INT) { ++ return copy_int_value(value->ptr, pint, value->type, BINN_INT32); ++ } ++ ++ switch (value->type) { ++ case BINN_FLOAT: ++ if ((value->vfloat < binn_cvt_int2float(INT32_MIN)) || (value->vfloat > binn_cvt_int2float(INT32_MAX))) return FALSE; ++ *pint = roundval(value->vfloat); ++ break; ++ case BINN_DOUBLE: ++ if ((value->vdouble < INT32_MIN) || (value->vdouble > INT32_MAX)) return FALSE; ++ *pint = roundval(value->vdouble); ++ break; ++ case BINN_STRING: ++ if (is_integer((char*)value->ptr)) ++ *pint = atoi((char*)value->ptr); ++ else if (is_float((char*)value->ptr)) ++ *pint = roundval(atof((char*)value->ptr)); ++ else ++ return FALSE; ++ break; ++ case BINN_BOOL: ++ *pint = value->vbool; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_get_int64(binn *value, int64 *pint) { ++ ++ if (value == NULL || pint == NULL) return FALSE; ++ ++ if (type_family(value->type) == BINN_FAMILY_INT) { ++ return copy_int_value(value->ptr, pint, value->type, BINN_INT64); ++ } ++ ++ switch (value->type) { ++ case BINN_FLOAT: ++ if ((value->vfloat < binn_cvt_long2float(INT64_MIN)) || (value->vfloat > binn_cvt_long2float(INT64_MAX))) return FALSE; ++ *pint = roundval(value->vfloat); ++ break; ++ case BINN_DOUBLE: ++ if ((value->vdouble < binn_cvt_long2dbl(INT64_MIN)) || (value->vdouble > binn_cvt_long2dbl(INT64_MAX))) return FALSE; ++ *pint = roundval(value->vdouble); ++ break; ++ case BINN_STRING: ++ if (is_integer((char*)value->ptr)) ++ *pint = atoi64((char*)value->ptr); ++ else if (is_float((char*)value->ptr)) ++ *pint = roundval(atof((char*)value->ptr)); ++ else ++ return FALSE; ++ break; ++ case BINN_BOOL: ++ *pint = value->vbool; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_get_double(binn *value, double *pfloat) { ++ int64 vint; ++ ++ if (value == NULL || pfloat == NULL) return FALSE; ++ ++ if (type_family(value->type) == BINN_FAMILY_INT) { ++ if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return FALSE; ++ *pfloat = (double) vint; ++ return TRUE; ++ } ++ ++ switch (value->type) { ++ case BINN_FLOAT: ++ *pfloat = value->vfloat; ++ break; ++ case BINN_DOUBLE: ++ *pfloat = value->vdouble; ++ break; ++ case BINN_STRING: ++ if (is_integer((char*)value->ptr)) ++ *pfloat = (double) atoi64((char*)value->ptr); ++ else if (is_float((char*)value->ptr)) ++ *pfloat = atof((char*)value->ptr); ++ else ++ return FALSE; ++ break; ++ case BINN_BOOL: ++ *pfloat = value->vbool; ++ break; ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_get_bool(binn *value, BOOL *pbool) { ++ int64 vint; ++ ++ if (value == NULL || pbool == NULL) return FALSE; ++ ++ if (type_family(value->type) == BINN_FAMILY_INT) { ++ if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return FALSE; ++ *pbool = (vint != 0) ? TRUE : FALSE; ++ return TRUE; ++ } ++ ++ switch (value->type) { ++ case BINN_BOOL: ++ *pbool = value->vbool; ++ break; ++ case BINN_FLOAT: ++ *pbool = (value->vfloat != 0) ? TRUE : FALSE; ++ break; ++ case BINN_DOUBLE: ++ *pbool = (value->vdouble != 0) ? TRUE : FALSE; ++ break; ++ case BINN_STRING: ++ return is_bool_str((char*)value->ptr, pbool); ++ default: ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/*************************************************************************************/ ++ ++char * APIENTRY binn_get_str(binn *value) { ++ int64 vint; ++ char buf[128]; ++ ++ if (value == NULL) return NULL; ++ ++ if (type_family(value->type) == BINN_FAMILY_INT) { ++ if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return NULL; ++ snprintf(buf, sizeof buf, "%" INT64_FORMAT, vint); ++ goto loc_convert_value; ++ } ++ ++ switch (value->type) { ++ case BINN_FLOAT: ++ value->vdouble = value->vfloat; ++ /* fall through */ ++ case BINN_DOUBLE: ++ snprintf(buf, sizeof buf, "%g", value->vdouble); ++ goto loc_convert_value; ++ case BINN_STRING: ++ return (char*) value->ptr; ++ case BINN_BOOL: ++ if (value->vbool) ++ strcpy(buf, "true"); ++ else ++ strcpy(buf, "false"); ++ goto loc_convert_value; ++ } ++ ++ return NULL; ++ ++loc_convert_value: ++ ++ /* value->vint64 = 0; */ ++ value->ptr = strdup(buf); ++ if (value->ptr == NULL) return NULL; ++ value->freefn = free; ++ value->type = BINN_STRING; ++ return (char*) value->ptr; ++ ++} ++ ++/*************************************************************************************/ ++/*** GENERAL FUNCTIONS ***************************************************************/ ++/*************************************************************************************/ ++ ++BOOL APIENTRY binn_is_container(binn *item) { ++ ++ if (item == NULL) return FALSE; ++ ++ switch (item->type) { ++ case BINN_LIST: ++ case BINN_MAP: ++ case BINN_OBJECT: ++ return TRUE; ++ default: ++ return FALSE; ++ } ++ ++} ++ ++/*************************************************************************************/ +diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +--- openssh-9.6p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/binn.h 2024-07-10 13:34:02.708358559 +0200 +@@ -0,0 +1,944 @@ ++ ++/* TO ENABLE INLINE FUNCTIONS: */ ++/* ON MSVC: enable the 'Inline Function Expansion' (/Ob2) compiler option, and maybe the */ ++/* 'Whole Program Optimitazion' (/GL), that requires the */ ++/* 'Link Time Code Generation' (/LTCG) linker option to be enabled too */ ++ ++#ifndef BINN_H ++#define BINN_H ++#include ++#include "config.h" ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define BINN_VERSION "3.0.0" /* using semantic versioning */ ++ ++#ifndef NULL ++#ifdef __cplusplus ++#define NULL 0 ++#else ++#define NULL ((void *)0) ++#endif ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef BOOL ++typedef int BOOL; ++#endif ++ ++#ifndef APIENTRY ++ #ifdef _WIN32 ++ #define APIENTRY __stdcall ++ #else ++ /* #define APIENTRY __attribute__((stdcall)) */ ++ #define APIENTRY ++ #endif ++#endif ++ ++#ifndef BINN_PRIVATE ++ #ifdef DEBUG ++ #define BINN_PRIVATE ++ #else ++ #define BINN_PRIVATE static ++ #endif ++#endif ++ ++#ifdef _MSC_VER ++ #define INLINE __inline ++ #define ALWAYS_INLINE __forceinline ++#else ++ /* you can change to 'extern inline' if using the gcc option -flto */ ++ #define INLINE static inline ++ #define ALWAYS_INLINE static inline __attribute__((always_inline)) ++#endif ++ ++#ifndef int64 ++#if defined(_MSC_VER) || defined(__BORLANDC__) ++ typedef __int64 int64; ++ typedef unsigned __int64 uint64; ++#else ++ typedef long long int int64; ++ typedef unsigned long long int uint64; ++#endif ++#endif ++ ++#ifdef _WIN32 ++#define INT64_FORMAT "I64i" ++#define UINT64_FORMAT "I64u" ++#define INT64_HEX_FORMAT "I64x" ++#else ++#define INT64_FORMAT "lli" ++#define UINT64_FORMAT "llu" ++#define INT64_HEX_FORMAT "llx" ++#endif ++ ++ ++/* BINN CONSTANTS ---------------------------------------- */ ++ ++#define INVALID_BINN 0 ++ ++/* Storage Data Types ------------------------------------ */ ++ ++#define BINN_STORAGE_NOBYTES 0x00 ++#define BINN_STORAGE_BYTE 0x20 /* 8 bits */ ++#define BINN_STORAGE_WORD 0x40 /* 16 bits -- the endianess (byte order) is automatically corrected */ ++#define BINN_STORAGE_DWORD 0x60 /* 32 bits -- the endianess (byte order) is automatically corrected */ ++#define BINN_STORAGE_QWORD 0x80 /* 64 bits -- the endianess (byte order) is automatically corrected */ ++#define BINN_STORAGE_STRING 0xA0 /* Are stored with null termination */ ++#define BINN_STORAGE_BLOB 0xC0 ++#define BINN_STORAGE_CONTAINER 0xE0 ++#define BINN_STORAGE_VIRTUAL 0x80000 ++ ++#define BINN_STORAGE_MIN BINN_STORAGE_NOBYTES ++#define BINN_STORAGE_MAX BINN_STORAGE_CONTAINER ++ ++#define BINN_STORAGE_MASK 0xE0 ++#define BINN_STORAGE_MASK16 0xE000 ++#define BINN_STORAGE_HAS_MORE 0x10 ++#define BINN_TYPE_MASK 0x0F ++#define BINN_TYPE_MASK16 0x0FFF ++ ++#define BINN_MAX_VALUE_MASK 0xFFFFF ++ ++ ++/* Data Formats ------------------------------------------ */ ++ ++#define BINN_LIST 0xE0 ++#define BINN_MAP 0xE1 ++#define BINN_OBJECT 0xE2 ++ ++#define BINN_NULL 0x00 ++#define BINN_TRUE 0x01 ++#define BINN_FALSE 0x02 ++ ++#define BINN_UINT8 0x20 /* (BYTE) (unsigned byte) Is the default format for the BYTE type */ ++#define BINN_INT8 0x21 /* (BYTE) (signed byte, from -128 to +127. The 0x80 is the sign bit, so the range in hex is from 0x80 [-128] to 0x7F [127], being 0x00 = 0 and 0xFF = -1) */ ++#define BINN_UINT16 0x40 /* (WORD) (unsigned integer) Is the default format for the WORD type */ ++#define BINN_INT16 0x41 /* (WORD) (signed integer) */ ++#define BINN_UINT32 0x60 /* (DWORD) (unsigned integer) Is the default format for the DWORD type */ ++#define BINN_INT32 0x61 /* (DWORD) (signed integer) */ ++#define BINN_UINT64 0x80 /* (QWORD) (unsigned integer) Is the default format for the QWORD type */ ++#define BINN_INT64 0x81 /* (QWORD) (signed integer) */ ++ ++#define BINN_SCHAR BINN_INT8 ++#define BINN_UCHAR BINN_UINT8 ++ ++#define BINN_STRING 0xA0 /* (STRING) Raw String */ ++#define BINN_DATETIME 0xA1 /* (STRING) iso8601 format -- YYYY-MM-DD HH:MM:SS */ ++#define BINN_DATE 0xA2 /* (STRING) iso8601 format -- YYYY-MM-DD */ ++#define BINN_TIME 0xA3 /* (STRING) iso8601 format -- HH:MM:SS */ ++#define BINN_DECIMAL 0xA4 /* (STRING) High precision number - used for generic decimal values and for those ones that cannot be represented in the float64 format. */ ++#define BINN_CURRENCYSTR 0xA5 /* (STRING) With currency unit/symbol - check for some iso standard format */ ++#define BINN_SINGLE_STR 0xA6 /* (STRING) Can be restored to float32 */ ++#define BINN_DOUBLE_STR 0xA7 /* (STRING) May be restored to float64 */ ++ ++#define BINN_FLOAT32 0x62 /* (DWORD) */ ++#define BINN_FLOAT64 0x82 /* (QWORD) */ ++#define BINN_FLOAT BINN_FLOAT32 ++#define BINN_SINGLE BINN_FLOAT32 ++#define BINN_DOUBLE BINN_FLOAT64 ++ ++#define BINN_CURRENCY 0x83 /* (QWORD) */ ++ ++#define BINN_BLOB 0xC0 /* (BLOB) Raw Blob */ ++ ++ ++/* virtual types: */ ++ ++#define BINN_BOOL 0x80061 /* (DWORD) The value may be 0 or 1 */ ++ ++#ifdef BINN_EXTENDED ++/* #define BINN_SINGLE 0x800A1 // (STRING) Can be restored to float32 */ ++/* #define BINN_DOUBLE 0x800A2 // (STRING) May be restored to float64 */ ++#endif ++ ++/* #define BINN_BINN 0x800E1 // (CONTAINER) */ ++/* #define BINN_BINN_BUFFER 0x800C1 // (BLOB) user binn. it's not open by the parser */ ++ ++ ++/* extended content types: */ ++ ++/* strings: */ ++ ++#define BINN_HTML 0xB001 ++#define BINN_XML 0xB002 ++#define BINN_JSON 0xB003 ++#define BINN_JAVASCRIPT 0xB004 ++#define BINN_CSS 0xB005 ++ ++/* blobs: */ ++ ++#define BINN_JPEG 0xD001 ++#define BINN_GIF 0xD002 ++#define BINN_PNG 0xD003 ++#define BINN_BMP 0xD004 ++ ++ ++/* type families */ ++#define BINN_FAMILY_NONE 0x00 ++#define BINN_FAMILY_NULL 0xf1 ++#define BINN_FAMILY_INT 0xf2 ++#define BINN_FAMILY_FLOAT 0xf3 ++#define BINN_FAMILY_STRING 0xf4 ++#define BINN_FAMILY_BLOB 0xf5 ++#define BINN_FAMILY_BOOL 0xf6 ++#define BINN_FAMILY_BINN 0xf7 ++ ++/* integer types related to signal */ ++#define BINN_SIGNED_INT 11 ++#define BINN_UNSIGNED_INT 22 ++ ++ ++typedef void (*binn_mem_free)(void*); ++#define BINN_STATIC ((binn_mem_free)0) ++#define BINN_TRANSIENT ((binn_mem_free)-1) ++ ++ ++/* --- BINN STRUCTURE -------------------------------------------------------------- */ ++ ++ ++struct binn_struct { ++ int header; /* this struct header holds the magic number (BINN_MAGIC) that identifies this memory block as a binn structure */ ++ BOOL allocated; /* the struct can be allocated using malloc_fn() or can be on the stack */ ++ BOOL writable; /* did it was create for writing? it can use the pbuf if not unified with ptr */ ++ BOOL dirty; /* the container header is not written to the buffer */ ++ /* */ ++ void *pbuf; /* use *ptr below? */ ++ BOOL pre_allocated; ++ int alloc_size; ++ int used_size; ++ /* */ ++ int type; ++ void *ptr; ++ int size; ++ int count; ++ /* */ ++ binn_mem_free freefn; /* used only when type == BINN_STRING or BINN_BLOB */ ++ /* */ ++ union { ++ signed char vint8; ++ signed short vint16; ++ signed int vint32; ++ int64 vint64; ++ unsigned char vuint8; ++ unsigned short vuint16; ++ unsigned int vuint32; ++ uint64 vuint64; ++ /* */ ++ signed char vchar; ++ unsigned char vuchar; ++ signed short vshort; ++ unsigned short vushort; ++ signed int vint; ++ unsigned int vuint; ++ /* */ ++ float vfloat; ++ double vdouble; ++ /* */ ++ BOOL vbool; ++ }; ++ /* */ ++ BOOL disable_int_compression; ++}; ++ ++typedef struct binn_struct binn; ++ ++ ++ ++/* --- GENERAL FUNCTIONS ---------------------------------------------------------- */ ++ ++char * APIENTRY binn_version(); ++ ++void APIENTRY binn_set_alloc_functions(void* (*new_malloc)(size_t), void* (*new_realloc)(void*,size_t), void (*new_free)(void*)); ++ ++int APIENTRY binn_create_type(int storage_type, int data_type_index); ++BOOL APIENTRY binn_get_type_info(int long_type, int *pstorage_type, int *pextra_type); ++ ++int APIENTRY binn_get_write_storage(int type); ++int APIENTRY binn_get_read_storage(int type); ++ ++BOOL APIENTRY binn_is_container(binn *item); ++ ++ ++/* --- WRITE FUNCTIONS ------------------------------------------------------------ */ ++ ++/* create a new binn allocating memory for the structure */ ++binn * APIENTRY binn_new(int type, int size, void *buffer); ++binn * APIENTRY binn_list(); ++binn * APIENTRY binn_map(); ++binn * APIENTRY binn_object(); ++ ++/* create a new binn storing the structure on the stack */ ++BOOL APIENTRY binn_create(binn *item, int type, int size, void *buffer); ++BOOL APIENTRY binn_create_list(binn *list); ++BOOL APIENTRY binn_create_map(binn *map); ++BOOL APIENTRY binn_create_object(binn *object); ++ ++/* create a new binn as a copy from another */ ++binn * APIENTRY binn_copy(void *old); ++ ++ ++BOOL APIENTRY binn_list_add_new(binn *list, binn *value); ++BOOL APIENTRY binn_map_set_new(binn *map, int id, binn *value); ++BOOL APIENTRY binn_object_set_new(binn *obj, const char *key, binn *value); ++ ++ ++/* extended interface */ ++ ++BOOL APIENTRY binn_list_add(binn *list, int type, void *pvalue, int size); ++BOOL APIENTRY binn_map_set(binn *map, int id, int type, void *pvalue, int size); ++BOOL APIENTRY binn_object_set(binn *obj, const char *key, int type, void *pvalue, int size); ++ ++ ++/* release memory */ ++ ++void APIENTRY binn_free(binn *item); ++void * APIENTRY binn_release(binn *item); /* free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later */ ++ ++ ++/* --- CREATING VALUES --------------------------------------------------- */ ++ ++binn * APIENTRY binn_value(int type, void *pvalue, int size, binn_mem_free freefn); ++ ++ALWAYS_INLINE binn * binn_int8(signed char value) { ++ return binn_value(BINN_INT8, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_int16(short value) { ++ return binn_value(BINN_INT16, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_int32(int value) { ++ return binn_value(BINN_INT32, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_int64(int64 value) { ++ return binn_value(BINN_INT64, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_uint8(unsigned char value) { ++ return binn_value(BINN_UINT8, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_uint16(unsigned short value) { ++ return binn_value(BINN_UINT16, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_uint32(unsigned int value) { ++ return binn_value(BINN_UINT32, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_uint64(uint64 value) { ++ return binn_value(BINN_UINT64, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_float(float value) { ++ return binn_value(BINN_FLOAT, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_double(double value) { ++ return binn_value(BINN_DOUBLE, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_bool(BOOL value) { ++ return binn_value(BINN_BOOL, &value, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_null() { ++ return binn_value(BINN_NULL, NULL, 0, NULL); ++} ++ALWAYS_INLINE binn * binn_string(char *str, binn_mem_free freefn) { ++ return binn_value(BINN_STRING, str, 0, freefn); ++} ++ALWAYS_INLINE binn * binn_blob(void *ptr, int size, binn_mem_free freefn) { ++ return binn_value(BINN_BLOB, ptr, size, freefn); ++} ++ ++ ++/* --- READ FUNCTIONS ------------------------------------------------------------- */ ++ ++/* these functions accept pointer to the binn structure and pointer to the binn buffer */ ++void * APIENTRY binn_ptr(void *ptr); ++int APIENTRY binn_size(void *ptr); ++int APIENTRY binn_type(void *ptr); ++int APIENTRY binn_count(void *ptr); ++ ++BOOL APIENTRY binn_is_valid(void *ptr, int *ptype, int *pcount, int *psize); ++/* the function returns the values (type, count and size) and they don't need to be ++ initialized. these values are read from the buffer. example: ++ ++ int type, count, size; ++ result = binn_is_valid(ptr, &type, &count, &size); ++*/ ++BOOL APIENTRY binn_is_valid_ex(void *ptr, int *ptype, int *pcount, int *psize); ++/* if some value is informed (type, count or size) then the function will check if ++ the value returned from the serialized data matches the informed value. otherwise ++ the values must be initialized to zero. example: ++ ++ int type=0, count=0, size = known_size; ++ result = binn_is_valid_ex(ptr, &type, &count, &size); ++*/ ++ ++BOOL APIENTRY binn_is_struct(void *ptr); ++ ++ ++/* Loading a binn buffer into a binn value - this is optional */ ++ ++BOOL APIENTRY binn_load(void *data, binn *item); /* on stack */ ++binn * APIENTRY binn_open(void *data); /* allocated */ ++ ++ ++/* easiest interface to use, but don't check if the value is there */ ++ ++signed char APIENTRY binn_list_int8(void *list, int pos); ++short APIENTRY binn_list_int16(void *list, int pos); ++int APIENTRY binn_list_int32(void *list, int pos); ++int64 APIENTRY binn_list_int64(void *list, int pos); ++unsigned char APIENTRY binn_list_uint8(void *list, int pos); ++unsigned short APIENTRY binn_list_uint16(void *list, int pos); ++unsigned int APIENTRY binn_list_uint32(void *list, int pos); ++uint64 APIENTRY binn_list_uint64(void *list, int pos); ++float APIENTRY binn_list_float(void *list, int pos); ++double APIENTRY binn_list_double(void *list, int pos); ++BOOL APIENTRY binn_list_bool(void *list, int pos); ++BOOL APIENTRY binn_list_null(void *list, int pos); ++char * APIENTRY binn_list_str(void *list, int pos); ++void * APIENTRY binn_list_blob(void *list, int pos, int *psize); ++void * APIENTRY binn_list_list(void *list, int pos); ++void * APIENTRY binn_list_map(void *list, int pos); ++void * APIENTRY binn_list_object(void *list, int pos); ++ ++signed char APIENTRY binn_map_int8(void *map, int id); ++short APIENTRY binn_map_int16(void *map, int id); ++int APIENTRY binn_map_int32(void *map, int id); ++int64 APIENTRY binn_map_int64(void *map, int id); ++unsigned char APIENTRY binn_map_uint8(void *map, int id); ++unsigned short APIENTRY binn_map_uint16(void *map, int id); ++unsigned int APIENTRY binn_map_uint32(void *map, int id); ++uint64 APIENTRY binn_map_uint64(void *map, int id); ++float APIENTRY binn_map_float(void *map, int id); ++double APIENTRY binn_map_double(void *map, int id); ++BOOL APIENTRY binn_map_bool(void *map, int id); ++BOOL APIENTRY binn_map_null(void *map, int id); ++char * APIENTRY binn_map_str(void *map, int id); ++void * APIENTRY binn_map_blob(void *map, int id, int *psize); ++void * APIENTRY binn_map_list(void *map, int id); ++void * APIENTRY binn_map_map(void *map, int id); ++void * APIENTRY binn_map_object(void *map, int id); ++ ++signed char APIENTRY binn_object_int8(void *obj, const char *key); ++short APIENTRY binn_object_int16(void *obj, const char *key); ++int APIENTRY binn_object_int32(void *obj, const char *key); ++int64 APIENTRY binn_object_int64(void *obj, const char *key); ++unsigned char APIENTRY binn_object_uint8(void *obj, const char *key); ++unsigned short APIENTRY binn_object_uint16(void *obj, const char *key); ++unsigned int APIENTRY binn_object_uint32(void *obj, const char *key); ++uint64 APIENTRY binn_object_uint64(void *obj, const char *key); ++float APIENTRY binn_object_float(void *obj, const char *key); ++double APIENTRY binn_object_double(void *obj, const char *key); ++BOOL APIENTRY binn_object_bool(void *obj, const char *key); ++BOOL APIENTRY binn_object_null(void *obj, const char *key); ++char * APIENTRY binn_object_str(void *obj, const char *key); ++void * APIENTRY binn_object_blob(void *obj, const char *key, int *psize); ++void * APIENTRY binn_object_list(void *obj, const char *key); ++void * APIENTRY binn_object_map(void *obj, const char *key); ++void * APIENTRY binn_object_object(void *obj, const char *key); ++ ++ ++/* return a pointer to an allocated binn structure - must be released with the free() function or equivalent set in binn_set_alloc_functions() */ ++binn * APIENTRY binn_list_value(void *list, int pos); ++binn * APIENTRY binn_map_value(void *map, int id); ++binn * APIENTRY binn_object_value(void *obj, const char *key); ++ ++/* read the value to a binn structure on the stack */ ++BOOL APIENTRY binn_list_get_value(void* list, int pos, binn *value); ++BOOL APIENTRY binn_map_get_value(void* map, int id, binn *value); ++BOOL APIENTRY binn_object_get_value(void *obj, const char *key, binn *value); ++ ++/* single interface - these functions check the data type */ ++BOOL APIENTRY binn_list_get(void *list, int pos, int type, void *pvalue, int *psize); ++BOOL APIENTRY binn_map_get(void *map, int id, int type, void *pvalue, int *psize); ++BOOL APIENTRY binn_object_get(void *obj, const char *key, int type, void *pvalue, int *psize); ++ ++/* these 3 functions return a pointer to the value and the data type */ ++/* they are thread-safe on big-endian devices */ ++/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ ++/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ ++void * APIENTRY binn_list_read(void *list, int pos, int *ptype, int *psize); ++void * APIENTRY binn_map_read(void *map, int id, int *ptype, int *psize); ++void * APIENTRY binn_object_read(void *obj, const char *key, int *ptype, int *psize); ++ ++ ++/* READ PAIR FUNCTIONS */ ++ ++/* these functions use base 1 in the 'pos' argument */ ++ ++/* on stack */ ++BOOL APIENTRY binn_map_get_pair(void *map, int pos, int *pid, binn *value); ++BOOL APIENTRY binn_object_get_pair(void *obj, int pos, char *pkey, binn *value); /* must free the memory returned in the pkey */ ++ ++/* allocated */ ++binn * APIENTRY binn_map_pair(void *map, int pos, int *pid); ++binn * APIENTRY binn_object_pair(void *obj, int pos, char *pkey); /* must free the memory returned in the pkey */ ++ ++/* these 2 functions return a pointer to the value and the data type */ ++/* they are thread-safe on big-endian devices */ ++/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ ++/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ ++void * APIENTRY binn_map_read_pair(void *ptr, int pos, int *pid, int *ptype, int *psize); ++void * APIENTRY binn_object_read_pair(void *ptr, int pos, char *pkey, int *ptype, int *psize); ++ ++ ++/* SEQUENTIAL READ FUNCTIONS */ ++ ++typedef struct binn_iter_struct { ++ unsigned char *pnext; ++ unsigned char *plimit; ++ int type; ++ int count; ++ int current; ++} binn_iter; ++ ++BOOL APIENTRY binn_iter_init(binn_iter *iter, void *pbuf, int type); ++ ++/* allocated */ ++binn * APIENTRY binn_list_next_value(binn_iter *iter); ++binn * APIENTRY binn_map_next_value(binn_iter *iter, int *pid); ++binn * APIENTRY binn_object_next_value(binn_iter *iter, char *pkey); /* the key must be declared as: char key[256]; */ ++ ++/* on stack */ ++BOOL APIENTRY binn_list_next(binn_iter *iter, binn *value); ++BOOL APIENTRY binn_map_next(binn_iter *iter, int *pid, binn *value); ++BOOL APIENTRY binn_object_next(binn_iter *iter, char *pkey, binn *value); /* the key must be declared as: char key[256]; */ ++ ++/* these 3 functions return a pointer to the value and the data type */ ++/* they are thread-safe on big-endian devices */ ++/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ ++/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ ++void * APIENTRY binn_list_read_next(binn_iter *iter, int *ptype, int *psize); ++void * APIENTRY binn_map_read_next(binn_iter *iter, int *pid, int *ptype, int *psize); ++void * APIENTRY binn_object_read_next(binn_iter *iter, char *pkey, int *ptype, int *psize); /* the key must be declared as: char key[256]; */ ++ ++ ++/* --- MACROS ------------------------------------------------------------ */ ++ ++ ++#define binn_is_writable(item) (item)->writable; ++ ++ ++/* set values on stack allocated binn structures */ ++ ++#define binn_set_null(item) do { (item)->type = BINN_NULL; } while (0) ++ ++#define binn_set_bool(item,value) do { (item)->type = BINN_BOOL; (item)->vbool = value; (item)->ptr = &((item)->vbool); } while (0) ++ ++#define binn_set_int(item,value) do { (item)->type = BINN_INT32; (item)->vint32 = value; (item)->ptr = &((item)->vint32); } while (0) ++#define binn_set_int64(item,value) do { (item)->type = BINN_INT64; (item)->vint64 = value; (item)->ptr = &((item)->vint64); } while (0) ++ ++#define binn_set_uint(item,value) do { (item)->type = BINN_UINT32; (item)->vuint32 = value; (item)->ptr = &((item)->vuint32); } while (0) ++#define binn_set_uint64(item,value) do { (item)->type = BINN_UINT64; (item)->vuint64 = value; (item)->ptr = &((item)->vuint64); } while (0) ++ ++#define binn_set_float(item,value) do { (item)->type = BINN_FLOAT; (item)->vfloat = value; (item)->ptr = &((item)->vfloat); } while (0) ++#define binn_set_double(item,value) do { (item)->type = BINN_DOUBLE; (item)->vdouble = value; (item)->ptr = &((item)->vdouble); } while (0) ++ ++/* #define binn_set_string(item,str,pfree) do { (item)->type = BINN_STRING; (item)->ptr = str; (item)->freefn = pfree; } while (0) */ ++/* #define binn_set_blob(item,ptr,size,pfree) do { (item)->type = BINN_BLOB; (item)->ptr = ptr; (item)->freefn = pfree; (item)->size = size; } while (0) */ ++BOOL APIENTRY binn_set_string(binn *item, char *str, binn_mem_free pfree); ++BOOL APIENTRY binn_set_blob(binn *item, void *ptr, int size, binn_mem_free pfree); ++ ++ ++/* #define binn_double(value) { (item)->type = BINN_DOUBLE; (item)->vdouble = value; (item)->ptr = &((item)->vdouble) } */ ++ ++ ++ ++/* FOREACH MACROS */ ++/* -------------- */ ++/* */ ++/* We must use these declarations inside the functions that will use the macros: */ ++/* */ ++/* binn_iter iter; */ ++/* binn value; */ ++/* char key[256]; // only for objects */ ++/* int id; // only for maps */ ++ ++#define binn_object_foreach(object, key, value) \ ++ binn_iter_init(&iter, object, BINN_OBJECT); \ ++ while (binn_object_next(&iter, key, &value)) ++ ++#define binn_map_foreach(map, id, value) \ ++ binn_iter_init(&iter, map, BINN_MAP); \ ++ while (binn_map_next(&iter, &id, &value)) ++ ++#define binn_list_foreach(list, value) \ ++ binn_iter_init(&iter, list, BINN_LIST); \ ++ while (binn_list_next(&iter, &value)) ++ ++/* If you need nested foreach loops, use the macros below for the nested loop */ ++/* Also we need to add an additional declaration on the function to hold the iterator */ ++/* We can add in the same line as the first iterator: */ ++/* */ ++/* binn_iter iter, iter2; */ ++ ++#define binn_object_foreach2(object, key, value) \ ++ binn_iter_init(&iter2, object, BINN_OBJECT); \ ++ while (binn_object_next(&iter2, key, &value)) ++ ++#define binn_map_foreach2(map, id, value) \ ++ binn_iter_init(&iter2, map, BINN_MAP); \ ++ while (binn_map_next(&iter2, &id, &value)) ++ ++#define binn_list_foreach2(list, value) \ ++ binn_iter_init(&iter2, list, BINN_LIST); \ ++ while (binn_list_next(&iter2, &value)) ++ ++ ++/*************************************************************************************/ ++/*** SET FUNCTIONS *******************************************************************/ ++/*************************************************************************************/ ++ ++ALWAYS_INLINE BOOL binn_list_add_int8(binn *list, signed char value) { ++ return binn_list_add(list, BINN_INT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_int16(binn *list, short value) { ++ return binn_list_add(list, BINN_INT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_int32(binn *list, int value) { ++ return binn_list_add(list, BINN_INT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_int64(binn *list, int64 value) { ++ return binn_list_add(list, BINN_INT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_uint8(binn *list, unsigned char value) { ++ return binn_list_add(list, BINN_UINT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_uint16(binn *list, unsigned short value) { ++ return binn_list_add(list, BINN_UINT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_uint32(binn *list, unsigned int value) { ++ return binn_list_add(list, BINN_UINT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_uint64(binn *list, uint64 value) { ++ return binn_list_add(list, BINN_UINT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_float(binn *list, float value) { ++ return binn_list_add(list, BINN_FLOAT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_double(binn *list, double value) { ++ return binn_list_add(list, BINN_FLOAT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_bool(binn *list, BOOL value) { ++ return binn_list_add(list, BINN_BOOL, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_null(binn *list) { ++ return binn_list_add(list, BINN_NULL, NULL, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_str(binn *list, char *str) { ++ return binn_list_add(list, BINN_STRING, str, 0); ++} ++ALWAYS_INLINE BOOL binn_list_add_blob(binn *list, void *ptr, int size) { ++ return binn_list_add(list, BINN_BLOB, ptr, size); ++} ++ALWAYS_INLINE BOOL binn_list_add_list(binn *list, void *list2) { ++ return binn_list_add(list, BINN_LIST, binn_ptr(list2), binn_size(list2)); ++} ++ALWAYS_INLINE BOOL binn_list_add_map(binn *list, void *map) { ++ return binn_list_add(list, BINN_MAP, binn_ptr(map), binn_size(map)); ++} ++ALWAYS_INLINE BOOL binn_list_add_object(binn *list, void *obj) { ++ return binn_list_add(list, BINN_OBJECT, binn_ptr(obj), binn_size(obj)); ++} ++ALWAYS_INLINE BOOL binn_list_add_value(binn *list, binn *value) { ++ return binn_list_add(list, value->type, binn_ptr(value), binn_size(value)); ++} ++ ++/*************************************************************************************/ ++ ++ALWAYS_INLINE BOOL binn_map_set_int8(binn *map, int id, signed char value) { ++ return binn_map_set(map, id, BINN_INT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_int16(binn *map, int id, short value) { ++ return binn_map_set(map, id, BINN_INT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_int32(binn *map, int id, int value) { ++ return binn_map_set(map, id, BINN_INT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_int64(binn *map, int id, int64 value) { ++ return binn_map_set(map, id, BINN_INT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_uint8(binn *map, int id, unsigned char value) { ++ return binn_map_set(map, id, BINN_UINT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_uint16(binn *map, int id, unsigned short value) { ++ return binn_map_set(map, id, BINN_UINT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_uint32(binn *map, int id, unsigned int value) { ++ return binn_map_set(map, id, BINN_UINT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_uint64(binn *map, int id, uint64 value) { ++ return binn_map_set(map, id, BINN_UINT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_float(binn *map, int id, float value) { ++ return binn_map_set(map, id, BINN_FLOAT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_double(binn *map, int id, double value) { ++ return binn_map_set(map, id, BINN_FLOAT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_bool(binn *map, int id, BOOL value) { ++ return binn_map_set(map, id, BINN_BOOL, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_null(binn *map, int id) { ++ return binn_map_set(map, id, BINN_NULL, NULL, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_str(binn *map, int id, char *str) { ++ return binn_map_set(map, id, BINN_STRING, str, 0); ++} ++ALWAYS_INLINE BOOL binn_map_set_blob(binn *map, int id, void *ptr, int size) { ++ return binn_map_set(map, id, BINN_BLOB, ptr, size); ++} ++ALWAYS_INLINE BOOL binn_map_set_list(binn *map, int id, void *list) { ++ return binn_map_set(map, id, BINN_LIST, binn_ptr(list), binn_size(list)); ++} ++ALWAYS_INLINE BOOL binn_map_set_map(binn *map, int id, void *map2) { ++ return binn_map_set(map, id, BINN_MAP, binn_ptr(map2), binn_size(map2)); ++} ++ALWAYS_INLINE BOOL binn_map_set_object(binn *map, int id, void *obj) { ++ return binn_map_set(map, id, BINN_OBJECT, binn_ptr(obj), binn_size(obj)); ++} ++ALWAYS_INLINE BOOL binn_map_set_value(binn *map, int id, binn *value) { ++ return binn_map_set(map, id, value->type, binn_ptr(value), binn_size(value)); ++} ++ ++/*************************************************************************************/ ++ ++ALWAYS_INLINE BOOL binn_object_set_int8(binn *obj, const char *key, signed char value) { ++ return binn_object_set(obj, key, BINN_INT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_int16(binn *obj, const char *key, short value) { ++ return binn_object_set(obj, key, BINN_INT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_int32(binn *obj, const char *key, int value) { ++ return binn_object_set(obj, key, BINN_INT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_int64(binn *obj, const char *key, int64 value) { ++ return binn_object_set(obj, key, BINN_INT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_uint8(binn *obj, const char *key, unsigned char value) { ++ return binn_object_set(obj, key, BINN_UINT8, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_uint16(binn *obj, const char *key, unsigned short value) { ++ return binn_object_set(obj, key, BINN_UINT16, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_uint32(binn *obj, const char *key, unsigned int value) { ++ return binn_object_set(obj, key, BINN_UINT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_uint64(binn *obj, const char *key, uint64 value) { ++ return binn_object_set(obj, key, BINN_UINT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_float(binn *obj, const char *key, float value) { ++ return binn_object_set(obj, key, BINN_FLOAT32, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_double(binn *obj, const char *key, double value) { ++ return binn_object_set(obj, key, BINN_FLOAT64, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_bool(binn *obj, const char *key, BOOL value) { ++ return binn_object_set(obj, key, BINN_BOOL, &value, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_null(binn *obj, const char *key) { ++ return binn_object_set(obj, key, BINN_NULL, NULL, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_str(binn *obj, const char *key, char *str) { ++ return binn_object_set(obj, key, BINN_STRING, str, 0); ++} ++ALWAYS_INLINE BOOL binn_object_set_blob(binn *obj, const char *key, void *ptr, int size) { ++ return binn_object_set(obj, key, BINN_BLOB, ptr, size); ++} ++ALWAYS_INLINE BOOL binn_object_set_list(binn *obj, const char *key, void *list) { ++ return binn_object_set(obj, key, BINN_LIST, binn_ptr(list), binn_size(list)); ++} ++ALWAYS_INLINE BOOL binn_object_set_map(binn *obj, const char *key, void *map) { ++ return binn_object_set(obj, key, BINN_MAP, binn_ptr(map), binn_size(map)); ++} ++ALWAYS_INLINE BOOL binn_object_set_object(binn *obj, const char *key, void *obj2) { ++ return binn_object_set(obj, key, BINN_OBJECT, binn_ptr(obj2), binn_size(obj2)); ++} ++ALWAYS_INLINE BOOL binn_object_set_value(binn *obj, const char *key, binn *value) { ++ return binn_object_set(obj, key, value->type, binn_ptr(value), binn_size(value)); ++} ++ ++/*************************************************************************************/ ++/*** GET FUNCTIONS *******************************************************************/ ++/*************************************************************************************/ ++ ++ALWAYS_INLINE BOOL binn_list_get_int8(void *list, int pos, signed char *pvalue) { ++ return binn_list_get(list, pos, BINN_INT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_int16(void *list, int pos, short *pvalue) { ++ return binn_list_get(list, pos, BINN_INT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_int32(void *list, int pos, int *pvalue) { ++ return binn_list_get(list, pos, BINN_INT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_int64(void *list, int pos, int64 *pvalue) { ++ return binn_list_get(list, pos, BINN_INT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_uint8(void *list, int pos, unsigned char *pvalue) { ++ return binn_list_get(list, pos, BINN_UINT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_uint16(void *list, int pos, unsigned short *pvalue) { ++ return binn_list_get(list, pos, BINN_UINT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_uint32(void *list, int pos, unsigned int *pvalue) { ++ return binn_list_get(list, pos, BINN_UINT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_uint64(void *list, int pos, uint64 *pvalue) { ++ return binn_list_get(list, pos, BINN_UINT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_float(void *list, int pos, float *pvalue) { ++ return binn_list_get(list, pos, BINN_FLOAT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_double(void *list, int pos, double *pvalue) { ++ return binn_list_get(list, pos, BINN_FLOAT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_bool(void *list, int pos, BOOL *pvalue) { ++ return binn_list_get(list, pos, BINN_BOOL, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_str(void *list, int pos, char **pvalue) { ++ return binn_list_get(list, pos, BINN_STRING, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_blob(void *list, int pos, void **pvalue, int *psize) { ++ return binn_list_get(list, pos, BINN_BLOB, pvalue, psize); ++} ++ALWAYS_INLINE BOOL binn_list_get_list(void *list, int pos, void **pvalue) { ++ return binn_list_get(list, pos, BINN_LIST, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_map(void *list, int pos, void **pvalue) { ++ return binn_list_get(list, pos, BINN_MAP, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_list_get_object(void *list, int pos, void **pvalue) { ++ return binn_list_get(list, pos, BINN_OBJECT, pvalue, NULL); ++} ++ ++/***************************************************************************/ ++ ++ALWAYS_INLINE BOOL binn_map_get_int8(void *map, int id, signed char *pvalue) { ++ return binn_map_get(map, id, BINN_INT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_int16(void *map, int id, short *pvalue) { ++ return binn_map_get(map, id, BINN_INT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_int32(void *map, int id, int *pvalue) { ++ return binn_map_get(map, id, BINN_INT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_int64(void *map, int id, int64 *pvalue) { ++ return binn_map_get(map, id, BINN_INT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_uint8(void *map, int id, unsigned char *pvalue) { ++ return binn_map_get(map, id, BINN_UINT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_uint16(void *map, int id, unsigned short *pvalue) { ++ return binn_map_get(map, id, BINN_UINT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_uint32(void *map, int id, unsigned int *pvalue) { ++ return binn_map_get(map, id, BINN_UINT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_uint64(void *map, int id, uint64 *pvalue) { ++ return binn_map_get(map, id, BINN_UINT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_float(void *map, int id, float *pvalue) { ++ return binn_map_get(map, id, BINN_FLOAT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_double(void *map, int id, double *pvalue) { ++ return binn_map_get(map, id, BINN_FLOAT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_bool(void *map, int id, BOOL *pvalue) { ++ return binn_map_get(map, id, BINN_BOOL, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_str(void *map, int id, char **pvalue) { ++ return binn_map_get(map, id, BINN_STRING, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_blob(void *map, int id, void **pvalue, int *psize) { ++ return binn_map_get(map, id, BINN_BLOB, pvalue, psize); ++} ++ALWAYS_INLINE BOOL binn_map_get_list(void *map, int id, void **pvalue) { ++ return binn_map_get(map, id, BINN_LIST, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_map(void *map, int id, void **pvalue) { ++ return binn_map_get(map, id, BINN_MAP, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_map_get_object(void *map, int id, void **pvalue) { ++ return binn_map_get(map, id, BINN_OBJECT, pvalue, NULL); ++} ++ ++/***************************************************************************/ ++ ++/* usage: */ ++/* if (binn_object_get_int32(obj, "key", &value) == FALSE) xxx; */ ++ ++ALWAYS_INLINE BOOL binn_object_get_int8(void *obj, const char *key, signed char *pvalue) { ++ return binn_object_get(obj, key, BINN_INT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_int16(void *obj, const char *key, short *pvalue) { ++ return binn_object_get(obj, key, BINN_INT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_int32(void *obj, const char *key, int *pvalue) { ++ return binn_object_get(obj, key, BINN_INT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_int64(void *obj, const char *key, int64 *pvalue) { ++ return binn_object_get(obj, key, BINN_INT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_uint8(void *obj, const char *key, unsigned char *pvalue) { ++ return binn_object_get(obj, key, BINN_UINT8, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_uint16(void *obj, const char *key, unsigned short *pvalue) { ++ return binn_object_get(obj, key, BINN_UINT16, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_uint32(void *obj, const char *key, unsigned int *pvalue) { ++ return binn_object_get(obj, key, BINN_UINT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_uint64(void *obj, const char *key, uint64 *pvalue) { ++ return binn_object_get(obj, key, BINN_UINT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_float(void *obj, const char *key, float *pvalue) { ++ return binn_object_get(obj, key, BINN_FLOAT32, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_double(void *obj, const char *key, double *pvalue) { ++ return binn_object_get(obj, key, BINN_FLOAT64, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_bool(void *obj, const char *key, BOOL *pvalue) { ++ return binn_object_get(obj, key, BINN_BOOL, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_str(void *obj, const char *key, char **pvalue) { ++ return binn_object_get(obj, key, BINN_STRING, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_blob(void *obj, const char *key, void **pvalue, int *psize) { ++ return binn_object_get(obj, key, BINN_BLOB, pvalue, psize); ++} ++ALWAYS_INLINE BOOL binn_object_get_list(void *obj, const char *key, void **pvalue) { ++ return binn_object_get(obj, key, BINN_LIST, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_map(void *obj, const char *key, void **pvalue) { ++ return binn_object_get(obj, key, BINN_MAP, pvalue, NULL); ++} ++ALWAYS_INLINE BOOL binn_object_get_object(void *obj, const char *key, void **pvalue) { ++ return binn_object_get(obj, key, BINN_OBJECT, pvalue, NULL); ++} ++ ++/***************************************************************************/ ++ ++BOOL APIENTRY binn_get_int32(binn *value, int *pint); ++BOOL APIENTRY binn_get_int64(binn *value, int64 *pint); ++BOOL APIENTRY binn_get_double(binn *value, double *pfloat); ++BOOL APIENTRY binn_get_bool(binn *value, BOOL *pbool); ++char * APIENTRY binn_get_str(binn *value); ++ ++/* boolean string values: */ ++/* 1, true, yes, on */ ++/* 0, false, no, off */ ++ ++/* boolean number values: */ ++/* !=0 [true] */ ++/* ==0 [false] */ ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* BINN_H */ +diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c +--- openssh-9.6p1.orig/channels.c 2024-07-10 13:32:39.521111580 +0200 ++++ openssh-9.6p1/channels.c 2024-07-10 13:45:10.402355836 +0200 +@@ -104,6 +104,11 @@ + /* Minimum port number for X11 forwarding */ + #define X11_PORT_MIN 6000 + ++/* in version of OpenSSH later than 8.8 if we advertise a window ++ * 16MB or larger is causes a pathological behaviour that reduces ++ * throughput. This is not a great solution. */ ++#define NON_HPN_WINDOW_MAX (15 * 1024 * 1024) ++ + /* Per-channel callback for pre/post IO actions */ + typedef void chan_fn(struct ssh *, Channel *c); + +@@ -229,6 +234,9 @@ + /* Setup helper */ + static void channel_handler_init(struct ssh_channels *sc); + ++/* default values to enable hpn and the initial buffer size */ ++static int hpn_disabled = 0; ++ + /* -- channel core */ + + void +@@ -484,6 +492,9 @@ + (c->output = sshbuf_new()) == NULL || + (c->extended = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); ++ sshbuf_relabel(c->input, "channel input"); ++ sshbuf_relabel(c->output, "channel output"); ++ sshbuf_relabel(c->extended, "channel extended"); + if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) + fatal_fr(r, "sshbuf_set_max_size"); + c->ostate = CHAN_OUTPUT_OPEN; +@@ -495,6 +506,7 @@ + c->local_window = window; + c->local_window_max = window; + c->local_maxpacket = maxpack; ++ c->dynamic_window = 0; + c->remote_name = xstrdup(remote_name); + c->ctl_chan = -1; + c->delayed = 1; /* prevent call to channel_post handler */ +@@ -1220,6 +1232,33 @@ + c->io_want = SSH_CHAN_IO_SOCK_W; + } + ++static int ++channel_tcpwinsz(struct ssh *ssh) ++{ ++ u_int32_t tcpwinsz = 0; ++ socklen_t optsz = sizeof(tcpwinsz); ++ int ret = -1; ++ ++ /* if we aren't on a socket return 128KB */ ++ if (!ssh_packet_connection_is_on_socket(ssh)) ++ return 128 * 1024; ++ ++ ret = getsockopt(ssh_packet_get_connection_in(ssh), ++ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); ++ /* return no more than SSHBUF_SIZE_MAX (currently 256MB) */ ++ if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX) ++ tcpwinsz = SSHBUF_SIZE_MAX; ++ /* if the remote side is OpenSSH after version 8.8 we need to restrict ++ * the size of the advertised window. Now this means that any HPN to non-HPN ++ * connection will be window limited to 15MB of receive space. This is a ++ * non-optimal solution. ++ */ ++ ++ if ((ssh->compat & SSH_RESTRICT_WINDOW) && (tcpwinsz > NON_HPN_WINDOW_MAX)) ++ tcpwinsz = NON_HPN_WINDOW_MAX; ++ return (tcpwinsz); ++} ++ + static void + channel_pre_open(struct ssh *ssh, Channel *c) + { +@@ -2321,24 +2360,55 @@ + { + int r; + ++ /* going back to a set denominator of 2. Prior versions had a ++ * dynamic denominator based on the size of the buffer. This may ++ * have been helpful in some situations but it isn't helping in ++ * the general case -cjr 6/30/23 */ + if (c->type == SSH_CHANNEL_OPEN && + !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && + ((c->local_window_max - c->local_window > + c->local_maxpacket*3) || + c->local_window < c->local_window_max/2) && + c->local_consumed > 0) { ++ u_int addition = 0; ++ u_int32_t tcpwinsz = channel_tcpwinsz(ssh); ++ /* adjust max window size if we are in a dynamic environment ++ * and the tcp receive buffer is larger than the ssh window */ ++ if (c->dynamic_window && (tcpwinsz > c->local_window_max)) { ++ if (c->hpn_buffer_limit) { ++ /* limit window growth to prevent buffer issues ++ * still not sure what is causing the buffer issues ++ * but it may be an issue with c->local_consumed not being ++ * handled properly in the cases of bottenecked IO to the ++ * wfd endpoint. This does have an impact on throughput ++ * as we're essentially maxing out local_window_max to ++ * half of the window size */ ++ addition = (tcpwinsz/2 - c->local_window_max); ++ } ++ else { ++ /* aggressively grow the window */ ++ addition = tcpwinsz - c->local_window_max; ++ } ++ c->local_window_max += addition; ++ /* doesn't look like we need these ++ * sshbuf_set_window_max(c->output, c->local_window_max); ++ * sshbuf_set_window_max(c->input, c->local_window_max); ++ */ ++ debug("Channel %d: Window growth to %d by %d bytes",c->self, ++ c->local_window_max, addition); ++ } + if (!c->have_remote_id) + fatal_f("channel %d: no remote id", c->self); + if ((r = sshpkt_start(ssh, + SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 || + (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || +- (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || ++ (r = sshpkt_put_u32(ssh, c->local_consumed + addition)) != 0 || + (r = sshpkt_send(ssh)) != 0) { + fatal_fr(r, "channel %i", c->self); + } + debug2("channel %d: window %d sent adjust %d", c->self, +- c->local_window, c->local_consumed); +- c->local_window += c->local_consumed; ++ c->local_window, c->local_consumed + addition); ++ c->local_window += c->local_consumed + addition; + c->local_consumed = 0; + } + return 1; +@@ -2926,9 +2996,7 @@ + * in use. + */ + if (CHANNEL_EFD_INPUT_ACTIVE(c)) +- debug2("channel %d: " +- "ibuf_empty delayed efd %d/(%zu)", +- c->self, c->efd, sshbuf_len(c->extended)); ++ {} + else + chan_ibuf_empty(ssh, c); + } +@@ -3638,7 +3706,7 @@ + error_fr(r, "parse adjust"); + ssh_packet_disconnect(ssh, "Invalid window adjust message"); + } +- debug2("channel %d: rcvd adjust %u", c->self, adjust); ++ debug3_f("channel %d: rcvd adjust %u", c->self, adjust); + if ((new_rwin = c->remote_window + adjust) < c->remote_window) { + fatal("channel %d: adjust %u overflows remote window %u", + c->self, adjust, c->remote_window); +@@ -3753,6 +3821,13 @@ + return addr; + } + ++void ++channel_set_hpn_disabled(int external_hpn_disabled) ++{ ++ hpn_disabled = external_hpn_disabled; ++ debug("HPN Disabled: %d", hpn_disabled); ++} ++ + static int + channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, + struct Forward *fwd, int *allocated_listen_port, +diff -Nur openssh-9.6p1.orig/channels.h openssh-9.6p1/channels.h +--- openssh-9.6p1.orig/channels.h 2024-07-10 13:32:39.484111470 +0200 ++++ openssh-9.6p1/channels.h 2024-07-10 13:34:02.710358565 +0200 +@@ -174,6 +174,8 @@ + u_int local_window_max; + u_int local_consumed; + u_int local_maxpacket; ++ int dynamic_window; ++ int hpn_buffer_limit; + int extended_usage; + int single_connection; + +@@ -255,7 +257,7 @@ + #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) + + /* Read buffer size */ +-#define CHAN_RBUF (16*1024) ++#define CHAN_RBUF CHAN_SES_PACKET_DEFAULT + + /* Maximum size for direct reads to buffers */ + #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT +@@ -398,4 +400,6 @@ + void chan_write_failed(struct ssh *, Channel *); + void chan_obuf_empty(struct ssh *, Channel *); + ++/* hpn handler */ ++void channel_set_hpn_disabled(int); + #endif +diff -Nur openssh-9.6p1.orig/cipher.c openssh-9.6p1/cipher.c +--- openssh-9.6p1.orig/cipher.c 2024-07-10 13:32:39.541111639 +0200 ++++ openssh-9.6p1/cipher.c 2024-07-10 13:50:07.565252024 +0200 +@@ -48,23 +48,39 @@ + #include "sshbuf.h" + #include "ssherr.h" + #include "digest.h" ++#include "log.h" + + #include "openbsd-compat/openssl-compat.h" + ++/* for provider functions */ ++#ifdef WITH_OPENSSL3 ++#include ++#include ++#include ++#endif ++ + #ifndef WITH_OPENSSL + #define EVP_CIPHER_CTX void ++#define EVP_CIPHER void ++#else ++/* for multi-threaded aes-ctr cipher */ ++extern const EVP_CIPHER *evp_aes_ctr_mt(void); + #endif + + struct sshcipher_ctx { + int plaintext; + int encrypt; + EVP_CIPHER_CTX *evp; ++ const EVP_CIPHER *meth_ptr; /*used to free memory in aes_ctr_mt */ + struct chachapoly_ctx *cp_ctx; ++#ifdef WITH_OPENSSL ++ struct chachapoly_ctx_mt *cp_ctx_mt; ++#endif + struct aesctr_ctx ac_ctx; /* XXX union with evp? */ + const struct sshcipher *cipher; + }; + +-static const struct sshcipher ciphers[] = { ++static struct sshcipher ciphers[] = { + #ifdef WITH_OPENSSL + #ifndef OPENSSL_NO_DES + { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, +@@ -86,6 +102,10 @@ + #endif + { "chacha20-poly1305@openssh.com", + 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL }, ++#ifdef WITH_OPENSSL ++ { "chacha20-poly1305-mt@hpnssh.org", ++ 8, 64, 0, 16, CFLAG_CHACHAPOLY|CFLAG_MT, NULL }, ++#endif + { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, + + { NULL, 0, 0, 0, 0, 0, NULL } +@@ -131,12 +151,63 @@ + #endif + } + ++/* used to get the cipher name when we are testing to ++ * see if we can move from a serial to parallel cipher ++ * only called in cipher-switch.c ++ */ ++const char * ++cipher_ctx_name(const struct sshcipher_ctx *cc) ++{ ++ return cc->cipher->name; ++} ++ + u_int + cipher_blocksize(const struct sshcipher *c) + { + return (c->block_size); + } + ++uint64_t ++cipher_rekey_blocks(const struct sshcipher *c) ++{ ++ /* ++ * Chacha20-Poly1305 does not benefit from data-based rekeying, ++ * per "The Security of ChaCha20-Poly1305 in the Multi-user Setting", ++ * Degabriele, J. P., Govinden, J, Gunther, F. and Paterson K. ++ * ACM CCS 2021; https://eprint.iacr.org/2023/085.pdf ++ * ++ * Cryptanalysis aside, we do still want do need to prevent the SSH ++ * sequence number wrapping and also to rekey to provide some ++ * protection for long lived sessions against key disclosure at the ++ * endpoints, so arrange for rekeying every 2**32 blocks as the ++ * 128-bit block ciphers do (i.e. every 32GB data). ++ */ ++ if ((c->flags & CFLAG_CHACHAPOLY) != 0) ++ return (uint64_t)1 << 32; ++ ++ /* there is no actual need to rekey the NULL cipher but ++ * rekeying is a necessary step. In part, as mentioned above, ++ * to keep the seqnr from wrapping. So we set it to the ++ * maximum possible -cjr 4/10/23 */ ++ if ((c->flags & CFLAG_NONE) != 0) ++ return (uint64_t)1 << 32; ++ ++ /* ++ * The 2^(blocksize*2) limit is too expensive for 3DES, ++ * so enforce a 1GB data limit for small blocksizes. ++ * See discussion in RFC4344 section 3.2. ++ */ ++ if (c->block_size < 16) ++ return ((uint64_t)1 << 30) / c->block_size; ++ /* ++ * Otherwise, use the RFC4344 s3.2 recommendation of 2**(L/4) blocks ++ * before rekeying where L is the blocksize in bits. ++ * Most other ciphers have a 128 bit blocksize, so this equates to ++ * 2**32 blocks / 64GB data. ++ */ ++ return (uint64_t)1 << (c->block_size * 2); ++} ++ + u_int + cipher_keylen(const struct sshcipher *c) + { +@@ -180,10 +251,10 @@ + return cc->plaintext; + } + +-const struct sshcipher * ++struct sshcipher * + cipher_by_name(const char *name) + { +- const struct sshcipher *c; ++ struct sshcipher *c; + for (c = ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; +@@ -205,7 +276,8 @@ + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + c = cipher_by_name(p); +- if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) { ++ if (c == NULL || ((c->flags & CFLAG_INTERNAL) != 0 && ++ (c->flags & CFLAG_NONE) != 0)) { + free(cipher_list); + return 0; + } +@@ -226,7 +298,7 @@ + int + cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, + const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, +- int do_encrypt) ++ u_int seqnr, int do_encrypt, int enable_threads) + { + struct sshcipher_ctx *cc = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; +@@ -241,6 +313,7 @@ + + cc->plaintext = (cipher->flags & CFLAG_NONE) != 0; + cc->encrypt = do_encrypt; ++ cc->meth_ptr = NULL; + + if (keylen < cipher->key_len || + (iv != NULL && ivlen < cipher_ivlen(cipher))) { +@@ -250,8 +323,19 @@ + + cc->cipher = cipher; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ++#ifdef WITH_OPENSSL ++ if ((cc->cipher->flags & CFLAG_MT) != 0) { ++ cc->cp_ctx_mt = chachapoly_new_mt(seqnr, key, keylen); ++ ret = cc->cp_ctx_mt != NULL ? 0 : ++ SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ cc->cp_ctx = chachapoly_new(key, keylen); ++ ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT; ++ } ++#else + cc->cp_ctx = chachapoly_new(key, keylen); + ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT; ++#endif + goto out; + } + if ((cc->cipher->flags & CFLAG_NONE) != 0) { +@@ -273,6 +357,53 @@ + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } ++ /* the following block is for AES-CTR-MT cipher switching ++ * if we are using the ctr cipher and we are post-auth then ++ * start the threaded cipher. If OSSL supports providers (OSSL 3.0+) then ++ * we load our hpnssh provider. If it doesn't (OSSL < 1.1) then we use the ++ * _meth_new process found in cipher-ctr-mt.c */ ++ if (strstr(cc->cipher->name, "ctr") && enable_threads) { ++#ifdef WITH_OPENSSL3 ++ /* this version of openssl uses providers */ ++ OSSL_LIB_CTX *aes_lib = NULL; /* probably not needed */ ++ OSSL_PROVIDER *aes_mt_provider = NULL; ++ type = NULL; ++ ++ if (OSSL_PROVIDER_add_builtin(aes_lib, "hpnssh", ++ OSSL_provider_init) != 1) { ++ fatal("Failed to add HPNSSH provider for AES-CTR"); ++ } ++ aes_mt_provider = OSSL_PROVIDER_load(aes_lib, "hpnssh"); ++ ++ if (aes_mt_provider != NULL) { ++ /* use the previous key length to determine which cipher to load */ ++ if (cipher->key_len == 32) ++ type = EVP_CIPHER_fetch(aes_lib, "aes_ctr_mt_256", NULL); ++ if (cipher->key_len == 24) ++ type = EVP_CIPHER_fetch(aes_lib, "aes_ctr_mt_192", NULL); ++ if (cipher->key_len == 16) ++ type = EVP_CIPHER_fetch(aes_lib, "aes_ctr_mt_128", NULL); ++ if (type == NULL) { ++ ERR_print_errors_fp(stderr); ++ fatal("FAILED TO LOAD aes_ctr_mt"); ++ } else { ++ debug("LOADED aes_ctr_mt"); ++ } ++ } ++ else { ++ ERR_print_errors_fp(stderr); ++ fatal("Failed to load HPN-SSH AES-CTR-MT provider."); ++ } ++#else ++ type = (*evp_aes_ctr_mt)(); /* see cipher-ctr-mt.c */ ++ /* we need to free this later if using aes_ctr_mt ++ * under OSSL 1.1. Honestly, we could avoid this by making ++ * it a global in cipher-ctr_mt.c and exporting it here ++ * then we'd only have to call EVP_CIPHER_meth once but this ++ * works for now. TODO: This. cjr 02.22.2023 */ ++ cc->meth_ptr = type; ++#endif /* WITH_OPENSSL3 */ ++ } /* if (strstr()) */ + if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, + (do_encrypt == CIPHER_ENCRYPT)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; +@@ -327,6 +458,12 @@ + const u_char *src, u_int len, u_int aadlen, u_int authlen) + { + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ++#ifdef WITH_OPENSSL ++ if ((cc->cipher->flags & CFLAG_MT) != 0) { ++ return chachapoly_crypt_mt(cc->cp_ctx_mt, seqnr, dest, ++ src, len, aadlen, authlen, cc->encrypt); ++ } ++#endif + return chachapoly_crypt(cc->cp_ctx, seqnr, dest, src, + len, aadlen, authlen, cc->encrypt); + } +@@ -389,9 +526,16 @@ + cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, + const u_char *cp, u_int len) + { +- if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) ++ if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ++#ifdef WITH_OPENSSL ++ if ((cc->cipher->flags & CFLAG_MT) != 0) { ++ return chachapoly_get_length_mt(cc->cp_ctx_mt, plenp, ++ seqnr, cp, len); ++ } ++#endif + return chachapoly_get_length(cc->cp_ctx, plenp, seqnr, + cp, len); ++ } + if (len < 4) + return SSH_ERR_MESSAGE_INCOMPLETE; + *plenp = PEEK_U32(cp); +@@ -404,13 +548,33 @@ + if (cc == NULL || cc->cipher == NULL) + return; + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ++#ifdef WITH_OPENSSL ++ if ((cc->cipher->flags & CFLAG_MT) != 0) { ++ chachapoly_free_mt(cc->cp_ctx_mt); ++ cc->cp_ctx_mt = NULL; ++ } else { ++ chachapoly_free(cc->cp_ctx); ++ cc->cp_ctx = NULL; ++ } ++#else + chachapoly_free(cc->cp_ctx); + cc->cp_ctx = NULL; ++#endif + } else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) + explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); + #ifdef WITH_OPENSSL + EVP_CIPHER_CTX_free(cc->evp); + cc->evp = NULL; ++ /* if meth_ptr isn't null then we are using the aes_ctr_mt ++ * evp_cipher_meth_new() in cipher-ctr-mt.c under OSSL 1.1 ++ * if we don't explicitly free it then, even though we free ++ * the ctx it is a part of it doesn't get freed. So... ++ * cjr 2/7/2023 ++ */ ++ if (cc->meth_ptr != NULL) { ++ EVP_CIPHER_meth_free((void *)(EVP_CIPHER *)cc->meth_ptr); ++ cc->meth_ptr = NULL; ++ } + #endif + freezero(cc, sizeof(*cc)); + } +diff -Nur openssh-9.6p1.orig/cipher-chachapoly.c openssh-9.6p1/cipher-chachapoly.c +--- openssh-9.6p1.orig/cipher-chachapoly.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/cipher-chachapoly.c 2024-07-10 13:34:02.711358567 +0200 +@@ -88,7 +88,7 @@ + if (!do_encrypt) { + const u_char *tag = src + aadlen + len; + +- poly1305_auth(expected_tag, src, aadlen + len, poly_key); ++ poly1305_auth(NULL, expected_tag, src, aadlen + len, poly_key); + if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { + r = SSH_ERR_MAC_INVALID; + goto out; +@@ -108,7 +108,7 @@ + + /* If encrypting, calculate and append tag */ + if (do_encrypt) { +- poly1305_auth(dest + aadlen + len, dest, aadlen + len, ++ poly1305_auth(NULL, dest + aadlen + len, dest, aadlen + len, + poly_key); + } + r = 0; +diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto.c openssh-9.6p1/cipher-chachapoly-libcrypto.c +--- openssh-9.6p1.orig/cipher-chachapoly-libcrypto.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/cipher-chachapoly-libcrypto.c 2024-07-10 13:34:02.711358567 +0200 +@@ -34,8 +34,17 @@ + #include "ssherr.h" + #include "cipher-chachapoly.h" + ++/* using the EVP_MAC interface for poly1305 is significantly ++ * faster than the version bundled with OpenSSH. However, ++ * this interface is only available in OpenSSL 3.0+ ++ * -cjr 10/21/2022 */ + struct chachapoly_ctx { + EVP_CIPHER_CTX *main_evp, *header_evp; ++#ifdef OPENSSL_HAVE_POLY_EVP ++ EVP_MAC_CTX *poly_ctx; ++#else ++ char *poly_ctx; ++#endif + }; + + struct chachapoly_ctx * +@@ -56,6 +65,15 @@ + goto fail; + if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16) + goto fail; ++#ifdef OPENSSL_HAVE_POLY_EVP ++ EVP_MAC *mac = NULL; ++ if ((mac = EVP_MAC_fetch(NULL, "POLY1305", NULL)) == NULL) ++ goto fail; ++ if ((ctx->poly_ctx = EVP_MAC_CTX_new(mac)) == NULL) ++ goto fail; ++#else ++ ctx->poly_ctx = NULL; ++#endif + return ctx; + fail: + chachapoly_free(ctx); +@@ -69,6 +87,9 @@ + return; + EVP_CIPHER_CTX_free(cpctx->main_evp); + EVP_CIPHER_CTX_free(cpctx->header_evp); ++#ifdef OPENSSL_HAVE_POLY_EVP ++ EVP_MAC_CTX_free(cpctx->poly_ctx); ++#endif + freezero(cpctx, sizeof(*cpctx)); + } + +@@ -107,7 +128,7 @@ + if (!do_encrypt) { + const u_char *tag = src + aadlen + len; + +- poly1305_auth(expected_tag, src, aadlen + len, poly_key); ++ poly1305_auth(ctx->poly_ctx, expected_tag, src, aadlen + len, poly_key); + if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { + r = SSH_ERR_MAC_INVALID; + goto out; +@@ -133,7 +154,7 @@ + + /* If encrypting, calculate and append tag */ + if (do_encrypt) { +- poly1305_auth(dest + aadlen + len, dest, aadlen + len, ++ poly1305_auth(ctx->poly_ctx, dest + aadlen + len, dest, aadlen + len, + poly_key); + } + r = 0; +diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.6p1/cipher-chachapoly-libcrypto-mt.c +--- openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-chachapoly-libcrypto-mt.c 2024-07-10 13:34:02.712358571 +0200 +@@ -0,0 +1,695 @@ ++/* ++ * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Mitchell Dorrell ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++/* TODO: audit includes */ ++ ++#include "includes.h" ++#ifdef WITH_OPENSSL ++#include "openbsd-compat/openssl-compat.h" ++#endif ++ ++#if defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) ++ ++#include ++#include /* needed for getpid under C99 */ ++#include /* needed for log.h */ ++#include ++#include /* needed for misc.h */ ++#include ++ ++#include ++ ++#include "defines.h" ++#include "log.h" ++#include "sshbuf.h" ++#include "ssherr.h" ++ ++#include "xmalloc.h" ++#include "cipher-chachapoly.h" ++#include "cipher-chachapoly-libcrypto-mt.h" ++ ++#ifndef likely ++# define likely(x) __builtin_expect(!!(x), 1) ++#endif ++#ifndef unlikely ++# define unlikely(x) __builtin_expect(!!(x), 0) ++#endif ++ ++/* Size of keystream to pregenerate, measured in bytes ++ * we want to round up to the nearest chacha block and have ++ * 128 bytes for overhead */ ++#define ROUND_UP(x,y) (((((x)-1)/(y))+1)*(y)) ++#define KEYSTREAMLEN (ROUND_UP((SSH_IOBUFSZ) + 128, (CHACHA_BLOCKLEN))) ++ ++/* BEGIN TUNABLES */ ++ ++/* Number of worker threads to spawn. */ ++/* the goal is to ensure that main is never ++ * waiting on the worker threads for keystream data */ ++#define NUMTHREADS 1 ++ ++/* 64 seems to be a pretty blance between memory and performance ++ * 128 is another option with somewhat higher memory consumption */ ++#define NUMSTREAMS 64 ++ ++/* END TUNABLES */ ++ ++struct mt_keystream { ++ u_char poly_key[POLY1305_KEYLEN]; /* POLY1305_KEYLEN == 32 */ ++ u_char headerStream[CHACHA_BLOCKLEN]; /* CHACHA_BLOCKLEN == 64 */ ++ u_char mainStream[KEYSTREAMLEN]; /* KEYSTREAMLEN == 32768 */ ++}; ++ ++struct threadData { ++ EVP_CIPHER_CTX * main_evp; ++ EVP_CIPHER_CTX * header_evp; ++ u_char seqbuf[16]; ++}; ++ ++struct mt_keystream_batch { ++ u_int batchID; ++ struct threadData tds[NUMTHREADS]; ++ struct mt_keystream streams[NUMSTREAMS]; ++}; ++ ++struct chachapoly_ctx_mt { ++ u_int seqnr; ++ u_int batchID; ++ ++ struct mt_keystream_batch batches[2]; ++ ++ pthread_t manager_tid[2]; ++ pthread_t self_tid; ++ ++ pid_t mainpid; ++ u_char zeros[KEYSTREAMLEN]; /* KEYSTREAMLEN == 32768 */ ++ ++ /* if OpenSSL has support for Poly1305 in the MAC EVPs ++ * use that (OSSL >= 3.0) if not then it's OSSL 1.1 so ++ * use the Poly1305 digest methods. Failing that use the ++ * internal poly1305 methods */ ++#ifdef OPENSSL_HAVE_POLY_EVP ++ EVP_MAC_CTX *poly_ctx; ++#elif !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ EVP_PKEY_CTX *poly_ctx; ++ EVP_MD_CTX *md_ctx; ++ EVP_PKEY *pkey; ++ size_t ptaglen; ++#else ++ char *poly_ctx; ++#endif ++}; ++ ++struct manager_thread_args { ++ struct chachapoly_ctx_mt * ctx_mt; ++ u_int oldBatchID; ++ int retval; ++}; ++ ++struct worker_thread_args { ++ u_int batchID; ++ struct mt_keystream_batch * batch; ++ int threadIndex; ++ u_char * zeros; ++ int retval; ++}; ++ ++/* generate the keystream and header ++ * we use nulls for the "data" (the zeros variable) in order to ++ * get the raw keystream ++ * Returns 0 on success and -1 on failure */ ++int ++generate_keystream(struct mt_keystream * ks, u_int seqnr, ++ struct threadData * td, u_char * zeros) ++{ ++ /* generate poly1305 key */ ++ memset(td->seqbuf, 0, sizeof(td->seqbuf)); ++ POKE_U64(td->seqbuf + 8, seqnr); ++ memset(ks->poly_key , 0, sizeof(ks->poly_key)); ++ if (!EVP_CipherInit(td->main_evp, NULL, NULL, td->seqbuf, 1) || ++ EVP_Cipher(td->main_evp, ks->poly_key, ks->poly_key, ++ sizeof(ks->poly_key)) < 0) ++ return -1; ++ ++ /* generate header keystream for encrypting payload length */ ++ if (!EVP_CipherInit(td->header_evp, NULL, NULL, td->seqbuf, 1) || ++ EVP_Cipher(td->header_evp, ks->headerStream, zeros, CHACHA_BLOCKLEN) ++ < 0 ) ++ return -1; ++ ++ /* generate main keystream for encrypting payload */ ++ td->seqbuf[0] = 1; ++ if (!EVP_CipherInit(td->main_evp, NULL, NULL, td->seqbuf, 1) || ++ EVP_Cipher(td->main_evp, ks->mainStream, zeros, KEYSTREAMLEN) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++/* free the EVP contexts associated with the give thread */ ++void ++free_threadData(struct threadData * td) ++{ ++ if (td == NULL) ++ return; ++ if (td->main_evp) /* false if initialization didn't get this far */ ++ EVP_CIPHER_CTX_free(td->main_evp); ++ if (td->header_evp) /* false if initialization didn't get this far */ ++ EVP_CIPHER_CTX_free(td->header_evp); ++ explicit_bzero(td, sizeof(*td)); ++} ++ ++/* initialize the EVPs used by the worker thread ++ Returns 0 on success and -1 on failure */ ++int ++initialize_threadData(struct threadData * td, const u_char *key) ++{ ++ memset(td,0,sizeof(*td)); ++ if ((td->main_evp = EVP_CIPHER_CTX_new()) == NULL || ++ (td->header_evp = EVP_CIPHER_CTX_new()) == NULL) ++ goto fail; ++ if (!EVP_CipherInit(td->main_evp, EVP_chacha20(), key, NULL, 1)) ++ goto fail; ++ if (!EVP_CipherInit(td->header_evp, EVP_chacha20(), key + 32, NULL, 1)) ++ goto fail; ++ if (EVP_CIPHER_CTX_iv_length(td->header_evp) != 16) ++ goto fail; ++ return 0; ++ fail: ++ free_threadData(td); ++ return -1; ++} ++ ++struct worker_thread_args * ++worker_thread(struct worker_thread_args * args) ++{ ++ /* check first */ ++ if (args == NULL) ++ return NULL; ++ if (args->batch == NULL || args->zeros == NULL) { ++ args->retval = 1; ++ return args; ++ } ++ ++ int threadIndex = args->threadIndex; ++ struct threadData * td = &(args->batch->tds[threadIndex]); ++ u_int refseqnr = args->batchID * NUMSTREAMS; ++ ++ for (int i = threadIndex; i < NUMSTREAMS; i += NUMTHREADS) { ++ if (generate_keystream(&(args->batch->streams[i]), refseqnr + i, ++ td, args->zeros) == -1) { ++ args->retval = 1; ++ return args; ++ } ++ } ++ ++ args->retval = 0; ++ return args; ++} ++ ++int ++join_manager_thread(pthread_t manager_tid) ++{ ++ struct manager_thread_args * args; ++ if (pthread_join(manager_tid, (void **) &args) == 0) { ++ if (args == NULL) { ++ debug_f("Manager thread returned NULL!"); ++ return 1; ++ } else if (args == PTHREAD_CANCELED) { ++ debug_f("Manager thread canceled!"); ++ return 1; ++ } else if (args->retval != 0) { ++ debug_f("Manager thread error (%d)", args->retval); ++ free(args); ++ return 1; ++ } else { ++ free(args); ++ return 0; ++ } ++ } else { ++ debug_f("pthread_join error!"); ++ return 1; ++ } ++} ++ ++void ++chachapoly_free_mt(struct chachapoly_ctx_mt * ctx_mt) ++{ ++ if (ctx_mt == NULL) ++ return; ++ ++#ifdef OPENSSL_HAVE_POLY_EVP ++ if (ctx_mt->poly_ctx != NULL) { ++ EVP_MAC_CTX_free(ctx_mt->poly_ctx); ++ ctx_mt->poly_ctx = NULL; ++ } ++#elif !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ if (ctx_mt->md_ctx != NULL) { ++ EVP_MD_CTX_free(ctx_mt->md_ctx); ++ ctx_mt->md_ctx = NULL; ++ } ++ if (ctx_mt->pkey != NULL) { ++ EVP_PKEY_free(ctx_mt->pkey); ++ ctx_mt->pkey = NULL; ++ } ++#endif ++ ++ /* ++ * Only cleanup the manager threads if we are the PID that initialized ++ * them! If we're a fork, the threads don't really exist. ++ */ ++ ++ if (getpid() == ctx_mt->mainpid) { ++ if (ctx_mt->manager_tid[0] != ctx_mt->self_tid) { ++ join_manager_thread(ctx_mt->manager_tid[0]); ++ ctx_mt->manager_tid[0] = ctx_mt->self_tid; ++ } ++ if (ctx_mt->manager_tid[1] != ctx_mt->self_tid) { ++ join_manager_thread(ctx_mt->manager_tid[1]); ++ ctx_mt->manager_tid[1] = ctx_mt->self_tid; ++ } ++ } ++ ++ /* Cleanup thread data structures. */ ++ for (int i=0; i<2; i++) ++ for (int j=0; jbatches[i].tds[j])); ++ ++ /* Zero and free the whole multithreaded cipher context. */ ++ freezero(ctx_mt, sizeof(*ctx_mt)); ++ ++ return; ++} ++ ++struct chachapoly_ctx_mt * ++chachapoly_new_mt(u_int startseqnr, const u_char * key, u_int keylen) ++{ ++ struct chachapoly_ctx_mt * ctx_mt = xmalloc(sizeof(*ctx_mt)); ++ memset(ctx_mt, 0, sizeof(*ctx_mt)); ++ /* Initialize the sequence number. When rekeying, this won't be zero. */ ++ ctx_mt->seqnr = startseqnr; ++ ctx_mt->batchID = startseqnr / NUMSTREAMS; ++ struct threadData mainData; ++ int tDataI; ++ int genKSfailed = 0; ++ ++#ifdef OPENSSL_HAVE_POLY_EVP ++ EVP_MAC *mac = NULL; ++ if ((mac = EVP_MAC_fetch(NULL, "POLY1305", NULL)) == NULL) ++ goto fail; ++ if ((ctx_mt->poly_ctx = EVP_MAC_CTX_new(mac)) == NULL) ++ goto fail; ++#elif !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ if ((ctx_mt->md_ctx = EVP_MD_CTX_new()) == NULL) ++ goto fail; ++ if ((ctx_mt->pkey = EVP_PKEY_new_mac_key(EVP_PKEY_POLY1305, NULL, ++ ctx_mt->zeros, POLY1305_KEYLEN)) == NULL) ++ goto fail; ++ if (EVP_DigestSignInit(ctx_mt->md_ctx, &ctx_mt->poly_ctx, NULL, NULL, ++ ctx_mt->pkey) == 0) ++ goto fail; ++#else ++ ctx_mt->poly_ctx = NULL; ++#endif ++ ++ ctx_mt->batches[ctx_mt->batchID % 2].batchID = ctx_mt->batchID; ++ ctx_mt->batches[(ctx_mt->batchID + 1) % 2].batchID = ++ ctx_mt->batchID + 1; ++ ++ /* initialize batches[0] tds */ ++ for (tDataI = 0; tDataI < NUMTHREADS; tDataI++) { ++ if (initialize_threadData(&(ctx_mt->batches[0].tds[tDataI]), ++ key) != 0) ++ break; ++ } ++ if (tDataI < NUMTHREADS) { ++ /* Backtrack starting with 'tDataI - 1' */ ++ for (tDataI--; tDataI >= 0; tDataI--) ++ free_threadData(&(ctx_mt->batches[0].tds[tDataI])); ++ goto fail; ++ } ++ /* initialize batches[1] tds */ ++ for (tDataI = 0; tDataI < NUMTHREADS; tDataI++) { ++ if (initialize_threadData(&(ctx_mt->batches[1].tds[tDataI]), ++ key) != 0) ++ break; ++ } ++ if (tDataI < NUMTHREADS) { ++ /* Backtrack starting with 'tDataI - 1' */ ++ for (tDataI--; tDataI >= 0; tDataI--) ++ free_threadData(&(ctx_mt->batches[1].tds[tDataI])); ++ /* Free the batches[0] tds too */ ++ for (tDataI = NUMTHREADS; tDataI >= 0; tDataI--) ++ free_threadData(&(ctx_mt->batches[0].tds[tDataI])); ++ goto fail; ++ } ++ ++ if (initialize_threadData(&mainData, key) != 0) { ++ chachapoly_free_mt(ctx_mt); ++ explicit_bzero(&startseqnr, sizeof(startseqnr)); ++ return NULL; ++ } ++ ++ for (int i=0; i<2; i++) { ++ u_int refseqnr = ctx_mt->batches[i].batchID * NUMSTREAMS; ++ for (int j = startseqnr > refseqnr ? startseqnr - refseqnr : 0; ++ jbatches[i].streams[j]), ++ refseqnr + j, &mainData, ctx_mt->zeros) == -1) { ++ debug_f("generate_keystream failed in " ++ "chacha20-poly1305@hpnssh.org"); ++ genKSfailed = 1; ++ break; /* imperfect, but it helps */ ++ } ++ } ++ } ++ ++ free_threadData(&mainData); ++ ++ if (genKSfailed != 0) { ++ chachapoly_free_mt(ctx_mt); ++ explicit_bzero(&startseqnr, sizeof(startseqnr)); ++ return NULL; ++ } ++ ++ /* Store the PID so that in the future, we can tell if we're a fork */ ++ ctx_mt->mainpid = getpid(); ++ ctx_mt->self_tid = pthread_self(); ++ ctx_mt->manager_tid[0] = ctx_mt->self_tid; ++ ctx_mt->manager_tid[1] = ctx_mt->self_tid; ++ /* was reporting the TID using gettid() but it's not portable */ ++ debug2_f("
", getpid(), pthread_self()); ++ ++ /* Success! */ ++ explicit_bzero(&startseqnr, sizeof(startseqnr)); ++ return ctx_mt; ++ ++ fail: ++#ifdef OPENSSL_HAVE_POLY_EVP ++ if (ctx_mt->poly_ctx != NULL) { ++ EVP_MAC_CTX_free(ctx_mt->poly_ctx); ++ ctx_mt->poly_ctx = NULL; ++ } ++#elif !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ if (ctx_mt->md_ctx != NULL) { ++ EVP_MD_CTX_free(ctx_mt->md_ctx); ++ ctx_mt->md_ctx = NULL; ++ } ++ if (ctx_mt->pkey != NULL) { ++ EVP_PKEY_free(ctx_mt->pkey); ++ ctx_mt->pkey = NULL; ++ } ++#endif ++ freezero(ctx_mt, sizeof(*ctx_mt)); ++ explicit_bzero(&startseqnr, sizeof(startseqnr)); ++ return NULL; ++} ++ ++/* a fast method to XOR the keystream against the data */ ++static inline void ++fastXOR(u_char *dest, const u_char *src, const u_char *keystream, u_int len) ++{ ++ ++ /* XXX: this was __uint128_t but that was causing unaligned load errors. ++ * this works but we need to explore it more. */ ++ typedef uint32_t chunk; ++ size_t i; ++ ++ for (i=0; i < (len / sizeof(chunk)); i++) ++ ((chunk *)dest)[i]=((chunk *)src)[i]^((chunk *)keystream)[i]; ++ for (i=i*(sizeof(chunk) / sizeof(char)); i < len; i++) ++ dest[i]=src[i]^keystream[i]; ++} ++ ++struct manager_thread_args * ++manager_thread(struct manager_thread_args * margs) { ++ /* make sure we have valid data before proceeding */ ++ if (margs == NULL) ++ return NULL; ++ ++ struct chachapoly_ctx_mt * ctx_mt = margs->ctx_mt; ++ if (ctx_mt == NULL) { ++ margs->retval = 1; ++ return margs; ++ } ++ ++ u_int oldBatchID = margs->oldBatchID; ++ ++ struct mt_keystream_batch * batch = &(ctx_mt->batches[oldBatchID % 2]); ++ if (batch->batchID != oldBatchID) { ++ debug_f("Post-crypt batch miss! Seeking %u, found %u. Failing.", ++ oldBatchID, batch->batchID); ++ margs->retval = 1; ++ return margs; ++ } ++ ++ margs->retval = 0; ++ u_int batchID = oldBatchID + 2; ++ ++ pthread_t tid[NUMTHREADS]; ++ struct worker_thread_args * wargs = malloc(NUMTHREADS * sizeof(*wargs)); ++ int ti; ++ ++ for (ti = 0; ti < NUMTHREADS; ti++) { ++ wargs[ti].batchID = batchID; ++ wargs[ti].batch = batch; ++ wargs[ti].threadIndex = ti; ++ wargs[ti].zeros = ctx_mt->zeros; ++ if (pthread_create(&(tid[ti]), NULL, (void *) worker_thread, ++ &(wargs[ti])) != 0) { ++ margs->retval = 1; ++ break; ++ } ++ } ++ for (; ti < NUMTHREADS; ti++) /* for error condition */ ++ tid[ti] = pthread_self(); ++ ++ struct worker_thread_args * retwargs; ++ ++ for (ti = 0; ti < NUMTHREADS; ti++) { ++ if (tid[ti] == pthread_self()) { ++ margs->retval = 1; /* redundant, but harmless */ ++ continue; ++ } ++ if (pthread_join(tid[ti], (void **) &retwargs) == 0) { ++ if (retwargs == NULL) { ++ debug_f("Worker thread returned NULL!"); ++ margs->retval = 1; ++ } else if (retwargs == PTHREAD_CANCELED) { ++ debug_f("Worker thread canceled!"); ++ margs->retval = 1; ++ } else { ++ if (retwargs->retval != 0) { ++ debug_f("Worker thread error (%d)", ++ retwargs->retval); ++ margs->retval = 1; ++ } ++ if (retwargs != &(wargs[ti])) { ++ debug_f("Worker thread didn't return " ++ "expected structure!"); ++ margs->retval = 1; ++ } ++ } ++ } else { ++ debug_f("pthread_join error!"); ++ margs->retval = 1; ++ } ++ } ++ free(wargs); ++ ++ if (margs->retval == 0) { ++ batch->batchID = batchID; ++ } ++ ++ return margs; ++} ++ ++int ++chachapoly_crypt_mt(struct chachapoly_ctx_mt *ctx_mt, u_int seqnr, u_char *dest, ++ const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt) ++{ ++#ifdef SAFETY ++ if (ctx_mt->mainpid != getpid()) { /* we're a fork */ ++ /* ++ * TODO: this is EXTREMELY RARE, may never happen at all (only ++ * if the fork calls crypt), so we should tell the compiler. ++ */ ++ /* The worker threads don't exist, we could spawn them? */ ++ debug_f("Fork called crypt without workers!"); ++ chachapoly_free_mt(ctx_mt); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++#endif ++ ++ pthread_t * manager_tid = &(ctx_mt->manager_tid[ctx_mt->batchID % 2]); ++ if (unlikely(*manager_tid != ctx_mt->self_tid)) { ++ int ret = join_manager_thread(*manager_tid); ++ *manager_tid = ctx_mt->self_tid; ++ if (ret != 0) ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ ++ struct mt_keystream_batch * batch = ++ &(ctx_mt->batches[ctx_mt->batchID % 2]); ++ ++ struct mt_keystream * ks = &(batch->streams[seqnr % NUMSTREAMS]); ++ ++ int r = SSH_ERR_INTERNAL_ERROR; ++ ++#ifdef SAFETY ++ if (batch->batchID == ctx_mt->batchID) { /* Safety check */ ++#endif ++ /* check tag before anything else */ ++ if (!do_encrypt) { ++ const u_char *tag = src + aadlen + len; ++ u_char expected_tag[POLY1305_TAGLEN]; ++#if !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ if ((EVP_PKEY_CTX_ctrl(ctx_mt->poly_ctx, -1, ++ EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_MAC_KEY, ++ POLY1305_KEYLEN, ks->poly_key) <= 0) || ++ (EVP_DigestSignUpdate(ctx_mt->md_ctx, src, aadlen + len) == 0)) { ++ debug_f("SSL error while decrypting poly1305 tag"); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ ctx_mt->ptaglen = POLY1305_TAGLEN; ++ if (EVP_DigestSignFinal(ctx_mt->md_ctx, expected_tag, ++ &ctx_mt->ptaglen) == 0) { ++ debug_f("SSL error while finalizing decyrpted poly1305"); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++#else ++ poly1305_auth(ctx_mt->poly_ctx, expected_tag, src, ++ aadlen + len, ks->poly_key); ++#endif ++ if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) ++ != 0) ++ r = SSH_ERR_MAC_INVALID; ++ explicit_bzero(expected_tag, sizeof(expected_tag)); ++ } ++ if (r != SSH_ERR_MAC_INVALID) { ++ /* Crypt additional data (i.e., packet length) */ ++ /* TODO: is aadlen always four bytes? */ ++ /* TODO: do we always have an aadlen? */ ++ if (aadlen) ++ for (u_int i=0; iheaderStream[i] ^ src[i]; ++ /* Crypt payload */ ++ fastXOR(dest+aadlen,src+aadlen,ks->mainStream,len); ++ /* calculate and append tag */ ++#if !defined(WITH_OPENSSL3) && defined(EVP_PKEY_POLY1305) ++ if (do_encrypt) { ++ if ((EVP_PKEY_CTX_ctrl(ctx_mt->poly_ctx, -1, ++ EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_MAC_KEY, ++ POLY1305_KEYLEN, ks->poly_key) <=0) || ++ (EVP_DigestSignUpdate(ctx_mt->md_ctx, dest, aadlen + len) == 0)) { ++ debug_f ("SSL error while encrypting poly1305 tag"); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ ctx_mt->ptaglen = POLY1305_TAGLEN; ++ if (EVP_DigestSignFinal(ctx_mt->md_ctx, dest+aadlen+len, ++ &ctx_mt->ptaglen) == 0) { ++ debug_f("SSL error while finalizing decyrpted poly1305"); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ } ++#else ++ if (do_encrypt) ++ poly1305_auth(ctx_mt->poly_ctx, dest+aadlen+len, ++ dest, aadlen+len, ks->poly_key); ++#endif ++ r=0; /* Success! */ ++ } ++ if (r) /* Anything nonzero is an error. */ ++ return r; ++ ++ ctx_mt->seqnr = seqnr + 1; ++ ++ if (unlikely(ctx_mt->seqnr / NUMSTREAMS > ctx_mt->batchID)) { ++ struct manager_thread_args * args = ++ malloc(sizeof(*args)); ++ if (args == NULL) { ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ args->ctx_mt = ctx_mt; ++ args->oldBatchID = ctx_mt->batchID; ++ if (pthread_create(&(ctx_mt->manager_tid[ctx_mt->batchID ++ % 2]), NULL, (void *) manager_thread, args) != 0) { ++ free(args); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ ctx_mt->batchID = ctx_mt->seqnr / NUMSTREAMS; ++ } ++ ++ /* TODO: Nothing we need to sanitize here? */ ++ ++ return 0; ++#ifdef SAFETY ++ } else { /* Bad, it's the wrong batch. */ ++ debug_f( "Pre-crypt batch miss! Seeking %u, found %u. Failing.", ++ ctx_mt->batchID, batch->batchID); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++#endif ++} ++ ++int ++chachapoly_get_length_mt(struct chachapoly_ctx_mt *ctx_mt, u_int *plenp, ++ u_int seqnr, const u_char *cp, u_int len) ++{ ++ /* TODO: add compiler hints */ ++#ifdef SAFETY ++ if (ctx_mt->mainpid != getpid()) { /* Use serial mode if we're a fork */ ++ debug_f("We're a fork. Failing."); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++#endif ++ ++ if (len < 4) ++ return SSH_ERR_MESSAGE_INCOMPLETE; ++ ++ pthread_t * manager_tid = &(ctx_mt->manager_tid[ctx_mt->batchID % 2]); ++ if (unlikely(*manager_tid != ctx_mt->self_tid)) { ++ int ret = join_manager_thread(*manager_tid); ++ *manager_tid = ctx_mt->self_tid; ++ if (ret != 0) ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++ ++ u_char buf[4]; ++#ifdef SAFETY ++ u_int sought_batchID = seqnr / NUMSTREAMS; ++#endif ++ struct mt_keystream_batch * batch = ++ &(ctx_mt->batches[ctx_mt->batchID % 2]); ++ struct mt_keystream * ks = &(batch->streams[seqnr % NUMSTREAMS]); ++#ifdef SAFETY ++ if (batch->batchID == sought_batchID) { ++#endif ++ for (u_int i=0; i < sizeof(buf); i++) ++ buf[i]=ks->headerStream[i] ^ cp[i]; ++ *plenp = PEEK_U32(buf); ++ return 0; ++#ifdef SAFETY ++ } else { ++ debug_f("Batch miss! Seeking %u, found %u. Failing.", ++ sought_batchID, batch->batchID); ++ return SSH_ERR_INTERNAL_ERROR; ++ } ++#endif ++} ++#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */ +diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.6p1/cipher-chachapoly-libcrypto-mt.h +--- openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-chachapoly-libcrypto-mt.h 2024-07-10 13:34:02.712358571 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Mitchell Dorrell ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++#ifndef CHACHA_POLY_LIBCRYPTO_MT_H ++#define CHACHA_POLY_LIBCRYPTO_MT_H ++ ++#include ++#include "chacha.h" ++#include "poly1305.h" ++ ++#ifndef CHACHA_KEYLEN ++#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ ++#endif ++ ++struct chachapoly_ctx_mt; /* defined in cipher-chachapoly-libcrypto-mt.c */ ++ ++struct chachapoly_ctx_mt *chachapoly_new_mt(u_int startseqnr, const u_char *key, u_int keylen) ++ __attribute__((__bounded__(__buffer__, 2, 3))); ++ ++void chachapoly_free_mt(struct chachapoly_ctx_mt *cpctx); ++ ++int chachapoly_crypt_mt(struct chachapoly_ctx_mt *cpctx, u_int seqnr, ++ u_char *dest, const u_char *src, u_int len, u_int aadlen, ++ u_int authlen, int do_encrypt); ++ ++int chachapoly_get_length_mt(struct chachapoly_ctx_mt *cpctx, ++ u_int *plenp, u_int seqnr, const u_char *cp, u_int len) ++ __attribute__((__bounded__(__buffer__, 4, 5))); ++ ++#endif /* CHACHA_POLY_LIBCRYPTO_MT_H */ +diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c +--- openssh-9.6p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-ctr-mt.c 2024-07-10 13:58:24.488736203 +0200 +@@ -0,0 +1,677 @@ ++/* ++ * OpenSSH Multi-threaded AES-CTR Cipher ++ * ++ * Author: Benjamin Bennett ++ * Author: Mike Tasota ++ * Author: Chris Rapier ++ * Copyright (c) 2008-2021 Pittsburgh Supercomputing Center. All rights reserved. ++ * ++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged, ++ * Copyright (c) 2003 Markus Friedl ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#include "includes.h" ++ ++#if defined(WITH_OPENSSL) && !defined(WITH_OPENSSL3) ++#include ++ ++#include ++#include ++ ++#include ++ ++#include "xmalloc.h" ++#include "log.h" ++#include ++#include "uthash.h" ++ ++/* compatibility with old or broken OpenSSL versions */ ++#include "openbsd-compat/openssl-compat.h" ++ ++#ifndef USE_BUILTIN_RIJNDAEL ++#include ++#endif ++ ++#include ++ ++#ifdef __APPLE__ ++#include ++#include ++#endif ++ ++/* note regarding threads and queues */ ++/* initially this cipher was written in a way that ++ * the key stream was generated in a per cipher block ++ * loop. For example, if the key stream queue length was ++ * 16k and the cipher block size was 16 bytes it would ++ * fill the queue 16 bytes at a time. Mitch Dorrell pointed ++ * out that we could fill the queue in once call eliminating ++ * loop and multiple calls to EVP_EncryptUpdate. Doing so ++ * dramatically reduced CPU load in the threads and indicated ++ * that we could also eliminate most of the threads and queues ++ * as it would take far less time for a queue to ebter KQ_FULL ++ * state. As such, we've reduced the default number of threads ++ * and queues from 2 and 8 (respectively) to 1 and 2. We've also ++ * elimnated the need to determine the physical number of cores on ++ * the system and, if the user desires, can spin up more threads ++ * using an environment variable. Additionally, queues is now fixed ++ * at thread_count + 1. ++ * cjr 10/19/2022 */ ++ ++/*-------------------- TUNABLES --------------------*/ ++/* maximum number of threads and queues */ ++#define MAX_THREADS 4 ++#define MAX_NUMKQ (MAX_THREADS + 1) ++ ++/* Number of pregen threads to use */ ++/* this is a default value. The actual number is ++ * determined during init as a function of the number ++ * of available cores */ ++int cipher_threads = 1; ++ ++/* Number of keystream queues */ ++/* ideally this should be large enough so that there is ++ * always a key queue for a thread to work on ++ * so maybe double of the number of threads. Again this ++ * is a default and the actual value is determined in init*/ ++int numkq = 2; ++ ++/* Length of a keystream queue */ ++/* one queue holds 512KB (1024 * 32 * 16) of key data ++ * being that the queues are destroyed after a rekey ++ * and at leats one has to be fully filled prior to ++ * enciphering data we don't want this to be too large */ ++#define KQLEN (1024 * 32) ++ ++/* Processor cacheline length */ ++#define CACHELINE_LEN 64 ++ ++/* Can the system do unaligned loads natively? */ ++#if defined(__aarch64__) || \ ++ defined(__i386__) || \ ++ defined(__powerpc__) || \ ++ defined(__x86_64__) ++# define CIPHER_UNALIGNED_OK ++#endif ++#if defined(__SIZEOF_INT128__) ++# define CIPHER_INT128_OK ++#endif ++/*-------------------- END TUNABLES --------------------*/ ++ ++#define HAVE_NONE 0 ++#define HAVE_KEY 1 ++#define HAVE_IV 2 ++int X = 0; ++ ++const EVP_CIPHER *evp_aes_ctr_mt(void); ++ ++/* Keystream Queue state */ ++enum { ++ KQINIT, ++ KQEMPTY, ++ KQFILLING, ++ KQFULL, ++ KQDRAINING ++}; ++ ++/* Keystream Queue struct */ ++struct kq { ++ u_char keys[KQLEN][AES_BLOCK_SIZE]; /* [32768][16B] */ ++ u_char ctr[AES_BLOCK_SIZE]; /* 16B */ ++ u_char pad0[CACHELINE_LEN]; ++ pthread_mutex_t lock; ++ pthread_cond_t cond; ++ int qstate; ++ u_char pad1[CACHELINE_LEN]; ++}; ++ ++/* Context struct */ ++struct ssh_aes_ctr_ctx_mt ++{ ++ long unsigned int struct_id; ++ int keylen; ++ int state; ++ int qidx; ++ int ridx; ++ int id[MAX_THREADS]; /* 32 */ ++ AES_KEY aes_key; ++ const u_char *orig_key; ++ u_char aes_counter[AES_BLOCK_SIZE]; /* 16B */ ++ pthread_t tid[MAX_THREADS]; /* 32 */ ++ pthread_rwlock_t tid_lock; ++ struct kq q[MAX_NUMKQ]; /* 33 */ ++#ifdef __APPLE__ ++ pthread_rwlock_t stop_lock; ++ int exit_flag; ++#endif /* __APPLE__ */ ++}; ++ ++/* this defines the hash and elements of evp context pointers ++ * that are created in thread_loop. We use this to clear and ++ * free the contexts in stop_and_prejoin ++ */ ++struct aes_mt_ctx_ptrs { ++ pthread_t tid; ++ EVP_CIPHER_CTX *pointer; /* 32 */ ++ UT_hash_handle hh; ++}; ++ ++/* globals */ ++/* how we increment the id the structs we create */ ++long unsigned int global_struct_id = 0; ++ ++/* keep a copy of the pointers created in thread_loop to free later */ ++struct aes_mt_ctx_ptrs *evp_ptrs = NULL; ++ ++/* ++ * Add num to counter 'ctr' ++ */ ++static void ++ssh_ctr_add(u_char *ctr, uint32_t num, u_int len) ++{ ++ int i; ++ uint16_t n; ++ ++ for (n = 0, i = len - 1; i >= 0 && (num || n); i--) { ++ n = ctr[i] + (num & 0xff) + n; ++ num >>= 8; ++ ctr[i] = n & 0xff; ++ n >>= 8; ++ } ++} ++ ++/* ++ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex ++ */ ++static void ++thread_loop_cleanup(void *x) ++{ ++ pthread_mutex_unlock((pthread_mutex_t *)x); ++} ++ ++#ifdef __APPLE__ ++/* Check if we should exit, we are doing both cancel and exit condition ++ * since on OSX threads seem to occasionally fail to notice when they have ++ * been cancelled. We want to have a backup to make sure that we won't hang ++ * when the main process join()-s the cancelled thread. ++ */ ++static void ++thread_loop_check_exit(struct ssh_aes_ctr_ctx_mt *c) ++{ ++ int exit_flag; ++ ++ pthread_rwlock_rdlock(&c->stop_lock); ++ exit_flag = c->exit_flag; ++ pthread_rwlock_unlock(&c->stop_lock); ++ ++ if (exit_flag) ++ pthread_exit(NULL); ++} ++#else ++# define thread_loop_check_exit(s) ++#endif /* __APPLE__ */ ++ ++/* ++ * Helper function to terminate the helper threads ++ */ ++static void ++stop_and_join_pregen_threads(struct ssh_aes_ctr_ctx_mt *c) ++{ ++ int i; ++ ++#ifdef __APPLE__ ++ /* notify threads that they should exit */ ++ pthread_rwlock_wrlock(&c->stop_lock); ++ c->exit_flag = TRUE; ++ pthread_rwlock_unlock(&c->stop_lock); ++#endif /* __APPLE__ */ ++ ++ /* Cancel pregen threads */ ++ for (i = 0; i < cipher_threads; i++) { ++ debug ("Canceled %lu (%lu,%d)", c->tid[i], c->struct_id, c->id[i]); ++ pthread_cancel(c->tid[i]); ++ } ++ for (i = 0; i < numkq; i++) { ++ pthread_mutex_lock(&c->q[i].lock); ++ pthread_cond_broadcast(&c->q[i].cond); ++ pthread_mutex_unlock(&c->q[i].lock); ++ } ++ for (i = 0; i < cipher_threads; i++) { ++ if (pthread_kill(c->tid[i], 0) != 0) ++ debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", ++ c->tid[i], __FUNCTION__); ++ else { ++ debug ("Joining %lu (%lu, %d)", c->tid[i], c->struct_id, c->id[i]); ++ pthread_mutex_destroy(&c->q[i].lock); ++ pthread_cond_destroy(&c->q[i].cond); ++ pthread_join(c->tid[i], NULL); ++ /* this finds the entry in the hash that corresponding to the ++ * thread id. That's used to find the pointer to the cipher struct ++ * created in thread_loop. */ ++ struct aes_mt_ctx_ptrs *ptr; ++ HASH_FIND_INT(evp_ptrs, &c->tid[i], ptr); ++ EVP_CIPHER_CTX_free(ptr->pointer); ++ HASH_DEL(evp_ptrs, ptr); ++ free(ptr); } ++ } ++ pthread_rwlock_destroy(&c->tid_lock); ++} ++ ++/* ++ * The life of a pregen thread: ++ * Find empty keystream queues and fill them using their counter. ++ * When done, update counter for the next fill. ++ */ ++/* previously this used the low level interface which is, sadly, ++ * slower than the EVP interface by a long shot. The original ctx (from the ++ * body of the code) isn't passed in here but we have the key and the counter ++ * which means we should be able to create the exact same ctx and use that to ++ * fill the keystream queues. I'm concerned about additional overhead but the ++ * additional speed from AESNI should make up for it. */ ++/* The above comment was made when I thought I needed to do a new EVP init for ++ * each counter increment. Turns out not to be the case -cjr 10/15/21*/ ++ ++static void * ++thread_loop(void *x) ++{ ++ EVP_CIPHER_CTX *aesni_ctx; ++ struct ssh_aes_ctr_ctx_mt *c = x; ++ struct kq *q; ++ struct aes_mt_ctx_ptrs *ptr; ++ int qidx; ++ pthread_t first_tid; ++ int outlen; ++ u_char mynull[KQLEN * AES_BLOCK_SIZE]; ++ memset(&mynull, 0, KQLEN * AES_BLOCK_SIZE); ++ ++ /* get the thread id to see if this is the first one */ ++ pthread_rwlock_rdlock(&c->tid_lock); ++ first_tid = c->tid[0]; ++ pthread_rwlock_unlock(&c->tid_lock); ++ ++ /* create the context for this thread */ ++ aesni_ctx = EVP_CIPHER_CTX_new(); ++ ++ /* keep track of the pointer for the evp in this struct ++ * so we can free it later. So we place it in a hash indexed on the ++ * thread id, which is available to us in the free function. ++ * Note, the thread id isn't necessary unique across rekeys but ++ * that's okay as they are unique during a key. */ ++ ptr = malloc(sizeof *ptr); /*freed in stop & prejoin */ ++ ptr->tid = pthread_self(); /* index for hash */ ++ ptr->pointer = aesni_ctx; ++ HASH_ADD_INT(evp_ptrs, tid, ptr); ++ ++ /* initialize the cipher ctx with the key provided ++ * determine which cipher to use based on the key size */ ++ if (c->keylen == 256) ++ EVP_EncryptInit_ex(aesni_ctx, EVP_aes_256_ctr(), NULL, c->orig_key, NULL); ++ else if (c->keylen == 128) ++ EVP_EncryptInit_ex(aesni_ctx, EVP_aes_128_ctr(), NULL, c->orig_key, NULL); ++ else if (c->keylen == 192) ++ EVP_EncryptInit_ex(aesni_ctx, EVP_aes_192_ctr(), NULL, c->orig_key, NULL); ++ else { ++ logit("Invalid key length of %d in AES CTR MT. Exiting", c->keylen); ++ exit(1); ++ } ++ ++ /* ++ * Handle the special case of startup, one thread must fill ++ * the first KQ then mark it as draining. Lock held throughout. ++ */ ++ ++ if (pthread_equal(pthread_self(), first_tid)) { ++ /* get the first element of the keyque struct */ ++ q = &c->q[0]; ++ pthread_mutex_lock(&q->lock); ++ /* if we are in the INIT state then fill the queue */ ++ if (q->qstate == KQINIT) { ++ /* set the initial counter */ ++ EVP_EncryptInit_ex(aesni_ctx, NULL, NULL, NULL, q->ctr); ++ ++ /* encypher a block sized null string (mynull) with the key. This ++ * returns the keystream because xoring the keystream ++ * against null returns the keystream. Store that in the appropriate queue */ ++ EVP_EncryptUpdate(aesni_ctx, q->keys[0], &outlen, mynull, KQLEN * AES_BLOCK_SIZE); ++ ++ /* add the number of blocks creates to the aes counter */ ++ ssh_ctr_add(q->ctr, KQLEN * numkq, AES_BLOCK_SIZE); ++ q->qstate = KQDRAINING; ++ pthread_cond_broadcast(&q->cond); ++ } ++ pthread_mutex_unlock(&q->lock); ++ } ++ ++ /* ++ * Normal case is to find empty queues and fill them, skipping over ++ * queues already filled by other threads and stopping to wait for ++ * a draining queue to become empty. ++ * ++ * Multiple threads may be waiting on a draining queue and awoken ++ * when empty. The first thread to wake will mark it as filling, ++ * others will move on to fill, skip, or wait on the next queue. ++ */ ++ for (qidx = 1;; qidx = (qidx + 1) % numkq) { ++ /* Check if I was cancelled, also checked in cond_wait */ ++ pthread_testcancel(); ++ ++ /* Check if we should exit as well */ ++ thread_loop_check_exit(c); ++ ++ /* Lock queue and block if its draining */ ++ q = &c->q[qidx]; ++ pthread_mutex_lock(&q->lock); ++ pthread_cleanup_push(thread_loop_cleanup, &q->lock); ++ while (q->qstate == KQDRAINING || q->qstate == KQINIT) { ++ thread_loop_check_exit(c); ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ pthread_cleanup_pop(0); ++ ++ /* If filling or full, somebody else got it, skip */ ++ if (q->qstate != KQEMPTY) { ++ pthread_mutex_unlock(&q->lock); ++ continue; ++ } ++ ++ /* ++ * Empty, let's fill it. ++ * Queue lock is relinquished while we do this so others ++ * can see that it's being filled. ++ */ ++ q->qstate = KQFILLING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ ++ /* set the initial counter */ ++ EVP_EncryptInit_ex(aesni_ctx, NULL, NULL, NULL, q->ctr); ++ ++ /* see coresponding block above for useful comments */ ++ EVP_EncryptUpdate(aesni_ctx, q->keys[0], &outlen, mynull, KQLEN * AES_BLOCK_SIZE); ++ ++ /* Re-lock, mark full and signal consumer */ ++ pthread_mutex_lock(&q->lock); ++ ssh_ctr_add(q->ctr, KQLEN * numkq, AES_BLOCK_SIZE); ++ q->qstate = KQFULL; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ } ++ ++ return NULL; ++} ++ ++/* this is where the data is actually enciphered and deciphered */ ++/* this may also benefit from upgrading to the EVP API */ ++static int ++ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, ++ size_t len) ++{ ++ typedef union { ++#ifdef CIPHER_INT128_OK ++ __uint128_t *u128; ++#endif ++ uint64_t *u64; ++ uint32_t *u32; ++ uint8_t *u8; ++ const uint8_t *cu8; ++ uintptr_t u; ++ } ptrs_t; ++ ptrs_t destp, srcp, bufp; ++ uintptr_t align; ++ struct ssh_aes_ctr_ctx_mt *c; ++ struct kq *q, *oldq; ++ int ridx; ++ u_char *buf; ++ ++ if (len == 0) ++ return 1; ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) ++ return 0; ++ ++ q = &c->q[c->qidx]; ++ ridx = c->ridx; ++ ++ /* src already padded to block multiple */ ++ srcp.cu8 = src; ++ destp.u8 = dest; ++ do { /* do until len is 0 */ ++ buf = q->keys[ridx]; ++ bufp.u8 = buf; ++ ++ /* figure out the alignment on the fly */ ++#ifdef CIPHER_UNALIGNED_OK ++ align = 0; ++#else ++ align = destp.u | srcp.u | bufp.u; ++#endif ++ ++ /* xor the src against the key (buf) ++ * different systems can do all 16 bytes at once or ++ * may need to do it in 8 or 4 bytes chunks ++ * worst case is doing it as a loop */ ++#ifdef CIPHER_INT128_OK ++ /* with GCC 13 we have having consistent seg faults ++ * in this section of code. Since this is a critical ++ * code path we are removing this until we have a solution ++ * in place -cjr 02/22/24 ++ * TODO: FIX THIS ++ */ ++ /* if ((align & 0xf) == 0) { */ ++ /* destp.u128[0] = srcp.u128[0] ^ bufp.u128[0]; */ ++ /* } else */ ++#endif ++ /* 64 bits */ ++ if ((align & 0x7) == 0) { ++ destp.u64[0] = srcp.u64[0] ^ bufp.u64[0]; ++ destp.u64[1] = srcp.u64[1] ^ bufp.u64[1]; ++ /* 32 bits */ ++ } else if ((align & 0x3) == 0) { ++ destp.u32[0] = srcp.u32[0] ^ bufp.u32[0]; ++ destp.u32[1] = srcp.u32[1] ^ bufp.u32[1]; ++ destp.u32[2] = srcp.u32[2] ^ bufp.u32[2]; ++ destp.u32[3] = srcp.u32[3] ^ bufp.u32[3]; ++ } else { ++ /*1 byte at a time*/ ++ size_t i; ++ for (i = 0; i < AES_BLOCK_SIZE; ++i) ++ dest[i] = src[i] ^ buf[i]; ++ } ++ ++ /* inc/decrement the pointers by the block size (16)*/ ++ destp.u += AES_BLOCK_SIZE; ++ srcp.u += AES_BLOCK_SIZE; ++ ++ /* Increment read index, switch queues on rollover */ ++ if ((ridx = (ridx + 1) % KQLEN) == 0) { ++ oldq = q; ++ ++ /* Mark next queue draining, may need to wait */ ++ c->qidx = (c->qidx + 1) % numkq; ++ q = &c->q[c->qidx]; ++ pthread_mutex_lock(&q->lock); ++ while (q->qstate != KQFULL) { ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ q->qstate = KQDRAINING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ ++ /* Mark consumed queue empty and signal producers */ ++ pthread_mutex_lock(&oldq->lock); ++ oldq->qstate = KQEMPTY; ++ pthread_cond_broadcast(&oldq->cond); ++ pthread_mutex_unlock(&oldq->lock); ++ } ++ } while (len -= AES_BLOCK_SIZE); ++ c->ridx = ridx; ++ return 1; ++} ++ ++static int ++ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, ++ int enc) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ int i; ++ ++ char *aes_threads = getenv("SSH_CIPHER_THREADS"); ++ if (aes_threads != NULL && strlen(aes_threads) != 0) ++ cipher_threads = atoi(aes_threads); ++ else ++ cipher_threads = 1; ++ ++ if (cipher_threads < 1) ++ cipher_threads = 1; ++ ++ if (cipher_threads > MAX_THREADS) ++ cipher_threads = MAX_THREADS; ++ ++ numkq = cipher_threads + 1; ++ ++ if (numkq > MAX_NUMKQ) ++ numkq = MAX_NUMKQ; ++ ++ debug("Starting %d threads and %d queues\n", cipher_threads, numkq); ++ ++ /* set up the initial state of c (our cipher stream struct) */ ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { ++ c = xmalloc(sizeof(*c)); ++ pthread_rwlock_init(&c->tid_lock, NULL); ++#ifdef __APPLE__ ++ pthread_rwlock_init(&c->stop_lock, NULL); ++ c->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ c->state = HAVE_NONE; ++ ++ /* initialize the mutexs and conditions for each lock in our struct */ ++ for (i = 0; i < numkq; i++) { ++ pthread_mutex_init(&c->q[i].lock, NULL); ++ pthread_cond_init(&c->q[i].cond, NULL); ++ } ++ ++ /* attach our struct to the context */ ++ EVP_CIPHER_CTX_set_app_data(ctx, c); ++ } ++ ++ /* we are initializing but the current structure already ++ has an IV and key so we want to kill the existing key data ++ and start over. This is important when we need to rekey the data stream */ ++ if (c->state == (HAVE_KEY | HAVE_IV)) { ++ /* tell the pregen threads to exit */ ++ stop_and_join_pregen_threads(c); ++ ++#ifdef __APPLE__ ++ /* reset the exit flag */ ++ c->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ /* Start over getting key & iv */ ++ c->state = HAVE_NONE; ++ } ++ ++ /* set the initial key for this key stream queue */ ++ if (key != NULL) { ++ AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, ++ &c->aes_key); ++ c->orig_key = key; ++ c->keylen = EVP_CIPHER_CTX_key_length(ctx) * 8; ++ c->state |= HAVE_KEY; ++ } ++ ++ /* set the IV */ ++ if (iv != NULL) { ++ /* init the counter this is just a 16byte uchar */ ++ memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); ++ c->state |= HAVE_IV; ++ } ++ ++ if (c->state == (HAVE_KEY | HAVE_IV)) { ++ /* Clear queues */ ++ /* set the first key in the key queue to the current counter */ ++ memcpy(c->q[0].ctr, c->aes_counter, AES_BLOCK_SIZE); ++ /* indicate that it needs to be initialized */ ++ c->q[0].qstate = KQINIT; ++ /* for each of the remaining queues set the first counter to the ++ * counter and then add the size of the queue to the counter */ ++ for (i = 1; i < numkq; i++) { ++ memcpy(c->q[i].ctr, c->aes_counter, AES_BLOCK_SIZE); ++ ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE); ++ c->q[i].qstate = KQEMPTY; ++ } ++ c->qidx = 0; ++ c->ridx = 0; ++ c->struct_id = global_struct_id++; ++ ++ ++ /* Start threads */ ++#define STACK_SIZE (1024 * 1024) ++ pthread_attr_t attr; ++ pthread_attr_init(&attr); ++ pthread_attr_setstacksize(&attr, STACK_SIZE); ++ for (i = 0; i < cipher_threads; i++) { ++ pthread_rwlock_wrlock(&c->tid_lock); ++ if (pthread_create(&c->tid[i], &attr, thread_loop, c) != 0) ++ fatal ("AES-CTR MT Could not create thread in %s", __FUNCTION__); ++ /*should die here */ ++ else { ++ c->id[i] = i; ++ debug ("AES-CTR MT spawned a thread with id %lu in %s (%lu, %d)", ++ c->tid[i], __FUNCTION__, c->struct_id, c->id[i]); ++ } ++ pthread_rwlock_unlock(&c->tid_lock); ++ } ++ pthread_mutex_lock(&c->q[0].lock); ++ // wait for all of the threads to be initialized ++ while (c->q[0].qstate == KQINIT) ++ pthread_cond_wait(&c->q[0].cond, &c->q[0].lock); ++ pthread_mutex_unlock(&c->q[0].lock); ++ } ++ return 1; ++} ++ ++static int ++ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) ++{ ++ struct ssh_aes_ctr_ctx_mt *c; ++ ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { ++ stop_and_join_pregen_threads(c); ++ ++ memset(c, 0, sizeof(*c)); ++ free(c); ++ EVP_CIPHER_CTX_set_app_data(ctx, NULL); ++ } ++ return 1; ++} ++ ++/* */ ++const EVP_CIPHER * ++evp_aes_ctr_mt(void) ++{ ++ static EVP_CIPHER *aes_ctr; ++ aes_ctr = EVP_CIPHER_meth_new(NID_undef, 16/*block*/, 16/*key*/); ++ EVP_CIPHER_meth_set_iv_length(aes_ctr, AES_BLOCK_SIZE); ++ EVP_CIPHER_meth_set_init(aes_ctr, ssh_aes_ctr_init); ++ EVP_CIPHER_meth_set_cleanup(aes_ctr, ssh_aes_ctr_cleanup); ++ EVP_CIPHER_meth_set_do_cipher(aes_ctr, ssh_aes_ctr); ++# ifndef SSH_OLD_EVP ++ EVP_CIPHER_meth_set_flags(aes_ctr, EVP_CIPH_CBC_MODE ++ | EVP_CIPH_VARIABLE_LENGTH ++ | EVP_CIPH_ALWAYS_CALL_INIT ++ | EVP_CIPH_CUSTOM_IV); ++# endif /*SSH_OLD_EVP*/ ++ return aes_ctr; ++} ++#endif /* OSSL Check */ +diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.c openssh-9.6p1/cipher-ctr-mt-functions.c +--- openssh-9.6p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-ctr-mt-functions.c 2024-07-10 13:34:02.713358574 +0200 +@@ -0,0 +1,668 @@ ++/* ++ * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 ++ * ++ * Author: Benjamin Bennett ++ * Author: Mike Tasota ++ * Author: Chris Rapier ++ * Copyright (c) 2008-2022 Pittsburgh Supercomputing Center. All rights reserved. ++ * ++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged, ++ * Copyright (c) 2003 Markus Friedl ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++/* only for systems with OSSL 3 */ ++#ifdef WITH_OPENSSL3 ++#include ++#include ++#include ++#include "xmalloc.h" ++#include ++#include "cipher-ctr-mt-functions.h" ++#include "log.h" ++ ++/* for provider error struct */ ++#include "ossl3-provider-err.h" ++#include "num.h" ++ ++/* note regarding threads and queues */ ++/* initially this cipher was written in a way that ++ * the key stream was generated in a per cipher block ++ * loop. For example, if the key stream queue length was ++ * 16k and the cipher block size was 16 bytes it would ++ * fill the queue 16 bytes at a time. Mitch Dorrell pointed ++ * out that we could fill the queue in once call eliminating ++ * loop and multiple calls to EVP_EncryptUpdate. Doing so ++ * dramatically reduced CPU load in the threads and indicated ++ * that we could also eliminate most of the threads and queues ++ * as it would take far less time for a queue to ebter KQ_FULL ++ * state. As such, we've reduced the default number of threads ++ * and queues from 2 and 8 (respectively) to 1 and 2. We've also ++ * elimnated the need to determine the physical number of cores on ++ * the system and, if the user desires, can spin up more threads ++ * using an environment variable. Additionally, queues is now fixed ++ * at thread_count + 1. ++ * cjr 10/19/2022 */ ++ ++/*-------------------- TUNABLES --------------------*/ ++/* Number of pregen threads to use */ ++/* this is a default value. The actual number is ++ * determined during init as a function of the number ++ * of available cores */ ++int cipher_threads = 1; ++ ++/* Number of keystream queues */ ++/* ideally this should be large enough so that there is ++ * always a key queue for a thread to work on ++ * so maybe double of the number of threads. Again this ++ * is a default and the actual value is determined in init*/ ++int numkq = 2; ++/*-------------------- END TUNABLES --------------------*/ ++ ++/* globals */ ++/* how we increment the id the structs we create */ ++long unsigned int global_struct_id = 0; ++ ++/* keep a copy of the pointers created in thread_loop to free later */ ++struct aes_mt_ctx_ptrs *evp_ptrs = NULL; ++ ++/* private functions */ ++ ++/* ++ * Add num to counter 'ctr' ++ */ ++static void ++ssh_ctr_add(u_char *ctr, uint32_t num, u_int len) ++{ ++ int i; ++ uint16_t n; ++ ++ for (n = 0, i = len - 1; i >= 0 && (num || n); i--) { ++ n = ctr[i] + (num & 0xff) + n; ++ num >>= 8; ++ ctr[i] = n & 0xff; ++ n >>= 8; ++ } ++} ++ ++/* ++ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex ++ */ ++static void ++thread_loop_cleanup(void *x) ++{ ++ pthread_mutex_unlock((pthread_mutex_t *)x); ++} ++ ++#ifdef __APPLE__ ++/* Check if we should exit, we are doing both cancel and exit condition ++ * since on OSX threads seem to occasionally fail to notice when they have ++ * been cancelled. We want to have a backup to make sure that we won't hang ++ * when the main process join()-s the cancelled thread. ++ */ ++static void ++thread_loop_check_exit(struct aes_mt_ctx_st *aes_mt_ctx) ++{ ++ int exit_flag; ++ ++ pthread_rwlock_rdlock(&aes_mt_ctx->stop_lock); ++ exit_flag = aes_mt_ctx->exit_flag; ++ pthread_rwlock_unlock(&aes_mt_ctx->stop_lock); ++ ++ if (exit_flag) ++ pthread_exit(NULL); ++} ++#else ++# define thread_loop_check_exit(s) ++#endif /* __APPLE__ */ ++ ++/* ++ * Helper function to terminate the helper threads ++ */ ++static void ++stop_and_join_pregen_threads(struct aes_mt_ctx_st *aes_mt_ctx) ++{ ++ int i; ++ ++#ifdef __APPLE__ ++ /* notify threads that they should exit */ ++ pthread_rwlock_wrlock(&aes_mt_ctx->stop_lock); ++ aes_mt_ctx->exit_flag = TRUE; ++ pthread_rwlock_unlock(&aes_mt_ctx->stop_lock); ++#endif /* __APPLE__ */ ++ ++ /* Cancel pregen threads */ ++ for (i = 0; i < cipher_threads; i++) { ++ debug_f ("Canceled %lu (%lu,%d)", aes_mt_ctx->tid[i], aes_mt_ctx->struct_id, ++ aes_mt_ctx->id[i]); ++ pthread_cancel(aes_mt_ctx->tid[i]); ++ } ++ for (i = 0; i < cipher_threads; i++) { ++ if (pthread_kill(aes_mt_ctx->tid[i], 0) != 0) ++ debug3("AES-CTR MT pthread_join failure: Invalid thread id %lu in %s", ++ aes_mt_ctx->tid[i], __func__); ++ else { ++ debug_f ("Joining %lu (%lu, %d)", aes_mt_ctx->tid[i], aes_mt_ctx->struct_id, ++ aes_mt_ctx->id[i]); ++ pthread_join(aes_mt_ctx->tid[i], NULL); ++ /* this finds the entry in the hash that corresponding to the ++ * thread id. That's used to find the pointer to the cipher struct ++ * created in thread_loop. */ ++ struct aes_mt_ctx_ptrs *ptr; ++ HASH_FIND_INT(evp_ptrs, &aes_mt_ctx->tid[i], ptr); ++ EVP_CIPHER_CTX_free(ptr->pointer); ++ HASH_DEL(evp_ptrs, ptr); ++ free(ptr); ++ } ++ } ++ pthread_rwlock_destroy(&aes_mt_ctx->tid_lock); ++} ++ ++/* determine the number of threads to use ++ * Testing indicates that in most all situations the optimal number of ++ * threads is 1 meaning 1 for inbound and 1 for outbound. The optimal ++ * queue count has also been determined to be thread_count + 1. ++ * note this function updates two globals - numkq and cipher_threads ++ * it returns the value of cipher_threads but it doesn't need to */ ++static int get_thread_count() { ++ ++ char * aes_threads = getenv("SSH_CIPHER_THREADS"); ++ debug_f ("SSH thread count is %s", aes_threads); ++ if (aes_threads != NULL && strlen(aes_threads) != 0) ++ cipher_threads = atoi(aes_threads); ++ else ++ cipher_threads = 1; ++ ++ if (cipher_threads < 1) ++ cipher_threads = 1; ++ ++ if (cipher_threads > MAX_THREADS) ++ cipher_threads = MAX_THREADS; ++ ++ numkq = cipher_threads + 1; ++ ++ if (numkq > MAX_NUMKQ) ++ numkq = MAX_NUMKQ; ++ ++ debug_f ("Starting %d threads and %d queues\n", cipher_threads, numkq); ++ ++ return (cipher_threads); ++} ++ ++ ++/* ++ * The life of a pregen thread: ++ * Find empty keystream queues and fill them using their counter. ++ * When done, update counter for the next fill. ++ */ ++static void * ++thread_loop(void *job) ++{ ++ EVP_CIPHER_CTX *evp_ctx; ++ struct aes_mt_ctx_st *aes_mt_ctx = job; ++ struct kq *q; ++ struct aes_mt_ctx_ptrs *ptr; ++ pthread_t first_tid; ++ int outlen; ++ u_char mynull[KQLEN * AES_BLOCK_SIZE]; ++ memset(&mynull, 0, KQLEN * AES_BLOCK_SIZE); ++ ++ /* get the thread id to see if this is the first one */ ++ pthread_rwlock_rdlock(&aes_mt_ctx->tid_lock); ++ first_tid = aes_mt_ctx->tid[0]; ++ pthread_rwlock_unlock(&aes_mt_ctx->tid_lock); ++ ++ /* create the context for this thread */ ++ evp_ctx = EVP_CIPHER_CTX_new(); ++ ++ /* keep track of the pointer for the evp in this struct ++ * so we can free it later. So we place it in a hash indexed on the ++ * thread id, which is available to us in the free function. ++ * Note, the thread id isn't necessary unique across rekeys but ++ * that's okay as they are unique during a key. */ ++ ptr = malloc(sizeof *ptr); /*freed in stop & prejoin */ ++ ptr->tid = pthread_self(); /* index for hash */ ++ ptr->pointer = evp_ctx; ++ HASH_ADD_INT(evp_ptrs, tid, ptr); ++ ++ /* initialize the cipher ctx with the key provided ++ * determinbe which cipher to use based on the key size */ ++ if (aes_mt_ctx->keylen == 256) ++ EVP_EncryptInit_ex(evp_ctx, EVP_aes_256_ctr(), NULL, aes_mt_ctx->orig_key, NULL); ++ else if (aes_mt_ctx->keylen == 128) ++ EVP_EncryptInit_ex(evp_ctx, EVP_aes_128_ctr(), NULL, aes_mt_ctx->orig_key, NULL); ++ else if (aes_mt_ctx->keylen == 192) ++ EVP_EncryptInit_ex(evp_ctx, EVP_aes_192_ctr(), NULL, aes_mt_ctx->orig_key, NULL); ++ else ++ fatal("Invalid key length of %d in AES CTR MT. Exiting", aes_mt_ctx->keylen); ++ ++ /* ++ * Handle the special case of startup, one thread must fill ++ * the first KQ then mark it as draining. Lock held throughout. ++ */ ++ if (pthread_equal(pthread_self(), first_tid)) { ++ /* get the first element of the key queue struct */ ++ q = &aes_mt_ctx->q[0]; ++ pthread_mutex_lock(&q->lock); ++ /* if we are in the INIT state then fill the queue */ ++ if (q->qstate == KQINIT) { ++ /* set the initial counter */ ++ EVP_EncryptInit_ex(evp_ctx, NULL, NULL, NULL, q->ctr); ++ /* encypher a block sized null string (mynull) with the key. This ++ * returns the keystream because xoring the keystream ++ * against null returns the keystream. Store that in the appropriate queue */ ++ EVP_EncryptUpdate(evp_ctx, q->keys[0], &outlen, mynull, KQLEN * AES_BLOCK_SIZE); ++ /* Update the aes counter */ ++ ssh_ctr_add(q->ctr, KQLEN * numkq, AES_BLOCK_SIZE); ++ /* since this is the first thread set it to draining */ ++ q->qstate = KQDRAINING; ++ pthread_cond_broadcast(&q->cond); ++ } ++ pthread_mutex_unlock(&q->lock); ++ } ++ ++ /* ++ * Normal case is to find empty queues and fill them, skipping over ++ * queues already filled by other threads and stopping to wait for ++ * a draining queue to become empty. ++ * ++ * Multiple threads may be waiting on a draining queue and awoken ++ * when empty. The first thread to wake will mark it as filling, ++ * others will move on to fill, skip, or wait on the next queue. ++ * We init qidx here because if we do it at the top of the function ++ * we get a warning about it possibly being clobbered. The exact reason ++ * doesn't make a lot of sense but it has to happen after the ++ * first pthread_rwlock_rdlock(). Might have something to do with ++ * incorrect compiler optimizations. ++ */ ++ int qidx; ++ for (qidx = 1;; qidx = (qidx + 1) % numkq) { ++ /* Check if I was cancelled, also checked in cond_wait */ ++ pthread_testcancel(); ++ ++ /* Check if we should exit as well */ ++ thread_loop_check_exit(aes_mt_ctx); ++ ++ /* Lock queue and block if its draining */ ++ q = &aes_mt_ctx->q[qidx]; ++ pthread_mutex_lock(&q->lock); ++ pthread_cleanup_push(thread_loop_cleanup, &q->lock); ++ while (q->qstate == KQDRAINING || q->qstate == KQINIT) { ++ thread_loop_check_exit(aes_mt_ctx); ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ pthread_cleanup_pop(0); ++ ++ /* If filling or full, somebody else got it, skip */ ++ if (q->qstate != KQEMPTY) { ++ pthread_mutex_unlock(&q->lock); ++ continue; ++ } ++ ++ /* ++ * Empty, let's fill it. ++ * Queue lock is relinquished while we do this so others ++ * can see that it's being filled. ++ */ ++ q->qstate = KQFILLING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ ++ /* set the initial counter */ ++ EVP_EncryptInit_ex(evp_ctx, NULL, NULL, NULL, q->ctr); ++ ++ /* see coresponding block above for useful comments */ ++ EVP_EncryptUpdate(evp_ctx, q->keys[0], &outlen, mynull, KQLEN * AES_BLOCK_SIZE); ++ ++ /* Re-lock, mark full and signal consumer */ ++ pthread_mutex_lock(&q->lock); ++ ssh_ctr_add(q->ctr, KQLEN * numkq, AES_BLOCK_SIZE); ++ q->qstate = KQFULL; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ } ++ ++ return NULL; ++} ++ ++ ++/* Our version of the EVP functions ++ * these are public as they are used by the provider */ ++ ++/* instantiate the cipher context. ++ * in this we create the EVP ctx and the AES ctx, setup the AES ctx ++ * initialize the EVP and then attach the AES ctx to the EVP ctx. ++ * The *only* difference between aes_mt_newctx_256|192|128 is the ++ * keylength of the cipher used in EVP_CipherInit ++ * parameters: provider context ++ * returns: EVP context ++ */ ++/* honestly the way this works makes me think that there has to be ++ * a better way of doing this however, I've yet to find one that doesn't ++ * involve more madness. I think that's mostly becase I don't understand ++ * how params work properly. I feel like I shoudl be able to use them ++ * to specify the key length but... also, I'd think I'd be able to ++ * set aes_mt_ctx_st->keylen to the keylength but that doesn't seem to ++ * work either. That said, this does work even if it's a bit clunky. ++ * -cjr 09/08/2022 */ ++void *aes_mt_newctx_256(void *provctx) ++{ ++ struct aes_mt_ctx_st *aes_mt_ctx = malloc(sizeof(*aes_mt_ctx)); ++ EVP_CIPHER_CTX *evp_ctx = EVP_CIPHER_CTX_new(); ++ ++ if ((aes_mt_ctx != NULL) && (evp_ctx != NULL)) { ++ get_thread_count(); /* update cipher_threads and numkq */ ++ pthread_rwlock_init(&aes_mt_ctx->tid_lock, NULL); ++#ifdef __APPLE__ ++ pthread_rwlock_init(&aes_mt_ctx->stop_lock, NULL); ++ aes_mt_ctx->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ aes_mt_ctx->state = HAVE_NONE; ++ ++ /* initialize the mutexs and conditions for each lock in our struct */ ++ for (int i = 0; i < numkq; i++) { ++ pthread_mutex_init(&aes_mt_ctx->q[i].lock, NULL); ++ pthread_cond_init(&aes_mt_ctx->q[i].cond, NULL); ++ } ++ aes_mt_ctx->provctx = provctx; ++ EVP_CipherInit(evp_ctx, EVP_aes_256_ctr(), NULL, NULL, 0); ++ EVP_CIPHER_CTX_set_app_data(evp_ctx, aes_mt_ctx); ++ return evp_ctx; ++ } ++ return NULL; ++} ++ ++void *aes_mt_newctx_192(void *provctx) ++{ ++ struct aes_mt_ctx_st *aes_mt_ctx = malloc(sizeof(*aes_mt_ctx)); ++ EVP_CIPHER_CTX *evp_ctx = EVP_CIPHER_CTX_new(); ++ ++ if ((aes_mt_ctx != NULL) && (evp_ctx != NULL)) { ++ get_thread_count(); /* update cipher_threads and numkq */ ++ pthread_rwlock_init(&aes_mt_ctx->tid_lock, NULL); ++#ifdef __APPLE__ ++ pthread_rwlock_init(&aes_mt_ctx->stop_lock, NULL); ++ aes_mt_ctx->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ aes_mt_ctx->state = HAVE_NONE; ++ ++ /* initialize the mutexs and conditions for each lock in our struct */ ++ for (int i = 0; i < numkq; i++) { ++ pthread_mutex_init(&aes_mt_ctx->q[i].lock, NULL); ++ pthread_cond_init(&aes_mt_ctx->q[i].cond, NULL); ++ } ++ aes_mt_ctx->provctx = provctx; ++ EVP_CipherInit(evp_ctx, EVP_aes_192_ctr(), NULL, NULL, 0); ++ EVP_CIPHER_CTX_set_app_data(evp_ctx, aes_mt_ctx); ++ return evp_ctx; ++ } ++ return NULL; ++} ++ ++void *aes_mt_newctx_128(void *provctx) ++{ ++ struct aes_mt_ctx_st *aes_mt_ctx = malloc(sizeof(*aes_mt_ctx)); ++ EVP_CIPHER_CTX *evp_ctx = EVP_CIPHER_CTX_new(); ++ ++ if ((aes_mt_ctx != NULL) && (evp_ctx != NULL)) { ++ get_thread_count(); /* update cipher_threads and numkq */ ++ pthread_rwlock_init(&aes_mt_ctx->tid_lock, NULL); ++#ifdef __APPLE__ ++ pthread_rwlock_init(&aes_mt_ctx->stop_lock, NULL); ++ aes_mt_ctx->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ aes_mt_ctx->state = HAVE_NONE; ++ ++ /* initialize the mutexs and conditions for each lock in our struct */ ++ for (int i = 0; i < numkq; i++) { ++ pthread_mutex_init(&aes_mt_ctx->q[i].lock, NULL); ++ pthread_cond_init(&aes_mt_ctx->q[i].cond, NULL); ++ } ++ aes_mt_ctx->provctx = provctx; ++ EVP_CipherInit(evp_ctx, EVP_aes_128_ctr(), NULL, NULL, 0); ++ EVP_CIPHER_CTX_set_app_data(evp_ctx, aes_mt_ctx); ++ return evp_ctx; ++ } ++ return NULL; ++} ++ ++/* this function expects a void but we need the actual context ++ * to get the app_data. ++ */ ++void aes_mt_freectx(void *vevp_ctx) ++{ ++ EVP_CIPHER_CTX *evp_ctx = vevp_ctx; ++ struct aes_mt_ctx_st *aes_mt_ctx; ++ ++ if ((aes_mt_ctx = EVP_CIPHER_CTX_get_app_data(evp_ctx)) != NULL) { ++ stop_and_join_pregen_threads(aes_mt_ctx); ++ ++ memset(aes_mt_ctx, 0, sizeof(*aes_mt_ctx)); ++ free(aes_mt_ctx); ++ EVP_CIPHER_CTX_set_app_data(evp_ctx, NULL); ++ } ++ EVP_CIPHER_CTX_free(evp_ctx); ++} ++ ++/* this function takes the EVP context, gets the AES context ++ * and starts the various threads we need */ ++int aes_mt_start_threads(void *vevp_ctx, const u_char *key, ++ size_t keylen, const u_char *iv, ++ size_t ivlen, const OSSL_PARAM *ossl_params) ++{ ++ EVP_CIPHER_CTX *evp_ctx = vevp_ctx; ++ struct aes_mt_ctx_st *aes_mt_ctx; ++ ++ ++ /* get the initial state of aes_mt_ctx (our cipher stream struct) */ ++ if ((aes_mt_ctx = EVP_CIPHER_CTX_get_app_data(evp_ctx)) == NULL) { ++ fatal("Missing AES MT context data!"); ++ } ++ ++ /* we are initializing but the current structure already ++ * has an IV and key so we want to kill the existing key data ++ * and start over. This is important when we need to rekey the data stream */ ++ if (aes_mt_ctx->state == (HAVE_KEY | HAVE_IV)) { ++ /* tell the pregen threads to exit */ ++ stop_and_join_pregen_threads(aes_mt_ctx); ++ ++#ifdef __APPLE__ ++ /* reset the exit flag */ ++ aes_mt_ctx->exit_flag = FALSE; ++#endif /* __APPLE__ */ ++ ++ /* Start over getting key & iv */ ++ aes_mt_ctx->state = HAVE_NONE; ++ } ++ ++ /* set the initial key for this key stream queue */ ++ if (key != NULL) { ++ aes_mt_ctx->keylen = EVP_CIPHER_CTX_key_length(evp_ctx) * 8; ++ aes_mt_ctx->orig_key = key; ++ aes_mt_ctx->state |= HAVE_KEY; ++ } ++ ++ /* set the IV */ ++ if (iv != NULL) { ++ /* init the counter this is just a 16byte uchar */ ++ memcpy(aes_mt_ctx->aes_counter, iv, AES_BLOCK_SIZE); ++ aes_mt_ctx->state |= HAVE_IV; ++ } ++ ++ if (aes_mt_ctx->state == (HAVE_KEY | HAVE_IV)) { ++ /* Clear queues */ ++ /* set the first key in the key queue to the current counter */ ++ memcpy(aes_mt_ctx->q[0].ctr, aes_mt_ctx->aes_counter, AES_BLOCK_SIZE); ++ /* indicate that it needs to be initialized */ ++ aes_mt_ctx->q[0].qstate = KQINIT; ++ /* for each of the remaining queues set the first counter to the ++ * counter and then add the size of the queue to the counter */ ++ for (int i = 1; i < numkq; i++) { ++ memcpy(aes_mt_ctx->q[i].ctr, aes_mt_ctx->aes_counter, AES_BLOCK_SIZE); ++ ssh_ctr_add(aes_mt_ctx->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE); ++ aes_mt_ctx->q[i].qstate = KQEMPTY; ++ } ++ aes_mt_ctx->qidx = 0; ++ aes_mt_ctx->ridx = 0; ++ aes_mt_ctx->struct_id = global_struct_id++; ++ ++ /* Start threads. Make sure we have enough stack space (under alpine) ++ * and aren't using more than we need (linux). This can be as low as ++ * 512KB but that's a minimum. 1024KB gives us a little headroom if we ++ * need it */ ++#define STACK_SIZE (1024 * 1024) ++ pthread_attr_t attr; ++ pthread_attr_init(&attr); ++ pthread_attr_setstacksize(&attr, STACK_SIZE); ++ for (int i = 0; i < cipher_threads; i++) { ++ pthread_rwlock_wrlock(&aes_mt_ctx->tid_lock); ++ if (pthread_create(&aes_mt_ctx->tid[i], &attr, thread_loop, aes_mt_ctx) != 0) ++ fatal ("AES-CTR MT Could not create thread in %s", __func__); ++ else { ++ aes_mt_ctx->id[i] = i; ++ debug_f ("AES-CTR MT spawned a thread with id %lu (%lu, %d)", ++ aes_mt_ctx->tid[i], aes_mt_ctx->struct_id, ++ aes_mt_ctx->id[i]); ++ } ++ pthread_rwlock_unlock(&aes_mt_ctx->tid_lock); ++ } ++ pthread_mutex_lock(&aes_mt_ctx->q[0].lock); ++ // wait for all of the threads to be initialized ++ while (aes_mt_ctx->q[0].qstate == KQINIT) ++ pthread_cond_wait(&aes_mt_ctx->q[0].cond, &aes_mt_ctx->q[0].lock); ++ pthread_mutex_unlock(&aes_mt_ctx->q[0].lock); ++ } ++ return 1; ++} ++ ++/* this should correspond to ssh_aes_ctr ++ * OSSL_CORE_MAKE_FUNC(int, cipher_cipher, ++ * (void *cctx, ++ * unsigned char *out, size_t *outl, size_t outsize, ++ * const unsigned char *in, size_t inl)) ++ */ ++ ++int aes_mt_do_cipher(void *vevp_ctx, ++ u_char *dest, size_t *destlen, size_t destsize, ++ const u_char *src, size_t len) ++{ ++ typedef union { ++#ifdef CIPHER_INT128_OK ++ __uint128_t *u128; ++#endif ++ uint64_t *u64; ++ uint32_t *u32; ++ uint8_t *u8; ++ const uint8_t *cu8; ++ uintptr_t u; ++ } ptrs_t; ++ ptrs_t destp, srcp, bufp; ++ uintptr_t align; ++ struct aes_mt_ctx_st *aes_mt_ctx; ++ struct kq *q, *oldq; ++ int ridx; ++ u_char *buf; ++ EVP_CIPHER_CTX *evp_ctx = vevp_ctx; ++ ++ if (len == 0) ++ return 1; ++ ++ if ((aes_mt_ctx = EVP_CIPHER_CTX_get_app_data(evp_ctx)) == NULL) ++ return 0; ++ ++ q = &aes_mt_ctx->q[aes_mt_ctx->qidx]; ++ ridx = aes_mt_ctx->ridx; ++ ++ /* src already padded to block multiple */ ++ srcp.cu8 = src; ++ destp.u8 = dest; ++ do { /* do until len is 0 */ ++ buf = q->keys[ridx]; ++ bufp.u8 = buf; ++ ++ /* figure out the alignment on the fly */ ++#ifdef CIPHER_UNALIGNED_OK ++ align = 0; ++#else ++ align = destp.u | srcp.u | bufp.u; ++#endif ++ ++ /* xor the src against the key (buf) ++ * different systems can do all 16 bytes at once or ++ * may need to do it in 8 or 4 bytes chunks ++ * worst case is doing it as a loop */ ++#ifdef CIPHER_INT128_OK ++ /* with GCC 13 we have having consistent seg faults ++ * in this section of code. Since this is a critical ++ * code path we are removing this until we have a solution ++ * in place -cjr 02/22/24 ++ * TODO: FIX THIS ++ */ ++ /* if ((align & 0xf) == 0) { */ ++ /* destp.u128[0] = srcp.u128[0] ^ bufp.u128[0]; */ ++ /* } else */ ++#endif ++ /* 64 bits */ ++ if ((align & 0x7) == 0) { ++ destp.u64[0] = srcp.u64[0] ^ bufp.u64[0]; ++ destp.u64[1] = srcp.u64[1] ^ bufp.u64[1]; ++ /* 32 bits */ ++ } else if ((align & 0x3) == 0) { ++ destp.u32[0] = srcp.u32[0] ^ bufp.u32[0]; ++ destp.u32[1] = srcp.u32[1] ^ bufp.u32[1]; ++ destp.u32[2] = srcp.u32[2] ^ bufp.u32[2]; ++ destp.u32[3] = srcp.u32[3] ^ bufp.u32[3]; ++ } else { ++ /*1 byte at a time*/ ++ size_t i; ++ for (i = 0; i < AES_BLOCK_SIZE; ++i) ++ dest[i] = src[i] ^ buf[i]; ++ } ++ ++ /* inc/decrement the pointers by the block size (16)*/ ++ destp.u += AES_BLOCK_SIZE; ++ srcp.u += AES_BLOCK_SIZE; ++ ++ /* Increment read index, switch queues on rollover */ ++ if ((ridx = (ridx + 1) % KQLEN) == 0) { ++ oldq = q; ++ ++ /* Mark next queue draining, may need to wait */ ++ aes_mt_ctx->qidx = (aes_mt_ctx->qidx + 1) % numkq; ++ q = &aes_mt_ctx->q[aes_mt_ctx->qidx]; ++ pthread_mutex_lock(&q->lock); ++ while (q->qstate != KQFULL) { ++ pthread_cond_wait(&q->cond, &q->lock); ++ } ++ q->qstate = KQDRAINING; ++ pthread_cond_broadcast(&q->cond); ++ pthread_mutex_unlock(&q->lock); ++ ++ /* Mark consumed queue empty and signal producers */ ++ pthread_mutex_lock(&oldq->lock); ++ oldq->qstate = KQEMPTY; ++ pthread_cond_broadcast(&oldq->cond); ++ pthread_mutex_unlock(&oldq->lock); ++ } ++ } while (len -= AES_BLOCK_SIZE); ++ aes_mt_ctx->ridx = ridx; ++ return 1; ++} ++ ++#endif /*WITH_OPENSSL3*/ +diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.h openssh-9.6p1/cipher-ctr-mt-functions.h +--- openssh-9.6p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-ctr-mt-functions.h 2024-07-10 13:34:02.714358576 +0200 +@@ -0,0 +1,142 @@ ++/* ++ * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 ++ * ++ * Author: Benjamin Bennett ++ * Author: Mike Tasota ++ * Author: Chris Rapier ++ * Copyright (c) 2008-2022 Pittsburgh Supercomputing Center. All rights reserved. ++ * ++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged, ++ * Copyright (c) 2003 Markus Friedl ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef CTR_MT_FUNCS ++#define CTR_MT_FUNCS ++ ++/* includes */ ++#include "includes.h" /* needed to get version number */ ++#include ++#include ++#include "cipher-aesctr.h" ++#include "uthash.h" ++ ++#ifndef USE_BUILTIN_RIJNDAEL ++#include ++#endif ++ ++/* only for systems with OSSL 3 */ ++#ifdef WITH_OPENSSL3 ++ ++/*-------------------- TUNABLES --------------------*/ ++/* maximum number of threads and queues */ ++#define MAX_THREADS 32 ++#define MAX_NUMKQ (MAX_THREADS + 1) ++ ++/* one queue holds 8192 * 4 * 16B (512KB) of key data ++ * being that the queues are destroyed after a rekey ++ * and at leats one has to be fully filled prior to ++ * enciphering data we don't want this to be too large */ ++#define KQLEN (8192 * 4) ++ ++/* Processor cacheline length */ ++#define CACHELINE_LEN 64 ++ ++/* Can the system do unaligned loads natively? */ ++#if defined(__aarch64__) || \ ++ defined(__i386__) || \ ++ defined(__powerpc__) || \ ++ defined(__x86_64__) ++# define CIPHER_UNALIGNED_OK ++#endif ++#if defined(__SIZEOF_INT128__) ++# define CIPHER_INT128_OK ++#endif ++ ++/* context states */ ++#define HAVE_NONE 0 ++#define HAVE_KEY 1 ++#define HAVE_IV 2 ++ ++/* Keystream Queue state */ ++enum { ++ KQINIT, ++ KQEMPTY, ++ KQFILLING, ++ KQFULL, ++ KQDRAINING ++}; ++ ++/* structs */ ++ ++/* provider struct */ ++struct provider_ctx_st { ++ const OSSL_CORE_HANDLE *core_handle; ++ struct proverr_functions_st *proverr_handle; ++}; ++ ++/* Keystream Queue struct */ ++struct kq { ++ u_char keys[KQLEN][AES_BLOCK_SIZE]; /* [32768][16B] */ ++ u_char ctr[AES_BLOCK_SIZE]; /* 16B */ ++ u_char pad0[CACHELINE_LEN]; ++ pthread_mutex_t lock; ++ pthread_cond_t cond; ++ int qstate; ++ u_char pad1[CACHELINE_LEN]; ++}; ++ ++/* AES MT context struct */ ++struct aes_mt_ctx_st { ++ struct provider_ctx_st *provctx; ++ long unsigned int struct_id; ++ int keylen; ++ int state; ++ int qidx; ++ int ridx; ++ int id[MAX_THREADS]; /* 32 */ ++ AES_KEY aes_key; ++ const u_char *orig_key; ++ u_char aes_counter[AES_BLOCK_SIZE]; /* 16B */ ++ pthread_t tid[MAX_THREADS]; /* 32 */ ++ pthread_rwlock_t tid_lock; ++ struct kq q[MAX_NUMKQ]; /* 33 */ ++#ifdef __APPLE__ ++ pthread_rwlock_t stop_lock; ++ int exit_flag; ++#endif /* __APPLE__ */ ++ int ongoing; /* possibly not needed */ ++}; ++ ++/* this holds an array of evp context pointers that are ++ * created in thread_loop. Since we can't effectively free those ++ * contexts in thread_loop we keep a copy of those pointers here ++ * and then free them in stop_and_join_pregenthreads ++ * cjr 2/2/2023 ++ */ ++struct aes_mt_ctx_ptrs { ++ EVP_CIPHER_CTX *pointer; ++ pthread_t tid; ++ UT_hash_handle hh; ++}; ++ ++int aes_mt_do_cipher(void *, u_char *, size_t *, size_t, const u_char *, size_t); ++int aes_mt_start_threads(void *, const u_char *, size_t, const u_char *, size_t, const OSSL_PARAM *); ++void aes_mt_freectx(void *); ++void *aes_mt_newctx_256(void *); ++void *aes_mt_newctx_192(void *); ++void *aes_mt_newctx_128(void *); ++ ++#endif /* WITH OPENSSL */ ++#endif /* CTR_MT_FUNCS */ +diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-provider.c openssh-9.6p1/cipher-ctr-mt-provider.c +--- openssh-9.6p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-ctr-mt-provider.c 2024-07-10 13:34:02.714358576 +0200 +@@ -0,0 +1,390 @@ ++/* ++ * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 ++ * ++ * Author: Chris Rapier ++ * Copyright (c) 2022 Pittsburgh Supercomputing Center. All rights reserved. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* based on vienere.c from https://github.com/provider-corner/vigenere by ++ * Richard Levitte provided under a CC0 Public License. */ ++ ++#include "includes.h" ++ ++/* only for systems with OSSL 3.0+ */ ++#ifdef WITH_OPENSSL3 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "xmalloc.h" ++#include "ossl3-provider-err.h" ++#include "num.h" ++#include "cipher-ctr-mt-functions.h" ++ ++#define ERR_HANDLE(ctx) ((ctx)->provctx->proverr_handle) ++ ++/* forward declartion of cipher functions */ ++/* cipher context functions */ ++OSSL_FUNC_cipher_newctx_fn aes_mt_newctx_256; ++OSSL_FUNC_cipher_newctx_fn aes_mt_newctx_192; ++OSSL_FUNC_cipher_newctx_fn aes_mt_newctx_128; ++OSSL_FUNC_cipher_freectx_fn aes_mt_freectx; ++ ++/* param related function*/ ++static OSSL_FUNC_cipher_get_params_fn aes_mt_get_params_256; ++static OSSL_FUNC_cipher_get_params_fn aes_mt_get_params_192; ++static OSSL_FUNC_cipher_get_params_fn aes_mt_get_params_128; ++static OSSL_FUNC_cipher_gettable_params_fn aes_mt_gettable_params; ++static OSSL_FUNC_cipher_set_ctx_params_fn aes_mt_set_ctx_params; ++static OSSL_FUNC_cipher_get_ctx_params_fn aes_mt_get_ctx_params; ++static OSSL_FUNC_cipher_settable_ctx_params_fn aes_mt_settable_ctx_params; ++static OSSL_FUNC_cipher_gettable_ctx_params_fn aes_mt_gettable_ctx_params; ++ ++/* en/decipher functions */ ++OSSL_FUNC_cipher_encrypt_init_fn aes_mt_start_threads; ++OSSL_FUNC_cipher_decrypt_init_fn aes_mt_start_threads; ++OSSL_FUNC_cipher_update_fn aes_mt_do_cipher; ++ ++/* provider context */ ++static OSSL_FUNC_provider_query_operation_fn aes_mt_prov_query; ++static OSSL_FUNC_provider_get_reason_strings_fn aes_mt_prov_reasons; ++static OSSL_FUNC_provider_teardown_fn aes_mt_prov_teardown; ++static OSSL_FUNC_provider_get_params_fn aes_mt_prov_get_params; ++OSSL_provider_init_fn OSSL_provider_init; /* need this? */ ++ ++/* error functions */ ++OSSL_FUNC_core_new_error_fn *c_new_error; ++OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug; ++OSSL_FUNC_core_vset_error_fn *c_vset_error; ++OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark; ++OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark; ++OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark; ++ ++/* Errors used in this provider */ ++#define AES_MT_E_MALLOC 1 ++#define AES_MT_ONGOING_OPERATION 2 ++#define AES_MT_BAD_KEYLEN 3 ++ ++/* typedef for function pointers */ ++typedef void(*fptr_t)(void); ++ ++/* all of the various arrays we need */ ++ ++/* BAD_KEYLEN isn't being used at the moment */ ++const OSSL_ITEM reasons[] = { ++ { AES_MT_E_MALLOC, "Memory allocation failure" }, ++ { AES_MT_ONGOING_OPERATION, "Operation underway" }, ++ { AES_MT_BAD_KEYLEN, "Only 256, 192, and 128 Key lengths are supported" }, ++ { 0, NULL } /* Termination */ ++}; ++ ++/* function mapping for 256|192|128 key lengths */ ++const OSSL_DISPATCH aes_mt_funcs_256[] = { ++ { OSSL_FUNC_CIPHER_NEWCTX, (fptr_t)aes_mt_newctx_256 } , ++ { OSSL_FUNC_CIPHER_FREECTX, (fptr_t)aes_mt_freectx }, ++ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_UPDATE, (fptr_t)aes_mt_do_cipher }, ++ { OSSL_FUNC_CIPHER_GET_PARAMS, (fptr_t)aes_mt_get_params_256 }, ++ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (fptr_t)aes_mt_gettable_params }, ++ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (fptr_t)aes_mt_get_ctx_params }, ++ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_gettable_ctx_params }, ++ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (fptr_t)aes_mt_set_ctx_params }, ++ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_settable_ctx_params }, ++ { 0, NULL } ++}; ++ ++const OSSL_DISPATCH aes_mt_funcs_192[] = { ++ { OSSL_FUNC_CIPHER_NEWCTX, (fptr_t)aes_mt_newctx_192 } , ++ { OSSL_FUNC_CIPHER_FREECTX, (fptr_t)aes_mt_freectx }, ++ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_UPDATE, (fptr_t)aes_mt_do_cipher }, ++ { OSSL_FUNC_CIPHER_GET_PARAMS, (fptr_t)aes_mt_get_params_192 }, ++ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (fptr_t)aes_mt_gettable_params }, ++ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (fptr_t)aes_mt_get_ctx_params }, ++ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_gettable_ctx_params }, ++ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (fptr_t)aes_mt_set_ctx_params }, ++ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_settable_ctx_params }, ++ { 0, NULL } ++}; ++ ++const OSSL_DISPATCH aes_mt_funcs_128[] = { ++ { OSSL_FUNC_CIPHER_NEWCTX, (fptr_t)aes_mt_newctx_128 } , ++ { OSSL_FUNC_CIPHER_FREECTX, (fptr_t)aes_mt_freectx }, ++ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (fptr_t)aes_mt_start_threads }, ++ { OSSL_FUNC_CIPHER_UPDATE, (fptr_t)aes_mt_do_cipher }, ++ { OSSL_FUNC_CIPHER_GET_PARAMS, (fptr_t)aes_mt_get_params_128 }, ++ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (fptr_t)aes_mt_gettable_params }, ++ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (fptr_t)aes_mt_get_ctx_params }, ++ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_gettable_ctx_params }, ++ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (fptr_t)aes_mt_set_ctx_params }, ++ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, ++ (fptr_t)aes_mt_settable_ctx_params }, ++ { 0, NULL } ++}; ++ ++/* the ciphers found in this provider */ ++const OSSL_ALGORITHM aes_mt_ciphers[] = { ++ { "aes_ctr_mt_256", "provider=hpnssh", aes_mt_funcs_256, NULL }, ++ { "aes_ctr_mt_192", "provider=hpnssh", aes_mt_funcs_192, NULL }, ++ { "aes_ctr_mt_128", "provider=hpnssh", aes_mt_funcs_128, NULL }, ++ { NULL, NULL, NULL, NULL } ++}; ++ ++/* function mapping for provider methods */ ++const OSSL_DISPATCH provider_functions[] = { ++ { OSSL_FUNC_PROVIDER_TEARDOWN, (fptr_t)aes_mt_prov_teardown }, ++ { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (fptr_t)aes_mt_prov_query }, ++ { OSSL_FUNC_PROVIDER_GET_PARAMS, (fptr_t)aes_mt_prov_get_params }, ++ { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (fptr_t)aes_mt_prov_reasons }, ++ { 0, NULL } ++}; ++ ++static const OSSL_PARAM ctx_get_param_table[] = { ++ { "keylen", OSSL_PARAM_UNSIGNED_INTEGER, NULL, sizeof(size_t), 0 }, ++ { NULL, 0, NULL, 0, 0 }, ++}; ++ ++static const OSSL_PARAM cipher_get_param_table[] = { ++ { "blocksize", OSSL_PARAM_UNSIGNED_INTEGER, NULL, sizeof(size_t), 0 }, ++ { "keylen", OSSL_PARAM_UNSIGNED_INTEGER, NULL, sizeof(size_t), 0 }, ++ { NULL, 0, NULL, 0, 0 }, ++}; ++ ++static const OSSL_PARAM cipher_set_param_table[] = { ++ { "keylen", OSSL_PARAM_UNSIGNED_INTEGER, NULL, sizeof(size_t), 0 }, ++ { NULL, 0, NULL, 0, 0 }, ++}; ++ ++ ++/* provider functions start here */ ++ ++static void provider_ctx_free(struct provider_ctx_st *ctx) ++{ ++ if (ctx != NULL) ++ proverr_free_handle(ctx->proverr_handle); ++ free(ctx); ++} ++ ++static struct provider_ctx_st *provider_ctx_new(const OSSL_CORE_HANDLE *core, ++ const OSSL_DISPATCH *in) ++{ ++ struct provider_ctx_st *ctx; ++ ++ if ((ctx = malloc(sizeof(*ctx))) != NULL ++ && (ctx->proverr_handle = proverr_new_handle(core, in)) != NULL) { ++ ctx->core_handle = core; ++ } else { ++ provider_ctx_free(ctx); ++ ctx = NULL; ++ } ++ return ctx; ++} ++ ++ ++/* returns the appropriate algo table for the requested function ++ * in this case we should only be working with OP_CIPHER */ ++const OSSL_ALGORITHM *aes_mt_prov_query(void *provctx, int operation_id, ++ int *no_store) ++{ ++ switch (operation_id) { ++ case OSSL_OP_CIPHER: ++ return aes_mt_ciphers; ++ } ++ return NULL; ++} ++ ++const OSSL_ITEM *aes_mt_prov_reasons(void *provctx) ++{ ++ return reasons; ++} ++ ++static int aes_mt_prov_get_params(void *provctx, OSSL_PARAM *params) ++{ ++ OSSL_PARAM *p; ++ int ok = 1; ++ ++ char *VERSION="1.0"; ++ char *BUILDTYPE="aes_ctr_mt@hpnssh.org"; ++ ++ for(p = params; p->key != NULL; p++) ++ if (strcasecmp(p->key, "version") == 0) { ++ *(const void **)p->data = VERSION; ++ p->return_size = strlen(VERSION); ++ } else if (strcasecmp(p->key, "buildinfo") == 0 ++ && BUILDTYPE[0] != '\0') { ++ *(const void **)p->data = BUILDTYPE; ++ p->return_size = strlen(BUILDTYPE); ++ } ++ return ok; ++} ++ ++/* The function that tears down this provider */ ++static void aes_mt_prov_teardown(void *vprovctx) ++{ ++ provider_ctx_free(vprovctx); ++} ++ ++int OSSL_provider_init(const OSSL_CORE_HANDLE *core, ++ const OSSL_DISPATCH *in, ++ const OSSL_DISPATCH **out, ++ void **vprovctx) ++{ ++ if ((*vprovctx = provider_ctx_new(core, in)) == NULL) ++ return 0; ++ *out = provider_functions; ++ return 1; ++} ++ ++/* parameter functions for 256|192|128 bit key lengths */ ++static int aes_mt_get_params_256(OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ int ok = 1; ++ ++ for (p = params; p->key != NULL; p++) { ++ if (strcasecmp(p->key, "blocksize") == 0) ++ if (provnum_set_size_t(p, AES_BLOCK_SIZE) < 0) { ++ ok = 0; ++ continue; ++ } ++ if (strcasecmp(p->key, "keylen") == 0) { ++ size_t keyl = 32; ++ ++ if (provnum_set_size_t(p, keyl) < 0) { ++ ok = 0; ++ continue; ++ } ++ } ++ } ++ return ok; ++} ++ ++static int aes_mt_get_params_192(OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ int ok = 1; ++ ++ for (p = params; p->key != NULL; p++) { ++ if (strcasecmp(p->key, "blocksize") == 0) ++ if (provnum_set_size_t(p, AES_BLOCK_SIZE) < 0) { ++ ok = 0; ++ continue; ++ } ++ if (strcasecmp(p->key, "keylen") == 0) { ++ size_t keyl = 24; ++ ++ if (provnum_set_size_t(p, keyl) < 0) { ++ ok = 0; ++ continue; ++ } ++ } ++ } ++ return ok; ++} ++ ++static int aes_mt_get_params_128(OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ int ok = 1; ++ ++ for (p = params; p->key != NULL; p++) { ++ if (strcasecmp(p->key, "blocksize") == 0) ++ if (provnum_set_size_t(p, AES_BLOCK_SIZE) < 0) { ++ ok = 0; ++ continue; ++ } ++ if (strcasecmp(p->key, "keylen") == 0) { ++ size_t keyl = 16; ++ ++ if (provnum_set_size_t(p, keyl) < 0) { ++ ok = 0; ++ continue; ++ } ++ } ++ } ++ return ok; ++} ++ ++/* Parameters that libcrypto can get from this implementation */ ++static const OSSL_PARAM *aes_mt_gettable_params(void *provctx) ++{ ++ return cipher_get_param_table; ++} ++ ++static const OSSL_PARAM *aes_mt_gettable_ctx_params(void *cctx, void *provctx) ++{ ++ return ctx_get_param_table; ++} ++ ++static int aes_mt_get_ctx_params(void *vctx, OSSL_PARAM params[]) ++{ ++ struct aes_mt_ctx_st *ctx = vctx; ++ int ok = 1; ++ ++ if (ctx->keylen > 0) { ++ OSSL_PARAM *p; ++ ++ for (p = params; p->key != NULL; p++) ++ if (strcasecmp(p->key, "keylen") == 0 ++ && provnum_set_size_t(p, ctx->keylen) < 0) { ++ ok = 0; ++ continue; ++ } ++ } ++ return ok; ++} ++ ++/* Parameters that libcrypto can send to this implementation */ ++static const OSSL_PARAM *aes_mt_settable_ctx_params(void *cctx, void *provctx) ++{ ++ return cipher_set_param_table; ++} ++ ++static int aes_mt_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ++{ ++ struct aes_mt_ctx_st *ctx = vctx; ++ const OSSL_PARAM *p; ++ int ok = 1; ++ ++ if (ctx->ongoing) { ++ ERR_raise(ERR_HANDLE(ctx), AES_MT_ONGOING_OPERATION); ++ return 0; ++ } ++ ++ for (p = params; p->key != NULL; p++) ++ if (strcasecmp(p->key, "keylen") == 0) { ++ size_t keyl = 0; ++ ++ if (provnum_get_size_t(&keyl, p) < 0) { ++ ok = 0; ++ continue; ++ } ++ ctx->keylen = keyl; ++ } ++ return ok; ++} ++ ++#endif /*WITH_OPENSSL3*/ +diff -Nur openssh-9.6p1.orig/cipher.h openssh-9.6p1/cipher.h +--- openssh-9.6p1.orig/cipher.h 2024-07-10 13:32:39.541111639 +0200 ++++ openssh-9.6p1/cipher.h 2024-07-10 13:34:02.714358576 +0200 +@@ -42,11 +42,17 @@ + #include + #endif + #include "cipher-chachapoly.h" ++#ifdef WITH_OPENSSL ++#include "cipher-chachapoly-libcrypto-mt.h" ++#endif + #include "cipher-aesctr.h" + + #define CIPHER_ENCRYPT 1 + #define CIPHER_DECRYPT 0 + ++#define CIPHER_MULTITHREAD 1 ++#define CIPHER_SERIAL 0 ++ + struct sshcipher { + char *name; + u_int block_size; +@@ -60,6 +66,7 @@ + #define CFLAG_NONE (1<<3) + #define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ + #ifdef WITH_OPENSSL ++#define CFLAG_MT (1<<4) + const EVP_CIPHER *(*evptype)(void); + #else + void *ignored; +@@ -68,24 +75,27 @@ + + struct sshcipher_ctx; + +-const struct sshcipher *cipher_by_name(const char *); ++struct sshcipher *cipher_by_name(const char *); + const char *cipher_warning_message(const struct sshcipher_ctx *); + int ciphers_valid(const char *); + char *cipher_alg_list(char, int); + const char *compression_alg_list(int); + int cipher_init(struct sshcipher_ctx **, const struct sshcipher *, +- const u_char *, u_int, const u_char *, u_int, int); ++ const u_char *, u_int, const u_char *, u_int, u_int, int, int); + int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, + u_int, u_int, u_int); + int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, + const u_char *, u_int); + void cipher_free(struct sshcipher_ctx *); + u_int cipher_blocksize(const struct sshcipher *); ++uint64_t cipher_rekey_blocks(const struct sshcipher *); + u_int cipher_keylen(const struct sshcipher *); + u_int cipher_seclen(const struct sshcipher *); + u_int cipher_authlen(const struct sshcipher *); + u_int cipher_ivlen(const struct sshcipher *); + u_int cipher_is_cbc(const struct sshcipher *); ++void cipher_reset_multithreaded(void); ++const char *cipher_ctx_name(const struct sshcipher_ctx *); + + u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); + +diff -Nur openssh-9.6p1.orig/cipher-switch.c openssh-9.6p1/cipher-switch.c +--- openssh-9.6p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-switch.c 2024-07-10 13:34:02.715358579 +0200 +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++/* This provides the function to switch from a serial to parallel ++ * cipher. This has been moved into it's own file in order to make it ++ * available to both the client and server without having to clutter ++ * up other files. ++ */ ++ ++#include "includes.h" ++#include ++#include ++#include "cipher.h" ++#include "log.h" ++#include "packet.h" ++ ++ ++/* if we are using a parallel cipher there can be issues in either ++ * a fork or sandbox. Essentially, if we switch too early the ++ * threads get lost and the application hangs. So what we do is ++ * test if either the send or receive context cipher name ++ * matches the known available parallel ciphers. If it does ++ * then we force a rekey which automatically loads the parallel ++ * cipher. */ ++ ++void ++cipher_switch(struct ssh *ssh) { ++#ifdef WITH_OPENSSL ++ /* get the send and receive context and extract the cipher name */ ++ const void *send_cc = ssh_packet_get_send_context(ssh); ++ const void *recv_cc = ssh_packet_get_receive_context(ssh); ++ const char *send = cipher_ctx_name(send_cc); ++ const char *recv = cipher_ctx_name(recv_cc); ++ ++ debug_f("Send: %s Recv: %s", send, recv); ++ ++ /* if the name of the cipher matches then we set the context ++ * to authenticated (it likely already is though) and then ++ * force the rekey. Either side can do this. One downside of ++ * this method is that both sides can request a rekey so you ++ * can end up duplicating work. This is annoying but the ++ * performance gains make it worthwhile. Also I ++ * use strstr here because strcmp would require a 6 part ++ * if statement */ ++ if (strstr(send, "ctr") || strstr(recv, "ctr")) { ++ debug("Serial to parallel AES-CTR cipher swap"); ++ /* cipher_reset_multithreaded(); */ ++ ssh_packet_set_authenticated(ssh); ++ packet_request_rekeying(); ++ } ++ /* do the same for multithreaded chacha20 but with strcmp */ ++ if ((strcmp(send, "chacha20-poly1305@openssh.com") == 0) || ++ (strcmp(recv, "chacha20-poly1305@openssh.com") == 0)) { ++ debug("Serial to parallel Chacha20-poly1305 cipher swap"); ++ ssh_packet_set_authenticated(ssh); ++ packet_request_rekeying(); ++ } ++#endif ++} +diff -Nur openssh-9.6p1.orig/cipher-switch.h openssh-9.6p1/cipher-switch.h +--- openssh-9.6p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/cipher-switch.h 2024-07-10 13:34:02.715358579 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) 2015 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++void cipher_switch (struct ssh *); +diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c +--- openssh-9.6p1.orig/clientloop.c 2024-07-10 13:32:39.581111758 +0200 ++++ openssh-9.6p1/clientloop.c 2024-07-10 13:34:02.716358582 +0200 +@@ -114,6 +114,7 @@ + #include "msg.h" + #include "ssherr.h" + #include "hostfile.h" ++#include "metrics.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -172,6 +173,10 @@ + + static void client_init_dispatch(struct ssh *ssh); + int session_ident = -1; ++int metrics_hdr_remote_flag = 0; ++int metrics_hdr_local_flag = 0; ++int remote_no_poll_flag = 0; ++int local_no_poll_flag = 0; + + /* Track escape per proto2 channel */ + struct escape_filter_ctx { +@@ -199,6 +204,9 @@ + TAILQ_HEAD_INITIALIZER(global_confirms); + + void ssh_process_session2_setup(int, int, int, struct sshbuf *); ++ ++void client_request_metrics(struct ssh *); ++ + static void quit_message(const char *fmt, ...) + __attribute__((__format__ (printf, 1, 2))); + +@@ -1453,6 +1461,7 @@ + double start_time, total_time; + int channel_did_enqueue = 0, r, len; + u_int64_t ibytes, obytes; ++ time_t previous_time; + int conn_in_ready, conn_out_ready; + sigset_t bsigset, osigset; + +@@ -1494,6 +1503,7 @@ + client_repledge(); + + start_time = monotime_double(); ++ previous_time = time(NULL); /* for metrics polling */ + + /* Initialize variables. */ + last_was_cr = 1; +@@ -1539,6 +1549,8 @@ + } + + schedule_server_alive_check(); ++ if (options.metrics) ++ client_request_metrics(ssh); /* initial metrics polling */ + + if (sigemptyset(&bsigset) == -1 || + sigaddset(&bsigset, SIGHUP) == -1 || +@@ -1549,6 +1561,12 @@ + + /* Main loop of the client for the interactive session mode. */ + while (!quit_pending) { ++ if (options.metrics) { ++ if ((time(NULL) - previous_time) >= options.metrics_interval) { ++ client_request_metrics(ssh); ++ previous_time = time(NULL); ++ } ++ } + channel_did_enqueue = 0; + + /* Process buffered packets sent by the server. */ +@@ -1641,6 +1659,10 @@ + } + } + } ++ ++ if (options.metrics) ++ client_request_metrics(ssh); /* final metrics polling */ ++ + free(pfd); + + /* Terminate the session. */ +@@ -2684,6 +2706,167 @@ + return 1; + } + ++/* take the response from the server and parse out the data. ++ * the _ctx should be null. It's just here because the format ++ * of the callback handler expects it. Likewise, seq is ++ * not used. */ ++static void ++client_process_request_metrics (struct ssh *ssh, int type, u_int32_t seq, void *_ctx) { ++ struct tcp_info local_tcp_info; ++ const u_char *blob; ++ FILE *remfptr; ++ FILE *localfptr; ++ char remfilename[1024]; ++ char localfilename[1024]; ++ time_t now; ++ struct tm *info; ++ char timestamp[40]; ++ char *metricsstring = NULL; ++ size_t tcpi_len, len = 0; ++ binn *metricsobj = NULL; ++ int r, kernel_version = 0; ++ ++ time(&now); ++ info = localtime(&now); ++ strftime(timestamp, 40, "%d-%m-%Y %H:%M:%S", info); ++ ++ /* malloc the string 1KB should be large enough */ ++ metricsstring = malloc(1024); ++ ++ /* get the local socket information */ ++ int sock_in = ssh_packet_get_connection_in(ssh); ++ ++ /* the user can specify a name/path with options.metrics_path ++ * but if it's not defined we'll use a default name. In either case ++ * the name will have a suffix of local for the local data and remote for ++ * the remote data */ ++ if (options.metrics_path == NULL) { ++ snprintf(remfilename, 1024, "%s", "./ssh_stack_metrics.remote"); ++ snprintf(localfilename, 1024, "%s", "./ssh_stack_metrics.local"); ++ } else { ++ snprintf(remfilename, 1024, "%s.%s", options.metrics_path, "remote"); ++ snprintf(localfilename, 1024, "%s.%s", options.metrics_path, "local"); ++ } ++ ++ /* should be type 81 and if it's not then its likley that ++ * the remote does not support polling. We can still get local data though ++ */ ++ if (type != SSH2_MSG_REQUEST_SUCCESS) { ++ if (remote_no_poll_flag == 0) { ++ error("Remote does not support stack metric polling. Local data only."); ++ remote_no_poll_flag = 1; ++ } ++ goto localonly; ++ } ++ ++ /* open the file handle to write the remote data*/ ++ remfptr = fopen(remfilename, "a"); ++ if (remfptr == NULL) ++ fatal("Error opening %s: %s", remfilename, strerror(errno)); ++ ++ /* read the entire packet string into blob ++ * blob has to be a const uchar as that's what string_direct expects ++ * we cast it as a void for the binn functions */ ++ sshpkt_get_string_direct(ssh, &blob, &len); ++ if (len == 0) { ++ /* received no data. which is weird */ ++ error("Received no remote metrics data. Continuing."); ++ } ++ ++ /* get the kernel version printing the header */ ++ kernel_version = binn_object_int32((void *)blob, "kernel_version"); ++ ++ /* create a string of the data from the binn object blob */ ++ metrics_read_binn_object((void *)blob, &metricsstring); ++ ++ /* have we printed the header? */ ++ if (metrics_hdr_remote_flag == 0) { ++ metrics_print_header(remfptr, "REMOTE CONNECTION", kernel_version); ++ metrics_hdr_remote_flag = 1; ++ } ++ fprintf(remfptr, "%s, ", timestamp); ++ fprintf(remfptr, "%s\n", metricsstring); ++ ++ /* close remote file pointer*/ ++ fclose(remfptr); ++ ++ /* got the remote data, now get the local */ ++localonly: ++/* TCP_INFO is defined in metrics.h*/ ++#if !defined TCP_INFO ++ if (local_no_poll_flag == 0) { ++ error("Local host does not support metric polling. Remote data only."); ++ local_no_poll_flag = 1; ++ } ++#else ++ /* open file handle for local data */ ++ localfptr = fopen(localfilename, "a"); ++ if(localfptr == NULL) ++ fatal("Error opening %s: %s", localfilename, strerror(errno)); ++ ++ /* create the binn object*/ ++ metricsobj = binn_object(); ++ if (metricsobj == NULL) { ++ fatal("Could not create metrics object"); ++ } ++ ++ tcpi_len = (size_t)sizeof(local_tcp_info); ++ if ((r = getsockopt(sock_in, IPPROTO_TCP, TCP_INFO, (void *)&local_tcp_info, ++ (socklen_t *)&tcpi_len)) != 0){ ++ error("Could not read tcp_info from socket"); ++ goto out; ++ } ++ ++ /* we write and read to a binn object because it lets us ++ * format the data consistently */ ++ metrics_write_binn_object(&local_tcp_info, metricsobj); ++ ++ /* create a string of the data from the binn object metricsobj */ ++ metrics_read_binn_object((void *)metricsobj, &metricsstring); ++ ++ /* get the kernel version printing the header */ ++ kernel_version = binn_object_int32(metricsobj, "kernel_version"); ++ ++ if (metrics_hdr_local_flag == 0) { ++ metrics_print_header(localfptr, "LOCAL CONNECTION", kernel_version); ++ metrics_hdr_local_flag = 1; ++ } ++ ++ fprintf(localfptr, "%s, ", timestamp); ++ fprintf(localfptr, "%s\n", metricsstring); ++ fclose (localfptr); ++#endif /* TCP_INFO */ ++out: ++ free(metricsstring); ++} ++ ++/* Use the SSH2_MSG_GLOBAL_REQUEST protocol to ++ * ask the server to send metrics back to the client. ++ * we use the non-canonical string stack-metrics@hpnssh.org ++ * to indicate the type of request we want. If the receiver doesn't ++ * understand it then the response indiactes a failure. ++ * I can probably do this by using clint_input_global_request but ++ * I need to understand that better. ++ */ ++void client_request_metrics(struct ssh *ssh) { ++ int r; ++ ++ debug_f("Asking server for TCP stack metrics"); ++ /* create a pakcet of GLOBAL_REQUEST type */ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || ++ /* define the type of GLOBAL_REQUEST message */ ++ (r = sshpkt_put_cstring(ssh, ++ "stack-metrics@hpnssh.org")) != 0 || ++ /* indicate if we want a response. 1 for yes 0 for no */ ++ (r = sshpkt_put_u8(ssh, 1)) != 0) ++ fatal_fr(r, "prepare stack request failure"); ++ /* send the packet */ ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal_fr(r, "send stack request"); ++ /* i believe this indicates what we are to use for a callback */ ++ client_register_global_confirm(client_process_request_metrics, NULL); ++} ++ + static int + client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) + { +@@ -2739,6 +2922,11 @@ + if ((c = channel_lookup(ssh, id)) == NULL) + fatal_f("channel %d: unknown channel", id); + ++ if (options.hpn_buffer_limit) { ++ debug_f("Limiting receive buffer size"); ++ c->hpn_buffer_limit = 1; ++ } ++ + ssh_packet_set_interactive(ssh, want_tty, + options.ip_qos_interactive, options.ip_qos_bulk); + +@@ -2809,6 +2997,43 @@ + + len = sshbuf_len(cmd); + if (len > 0) { ++ /* we may be connecting to a server that has hpn prefixed ++ * binaries installed. In that case we need to rewrite any ++ * scp commands to look for hpnscp instead. ++ */ ++ if (ssh->compat & SSH_HPNSSH_PREFIX) { ++ char *new_cmd; ++ new_cmd = malloc(len+4); ++ /* read the existing command into a temp buffer */ ++ sprintf(new_cmd, "%s", (const u_char*)sshbuf_ptr(cmd)); ++ const char *pos; ++ /* see if the command starts with scp */ ++ pos = strstr(new_cmd, "scp"); ++ /* by substracting the pointer new_cmd from the pointer ++ * pos we end up with the position of the needle in the ++ * haystack. If it's 0 then we can mess with it ++ */ ++ if (pos - new_cmd == 0) { ++ debug_f("Rewriting scp command for hpnscp."); ++ sprintf(new_cmd, "hpn%s", (const u_char*)sshbuf_ptr(cmd)); ++ debug_f("Command was: %s and is now %s", ++ (const u_char*)sshbuf_ptr(cmd), new_cmd); ++ /* free the existing sshbuf 'cmd' ++ * recreate it and then write our new_cmd into ++ * the sshbuf struct ++ */ ++ sshbuf_free(cmd); ++ if ((cmd = sshbuf_new()) == NULL) ++ fatal("sshbuf_new failed in scp rewrite"); ++ sshbuf_putf(cmd, "%s", new_cmd); ++ /* we use len later on so don't forget to ++ * increment it by the number of new chars in the ++ * command ++ */ ++ len += 3; ++ free(new_cmd); ++ } ++ } + if (len > 900) + len = 900; + if (want_subsystem) { +diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c +--- openssh-9.6p1.orig/compat.c 2024-07-10 13:32:39.574111737 +0200 ++++ openssh-9.6p1/compat.c 2024-07-10 13:34:02.716358582 +0200 +@@ -135,6 +135,36 @@ + ssh->compat = check[i].bugs; + if (forbid_ssh_rsa) + ssh->compat |= SSH_RH_RSASIGSHA; ++ /* Check to see if the remote side is OpenSSH and not HPN */ ++ /* TODO: See if we can work this into the new method for bug checks */ ++ if (strstr(version, "OpenSSH") != NULL) { ++ if (strstr(version, "hpn")) { ++ ssh->compat |= SSH_HPNSSH; ++ debug("Remote is HPN enabled"); ++ } ++ /* this checks to see if the remote ++ * version string indicates that we ++ * have access to hpn prefixed binaries ++ * You'll need to change this to include ++ * new major version numbers. Which is ++ * why we should figure out how to make ++ * the match pattern list work ++ */ ++ if ((strstr(version, "hpn16") != NULL) || ++ (strstr(version, "hpn17") != NULL) || ++ (strstr(version, "hpn18") != NULL)) { ++ ssh->compat |= SSH_HPNSSH_PREFIX; ++ debug("Remote uses HPNSSH prefixes."); ++ break; ++ } ++ /* if it's openssh and not hpn */ ++ if ((strstr(version, "OpenSSH_8.9") != NULL) || ++ (strstr(version, "OpenSSH_9") != NULL)) { ++ ssh->compat |= SSH_RESTRICT_WINDOW; ++ debug("Restricting adverstised window size."); ++ } ++ } ++ debug("ssh->compat is %u", ssh->compat); + return; + } + } +diff -Nur openssh-9.6p1.orig/compat.h openssh-9.6p1/compat.h +--- openssh-9.6p1.orig/compat.h 2024-07-10 13:32:39.574111737 +0200 ++++ openssh-9.6p1/compat.h 2024-07-10 13:34:02.716358582 +0200 +@@ -46,12 +46,12 @@ + /* #define unused 0x00010000 */ + /* #define unused 0x00020000 */ + /* #define unused 0x00040000 */ +-/* #define unused 0x00100000 */ ++#define SSH_HPNSSH 0x00100000 /* basically a notice that this is HPN aware */ + #define SSH_BUG_EXTEOF 0x00200000 + #define SSH_BUG_PROBE 0x00400000 +-/* #define unused 0x00800000 */ ++#define SSH_RESTRICT_WINDOW 0x00800000 /* restrict adverstised window to OpenSSH clients */ + #define SSH_OLD_FORWARD_ADDR 0x01000000 +-/* #define unused 0x02000000 */ ++#define SSH_HPNSSH_PREFIX 0x02000000 /* indicates that we have hpn prefixes binaries */ + #define SSH_NEW_OPENSSH 0x04000000 + #define SSH_BUG_DYNAMIC_RPORT 0x08000000 + #define SSH_BUG_CURVE25519PAD 0x10000000 +diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac +--- openssh-9.6p1.orig/configure.ac 2024-07-10 13:32:39.595111799 +0200 ++++ openssh-9.6p1/configure.ac 2024-07-10 13:34:02.718358588 +0200 +@@ -2909,8 +2909,8 @@ + 200*) # LibreSSL + lver=`echo "$sslver" | sed 's/.*libressl-//'` + case "$lver" in +- 2*|300*) # 2.x, 3.0.0 +- AC_MSG_ERROR([LibreSSL >= 3.1.0 required (have "$ssl_showver")]) ++ 2*|300*|301*|302*|303*|304*|306*) # 2.x, 3.0.0 ++ AC_MSG_ERROR([LibreSSL >= 3.7.0 required (have "$ssl_showver")]) + ;; + *) ;; # Assume all other versions are good. + esac +@@ -2918,10 +2918,12 @@ + 300*) + # OpenSSL 3; we use the 1.1x API + CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ++ AC_DEFINE([WITH_OPENSSL3], [1], [With OpenSSL3]) + ;; + 301*|302*|303*) + # OpenSSL development branch; request 1.1x API + CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ++ AC_DEFINE([WITH_OPENSSL3], [1], [With OpenSSL3]) + ;; + *) + AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_showver")]) +@@ -3039,6 +3041,30 @@ + EVP_CIPHER_CTX_set_iv \ + ]) + ++ # OpenSSL 3.0 API ++ # Does OpenSSL support the EVP_MAC functions for Poly1305? ++ AC_MSG_CHECKING([whether OpenSSL supports Poly1305 MAC EVP]) ++ AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM([[ ++ #include ++ #include ++ #include ++ ]], [[ ++ EVP_MAC *mac = EVP_MAC_fetch(NULL, "poly1305", NULL); ++ if (mac == NULL) ++ exit(1); ++ ]])], ++ [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE([OPENSSL_HAVE_POLY_EVP], [1], ++ [Libcrypto supports Poly1305 MAC EVP]) ++ ], ++ [ ++ AC_MSG_RESULT([no]) ++ ] ++ ) ++ ++ + if test "x$openssl_engine" = "xyes" ; then + AC_MSG_CHECKING([for OpenSSL ENGINE support]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +diff -Nur openssh-9.6p1.orig/defines.h openssh-9.6p1/defines.h +--- openssh-9.6p1.orig/defines.h 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/defines.h 2024-07-10 13:34:02.718358588 +0200 +@@ -889,7 +889,7 @@ + #endif + + #ifndef SSH_IOBUFSZ +-# define SSH_IOBUFSZ 8192 ++# define SSH_IOBUFSZ (32*1024) + #endif + + /* +diff -Nur openssh-9.6p1.orig/digest.h openssh-9.6p1/digest.h +--- openssh-9.6p1.orig/digest.h 2024-07-10 13:32:39.511111550 +0200 ++++ openssh-9.6p1/digest.h 2024-07-10 13:34:02.719358591 +0200 +@@ -27,7 +27,8 @@ + #define SSH_DIGEST_SHA256 2 + #define SSH_DIGEST_SHA384 3 + #define SSH_DIGEST_SHA512 4 +-#define SSH_DIGEST_MAX 5 ++#define SSH_DIGEST_NULL 5 ++#define SSH_DIGEST_MAX 6 + + struct sshbuf; + struct ssh_digest_ctx; +diff -Nur openssh-9.6p1.orig/digest-openssl.c openssh-9.6p1/digest-openssl.c +--- openssh-9.6p1.orig/digest-openssl.c 2024-07-10 13:32:39.511111550 +0200 ++++ openssh-9.6p1/digest-openssl.c 2024-07-10 13:34:02.719358591 +0200 +@@ -61,6 +61,7 @@ + { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, + { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, + { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, ++ { SSH_DIGEST_NULL, "NONEMAC", 0, EVP_md_null}, + { -1, NULL, 0, NULL }, + }; + +diff -Nur openssh-9.6p1.orig/FUNDING.yml openssh-9.6p1/FUNDING.yml +--- openssh-9.6p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/FUNDING.yml 2024-07-10 13:34:02.719358591 +0200 +@@ -0,0 +1,12 @@ ++# These are supported funding model platforms ++ ++github:rapier1 # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] ++#patreon: # Replace with a single Patreon username ++#open_collective: # Replace with a single Open Collective username ++#ko_fi: # Replace with a single Ko-fi username ++#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel ++#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry ++#liberapay: # Replace with a single Liberapay username ++#issuehunt: # Replace with a single IssueHunt username ++#otechie: # Replace with a single Otechie username ++#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +diff -Nur openssh-9.6p1.orig/HPN-README openssh-9.6p1/HPN-README +--- openssh-9.6p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/HPN-README 2024-07-10 13:34:02.719358591 +0200 +@@ -0,0 +1,170 @@ ++Notes: ++ ++LibreSSL Support: ++Changes in LibreSSL version 3.5 and 3.6 prevent the use of the threaded AES CTR cipher. ++In those cases HPNSSH will fallback to the serial version of the AES CTR cipher. A warning ++is printed to stderr. ++ ++Automatic Port Fallback (in version 17v3) ++The hpnssh client now uses TCP port 2222 to connect automatically as this is the ++default hpnsshd port. However, we understand that many users will be end up connecting ++standard SSH servers on port 22. To make the easier for users the client will fall back to ++port 22 in the event that there is no hpnssh server running on port 2222. The behaviour can ++be modifed as follows: ++-oFallback=[yes|no] will enable or disable port fallback. Default is yes. ++-oFallbackPort=[N] where N is the port number that should be used for fall back. ++ Default is 22. ++ ++TCP_INFO Metrics ++This features allows the client to request tcp networking information from the ++TCP_INFO struct. This includes data on retransmits, round trip time, lost packets, ++data transferred, and the like. The metrics are polled periodically through the ++life of the connection. By default this is every 5 seconds but users can pick different ++polling periods. The resulting data is stored in two distinct files; one for local ++metrics and one for remote metrics. Remote metrics are only available if the remote ++supports this feature. This feature will *not* diagnose a poorly performing connection ++but may provide insight into what is happening during the connection. ++ ++Usage: ++-oMetrics=[yes|no] will enable metrics polling. Default: No. ++-oMetricsInterval=[N] where N is the polling period in seconds. Default: 5 seconds. ++-oMetricsPath=[/filepath/filename] is the name of the file where the remote and ++ local data will be stored. Default: ./ssh_stack_metrics.[local|remote]. ++ Any other option chosen by the user will have a .local or .remote suffix appended to it. ++ ++The number of instruments polled by this features is dependent on the kernel of the host. ++This means that a remote host with an older kernel may report fewer instruments than a client ++host running a current kernel or vice versa. If there is a discrepency in the number of instruments ++in the ssh_stack_metrics.local and .remote file this is the most likely reason. ++ ++Additionally, determining which file represents sender side versus receiver side is dependent ++on the nature of the connection. Therfore, it's up to the user to make that determination. ++ ++Linux Note: Currently this is only supported on Linux kernel versions 3.7 and greater. Newer kernels ++may have more instruments available to poll than older kernels. ++ ++FreeBSD Note: This is supported on Release 6 and higher. However, FreeBSD has fewer available ++instruments than new Linux kernels. ++ ++Multiplexing Note: The metrics are reported from the TCP socket which means that gathering ++metrics from multiplexed sessions will report on the activity of all sessions on that socket. ++This will likely result in less clear results and, as such, we suggest only gathering metrics ++from non-multiplexed session. ++ ++HPNSCP with Resume functionality ++This feature allows hpnscp to resume failed transfers. In the event of a failed transfer ++issues the same scp command with the '-R' option. For example - if you issued: ++'hpnscp myhugefile me@host:~' ++and it dies halfway through the transfer issuing ++'hpnscp -Z myhugefile me@host:~' ++will resume the transfer at the point where it left off. ++ ++This is implemented by having the source host send a hash (blake2b512) of the file to the ++target host. The target host then computes it's own hash of the target file. If the hashes match ++then the file is skipped as this indicates a successful transfer. However, if the hashes do not ++match then the target sends the source its hash along with the size of the file. The source then ++computes the hash of the file *up to* the size of the target file. If those hashes match then ++the source only send the necessary bytes to complete the transfer. If the hashes do not match then ++the entire file is resent. If the target file is larger then the source file then the entire ++source file is sent and any existing target file is overwritten. ++ ++ ++MULTI-THREADED AES CIPHER: ++The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations ++on hosts with multiple cores to use more than one processing core during encryption. ++Tests have show significant throughput performance increases when using MTR-AES-CTR up ++to and including a full gigabit per second on quad core systems. It should be possible to ++achieve full line rate on dual core systems but OS and data management overhead makes this ++more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single ++thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal ++performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. ++The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same ++nomenclature. ++Usage examples: ++ ssh -caes128-ctr you@host.com ++ scp -oCipher=aes256-ctr file you@host.com:~/file ++ ++MULTI-THREADED ChaCha20-Poly1305 CIPHER: ++The default cipher used by HPN-SSH is now a threaded implementation of the ++ChaCha20-Poly1305 cipher. In tests this cipher results in an approximately 90% gain in ++throughput performance in comparison to the serial implementation found in OpenSSH. ++This cipher is fully compatible with all known existing implementations of ChaCha20-Poly1305. ++ ++Internally this cipher is referred to as chacha20-poly1305-mt@hpnssh.org (CC20-MT) ++similar to how the OpenSSH implementation is known as chacha20-poly1305@openssh.com ++(CC20-S (for serial)). No changes are required on the part of the user to make use of CC20-MT. ++However, if the users doesn't want to make use of this cipher they can explicitly load CC20-S using ++'-cchach20-poly1305@openssh.com` on the command line. ++ ++NONE CIPHER: ++To use the NONE option you must have the NoneEnabled switch set on the server and ++you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE ++feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not ++spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will ++be disabled. ++ ++The performance increase will only be as good as the network and TCP stack tuning ++on the reciever side of the connection allows. As a rule of thumb a user will need ++at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The ++HPN-SSH home page describes this in greater detail. ++ ++http://www.psc.edu/networking/projects/hpn-ssh ++ ++NONE MAC: ++Starting with HPN 15v1 users will have the option to disable HMAC (message ++authentication ciphers) when using the NONE cipher. You must enable the following: ++NoneEnabled, NoneSwitch, and NoneMacEnabled. If all three are not enabled the None MAC ++will be automatically disabled. In tests the use of the None MAC improved throuput by ++more than 30%. ++ ++ex: scp -oNoneSwitch=yes -oNoneEnabled=yes -oNoneMacEnabled=yes file host:~ ++ ++HPN Specific Configuration options ++ ++TcpRcvBufPoll=[yes/no] client/server ++ Enable of disable the polling of the tcp receive buffer through the life ++of the connection. You would want to make sure that this option is enabled ++for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) ++default is yes. ++ ++NoneEnabled=[yes/no] client/server ++ Enable or disable the use of the None cipher. Care must always be used ++when enabling this as it will allow users to send data in the clear. However, ++it is important to note that authentication information remains encrypted ++even if this option is enabled. Set to no by default. ++ ++NoneMacEnabled=[yes/no] client/server ++ Enable or disable the use of the None MAC. When this is enabled ssh ++will *not* provide data integrity of any data being transmitted between hosts. Use ++with caution as it, unlike just using NoneEnabled, doesn't provide data integrity and ++protection against man-in-the-middle attacks. As with NoneEnabled all authentication ++remains encrypted and integrity is ensured. Default is no. ++ ++NoneSwitch=[yes/no] client ++ Switch the encryption cipher being used to the None cipher after ++authentication takes place. NoneEnabled must be enabled on both the client ++and server side of the connection. When the connection switches to the NONE ++cipher a warning is sent to STDERR. The connection attempt will fail with an ++error if a client requests a NoneSwitch from the server that does not explicitly ++have NoneEnabled set to yes. Note: The NONE cipher cannot be used in ++interactive (shell) sessions and it will fail silently. Set to no by default. ++ ++HPNDisabled=[yes/no] client/server ++ In some situations, such as transfers on a local area network, the impact ++of the HPN code produces a net decrease in performance. In these cases it is ++helpful to disable the HPN functionality. By default HPNDisabled is set to no. ++ ++Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu) ++ The majority of the actual coding for versions up to HPN12v1 was performed ++ by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was ++ implemented by Ben Bennet (ben@psc.edu) and improved by Mike Tasota ++ (tasota@gmail.com) an NSF REU grant recipient for 2013. ++ Allan Jude provided the code for the NoneMac and buffer normalization. ++ This work was financed, in part, by Cisco System, Inc., the National ++ Library of Medicine, and the National Science Foundation. ++ ++Sponsors: Thanks to Niklas Hambuchen for being the first sponsor of HPN-SSH ++ via github's sponsor program! ++ ++ ++Edited: October 11, 2023 +diff -Nur openssh-9.6p1.orig/HPNSSHInstallation.txt openssh-9.6p1/HPNSSHInstallation.txt +--- openssh-9.6p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/HPNSSHInstallation.txt 2024-07-10 13:34:02.720358594 +0200 +@@ -0,0 +1,354 @@ ++HPN-SSH Installation ++ ++The process of installing HPN-SSH from source is a relatively painless process ++but does have some nuances. This document will go through the process step by ++step to help you get the most from your installation. If you find any errors ++please contact us at hpnssh@psc.edu. ++ ++ ++Step 1: Get the source code. ++ ++The official repository for HPN-SSH is found at ++https://github.com/rapier1/hpn-ssh. Get a copy with ++"git clone https://github.com/rapier1/hpn-ssh”. ++ ++ ++Step 2: Install dependencies. ++ ++What you need to install is dependent on your distribution but will include: ++* OpenSSL development package ++ * Debian: libssl-dev ++ * Fedora: openssl-devel ++* Alternatively you can use LIbreSSL ++ * However, in this case we suggest compiling and installing libressl manually as ++ there are few maintained linux packages for LibreSSL. ++ * Also, LibreSSL v3.5 and v3.6 do not support the threaded AES-CTR cipher. ++ If that’s important to you then you should use OpenSSL. ++* Z compression library ++ * Debian: zlib1g-dev ++ * Fedora: zlib-devel ++* Autoconf ++* Automake ++ ++ ++Step 3: Install optional dependencies. ++ ++This optional libraries will extend the functionality of HPN-SSH to allow the use of PAM ++authentication, Kerberos, graphical password tools, etc. ++* PAM ++* Kerberos ++* GTK ++ ++ ++Step 4: Build the configure file ++ ++generate ./configure with “autoreconf -f -i” ++ ++ ++Step 5: Configuration ++ ++Configure the installation. You can get detailed information on how to do this by ++issuing “./configure --help”. However, commonly you will want to change the default installation ++location of the binaries. This can be done with “--prefix=/[desired_path]”. For example, ++if you want the binaries installed into /usr/bin as opposed to the default of ++/usr/local/bin you’d use “./configure --prefix=/usr”. Other common options would be to ++incorporate pam, kerberos, alternative SSL libraries, and so forth. However, for most users ++either no additional configuration options or modifying the prefix will suffice. ++ ++ ++Step 6: Make ++ ++Make the application with “make -j[num cores]”. So if you have an 8 core system ++you’d use “make -j8” ++ ++ ++Step 7: Set up the hpnsshd user. ++ ++This user is part of the privilege separation routines used in the ++pre-authentication sandbox. I suggest using the following command: ++ ++sudo useradd --system --shell /usr/sbin/nologin --comment="Privilege separated HPNSSH User" \ ++--home=/run/hpnsshd hpnsshd ++ ++Alternatively, you can use vipw to add the user manually. ++ ++ ++Step 8: Installation ++ ++After HPN-SSH successfully builds, install it with “sudo make install”. This will install the ++binaries, configuration files, and generate the unique host keys used. At this point you can ++make changes to the ssh client and server default configuration. These files are ++found, generally, in /etc/hpnssh/ssh_config and sshd_config respectively. You may want to ++change the default port from 2222 to some other value. You may also want to enable the ++NoneCipher and NoneMac options. For more information use “man hpnsshd_config” and ++“man hpnssh_config”. Note: The hpnssh client expects the server to be on port 2222 but will ++fallback to 22 if it’s not found there. So if you do change the default port you’ll need to ++make sure the clients point at the correct port. ++ ++Step 9: Finishing up. ++ ++At this point you can start hpnsshd manually by running “sudo /usr/sbin/hpnsshd” ++or whatever the full path to the hpnsshd binary might be. However, this won’t ++restart automatically on reboot. To do this you’ll need to install an appropriate ++systemd configuration file. If that seems like a good idea to you then following steps may be ++of help. Otherwise, you are done. Enjoy! ++ ++ ++Step 10: Installing a systemd startup file. ++ ++The correct systemd startup file depends on the distribution you are using. For system ++using systemd (you start a service with systemctl) create a file at /lib/systemd/system/hpnsshd.service ++with the following contents NB: you may need to update the paths to match your installation: ++ ++[Unit] ++Description=HPN/OpenBSD Secure Shell server ++Documentation=man:hpnsshd(8) man:hpnsshd_config(5) ++After=network.target auditd.service ++ConditionPathExists=!/etc/hpnssh/sshd_not_to_be_run ++ ++[Service] ++EnvironmentFile=-/etc/default/hpnssh ++ExecStartPre=/usr/sbin/hpnsshd -t ++ExecStart=/usr/sbin/hpnsshd -D $SSHD_OPTS ++ExecReload=/usr/sbin/hpnsshd -t ++ExecReload=/bin/kill -HUP $MAINPID ++KillMode=process ++Restart=on-failure ++RestartPreventExitStatus=255 ++Type=notify ++RuntimeDirectory=hpnsshd ++RuntimeDirectoryMode=0755 ++ ++[Install] ++WantedBy=multi-user.target ++Alias=hpnsshd.service ++ ++Alternatively, the ./configure command will generate a hpnsshd.service file from ++hpnsshd.service.in. You can use this file by copying it to ++/libsystemd/system/hpnsshd.service instead of copying the above text. ++ ++Then create the defaults file at /etc/defaults/hpnsshd with the following content: ++# Default settings for openssh-server. ++# Options to pass to sshd ++SSHD_OPTS= ++ ++Enter any runtime options you want on the SSHD_OPTS line. If you can’t think of any, simply ++leave it blank. A sample /etc/defauls/hpnssh file may be found in defaults.hpnsshd. ++ ++You must then reload the systemd service to make it aware of this new service with ++sudo systemctl daemon-reload ++ ++If you are using an init.d (you start a service with ‘system’) then you need to install an ++init.d. Create the file /etc/init.d/hpnssh and copy the following into it. NB: The following is ++for where hpnsshd is found at /usr/sbin/hpnsshd. If it is not in that location you’ll need to ++update the paths. ++ ++Alternatively, you may use the hpnsshd.init file created during configure. This will be ++prepopulated with the correct paths by the configure script. ++ ++#! /bin/sh ++ ++### BEGIN INIT INFO ++# Provides: hpnsshd ++# Required-Start: $remote_fs $syslog ++# Required-Stop: $remote_fs $syslog ++# Default-Start: 2 3 4 5 ++# Default-Stop: ++# Short-Description: OpenBSD Secure Shell server with HPN ++### END INIT INFO ++ ++set -e ++ ++# /etc/init.d/hpnssh: start and stop the OpenBSD "secure shell(tm)" daemon ++ ++test -x /usr/sbin/hpnsshd || exit 0 ++( /usr/sbin/hpnsshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0 ++ ++umask 022 ++ ++if test -f /etc/default/hpnssh; then ++ . /etc/default/hpnssh ++fi ++ ++. /lib/lsb/init-functions ++ ++ ++if [ -n "$2" ]; then ++ SSHD_OPTS="$SSHD_OPTS $2" ++fi ++ ++# Are we running from init? ++run_by_init() { ++ ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ] ++} ++ ++check_for_no_start() { ++ # forget it if we're trying to start, and /etc/hpnssh/sshd_not_to_be_run exists ++ if [ -e /etc/hpnssh/sshd_not_to_be_run ]; then ++ if [ "$1" = log_end_msg ]; then ++ log_end_msg 0 || true ++ fi ++ if ! run_by_init; then ++ log_action_msg "HPN/OpenBSD Secure Shell server not in use (/etc/hpnssh/sshd_not_to_be_run)" || true ++ fi ++ exit 0 ++ fi ++} ++ ++check_dev_null() { ++ if [ ! -c /dev/null ]; then ++ if [ "$1" = log_end_msg ]; then ++ log_end_msg 1 || true ++ fi ++ if ! run_by_init; then ++ log_action_msg "/dev/null is not a character device!" || true ++ fi ++ exit 1 ++ fi ++} ++ ++check_privsep_dir() { ++ # Create the PrivSep empty dir if necessary ++ if [ ! -d /run/hpnsshd ]; then ++ mkdir /run/hpnsshd ++ chmod 0755 /run/hpnsshd ++ fi ++} ++ ++check_config() { ++ if [ ! -e /etc/hpnssh/sshd_not_to_be_run ]; then ++ # shellcheck disable=SC2086 ++ /usr/sbin/hpnsshd $SSHD_OPTS -t || exit 1 ++ fi ++} ++ ++export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" ++ ++case "$1" in ++ start) ++ check_privsep_dir ++ check_for_no_start ++ check_dev_null ++ log_daemon_msg "Starting HPN/OpenBSD Secure Shell server" "hpnsshd" || true ++ # shellcheck disable=SC2086 ++ if start-stop-daemon --start --quiet --oknodo --chuid 0:0 --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd -- $SSHD_OPTS; then ++ log_end_msg 0 || true ++ else ++ log_end_msg 1 || true ++ fi ++ ;; ++ stop) ++ log_daemon_msg "Stopping HPN/OpenBSD Secure Shell server" "hpnsshd" || true ++ if start-stop-daemon --stop --quiet --oknodo --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd; then ++ log_end_msg 0 || true ++ else ++ log_end_msg 1 || true ++ fi ++ ;; ++ ++ ++ reload|force-reload) ++ check_for_no_start ++ check_config ++ log_daemon_msg "Reloading HPN/OpenBSD Secure Shell server's configuration" "hpnsshd" || true ++ if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd; then ++ log_end_msg 0 || true ++ else ++ log_end_msg 1 || true ++ fi ++ ;; ++ ++ ++ restart) ++ check_privsep_dir ++ check_config ++ log_daemon_msg "Restarting HPN/OpenBSD Secure Shell server" "hpnsshd" || true ++ start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd ++ check_for_no_start log_end_msg ++ check_dev_null log_end_msg ++ # shellcheck disable=SC2086 ++ if start-stop-daemon --start --quiet --oknodo --chuid 0:0 --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd -- $SSHD_OPTS; then ++ log_end_msg 0 || true ++ else ++ log_end_msg 1 || true ++ fi ++ ;; ++ ++ ++ try-restart) ++ check_privsep_dir ++ check_config ++ log_daemon_msg "Restarting HPN/OpenBSD Secure Shell server" "hpnsshd" || true ++ RET=0 ++ start-stop-daemon --stop --quiet --retry 30 --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd || RET="$?" ++ case $RET in ++ 0) ++ # old daemon stopped ++ check_for_no_start log_end_msg ++ check_dev_null log_end_msg ++ # shellcheck disable=SC2086 ++ if start-stop-daemon --start --quiet --oknodo --chuid 0:0 --pidfile /run/hpnsshd.pid --exec /usr/sbin/hpnsshd -- $SSHD_OPTS; then ++ log_end_msg 0 || true ++ else ++ log_end_msg 1 || true ++ fi ++ ;; ++ 1) ++ # daemon not running ++ log_progress_msg "(not running)" || true ++ log_end_msg 0 || true ++ ;; ++ *) ++ # failed to stop ++ log_progress_msg "(failed to stop)" || true ++ log_end_msg 1 || true ++ ;; ++ esac ++ ;; ++ ++ ++ status) ++ status_of_proc -p /run/hpnsshd.pid /usr/sbin/hpnsshd hpnsshd && exit 0 || exit $? ++ ;; ++ ++ ++ *) ++ log_action_msg "Usage: /etc/init.d/hpnssh {start|stop|reload|force-reload|restart|try-restart|status}" || true ++ exit 1 ++esac ++ ++exit 0 ++ ++ ++Step 10: Working with SELinux. ++ ++If you are using SELinux you’ll need to run a few more commands in order to grant hpnssh the ++necessary exceptions to open sockets, files, read keys, and so forth. Run the following commands ++to allow this. Note, I’m not sure every single one of these is needed so if someone knows better ++please let me know. Again, double check the paths of the files being updated. ++ ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_dsa_key ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_rsa_key ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_ecdsa_key ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_ed25519_key ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_dsa_key.pub ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_rsa_key.pub ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_ecdsa_key.pub ++semanage fcontext -a -f f -t sshd_key_t /etc/hpnssh/ssh_host_ed25519_key.pub ++semanage fcontext -a -f f -t sshd_exec_t /usr/sbin/hpnsshd ++semanage fcontext -a -f f -t sshd_keygen_exec_t /usr/libexec/hpnssh/hpnsshd-keygen ++semanage fcontext -a -f f -t bin_t /usr/libexec/hpnssh/hpnsftp-server ++semanage fcontext -a -f f -t ssh_exec_t /usr/bin/hpnssh ++semanage fcontext -a -f f -t ssh_agent_exec_t /usr/bin/hpnssh-agent ++semanage fcontext -a -f f -t ssh_keygen_exec_t /usr/bin/hpnssh-keygen ++semanage fcontext -a -f f -t etc_t /etc/pam.d/hpnsshd ++semanage port -a -t ssh_port_t -p tcp 2222 ++restorecon /usr/sbin/hpnsshd ++restorecon /etc/hpnssh/ssh*_key ++restorecon /etc/hpnssh/ssh*_key\.pub ++restorecon /usr/libexec/hpnssh/hpnsshd-keygen ++restorecon /usr/libexec/hpnssh/hpnsftp-server ++restorecon /usr/bin/hpnssh ++restorecon /usr/bin/hpnssh-agent ++restorecon /usr/bin/hpnssh-keygen ++restorecon /etc/pam.d/hpnsshd +diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c +--- openssh-9.6p1.orig/kex.c 2024-07-10 13:32:39.570111725 +0200 ++++ openssh-9.6p1/kex.c 2024-07-10 13:34:02.720358594 +0200 +@@ -65,6 +65,7 @@ + + #include "ssherr.h" + #include "sshbuf.h" ++#include "canohost.h" + #include "digest.h" + #include "xmalloc.h" + #include "audit.h" +@@ -1037,11 +1038,68 @@ + free(kex); + } + ++/* ++ * This function seeks through a comma-separated list and checks for instances ++ * of the multithreaded CC20 cipher. If found, it then ensures that the serial ++ * CC20 cipher is also in the list, adding it if necessary. ++ */ ++char * ++patch_list(char * orig) ++{ ++ char * adj = xstrdup(orig); ++ char * match; ++ u_int next; ++ ++ const char * ccpstr = "chacha20-poly1305@openssh.com"; ++ const char * ccpmtstr = "chacha20-poly1305-mt@hpnssh.org"; ++ ++ match = match_list(ccpmtstr, orig, &next); ++ if (match != NULL) { /* CC20-MT found in the list */ ++ free(match); ++ match = match_list(ccpstr, orig, NULL); ++ if (match == NULL) { /* CC20-Serial NOT found in the list */ ++ adj = xreallocarray(adj, ++ strlen(adj) /* original string length */ ++ + 1 /* for the original null-terminator */ ++ + strlen(ccpstr) /* make room for ccpstr */ ++ + 1 /* make room for the comma delimiter */ ++ , sizeof(char)); ++ /* ++ * adj[next] points to the character after the CC20-MT ++ * string. adj[next] might be ',' or '\0' at this point. ++ */ ++ adj[next] = ','; ++ /* adj + next + 1 is the character after that comma */ ++ memcpy(adj + next + 1, ccpstr, strlen(ccpstr)); ++ /* rewrite the rest of the original list */ ++ memcpy(adj + next + 1 + strlen(ccpstr), orig + next, ++ strlen(orig + next) + 1); ++ } else { /* CC20-Serial found in the list, nothing to do */ ++ free(match); ++ } ++ } ++ ++ return adj; ++} ++ + int + kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) + { + int r; + ++#ifdef WITH_OPENSSL ++ proposal[PROPOSAL_ENC_ALGS_CTOS] = ++ patch_list(proposal[PROPOSAL_ENC_ALGS_CTOS]); ++ proposal[PROPOSAL_ENC_ALGS_STOC] = ++ patch_list(proposal[PROPOSAL_ENC_ALGS_STOC]); ++ ++ /* ++ * TODO: Likely memory leak here. The original contents of ++ * proposal[PROPOSAL_ENC_ALGS_CTOS] are no longer accessible or ++ * freeable. ++ */ ++#endif ++ + if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0) + return r; + ssh->kex->flags = KEX_INITIAL; +@@ -1240,6 +1298,11 @@ + int nenc, nmac, ncomp; + u_int mode, ctos, need, dh_need, authlen; + int r, first_kex_follows; ++ int auth_flag = 0; ++ int log_flag = 0; ++ ++ auth_flag = packet_authentication_state(ssh); ++ debug("AUTH STATE IS %d", auth_flag); + + debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); + if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) +@@ -1316,6 +1379,31 @@ + peer[nenc] = NULL; + goto out; + } ++#ifdef WITH_OPENSSL ++ if ((strcmp(newkeys->enc.name, "chacha20-poly1305@openssh.com") ++ == 0) && (match_list("chacha20-poly1305-mt@hpnssh.org", ++ my[nenc], NULL) != NULL)) { ++ /* ++ * if we're using the serial CC20 cipher while the ++ * multithreaded implementation is an option... ++ */ ++ free(newkeys->enc.name); ++ newkeys->enc.cipher = cipher_by_name( ++ "chacha20-poly1305-mt@hpnssh.org"); ++ if (newkeys->enc.cipher == NULL) { ++ error_f("%s cipher not found.", ++ "chacha20-poly1305-mt@hpnssh.org"); ++ r = SSH_ERR_INTERNAL_ERROR; ++ kex->failed_choice = peer[nenc]; ++ peer[nenc] = NULL; ++ goto out; ++ } else { ++ newkeys->enc.name = xstrdup( ++ "chacha20-poly1305-mt@hpnssh.org"); ++ } ++ /* we promote to the multithreaded implementation */ ++ } ++#endif + authlen = cipher_authlen(newkeys->enc.cipher); + /* ignore mac for authenticated encryption */ + if (authlen == 0 && +@@ -1331,11 +1419,43 @@ + peer[ncomp] = NULL; + goto out; + } ++ debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); ++ debug("REQUESTED MAC.NAME is '%s'", newkeys->mac.name); ++ if (strcmp(newkeys->enc.name, "none") == 0) { ++ if (auth_flag == 1) { ++ debug("None requested post authentication."); ++ ssh->none = 1; ++ } ++ else ++ fatal("Pre-authentication none cipher requests are not allowed."); ++ ++ if (newkeys->mac.name != NULL && strcmp(newkeys->mac.name, "none") == 0) { ++ debug("Requesting: NONEMAC. Authflag is %d", auth_flag); ++ ssh->none_mac = 1; ++ } ++ } ++ + debug("kex: %s cipher: %s MAC: %s compression: %s", + ctos ? "client->server" : "server->client", + newkeys->enc.name, + authlen == 0 ? newkeys->mac.name : "", + newkeys->comp.name); ++ /* ++ * client starts with ctos = 0 && log flag = 0 and no log. ++ * 2nd client pass ctos = 1 and flag = 1 so no log. ++ * server starts with ctos = 1 && log_flag = 0 so log. ++ * 2nd sever pass ctos = 1 && log flag = 1 so no log. ++ * -cjr ++ */ ++ if (ctos && !log_flag) { ++ logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s", ++ ssh_remote_ipaddr(ssh), ++ ssh_remote_port(ssh), ++ newkeys->enc.name, ++ authlen == 0 ? newkeys->mac.name : "", ++ newkeys->comp.name); ++ } ++ log_flag = 1; + } + need = dh_need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { +@@ -1683,7 +1803,7 @@ + if (version_addendum != NULL && *version_addendum == '\0') + version_addendum = NULL; + if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", +- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, + version_addendum == NULL ? "" : " ", + version_addendum == NULL ? "" : version_addendum)) != 0) { + oerrno = errno; +@@ -1819,9 +1939,24 @@ + r = SSH_ERR_INVALID_FORMAT; + goto out; + } ++ ++ /* report the version information to syslog if this is the server */ ++ if (timeout_ms == -1) { /* only the server uses this value */ ++ logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ++ remote_major, remote_minor, remote_version); ++ } ++ + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + compat_banner(ssh, remote_version); ++ if (ssh->compat & SSH_HPNSSH) ++ debug("HPN to HPN Connection."); ++ else ++ debug("Non-HPN to HPN Connection."); ++ ++ if(ssh->compat & SSH_RESTRICT_WINDOW) ++ debug ("Window size restricted."); + + mismatch = 0; + switch (remote_major) { +diff -Nur openssh-9.6p1.orig/mac.c openssh-9.6p1/mac.c +--- openssh-9.6p1.orig/mac.c 2024-07-10 13:32:39.542111642 +0200 ++++ openssh-9.6p1/mac.c 2024-07-10 13:34:02.720358594 +0200 +@@ -63,6 +63,7 @@ + { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, + { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, + { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, ++ { "none", SSH_DIGEST, SSH_DIGEST_NULL, 0, 0, 0, 0 }, + { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, + { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, + +diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in +--- openssh-9.6p1.orig/Makefile.in 2024-07-10 13:32:39.597111805 +0200 ++++ openssh-9.6p1/Makefile.in 2024-07-10 13:34:02.721358597 +0200 +@@ -49,7 +49,7 @@ + CFLAGS_NOPIE=@CFLAGS_NOPIE@ + CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ + PICFLAG=@PICFLAG@ +-LIBS=@LIBS@ ++LIBS=@LIBS@ -lpthread + CHANNELLIBS=@CHANNELLIBS@ + K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ +@@ -97,7 +97,7 @@ + LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + authfd.o authfile.o \ + canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ +- cleanup.o \ ++ cleanup.o cipher-ctr-mt.o \ + compat.o fatal.o hostfile.o \ + log.o match.o moduli.o nchan.o packet.o \ + readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ +@@ -107,6 +107,7 @@ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ + ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ++ cipher-chachapoly-libcrypto-mt.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o ed25519.o hash.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +@@ -114,12 +115,13 @@ + kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ +- sshbuf-io.o auditstub.o ++ sshbuf-io.o auditstub.o metrics.o binn.o cipher-ctr-mt-provider.o \ ++ cipher-ctr-mt-functions.o ossl3-provider-err.o num.o + + SKOBJS= ssh-sk-client.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ +- sshconnect.o sshconnect2.o mux.o $(SKOBJS) ++ sshconnect.o sshconnect2.o mux.o cipher-switch.o $(SKOBJS) + + SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ +@@ -135,7 +137,7 @@ + srclimit.o sftp-server.o sftp-common.o \ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ +- sandbox-solaris.o uidswap.o $(SKOBJS) ++ sandbox-solaris.o uidswap.o cipher-switch.o $(SKOBJS) + + SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o + +@@ -214,7 +216,7 @@ + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) + + scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) +- $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) + + ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) + $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) +diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c +--- openssh-9.6p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/metrics.c 2024-07-10 13:34:02.721358597 +0200 +@@ -0,0 +1,444 @@ ++/* ++ * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++#include "includes.h" ++#include "metrics.h" ++#include "ssherr.h" ++#include ++#include ++#if defined(__linux__) && !defined(__alpine__) ++#include ++#endif ++ ++#ifndef KERNEL_VERSION /* shouldn't be necessary to define this */ ++#define KERNEL_VERSION(a,b,c) (((a) <<16) + ((b) << 8) +(c)) ++#endif ++ ++/* add the information from the tcp_info struct to the ++ * serialized binary object ++ */ ++void ++metrics_write_binn_object(struct tcp_info *data, struct binn_struct *binnobj) { ++#if !defined TCP_INFO ++ /*tcp info isn't supported on this system */ ++ return; ++#else ++ ++/* the base set of tcpi_ measurements starting from kernel 3.7.0 ++ * these measurements existed in previous kernels but the oldest this ++ * is going to support is 3.7.0. We do need to store the kernel version as well */ ++ ++/* obvioulsy the version code macro only exists under linux so ++ * on non linux systems we set the kernel version to 0 ++ * which will get us the base set of metrics from netinet/tcp.h ++ */ ++#if (defined __linux__) && !defined(__alpine__) ++ binn_object_set_uint32(binnobj, "kernel_version", LINUX_VERSION_CODE); ++#else ++ binn_object_set_uint32(binnobj, "kernel_version", 0); ++#endif ++ ++ /* the following are common under both linux and BSD */ ++ binn_object_set_uint8(binnobj, "tcpi_snd_wscale", ++ data->tcpi_snd_wscale); ++ binn_object_set_uint8(binnobj, "tcpi_rcv_wscale", ++ data->tcpi_rcv_wscale); ++ binn_object_set_uint8(binnobj, "tcpi_state", ++ data->tcpi_state); ++ binn_object_set_uint8(binnobj, "tcpi_options", ++ data->tcpi_options); ++ binn_object_set_uint32(binnobj, "tcpi_snd_ssthresh", ++ data->tcpi_snd_ssthresh); ++ binn_object_set_uint32(binnobj, "tcpi_rtt", ++ data->tcpi_rtt); ++ binn_object_set_uint32(binnobj, "tcpi_last_data_recv", ++ data->tcpi_last_data_recv); ++ binn_object_set_uint32(binnobj, "tcpi_rttvar", ++ data->tcpi_rttvar); ++ binn_object_set_uint32(binnobj, "tcpi_snd_cwnd", ++ data->tcpi_snd_cwnd); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_mss", ++ data->tcpi_rcv_mss); ++ binn_object_set_uint32(binnobj, "tcpi_rto", ++ data->tcpi_rto); ++ binn_object_set_uint32(binnobj, "tcpi_snd_mss", ++ data->tcpi_snd_mss); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_space", ++ data->tcpi_rcv_space); ++ ++/* the following exist under both but with different names */ ++#ifdef __linux__ ++ binn_object_set_uint8(binnobj, "tcpi_ca_state", ++ data->tcpi_ca_state); ++ binn_object_set_uint8(binnobj, "tcpi_probes", ++ data->tcpi_probes); ++ binn_object_set_uint8(binnobj, "tcpi_backoff", ++ data->tcpi_backoff); ++ binn_object_set_uint8(binnobj, "tcpi_retransmits", ++ data->tcpi_retransmits); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_ssthresh", ++ data->tcpi_rcv_ssthresh); ++ binn_object_set_uint32(binnobj, "tcpi_sacked", ++ data->tcpi_sacked); ++ binn_object_set_uint32(binnobj, "tcpi_pmtu", ++ data->tcpi_pmtu); ++ binn_object_set_uint32(binnobj, "tcpi_fackets", ++ data->tcpi_fackets); ++ binn_object_set_uint32(binnobj, "tcpi_lost", ++ data->tcpi_lost); ++ binn_object_set_uint32(binnobj, "tcpi_last_ack_sent", ++ data->tcpi_last_ack_sent); ++ binn_object_set_uint32(binnobj, "tcpi_unacked", ++ data->tcpi_unacked); ++ binn_object_set_uint32(binnobj, "tcpi_last_data_sent", ++ data->tcpi_last_data_sent); ++ binn_object_set_uint32(binnobj, "tcpi_last_ack_recv", ++ data->tcpi_last_ack_recv); ++ binn_object_set_uint32(binnobj, "tcpi_reordering", ++ data->tcpi_reordering); ++ binn_object_set_uint32(binnobj, "tcpi_advmss", ++ data->tcpi_advmss); ++ binn_object_set_uint32(binnobj, "tcpi_retrans", ++ data->tcpi_retrans); ++ binn_object_set_uint32(binnobj, "tcpi_ato", ++ data->tcpi_ato); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_rtt", ++ data->tcpi_rcv_rtt); ++#else ++ binn_object_set_uint8(binnobj, "tcpi_backoff", ++ data->__tcpi_backoff); ++ binn_object_set_uint8(binnobj, "tcpi_ca_state", ++ data->__tcpi_ca_state); ++ binn_object_set_uint8(binnobj, "tcpi_probes", ++ data->__tcpi_probes); ++ binn_object_set_uint8(binnobj, "tcpi_retransmits", ++ data->__tcpi_retransmits); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_ssthresh", ++ data->__tcpi_rcv_ssthresh); ++ binn_object_set_uint32(binnobj, "tcpi_sacked", ++ data->__tcpi_sacked); ++ binn_object_set_uint32(binnobj, "tcpi_pmtu", ++ data->__tcpi_pmtu); ++ binn_object_set_uint32(binnobj, "tcpi_fackets", ++ data->__tcpi_fackets); ++ binn_object_set_uint32(binnobj, "tcpi_lost", ++ data->__tcpi_lost); ++ binn_object_set_uint32(binnobj, "tcpi_last_ack_sent", ++ data->__tcpi_last_ack_sent); ++ binn_object_set_uint32(binnobj, "tcpi_unacked", ++ data->__tcpi_unacked); ++ binn_object_set_uint32(binnobj, "tcpi_last_data_sent", ++ data->__tcpi_last_data_sent); ++ binn_object_set_uint32(binnobj, "tcpi_last_ack_recv", ++ data->__tcpi_last_ack_recv); ++ binn_object_set_uint32(binnobj, "tcpi_reordering", ++ data->__tcpi_reordering); ++ binn_object_set_uint32(binnobj, "tcpi_advmss", ++ data->__tcpi_advmss); ++ binn_object_set_uint32(binnobj, "tcpi_retrans", ++ data->__tcpi_retrans); ++ binn_object_set_uint32(binnobj, "tcpi_ato", ++ data->__tcpi_ato); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_rtt", ++ data->__tcpi_rcv_rtt); ++#endif ++ ++/* Under BSD snd_rexmitpack is the same as linux total_retrans*/ ++#ifdef __linux__ ++ binn_object_set_uint32(binnobj, "tcpi_total_retrans", ++ data->tcpi_total_retrans); ++#else ++ binn_object_set_uint32(binnobj, "tcpi_total_retrans", ++ data->tcpi_snd_rexmitpack); ++#endif ++ ++/* The last section are for kernel specific metrics in linux */ ++#ifdef __linux__ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) ++ binn_object_set_uint64(binnobj, "tcpi_max_pacing_rate", ++ data->tcpi_max_pacing_rate); ++ binn_object_set_uint64(binnobj, "tcpi_pacing_rate", ++ data->tcpi_pacing_rate); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) ++ binn_object_set_uint64(binnobj, "tcpi_bytes_acked", ++ data->tcpi_bytes_acked); ++ binn_object_set_uint64(binnobj, "tcpi_bytes_received", ++ data->tcpi_bytes_received); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0) ++ binn_object_set_uint32(binnobj, "tcpi_segs_in", ++ data->tcpi_segs_in); ++ binn_object_set_uint32(binnobj, "tcpi_segs_out", ++ data->tcpi_segs_out); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) ++ binn_object_set_uint32(binnobj, "tcpi_notsent_bytes", ++ data->tcpi_notsent_bytes); ++ binn_object_set_uint32(binnobj, "tcpi_min_rtt", ++ data->tcpi_min_rtt); ++ binn_object_set_uint32(binnobj, "tcpi_data_segs_in", ++ data->tcpi_data_segs_in); ++ binn_object_set_uint32(binnobj, "tcpi_data_segs_out", ++ data->tcpi_data_segs_out); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0) ++ binn_object_set_uint8(binnobj, "tcpi_delivery_rate_app_limited", ++ data->tcpi_delivery_rate_app_limited); ++ binn_object_set_uint64(binnobj, "tcpi_delivery_rate", ++ data->tcpi_delivery_rate); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) ++ binn_object_set_uint64(binnobj, "tcpi_busy_time", ++ data->tcpi_busy_time); ++ binn_object_set_uint64(binnobj, "tcpi_sndbuf_limited", ++ data->tcpi_sndbuf_limited); ++ binn_object_set_uint64(binnobj, "tcpi_rwnd_limited", ++ data->tcpi_rwnd_limited); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,0) ++ binn_object_set_uint32(binnobj, "tcpi_delivered", ++ data->tcpi_delivered); ++ binn_object_set_uint32(binnobj, "tcpi_delivered_ce", ++ data->tcpi_delivered_ce); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0) ++ binn_object_set_uint64(binnobj, "tcpi_bytes_sent", ++ data->tcpi_bytes_sent); ++ binn_object_set_uint64(binnobj, "tcpi_bytes_retrans", ++ data->tcpi_bytes_retrans); ++ binn_object_set_uint32(binnobj, "tcpi_dsack_dups", ++ data->tcpi_dsack_dups); ++ binn_object_set_uint32(binnobj, "tcpi_reord_seen", ++ data->tcpi_reord_seen); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0) ++ binn_object_set_uint32(binnobj, "tcpi_snd_wnd", ++ data->tcpi_snd_wnd); ++ binn_object_set_uint32(binnobj, "tcpi_rcv_ooopack", ++ data->tcpi_rcv_ooopack); ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0) ++ binn_object_set_uint8(binnobj, "tcpi_fastopen_client_fail", ++ data->tcpi_fastopen_client_fail); ++#endif ++#endif /*endif for #ifdef __linux__ */ ++#endif /*endif for TCP_INFO */ ++} ++ ++/* this reads out the tcp_info binn object and formats it into a single line ++ * the object will not necessarily have all of the elements. If it's empty it ++ * current just spits out 0. This isn't optimal as 0 can also be a valid value */ ++void ++metrics_read_binn_object (void *binnobj, char **output) { ++ int len = 0; ++ int buflen = 1023; ++ int kernel_version = 0; ++ if (binnobj == NULL) { ++ fprintf(stderr, "Metric polling returned bad data.\n"); ++ return; ++ } ++ kernel_version = binn_object_uint32(binnobj, "kernel_version"); ++ ++ /* base set of metrics */ ++ len = snprintf(*output, buflen, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", ++ binn_object_uint8(binnobj, "tcpi_state"), ++ binn_object_uint8(binnobj, "tcpi_ca_state"), ++ binn_object_uint8(binnobj, "tcpi_retransmits"), ++ binn_object_uint8(binnobj, "tcpi_probes"), ++ binn_object_uint8(binnobj, "tcpi_backoff"), ++ binn_object_uint8(binnobj, "tcpi_options"), ++ binn_object_uint8(binnobj, "tcpi_snd_wscale"), ++ binn_object_uint8(binnobj, "tcpi_rcv_wscale"), ++ binn_object_uint32(binnobj, "tcpi_rto"), ++ binn_object_uint32(binnobj, "tcpi_ato"), ++ binn_object_uint32(binnobj, "tcpi_snd_mss"), ++ binn_object_uint32(binnobj, "tcpi_rcv_mss"), ++ binn_object_uint32(binnobj, "tcpi_unacked"), ++ binn_object_uint32(binnobj, "tcpi_sacked"), ++ binn_object_uint32(binnobj, "tcpi_lost"), ++ binn_object_uint32(binnobj, "tcpi_retrans"), ++ binn_object_uint32(binnobj, "tcpi_fackets"), ++ binn_object_uint32(binnobj, "tcpi_last_data_sent"), ++ binn_object_uint32(binnobj, "tcpi_last_ack_sent"), ++ binn_object_uint32(binnobj, "tcpi_last_data_recv"), ++ binn_object_uint32(binnobj, "tcpi_last_ack_recv"), ++ binn_object_uint32(binnobj, "tcpi_pmtu"), ++ binn_object_uint32(binnobj, "tcpi_rcv_ssthresh"), ++ binn_object_uint32(binnobj, "tcpi_rtt"), ++ binn_object_uint32(binnobj, "tcpi_rttvar"), ++ binn_object_uint32(binnobj, "tcpi_snd_ssthresh"), ++ binn_object_uint32(binnobj, "tcpi_snd_cwnd"), ++ binn_object_uint32(binnobj, "tcpi_advmss"), ++ binn_object_uint32(binnobj, "tcpi_reordering"), ++ binn_object_uint32(binnobj, "tcpi_rcv_rtt"), ++ binn_object_uint32(binnobj, "tcpi_rcv_space"), ++ binn_object_uint32(binnobj, "tcpi_total_retrans") ++ ); ++ ++ /* compare the received kernel version to the version that supports ++ * any given metric. This means that a remote host that has a different ++ * kernel that the local host will be able to process the data in terms of ++ * the remote kernel version. Only necessary under linux*/ ++#ifdef __linux__ ++ if (kernel_version >= KERNEL_VERSION(3,15,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %llu, %llu", ++ binn_object_uint64(binnobj, "tcpi_max_pacing_rate"), ++ binn_object_uint64(binnobj, "tcpi_pacing_rate") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,1,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %llu, %llu", ++ binn_object_uint64(binnobj, "tcpi_bytes_acked"), ++ binn_object_uint64(binnobj, "tcpi_bytes_received") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,2,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ binn_object_uint32(binnobj, "tcpi_segs_in"), ++ binn_object_uint32(binnobj, "tcpi_segs_out") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,6,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d, %d, %d, %d", ++ binn_object_uint32(binnobj, "tcpi_notsent_bytes"), ++ binn_object_uint32(binnobj, "tcpi_min_rtt"), ++ binn_object_uint32(binnobj, "tcpi_data_segs_in"), ++ binn_object_uint32(binnobj, "tcpi_data_segs_out") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,9,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d, %llu", ++ binn_object_uint8(binnobj, "tcpi_delivery_rate_app_limited"), ++ binn_object_uint64(binnobj, "tcpi_delivery_rate") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,10,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %llu, %llu, %llu", ++ binn_object_uint64(binnobj, "tcpi_busy_time"), ++ binn_object_uint64(binnobj, "tcpi_sndbuf_limited"), ++ binn_object_uint64(binnobj, "tcpi_rwnd_limited") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,18,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ binn_object_uint32(binnobj, "tcpi_delivered"), ++ binn_object_uint32(binnobj, "tcpi_delivered_ce") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,19,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %llu, %llu, %d, %d", ++ binn_object_uint64(binnobj, "tcpi_bytes_sent"), ++ binn_object_uint64(binnobj, "tcpi_bytes_retrans"), ++ binn_object_uint32(binnobj, "tcpi_dsack_dups"), ++ binn_object_uint32(binnobj, "tcpi_reord_seen") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(5,4,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ binn_object_uint32(binnobj, "tcpi_snd_wnd"), ++ binn_object_uint32(binnobj, "tcpi_rcv_ooopack") ++ ); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(5,5,0)) { ++ len += snprintf(*output+len, (buflen-len), ", %d", ++ binn_object_uint8(binnobj, "tcpi_fastopen_client_fail") ++ ); ++ } ++#endif /* ifdef __linux__ */ ++} ++ ++/* Print out the header to the file so that the column header matches the ++ * data in the metrics object. That varies by kernel version so we have to ++ * do tests for each possible version where they added new values to tcp_info ++ * NOTE: This doesn't put the values/headers in the most useful order but the ++ * resulting file is probably going to get processed by something */ ++void ++metrics_print_header(FILE *fptr, char *extra_text, int kernel_version) { ++ if (extra_text != NULL) { ++ fprintf(fptr, "%s\n", extra_text); ++ } ++ fprintf(fptr, "timestamp, state, ca_state, retransmits, probes, backoff, options, "); ++ fprintf(fptr, "snd_wscale, rcv_wscale, rto, ato, snd_mss, rcv_mss, unacked, sacked, lost, retrans, "); ++ fprintf(fptr, "fackets, last_data_sent, last_ack_sent, last_data_recv, "); ++ fprintf(fptr, "last_ack_recv, pmtu, rcv_ssthresh, rtt, rttvar, snd_ssthresh, "); ++ fprintf(fptr, "snd_cwnd, advmss, reordering, rcv_rtt, rcv_space, total_retrans"); ++ ++ /* compare the received kernel version to the version that supports ++ * any given metric. This way we can print consistent headers. ++ * Only necessary under linux*/ ++#ifdef __linux__ ++ if (kernel_version >= KERNEL_VERSION(3,15,0)) { ++ fprintf(fptr, ", max_pacing_rate, pacing_rate"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,1,0)) { ++ fprintf(fptr, ", bytes_acked, bytes_received"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,2,0)) { ++ fprintf(fptr, ", segs_in, segs_out"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,6,0)) { ++ fprintf(fptr, ", notsent_bytes, min_rtt, data_segs_in, data_seg_out"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,9,0)) { ++ fprintf(fptr, ", delivery_rate_app_limited, delivery_rate"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,10,0)) { ++ fprintf(fptr, ", busy_time, sndbuf_limited, rwnd_limited"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,18,0)) { ++ fprintf(fptr, ", delivered, delivered_ce"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(4,19,0)) { ++ fprintf(fptr, ", bytes_sent, bytes_retrans, dsack_dups, reord_seen"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(5,4,0)) { ++ fprintf(fptr, ", snd_wnd, rcv_ooopack"); ++ } ++ ++ if (kernel_version >= KERNEL_VERSION(5,5,0)) { ++ fprintf(fptr, ", fastopen_client_fail"); ++ } ++#endif /* ifdef __linux__ */ ++ fprintf(fptr, "\n\n"); ++} +diff -Nur openssh-9.6p1.orig/metrics.h openssh-9.6p1/metrics.h +--- openssh-9.6p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/metrics.h 2024-07-10 13:34:02.721358597 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. ++ * ++ * Author: Chris Rapier ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the MIT License. ++ * ++ * This library is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the MIT License for more details. ++ * ++ * You should have received a copy of the MIT License along with this library; ++ * if not, see http://opensource.org/licenses/MIT. ++ * ++ */ ++ ++#ifndef METRICS_H ++#define METRICS_H ++ ++#include "binn.h" ++ ++/* linux, freebsd, and netbsd have tcp_info structs. ++ * I don't know about other systems so we disable this ++ * functionality for them */ ++#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ && !defined(__alpine__) ++#define TCP_INFO 1 ++#if defined __linux__ && !defined(__alpine__) ++#include ++#else ++#include ++#endif ++#else ++/* make a null struct for tcp_info on systems that don't support it*/ ++typedef struct tcp_info { ++ void *dummy; ++} tcp_info; ++#endif ++ ++void metrics_write_binn_object(struct tcp_info *, struct binn_struct *); ++void metrics_read_binn_object(void *, char **); ++void metrics_print_header(FILE *, char *, int); ++ ++ ++#endif /* define metrics_h */ +diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c +--- openssh-9.6p1.orig/misc.c 2024-07-10 13:32:39.597111805 +0200 ++++ openssh-9.6p1/misc.c 2024-07-10 13:34:02.722358600 +0200 +@@ -77,6 +77,29 @@ + #include "ssherr.h" + #include "platform.h" + ++void ++read_mem_stats(statm_t *result, int post_auth) ++{ ++ if (!post_auth) ++ return; ++ ++ const char* statm_path = "/proc/self/statm"; ++ ++ FILE *f = fopen(statm_path,"r"); ++ if(!f){ ++ perror(statm_path); ++ abort(); ++ } ++ if(7 != fscanf(f,"%lu %lu %lu %lu %lu %lu %lu", ++ &result->size, &result->resident, &result->share, &result->text, &result->lib, ++ &result->data, &result->dt)) ++ { ++ perror(statm_path); ++ abort(); ++ } ++ fclose(f); ++} ++ + /* remove newline at end of string */ + char * + chop(char *s) +@@ -1635,20 +1658,6 @@ + return (v); + } + +-u_int32_t +-get_u32_le(const void *vp) +-{ +- const u_char *p = (const u_char *)vp; +- u_int32_t v; +- +- v = (u_int32_t)p[0]; +- v |= (u_int32_t)p[1] << 8; +- v |= (u_int32_t)p[2] << 16; +- v |= (u_int32_t)p[3] << 24; +- +- return (v); +-} +- + u_int16_t + get_u16(const void *vp) + { +@@ -1688,17 +1697,6 @@ + } + + void +-put_u32_le(void *vp, u_int32_t v) +-{ +- u_char *p = (u_char *)vp; +- +- p[0] = (u_char)v & 0xff; +- p[1] = (u_char)(v >> 8) & 0xff; +- p[2] = (u_char)(v >> 16) & 0xff; +- p[3] = (u_char)(v >> 24) & 0xff; +-} +- +-void + put_u16(void *vp, u_int16_t v) + { + u_char *p = (u_char *)vp; +diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h +--- openssh-9.6p1.orig/misc.h 2024-07-10 13:32:39.598111808 +0200 ++++ openssh-9.6p1/misc.h 2024-07-10 13:34:02.722358600 +0200 +@@ -158,12 +158,6 @@ + void put_u16(void *, u_int16_t) + __attribute__((__bounded__( __minbytes__, 1, 2))); + +-/* Little-endian store/load, used by umac.c */ +-u_int32_t get_u32_le(const void *) +- __attribute__((__bounded__(__minbytes__, 1, 4))); +-void put_u32_le(void *, u_int32_t) +- __attribute__((__bounded__(__minbytes__, 1, 4))); +- + struct bwlimit { + size_t buflen; + u_int64_t rate; /* desired rate in kbit/s */ +@@ -248,4 +242,16 @@ + /* On OpenBSD time_t is int64_t which is long long. */ + /* #define SSH_TIME_T_MAX LLONG_MAX */ + ++typedef struct statm_t { ++ unsigned long size; ++ unsigned long resident; ++ unsigned long share; ++ unsigned long text; ++ unsigned long lib; ++ unsigned long data; ++ unsigned long dt; ++} statm_t; ++ ++void read_mem_stats(struct statm_t *, int); ++ + #endif /* _MISC_H */ +diff -Nur openssh-9.6p1.orig/myproposal.h openssh-9.6p1/myproposal.h +--- openssh-9.6p1.orig/myproposal.h 2024-07-10 13:32:39.557111687 +0200 ++++ openssh-9.6p1/myproposal.h 2024-07-10 13:34:02.722358600 +0200 +@@ -69,6 +69,7 @@ + "rsa-sha2-256" + + #define KEX_SERVER_ENCRYPT \ ++ "chacha20-poly1305-mt@hpnssh.org," \ + "chacha20-poly1305@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com" +diff -Nur openssh-9.6p1.orig/num.c openssh-9.6p1/num.c +--- openssh-9.6p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/num.c 2024-07-10 13:34:02.722358600 +0200 +@@ -0,0 +1,156 @@ ++/* CC0 license applied, see LICENCE.md */ ++ ++#include ++#include "num.h" ++ ++#ifdef WITH_OPENSSL3 ++ ++typedef enum { BIG = 1, LITTLE = -1 } endian_t; ++typedef enum { NEGATIVE = 0xff, POSITIVE = 0x00 } sign_t; ++ ++static endian_t nativeendian(void) ++{ ++ const int endiantest = 1; ++ ++ return *((char *)&endiantest) == 1 ? LITTLE : BIG; ++} ++ ++static sign_t paramsign(const OSSL_PARAM *param) ++{ ++ size_t srcmsb = nativeendian() == BIG ? 0 : param->data_size - 1; ++ ++ return ++ param->data_type == OSSL_PARAM_UNSIGNED_INTEGER ++ ? POSITIVE ++ : (((unsigned char *)param->data)[srcmsb] & 0x80 ++ ? NEGATIVE ++ : POSITIVE); ++} ++ ++struct numdesc { ++ void *data; ++ unsigned int data_type; /* The OSSL_PARAM data type */ ++ ++ /* These fields concern the whole number */ ++ size_t size; ++ endian_t endian; ++ sign_t sign; ++ ++ /* These fields concern the limbs of the number */ ++ size_t limbsize; ++ endian_t limbendian; ++ /* This is for odd archs. */ ++ /* see the manual for mpz_import() for an in depth explanation. */ ++ size_t limbnailbits; ++}; ++ ++struct resultdesc { ++ size_t size; ++ int result; /* 1 or (negative) error */ ++}; ++ ++static struct resultdesc provnum_copy(struct numdesc dest, struct numdesc src) ++{ ++ struct resultdesc result = { dest.size, 1, }; ++ ++ if (src.data_type != OSSL_PARAM_INTEGER ++ && src.data_type != OSSL_PARAM_UNSIGNED_INTEGER) { ++ result.result = PROVNUM_E_WRONG_TYPE; ++ return result; ++ } ++ ++ if (src.size == 0) { ++ memset(dest.data, 0, dest.size); ++ return result; ++ } ++ ++ /* Extra data */ ++ size_t srcmsb = src.endian == BIG ? 0 : src.size - 1; ++ int srcmsb2lsb = src.endian == BIG ? 1 : -1; ++ ++ /* ++ * If the source is bigger than the destination, analyse to see if the ++ * most significant byte is just padding that can be ignored. ++ * The rules to determine if the most significant byte is just padding ++ * are: ++ * ++ * 1. the most significant byte equals srcsigned, which just so happens ++ * to have the 2's complement padding value. ++ * 2. The most significant bit of the next to most significant byte ++ * equals the most significant bit of srcsigned. ++ */ ++ size_t end = dest.data == NULL ? 1 : dest.size; ++ for (; src.size > end; srcmsb += srcmsb2lsb, src.size--) ++ if (((unsigned char *)src.data)[srcmsb] != src.sign ++ || ((((unsigned char *)src.data)[srcmsb + srcmsb2lsb] & 0x80) ++ != (src.sign & 0x80))) ++ break; ++ ++ if (src.size > dest.size) { ++ result.result = PROVNUM_E_TOOBIG; ++ return result; ++ } ++ ++ size_t srclsb = srcmsb + srcmsb2lsb * (src.size - 1); ++ ++ /* Simple case, all significant details match */ ++ if (dest.endian == src.endian ++ && dest.limbsize == 1 ++ && dest.limbnailbits == 0 ++ && (dest.data_type == OSSL_PARAM_INTEGER || src.sign == POSITIVE)) { ++ ++ if (src.size < dest.size) { ++ size_t padstart = dest.endian == BIG ? 0 : dest.size - src.size; ++ ++ memset((unsigned char *)dest.data + padstart, src.sign, ++ dest.size - src.size); ++ } ++ ++ size_t deststart = dest.endian == BIG ? dest.size - src.size : 0; ++ size_t srcstart = src.endian == BIG ? srcmsb : srclsb; ++ ++ memcpy((unsigned char *)dest.data + deststart, ++ (unsigned char *)src.data + srcstart, ++ src.size); ++ return result; ++ } ++ ++ /* Complex case, for sign or limb conversion. Currently unsupported */ ++ result.result = PROVNUM_E_UNSUPPORTED; ++ return result; ++} ++ ++#define implement_provnum(T, DT) \ ++ int provnum_get_##T(T *dest, const OSSL_PARAM *param) \ ++ { \ ++ endian_t endian = nativeendian(); \ ++ struct numdesc destnd = { \ ++ dest, DT, sizeof(T), endian, POSITIVE, 1, endian, 0 \ ++ }; \ ++ struct numdesc srcnd = { \ ++ param->data, param->data_type, param->data_size, \ ++ endian, paramsign(param), 1, endian, 0 \ ++ }; \ ++ \ ++ struct resultdesc result = provnum_copy(destnd, srcnd); \ ++ return result.result; \ ++ } \ ++ int provnum_set_##T(OSSL_PARAM *param, T src) \ ++ { \ ++ endian_t endian = nativeendian(); \ ++ struct numdesc destnd = { \ ++ param->data, param->data_type, param->data_size, \ ++ endian, POSITIVE, 1, endian, 0 \ ++ }; \ ++ struct numdesc srcnd = { \ ++ &src, DT, sizeof(T), endian, POSITIVE, 1, endian, 0 \ ++ }; \ ++ \ ++ struct resultdesc result = provnum_copy(destnd, srcnd); \ ++ param->return_size = result.size; \ ++ return result.result; \ ++ } ++ ++implement_provnum(size_t, OSSL_PARAM_UNSIGNED_INTEGER) ++ ++#endif /* WITH_OPENSSL3 */ +diff -Nur openssh-9.6p1.orig/num.h openssh-9.6p1/num.h +--- openssh-9.6p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/num.h 2024-07-10 13:34:02.723358603 +0200 +@@ -0,0 +1,15 @@ ++/* CC0 license applied, see LICENCE.md */ ++ ++#include "includes.h" ++#ifdef WITH_OPENSSL3 ++ ++#include ++ ++/* Convert between OSSL_PARAM and size_t */ ++int provnum_get_size_t(size_t *dest, const OSSL_PARAM *param); ++int provnum_set_size_t(OSSL_PARAM *param, size_t src); ++ ++#define PROVNUM_E_WRONG_TYPE -1 ++#define PROVNUM_E_TOOBIG -2 ++#define PROVNUM_E_UNSUPPORTED -3 ++#endif /* WITH_OPENSSL3 */ +diff -Nur openssh-9.6p1.orig/ossl3-provider-err.c openssh-9.6p1/ossl3-provider-err.c +--- openssh-9.6p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/ossl3-provider-err.c 2024-07-10 13:34:02.723358603 +0200 +@@ -0,0 +1,108 @@ ++/* CC0 license applied, see LICENCE.md */ ++ ++#include ++#include ++#include "ossl3-provider-err.h" ++ ++#ifdef WITH_OPENSSL3 ++ ++struct proverr_functions_st { ++ const OSSL_CORE_HANDLE *core; ++ OSSL_FUNC_core_new_error_fn *core_new_error; ++ OSSL_FUNC_core_set_error_debug_fn *core_set_error_debug; ++ OSSL_FUNC_core_vset_error_fn *core_vset_error; ++}; ++ ++struct proverr_functions_st * ++proverr_new_handle(const OSSL_CORE_HANDLE *core, const OSSL_DISPATCH *dispatch) ++{ ++ /* ++ * libcrypto gives providers the tools to create error routines similar ++ * to the ones defined in ++ */ ++ OSSL_FUNC_core_new_error_fn *c_new_error = NULL; ++ OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug = NULL; ++ OSSL_FUNC_core_vset_error_fn *c_vset_error = NULL; ++ struct proverr_functions_st *handle = NULL; ++ ++ assert(core != NULL); ++ assert(dispatch != NULL); ++ ++#ifndef DEBUG ++ if (core == NULL || dispatch == NULL) ++ return NULL; ++#endif ++ ++ for (; dispatch->function_id != 0; dispatch++) ++ switch (dispatch->function_id) { ++ case OSSL_FUNC_CORE_NEW_ERROR: ++ c_new_error = OSSL_FUNC_core_new_error(dispatch); ++ break; ++ case OSSL_FUNC_CORE_SET_ERROR_DEBUG: ++ c_set_error_debug = OSSL_FUNC_core_set_error_debug(dispatch); ++ break; ++ case OSSL_FUNC_CORE_VSET_ERROR: ++ c_vset_error = OSSL_FUNC_core_vset_error(dispatch); ++ break; ++ } ++ ++ assert(c_new_error != NULL); ++ assert(c_set_error_debug != NULL); ++ assert(c_vset_error != NULL); ++ ++#ifdef NDEBUG ++ if (c_new_error == NULL || c_set_error_debug == NULL || c_vset_error == NULL) ++ return NULL; ++#endif ++ ++ if ((handle = malloc(sizeof(*handle))) != NULL) { ++ handle->core = core; ++ handle->core_new_error = c_new_error; ++ handle->core_set_error_debug = c_set_error_debug; ++ handle->core_vset_error = c_vset_error; ++ } ++ return handle; ++} ++ ++struct proverr_functions_st * ++proverr_dup_handle(struct proverr_functions_st *src) ++{ ++ struct proverr_functions_st *dst = NULL; ++ ++ if (src != NULL ++ && (dst = malloc(sizeof(*dst))) != NULL) { ++ dst->core = src->core; ++ dst->core_new_error = src->core_new_error; ++ dst->core_set_error_debug = src->core_set_error_debug; ++ dst->core_vset_error = src->core_vset_error; ++ } ++ return dst; ++} ++ ++void proverr_free_handle(struct proverr_functions_st *handle) ++{ ++ free(handle); ++} ++ ++void proverr_new_error(const struct proverr_functions_st *handle) ++{ ++ handle->core_new_error(handle->core); ++} ++ ++void proverr_set_error_debug(const struct proverr_functions_st *handle, ++ const char *file, int line, const char *func) ++{ ++ handle->core_set_error_debug(handle->core, file, line, func); ++} ++ ++void proverr_set_error(const struct proverr_functions_st *handle, ++ uint32_t reason, const char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ handle->core_vset_error(handle->core, reason, fmt, ap); ++ va_end(ap); ++} ++ ++#endif /* WITH_OPENSSL3 */ +diff -Nur openssh-9.6p1.orig/ossl3-provider-err.h openssh-9.6p1/ossl3-provider-err.h +--- openssh-9.6p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/ossl3-provider-err.h 2024-07-10 13:34:02.723358603 +0200 +@@ -0,0 +1,73 @@ ++/* CC0 license applied, see LICENCE.md */ ++ ++#include "includes.h" ++#ifdef WITH_OPENSSL3 ++#include ++#include ++#include ++ ++/* ++ * The idea with this library is to replace OpenSSL's ERR_raise() and ++ * ERR_raise_data() with variants that are more suitable for providers that ++ * have their own error reason table. ++ * ++ * This assumes variadic function-like macros, i.e. C99 or newer. ++ * ++ * A minimal amount of preparation is needed on provider initialization and ++ * takedown: ++ * ++ * 1. The provider's outgoing OSSL_DISPATCH table must include an entry ++ * got OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, with a function that returns ++ * the provider's table of reasons. ++ * That table of reasons is a simple OSSL_ITEM array, where each element ++ * contains a numeric reason identity for the reason, and the description ++ * text string for that reason. ++ * Each numeric reason identity MUST be unique within this array. ++ * ++ * 2. On provider initialization, an error handle must be created using ++ * proverr_new_handle(). The returned pointer is passed as first argument ++ * to ERR_raise() and ERR_raise_data(). ++ * ++ * 3. On provider takedown, the error handle must be freed, using ++ * proverr_free_handle(). ++ * ++ * With this preparation, the provider code can use ERR_raise() and ++ * ERR_raise_data() "as usual", with the exception that the first argument is ++ * the error handle instead of one of the OpenSSL ERR_LIB_ macros. ++ */ ++ ++/* ++ * In case was included, we throw away its error recording ++ * macros. ++ * Note that ERR_put_error() is NOT recreated. It's deprecated and should not ++ * be used any more. ++ */ ++#undef ERR_put_error ++#undef ERR_raise ++#undef ERR_raise_data ++ ++#define ERR_raise(handle, reason) ERR_raise_data((handle),(reason),NULL) ++ ++#define ERR_raise_data(handle, reason, ...) \ ++ (proverr_new_error(handle), \ ++ proverr_set_error_debug(handle, OPENSSL_FILE,OPENSSL_LINE,OPENSSL_FUNC), \ ++ proverr_set_error(handle, reason, __VA_ARGS__)) ++ ++/* ++ * The structure where the libcrypto core handle and core functions are ++ * captured. ++ */ ++struct proverr_functions_st; ++ ++struct proverr_functions_st * ++proverr_new_handle(const OSSL_CORE_HANDLE *core, const OSSL_DISPATCH *in); ++struct proverr_functions_st * ++proverr_dup_handle(struct proverr_functions_st *src); ++void proverr_free_handle(struct proverr_functions_st *handle); ++ ++void proverr_new_error(const struct proverr_functions_st *handle); ++void proverr_set_error_debug(const struct proverr_functions_st *handle, ++ const char *file, int line, const char *func); ++void proverr_set_error(const struct proverr_functions_st *handle, ++ uint32_t reason, const char *fmt, ...); ++#endif /* WITH_OPENSSL3 */ +diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c +--- openssh-9.6p1.orig/packet.c 2024-07-10 13:32:39.545111651 +0200 ++++ openssh-9.6p1/packet.c 2024-07-10 15:20:04.337115780 +0200 +@@ -63,6 +63,9 @@ + #endif + #include + #include ++#ifdef HAVE_UTIL_H ++# include ++#endif + + /* + * Explicitly include OpenSSL before zlib as some versions of OpenSSL have +@@ -104,7 +107,20 @@ + #define DBG(x) + #endif + +-#define PACKET_MAX_SIZE (256 * 1024) ++/* OpenSSH usings 256KB packet size max but that consumes a ++ * lot of memory with the buffers we are using. However, we need ++ * a large packet size if the banner that's being sent is large. ++ * So we need a 256KB packet pre authentication and a smaller one ++ * in this case SSH_IOBUFSZ + 1KB, afterwards. So we change ++ * PACKET_MAX_SIZE from a #define to a global. Then, in the function ++ * ssh_packet_set_authentcated we reduce the size to something ++ * more memory efficient. -cjr 04/07/23 ++ */ ++u_int packet_max_size = 256 * 1024; ++ ++/* global to support forced rekeying */ ++int rekey_requested = 0; ++ + + struct packet_state { + u_int32_t seqnr; +@@ -241,12 +257,19 @@ + (state->outgoing_packet = sshbuf_new()) == NULL || + (state->incoming_packet = sshbuf_new()) == NULL) + goto fail; ++ /* these buffers are important in terms of tracking buffer usage ++ * so we explicitly label them with descriptive names */ ++ sshbuf_relabel(state->input, "input"); ++ sshbuf_relabel(state->incoming_packet, "inpacket"); ++ sshbuf_relabel(state->output, "output"); ++ sshbuf_relabel(state->outgoing_packet, "outpacket"); ++ + TAILQ_INIT(&state->outgoing); + TAILQ_INIT(&ssh->private_keys); + TAILQ_INIT(&ssh->public_keys); + state->connection_in = -1; + state->connection_out = -1; +- state->max_packet_size = 32768; ++ state->max_packet_size = CHAN_SES_PACKET_DEFAULT; + state->packet_timeout_ms = -1; + state->p_send.packets = state->p_read.packets = 0; + state->initialized = 1; +@@ -294,7 +317,7 @@ + ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) + { + struct session_state *state; +- const struct sshcipher *none = cipher_by_name("none"); ++ struct sshcipher *none = cipher_by_name("none"); + int r; + + if (none == NULL) { +@@ -311,9 +334,11 @@ + state->connection_in = fd_in; + state->connection_out = fd_out; + if ((r = cipher_init(&state->send_context, none, +- (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || ++ (const u_char *)"", 0, NULL, 0, 0, CIPHER_ENCRYPT, ++ state->after_authentication)) != 0 || + (r = cipher_init(&state->receive_context, none, +- (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { ++ (const u_char *)"", 0, NULL, 0, 0, CIPHER_DECRYPT, ++ state->after_authentication)) != 0) { + error_fr(r, "cipher_init failed"); + free(ssh); /* XXX need ssh_free_session_state? */ + return NULL; +@@ -384,7 +409,7 @@ + + if (state->packet_discard_mac) { + char buf[1024]; +- size_t dlen = PACKET_MAX_SIZE; ++ size_t dlen = packet_max_size; + + if (dlen > state->packet_discard_mac_already) + dlen -= state->packet_discard_mac_already; +@@ -885,6 +910,7 @@ + const char *wmsg; + int r, crypt_type; + const char *dir = mode == MODE_OUT ? "out" : "in"; ++ char blocks_s[FMT_SCALED_STRSIZE], bytes_s[FMT_SCALED_STRSIZE]; + + debug2_f("mode %d", mode); + +@@ -923,12 +949,32 @@ + if ((r = mac_init(mac)) != 0) + return r; + } +- mac->enabled = 1; ++ ++ /* if we are using NONE MAC then we don't need to enable the ++ * mac routines. This disables them and we can claw back some cycles ++ * from the CPU -cjr 3/21/2023 */ ++ if (ssh->none_mac != 1) ++ mac->enabled = 1; ++ + DBG(debug_f("cipher_init: %s", dir)); + cipher_free(*ccp); + *ccp = NULL; ++#ifdef WITH_OPENSSL ++ if (strcmp(enc->name, "chacha20-poly1305-mt@hpnssh.org") == 0) { ++ if (state->after_authentication) ++ enc->cipher = cipher_by_name( ++ "chacha20-poly1305-mt@hpnssh.org"); ++ else ++ enc->cipher = cipher_by_name( ++ "chacha20-poly1305@openssh.com"); ++ if (enc->cipher == NULL) ++ return r; ++ } ++#endif + if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len, +- enc->iv, enc->iv_len, crypt_type)) != 0) ++ enc->iv, enc->iv_len, ++ crypt_type ? state->p_send.seqnr : state->p_read.seqnr, ++ crypt_type, state->after_authentication)) != 0) + return r; + if (!state->cipher_warning_done && + (wmsg = cipher_warning_message(*ccp)) != NULL) { +@@ -953,23 +999,45 @@ + } + comp->enabled = 1; + } +- /* +- * The 2^(blocksize*2) limit is too expensive for 3DES, +- * so enforce a 1GB limit for small blocksizes. +- * See RFC4344 section 3.2. +- */ +- if (enc->block_size >= 16) +- *max_blocks = (u_int64_t)1 << (enc->block_size*2); +- else +- *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; +- if (state->rekey_limit) +- *max_blocks = MINIMUM(*max_blocks, +- state->rekey_limit / enc->block_size); +- debug("rekey %s after %llu blocks", dir, +- (unsigned long long)*max_blocks); ++ ++ /* get the maximum number of blocks the cipher can ++ * handle safely */ ++ *max_blocks = cipher_rekey_blocks(enc->cipher); ++ ++ /* if we have a custom oRekeyLimit use that. */ ++ if (state->rekey_limit) ++ *max_blocks = MINIMUM(*max_blocks, ++ state->rekey_limit / enc->block_size); ++ ++ /* these lines support the debug */ ++ strlcpy(blocks_s, "?", sizeof(blocks_s)); ++ strlcpy(bytes_s, "?", sizeof(bytes_s)); ++ if (*max_blocks * enc->block_size < LLONG_MAX) { ++ fmt_scaled((long long)*max_blocks, blocks_s); ++ fmt_scaled((long long)*max_blocks * enc->block_size, bytes_s); ++ } ++ debug("rekey %s after %s blocks / %sB data", dir, blocks_s, bytes_s); ++ + return 0; + } + ++/* this supports the forced rekeying required for the NONE cipher */ ++void ++packet_request_rekeying(void) ++{ ++ rekey_requested = 1; ++} ++ ++/* used to determine if pre or post auth when rekeying for aes-ctr ++ * and none cipher switch */ ++int ++packet_authentication_state(const struct ssh *ssh) ++{ ++ struct session_state *state = ssh->state; ++ ++ return state->after_authentication; ++} ++ + #define MAX_PACKETS (1U<<31) + static int + ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) +@@ -996,6 +1064,14 @@ + if (state->p_send.packets == 0 && state->p_read.packets == 0) + return 0; + ++ /* used to force rekeying when called for by the none ++ * cipher switch and aes-mt-ctr methods -cjr */ ++ if (rekey_requested == 1) { ++ debug_f("Got the rekey request"); ++ rekey_requested = 0; ++ return 1; ++ } ++ + /* Time-based rekeying */ + if (state->rekey_interval != 0 && + (int64_t)state->rekey_time + state->rekey_interval <= monotime()) +@@ -1354,7 +1430,7 @@ + struct session_state *state = ssh->state; + int len, r, ms_remain = 0; + struct pollfd pfd; +- char buf[8192]; ++ char buf[SSH_IOBUFSZ]; + struct timeval start; + struct timespec timespec, *timespecp = NULL; + +@@ -1481,7 +1557,7 @@ + return 0; /* packet is incomplete */ + state->packlen = PEEK_U32(cp); + if (state->packlen < 4 + 1 || +- state->packlen > PACKET_MAX_SIZE) ++ state->packlen > packet_max_size) + return SSH_ERR_MESSAGE_INCOMPLETE; + } + need = state->packlen + 4; +@@ -1540,7 +1616,7 @@ + sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) + return 0; + if (state->packlen < 1 + 4 || +- state->packlen > PACKET_MAX_SIZE) { ++ state->packlen > packet_max_size) { + #ifdef PACKET_DEBUG + sshbuf_dump(state->input, stderr); + #endif +@@ -1567,7 +1643,7 @@ + goto out; + state->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet)); + if (state->packlen < 1 + 4 || +- state->packlen > PACKET_MAX_SIZE) { ++ state->packlen > packet_max_size) { + #ifdef PACKET_DEBUG + fprintf(stderr, "input: \n"); + sshbuf_dump(state->input, stderr); +@@ -1576,7 +1652,7 @@ + #endif + logit("Bad packet length %u.", state->packlen); + return ssh_packet_start_discard(ssh, enc, mac, 0, +- PACKET_MAX_SIZE); ++ packet_max_size); + } + if ((r = sshbuf_consume(state->input, block_size)) != 0) + goto out; +@@ -1599,7 +1675,7 @@ + logit("padding error: need %d block %d mod %d", + need, block_size, need % block_size); + return ssh_packet_start_discard(ssh, enc, mac, 0, +- PACKET_MAX_SIZE - block_size); ++ packet_max_size - block_size); + } + /* + * check if the entire packet has been received and +@@ -1643,11 +1719,11 @@ + if (r != SSH_ERR_MAC_INVALID) + goto out; + logit("Corrupted MAC on input."); +- if (need + block_size > PACKET_MAX_SIZE) ++ if (need + block_size > packet_max_size) + return SSH_ERR_INTERNAL_ERROR; + return ssh_packet_start_discard(ssh, enc, mac, + sshbuf_len(state->incoming_packet), +- PACKET_MAX_SIZE - need - block_size); ++ packet_max_size - need - block_size); + } + /* Remove MAC from input buffer */ + DBG(debug("MAC #%d ok", state->p_read.seqnr)); +@@ -1862,7 +1938,7 @@ + int r; + size_t rlen; + +- if ((r = sshbuf_read(fd, state->input, PACKET_MAX_SIZE, &rlen)) != 0) ++ if ((r = sshbuf_read(fd, state->input, packet_max_size, &rlen)) != 0) + return r; + + if (state->packet_discard) { +@@ -1941,17 +2017,21 @@ + switch (r) { + case SSH_ERR_CONN_CLOSED: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection closed by %s", remote_id); + case SSH_ERR_CONN_TIMEOUT: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection %s %s timed out", + ssh->state->server_side ? "from" : "to", remote_id); + case SSH_ERR_DISCONNECTED: + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Disconnected from %s", remote_id); + case SSH_ERR_SYSTEM_ERROR: + if (errno == ECONNRESET) { + ssh_packet_clear_keys(ssh); ++ sshpkt_final_log_entry(ssh); + logdie("Connection reset by %s", remote_id); + } + /* FALLTHROUGH */ +@@ -1993,6 +2073,24 @@ + logdie_f("should have exited"); + } + ++/* this prints out the final log entry */ ++void ++sshpkt_final_log_entry (struct ssh *ssh) { ++ double total_time; ++ ++ if (ssh->start_time < 1) ++ /* this will produce a NaN in the output. -cjr */ ++ total_time = 0; ++ else ++ total_time = monotime_double() - ssh->start_time; ++ ++ logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f", ++ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ++ ssh->stdin_bytes, ssh->fdout_bytes, total_time, ++ ssh->stdin_bytes / total_time, ++ ssh->fdout_bytes / total_time); ++} ++ + /* + * Logs the error plus constructs and sends a disconnect packet, closes the + * connection, and exits. This function never returns. The error message +@@ -2247,10 +2345,19 @@ + ssh->kex->server = 1; /* XXX unify? */ + } + ++/* Set the state of the connection to post auth ++ * While we are here also decrease the size of ++ * packet_max_size to something more reasonable. ++ * In this case thats 33k. Which is the size of ++ * the largest packet we expect to see and some space ++ * for overhead. This reduces memory usage in high ++ * BDP environments without impacting performance ++ * -cjr 4/11/23 */ + void + ssh_packet_set_authenticated(struct ssh *ssh) + { + ssh->state->after_authentication = 1; ++ packet_max_size = SSH_IOBUFSZ + 1024; + } + + void * +@@ -2868,3 +2975,17 @@ + ssh->state->extra_pad = pad; + return 0; + } ++ ++/* used for cipher switching ++ * only called in cipher-swtich.c */ ++void * ++ssh_packet_get_send_context(struct ssh *ssh) ++{ ++ return ssh->state->send_context; ++} ++ ++void * ++ssh_packet_get_receive_context(struct ssh *ssh) ++{ ++ return ssh->state->receive_context; ++} +diff -Nur openssh-9.6p1.orig/packet.h openssh-9.6p1/packet.h +--- openssh-9.6p1.orig/packet.h 2024-07-10 13:32:39.546111654 +0200 ++++ openssh-9.6p1/packet.h 2024-07-10 13:34:02.724358606 +0200 +@@ -86,6 +86,20 @@ + + /* APP data */ + void *app_data; ++ ++ /* logging data for ServerLogging patch*/ ++ double start_time; ++ u_long fdout_bytes; ++ u_long stdin_bytes; ++ ++ /* track that we are in a none cipher state */ ++ int none; ++ ++ /* track if we have disabled the mac as well */ ++ int none_mac; ++ ++ /* use the less agressive window growth option */ ++ int hpn_buffer_limit; + }; + + typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, +@@ -158,6 +172,8 @@ + int ssh_packet_set_maxsize(struct ssh *, u_int); + u_int ssh_packet_get_maxsize(struct ssh *); + ++int packet_authentication_state(const struct ssh *); ++ + int ssh_packet_get_state(struct ssh *, struct sshbuf *); + int ssh_packet_set_state(struct ssh *, struct sshbuf *); + +@@ -172,6 +188,13 @@ + + void *ssh_packet_get_input(struct ssh *); + void *ssh_packet_get_output(struct ssh *); ++void *ssh_packet_get_receive_context(struct ssh *); ++void *ssh_packet_get_send_context(struct ssh *); ++ ++/* for forced packet rekeying post auth */ ++void packet_request_rekeying(void); ++/* final log entry support */ ++void sshpkt_final_log_entry (struct ssh *); + + /* new API */ + int sshpkt_start(struct ssh *ssh, u_char type); +diff -Nur openssh-9.6p1.orig/poly1305.c openssh-9.6p1/poly1305.c +--- openssh-9.6p1.orig/poly1305.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/poly1305.c 2024-07-10 13:34:02.724358606 +0200 +@@ -13,6 +13,16 @@ + + #include "poly1305.h" + ++#ifdef OPENSSL_HAVE_POLY_EVP ++void ++poly1305_auth(EVP_MAC_CTX *poly_ctx, unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { ++ size_t poly_out_len; ++ EVP_MAC_init(poly_ctx, (const u_char *)key, POLY1305_KEYLEN, NULL); ++ EVP_MAC_update(poly_ctx, m, inlen); ++ EVP_MAC_final(poly_ctx, out, &poly_out_len, (size_t)POLY1305_TAGLEN); ++} ++#else ++ + #define mul32x32_64(a,b) ((uint64_t)(a) * (b)) + + #define U8TO32_LE(p) \ +@@ -30,7 +40,7 @@ + } while (0) + + void +-poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { ++poly1305_auth(char *unused, unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { + uint32_t t0,t1,t2,t3; + uint32_t h0,h1,h2,h3,h4; + uint32_t r0,r1,r2,r3,r4; +@@ -157,3 +167,4 @@ + U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32); + U32TO8_LE(&out[12], f3); + } ++#endif /* OPENSSL_HAVE_POLY_EVP */ +diff -Nur openssh-9.6p1.orig/poly1305.h openssh-9.6p1/poly1305.h +--- openssh-9.6p1.orig/poly1305.h 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/poly1305.h 2024-07-10 13:34:02.724358606 +0200 +@@ -13,8 +13,15 @@ + #define POLY1305_KEYLEN 32 + #define POLY1305_TAGLEN 16 + +-void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, ++#ifdef OPENSSL_HAVE_POLY_EVP ++#include ++ ++void poly1305_auth(EVP_MAC_CTX *poly_key, u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, ++ const u_char key[POLY1305_KEYLEN]) ++#else ++void poly1305_auth(char *unused, u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, + const u_char key[POLY1305_KEYLEN]) ++#endif + __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) + __attribute__((__bounded__(__buffer__, 2, 3))) + __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); +diff -Nur openssh-9.6p1.orig/progressmeter.c openssh-9.6p1/progressmeter.c +--- openssh-9.6p1.orig/progressmeter.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/progressmeter.c 2024-07-10 13:34:02.725358609 +0200 +@@ -66,6 +66,8 @@ + static off_t start_pos; /* initial position of transfer */ + static off_t end_pos; /* ending position of transfer */ + static off_t cur_pos; /* transfer position as of last refresh */ ++static off_t last_pos; ++static off_t max_delta_pos = 0; + static volatile off_t *counter; /* progress counter */ + static long stalled; /* how long we have been stalled */ + static int bytes_per_second; /* current speed in bytes per second */ +@@ -132,6 +134,7 @@ + int cur_speed; + int hours, minutes, seconds; + int file_len, cols; ++ off_t delta_pos; + + if ((!force_update && !alarm_fired && !win_resized) || !can_output()) + return; +@@ -147,6 +150,10 @@ + now = monotime_double(); + bytes_left = end_pos - cur_pos; + ++ delta_pos = cur_pos - last_pos; ++ if (delta_pos > max_delta_pos) ++ max_delta_pos = delta_pos; ++ + if (bytes_left > 0) + elapsed = now - last_update; + else { +@@ -176,7 +183,7 @@ + return; + + /* filename */ +- file_len = cols = win_size - 36; ++ file_len = cols = win_size - 45; + if (file_len > 0) { + asmprintf(&buf, INT_MAX, &cols, "%-*s", file_len, file); + /* If we used fewer columns than expected then pad */ +@@ -193,6 +200,12 @@ + xextendf(&buf, NULL, " %3d%% %s %s/s ", percent, format_size(cur_pos), + format_rate((off_t)bytes_per_second)); + ++ /* instantaneous rate */ ++ if (bytes_left > 0) ++ xextendf(&buf, NULL, "%s/s", format_rate((off_t)delta_pos)); ++ else ++ xextendf(&buf, NULL, "%s/s", format_rate((off_t)max_delta_pos)); ++ + /* ETA */ + if (!transferred) + stalled += elapsed; +@@ -235,6 +248,7 @@ + } + free(buf); + free(obuf); ++ last_pos = cur_pos; + } + + static void +diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c +--- openssh-9.6p1.orig/readconf.c 2024-07-10 13:32:39.600111814 +0200 ++++ openssh-9.6p1/readconf.c 2024-07-10 13:34:02.725358609 +0200 +@@ -72,6 +72,7 @@ + #include "myproposal.h" + #include "digest.h" + #include "ssh-gss.h" ++#include "sshbuf.h" + + /* Format of the configuration file: + +@@ -173,6 +174,9 @@ + oHashKnownHosts, + oTunnel, oTunnelDevice, + oLocalCommand, oPermitLocalCommand, oRemoteCommand, ++ oTcpRcvBufPoll, oHPNDisabled, ++ oNoneEnabled, oNoneMacEnabled, oNoneSwitch, oHPNBufferLimit, ++ oMetrics, oMetricsPath, oMetricsInterval, oFallback, oFallbackPort, + oVisualHostKey, + oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, + oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, +@@ -319,6 +323,15 @@ + { "kexalgorithms", oKexAlgorithms }, + { "ipqos", oIPQoS }, + { "requesttty", oRequestTTY }, ++ { "noneenabled", oNoneEnabled }, ++ { "nonemacenabled", oNoneMacEnabled }, ++ { "noneswitch", oNoneSwitch }, ++ { "hpnbufferlimit", oHPNBufferLimit }, ++ { "metrics", oMetrics }, ++ { "metricspath", oMetricsPath }, ++ { "metricsinterval", oMetricsInterval }, ++ { "fallback", oFallback }, ++ { "fallbackport", oFallbackPort }, + { "sessiontype", oSessionType }, + { "stdinnull", oStdinNull }, + { "forkafterauthentication", oForkAfterAuthentication }, +@@ -341,6 +354,8 @@ + { "proxyjump", oProxyJump }, + { "securitykeyprovider", oSecurityKeyProvider }, + { "knownhostscommand", oKnownHostsCommand }, ++ { "tcprcvbufpoll", oTcpRcvBufPoll }, ++ { "hpndisabled", oHPNDisabled }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ + { "enableescapecommandline", oEnableEscapeCommandline }, +@@ -539,7 +554,7 @@ + + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); +- port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; ++ port = sp ? ntohs(sp->s_port) : HPNSSH_DEFAULT_PORT; + } + return port; + } +@@ -1271,6 +1286,63 @@ + intptr = &options->check_host_ip; + goto parse_flag; + ++ case oHPNDisabled: ++ intptr = &options->hpn_disabled; ++ goto parse_flag; ++ ++ case oTcpRcvBufPoll: ++ intptr = &options->tcp_rcv_buf_poll; ++ goto parse_flag; ++ ++ case oNoneEnabled: ++ intptr = &options->none_enabled; ++ goto parse_flag; ++ ++ case oNoneMacEnabled: ++ intptr = &options->nonemac_enabled; ++ goto parse_flag; ++ ++ case oHPNBufferLimit: ++ intptr = &options->hpn_buffer_limit; ++ goto parse_flag; ++ ++ case oMetrics: ++ intptr = &options->metrics; ++ goto parse_flag; ++ ++ case oMetricsInterval: ++ intptr = &options->metrics_interval; ++ goto parse_int; ++ ++ case oMetricsPath: ++ charptr = &options->metrics_path; ++ options->metrics = 1; ++ goto parse_string; ++ ++ case oFallback: ++ intptr = &options->fallback; ++ goto parse_flag; ++ ++ case oFallbackPort: ++ intptr = &options->fallback_port; ++ goto parse_int; ++ ++ /* ++ * We check to see if the command comes from the command ++ * line or not. If it does then enable it otherwise fail. ++ * NONE should never be a default configuration. ++ */ ++ case oNoneSwitch: ++ if (strcmp(filename, "command-line") == 0) { ++ intptr = &options->none_switch; ++ goto parse_flag; ++ } else { ++ error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); ++ error("Continuing..."); ++ debug("NoneSwitch directive found in %.200s.", filename); ++ return 0; ++ } ++ + case oVerifyHostKeyDNS: + intptr = &options->verify_host_key_dns; + multistate_ptr = multistate_yesnoask; +@@ -2641,6 +2713,17 @@ + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->request_tty = -1; ++ options->none_switch = -1; ++ options->none_enabled = -1; ++ options->nonemac_enabled = -1; ++ options->metrics = -1; ++ options->metrics_path = NULL; ++ options->metrics_interval = -1; ++ options->hpn_disabled = -1; ++ options->hpn_buffer_limit = -1; ++ options->fallback = -1; ++ options->fallback_port = -1; ++ options->tcp_rcv_buf_poll = -1; + options->session_type = -1; + options->stdin_null = -1; + options->fork_after_authentication = -1; +@@ -2822,8 +2905,37 @@ + options->server_alive_interval = 0; + if (options->server_alive_count_max == -1) + options->server_alive_count_max = 3; ++ if (options->hpn_disabled == -1) ++ options->hpn_disabled = 0; ++ if (options->hpn_buffer_limit == -1) ++ options->hpn_buffer_limit = 0; ++ if (options->tcp_rcv_buf_poll == -1) ++ options->tcp_rcv_buf_poll = 1; ++ if (options->none_switch == -1) ++ options->none_switch = 0; ++ if (options->none_enabled == -1) ++ options->none_enabled = 0; ++ if (options->none_enabled == 0 && options->none_switch > 0) { ++ fprintf(stderr, "NoneEnabled must be enabled to use the None Switch option. None cipher disabled.\n"); ++ options->none_enabled = 0; ++ } ++ if (options->nonemac_enabled == -1) ++ options->nonemac_enabled = 0; ++ if (options->nonemac_enabled > 0 && (options->none_enabled == 0 || ++ options->none_switch == 0)) { ++ fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); ++ options->nonemac_enabled = 0; ++ } ++ if (options->metrics == -1) ++ options->metrics = 0; ++ if (options->metrics_interval == -1) ++ options->metrics_interval = 5; + if (options->control_master == -1) + options->control_master = 0; ++ if (options->fallback == -1) ++ options->fallback = 1; ++ if (options->fallback_port == -1) ++ options->fallback_port = SSH_DEFAULT_PORT; + if (options->control_persist == -1) { + options->control_persist = 0; + options->control_persist_timeout = 0; +diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h +--- openssh-9.6p1.orig/readconf.h 2024-07-10 13:32:39.600111814 +0200 ++++ openssh-9.6p1/readconf.h 2024-07-10 13:34:02.726358612 +0200 +@@ -56,6 +56,9 @@ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int tcp_keep_alive; /* Set SO_KEEPALIVE. */ ++ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ ++ int hpn_disabled; /* Switch to disable HPN buffer management */ ++ int hpn_buffer_limit; /* limit local_window_max to 1/2 receive buffer */ + int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ + int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ + SyslogFacility log_facility; /* Facility for system logging. */ +@@ -129,6 +132,16 @@ + int enable_ssh_keysign; + int64_t rekey_limit; + int rekey_interval; ++ ++ int none_switch; /* Use none cipher */ ++ int none_enabled; /* Allow none to be used */ ++ int nonemac_enabled; /* Allow none to be used */ ++ int metrics; /* enable metrics */ ++ int metrics_interval; /* time in seconds between polls */ ++ char *metrics_path; /* path for the metrics files */ ++ int fallback; /* en|disable fallback port (def: true) */ ++ int fallback_port; /* port to fallback to (def: 22) */ ++ + int no_host_authentication_for_localhost; + int identities_only; + int server_alive_interval; +diff -Nur openssh-9.6p1.orig/README.md openssh-9.6p1/README.md +--- openssh-9.6p1.orig/README.md 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/README.md 2024-07-10 13:34:02.726358612 +0200 +@@ -1,12 +1,16 @@ +-# Portable OpenSSH ++# HPNSSH: Based on Portable OpenSSH + +-[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml) +-[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh) +-[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) ++Starting with version HPN17v0 there will be significant changes to the naming convention used for executables and installation locations. The last version that does not include these changes is HPN16v1 corresponding to the HPN-8_8_P1 tag on the master branch. + +-OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs. ++HPNSSH is a variant of OpenSSH. It a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``hpnssh`` and server ``hpnsshd``, file transfer utilities ``hpnscp`` and ``hpnsftp`` as well as tools for key generation (``hpnssh-keygen``), run-time key storage (``hpnssh-agent``) and a number of supporting programs. It includes numerous performance and functionality enhancements focused on high performance networks and computing envrironments. Complete information can be found in the HPN-README file. + +-This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM). ++It is fully compatible with all compliant implementations of the SSH protocol and OpenSSH in particular. ++ ++This version of HPNSSH is significant departure in terms of naming executables and installation locations. Specifically, all executables are now prefixed with ``hpn``. So ``ssh`` becomes ``hpnssh`` and ``scp`` is now ``hpnscp``. Configuation files and host keys can now be found in ``/etc/hpnssh``. By default ``hpnsshd`` now runs on port 2222 but this is configurable. This change was made in order to prevent installations of hpnssh, particularly from package distributions, from interfering with default installations of OpenSSH. HPNSSH is backwards compatible with all versions of OpenSSH including configuration files, keys, and run time options. Additionally, the client will, by default attempt to connect to port 2222 but will automatically fall back to port 22. This is also user configurable. ++ ++HPNSSH is based on OpenSSH portable. This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM). ++ ++This document will be changing over time to reflect new changes and features. This document is built off of the OpenSSH README.md + + ## Documentation + +@@ -21,15 +25,15 @@ + * [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8) + * [sftp-server(8)](https://man.openbsd.org/sftp-server.8) + +-## Stable Releases ++All options in OpenSSH are respected by HPN-SSH. The man pages for HPN-SSH tools are the same as the name of the tool. + +-Stable release tarballs are available from a number of [download mirrors](https://www.openssh.com/portable.html#downloads). We recommend the use of a stable release for most users. Please read the [release notes](https://www.openssh.com/releasenotes.html) for details of recent changes and potential incompatibilities. ++## Building HPNSSH + +-## Building Portable OpenSSH ++Detailed step by step instructions can be found at https://psc.edu/hpn-ssh-home/ + + ### Dependencies + +-Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers. ++HPNSSH is built using autoconf and make. It requires a working C compiler, standard library and headers. + + ``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. + +@@ -44,8 +48,8 @@ + Releases include a pre-built copy of the ``configure`` script and may be built using: + + ``` +-tar zxvf openssh-X.YpZ.tar.gz +-cd openssh ++tar zxvf hpnssh-X.YpZ.tar.gz ++cd hpnssh + ./configure # [options] + make && make tests + ``` +@@ -57,7 +61,7 @@ + If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: + + ``` +-git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git ++git clone https://github.com/rapier1/hpn-ssh + cd openssh-portable + autoreconf + ./configure +@@ -76,6 +80,7 @@ + ``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp. + ``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported. + ``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support. ++``--with-security-key-builtin`` | Include built-in support for U2F/FIDO2 security keys. This requires [libfido2](https://github.com/Yubico/libfido2) be installed. + + ## Development + +diff -Nur openssh-9.6p1.orig/sandbox-seccomp-filter.c openssh-9.6p1/sandbox-seccomp-filter.c +--- openssh-9.6p1.orig/sandbox-seccomp-filter.c 2024-07-10 13:32:39.558111689 +0200 ++++ openssh-9.6p1/sandbox-seccomp-filter.c 2024-07-10 13:34:02.726358612 +0200 +@@ -295,6 +295,9 @@ + #ifdef __NR_geteuid32 + SC_ALLOW(__NR_geteuid32), + #endif ++#ifdef __NR_getpeername /* not defined on archs that go via socketcall(2) */ ++ SC_ALLOW(__NR_getpeername), ++#endif + #ifdef __NR_getpgid + SC_ALLOW(__NR_getpgid), + #endif +@@ -413,6 +416,9 @@ + #ifdef __NR_sigprocmask + SC_ALLOW(__NR_sigprocmask), + #endif ++#ifdef __NR_socketcall ++ SC_ALLOW(__NR_socketcall), ++#endif + #ifdef __NR_time + SC_ALLOW(__NR_time), + #endif +diff -Nur openssh-9.6p1.orig/scp.1 openssh-9.6p1/scp.1 +--- openssh-9.6p1.orig/scp.1 2024-07-10 13:32:39.528111600 +0200 ++++ openssh-9.6p1/scp.1 2024-07-10 14:33:54.369943270 +0200 +@@ -18,7 +18,7 @@ + .Nd OpenSSH secure file copy + .Sh SYNOPSIS + .Nm scp +-.Op Fl 346ABCOpqRrsTv ++.Op Fl 346ABCOpqRrsTvZ + .Op Fl c Ar cipher + .Op Fl D Ar sftp_server_path + .Op Fl F Ar ssh_config +@@ -252,6 +252,10 @@ + Note that + .Nm + follows symbolic links encountered in the tree traversal. ++.It Fl Z ++Resume failed or interrupted transfer. Identical files will be skipped. Remote must have resume option. ++.Nm ++only option. + .It Fl S Ar program + Name of + .Ar program +@@ -285,10 +289,13 @@ + .It Cm nrequests Ns = Ns Ar value + Controls how many concurrent SFTP read or write requests may be in progress + at any point in time during a download or upload. +-By default 64 requests may be active concurrently. ++This value must be between 1 and 8192. ++By default 1024 requests may be active concurrently. + .It Cm buffer Ns = Ns Ar value + Controls the maximum buffer size for a single SFTP read/write operation used + during download or upload. ++This value must be between 1B and 255KB. You may use ++the K unit for the size. E.g. 32768 or 32K. + By default a 32KB buffer is used. + .El + .El +@@ -322,6 +329,7 @@ + .Sh AUTHORS + .An Timo Rinne Aq Mt tri@iki.fi + .An Tatu Ylonen Aq Mt ylo@cs.hut.fi ++.An Chris Rapier Aq Mt rapier@psc.edu + .Sh CAVEATS + The legacy SCP protocol (selected by the + .Fl O +diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c +--- openssh-9.6p1.orig/scp.c 2024-07-10 13:32:39.530111606 +0200 ++++ openssh-9.6p1/scp.c 2024-07-10 14:15:34.032723487 +0200 +@@ -17,6 +17,7 @@ + /* + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Aaron Campbell. All rights reserved. ++ * Copyright (c) 2021 Chris Rapier. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -133,6 +134,12 @@ + #include "misc.h" + #include "progressmeter.h" + #include "utf8.h" ++/* libressl doesn't support the blake2b512 digest so ++ * we need to prevent libressl from using the resume feature ++ * cjr 7/18/2023 */ ++#if (defined WITH_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER) ++#include ++#endif + #include "sftp.h" + + #include "sftp-common.h" +@@ -175,6 +182,10 @@ + /* This is the program to execute for the secured connection. ("ssh" or -S) */ + char *ssh_program = _PATH_SSH_PROGRAM; + ++/* this is path to the remote scp program allowing the user to specify ++ * a non-default scp */ ++char *remote_path; ++ + /* This is used to store the pid of ssh_program */ + pid_t do_cmd_pid = -1; + pid_t do_cmd_pid2 = -1; +@@ -189,6 +200,17 @@ + int sftp_glob(struct sftp_conn *, const char *, int, + int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ + ++/* Flag to indicate that this is a file resume */ ++int resume_flag = 0; /* 0 is off, 1 is on */ ++ ++/* we want the host name for debugging purposes */ ++char hostname[HOST_NAME_MAX + 1]; ++ ++/* defines for the resume function. Need them even if not supported */ ++#define HASH_LEN 128 /*40 sha1, 64 blake2s256 128 blake2b512*/ ++#define BUF_AND_HASH HASH_LEN + 64 /* length of the hash and other data to get size of buffer */ ++#define HASH_BUFLEN 8192 /* 8192 seems to be a good balance between freads ++ * and the digest func*/ + static void + killchild(int signo) + { +@@ -234,6 +256,9 @@ + int status; + pid_t pid; + ++#ifdef DEBUG ++ fprintf(stderr, "In do_local_cmd\n"); ++#endif + if (a->num == 0) + fatal("do_local_cmd: no arguments"); + +@@ -460,6 +485,8 @@ + void tolocal(int, char *[], enum scp_mode_e, char *sftp_direct); + void toremote(int, char *[], enum scp_mode_e, char *sftp_direct); + void usage(void); ++void calculate_hash(char *, char *, off_t); /*get the hash of file to length*/ ++void rand_str(char *, size_t); /*gen randome char string */ + + void source_sftp(int, char *, char *, struct sftp_conn *); + void sink_sftp(int, char *, const char *, struct sftp_conn *); +@@ -478,11 +505,18 @@ + char *sftp_direct = NULL; + long long llv; + ++ /* we use this to prepend the debugging statements ++ * so we know which side is saying what */ ++ gethostname(hostname, HOST_NAME_MAX + 1); ++ + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + msetlocale(); + ++ /* for use with rand function when resume option is used*/ ++ srand(time(NULL)); ++ + /* Copy argv, because we modify it */ + argv0 = argv[0]; + newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); +@@ -506,7 +540,7 @@ + + fflag = Tflag = tflag = 0; + while ((ch = getopt(argc, argv, +- "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:X:")) != -1) { ++ "12346ABCTdfOpqRrstvZD:F:J:M:P:S:c:i:l:o:X:")) != -1) { + switch (ch) { + /* User-visible flags. */ + case '1': +@@ -587,24 +621,36 @@ + addargs(&remote_remote_args, "-q"); + showprogress = 0; + break; ++#if (defined WITH_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER) ++ case 'Z': ++ /* currently resume only works in SCP mode */ ++ resume_flag = 1; ++ mode = MODE_SCP; ++ break; ++#endif + case 'X': + /* Please keep in sync with sftp.c -X */ + if (strncmp(optarg, "buffer=", 7) == 0) { + r = scan_scaled(optarg + 7, &llv); +- if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { ++ /* don't ask for a buffer larger than the maximum ++ * size that SFTP can handle */ ++ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { + r = -1; + errno = EINVAL; + } + if (r == -1) { +- fatal("Invalid buffer size \"%s\": %s", +- optarg + 7, strerror(errno)); ++ fatal("Invalid buffer size. Must be between 1B and 255KB." ++ "\"%s\": %s", optarg + 7, strerror(errno)); + } + sftp_copy_buflen = (size_t)llv; + } else if (strncmp(optarg, "nrequests=", 10) == 0) { +- llv = strtonum(optarg + 10, 1, 256 * 1024, ++ /* more than 10k to 15k requests starts stalling the connection ++ * 8192 * default buffer size is 256MB of outstanding data. ++ * if users need more then they need to up the buffer size */ ++ llv = strtonum(optarg + 10, 1, 8 * 1024, + &errstr); + if (errstr != NULL) { +- fatal("Invalid number of requests " ++ fatal("Invalid number of requests. Must be between 1 and 8192. " + "\"%s\": %s", optarg + 10, errstr); + } + sftp_nrequests = (size_t)llv; +@@ -692,11 +738,20 @@ + remin = remout = -1; + do_cmd_pid = -1; + /* Command to be executed on remote system using "ssh". */ +- (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", +- verbose_mode ? " -v" : "", +- iamrecursive ? " -r" : "", pflag ? " -p" : "", +- targetshouldbedirectory ? " -d" : ""); +- ++ /* In the event of an hpn to hpn connection the scp ++ * command is rewritten to hpnscp. This happens in ++ * clientloop.c -cjr 12/12/2022 */ ++ ++ (void) snprintf(cmd, sizeof cmd, "%s%s%s%s%s%s", ++ remote_path ? remote_path : "scp", ++ verbose_mode ? " -v" : "", ++ iamrecursive ? " -r" : "", ++ pflag ? " -p" : "", ++ targetshouldbedirectory ? " -d" : "", ++ resume_flag ? " -Z" : ""); ++#ifdef DEBUG ++ fprintf(stderr, "%s: Sending cmd %s\n", hostname, cmd); ++#endif + (void) ssh_signal(SIGPIPE, lostconn); + + if (colon(argv[argc - 1])) /* Dest is remote host. */ +@@ -1321,6 +1376,74 @@ + free(src); + } + ++/* calculate the hash of a file up to length bytes ++ * this is used to determine if remote and local file ++ * fragments match. There may be a more efficient process for the hashing ++ * Note: LibreSSL doesn't support blake2b512 so we can't offer them ++ * the resume feature cjr 7/18/2023 */ ++#if (defined WITH_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER) ++void calculate_hash(char *filename, char *output, off_t length) ++{ ++ int n, md_len; ++ EVP_MD_CTX *c; ++ const EVP_MD *md; ++ char buf[HASH_BUFLEN]; ++ ssize_t bytes; ++ unsigned char out[EVP_MAX_MD_SIZE]; ++ char tmp[3]; ++ FILE *file_ptr; ++ *output = '\0'; ++ ++ /* open file for calculating hash */ ++ file_ptr = fopen(filename, "r"); ++ if (file_ptr==NULL) ++ { ++ if (verbose_mode) { ++ fprintf(stderr, "%s: error opening file %s\n", hostname, filename); ++ /* file the expected output with spaces */ ++ snprintf(output, HASH_LEN, "%s", " "); ++ } ++ return; ++ } ++ ++ md = EVP_get_digestbyname("blake2b512"); ++ c = EVP_MD_CTX_new(); ++ EVP_DigestInit_ex(c, md, NULL); ++ ++ while (length > 0) { ++ if (length > HASH_BUFLEN) ++ /* fread returns the number of elements read. ++ * in this case 1. Multiply by the length to get the bytes */ ++ bytes=fread(buf, HASH_BUFLEN, 1, file_ptr) * HASH_BUFLEN; ++ else ++ bytes=fread(buf, length, 1, file_ptr) * length; ++ EVP_DigestUpdate(c, buf, bytes); ++ length -= HASH_BUFLEN; ++ } ++ EVP_DigestFinal(c, out, &md_len); ++ EVP_MD_CTX_free(c); ++ /* convert the hash into a string */ ++ for(n=0; n < md_len; n++) { ++ snprintf(tmp, 3, "%02x", out[n]); ++ strncat(output, tmp, 3); ++ } ++#ifdef DEBUG ++ fprintf(stderr, "%s: HASH IS '%s' of length %ld\n", hostname, output, strlen(output)); ++#endif ++ fclose(file_ptr); ++} ++#else ++void calculate_hash(char *filename, char *output, off_t length) ++{ ++ /* empty function for builds without openssl or are using libressl */ ++} ++#endif /* WITH_OPENSSL */ ++ ++#define TYPE_OVERFLOW(type, val) \ ++ ((sizeof(type) == 4 && (val) > INT32_MAX) || \ ++ (sizeof(type) == 8 && (val) > INT64_MAX) || \ ++ (sizeof(type) != 4 && sizeof(type) != 8)) ++ + /* Prepare remote path, handling ~ by assuming cwd is the homedir */ + static char * + prepare_remote_path(struct sftp_conn *conn, const char *path) +@@ -1404,14 +1527,23 @@ + struct stat stb; + static BUF buffer; + BUF *bp; +- off_t i, statbytes; ++ off_t i, statbytes, xfer_size; + size_t amt, nr; + int fd = -1, haderr, indx; +- char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX]; ++ char *cp, *last, *name, buf[PATH_MAX + BUF_AND_HASH], encname[PATH_MAX]; + int len; ++ char hashsum[HASH_LEN+1], test_hashsum[HASH_LEN+1]; ++ char inbuf[PATH_MAX + BUF_AND_HASH]; ++ size_t insize; ++ unsigned long long ull; ++ char *match; /* used to communicate fragment match */ ++ match = "\0"; /*default is to fail the match. NULL and F both indicate fail*/ + + for (indx = 0; indx < argc; ++indx) { + name = argv[indx]; ++#ifdef DEBUG ++ fprintf(stderr, "%s index is %d, name is %s\n", hostname, indx, name); ++#endif + statbytes = 0; + len = strlen(name); + while (len > 1 && name[len-1] == '/') +@@ -1433,6 +1565,14 @@ + unset_nonblock(fd); + switch (stb.st_mode & S_IFMT) { + case S_IFREG: ++ /* only calculate hash if we are in resume mode and a file*/ ++ if (resume_flag) { ++ calculate_hash(name, hashsum, stb.st_size); ++#ifdef DEBUG ++ fprintf(stderr, "%s: Name is '%s' and hash '%s'\n", hostname, name, hashsum); ++ fprintf (stderr,"%s: size of %s is %ld\n", hostname, name, stb.st_size); ++#endif ++ } + break; + case S_IFDIR: + if (iamrecursive) { +@@ -1454,14 +1594,133 @@ + goto next; + } + #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) +- snprintf(buf, sizeof buf, "C%04o %lld %s\n", +- (u_int) (stb.st_mode & FILEMODEMASK), +- (long long)stb.st_size, last); +- if (verbose_mode) +- fmprintf(stderr, "Sending file modes: %s", buf); ++ /* Add a hash of the file along with the filemode if in resume */ ++ if (resume_flag) ++ snprintf(buf, sizeof buf, "C%04o %lld %s %s\n", ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, hashsum, last); ++ else ++ snprintf(buf, sizeof buf, "C%04o %lld %s\n", ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, last); ++ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Sending file modes: %s", hostname, buf); ++#endif + (void) atomicio(vwrite, remout, buf, strlen(buf)); +- if (response() < 0) ++ ++#ifdef DEBUG ++ fprintf(stderr, "%s: inbuf length %ld buf length %ld\n", hostname, strlen(inbuf), strlen(buf)); ++#endif ++ if (resume_flag) { /* get the hash response from the remote */ ++ (void) atomicio(read, remin, inbuf, BUF_AND_HASH - 1); ++#ifdef DEBUG ++ fprintf(stderr, "%s: we got '%s' in inbuf length %ld buf was %ld\n", ++ hostname, inbuf, strlen(inbuf), strlen(buf)); ++#endif ++ } ++ if (response() < 0) { ++#ifdef DEBUG ++ fprintf(stderr, "%s: response is less than 0\n", hostname); ++#endif + goto next; ++ } ++ xfer_size = stb.st_size; ++ ++ /* we only do the following in resume mode because we have a ++ * new buf from the remote to parse */ ++ if (resume_flag) { ++ cp = inbuf; ++ if (*cp == 'R') { /* resume file transfer*/ ++ char *in_hashsum; /* where to hold the incoming hash */ ++ in_hashsum = calloc(HASH_LEN+1, sizeof(char)); ++ for (++cp; cp < inbuf + 5; cp++) { ++ /* skip over the mode */ ++ } ++ if (*cp++ != ' ') { ++ fprintf(stderr, "%s: mode not delineated!\n", hostname); ++ } ++ ++ if (!isdigit((unsigned char)*cp)) ++ fprintf(stderr, "%s: size not present\n", hostname); ++ ull = strtoull(cp, &cp, 10); ++ if (!cp || *cp++ != ' ') ++ fprintf(stderr, "%s: size not delimited\n", hostname); ++ if (TYPE_OVERFLOW(off_t, ull)) ++ fprintf(stderr, "%s: size out of range\n", hostname); ++ insize = (off_t)ull; ++ ++#ifdef DEBUG ++ fprintf (stderr, "%s: received size of %ld\n", hostname, insize); ++#endif ++ ++ /* copy the cp pointer byte by byte */ ++ int i; ++ for (i = 0; i < HASH_LEN; i++) { ++ strncat(in_hashsum, cp++, 1); ++ } ++#ifdef DEBUG ++ fprintf (stderr, "%s: in_hashsum '%s'\n", hostname, in_hashsum); ++#endif ++ ++ /*get the hash of the source file to the byte length we just got*/ ++ calculate_hash(name, test_hashsum, insize); ++#ifdef DEBUG ++ fprintf(stderr, "%s: calculated hashsum of local %s to %ld is %s\n", ++ hostname, last, insize, test_hashsum); ++#endif ++ /* compare the incoming hash to the hash of the local file*/ ++ if (strcmp(in_hashsum, test_hashsum) == 0) { ++ /* the fragments match so we should seek to the appropriate place in the ++ * local file and set the remote file to append */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: File fragments match\n", hostname); ++ fprintf(stderr, "%s: seeking to %ld\n", hostname, insize); ++#endif ++ xfer_size = stb.st_size - insize; ++#ifdef DEBUG ++ fprintf(stderr, "%s: xfer_size: %ld, stb.st_size: %ld insize: %ld\n", ++ hostname, xfer_size, stb.st_size, insize); ++#endif ++ if (lseek(fd, insize, SEEK_CUR) != (off_t)insize) { ++#ifdef DEBUG ++ fprintf(stderr, "%s: lseek did not return %ld\n", hostname, insize) ; ++#endif ++ goto next; ++ } ++ match = "M"; ++ } else { ++ /* the fragments don't match so we should start over from the begining */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: File fragments do not match '%s'(in) '%s'(local)\n", ++ hostname, in_hashsum, test_hashsum); ++#endif ++ match = "F"; ++ xfer_size = stb.st_size; ++ } ++ free(in_hashsum); ++ } ++ if (*cp == 'S') { /* skip file */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Should be skipping this file\n", hostname); ++#endif ++ goto next; ++ } ++ if (*cp == 'C') { /*transfer entire file*/ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Resending entire file\n", hostname); ++#endif ++ xfer_size = stb.st_size; ++ } ++ /* need to send the match status ++ * We always send the match status or we get out of sync ++ */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: sending match %s\n", hostname, match); ++#endif ++ (void) atomicio(vwrite, remout, match, 1); ++ } ++ + if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { + next: if (fd != -1) { + (void) close(fd); +@@ -1469,13 +1728,17 @@ + } + continue; + } ++ ++#ifdef DEBUG ++ fprintf(stderr, "%s: going to xfer %ld\n", hostname, xfer_size); ++#endif + if (showprogress) +- start_progress_meter(curfile, stb.st_size, &statbytes); ++ start_progress_meter(curfile, xfer_size, &statbytes); + set_nonblock(remout); +- for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { ++ for (haderr = i = 0; i < xfer_size; i += bp->cnt) { + amt = bp->cnt; +- if (i + (off_t)amt > stb.st_size) +- amt = stb.st_size - i; ++ if (i + (off_t)amt > xfer_size) ++ amt = xfer_size - i; + if (!haderr) { + if ((nr = atomicio(read, fd, + bp->buf, amt)) != amt) { +@@ -1672,24 +1935,36 @@ + sink(int argc, char **argv, const char *src) + { + static BUF buffer; +- struct stat stb; ++ struct stat stb, cpstat, npstat; + BUF *bp; + off_t i; + size_t j, count; + int amt, exists, first, ofd; + mode_t mode, omode, mask; +- off_t size, statbytes; ++ off_t size, statbytes, xfer_size; + unsigned long long ull; + int setimes, targisdir, wrerr; +- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; ++ char ch, *cp, *np, *np_tmp, *targ, *why, *vect[1], buf[16384], visbuf[16384]; + char **patterns = NULL; + size_t n, npatterns = 0; + struct timeval tv[2]; ++ char remote_hashsum[HASH_LEN+1]; ++ char local_hashsum[HASH_LEN+1]; ++ char tmpbuf[BUF_AND_HASH]; ++ char outbuf[BUF_AND_HASH]; ++ char match; ++ int bad_match_flag = 0; ++ np = NULL; /* this was originally '/0' but that's wrong */ ++ np_tmp = NULL; ++ + + #define atime tv[0] + #define mtime tv[1] + #define SCREWUP(str) { why = str; goto screwup; } + ++#ifdef DEBUG ++ fprintf (stderr, "%s: LOCAL In sink with %s\n", hostname, src); ++#endif + if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) + SCREWUP("Unexpected off_t/time_t size"); + +@@ -1705,9 +1980,16 @@ + if (targetshouldbedirectory) + verifydir(targ); + ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n",hostname); ++#endif + (void) atomicio(vwrite, remout, "", 1); + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) + targisdir = 1; ++ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Target is %s with a size of %ld\n", hostname, targ, stb.st_size); ++#endif + if (src != NULL && !iamrecursive && !Tflag) { + /* + * Prepare to try to restrict incoming filenames to match +@@ -1716,7 +1998,12 @@ + if (brace_expand(src, &patterns, &npatterns) != 0) + fatal_f("could not expand pattern"); + } ++ + for (first = 1;; first = 0) { ++ bad_match_flag = 0; /* used in resume mode. */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: At start of loop buf is %s\n", hostname, buf); ++#endif + cp = buf; + if (atomicio(read, remin, cp, 1) != 1) + goto done; +@@ -1744,6 +2031,9 @@ + continue; + } + if (buf[0] == 'E') { ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n", hostname); ++#endif + (void) atomicio(vwrite, remout, "", 1); + goto done; + } +@@ -1751,6 +2041,9 @@ + *--cp = 0; + + cp = buf; ++#ifdef DEBUG ++ fprintf(stderr, "%s: buf is %s\n", hostname, buf); ++#endif + if (*cp == 'T') { + setimes++; + cp++; +@@ -1778,9 +2071,19 @@ + if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || + atime.tv_usec > 999999) + SCREWUP("atime.usec not delimited"); ++ ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n", hostname); ++#endif + (void) atomicio(vwrite, remout, "", 1); + continue; + } ++ if (*cp == 'R') { /*resume file transfer (dont' think I need this here)*/ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Received a RESUME request with %s\n", hostname, cp); ++#endif ++ resume_flag = 1; ++ } + if (*cp != 'C' && *cp != 'D') { + /* + * Check for the case "rcp remote:foo\* local:bar". +@@ -1796,6 +2099,18 @@ + SCREWUP("expected control record"); + } + mode = 0; ++#ifdef DEBUG ++ fprintf(stderr, "%s: buf is %s\n", hostname, buf); ++ fprintf(stderr, "%s: cp is %s\n", hostname, cp); ++#endif ++ /* we need to track if this object is a directory ++ * before we move the pointer. If we are in resume mode ++ * we might end up trying to get an mdsum on a directory ++ * and that doesn't work */ ++ int dir_flag = 0; ++ if (*cp == 'D') ++ dir_flag = 1; ++ + for (++cp; cp < buf + 5; cp++) { + if (*cp < '0' || *cp > '7') + SCREWUP("bad mode"); +@@ -1806,6 +2121,10 @@ + if (*cp++ != ' ') + SCREWUP("mode not delimited"); + ++#ifdef DEBUG ++ fprintf(stderr, "%s: cp is %s\n", hostname, cp); ++#endif ++ + if (!isdigit((unsigned char)*cp)) + SCREWUP("size not present"); + ull = strtoull(cp, &cp, 10); +@@ -1815,11 +2134,32 @@ + SCREWUP("size out of range"); + size = (off_t)ull; + ++#ifdef DEBUG ++ fprintf(stderr, "%s: cp is %s\n", hostname, cp); ++#endif ++ if (resume_flag && !dir_flag) { ++ *remote_hashsum = '\0'; ++ int i; ++ for (i = 0; i < HASH_LEN; i++) { ++ strncat (remote_hashsum, cp++, 1); ++ } ++#ifdef DEBUG ++ fprintf (stderr, "%s: '%s'\n", hostname, remote_hashsum); ++#endif ++ if (!cp || *cp++ != ' ') ++ SCREWUP("hash not delimited"); ++ } ++#ifdef DEBUG ++ fprintf(stderr, "%s: cp is %s\n", hostname, cp); ++#endif + if (*cp == '\0' || strchr(cp, '/') != NULL || + strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { + run_err("error: unexpected filename: %s", cp); + exit(1); + } ++#ifdef DEBUG ++ fprintf(stderr, "%s cp is %s\n", hostname, cp); ++#endif + if (npatterns > 0) { + for (n = 0; n < npatterns; n++) { + if (strcmp(patterns[n], cp) == 0 || +@@ -1889,11 +2229,195 @@ + } + omode = mode; + mode |= S_IWUSR; ++ stat(cp, &cpstat); ++ xfer_size = size; ++ if (resume_flag) { ++#ifdef DEBUG ++ fprintf(stderr, "%s: np is %s\n", hostname, np); ++#endif ++ /* does the file exist and if it does it writable? */ ++ if (stat(np, &npstat) == -1) { ++#ifdef DEBUG ++ fprintf(stderr, "%s Local file does not exist size is %ld!\n", ++ hostname, npstat.st_size); ++#endif ++ npstat.st_size = 0; ++ } else { ++ /* check to see if the file is writeable ++ * if it isn't then we need to skip it but ++ * before we skip it we need to send the remote ++ * what they are expecting so BUF_AND_HASH bytes and then ++ * a null. ++ * NOTE!!! The format in the snprintf needs the actual numeric ++ * because using a define isn't working */ ++ if (access (np, W_OK) != 0) { ++ fprintf(stderr, "scp: %s: Permission denied on %s\n", np, hostname); ++ snprintf(outbuf, BUF_AND_HASH, "S%-*s", BUF_AND_HASH-2, " "); ++ (void)atomicio(vwrite, remout, outbuf, strlen(outbuf)); ++ (void)atomicio(vwrite, remout, "", 1); ++ continue; ++ } ++ } ++ /* this file is already here do we need to move it? ++ * Check to make sure npstat.st_size > 0. If it is 0 then we ++ * may trying to be moving a zero byte file in which case this ++ * following block fails. See on 0 byte files the hashes will ++ * always match and the file won't be created even though it should ++ */ ++ if (xfer_size == npstat.st_size && (npstat.st_size > 0)) { ++ calculate_hash(np, local_hashsum, npstat.st_size); ++ if (strcmp(local_hashsum,remote_hashsum) == 0) { ++ /* we can skip this file if we want to. */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Files are the same\n", hostname); ++#endif ++ /* the remote is expecting something so we need to send them something*/ ++ snprintf(outbuf, BUF_AND_HASH, "S%-*s", BUF_AND_HASH-2, " "); ++ (void)atomicio(vwrite, remout, outbuf, strlen(outbuf)); ++#ifdef DEBUG ++ fprintf(stderr,"%s: sent '%s' to remote\n", hostname, outbuf); ++#endif ++ /* the remote is waiting on an ack so send a null */ ++ (void)atomicio(vwrite, remout, "", 1); ++ if (showprogress) ++ fprintf (stderr, "Skipping identical file: %s\n", np); ++ continue; ++ } else { ++ /* file sizes are the same but they don't match */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: target(%ld) is different than source(%ld)!\n", ++ hostname, npstat.st_size, size); ++#endif ++ snprintf(tmpbuf, sizeof outbuf, "C%04o %lld %s", ++ (u_int) (npstat.st_mode & FILEMODEMASK), ++ (long long)npstat.st_size, local_hashsum); ++ snprintf(outbuf, BUF_AND_HASH, "%-*s", BUF_AND_HASH-1, tmpbuf); ++ (void) atomicio(vwrite, remout, outbuf, strlen(outbuf)); ++ bad_match_flag = 1; ++ } ++ } ++ /* if npstat.st_size is 0 then the local file doesn't exist and ++ * we have to move it. Since we are in resume mode treat it as a resume */ ++ if (npstat.st_size < xfer_size || (npstat.st_size == 0)) { ++ char rand_string[9]; ++#ifdef DEBUG ++ fprintf (stderr, "%s: %s is smaller than %s\n", hostname, np, cp); ++#endif ++ calculate_hash(np, local_hashsum, npstat.st_size); ++#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) ++ snprintf(tmpbuf, sizeof outbuf, "R%04o %lld %s", ++ (u_int) (npstat.st_mode & FILEMODEMASK), ++ (long long)npstat.st_size, local_hashsum); ++ snprintf(outbuf, BUF_AND_HASH, "%-*s", BUF_AND_HASH-1, tmpbuf); ++#ifdef DEBUG ++ fprintf (stderr, "%s: new buf is %s of length %ld\n", ++ hostname, outbuf, strlen(outbuf)); ++ fprintf(stderr, "%s: Sending new file (%s) modes: %s\n", ++ hostname, np, outbuf); ++#endif ++ /*now we have to send np's length and hash to the other end ++ * if the computed hashes match then we seek to np's length in ++ * file and append to np starting from there */ ++ (void) atomicio(vwrite, remout, outbuf, strlen(outbuf)); ++#ifdef DEBUG ++ fprintf(stderr, "%s: New size: %ld, size: %ld, st_size: %ld\n", ++ hostname, size - npstat.st_size, size, npstat.st_size); ++#endif ++ xfer_size = size - npstat.st_size; ++ resume_flag = 1; ++ np_tmp = xstrdup(np); ++ /* We should have a random component to avoid clobbering a ++ * local file */ ++ rand_str(rand_string, 8); ++ strcat(np, rand_string); ++#ifdef DEBUG ++ fprintf(stderr, "%s: Will concat %s to %s after xfer\n", ++ hostname, np, np_tmp); ++#endif ++ } else if (npstat.st_size > size) { ++ /* the target file is larger than the source. ++ * so we need to overwrite it. We don't need to send the hash though. */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: target(%ld) is larger than source(%ld)!\n", ++ hostname, npstat.st_size, size); ++#endif ++ snprintf(tmpbuf, sizeof outbuf, "C%04o %lld", ++ (u_int) (npstat.st_mode & FILEMODEMASK), ++ (long long)npstat.st_size); ++ snprintf(outbuf, BUF_AND_HASH, "%-*s", BUF_AND_HASH-1, tmpbuf); ++ (void) atomicio(vwrite, remout, outbuf, strlen(outbuf)); ++ bad_match_flag = 1; ++ } ++ ++#ifdef DEBUG ++ fprintf (stderr, "%s: CP is %s(%ld) NP is %s(%ld)\n", ++ hostname, cp, size, np, npstat.st_size); ++#endif ++ /* we are in resume mode so we need this *here* and not later ++ * because we need to get the file match information from the remote ++ * outside of resume mode we don't get that so we get out of sync ++ * so we have a test for the resume_flag after this block */ ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n", hostname); ++#endif ++ (void) atomicio(vwrite, remout, "", 1); ++ ++ /* the remote is always going to send a match status ++ * so we need to read it so we don't get out of sync */ ++ (void) atomicio(read, remin, &match, 1); ++ if (match != 'M') {/*fragments do not match*/ ++ /* expected response of F, M and NULL *but* ++ * anything other than M is a failure ++ * if it's a NULL then we reset xfer_size but ++ * we retain the file pointers */ ++ xfer_size = size; ++ bad_match_flag = 1; ++ if (match == 'F') { ++ /* got an F for failure and not NULL ++ * so we want to swap over the filename from ++ * the temp back to the original */ ++#ifdef DEBUG ++ fprintf(stderr, "%s: match status is F\n", hostname); ++#endif ++ if (np_tmp != NULL) ++ np = np_tmp; ++ else { ++ continue; ++ } ++ } else { ++#ifdef DEBUG ++ fprintf(stderr, "%s: match received is NULL\n", hostname); ++#endif ++ } ++ } else { ++#ifdef DEBUG ++ fprintf(stderr, "%s match status is M\n", hostname); ++#endif ++ bad_match_flag = 0; /* while this is set at the beginning of the ++ * loop I'm setting it here explicitly as well */ ++ } ++ } ++ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Creating file. mode is %d for %s\n", ++ hostname, mode, np); ++#endif + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { + bad: run_err("%s: %s", np, strerror(errno)); + continue; + } +- (void) atomicio(vwrite, remout, "", 1); ++ ++ /* in the case of not using the resume function we need this vwrite here ++ * in the case of using the resume flag it comes in the above if (resume_flag) block ++ * why? because scp is weird and depends on an intricate and silly dance of ++ * call and response at just the right time. That's why */ ++ if (!resume_flag) { ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n", hostname); ++#endif ++ (void) atomicio(vwrite, remout, "", 1); ++ } ++ + if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { + (void) close(ofd); + continue; +@@ -1908,13 +2432,17 @@ + */ + statbytes = 0; + if (showprogress) +- start_progress_meter(curfile, size, &statbytes); ++ start_progress_meter(curfile, xfer_size, &statbytes); + set_nonblock(remin); +- for (count = i = 0; i < size; i += bp->cnt) { ++#ifdef DEBUG ++ fprintf(stderr, "%s: xfer_size is %ld\n", hostname, xfer_size); ++#endif ++ for (count = i = 0; i < xfer_size; i += bp->cnt) { + amt = bp->cnt; +- if (i + amt > size) +- amt = size - i; ++ if (i + amt > xfer_size) ++ amt = xfer_size - i; + count += amt; ++ /* read the data from the socket*/ + do { + j = atomicio6(read, remin, cp, amt, + scpio, &statbytes); +@@ -1949,8 +2477,78 @@ + wrerr = 1; + } + if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && +- ftruncate(ofd, size) != 0) ++ ftruncate(ofd, xfer_size) != 0) + note_err("%s: truncate: %s", np, strerror(errno)); ++ ++ /* if np_tmp isn't set then we don't have a resume file to cat */ ++ /* likewise, bad match flag means no resume flag */ ++#ifdef DEBUG ++ fprintf (stderr, "%s: resume_flag: %d, np_tmp: %s, bad_match_flag: %d\n", ++ hostname, resume_flag, np_tmp, bad_match_flag); ++#endif ++ if (resume_flag && np_tmp && !bad_match_flag) { ++ FILE *orig, *resume; ++ char res_buf[512]; /* set at 512 just because, might want to increase*/ ++ ssize_t res_bytes = 0; ++ off_t sum = 0; ++ struct stat res_stat; ++ *res_buf = '\0'; ++ orig = NULL; /*supress warnings*/ ++ resume = NULL; /*supress warnings*/ ++#ifdef DEBUG ++ fprintf(stderr, "%s: Resume flag is set. Going to concat %s to %s now\n", ++ hostname, np, np_tmp); ++#endif ++ /* np/ofd is the resume file so open np_tmp for appending ++ * close ofd because we are going to be shifting it ++ * and I don't wnat the same file open in multiple descriptors */ ++ if (close(ofd) == -1) ++ note_err("%s: close: %s", np, strerror(errno)); ++ /* orig is the target file, resume is the temp file */ ++ orig = fopen(np_tmp, "a"); /*open for appending*/ ++ if (orig == NULL) { ++ fprintf(stderr, "%s: Could not open %s for appending.", hostname, np_tmp); ++ goto stopcat; ++ } ++ resume = fopen(np, "r"); /*open for reading only*/ ++ if (resume == NULL) { ++ fprintf(stderr, "%s: Could not open %s for reading.", hostname, np); ++ goto stopcat; ++ } ++ /* get the number of bytes in the temp file*/ ++ if (fstat(fileno(resume), &res_stat) == -1) { ++ fprintf(stderr, "%s: Could not stat %s", hostname, np); ++ goto stopcat; ++ } ++ /* while the number of bytes read from the temp file ++ * is less than the size of the file read in a chunk and ++ * write it to the target file */ ++ do { ++ res_bytes = fread(res_buf, 1, 512, resume); ++ fwrite(res_buf, 1, res_bytes, orig); ++ sum += res_bytes; ++ } while (sum < res_stat.st_size); ++ ++stopcat: if (orig) ++ fclose(orig); ++ if (resume) ++ fclose(resume); ++ /* delete the resume file */ ++ remove(np); ++#ifdef DEBUG ++ fprintf (stderr, "%s: np(%s) and np_tmp(%s)\n", hostname, np, np_tmp); ++#endif ++ np = np_tmp; ++#ifdef DEBUG ++ fprintf (stderr, "%s np(%s) and np_tmp(%s)\n", hostname, np, np_tmp); ++#endif ++ /* reset ofd to the original np */ ++ if ((ofd = open(np_tmp, O_WRONLY)) == -1) { ++ fprintf(stderr, "%s: couldn't open %s in append function\n", hostname, np_tmp); ++ atomicio(vwrite, remout, "", 1); ++ goto bad; ++ } ++ } + if (pflag) { + if (exists || omode != mode) + #ifdef HAVE_FCHMOD +@@ -1985,8 +2583,17 @@ + } + } + /* If no error was noted then signal success for this file */ +- if (note_err(NULL) == 0) ++ if (note_err(NULL) == 0) { ++#ifdef DEBUG ++ fprintf (stderr, "%s: Sending null to remout.\n", hostname); ++#endif + (void) atomicio(vwrite, remout, "", 1); ++ } ++ /* we are in resume mode and we have allocated memory for np_tmp */ ++ if (resume_flag && np_tmp != NULL) { ++ free(np_tmp); ++ np_tmp = NULL; ++ } + } + done: + for (n = 0; n < npatterns; n++) +@@ -2130,11 +2737,19 @@ + void + usage(void) + { ++#if (defined WITH_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER) ++ (void) fprintf(stderr, ++ "usage: scp [-346ABCOpqRrsTvZ] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" ++ " [-i identity_file] [-J destination] [-l limit] [-o ssh_option]\n" ++ " [-P port] [-S program] [-X sftp_option] source ... target\n"); ++ exit(1); ++#else + (void) fprintf(stderr, + "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" + " [-i identity_file] [-J destination] [-l limit] [-o ssh_option]\n" + " [-P port] [-S program] [-X sftp_option] source ... target\n"); + exit(1); ++#endif + } + + void +@@ -2273,6 +2888,18 @@ + exit(1); + } + ++void rand_str(char *dest, size_t length) { ++ char charset[] = "0123456789" ++ "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ++ ++ while (length-- > 0) { ++ size_t index = (double) rand() / RAND_MAX * (sizeof charset - 1); ++ *dest++ = charset[index]; ++ } ++ *dest = '\0'; ++} ++ + void + cleanup_exit(int i) + { +diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c +--- openssh-9.6p1.orig/servconf.c 2024-07-10 13:32:39.601111817 +0200 ++++ openssh-9.6p1/servconf.c 2024-07-10 14:16:52.654947762 +0200 +@@ -199,6 +199,11 @@ + options->authorized_principals_file = NULL; + options->authorized_principals_command = NULL; + options->authorized_principals_command_user = NULL; ++ options->tcp_rcv_buf_poll = -1; ++ options->hpn_disabled = -1; ++ options->none_enabled = -1; ++ options->nonemac_enabled = -1; ++ options->hpn_buffer_limit = -1; + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; +@@ -464,6 +469,18 @@ + } + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; ++ if (options->none_enabled == -1) ++ options->none_enabled = 0; ++ if (options->nonemac_enabled == -1) ++ options->nonemac_enabled = 0; ++ if (options->nonemac_enabled > 0 && options->none_enabled == 0) { ++ debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); ++ options->nonemac_enabled = 0; ++ } ++ if (options->hpn_disabled == -1) ++ options->hpn_disabled = 0; ++ if (options->hpn_buffer_limit == -1) ++ options->hpn_buffer_limit = 0; + if (options->ip_qos_interactive == -1) + options->ip_qos_interactive = IPTOS_DSCP_AF21; + if (options->ip_qos_bulk == -1) +@@ -545,6 +562,8 @@ + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, ++ sNoneEnabled, sNoneMacEnabled, sHPNBufferLimit, ++ sTcpRcvBufPoll, sHPNDisabled, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitUserEnvironment, sAllowTcpForwarding, sCompression, +@@ -746,6 +765,11 @@ + { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, + { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, + { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, ++ { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, ++ { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, ++ { "noneenabled", sNoneEnabled, SSHCFG_ALL }, ++ { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, ++ { "hpnbufferlimit", sHPNBufferLimit, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "include", sInclude, SSHCFG_ALL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, +@@ -808,6 +832,7 @@ + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) { ++ debug("Config token is %s", keywords[i].name); + *flags = keywords[i].flags; + return keywords[i].opcode; + } +@@ -1604,12 +1629,32 @@ + multistate_ptr = multistate_ignore_rhosts; + goto parse_multistate; + ++ case sTcpRcvBufPoll: ++ intptr = &options->tcp_rcv_buf_poll; ++ goto parse_flag; ++ ++ case sHPNDisabled: ++ intptr = &options->hpn_disabled; ++ goto parse_flag; ++ + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + parse_flag: + multistate_ptr = multistate_flag; + goto parse_multistate; + ++ case sNoneEnabled: ++ intptr = &options->none_enabled; ++ goto parse_flag; ++ ++ case sNoneMacEnabled: ++ intptr = &options->nonemac_enabled; ++ goto parse_flag; ++ ++ case sHPNBufferLimit: ++ intptr = &options->hpn_buffer_limit; ++ goto parse_flag; ++ + case sHostbasedAuthentication: + intptr = &options->hostbased_authentication; + goto parse_flag; +diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h +--- openssh-9.6p1.orig/servconf.h 2024-07-10 13:32:39.601111817 +0200 ++++ openssh-9.6p1/servconf.h 2024-07-10 13:34:02.728358618 +0200 +@@ -211,6 +211,11 @@ + + int use_pam; /* Enable auth via PAM */ + int permit_pam_user_change; /* Allow PAM to change user name */ ++ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ ++ int hpn_disabled; /* disable hpn functionality. false by default */ ++ int none_enabled; /* Enable NONE cipher switch */ ++ int nonemac_enabled; /* Enable NONE MAC switch */ ++ int hpn_buffer_limit; /* limit local_window_max to 1/2 receive buffer */ + + int permit_tun; + +diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c +--- openssh-9.6p1.orig/serverloop.c 2024-07-10 13:32:39.588111779 +0200 ++++ openssh-9.6p1/serverloop.c 2024-07-10 14:18:04.600152988 +0200 +@@ -81,6 +81,8 @@ + #include "serverloop.h" + #include "ssherr.h" + #include "compat.h" ++#include "metrics.h" ++#include "cipher-switch.h" + + extern ServerOptions options; + +@@ -347,6 +349,7 @@ + sigset_t bsigset, osigset; + + debug("Entering interactive session for SSH2."); ++ ssh->start_time = monotime_double(); + + if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) + error_f("bsigset setup: %s", strerror(errno)); +@@ -385,7 +388,9 @@ + error_f("osigset sigprocmask: %s", strerror(errno)); + + if (received_sigterm) { ++ sshpkt_final_log_entry(ssh); + logit("Exiting on signal %d", (int)received_sigterm); ++ sshpkt_final_log_entry(ssh); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } +@@ -403,9 +408,15 @@ + collect_children(ssh); + free(pfd); + ++ /* write final log entry */ ++ sshpkt_final_log_entry(ssh); ++ + /* free all channels, no more reads and writes */ + channel_free_all(ssh); + ++ /* final entry must come after channels close -cjr */ ++ sshpkt_final_log_entry(ssh); ++ + /* free remaining sessions, e.g. remove wtmp entries */ + session_destroy_all(ssh, NULL); + } +@@ -607,6 +618,10 @@ + c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, + -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, + 0, "server-session", 1); ++ if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled)) ++ c->dynamic_window = 1; ++ if (options.hpn_buffer_limit) ++ c->hpn_buffer_limit = 1; + if (session_open(the_authctxt, c->self) != 1) { + debug("session open failed, free channel %d", c->self); + channel_free(ssh, c); +@@ -675,6 +690,67 @@ + return 0; + } + ++/* we need to get the actual socket in use and from there ++ * read the values in the TCP_INFO struct. ++ * shout out to Rene Pfiffer for the article https://linuxgazette.net/136/pfeiffer.html ++ * for getting me started. This only works on systems that support the tcp_info ++ * struct; linux, freebsd, netbsd as of now. Apple has one but it's completely different ++ * than any of the others. ++ */ ++static int ++server_input_metrics_request(struct ssh *ssh, struct sshbuf **respp) ++{ ++ int success = 0; ++ /* TCP_INFO is defined in metrics.h ++ * if it's not defined then we don't support tcp_info ++ * so just return a failure code */ ++#if !defined TCP_INFO ++ return success; ++#else ++ struct tcp_info tcp_info; ++ struct sshbuf *resp = NULL; ++ int tcp_info_len; ++ /* this is the socket of the current connection */ ++ int sock_in = ssh_packet_get_connection_in(ssh); ++ int r; ++ binn *metricsobj; ++ ++ tcp_info_len = sizeof(tcp_info); /*expect around 330 bytes */ ++ if ((resp = sshbuf_new()) == NULL) ++ fatal_f("sshbuf_new"); ++ ++ /* create the binn object to hold the serialized metrics */ ++ metricsobj = binn_object(); ++ if (metricsobj == NULL) { ++ error_f("Could not create metrics object"); ++ goto out; ++ } ++ ++ debug("Stack metrics request for connection %d", sock_in); ++ if ((r = getsockopt(sock_in, IPPROTO_TCP, TCP_INFO, (void *)&tcp_info, ++ (socklen_t *)&tcp_info_len)) != 0) { ++ error_f("Could not read tcp_info from socket"); ++ goto out; ++ } ++ /* write the tcp_info data to the binn object */ ++ metrics_write_binn_object(&tcp_info, metricsobj); ++ if ((r = sshbuf_put_string(resp, binn_ptr(metricsobj), ++ binn_size(metricsobj))) != 0) { ++ error_fr(r, "Failed to build tcp_info object"); ++ goto out; ++ } ++ /* copy the pointer of the response to the passed in response pointer */ ++ *respp = resp; ++ resp = NULL; /* don't free it */ ++ /* everything worked so set success to true */ ++ success = 1; ++out: ++ sshbuf_free(resp); ++ binn_free(metricsobj); ++ return success; ++#endif /* TCP_INFO */ ++} ++ + static int + server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) + { +@@ -854,6 +930,10 @@ + success = 1; + } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { + success = server_input_hostkeys_prove(ssh, &resp); ++ } else if (strcmp(rtype, "stack-metrics@hpnssh.org") == 0) { ++ /* resp is the response (sshbuf struct) from the function which is ++ * handled below in the want_reply stanza */ ++ success = server_input_metrics_request(ssh, &resp); + } + /* XXX sshpkt_get_end() */ + if (want_reply) { +diff -Nur openssh-9.6p1.orig/session.c openssh-9.6p1/session.c +--- openssh-9.6p1.orig/session.c 2024-07-10 13:32:39.552111672 +0200 ++++ openssh-9.6p1/session.c 2024-07-10 13:34:02.729358621 +0200 +@@ -94,6 +94,7 @@ + #include "monitor_wrap.h" + #include "sftp.h" + #include "atomicio.h" ++#include "cipher-switch.h" + + #if defined(KRB5) && defined(USE_AFS) + #include +@@ -226,6 +227,7 @@ + goto authsock_err; + + /* Allocate a channel for the authentication agent socket. */ ++ /* this shouldn't matter if its hpn or not - cjr */ + nc = channel_new(ssh, "auth-listener", + SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, +@@ -553,6 +555,8 @@ + session_set_fds(ssh, s, inout[1], inout[1], err[1], + s->is_subsystem, 0); + #endif ++ /* switch to the parallel ciphers if necessary */ ++ cipher_switch(ssh); + return 0; + } + +@@ -666,6 +670,8 @@ + ssh_packet_set_interactive(ssh, 1, + options.ip_qos_interactive, options.ip_qos_bulk); + session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); ++ /* switch to the parallel cipher if appropriate */ ++ cipher_switch(ssh); + return 0; + } + +@@ -2884,4 +2890,3 @@ + remote = ssh_remote_ipaddr(ssh); + return remote; + } +- +diff -Nur openssh-9.6p1.orig/sftp.1 openssh-9.6p1/sftp.1 +--- openssh-9.6p1.orig/sftp.1 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/sftp.1 2024-07-10 13:34:02.730358624 +0200 +@@ -299,7 +299,8 @@ + Specify how many requests may be outstanding at any one time. + Increasing this may slightly improve file transfer speed + but will increase memory usage. +-The default is 64 outstanding requests. ++The default is 1024 outstanding requests providing for 32MB ++of outstanding data with a 32KB buffer. + .It Fl r + Recursively copy entire directories when uploading and downloading. + Note that +@@ -328,10 +329,13 @@ + .It Cm nrequests Ns = Ns Ar value + Controls how many concurrent SFTP read or write requests may be in progress + at any point in time during a download or upload. +-By default 64 requests may be active concurrently. ++This value must be between 1 and 8192. ++By default 1024 requests may be active concurrently. + .It Cm buffer Ns = Ns Ar value + Controls the maximum buffer size for a single SFTP read/write operation used + during download or upload. ++This value must be between 1B and 255KB. You may use ++the K unit for the size. E.g. 32768 or 32K. + By default a 32KB buffer is used. + .El + .El +diff -Nur openssh-9.6p1.orig/sftp.c openssh-9.6p1/sftp.c +--- openssh-9.6p1.orig/sftp.c 2024-07-10 13:32:39.531111609 +0200 ++++ openssh-9.6p1/sftp.c 2024-07-10 14:19:56.850473846 +0200 +@@ -2562,23 +2562,28 @@ + replacearg(&args, 0, "%s", ssh_program); + break; + case 'X': +- /* Please keep in sync with ssh.c -X */ ++ /* Please keep in sync with scp.c -X */ + if (strncmp(optarg, "buffer=", 7) == 0) { + r = scan_scaled(optarg + 7, &llv); +- if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { ++ /* don't ask for a buffer larger than the maximum ++ * size that SFTP can handle */ ++ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { + r = -1; + errno = EINVAL; + } + if (r == -1) { +- fatal("Invalid buffer size \"%s\": %s", +- optarg + 7, strerror(errno)); ++ fatal("Invalid buffer size. Must be between 1B and 255KB." ++ "\"%s\": %s", optarg + 7, strerror(errno)); + } + copy_buffer_len = (size_t)llv; + } else if (strncmp(optarg, "nrequests=", 10) == 0) { +- llv = strtonum(optarg + 10, 1, 256 * 1024, ++ /* more than 10k to 15k requests starts stalling the connection ++ * 8192 * default buffer size is 256MB of outstanding data. ++ * if users need more then they need to up the buffer size */ ++ llv = strtonum(optarg + 10, 1, 8 * 1024, + &errstr); + if (errstr != NULL) { +- fatal("Invalid number of requests " ++ fatal("Invalid number of requests. Must be between 1 and 8192. " + "\"%s\": %s", optarg + 10, errstr); + } + num_requests = (size_t)llv; +diff -Nur openssh-9.6p1.orig/sftp-client.c openssh-9.6p1/sftp-client.c +--- openssh-9.6p1.orig/sftp-client.c 2024-07-10 13:32:39.531111609 +0200 ++++ openssh-9.6p1/sftp-client.c 2024-07-10 13:34:02.731358627 +0200 +@@ -72,7 +72,8 @@ + #define DEFAULT_COPY_BUFLEN 32768 + + /* Default number of concurrent xfer requests (fix sftp.1 scp.1 if changed) */ +-#define DEFAULT_NUM_REQUESTS 64 ++/* 1024 xfer requests gives us 32MB of receive buffer space */ ++#define DEFAULT_NUM_REQUESTS 1024 + + /* Minimum amount of data to read at a time */ + #define MIN_READ_SIZE 512 +diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 +--- openssh-9.6p1.orig/ssh.1 2024-07-10 13:32:39.601111817 +0200 ++++ openssh-9.6p1/ssh.1 2024-07-10 13:34:02.731358627 +0200 +@@ -524,6 +524,7 @@ + .It ControlMaster + .It ControlPath + .It ControlPersist ++.It DisableMTAES* + .It DynamicForward + .It EnableSSHKeysign + .It EnableEscapeCommandline +@@ -552,6 +553,8 @@ + .It HostKeyAlgorithms + .It HostKeyAlias + .It Hostname ++.It HPNDisabled* ++.It HPNBufferLimit* + .It IdentitiesOnly + .It IdentityAgent + .It IdentityFile +@@ -568,7 +571,13 @@ + .It LogVerbose + .It MACs + .It Match ++.It Metrics ++.It MetricsInterval ++.It MetricsPath + .It NoHostAuthenticationForLocalhost ++.It NoneCipherEnabled* ++.It NoneEnabled* ++.It NoneMacEnabled* + .It NumberOfPasswordPrompts + .It PasswordAuthentication + .It PermitLocalCommand +@@ -599,6 +608,7 @@ + .It StrictHostKeyChecking + .It SyslogFacility + .It TCPKeepAlive ++.It TcpRcvBufPoll* + .It Tunnel + .It TunnelDevice + .It UpdateHostKeys +@@ -607,6 +617,8 @@ + .It VerifyHostKeyDNS + .It VisualHostKey + .It XAuthLocation ++.Pp ++.It * Hpnssh specific configuration option. + .El + .Pp + .It Fl P Ar tag +@@ -1825,3 +1837,7 @@ + created OpenSSH. + Markus Friedl contributed the support for SSH + protocol versions 1.5 and 2.0. ++Chris Rapier, Michael Stevens, Ben Bennet, and Mike Tasota developed ++the HPN extensions at the Pittsburgh Supercomuting Center with grants ++from Cisco, the National Library of Medicine, and the National Science ++Foundation. +diff -Nur openssh-9.6p1.orig/ssh_api.c openssh-9.6p1/ssh_api.c +--- openssh-9.6p1.orig/ssh_api.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh_api.c 2024-07-10 13:34:02.732358630 +0200 +@@ -410,7 +410,7 @@ + char *cp; + int r; + +- if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_VERSION)) != 0) ++ if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_RELEASE)) != 0) + return r; + if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) + return r; +diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c +--- openssh-9.6p1.orig/sshbuf.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/sshbuf.c 2024-07-10 13:34:02.732358630 +0200 +@@ -27,6 +27,20 @@ + #define SSHBUF_INTERNAL + #include "sshbuf.h" + #include "misc.h" ++/* #include "log.h" */ ++ ++#define BUF_WATERSHED 256*1024 ++ ++#ifdef SSHBUF_DEBUG ++# define SSHBUF_TELL(what) do { \ ++ printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \ ++ __FILE__, __LINE__, __func__, what, \ ++ buf->size, buf->alloc, buf->off, buf->max_size); \ ++ fflush(stdout); \ ++ } while (0) ++#else ++# define SSHBUF_TELL(what) ++#endif + + #ifdef SSHBUF_DEBUG + # define SSHBUF_TELL(what) do { \ +@@ -45,12 +59,27 @@ + size_t off; /* First available byte is buf->d + buf->off */ + size_t size; /* Last byte is buf->d + buf->size - 1 */ + size_t max_size; /* Maximum size of buffer */ ++ size_t window_max; /* channel window max */ + size_t alloc; /* Total bytes allocated to buf->d */ + int readonly; /* Refers to external, const data */ + u_int refcount; /* Tracks self and number of child buffers */ + struct sshbuf *parent; /* If child, pointer to parent */ ++ char label[MAX_LABEL_LEN]; /* String for buffer label - debugging use */ ++ struct timeval buf_ts; /* creation time of buffer */ + }; + ++void ++sshbuf_relabel(struct sshbuf *buf, const char *label) ++{ ++ if (label != NULL) ++ strncpy(buf->label, label, MAX_LABEL_LEN-1); ++} ++ ++float time_diff(struct timeval *start, struct timeval *end) ++{ ++ return (end->tv_sec - start->tv_sec) + 1e-6*(end->tv_usec - start->tv_usec); ++} ++ + static inline int + sshbuf_check_sanity(const struct sshbuf *buf) + { +@@ -89,7 +118,7 @@ + } + + struct sshbuf * +-sshbuf_new(void) ++sshbuf_new_label (const char *label) + { + struct sshbuf *ret; + +@@ -100,6 +129,8 @@ + ret->readonly = 0; + ret->refcount = 1; + ret->parent = NULL; ++ if (label != NULL) ++ strncpy(ret->label, label, MAX_LABEL_LEN-1); + if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) { + free(ret); + return NULL; +@@ -218,7 +249,7 @@ + size_t + sshbuf_max_size(const struct sshbuf *buf) + { +- return buf->max_size; ++ return buf->max_size / 2; + } + + size_t +@@ -240,13 +271,18 @@ + } + + int +-sshbuf_set_max_size(struct sshbuf *buf, size_t max_size) ++sshbuf_set_max_size(struct sshbuf *buf, size_t requested_size) + { +- size_t rlen; ++ size_t rlen, max_size = requested_size * 2; + u_char *dp; + int r; + +- SSHBUF_DBG(("set max buf = %p len = %zu", buf, max_size)); ++ /* ++ * Note that we set the actual allocation limit to be 2x the requested ++ * size. This is to avoid some pathological compaction behaviour later ++ * when a buffer is at capacity and has small drains/fills on it. ++ */ ++ SSHBUF_DBG(("set max buf = %p requested = %zu", buf, requested_size)); + if ((r = sshbuf_check_sanity(buf)) != 0) + return r; + if (max_size == buf->max_size) +@@ -255,9 +291,17 @@ + return SSH_ERR_BUFFER_READ_ONLY; + if (max_size > SSHBUF_SIZE_MAX) + return SSH_ERR_NO_BUFFER_SPACE; +- /* pack and realloc if necessary */ +- sshbuf_maybe_pack(buf, max_size < buf->size); +- if (max_size < buf->alloc && max_size > buf->size) { ++ /* ++ * Always pack as it makes everything that follows easier. ++ * Potentially expensive, but this should seldom be called on buffers ++ * that already contain data. ++ */ ++ sshbuf_maybe_pack(buf, 1); ++ /* Refuse setting a maximum below current amount of data in buffer */ ++ if (requested_size < buf->size) ++ return SSH_ERR_NO_BUFFER_SPACE; ++ /* Shrink alloc if the existing allocation is larger than requested */ ++ if (requested_size < buf->alloc) { + if (buf->size < SSHBUF_SIZE_INIT) + rlen = SSHBUF_SIZE_INIT; + else +@@ -271,8 +315,6 @@ + buf->alloc = rlen; + } + SSHBUF_TELL("new-max"); +- if (max_size < buf->alloc) +- return SSH_ERR_NO_BUFFER_SPACE; + buf->max_size = max_size; + return 0; + } +@@ -290,7 +332,7 @@ + { + if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1) + return 0; +- return buf->max_size - (buf->size - buf->off); ++ return (buf->max_size / 2) - (buf->size - buf->off); + } + + const u_char * +@@ -320,11 +362,18 @@ + return SSH_ERR_BUFFER_READ_ONLY; + SSHBUF_TELL("check"); + /* Check that len is reasonable and that max_size + available < len */ +- if (len > buf->max_size || buf->max_size - len < buf->size - buf->off) ++ if (len > (buf->max_size / 2) || ++ (buf->max_size / 2) - len < buf->size - buf->off) + return SSH_ERR_NO_BUFFER_SPACE; + return 0; + } + ++void ++sshbuf_set_window_max(struct sshbuf *buf, size_t len) ++{ ++ buf->window_max = len; ++} ++ + int + sshbuf_allocate(struct sshbuf *buf, size_t len) + { +@@ -350,9 +399,42 @@ + */ + need = len + buf->size - buf->alloc; + rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC); ++ /* With the changes in 8.9 the output buffer end up growing pretty ++ * slowly. It's knows that it needs to grow but it only does so 32K ++ * at a time. This means a lot of calls to realloc and memcpy which ++ * kills performance until the buffer reaches some maximum size. ++ * so we explicitly test for a buffer that's trying to grow and ++ * if it is then we push the growth to whatever the adjusted value of ++ * local_window_max happens to be. This significantly reduces overhead ++ * and improves performance. In this case we look for a buffer that is trying ++ * to grow larger than BUF_WATERSHED (256*1024 taken from PACKET_MAX_SIZE) ++ * and where the local_window_max isn't zero (which is usally in the Channels ++ * struct but we copied it into the shhbuf as window_max). If it is zero or ++ * the buffer is smaller than BUF_WATERSHED we just use the ++ * normal value for need. We also don't want to grow the buffer past ++ * what we need (the size of window_max) so if the current allocation (in ++ * buf->alloc) is greater than window_max we skip it. ++ * ++ * Turns out the extra functions on the following conditional aren't needed ++ * -cjr 04/06/23 ++ */ ++ if (rlen > BUF_WATERSHED) { ++ /* debug_f ("Prior: label: %s, %p, rlen is %zu need is %zu win_max is %zu max_size is %zu", ++ buf->label, buf, rlen, need, buf->window_max, buf->max_size); */ ++ /* easiest thing to do is grow the nuffer by 4MB each time. It might end ++ * up being somewhat overallocated but works quickly */ ++ need = (4*1024*1024); ++ rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC); ++ /* debug_f ("Post: label: %s, %p, rlen is %zu need is %zu win_max is %zu max_size is %zu", */ ++ /* buf->label, buf, rlen, need, buf->window_max, buf->max_size); */ ++ } + SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen)); +- if (rlen > buf->max_size) +- rlen = buf->alloc + need; ++ ++ /* rlen might be above the max allocation */ ++ if (rlen > buf->max_size) { ++ rlen = buf->max_size; ++ /* debug_f("set rlen to %zu", buf->max_size);*/ ++ } + SSHBUF_DBG(("adjusted rlen %zu", rlen)); + if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) { + SSHBUF_DBG(("realloc fail")); +diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h +--- openssh-9.6p1.orig/sshbuf.h 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/sshbuf.h 2024-07-10 13:34:02.732358630 +0200 +@@ -28,10 +28,12 @@ + # endif /* OPENSSL_HAS_ECC */ + #endif /* WITH_OPENSSL */ + +-#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ ++#define SSHBUF_SIZE_MAX 0xFFFFFFF /* Hard maximum size 256MB */ + #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ + #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ + #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ ++#define MAX_LABEL_LEN 64 /*maximum size of sshbuf label */ ++#define sshbuf_new() sshbuf_new_label(__func__) + + struct sshbuf; + +@@ -39,7 +41,18 @@ + * Create a new sshbuf buffer. + * Returns pointer to buffer on success, or NULL on allocation failure. + */ +-struct sshbuf *sshbuf_new(void); ++/* struct sshbuf *sshbuf_new(void); */ ++ ++/* ++ * Create a new labeled sshbuf buffer. ++ * Returns pointer to buffer on success, or NULL on allocation failure. ++ */ ++struct sshbuf *sshbuf_new_label(const char *); ++ ++/* ++ * relabel the sshbuf struct ++ */ ++void sshbuf_relabel(struct sshbuf *, const char *); + + /* + * Create a new, read-only sshbuf buffer from existing data. +@@ -75,12 +88,13 @@ + void sshbuf_reset(struct sshbuf *buf); + + /* +- * Return the maximum size of buf ++ * Return the maximum usable size of buf + */ + size_t sshbuf_max_size(const struct sshbuf *buf); + + /* +- * Set the maximum size of buf ++ * Set the maximum usable size of buf. Note that the buffer may consume up ++ * to 2x this memory plus bookkeeping overhead. + * Returns 0 on success, or a negative SSH_ERR_* error code on failure. + */ + int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size); +@@ -344,6 +358,9 @@ + ((u_char *)(p))[1] = __v & 0xff; \ + } while (0) + ++ ++void sshbuf_set_window_max(struct sshbuf *buf , size_t len); ++ + /* Internal definitions follow. Exposed for regress tests */ + #ifdef SSHBUF_INTERNAL + +diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c +--- openssh-9.6p1.orig/ssh.c 2024-07-10 13:32:39.602111820 +0200 ++++ openssh-9.6p1/ssh.c 2024-07-10 13:34:02.733358633 +0200 +@@ -109,6 +109,7 @@ + #include "ssherr.h" + #include "myproposal.h" + #include "utf8.h" ++#include "cipher-switch.h" + + #ifdef ENABLE_PKCS11 + #include "ssh-pkcs11.h" +@@ -1113,6 +1114,10 @@ + break; + case 'T': + options.request_tty = REQUEST_TTY_NO; ++ /* ensure that the user doesn't try to backdoor a */ ++ /* null cipher switch on an interactive session */ ++ /* so explicitly disable it no matter what */ ++ options.none_switch=0; + break; + case 'o': + line = xstrdup(optarg); +@@ -1682,10 +1687,36 @@ + } + + /* Open a connection to the remote host. */ ++ /* we try initially on the default hpnssh port returned by ++ * default_ssh_port() which now returns HPNSSH_DEFAULT_PORT ++ * if that fails we reset the port to SSH_DEFAULT_PORT ++ * -cjr 8/17/2022 ++ */ ++tryagain: + if (ssh_connect(ssh, host, options.host_arg, addrs, &hostaddr, + options.port, options.connection_attempts, +- &timeout_ms, options.tcp_keep_alive) != 0) ++ &timeout_ms, options.tcp_keep_alive) != 0) { ++ /* could not connect. If the port requested is the same as ++ * hpnssh default port then fallback. Otherwise, exit */ ++ if ((options.port == default_ssh_port()) && options.fallback) { ++ int port = options.fallback_port; ++ options.port = port; ++ fprintf(stderr, "HPNSSH server not available on default port %d\n", ++ default_ssh_port()); ++ if (port == 22) ++ fprintf(stderr, "Falling back to OpenSSH default port %d\n", ++ port); ++ else ++ fprintf(stderr, "Falling back to user defined port %d\n", ++ port); ++ addrs = resolve_host(host, port, 1, ++ cname, sizeof(cname)); ++ goto tryagain; ++ } else { ++ exit(255); ++ } + exit(255); ++ } + + if (addrs != NULL) + freeaddrinfo(addrs); +@@ -1892,7 +1923,7 @@ + + /* Do fork() after authentication. Used by "ssh -f" */ + static void +-fork_postauth(void) ++fork_postauth(struct ssh *ssh) + { + if (need_controlpersist_detach) + control_persist_detach(); +@@ -1902,17 +1933,20 @@ + fatal("daemon() failed: %.200s", strerror(errno)); + if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1) + error_f("stdfd_devnull failed"); ++ /* we do the cipher switch here in the event that the client ++ is forking or has a delayed fork */ ++ cipher_switch(ssh); + } + + static void +-forwarding_success(void) ++forwarding_success(struct ssh *ssh) + { + if (forward_confirms_pending == -1) + return; + if (--forward_confirms_pending == 0) { + debug_f("all expected forwarding replies received"); + if (options.fork_after_authentication) +- fork_postauth(); ++ fork_postauth(ssh); + } else { + debug2_f("%d expected forwarding replies remaining", + forward_confirms_pending); +@@ -1979,7 +2013,7 @@ + "for listen port %d", rfwd->listen_port); + } + } +- forwarding_success(); ++ forwarding_success(ssh); + } + + static void +@@ -2006,7 +2040,7 @@ + } + + debug_f("tunnel forward established, id=%d", id); +- forwarding_success(); ++ forwarding_success(ssh); + } + + static void +@@ -2207,6 +2241,15 @@ + NULL, fileno(stdin), command, environ); + } + ++/* this used to do a lot more but now it just checks to see ++ * if we are disabling hpn */ ++static void ++hpn_options_init(struct ssh *ssh) ++{ ++ channel_set_hpn_disabled(options.hpn_disabled); ++ debug_f("HPN disabled: %d", options.hpn_disabled); ++} ++ + /* open new channel for a session */ + static int + ssh_session2_open(struct ssh *ssh) +@@ -2228,6 +2271,7 @@ + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (tty_flag) { ++ window = CHAN_SES_WINDOW_DEFAULT; + window >>= 1; + packetmax >>= 1; + } +@@ -2236,6 +2280,16 @@ + window, packetmax, CHAN_EXTENDED_WRITE, + "client-session", CHANNEL_NONBLOCK_STDIO); + ++ /* TODO: Is this the right place for these options? */ ++ if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) { ++ c->dynamic_window = 1; ++ debug("Enabled Dynamic Window Scaling"); ++ } ++ ++ if (options.hpn_buffer_limit) ++ c->hpn_buffer_limit = 1; ++ ++ + debug3_f("channel_new: %d", c->self); + + channel_send_open(ssh, c->self); +@@ -2252,6 +2306,13 @@ + int r, interactive, id = -1; + char *cp, *tun_fwd_ifname = NULL; + ++ /* ++ * We need to initialize this early because the forwarding logic below ++ * might open channels that use the hpn buffer sizes. We can't send a ++ * window of -1 (the default) to the server as it breaks things. ++ */ ++ hpn_options_init(ssh); ++ + /* XXX should be pre-session */ + if (!options.control_persist) + ssh_init_stdio_forwarding(ssh); +@@ -2350,7 +2411,13 @@ + debug("deferring postauth fork until remote forward " + "confirmation received"); + } else +- fork_postauth(); ++ fork_postauth(ssh); ++ } else { ++ /* check to see if we are switching ciphers to ++ * one of our parallel versions. If the client is ++ * forking then we handle it in fork_postauth() ++ */ ++ cipher_switch(ssh); + } + + return client_loop(ssh, tty_flag, tty_flag ? +diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1.orig/ssh_config.5 2024-07-10 13:32:39.603111823 +0200 ++++ openssh-9.6p1/ssh_config.5 2024-07-10 13:34:02.734358636 +0200 +@@ -62,6 +62,19 @@ + .Pq Pa /etc/ssh/ssh_config + .El + .Pp ++.Xr hpnssh 1 ++is fully compatible with OpenSSH's ssh and uses the same configuration format, directives, and options. ++.Xr hpnssh 1 ++can use the same configuration file as ++.Xr ssh 1 ++though the inverse is not necessarily true. This is because ++.Xr hpnssh 1 ++has some additional options which are discussed below. As such users should either not ++use ++.Xr hpnssh 1 ++specific directives in their default ssh_config files or ensure that they always use a ++custom config file. ++.Pp + Unless noted otherwise, for each parameter, the first obtained value + will be used. + The configuration files contain sections separated by +@@ -700,6 +713,11 @@ + then the backgrounded master connection will automatically terminate + after it has remained idle (with no client connections) for the + specified time. ++.It Cm DisableMTAES ++Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher ++back to the stock single-threaded AES-CTR cipher. This may prove to be more ++effcient in some circumstances. Default is ++.Cm no. HPNSSH only. + .It Cm DynamicForward + Specifies that a TCP port on the local machine be forwarded + over the secure channel, and the application +@@ -1111,6 +1129,20 @@ + .Cm Hostname + specifications). + The default is the name given on the command line. ++.It Cm HPNDisabled ++In some situations, such as transfers on a local area network, the impact ++of the HPN code produces a net decrease in performance. In these cases it is ++helpful to disable the HPN functionality. By default HPNDisabled is set to ++.Cm no. HPNSSH only. ++.It Cm HPNBufferLimit ++This option will force the hpnssh receive buffer to grow more slowly and limits ++the growth to one half of the TCP receive buffer. This option can prove useful ++in situation where a high speed path with larger RTTs are writing to a slower ++device or file system. Enabling this option will reduce performance but may provide ++a more stable connection. The option only impacts the receiving side of the connection. ++For example, a client receiving data from a server but not a client sending data. ++By default this option is set to ++.Cm no. HPNSSH only. + .It Cm IdentitiesOnly + Specifies that + .Xr ssh 1 +@@ -1484,6 +1516,63 @@ + .Pp + The list of available MAC algorithms may also be obtained using + .Qq ssh -Q mac . ++.It Cm Metrics ++Indicate that the ssh client should gather and write TCP stack metrics from the ++TCP_INFO socket structure on compliant operating systems to a text file. ++These metrics will be collected from both the local and remote hosts if metrics ++are supported by the version of SSH and TCP_INFO is supported by the ++operating system. Currently operating system support is limited to Linux ++version 3.7 and greater, NetBSD, and FreeBSD (version 6 or greater). ++ ++If one of the hosts does not support the Metrics option then only data ++from the the host that does will be reported. See the HPN-README file ++for more detail. ++ ++The argument to the keyword must be ++.Cm yes ++or ++.Cm no ++(the default). ++ ++See ++.Cm MetricsInterval ++and ++.Cm MetricsPath ++for more metrics options. ++.Cm HPNSSH only. ++.It Cm MetricsInterval ++The frequency, in seconds, with which the TCP_INFO struct will be polled. The ++default value is 5 seconds. ++ ++.Cm Metrics ++must be set to ++.Cm yes ++fot this option to have any effect. ++.Cm HPNSSH only. ++.It Cm MetricsPath ++The file path where ++.Cm Metrics ++should write the TCP stack metrics. ++ ++The default is ++.Sm off ++.Ar ./ssh_stack_metrics.local ++ and ++.Ar ./ssh_stack_metrics.remote ++.Sm on ++ ++The user may specify any other filepath and filename that they have write ++access to. E.g. MetricsPath=/tmp/my_metrics. The suffix of .local ++and .remote will be appended to this path. Files are ++.Cm not ++overwritten by subsequent metrics sessions. Instead, data from new sessions ++will be appended if the file already exists. ++ ++.Cm Metrics ++must be set to ++.Cm yes ++fot this option to have any effect. ++.Cm HPNSSH only. + .It Cm NoHostAuthenticationForLocalhost + Disable host authentication for localhost (loopback addresses). + The argument to this keyword must be +@@ -1491,6 +1580,36 @@ + or + .Cm no + (the default). ++.It Cm NoneEnabled ++Enable or disable the use of the None cipher. Care must always be used ++when enabling this as it will allow users to send data in the clear. However, ++it is important to note that authentication information remains encrypted ++even if this option is enabled. Default is ++.Cm no. HPNSSH only. ++.It Cm NoneMacEnabled ++Enable or disable the use of the None MAC. When this is enabled ssh ++will *not* provide data integrity of any data being transmitted between hosts. Use ++with caution as it, unlike just using NoneEnabled, doesn't provide data integrity and ++protection against man-in-the-middle attacks. As with NoneEnabled all authentication ++remains encrypted and integrity is ensured. Default is ++.Cm no. HPNSSH only. ++.It Cm NoneSwitch ++Switch the encryption cipher being used to the None cipher after ++authentication takes place. NoneEnabled must be enabled on both the client ++and server side of the connection. When the connection switches to the NONE ++cipher a warning is sent to STDERR. The connection attempt will fail with an ++error if a client requests a NoneSwitch from the server that does not explicitly ++have NoneEnabled set to yes. Note: The NONE cipher cannot be used in ++interactive (shell) sessions and it will fail silently. Set to ++.Cm no ++by default. ++.Cm HPNSSH only. ++.Pp ++.Cm Note: ++this options cannot actualy be set in the ssh_config file. It must be ++set on the command line use -oNoneEnabled. This is to prevent it from being ++used accidentally. It is included here for completeness as neither NoneMacEnabled ++or NoneCipherEnabled have any effect without this option. + .It Cm NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. + The argument to this keyword must be an integer. +@@ -2048,6 +2167,12 @@ + Specify a configuration tag name that may be later used by a + .Cm Match + directive to select a block of configuration. ++.It Cm TcpRcvBufPoll ++Enable of disable the polling of the tcp receive buffer through the life ++of the connection. You would want to make sure that this option is enabled ++for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista). ++Default is ++.Cm yes. HPNSSH only. + .It Cm Tunnel + Request + .Xr tun 4 +@@ -2404,3 +2529,11 @@ + created OpenSSH. + .An Markus Friedl + contributed the support for SSH protocol versions 1.5 and 2.0. ++.An Chris Rapier, ++.An Michael Stevens, ++.An Ben Bennet, ++and ++.An Mike Tasota ++developed the HPN extensions at the Pittsburgh Supercomuting Center ++with grants from Cisco, the National Library of Medicine, and ++the National Science Foundation. +diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c +--- openssh-9.6p1.orig/sshconnect2.c 2024-07-10 13:32:39.603111823 +0200 ++++ openssh-9.6p1/sshconnect2.c 2024-07-10 13:34:02.734358636 +0200 +@@ -76,6 +76,7 @@ + #include "utf8.h" + #include "ssh-sk.h" + #include "sk-api.h" ++#include "cipher-switch.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -85,6 +86,13 @@ + extern Options options; + + /* ++ * tty_flag is set in ssh.c. Use this in ssh_userauth2: ++ * if it is set, then prevent the switch to the null cipher. ++ */ ++ ++extern int tty_flag; ++ ++/* + * SSH2 key exchange + */ + +@@ -582,6 +590,42 @@ + + if (!authctxt.success) + fatal("Authentication failed."); ++ ++ /* ++ * If the user wants to use the none cipher and/or none mac, do it post authentication ++ * and only if the right conditions are met -- both of the NONE commands ++ * must be true and there must be no tty allocated. ++ */ ++ if (options.none_switch == 1 && options.none_enabled == 1) { ++ char *myproposal[PROPOSAL_MAX]; ++ char *s = NULL; ++ const char *none_cipher = "none"; ++ if (!tty_flag) { /* no null on tty sessions */ ++ debug("Requesting none rekeying..."); ++ kex_proposal_populate_entries(ssh, myproposal, s, none_cipher, ++ options.macs, ++ compression_alg_list(options.compression), ++ options.hostkeyalgorithms); ++ fprintf(stderr, "WARNING: ENABLED NONE CIPHER!!!\n"); ++ ++ /* NONEMAC can only be used in context of the NONE CIPHER */ ++ if (options.nonemac_enabled == 1) { ++ const char *none_mac = "none"; ++ kex_proposal_populate_entries(ssh, myproposal, s, none_cipher, ++ none_mac, ++ compression_alg_list(options.compression), ++ options.hostkeyalgorithms); ++ fprintf(stderr, "WARNING: ENABLED NONE MAC\n"); ++ } ++ kex_prop2buf(ssh->kex->my, myproposal); ++ packet_request_rekeying(); ++ } else { ++ /* requested NONE cipher when in a tty */ ++ debug("Cannot switch to NONE cipher with tty allocated"); ++ fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); ++ } ++ } ++ + if (ssh_packet_connection_is_on_socket(ssh)) { + verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), +diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 +--- openssh-9.6p1.orig/sshd.8 2024-07-10 13:32:39.603111823 +0200 ++++ openssh-9.6p1/sshd.8 2024-07-10 13:34:02.734358636 +0200 +@@ -1078,3 +1078,7 @@ + protocol versions 1.5 and 2.0. + Niels Provos and Markus Friedl contributed support + for privilege separation. ++Chris Rapier, Michael Stevens, Ben Bennet, and Mike Tasota developed ++the HPN extensions at the Pittsburgh Supercomuting Center with grants ++from Cisco, the National Library of Medicine, and the National Science ++Foundation. +diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c +--- openssh-9.6p1.orig/sshd.c 2024-07-10 13:32:39.604111826 +0200 ++++ openssh-9.6p1/sshd.c 2024-07-10 13:34:02.735358639 +0200 +@@ -1093,6 +1093,8 @@ + int ret, listen_sock; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; ++ int socksize; ++ int socksizelen = sizeof(int); + + for (ai = la->addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) +@@ -1138,6 +1140,10 @@ + + debug("Bind to port %s on %s.", strport, ntop); + ++ getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, ++ &socksize, &socksizelen); ++ debug("Server TCP RWIN socket size: %d", socksize); ++ + /* Bind the socket to the desired port. */ + if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { + error("Bind to port %s on %s failed: %.200s.", +@@ -1876,6 +1882,19 @@ + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + ++ if (options.none_enabled == 1) { ++ char *old_ciphers = options.ciphers; ++ xasprintf(&options.ciphers, "%s,none", old_ciphers); ++ free(old_ciphers); ++ ++ /* only enable the none MAC in context of the none cipher -cjr */ ++ if (options.nonemac_enabled == 1) { ++ char *old_macs = options.macs; ++ xasprintf(&options.macs, "%s,none", old_macs); ++ free(old_macs); ++ } ++ } ++ + /* Check that options are sensible */ + if (options.authorized_keys_command_user == NULL && + (options.authorized_keys_command != NULL && +@@ -2359,6 +2378,9 @@ + rdomain == NULL ? "" : "\""); + free(laddr); + ++ /* set the HPN options for the child */ ++ channel_set_hpn_disabled(options.hpn_disabled); ++ + /* + * We don't want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is +@@ -2545,6 +2567,11 @@ + struct kex *kex; + int r; + ++ if (options.none_enabled == 1) ++ debug("WARNING: None cipher enabled"); ++ if (options.nonemac_enabled == 1) ++ debug("WARNING: None MAC enabled"); ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config +--- openssh-9.6p1.orig/sshd_config 2024-07-10 13:32:39.604111826 +0200 ++++ openssh-9.6p1/sshd_config 2024-07-10 13:34:02.735358639 +0200 +@@ -19,6 +19,7 @@ + # semanage port -a -t ssh_port_t -p tcp #PORTNUMBER + # + #Port 22 ++Port 2222 + #AddressFamily any + #ListenAddress 0.0.0.0 + #ListenAddress :: +@@ -127,6 +128,24 @@ + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + ++# the following are HPN related configuration options ++# tcp receive buffer polling. disable in non autotuning kernels ++#TcpRcvBufPoll yes ++ ++# disable hpn performance boosts ++#HPNDisabled no ++ ++# allow the use of the none cipher ++#NoneEnabled no ++ ++# allow the use of the none MAC ++#NoneMacEnabled no ++ ++# clamp the server's receive buffer to ++# 1/2 the tcp receive window. This may be useful ++# in some environments. ++#HPNBufferLimit no ++ + # Example of overriding settings on a per-user basis + #Match User anoncvs + # X11Forwarding no +diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 +--- openssh-9.6p1.orig/sshd_config.5 2024-07-10 13:32:39.605111829 +0200 ++++ openssh-9.6p1/sshd_config.5 2024-07-10 13:34:02.736358642 +0200 +@@ -56,6 +56,16 @@ + .Pq \&" + in order to represent arguments containing spaces. + .Pp ++.Xr hpnsshd 8 ++is fully compatible with OpenSSH's sshd and uses the same configuration format, directives, and options. ++.Xr hpnsshd 8 ++can use the same configuration file as ++.Xr sshd 8 ++though the inverse is not necessarily true. This is because ++.Xr hpnssh 8 ++has some additional options which are discussed below. As such administrators should maintain ++seperate configuration files for each. ++.Pp + The possible + keywords and their meanings are as follows (note that + keywords are case-insensitive and arguments are case-sensitive): +@@ -659,6 +669,10 @@ + TCP and StreamLocal. + This option overrides all other forwarding-related options and may + simplify restricted configurations. ++.It Cm DisableMTAES ++Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher ++back to the stock single-threaded AES-CTR cipher. Default is ++.Cm no. HPNSSH only. + .It Cm ExposeAuthInfo + Writes a temporary file containing a list of authentication methods and + public credentials (e.g. keys) used to authenticate the user. +@@ -892,6 +906,21 @@ + The default for this option is: + The list of available signature algorithms may also be obtained using + .Qq ssh -Q HostKeyAlgorithms . ++.It Cm HPNDisabled ++In some situations, such as transfers on a local area network, the impact ++of the HPN code produces a net decrease in performance. In these cases it is ++helpful to disable the HPN functionality. By default HPNDisabled is set to ++.CM no. ++.It Cm HPNBufferLimit ++This option will force the hpnssh receive buffer to grow more slowly and limits ++the growth to one half of the TCP receive buffer. This option can prove useful ++in situation where a high speed path with larger RTTs are writing to a slower ++device or file system. Enabling this option will reduce performance but may provide ++a more stable connection. The option only impacts the receiving side of the connection. ++For example, a client receiving data from a server but not a client sending data. If ++enabled on a server this will impact all incoming connections. ++By default this option is set to ++.Cm no. HPNSSH only. + .It Cm IgnoreRhosts + Specifies whether to ignore per-user + .Pa .rhosts +@@ -1393,6 +1422,19 @@ + key exchange methods. + The default is + .Pa /etc/moduli . ++.It Cm NoneEnabled ++Enable or disable the use of the None cipher. Care must always be used ++when enabling this as it will allow users to send data in the clear. However, ++it is important to note that authentication information remains encrypted ++even if this option is enabled. Default is ++.Cm no ++.It Cm NoneMacEnabled ++Enable or disable the use of the None MAC. When this is enabled ssh ++will *not* provide data integrity of any data being transmitted between hosts. Use ++with caution as it, unlike just using NoneEnabled, doesn't provide data integrity and ++protection against man-in-the-middle attacks. As with NoneEnabled all authentication ++remains encrypted and integrity is ensured. Default is ++.Cm no. + .It Cm PasswordAuthentication + Specifies whether password authentication is allowed. + The default is +@@ -1835,6 +1877,13 @@ + .Pp + To disable TCP keepalive messages, the value should be set to + .Cm no . ++.IT Cm TcpRcvBufPoll ++Enable of disable the polling of the tcp receive buffer throughout the life ++of the connection. Make sure that this option is enabled for systems making ++use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) in order to ++maximize throughput on high performance networks. ++Default is ++.Cm yes. + .It Cm TrustedUserCAKeys + Specifies a file containing public keys of certificate authorities that are + trusted to sign user certificates for authentication, or +@@ -2133,3 +2182,11 @@ + and + .An Markus Friedl + contributed support for privilege separation. ++.An Chris Rapier, ++.An Michael Stevens, ++.An Ben Bennet, ++and ++.An Mike Tasota ++developed the HPN extensions at the Pittsburgh Supercomuting Center ++with grants from Cisco, the National Library of Medicine, and ++the National Science Foundation. +diff -Nur openssh-9.6p1.orig/ssh.h openssh-9.6p1/ssh.h +--- openssh-9.6p1.orig/ssh.h 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh.h 2024-07-10 13:34:02.736358642 +0200 +@@ -17,6 +17,7 @@ + + /* Default port number. */ + #define SSH_DEFAULT_PORT 22 ++#define HPNSSH_DEFAULT_PORT 2222 + + /* + * Maximum number of certificate files that can be specified +@@ -48,7 +49,7 @@ + * Name for the service. The port named by this service overrides the + * default port if present. + */ +-#define SSH_SERVICE_NAME "ssh" ++#define SSH_SERVICE_NAME "hpnssh" + + /* + * Name of the environment variable containing the process ID of the +diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c +--- openssh-9.6p1.orig/sshkey.c 2024-07-10 13:32:39.561111698 +0200 ++++ openssh-9.6p1/sshkey.c 2024-07-10 13:34:02.737358645 +0200 +@@ -1780,7 +1780,8 @@ + stderr); + #endif + if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), +- keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0) ++ keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0, ++ CIPHER_ENCRYPT, CIPHER_SERIAL)) != 0) + goto out; + + /* Serialise and encrypt the private key using the ephemeral key */ +@@ -1915,7 +1916,8 @@ + keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) + goto out; + if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), +- keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0) ++ keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0, ++ CIPHER_DECRYPT, CIPHER_SERIAL)) != 0) + goto out; + #ifdef DEBUG_PK + fprintf(stderr, "%s: key+iv\n", __func__); +@@ -2983,6 +2985,13 @@ + kdfname = "none"; + } else if (ciphername == NULL) + ciphername = DEFAULT_CIPHERNAME; ++ /* ++ * NOTE: Without OpenSSL, this string comparison is still safe, even ++ * though it will never match because the multithreaded cipher is not ++ * enabled. ++ */ ++ else if (strcmp(ciphername, "chacha20-poly1305-mt@hpnssh.org") == 0) ++ ciphername = "chacha20-poly1305@openssh.com"; + if ((cipher = cipher_by_name(ciphername)) == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; +@@ -3018,7 +3027,7 @@ + goto out; + } + if ((r = cipher_init(&ciphercontext, cipher, key, keylen, +- key + keylen, ivlen, 1)) != 0) ++ key + keylen, ivlen, 0, CIPHER_ENCRYPT, CIPHER_SERIAL)) != 0) + goto out; + + if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || +@@ -3205,6 +3214,8 @@ + (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) + goto out; + ++ if (strcmp(ciphername, "chacha20-poly1305-mt@hpnssh.org") == 0) ++ strcpy(ciphername, "chacha20-poly1305@openssh.com"); + if ((cipher = cipher_by_name(ciphername)) == NULL) { + r = SSH_ERR_KEY_UNKNOWN_CIPHER; + goto out; +@@ -3260,7 +3271,7 @@ + /* decrypt private portion of key */ + if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || + (r = cipher_init(&ciphercontext, cipher, key, keylen, +- key + keylen, ivlen, 0)) != 0) ++ key + keylen, ivlen, 0, CIPHER_DECRYPT, CIPHER_SERIAL)) != 0) + goto out; + if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), + encrypted_len, 0, authlen)) != 0) { +diff -Nur openssh-9.6p1.orig/sshkey-xmss.c openssh-9.6p1/sshkey-xmss.c +--- openssh-9.6p1.orig/sshkey-xmss.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/sshkey-xmss.c 2024-07-10 13:34:02.737358645 +0200 +@@ -903,9 +903,29 @@ + state->enc_keyiv == NULL || + state->enc_ciphername == NULL) + return SSH_ERR_INTERNAL_ERROR; +- if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { +- r = SSH_ERR_INTERNAL_ERROR; +- goto out; ++ /* ++ * chacha20-poly1305-mt@hpnssh.org and chacha20-poly1305@openssh.com ++ * represent different implementations of the same cipher. For key ++ * encryption purposes, they're equivalent, and the multithreaded ++ * implementation is excessive. It can be assumed that references to the ++ * multithreaded implementation in this context are unintentional, so ++ * these checks should look for the serial implementation instead. ++ * ++ * Additionally, the following code is safe regardless of whether the ++ * multithreaded implementation is enabled, so no #ifdefs are necessary. ++ */ ++ if (strcmp(state->enc_ciphername, "chacha20-poly1305-mt@hpnssh.org") ++ == 0) { ++ if ((cipher = cipher_by_name("chacha20-poly1305@openssh.com")) ++ == NULL) { ++ r = SSH_ERR_INTERNAL_ERROR; ++ goto out; ++ } ++ } else { ++ if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { ++ r = SSH_ERR_INTERNAL_ERROR; ++ goto out; ++ } + } + blocksize = cipher_blocksize(cipher); + keylen = cipher_keylen(cipher); +@@ -956,7 +976,7 @@ + if ((r = sshbuf_reserve(encrypted, + encrypted_len + aadlen + authlen, &cp)) != 0 || + (r = cipher_init(&ciphercontext, cipher, key, keylen, +- iv, ivlen, 1)) != 0 || ++ iv, ivlen, 0, CIPHER_ENCRYPT, CIPHER_SERIAL)) != 0 || + (r = cipher_crypt(ciphercontext, 0, cp, sshbuf_ptr(encoded), + encrypted_len, aadlen, authlen)) != 0) + goto out; +@@ -995,9 +1015,29 @@ + state->enc_keyiv == NULL || + state->enc_ciphername == NULL) + return SSH_ERR_INTERNAL_ERROR; +- if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { +- r = SSH_ERR_INVALID_FORMAT; +- goto out; ++ /* ++ * chacha20-poly1305-mt@hpnssh.org and chacha20-poly1305@openssh.com ++ * represent different implementations of the same cipher. For key ++ * encryption purposes, they're equivalent, and the multithreaded ++ * implementation is excessive. It can be assumed that references to the ++ * multithreaded implementation in this context are unintentional, so ++ * these checks should look for the serial implementation instead. ++ * ++ * Additionally, the following code is safe regardless of whether the ++ * multithreaded implementation is enabled, so no #ifdefs are necessary. ++ */ ++ if (strcmp(state->enc_ciphername, "chacha20-poly1305-mt@hpnssh.org") ++ == 0) { ++ if ((cipher = cipher_by_name("chacha20-poly1305@openssh.com")) ++ == NULL) { ++ r = SSH_ERR_INVALID_FORMAT; ++ goto out; ++ } ++ } else { ++ if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { ++ r = SSH_ERR_INVALID_FORMAT; ++ goto out; ++ } + } + blocksize = cipher_blocksize(cipher); + keylen = cipher_keylen(cipher); +@@ -1049,7 +1089,7 @@ + /* decrypt private state of key */ + if ((r = sshbuf_reserve(decrypted, aadlen + encrypted_len, &dp)) != 0 || + (r = cipher_init(&ciphercontext, cipher, key, keylen, +- iv, ivlen, 0)) != 0 || ++ iv, ivlen, 0, CIPHER_DECRYPT, CIPHER_SERIAL)) != 0 || + (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), + encrypted_len, aadlen, authlen)) != 0) + goto out; +diff -Nur openssh-9.6p1.orig/umac.c openssh-9.6p1/umac.c +--- openssh-9.6p1.orig/umac.c 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/umac.c 2024-07-10 13:34:02.738358648 +0200 +@@ -134,15 +134,48 @@ + /* --- Endian Conversion --- Forcing assembly on some platforms */ + /* ---------------------------------------------------------------------- */ + ++ ++/* Using local statically defined versions of the get/put functions ++ * found in misc.c allows them to be inlined. This improves throughput ++ * performance by 10% to 15% on well connected (10Gb/s+) systems. ++ * Chris Rapier 2022-03-09 */ ++ ++static __attribute__((__bounded__(__minbytes__, 1, 4))) ++u_int32_t umac_get_u32_le(const void *vp) ++{ ++ const u_char *p = (const u_char *)vp; ++ u_int32_t v; ++ ++ v = (u_int32_t)p[0]; ++ v |= (u_int32_t)p[1] << 8; ++ v |= (u_int32_t)p[2] << 16; ++ v |= (u_int32_t)p[3] << 24; ++ ++ return (v); ++} ++ ++#if (! __LITTLE_ENDIAN__) /* compile time warning thrown otherwise */ ++static __attribute__((__bounded__(__minbytes__, 1, 4))); ++void umac_put_u32_le(void *vp, u_int32_t v) ++{ ++ u_char *p = (u_char *)vp; ++ ++ p[0] = (u_char)v & 0xff; ++ p[1] = (u_char)(v >> 8) & 0xff; ++ p[2] = (u_char)(v >> 16) & 0xff; ++ p[3] = (u_char)(v >> 24) & 0xff; ++} ++#endif ++ + #if (__LITTLE_ENDIAN__) + #define LOAD_UINT32_REVERSED(p) get_u32(p) + #define STORE_UINT32_REVERSED(p,v) put_u32(p,v) + #else +-#define LOAD_UINT32_REVERSED(p) get_u32_le(p) +-#define STORE_UINT32_REVERSED(p,v) put_u32_le(p,v) ++#define LOAD_UINT32_REVERSED(p) umac_get_u32_le(p) ++#define STORE_UINT32_REVERSED(p,v) umac_put_u32_le(p,v) + #endif + +-#define LOAD_UINT32_LITTLE(p) (get_u32_le(p)) ++#define LOAD_UINT32_LITTLE(p) (umac_get_u32_le(p)) + #define STORE_UINT32_BIG(p,v) put_u32(p, v) + + /* ---------------------------------------------------------------------- */ +diff -Nur openssh-9.6p1.orig/uthash.h openssh-9.6p1/uthash.h +--- openssh-9.6p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.6p1/uthash.h 2024-07-10 13:34:02.738358648 +0200 +@@ -0,0 +1,1140 @@ ++/* ++Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ++TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER ++OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#ifndef UTHASH_H ++#define UTHASH_H ++ ++#define UTHASH_VERSION 2.3.0 ++ ++#include /* memcmp, memset, strlen */ ++#include /* ptrdiff_t */ ++#include /* exit */ ++ ++#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT ++/* This codepath is provided for backward compatibility, but I plan to remove it. */ ++#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead" ++typedef unsigned int uint32_t; ++typedef unsigned char uint8_t; ++#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT ++#else ++#include /* uint8_t, uint32_t */ ++#endif ++ ++/* These macros use decltype or the earlier __typeof GNU extension. ++ As decltype is only available in newer compilers (VS2010 or gcc 4.3+ ++ when compiling c++ source) this code uses whatever method is needed ++ or, for VS2008 where neither is available, uses casting workarounds. */ ++#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) ++#if defined(_MSC_VER) /* MS compiler */ ++#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ ++#define DECLTYPE(x) (decltype(x)) ++#else /* VS2008 or older (or VS2010 in C mode) */ ++#define NO_DECLTYPE ++#endif ++#elif defined(__MCST__) /* Elbrus C Compiler */ ++#define DECLTYPE(x) (__typeof(x)) ++#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) ++#define NO_DECLTYPE ++#else /* GNU, Sun and other compilers */ ++#define DECLTYPE(x) (__typeof(x)) ++#endif ++#endif ++ ++#ifdef NO_DECLTYPE ++#define DECLTYPE(x) ++#define DECLTYPE_ASSIGN(dst,src) \ ++do { \ ++ char **_da_dst = (char**)(&(dst)); \ ++ *_da_dst = (char*)(src); \ ++} while (0) ++#else ++#define DECLTYPE_ASSIGN(dst,src) \ ++do { \ ++ (dst) = DECLTYPE(dst)(src); \ ++} while (0) ++#endif ++ ++#ifndef uthash_malloc ++#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ ++#endif ++#ifndef uthash_free ++#define uthash_free(ptr,sz) free(ptr) /* free fcn */ ++#endif ++#ifndef uthash_bzero ++#define uthash_bzero(a,n) memset(a,'\0',n) ++#endif ++#ifndef uthash_strlen ++#define uthash_strlen(s) strlen(s) ++#endif ++ ++#ifndef HASH_FUNCTION ++#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv) ++#endif ++ ++#ifndef HASH_KEYCMP ++#define HASH_KEYCMP(a,b,n) memcmp(a,b,n) ++#endif ++ ++#ifndef uthash_noexpand_fyi ++#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ ++#endif ++#ifndef uthash_expand_fyi ++#define uthash_expand_fyi(tbl) /* can be defined to log expands */ ++#endif ++ ++#ifndef HASH_NONFATAL_OOM ++#define HASH_NONFATAL_OOM 0 ++#endif ++ ++#if HASH_NONFATAL_OOM ++/* malloc failures can be recovered from */ ++ ++#ifndef uthash_nonfatal_oom ++#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ ++#endif ++ ++#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) ++#define IF_HASH_NONFATAL_OOM(x) x ++ ++#else ++/* malloc failures result in lost memory, hash tables are unusable */ ++ ++#ifndef uthash_fatal ++#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ ++#endif ++ ++#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") ++#define IF_HASH_NONFATAL_OOM(x) ++ ++#endif ++ ++/* initial number of buckets */ ++#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ ++#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ ++#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ ++ ++/* calculate the element whose hash handle address is hhp */ ++#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) ++/* calculate the hash handle from element address elp */ ++#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) ++ ++#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ ++do { \ ++ struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ ++ unsigned _hd_bkt; \ ++ HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ ++ (head)->hh.tbl->buckets[_hd_bkt].count++; \ ++ _hd_hh_item->hh_next = NULL; \ ++ _hd_hh_item->hh_prev = NULL; \ ++} while (0) ++ ++#define HASH_VALUE(keyptr,keylen,hashv) \ ++do { \ ++ HASH_FUNCTION(keyptr, keylen, hashv); \ ++} while (0) ++ ++#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ ++do { \ ++ (out) = NULL; \ ++ if (head) { \ ++ unsigned _hf_bkt; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ ++ if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ ++ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ ++ } \ ++ } \ ++} while (0) ++ ++#define HASH_FIND(hh,head,keyptr,keylen,out) \ ++do { \ ++ (out) = NULL; \ ++ if (head) { \ ++ unsigned _hf_hashv; \ ++ HASH_VALUE(keyptr, keylen, _hf_hashv); \ ++ HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ ++ } \ ++} while (0) ++ ++#ifdef HASH_BLOOM ++#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) ++#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) ++#define HASH_BLOOM_MAKE(tbl,oomed) \ ++do { \ ++ (tbl)->bloom_nbits = HASH_BLOOM; \ ++ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ ++ if (!(tbl)->bloom_bv) { \ ++ HASH_RECORD_OOM(oomed); \ ++ } else { \ ++ uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ ++ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ ++ } \ ++} while (0) ++ ++#define HASH_BLOOM_FREE(tbl) \ ++do { \ ++ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ ++} while (0) ++ ++#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) ++#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) ++ ++#define HASH_BLOOM_ADD(tbl,hashv) \ ++ HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) ++ ++#define HASH_BLOOM_TEST(tbl,hashv) \ ++ HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) ++ ++#else ++#define HASH_BLOOM_MAKE(tbl,oomed) ++#define HASH_BLOOM_FREE(tbl) ++#define HASH_BLOOM_ADD(tbl,hashv) ++#define HASH_BLOOM_TEST(tbl,hashv) (1) ++#define HASH_BLOOM_BYTELEN 0U ++#endif ++ ++#define HASH_MAKE_TABLE(hh,head,oomed) \ ++do { \ ++ (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ ++ if (!(head)->hh.tbl) { \ ++ HASH_RECORD_OOM(oomed); \ ++ } else { \ ++ uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ (head)->hh.tbl->tail = &((head)->hh); \ ++ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ ++ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ ++ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ ++ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ ++ HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ ++ (head)->hh.tbl->signature = HASH_SIGNATURE; \ ++ if (!(head)->hh.tbl->buckets) { \ ++ HASH_RECORD_OOM(oomed); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ } else { \ ++ uthash_bzero((head)->hh.tbl->buckets, \ ++ HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ ++ HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ ++ IF_HASH_NONFATAL_OOM( \ ++ if (oomed) { \ ++ uthash_free((head)->hh.tbl->buckets, \ ++ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ } \ ++ ) \ ++ } \ ++ } \ ++} while (0) ++ ++#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ ++do { \ ++ (replaced) = NULL; \ ++ HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ ++ if (replaced) { \ ++ HASH_DELETE(hh, head, replaced); \ ++ } \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ ++} while (0) ++ ++#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ ++do { \ ++ (replaced) = NULL; \ ++ HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ ++ if (replaced) { \ ++ HASH_DELETE(hh, head, replaced); \ ++ } \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ ++} while (0) ++ ++#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ ++do { \ ++ unsigned _hr_hashv; \ ++ HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ ++ HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ ++} while (0) ++ ++#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ ++do { \ ++ unsigned _hr_hashv; \ ++ HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ ++ HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ ++} while (0) ++ ++#define HASH_APPEND_LIST(hh, head, add) \ ++do { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ ++ (head)->hh.tbl->tail->next = (add); \ ++ (head)->hh.tbl->tail = &((add)->hh); \ ++} while (0) ++ ++#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ ++do { \ ++ do { \ ++ if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ ++ break; \ ++ } \ ++ } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ ++} while (0) ++ ++#ifdef NO_DECLTYPE ++#undef HASH_AKBI_INNER_LOOP ++#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ ++do { \ ++ char *_hs_saved_head = (char*)(head); \ ++ do { \ ++ DECLTYPE_ASSIGN(head, _hs_iter); \ ++ if (cmpfcn(head, add) > 0) { \ ++ DECLTYPE_ASSIGN(head, _hs_saved_head); \ ++ break; \ ++ } \ ++ DECLTYPE_ASSIGN(head, _hs_saved_head); \ ++ } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ ++} while (0) ++#endif ++ ++#if HASH_NONFATAL_OOM ++ ++#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ ++do { \ ++ if (!(oomed)) { \ ++ unsigned _ha_bkt; \ ++ (head)->hh.tbl->num_items++; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ ++ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ ++ if (oomed) { \ ++ HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ ++ HASH_DELETE_HH(hh, head, &(add)->hh); \ ++ (add)->hh.tbl = NULL; \ ++ uthash_nonfatal_oom(add); \ ++ } else { \ ++ HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ ++ HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ ++ } \ ++ } else { \ ++ (add)->hh.tbl = NULL; \ ++ uthash_nonfatal_oom(add); \ ++ } \ ++} while (0) ++ ++#else ++ ++#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ ++do { \ ++ unsigned _ha_bkt; \ ++ (head)->hh.tbl->num_items++; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ ++ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ ++ HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ ++ HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ ++} while (0) ++ ++#endif ++ ++ ++#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ ++do { \ ++ IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ ++ (add)->hh.hashv = (hashval); \ ++ (add)->hh.key = (char*) (keyptr); \ ++ (add)->hh.keylen = (unsigned) (keylen_in); \ ++ if (!(head)) { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = NULL; \ ++ HASH_MAKE_TABLE(hh, add, _ha_oomed); \ ++ IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ ++ (head) = (add); \ ++ IF_HASH_NONFATAL_OOM( } ) \ ++ } else { \ ++ void *_hs_iter = (head); \ ++ (add)->hh.tbl = (head)->hh.tbl; \ ++ HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ ++ if (_hs_iter) { \ ++ (add)->hh.next = _hs_iter; \ ++ if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ ++ HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ ++ } else { \ ++ (head) = (add); \ ++ } \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ ++ } else { \ ++ HASH_APPEND_LIST(hh, head, add); \ ++ } \ ++ } \ ++ HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ ++ HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ ++} while (0) ++ ++#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ ++do { \ ++ unsigned _hs_hashv; \ ++ HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ ++} while (0) ++ ++#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) ++ ++#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ ++ HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) ++ ++#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ ++do { \ ++ IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ ++ (add)->hh.hashv = (hashval); \ ++ (add)->hh.key = (const void*) (keyptr); \ ++ (add)->hh.keylen = (unsigned) (keylen_in); \ ++ if (!(head)) { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = NULL; \ ++ HASH_MAKE_TABLE(hh, add, _ha_oomed); \ ++ IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ ++ (head) = (add); \ ++ IF_HASH_NONFATAL_OOM( } ) \ ++ } else { \ ++ (add)->hh.tbl = (head)->hh.tbl; \ ++ HASH_APPEND_LIST(hh, head, add); \ ++ } \ ++ HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ ++ HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ ++} while (0) ++ ++#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ ++do { \ ++ unsigned _ha_hashv; \ ++ HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ ++} while (0) ++ ++#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) ++ ++#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ ++ HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) ++ ++#define HASH_TO_BKT(hashv,num_bkts,bkt) \ ++do { \ ++ bkt = ((hashv) & ((num_bkts) - 1U)); \ ++} while (0) ++ ++/* delete "delptr" from the hash table. ++ * "the usual" patch-up process for the app-order doubly-linked-list. ++ * The use of _hd_hh_del below deserves special explanation. ++ * These used to be expressed using (delptr) but that led to a bug ++ * if someone used the same symbol for the head and deletee, like ++ * HASH_DELETE(hh,users,users); ++ * We want that to work, but by changing the head (users) below ++ * we were forfeiting our ability to further refer to the deletee (users) ++ * in the patch-up process. Solution: use scratch space to ++ * copy the deletee pointer, then the latter references are via that ++ * scratch pointer rather than through the repointed (users) symbol. ++ */ ++#define HASH_DELETE(hh,head,delptr) \ ++ HASH_DELETE_HH(hh, head, &(delptr)->hh) ++ ++#define HASH_DELETE_HH(hh,head,delptrhh) \ ++do { \ ++ const struct UT_hash_handle *_hd_hh_del = (delptrhh); \ ++ if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ ++ HASH_BLOOM_FREE((head)->hh.tbl); \ ++ uthash_free((head)->hh.tbl->buckets, \ ++ (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ (head) = NULL; \ ++ } else { \ ++ unsigned _hd_bkt; \ ++ if (_hd_hh_del == (head)->hh.tbl->tail) { \ ++ (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ ++ } \ ++ if (_hd_hh_del->prev != NULL) { \ ++ HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ ++ } else { \ ++ DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ ++ } \ ++ if (_hd_hh_del->next != NULL) { \ ++ HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ ++ } \ ++ HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ ++ HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ ++ (head)->hh.tbl->num_items--; \ ++ } \ ++ HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ ++} while (0) ++ ++/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ ++#define HASH_FIND_STR(head,findstr,out) \ ++do { \ ++ unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ ++ HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ ++} while (0) ++#define HASH_ADD_STR(head,strfield,add) \ ++do { \ ++ unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ ++ HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ ++} while (0) ++#define HASH_REPLACE_STR(head,strfield,add,replaced) \ ++do { \ ++ unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ ++ HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ ++} while (0) ++#define HASH_FIND_INT(head,findint,out) \ ++ HASH_FIND(hh,head,findint,sizeof(int),out) ++#define HASH_ADD_INT(head,intfield,add) \ ++ HASH_ADD(hh,head,intfield,sizeof(int),add) ++#define HASH_REPLACE_INT(head,intfield,add,replaced) \ ++ HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) ++#define HASH_FIND_PTR(head,findptr,out) \ ++ HASH_FIND(hh,head,findptr,sizeof(void *),out) ++#define HASH_ADD_PTR(head,ptrfield,add) \ ++ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) ++#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ ++ HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) ++#define HASH_DEL(head,delptr) \ ++ HASH_DELETE(hh,head,delptr) ++ ++/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. ++ * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. ++ */ ++#ifdef HASH_DEBUG ++#include /* fprintf, stderr */ ++#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) ++#define HASH_FSCK(hh,head,where) \ ++do { \ ++ struct UT_hash_handle *_thh; \ ++ if (head) { \ ++ unsigned _bkt_i; \ ++ unsigned _count = 0; \ ++ char *_prev; \ ++ for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ ++ unsigned _bkt_count = 0; \ ++ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ ++ _prev = NULL; \ ++ while (_thh) { \ ++ if (_prev != (char*)(_thh->hh_prev)) { \ ++ HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ ++ (where), (void*)_thh->hh_prev, (void*)_prev); \ ++ } \ ++ _bkt_count++; \ ++ _prev = (char*)(_thh); \ ++ _thh = _thh->hh_next; \ ++ } \ ++ _count += _bkt_count; \ ++ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ ++ HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ ++ (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ ++ } \ ++ } \ ++ if (_count != (head)->hh.tbl->num_items) { \ ++ HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ ++ (where), (head)->hh.tbl->num_items, _count); \ ++ } \ ++ _count = 0; \ ++ _prev = NULL; \ ++ _thh = &(head)->hh; \ ++ while (_thh) { \ ++ _count++; \ ++ if (_prev != (char*)_thh->prev) { \ ++ HASH_OOPS("%s: invalid prev %p, actual %p\n", \ ++ (where), (void*)_thh->prev, (void*)_prev); \ ++ } \ ++ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ ++ _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ ++ } \ ++ if (_count != (head)->hh.tbl->num_items) { \ ++ HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ ++ (where), (head)->hh.tbl->num_items, _count); \ ++ } \ ++ } \ ++} while (0) ++#else ++#define HASH_FSCK(hh,head,where) ++#endif ++ ++/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to ++ * the descriptor to which this macro is defined for tuning the hash function. ++ * The app can #include to get the prototype for write(2). */ ++#ifdef HASH_EMIT_KEYS ++#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ ++do { \ ++ unsigned _klen = fieldlen; \ ++ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ ++ write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ ++} while (0) ++#else ++#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) ++#endif ++ ++/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ ++#define HASH_BER(key,keylen,hashv) \ ++do { \ ++ unsigned _hb_keylen = (unsigned)keylen; \ ++ const unsigned char *_hb_key = (const unsigned char*)(key); \ ++ (hashv) = 0; \ ++ while (_hb_keylen-- != 0U) { \ ++ (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ ++ } \ ++} while (0) ++ ++ ++/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at ++ * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx ++ * (archive link: https://archive.is/Ivcan ) ++ */ ++#define HASH_SAX(key,keylen,hashv) \ ++do { \ ++ unsigned _sx_i; \ ++ const unsigned char *_hs_key = (const unsigned char*)(key); \ ++ hashv = 0; \ ++ for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ ++ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ ++ } \ ++} while (0) ++/* FNV-1a variation */ ++#define HASH_FNV(key,keylen,hashv) \ ++do { \ ++ unsigned _fn_i; \ ++ const unsigned char *_hf_key = (const unsigned char*)(key); \ ++ (hashv) = 2166136261U; \ ++ for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ ++ hashv = hashv ^ _hf_key[_fn_i]; \ ++ hashv = hashv * 16777619U; \ ++ } \ ++} while (0) ++ ++#define HASH_OAT(key,keylen,hashv) \ ++do { \ ++ unsigned _ho_i; \ ++ const unsigned char *_ho_key=(const unsigned char*)(key); \ ++ hashv = 0; \ ++ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ ++ hashv += _ho_key[_ho_i]; \ ++ hashv += (hashv << 10); \ ++ hashv ^= (hashv >> 6); \ ++ } \ ++ hashv += (hashv << 3); \ ++ hashv ^= (hashv >> 11); \ ++ hashv += (hashv << 15); \ ++} while (0) ++ ++#define HASH_JEN_MIX(a,b,c) \ ++do { \ ++ a -= b; a -= c; a ^= ( c >> 13 ); \ ++ b -= c; b -= a; b ^= ( a << 8 ); \ ++ c -= a; c -= b; c ^= ( b >> 13 ); \ ++ a -= b; a -= c; a ^= ( c >> 12 ); \ ++ b -= c; b -= a; b ^= ( a << 16 ); \ ++ c -= a; c -= b; c ^= ( b >> 5 ); \ ++ a -= b; a -= c; a ^= ( c >> 3 ); \ ++ b -= c; b -= a; b ^= ( a << 10 ); \ ++ c -= a; c -= b; c ^= ( b >> 15 ); \ ++} while (0) ++ ++#define HASH_JEN(key,keylen,hashv) \ ++do { \ ++ unsigned _hj_i,_hj_j,_hj_k; \ ++ unsigned const char *_hj_key=(unsigned const char*)(key); \ ++ hashv = 0xfeedbeefu; \ ++ _hj_i = _hj_j = 0x9e3779b9u; \ ++ _hj_k = (unsigned)(keylen); \ ++ while (_hj_k >= 12U) { \ ++ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ ++ + ( (unsigned)_hj_key[2] << 16 ) \ ++ + ( (unsigned)_hj_key[3] << 24 ) ); \ ++ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ ++ + ( (unsigned)_hj_key[6] << 16 ) \ ++ + ( (unsigned)_hj_key[7] << 24 ) ); \ ++ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ ++ + ( (unsigned)_hj_key[10] << 16 ) \ ++ + ( (unsigned)_hj_key[11] << 24 ) ); \ ++ \ ++ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ ++ \ ++ _hj_key += 12; \ ++ _hj_k -= 12U; \ ++ } \ ++ hashv += (unsigned)(keylen); \ ++ switch ( _hj_k ) { \ ++ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ ++ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ ++ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ ++ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ ++ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ ++ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ ++ case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ ++ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ ++ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ ++ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ ++ case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \ ++ default: ; \ ++ } \ ++ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ ++} while (0) ++ ++/* The Paul Hsieh hash function */ ++#undef get16bits ++#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ ++ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) ++#define get16bits(d) (*((const uint16_t *) (d))) ++#endif ++ ++#if !defined (get16bits) ++#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ ++ +(uint32_t)(((const uint8_t *)(d))[0]) ) ++#endif ++#define HASH_SFH(key,keylen,hashv) \ ++do { \ ++ unsigned const char *_sfh_key=(unsigned const char*)(key); \ ++ uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ ++ \ ++ unsigned _sfh_rem = _sfh_len & 3U; \ ++ _sfh_len >>= 2; \ ++ hashv = 0xcafebabeu; \ ++ \ ++ /* Main loop */ \ ++ for (;_sfh_len > 0U; _sfh_len--) { \ ++ hashv += get16bits (_sfh_key); \ ++ _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ ++ hashv = (hashv << 16) ^ _sfh_tmp; \ ++ _sfh_key += 2U*sizeof (uint16_t); \ ++ hashv += hashv >> 11; \ ++ } \ ++ \ ++ /* Handle end cases */ \ ++ switch (_sfh_rem) { \ ++ case 3: hashv += get16bits (_sfh_key); \ ++ hashv ^= hashv << 16; \ ++ hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ ++ hashv += hashv >> 11; \ ++ break; \ ++ case 2: hashv += get16bits (_sfh_key); \ ++ hashv ^= hashv << 11; \ ++ hashv += hashv >> 17; \ ++ break; \ ++ case 1: hashv += *_sfh_key; \ ++ hashv ^= hashv << 10; \ ++ hashv += hashv >> 1; \ ++ break; \ ++ default: ; \ ++ } \ ++ \ ++ /* Force "avalanching" of final 127 bits */ \ ++ hashv ^= hashv << 3; \ ++ hashv += hashv >> 5; \ ++ hashv ^= hashv << 4; \ ++ hashv += hashv >> 17; \ ++ hashv ^= hashv << 25; \ ++ hashv += hashv >> 6; \ ++} while (0) ++ ++/* iterate over items in a known bucket to find desired item */ ++#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ ++do { \ ++ if ((head).hh_head != NULL) { \ ++ DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ ++ } else { \ ++ (out) = NULL; \ ++ } \ ++ while ((out) != NULL) { \ ++ if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ ++ if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ ++ break; \ ++ } \ ++ } \ ++ if ((out)->hh.hh_next != NULL) { \ ++ DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ ++ } else { \ ++ (out) = NULL; \ ++ } \ ++ } \ ++} while (0) ++ ++/* add an item to a bucket */ ++#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ ++do { \ ++ UT_hash_bucket *_ha_head = &(head); \ ++ _ha_head->count++; \ ++ (addhh)->hh_next = _ha_head->hh_head; \ ++ (addhh)->hh_prev = NULL; \ ++ if (_ha_head->hh_head != NULL) { \ ++ _ha_head->hh_head->hh_prev = (addhh); \ ++ } \ ++ _ha_head->hh_head = (addhh); \ ++ if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ ++ && !(addhh)->tbl->noexpand) { \ ++ HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ ++ IF_HASH_NONFATAL_OOM( \ ++ if (oomed) { \ ++ HASH_DEL_IN_BKT(head,addhh); \ ++ } \ ++ ) \ ++ } \ ++} while (0) ++ ++/* remove an item from a given bucket */ ++#define HASH_DEL_IN_BKT(head,delhh) \ ++do { \ ++ UT_hash_bucket *_hd_head = &(head); \ ++ _hd_head->count--; \ ++ if (_hd_head->hh_head == (delhh)) { \ ++ _hd_head->hh_head = (delhh)->hh_next; \ ++ } \ ++ if ((delhh)->hh_prev) { \ ++ (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ ++ } \ ++ if ((delhh)->hh_next) { \ ++ (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ ++ } \ ++} while (0) ++ ++/* Bucket expansion has the effect of doubling the number of buckets ++ * and redistributing the items into the new buckets. Ideally the ++ * items will distribute more or less evenly into the new buckets ++ * (the extent to which this is true is a measure of the quality of ++ * the hash function as it applies to the key domain). ++ * ++ * With the items distributed into more buckets, the chain length ++ * (item count) in each bucket is reduced. Thus by expanding buckets ++ * the hash keeps a bound on the chain length. This bounded chain ++ * length is the essence of how a hash provides constant time lookup. ++ * ++ * The calculation of tbl->ideal_chain_maxlen below deserves some ++ * explanation. First, keep in mind that we're calculating the ideal ++ * maximum chain length based on the *new* (doubled) bucket count. ++ * In fractions this is just n/b (n=number of items,b=new num buckets). ++ * Since the ideal chain length is an integer, we want to calculate ++ * ceil(n/b). We don't depend on floating point arithmetic in this ++ * hash, so to calculate ceil(n/b) with integers we could write ++ * ++ * ceil(n/b) = (n/b) + ((n%b)?1:0) ++ * ++ * and in fact a previous version of this hash did just that. ++ * But now we have improved things a bit by recognizing that b is ++ * always a power of two. We keep its base 2 log handy (call it lb), ++ * so now we can write this with a bit shift and logical AND: ++ * ++ * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) ++ * ++ */ ++#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ ++do { \ ++ unsigned _he_bkt; \ ++ unsigned _he_bkt_i; \ ++ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ ++ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ ++ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ ++ sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ ++ if (!_he_new_buckets) { \ ++ HASH_RECORD_OOM(oomed); \ ++ } else { \ ++ uthash_bzero(_he_new_buckets, \ ++ sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ ++ (tbl)->ideal_chain_maxlen = \ ++ ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ ++ ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ ++ (tbl)->nonideal_items = 0; \ ++ for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ ++ _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ ++ while (_he_thh != NULL) { \ ++ _he_hh_nxt = _he_thh->hh_next; \ ++ HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ ++ _he_newbkt = &(_he_new_buckets[_he_bkt]); \ ++ if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ ++ (tbl)->nonideal_items++; \ ++ if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ ++ _he_newbkt->expand_mult++; \ ++ } \ ++ } \ ++ _he_thh->hh_prev = NULL; \ ++ _he_thh->hh_next = _he_newbkt->hh_head; \ ++ if (_he_newbkt->hh_head != NULL) { \ ++ _he_newbkt->hh_head->hh_prev = _he_thh; \ ++ } \ ++ _he_newbkt->hh_head = _he_thh; \ ++ _he_thh = _he_hh_nxt; \ ++ } \ ++ } \ ++ uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ ++ (tbl)->num_buckets *= 2U; \ ++ (tbl)->log2_num_buckets++; \ ++ (tbl)->buckets = _he_new_buckets; \ ++ (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ ++ ((tbl)->ineff_expands+1U) : 0U; \ ++ if ((tbl)->ineff_expands > 1U) { \ ++ (tbl)->noexpand = 1; \ ++ uthash_noexpand_fyi(tbl); \ ++ } \ ++ uthash_expand_fyi(tbl); \ ++ } \ ++} while (0) ++ ++ ++/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ ++/* Note that HASH_SORT assumes the hash handle name to be hh. ++ * HASH_SRT was added to allow the hash handle name to be passed in. */ ++#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) ++#define HASH_SRT(hh,head,cmpfcn) \ ++do { \ ++ unsigned _hs_i; \ ++ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ ++ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ ++ if (head != NULL) { \ ++ _hs_insize = 1; \ ++ _hs_looping = 1; \ ++ _hs_list = &((head)->hh); \ ++ while (_hs_looping != 0U) { \ ++ _hs_p = _hs_list; \ ++ _hs_list = NULL; \ ++ _hs_tail = NULL; \ ++ _hs_nmerges = 0; \ ++ while (_hs_p != NULL) { \ ++ _hs_nmerges++; \ ++ _hs_q = _hs_p; \ ++ _hs_psize = 0; \ ++ for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ ++ _hs_psize++; \ ++ _hs_q = ((_hs_q->next != NULL) ? \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ ++ if (_hs_q == NULL) { \ ++ break; \ ++ } \ ++ } \ ++ _hs_qsize = _hs_insize; \ ++ while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ ++ if (_hs_psize == 0U) { \ ++ _hs_e = _hs_q; \ ++ _hs_q = ((_hs_q->next != NULL) ? \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ ++ _hs_qsize--; \ ++ } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ ++ _hs_e = _hs_p; \ ++ if (_hs_p != NULL) { \ ++ _hs_p = ((_hs_p->next != NULL) ? \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ ++ } \ ++ _hs_psize--; \ ++ } else if ((cmpfcn( \ ++ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ ++ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ ++ )) <= 0) { \ ++ _hs_e = _hs_p; \ ++ if (_hs_p != NULL) { \ ++ _hs_p = ((_hs_p->next != NULL) ? \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ ++ } \ ++ _hs_psize--; \ ++ } else { \ ++ _hs_e = _hs_q; \ ++ _hs_q = ((_hs_q->next != NULL) ? \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ ++ _hs_qsize--; \ ++ } \ ++ if ( _hs_tail != NULL ) { \ ++ _hs_tail->next = ((_hs_e != NULL) ? \ ++ ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ ++ } else { \ ++ _hs_list = _hs_e; \ ++ } \ ++ if (_hs_e != NULL) { \ ++ _hs_e->prev = ((_hs_tail != NULL) ? \ ++ ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ ++ } \ ++ _hs_tail = _hs_e; \ ++ } \ ++ _hs_p = _hs_q; \ ++ } \ ++ if (_hs_tail != NULL) { \ ++ _hs_tail->next = NULL; \ ++ } \ ++ if (_hs_nmerges <= 1U) { \ ++ _hs_looping = 0; \ ++ (head)->hh.tbl->tail = _hs_tail; \ ++ DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ ++ } \ ++ _hs_insize *= 2U; \ ++ } \ ++ HASH_FSCK(hh, head, "HASH_SRT"); \ ++ } \ ++} while (0) ++ ++/* This function selects items from one hash into another hash. ++ * The end result is that the selected items have dual presence ++ * in both hashes. There is no copy of the items made; rather ++ * they are added into the new hash through a secondary hash ++ * hash handle that must be present in the structure. */ ++#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ ++do { \ ++ unsigned _src_bkt, _dst_bkt; \ ++ void *_last_elt = NULL, *_elt; \ ++ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ++ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ ++ if ((src) != NULL) { \ ++ for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ ++ for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ ++ _src_hh != NULL; \ ++ _src_hh = _src_hh->hh_next) { \ ++ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ ++ if (cond(_elt)) { \ ++ IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ ++ _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ ++ _dst_hh->key = _src_hh->key; \ ++ _dst_hh->keylen = _src_hh->keylen; \ ++ _dst_hh->hashv = _src_hh->hashv; \ ++ _dst_hh->prev = _last_elt; \ ++ _dst_hh->next = NULL; \ ++ if (_last_elt_hh != NULL) { \ ++ _last_elt_hh->next = _elt; \ ++ } \ ++ if ((dst) == NULL) { \ ++ DECLTYPE_ASSIGN(dst, _elt); \ ++ HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ ++ IF_HASH_NONFATAL_OOM( \ ++ if (_hs_oomed) { \ ++ uthash_nonfatal_oom(_elt); \ ++ (dst) = NULL; \ ++ continue; \ ++ } \ ++ ) \ ++ } else { \ ++ _dst_hh->tbl = (dst)->hh_dst.tbl; \ ++ } \ ++ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ ++ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ ++ (dst)->hh_dst.tbl->num_items++; \ ++ IF_HASH_NONFATAL_OOM( \ ++ if (_hs_oomed) { \ ++ HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ ++ HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ ++ _dst_hh->tbl = NULL; \ ++ uthash_nonfatal_oom(_elt); \ ++ continue; \ ++ } \ ++ ) \ ++ HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ ++ _last_elt = _elt; \ ++ _last_elt_hh = _dst_hh; \ ++ } \ ++ } \ ++ } \ ++ } \ ++ HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ ++} while (0) ++ ++#define HASH_CLEAR(hh,head) \ ++do { \ ++ if ((head) != NULL) { \ ++ HASH_BLOOM_FREE((head)->hh.tbl); \ ++ uthash_free((head)->hh.tbl->buckets, \ ++ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ (head) = NULL; \ ++ } \ ++} while (0) ++ ++#define HASH_OVERHEAD(hh,head) \ ++ (((head) != NULL) ? ( \ ++ (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ ++ ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ ++ sizeof(UT_hash_table) + \ ++ (HASH_BLOOM_BYTELEN))) : 0U) ++ ++#ifdef NO_DECLTYPE ++#define HASH_ITER(hh,head,el,tmp) \ ++for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ ++ (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) ++#else ++#define HASH_ITER(hh,head,el,tmp) \ ++for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ ++ (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) ++#endif ++ ++/* obtain a count of items in the hash */ ++#define HASH_COUNT(head) HASH_CNT(hh,head) ++#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) ++ ++typedef struct UT_hash_bucket { ++ struct UT_hash_handle *hh_head; ++ unsigned count; ++ ++ /* expand_mult is normally set to 0. In this situation, the max chain length ++ * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If ++ * the bucket's chain exceeds this length, bucket expansion is triggered). ++ * However, setting expand_mult to a non-zero value delays bucket expansion ++ * (that would be triggered by additions to this particular bucket) ++ * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. ++ * (The multiplier is simply expand_mult+1). The whole idea of this ++ * multiplier is to reduce bucket expansions, since they are expensive, in ++ * situations where we know that a particular bucket tends to be overused. ++ * It is better to let its chain length grow to a longer yet-still-bounded ++ * value, than to do an O(n) bucket expansion too often. ++ */ ++ unsigned expand_mult; ++ ++} UT_hash_bucket; ++ ++/* random signature used only to find hash tables in external analysis */ ++#define HASH_SIGNATURE 0xa0111fe1u ++#define HASH_BLOOM_SIGNATURE 0xb12220f2u ++ ++typedef struct UT_hash_table { ++ UT_hash_bucket *buckets; ++ unsigned num_buckets, log2_num_buckets; ++ unsigned num_items; ++ struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ++ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ ++ ++ /* in an ideal situation (all buckets used equally), no bucket would have ++ * more than ceil(#items/#buckets) items. that's the ideal chain length. */ ++ unsigned ideal_chain_maxlen; ++ ++ /* nonideal_items is the number of items in the hash whose chain position ++ * exceeds the ideal chain maxlen. these items pay the penalty for an uneven ++ * hash distribution; reaching them in a chain traversal takes >ideal steps */ ++ unsigned nonideal_items; ++ ++ /* ineffective expands occur when a bucket doubling was performed, but ++ * afterward, more than half the items in the hash had nonideal chain ++ * positions. If this happens on two consecutive expansions we inhibit any ++ * further expansion, as it's not helping; this happens when the hash ++ * function isn't a good fit for the key domain. When expansion is inhibited ++ * the hash will still work, albeit no longer in constant time. */ ++ unsigned ineff_expands, noexpand; ++ ++ uint32_t signature; /* used only to find hash tables in external analysis */ ++#ifdef HASH_BLOOM ++ uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ ++ uint8_t *bloom_bv; ++ uint8_t bloom_nbits; ++#endif ++ ++} UT_hash_table; ++ ++typedef struct UT_hash_handle { ++ struct UT_hash_table *tbl; ++ void *prev; /* prev element in app order */ ++ void *next; /* next element in app order */ ++ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ ++ struct UT_hash_handle *hh_next; /* next hh in bucket order */ ++ const void *key; /* ptr to enclosing struct's key */ ++ unsigned keylen; /* enclosing struct's key len */ ++ unsigned hashv; /* result of hash-fcn(key) */ ++} UT_hash_handle; ++ ++#endif /* UTHASH_H */ +diff -Nur openssh-9.6p1.orig/version.h openssh-9.6p1/version.h +--- openssh-9.6p1.orig/version.h 2024-07-10 13:32:39.605111829 +0200 ++++ openssh-9.6p1/version.h 2024-07-10 14:25:00.449370077 +0200 +@@ -16,5 +16,6 @@ + + #define SSH_PORTABLE "p1" + #define GSI_PORTABLE "c-GSI" ++#define SSH_HPN "-hpn18.3.1" + #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ +- GSI_VERSION KRB5_VERSION ++ GSI_VERSION KRB5_VERSION SSH_HPN diff --git a/sources b/sources index c322d35..b461406 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-9.3p1.tar.gz) = 087ff6fe5f6caab4c6c3001d906399e02beffad7277280f11187420c2939fd4befdcb14643862a657ce4cad2f115b82a0a1a2c99df6ee54dcd76b53647637c19 -SHA512 (openssh-9.3p1.tar.gz.asc) = 6222378eb24a445c6c1db255392b405f5369b1af0e92f558d4ba05b0d83ab0d084cb8f4b91d7ae8636f333d970638a6635e2bc7af885135dd34992d87f2ef1f4 +SHA512 (openssh-9.6p1.tar.gz) = 0ebf81e39914c3a90d7777a001ec7376a94b37e6024baf3e972c58f0982b7ddef942315f5e01d56c00ff95603b4a20ee561ab918ecc55511df007ac138160509 +SHA512 (openssh-9.6p1.tar.gz.asc) = aec5a5bd6ce480a8e5b5879dc55f8186aec90fe61f085aa92ad7d07f324574aa781be09c83b7443a32848d091fd44fb12c1842d49cee77afc351e550ffcc096d SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 8ba66847e4bd142c0cc4829507e8585726dc771b Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 10 Jul 2024 15:35:42 +0200 Subject: [PATCH 127/146] Based on openssh-9.6p1-1.fc41.13 --- CVE-2024-6387.patch | 18 + gsi-openssh.spec | 21 +- gsisshd-keygen | 12 +- gsisshd.sysconfig | 3 + openssh-7.4p1-systemd.patch | 98 -- openssh-7.6p1-audit.patch | 4 +- openssh-7.7p1-fips.patch | 2 +- openssh-8.0p1-openssl-kdf.patch | 96 +- openssh-8.7p1-audit-hostname.patch | 106 ++ openssh-8.7p1-nohostsha1proof.patch | 6 +- openssh-9.6p1-cve-2024-6387.patch | 35 - openssh-9.6p1-gsissh.patch | 211 +-- openssh-9.6p1-gsskex-new-api.patch | 1965 +++++++++++++++++++++++++++ openssh-9.6p1-pam-rhost.patch | 32 + openssh-9.8p1-systemd.patch | 201 +++ 15 files changed, 2521 insertions(+), 289 deletions(-) create mode 100644 CVE-2024-6387.patch delete mode 100644 openssh-7.4p1-systemd.patch create mode 100644 openssh-8.7p1-audit-hostname.patch delete mode 100644 openssh-9.6p1-cve-2024-6387.patch create mode 100644 openssh-9.6p1-gsskex-new-api.patch create mode 100644 openssh-9.6p1-pam-rhost.patch create mode 100644 openssh-9.8p1-systemd.patch diff --git a/CVE-2024-6387.patch b/CVE-2024-6387.patch new file mode 100644 index 0000000..0b976c0 --- /dev/null +++ b/CVE-2024-6387.patch @@ -0,0 +1,18 @@ +diff --git a/log.c b/log.c +index 9fc1a2e2e..191ff4a5a 100644 +--- a/log.c ++++ b/log.c +@@ -451,12 +451,14 @@ void + sshsigdie(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, ...) + { ++#ifdef SYSLOG_R_SAFE_IN_SIGHAND + va_list args; + + va_start(args, fmt); + sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL, + suffix, fmt, args); + va_end(args); ++#endif + _exit(1); + } diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 49140db..70a279f 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.6p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -60,6 +60,8 @@ Patch200: openssh-7.6p1-audit.patch Patch201: openssh-7.1p2-audit-race-condition.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2049947 Patch202: openssh-9.0p1-audit-log.patch +# Correctly audit hostname and IP address +Patch203: openssh-8.7p1-audit-hostname.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-7.8p1-role-mls.patch @@ -105,6 +107,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 @@ -125,7 +129,7 @@ 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 +Patch948: openssh-9.8p1-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 @@ -178,9 +182,9 @@ Patch1012: openssh-9.0p1-evp-fips-dh.patch Patch1013: openssh-9.0p1-evp-fips-ecdh.patch Patch1014: openssh-8.7p1-nohostsha1proof.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2294879 -# Merged in OpenSSH 9.8 -Patch1016: openssh-9.6p1-cve-2024-6387.patch +Patch1015: openssh-9.6p1-pam-rhost.patch + +Patch1016: CVE-2024-6387.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -301,6 +305,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 @@ -332,6 +337,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 200 -p1 -b .audit %patch -P 201 -p1 -b .audit-race %patch -P 202 -p1 -b .audit-log +%patch -P 203 -p1 -b .audit-hostname %patch -P 700 -p1 -b .fips %patch -P 1002 -p1 -b .ssh-manpage @@ -339,6 +345,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 1016 -p1 -b .cve-2024-6387 %patch -P 100 -p1 -b .coverity @@ -403,6 +410,7 @@ fi --with-default-pkcs11-provider=yes \ --with-security-key-builtin=yes \ --with-pam \ + --without-ssl-engine \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ --with-sandbox=seccomp_filter \ @@ -552,6 +560,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Sat Jul 06 2024 Mattias Ellert - 9.6p1-2 +- Based on openssh-9.6p1-1.fc41.13 + * Sat Jul 06 2024 Mattias Ellert - 9.6p1-1 - Based on openssh-9.6p1-1.fc40.4 diff --git a/gsisshd-keygen b/gsisshd-keygen index 772550e..c49da87 100644 --- a/gsisshd-keygen +++ b/gsisshd-keygen @@ -9,8 +9,14 @@ case $KEYTYPE in if [[ -r "$FIPS" && $(cat $FIPS) == "1" ]]; then exit 0 fi ;; - "rsa") ;; # always ok - "ecdsa") ;; + "rsa") + if [[ ! -z $SSH_RSA_BITS ]]; then + SSH_KEYGEN_OPTIONS="-b $SSH_RSA_BITS" + fi ;; # always ok + "ecdsa") + if [[ ! -z $SSH_ECDSA_BITS ]]; then + SSH_KEYGEN_OPTIONS="-b $SSH_ECDSA_BITS" + fi ;; *) # wrong argument exit 12 ;; esac @@ -25,7 +31,7 @@ fi rm -f $KEY{,.pub} # create new keys -if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then +if ! $KEYGEN -q -t $KEYTYPE $SSH_KEYGEN_OPTIONS -f $KEY -C '' -N '' >&/dev/null; then exit 1 fi diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 904d8c1..7e106f4 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -5,3 +5,6 @@ # 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 diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch deleted file mode 100644 index 1242aac..0000000 --- a/openssh-7.4p1-systemd.patch +++ /dev/null @@ -1,98 +0,0 @@ -commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31 -Author: Jakub Jelen -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 - #endif - -+#ifdef HAVE_SYSTEMD -+#include -+#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); diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 748c4b6..cec5b23 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -2206,8 +2206,8 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2098,7 +2154,7 @@ main(int ac, char **av) - #endif +@@ -2189,7 +2189,7 @@ + } /* Accept a connection and return in a forked child */ - server_accept_loop(&sock_in, &sock_out, diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 5351571..b1007b2 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -81,7 +81,7 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c #include +#include #include - # ifdef HAVE_EVP_KDF_CTX_NEW_ID + # ifdef HAVE_EVP_KDF_CTX_NEW # include @@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch index 5d76a4f..c22b210 100644 --- a/openssh-8.0p1-openssl-kdf.patch +++ b/openssh-8.0p1-openssl-kdf.patch @@ -12,7 +12,7 @@ index 2a455e4e..e01c3d43 100644 HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ -+ EVP_KDF_CTX_new_id \ ++ EVP_KDF_CTX_new \ ]) # OpenSSL_add_all_algorithms may be a macro. @@ -20,33 +20,35 @@ diff --git a/kex.c b/kex.c index b6f041f4..1fbce2bb 100644 --- a/kex.c +++ b/kex.c -@@ -38,6 +38,9 @@ +@@ -38,6 +38,11 @@ #ifdef WITH_OPENSSL #include #include -+# ifdef HAVE_EVP_KDF_CTX_NEW_ID ++# ifdef HAVE_EVP_KDF_CTX_NEW +# include ++# include ++# include +# endif #endif #include "ssh.h" -@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh) +@@ -942,6 +945,107 @@ kex_choose_conf(struct ssh *ssh) return r; } -+#ifdef HAVE_EVP_KDF_CTX_NEW_ID -+static const EVP_MD * ++#ifdef HAVE_EVP_KDF_CTX_NEW ++static const char * +digest_to_md(int digest_type) +{ + switch (digest_type) { + case SSH_DIGEST_SHA1: -+ return EVP_sha1(); ++ return SN_sha1; + case SSH_DIGEST_SHA256: -+ return EVP_sha256(); ++ return SN_sha256; + case SSH_DIGEST_SHA384: -+ return EVP_sha384(); ++ return SN_sha384; + case SSH_DIGEST_SHA512: -+ return EVP_sha512(); ++ return SN_sha512; + } + return NULL; +} @@ -56,52 +58,62 @@ index b6f041f4..1fbce2bb 100644 + 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; ++ 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; + } + -+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); -+ if (!ctx) { ++ 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; + } + -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg)); -+ if (r != 1) { ++ params = OSSL_PARAM_BLD_to_param(param_bld); ++ if (params == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, -+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, -+ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ r = EVP_KDF_derive(ctx, key, key_len); ++ r = EVP_KDF_derive(ctx, key, key_len, params); + if (r != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; @@ -115,6 +127,8 @@ index b6f041f4..1fbce2bb 100644 + r = 0; + +out: ++ OSSL_PARAM_BLD_free(param_bld); ++ OSSL_PARAM_free(params); + free (key); + EVP_KDF_CTX_free(ctx); + if (r < 0) { @@ -130,7 +144,7 @@ index b6f041f4..1fbce2bb 100644 ssh_digest_free(hashctx); return r; } -+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */ ++#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW */ #define NKEYS 6 int diff --git a/openssh-8.7p1-audit-hostname.patch b/openssh-8.7p1-audit-hostname.patch new file mode 100644 index 0000000..e450c00 --- /dev/null +++ b/openssh-8.7p1-audit-hostname.patch @@ -0,0 +1,106 @@ +diff --color -ruNp a/audit-linux.c b/audit-linux.c +--- a/audit-linux.c 2024-05-09 12:38:08.843017319 +0200 ++++ b/audit-linux.c 2024-05-09 12:47:05.162267634 +0200 +@@ -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 c + } + 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); + +@@ -181,9 +181,11 @@ audit_run_command(struct ssh *ssh, const + { + if (!user_login_count++) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_LOGIN); + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_START); + return 0; +@@ -193,10 +195,12 @@ void + audit_end_command(struct ssh *ssh, int handle, const char *command) + { + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ options.use_dns ? remote_hostname(ssh) : NULL, + 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, ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_LOGOUT); + } +@@ -211,19 +215,27 @@ 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); + } + +@@ -236,6 +248,7 @@ audit_event(struct ssh *ssh, ssh_audit_e + linux_audit_user_auth(-1, audit_username(), + ssh_remote_ipaddr(ssh), "ssh", 0, event); + linux_audit_user_logxxx(-1, audit_username(), ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); + break; + case SSH_AUTH_FAIL_PASSWD: +@@ -254,9 +267,11 @@ audit_event(struct ssh *ssh, ssh_audit_e + if (user_login_count) { + while (user_login_count--) + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_END); + linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), + "ssh", 1, AUDIT_USER_LOGOUT); + } +@@ -265,6 +280,7 @@ audit_event(struct ssh *ssh, ssh_audit_e + case SSH_CONNECTION_ABANDON: + case SSH_INVALID_USER: + linux_audit_user_logxxx(-1, audit_username(), ++ options.use_dns ? remote_hostname(ssh) : NULL, + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); + break; + default: diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch index 7fea800..6a6b63d 100644 --- a/openssh-8.7p1-nohostsha1proof.patch +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -241,10 +241,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); diff --git a/openssh-9.6p1-cve-2024-6387.patch b/openssh-9.6p1-cve-2024-6387.patch deleted file mode 100644 index 646cf7c..0000000 --- a/openssh-9.6p1-cve-2024-6387.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/log.c b/log.c -index 9fc1a2e2e..191ff4a5a 100644 ---- a/log.c -+++ b/log.c -@@ -451,12 +451,14 @@ void - sshsigdie(const char *file, const char *func, int line, int showfunc, - LogLevel level, const char *suffix, const char *fmt, ...) - { -+#ifdef SYSLOG_R_SAFE_IN_SIGHAND - va_list args; - - va_start(args, fmt); - sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL, - suffix, fmt, args); - va_end(args); -+#endif - _exit(1); - } - -diff --git a/clientloop.c b/clientloop.c -index 8ec36af94..6dcd6c853 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -608,8 +608,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, - if (timespeccmp(&now, &chaff_until, >=)) { - /* Stop if there have been no keystrokes for a while */ - stop_reason = "chaff time expired"; -- } else if (timespeccmp(&now, &next_interval, >=)) { -- /* Otherwise if we were due to send, then send chaff */ -+ } else if (timespeccmp(&now, &next_interval, >=) && -+ !ssh_packet_have_data_to_write(ssh)) { -+ /* If due to send but have no data, then send chaff */ - if (send_chaff(ssh)) - nchaff++; - } diff --git a/openssh-9.6p1-gsissh.patch b/openssh-9.6p1-gsissh.patch index 4929e40..a2d2eff 100644 --- a/openssh-9.6p1-gsissh.patch +++ b/openssh-9.6p1-gsissh.patch @@ -1,6 +1,6 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c ---- openssh-9.6p1.orig/auth2.c 2024-07-06 07:19:36.958049782 +0200 -+++ openssh-9.6p1/auth2.c 2024-07-06 07:20:29.705200575 +0200 +--- openssh-9.6p1.orig/auth2.c 2024-07-07 07:25:31.581747706 +0200 ++++ openssh-9.6p1/auth2.c 2024-07-07 07:26:28.481916473 +0200 @@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -102,8 +102,8 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c authctxt->user, authctxt->service, user, service); } diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c ---- openssh-9.6p1.orig/auth2-gss.c 2024-07-06 07:19:36.850049473 +0200 -+++ openssh-9.6p1/auth2-gss.c 2024-07-06 07:20:29.705200575 +0200 +--- openssh-9.6p1.orig/auth2-gss.c 2024-07-07 07:25:31.469747374 +0200 ++++ openssh-9.6p1/auth2-gss.c 2024-07-07 07:26:28.482916477 +0200 @@ -52,6 +52,7 @@ extern ServerOptions options; @@ -309,8 +309,8 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c "gssapi-keyex", NULL, diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c ---- openssh-9.6p1.orig/auth.c 2024-07-06 07:19:36.958049782 +0200 -+++ openssh-9.6p1/auth.c 2024-07-06 07:20:29.706200578 +0200 +--- openssh-9.6p1.orig/auth.c 2024-07-07 07:25:31.582747709 +0200 ++++ openssh-9.6p1/auth.c 2024-07-07 07:26:28.482916477 +0200 @@ -299,7 +299,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -342,8 +342,8 @@ diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); diff -Nur openssh-9.6p1.orig/auth.h openssh-9.6p1/auth.h ---- openssh-9.6p1.orig/auth.h 2024-07-06 07:19:36.959049785 +0200 -+++ openssh-9.6p1/auth.h 2024-07-06 07:20:29.706200578 +0200 +--- openssh-9.6p1.orig/auth.h 2024-07-07 07:25:31.582747709 +0200 ++++ openssh-9.6p1/auth.h 2024-07-07 07:26:28.483916479 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -354,8 +354,8 @@ diff -Nur openssh-9.6p1.orig/auth.h openssh-9.6p1/auth.h #endif struct sshbuf *loginmsg; diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c ---- openssh-9.6p1.orig/auth-pam.c 2024-07-06 07:19:36.944049742 +0200 -+++ openssh-9.6p1/auth-pam.c 2024-07-06 07:20:29.707200580 +0200 +--- openssh-9.6p1.orig/auth-pam.c 2024-07-07 07:25:31.623747830 +0200 ++++ openssh-9.6p1/auth-pam.c 2024-07-07 07:26:28.483916479 +0200 @@ -252,6 +252,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; @@ -485,7 +485,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c + /* Save so allowed_user can be called later */ + sshpam_ssh = ssh; } - if (sshpam_rhost != NULL) { + if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); @@ -1096,6 +1176,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, @@ -517,8 +517,8 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c free(fake); if (sshpam_err == PAM_MAXTRIES) diff -Nur openssh-9.6p1.orig/auth-pam.h openssh-9.6p1/auth-pam.h ---- openssh-9.6p1.orig/auth-pam.h 2024-07-06 07:19:36.818049382 +0200 -+++ openssh-9.6p1/auth-pam.h 2024-07-06 07:20:29.708200583 +0200 +--- openssh-9.6p1.orig/auth-pam.h 2024-07-07 07:25:31.437747279 +0200 ++++ openssh-9.6p1/auth-pam.h 2024-07-07 07:26:28.484916482 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -527,8 +527,8 @@ diff -Nur openssh-9.6p1.orig/auth-pam.h openssh-9.6p1/auth-pam.h #endif /* USE_PAM */ diff -Nur openssh-9.6p1.orig/canohost.c openssh-9.6p1/canohost.c ---- openssh-9.6p1.orig/canohost.c 2024-07-06 07:19:36.850049473 +0200 -+++ openssh-9.6p1/canohost.c 2024-07-06 07:20:29.708200583 +0200 +--- openssh-9.6p1.orig/canohost.c 2024-07-07 07:25:31.470747377 +0200 ++++ openssh-9.6p1/canohost.c 2024-07-07 07:26:28.484916482 +0200 @@ -17,6 +17,7 @@ #include #include @@ -572,8 +572,8 @@ diff -Nur openssh-9.6p1.orig/canohost.c openssh-9.6p1/canohost.c + } +} diff -Nur openssh-9.6p1.orig/canohost.h openssh-9.6p1/canohost.h ---- openssh-9.6p1.orig/canohost.h 2024-07-06 07:19:36.850049473 +0200 -+++ openssh-9.6p1/canohost.h 2024-07-06 07:20:29.709200586 +0200 +--- openssh-9.6p1.orig/canohost.h 2024-07-07 07:25:31.470747377 +0200 ++++ openssh-9.6p1/canohost.h 2024-07-07 07:26:28.484916482 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -582,9 +582,9 @@ diff -Nur openssh-9.6p1.orig/canohost.h openssh-9.6p1/canohost.h + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac ---- openssh-9.6p1.orig/configure.ac 2024-07-06 07:19:36.936049719 +0200 -+++ openssh-9.6p1/configure.ac 2024-07-06 07:20:29.710200589 +0200 -@@ -4865,6 +4865,14 @@ +--- openssh-9.6p1.orig/configure.ac 2024-07-07 07:25:31.559747641 +0200 ++++ openssh-9.6p1/configure.ac 2024-07-07 07:26:28.486916488 +0200 +@@ -4866,6 +4866,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -599,9 +599,9 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4930,6 +4938,40 @@ - ) - +@@ -4907,6 +4915,40 @@ + AC_SUBST([K5LIBS]) + AC_SUBST([CHANNELLIBS]) +# Check whether the user wants GSI (Globus) support +gsi="no" @@ -641,8 +641,8 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac PRIVSEP_PATH=/var/empty diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c ---- openssh-9.6p1.orig/gss-genr.c 2024-07-06 07:19:37.001049905 +0200 -+++ openssh-9.6p1/gss-genr.c 2024-07-06 07:20:29.711200592 +0200 +--- openssh-9.6p1.orig/gss-genr.c 2024-07-07 07:25:31.626747839 +0200 ++++ openssh-9.6p1/gss-genr.c 2024-07-07 07:26:28.486916488 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -651,7 +651,7 @@ diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c #include "ssh2.h" #include "cipher.h" #include "sshkey.h" -@@ -409,9 +410,18 @@ +@@ -416,9 +417,18 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; @@ -671,7 +671,7 @@ diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); -@@ -419,6 +429,7 @@ +@@ -426,6 +436,7 @@ &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); @@ -680,8 +680,8 @@ diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c return (ctx->major); } diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c ---- openssh-9.6p1.orig/gss-serv.c 2024-07-06 07:19:36.870049530 +0200 -+++ openssh-9.6p1/gss-serv.c 2024-07-06 07:20:29.712200595 +0200 +--- openssh-9.6p1.orig/gss-serv.c 2024-07-07 07:25:31.489747433 +0200 ++++ openssh-9.6p1/gss-serv.c 2024-07-07 07:26:28.487916491 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -964,7 +964,7 @@ diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c diff -Nur openssh-9.6p1.orig/gss-serv-gsi.c openssh-9.6p1/gss-serv-gsi.c --- openssh-9.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/gss-serv-gsi.c 2024-07-06 07:20:29.712200595 +0200 ++++ openssh-9.6p1/gss-serv-gsi.c 2024-07-07 07:26:28.488916494 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1295,8 +1295,8 @@ diff -Nur openssh-9.6p1.orig/gss-serv-gsi.c openssh-9.6p1/gss-serv-gsi.c +#endif /* GSI */ +#endif /* GSSAPI */ diff -Nur openssh-9.6p1.orig/gss-serv-krb5.c openssh-9.6p1/gss-serv-krb5.c ---- openssh-9.6p1.orig/gss-serv-krb5.c 2024-07-06 07:19:36.892049593 +0200 -+++ openssh-9.6p1/gss-serv-krb5.c 2024-07-06 07:20:29.713200598 +0200 +--- openssh-9.6p1.orig/gss-serv-krb5.c 2024-07-07 07:25:31.515747510 +0200 ++++ openssh-9.6p1/gss-serv-krb5.c 2024-07-07 07:26:28.488916494 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1351,8 +1351,8 @@ diff -Nur openssh-9.6p1.orig/gss-serv-krb5.c openssh-9.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_updatecreds }; diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c ---- openssh-9.6p1.orig/kexgsss.c 2024-07-06 07:19:36.855049488 +0200 -+++ openssh-9.6p1/kexgsss.c 2024-07-06 07:20:29.713200598 +0200 +--- openssh-9.6p1.orig/kexgsss.c 2024-07-07 07:25:31.497747457 +0200 ++++ openssh-9.6p1/kexgsss.c 2024-07-07 08:04:49.351732601 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1360,27 +1360,36 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c +static void kex_gss_send_error(Gssctxt *ctxt, struct ssh *ssh); extern ServerOptions options; - int -@@ -96,8 +97,10 @@ + static int input_kexgss_init(int, u_int32_t, struct ssh *); +@@ -81,8 +82,10 @@ debug2_f("Acquiring credentials"); -- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) { -+ kex_gss_send_error(ctxt, ssh); +- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) { ++ kex_gss_send_error(kex->gss, ssh); fatal("Unable to acquire credentials for the server"); + } - do { - debug("Wait SSH2_MSG_KEXGSS_INIT"); -@@ -195,13 +198,14 @@ - } while (maj_status & GSS_S_CONTINUE_NEEDED); + ssh_gssapi_build_ctx(&kex->gss); + if (kex->gss == NULL) +@@ -127,7 +130,7 @@ + gss_buffer_desc *send_tok, + OM_uint32 *ret_flags) + { +- struct kex *kex = ssh->kex; ++struct kex *kex = ssh->kex; + Gssctxt *gss = kex->gss; + gss_buffer_desc msg_tok; + int r; +@@ -136,13 +139,14 @@ + ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); - if (GSS_ERROR(maj_status)) { -+ kex_gss_send_error(ctxt, ssh); - if (send_tok.length > 0) { + if (GSS_ERROR(gss->major)) { ++ kex_gss_send_error(kex->gss, ssh); + if (send_tok->length > 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || - (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || + (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("sshpkt failed: %s", ssh_err(r)); } @@ -1388,12 +1397,11 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c + ssh_packet_disconnect(ssh, "GSSAPI Key Exchange handshake failed"); } - if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -479,4 +483,26 @@ - sshbuf_free(shared_secret); - return r; + if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) +@@ -587,4 +591,26 @@ + return kexgssgex_final(ssh, &send_tok, &ret_flags); } -+ + +static void +kex_gss_send_error(Gssctxt *ctxt, struct ssh *ssh) { + char *errstr; @@ -1415,10 +1423,11 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c + free(errstr); + } +} ++ #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in ---- openssh-9.6p1.orig/Makefile.in 2024-07-06 07:19:36.961049790 +0200 -+++ openssh-9.6p1/Makefile.in 2024-07-06 07:20:29.713200598 +0200 +--- openssh-9.6p1.orig/Makefile.in 2024-07-07 07:25:31.584747715 +0200 ++++ openssh-9.6p1/Makefile.in 2024-07-07 07:26:28.489916497 +0200 @@ -130,6 +130,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o \ @@ -1428,8 +1437,8 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c ---- openssh-9.6p1.orig/misc.c 2024-07-06 07:19:37.002049908 +0200 -+++ openssh-9.6p1/misc.c 2024-07-06 07:20:29.714200600 +0200 +--- openssh-9.6p1.orig/misc.c 2024-07-07 07:25:31.628747845 +0200 ++++ openssh-9.6p1/misc.c 2024-07-07 07:26:28.490916500 +0200 @@ -419,11 +419,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1490,8 +1499,8 @@ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h ---- openssh-9.6p1.orig/misc.h 2024-07-06 07:19:36.911049648 +0200 -+++ openssh-9.6p1/misc.h 2024-07-06 07:20:29.715200603 +0200 +--- openssh-9.6p1.orig/misc.h 2024-07-07 07:25:31.534747567 +0200 ++++ openssh-9.6p1/misc.h 2024-07-07 07:26:28.490916500 +0200 @@ -103,6 +103,7 @@ void sock_set_v6only(int); @@ -1501,8 +1510,8 @@ diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h typedef void privdrop_fn(struct passwd *); diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c ---- openssh-9.6p1.orig/monitor.c 2024-07-06 07:19:37.002049908 +0200 -+++ openssh-9.6p1/monitor.c 2024-07-06 07:20:29.716200606 +0200 +--- openssh-9.6p1.orig/monitor.c 2024-07-07 07:25:31.628747845 +0200 ++++ openssh-9.6p1/monitor.c 2024-07-07 07:26:28.491916503 +0200 @@ -149,6 +149,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -1673,8 +1682,8 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c { gss_buffer_desc data; diff -Nur openssh-9.6p1.orig/monitor.h openssh-9.6p1/monitor.h ---- openssh-9.6p1.orig/monitor.h 2024-07-06 07:19:36.962049793 +0200 -+++ openssh-9.6p1/monitor.h 2024-07-06 07:20:29.716200606 +0200 +--- openssh-9.6p1.orig/monitor.h 2024-07-07 07:25:31.585747718 +0200 ++++ openssh-9.6p1/monitor.h 2024-07-07 07:26:28.492916506 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1687,8 +1696,8 @@ diff -Nur openssh-9.6p1.orig/monitor.h openssh-9.6p1/monitor.h struct ssh; diff -Nur openssh-9.6p1.orig/monitor_wrap.c openssh-9.6p1/monitor_wrap.c ---- openssh-9.6p1.orig/monitor_wrap.c 2024-07-06 07:19:36.968049810 +0200 -+++ openssh-9.6p1/monitor_wrap.c 2024-07-06 07:20:29.716200606 +0200 +--- openssh-9.6p1.orig/monitor_wrap.c 2024-07-07 07:25:31.592747738 +0200 ++++ openssh-9.6p1/monitor_wrap.c 2024-07-07 07:26:28.492916506 +0200 @@ -1083,6 +1083,94 @@ return (authenticated); } @@ -1785,8 +1794,8 @@ diff -Nur openssh-9.6p1.orig/monitor_wrap.c openssh-9.6p1/monitor_wrap.c mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { diff -Nur openssh-9.6p1.orig/monitor_wrap.h openssh-9.6p1/monitor_wrap.h ---- openssh-9.6p1.orig/monitor_wrap.h 2024-07-06 07:19:36.968049810 +0200 -+++ openssh-9.6p1/monitor_wrap.h 2024-07-06 07:20:29.717200609 +0200 +--- openssh-9.6p1.orig/monitor_wrap.h 2024-07-07 07:25:31.592747738 +0200 ++++ openssh-9.6p1/monitor_wrap.h 2024-07-07 07:26:28.493916509 +0200 @@ -73,6 +73,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1799,8 +1808,8 @@ diff -Nur openssh-9.6p1.orig/monitor_wrap.h openssh-9.6p1/monitor_wrap.h #endif diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c ---- openssh-9.6p1.orig/readconf.c 2024-07-06 07:19:37.004049913 +0200 -+++ openssh-9.6p1/readconf.c 2024-07-06 07:20:29.718200612 +0200 +--- openssh-9.6p1.orig/readconf.c 2024-07-07 07:25:31.629747848 +0200 ++++ openssh-9.6p1/readconf.c 2024-07-07 07:26:28.493916509 +0200 @@ -2723,11 +2723,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; @@ -1817,8 +1826,8 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h ---- openssh-9.6p1.orig/readconf.h 2024-07-06 07:19:36.858049496 +0200 -+++ openssh-9.6p1/readconf.h 2024-07-06 07:20:29.718200612 +0200 +--- openssh-9.6p1.orig/readconf.h 2024-07-07 07:25:31.477747397 +0200 ++++ openssh-9.6p1/readconf.h 2024-07-07 07:26:28.494916512 +0200 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1829,8 +1838,8 @@ diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c ---- openssh-9.6p1.orig/servconf.c 2024-07-06 07:19:37.004049913 +0200 -+++ openssh-9.6p1/servconf.c 2024-07-06 07:20:29.719200615 +0200 +--- openssh-9.6p1.orig/servconf.c 2024-07-07 07:25:31.630747851 +0200 ++++ openssh-9.6p1/servconf.c 2024-07-07 07:26:28.495916515 +0200 @@ -92,6 +92,7 @@ /* Portable-specific options */ @@ -2002,8 +2011,8 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h ---- openssh-9.6p1.orig/servconf.h 2024-07-06 07:19:36.904049628 +0200 -+++ openssh-9.6p1/servconf.h 2024-07-06 07:20:29.719200615 +0200 +--- openssh-9.6p1.orig/servconf.h 2024-07-07 07:25:31.526747543 +0200 ++++ openssh-9.6p1/servconf.h 2024-07-07 07:26:28.495916515 +0200 @@ -144,9 +144,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2026,8 +2035,8 @@ diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h int permit_tun; diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 ---- openssh-9.6p1.orig/ssh.1 2024-07-06 07:19:36.983049853 +0200 -+++ openssh-9.6p1/ssh.1 2024-07-06 07:20:29.720200618 +0200 +--- openssh-9.6p1.orig/ssh.1 2024-07-07 07:25:31.608747786 +0200 ++++ openssh-9.6p1/ssh.1 2024-07-07 07:26:28.496916518 +0200 @@ -1528,6 +1528,18 @@ on to new connections). .It Ev USER @@ -2048,8 +2057,8 @@ diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 .Pp Additionally, diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c ---- openssh-9.6p1.orig/ssh.c 2024-07-06 07:19:36.977049836 +0200 -+++ openssh-9.6p1/ssh.c 2024-07-06 07:20:29.720200618 +0200 +--- openssh-9.6p1.orig/ssh.c 2024-07-07 07:25:31.602747768 +0200 ++++ openssh-9.6p1/ssh.c 2024-07-07 07:26:28.496916518 +0200 @@ -573,6 +573,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2104,8 +2113,8 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. diff -Nur openssh-9.6p1.orig/ssh_config openssh-9.6p1/ssh_config ---- openssh-9.6p1.orig/ssh_config 2024-07-06 07:19:36.860049502 +0200 -+++ openssh-9.6p1/ssh_config 2024-07-06 07:20:29.721200620 +0200 +--- openssh-9.6p1.orig/ssh_config 2024-07-07 07:25:31.479747403 +0200 ++++ openssh-9.6p1/ssh_config 2024-07-07 07:26:28.496916518 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2120,8 +2129,8 @@ diff -Nur openssh-9.6p1.orig/ssh_config openssh-9.6p1/ssh_config # BatchMode no # CheckHostIP no diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 ---- openssh-9.6p1.orig/ssh_config.5 2024-07-06 07:19:36.928049696 +0200 -+++ openssh-9.6p1/ssh_config.5 2024-07-06 07:20:29.721200620 +0200 +--- openssh-9.6p1.orig/ssh_config.5 2024-07-07 07:25:31.551747617 +0200 ++++ openssh-9.6p1/ssh_config.5 2024-07-07 07:26:28.497916521 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2169,8 +2178,8 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .Ed .It Cm ProxyCommand diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c ---- openssh-9.6p1.orig/sshconnect2.c 2024-07-06 07:19:36.995049888 +0200 -+++ openssh-9.6p1/sshconnect2.c 2024-07-06 07:20:29.722200623 +0200 +--- openssh-9.6p1.orig/sshconnect2.c 2024-07-07 07:25:31.620747821 +0200 ++++ openssh-9.6p1/sshconnect2.c 2024-07-07 07:26:28.498916524 +0200 @@ -863,6 +863,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2239,8 +2248,8 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 ---- openssh-9.6p1.orig/sshd.8 2024-07-06 07:19:36.875049545 +0200 -+++ openssh-9.6p1/sshd.8 2024-07-06 07:20:29.722200623 +0200 +--- openssh-9.6p1.orig/sshd.8 2024-07-07 07:25:31.494747448 +0200 ++++ openssh-9.6p1/sshd.8 2024-07-07 07:26:28.498916524 +0200 @@ -839,6 +839,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2272,9 +2281,9 @@ diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 .Bl -tag -width Ds -compact .It Pa ~/.hushlogin diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c ---- openssh-9.6p1.orig/sshd.c 2024-07-06 07:19:37.006049919 +0200 -+++ openssh-9.6p1/sshd.c 2024-07-06 07:20:29.723200626 +0200 -@@ -2438,7 +2438,7 @@ +--- openssh-9.6p1.orig/sshd.c 2024-07-07 07:25:31.631747854 +0200 ++++ openssh-9.6p1/sshd.c 2024-07-07 07:26:28.498916524 +0200 +@@ -2431,7 +2431,7 @@ #endif #ifdef GSSAPI @@ -2284,8 +2293,8 @@ diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config ---- openssh-9.6p1.orig/sshd_config 2024-07-06 07:19:36.894049599 +0200 -+++ openssh-9.6p1/sshd_config 2024-07-06 07:20:29.723200626 +0200 +--- openssh-9.6p1.orig/sshd_config 2024-07-07 07:25:31.517747516 +0200 ++++ openssh-9.6p1/sshd_config 2024-07-07 07:26:28.499916527 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2312,8 +2321,8 @@ diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config #AllowTcpForwarding yes #GatewayPorts no diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 ---- openssh-9.6p1.orig/sshd_config.5 2024-07-06 07:19:36.928049696 +0200 -+++ openssh-9.6p1/sshd_config.5 2024-07-06 07:20:29.724200629 +0200 +--- openssh-9.6p1.orig/sshd_config.5 2024-07-07 07:25:31.552747620 +0200 ++++ openssh-9.6p1/sshd_config.5 2024-07-07 07:26:28.499916527 +0200 @@ -716,15 +716,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2373,8 +2382,8 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. diff -Nur openssh-9.6p1.orig/sshd_config_redhat openssh-9.6p1/sshd_config_redhat ---- openssh-9.6p1.orig/sshd_config_redhat 2024-07-06 07:19:36.845049459 +0200 -+++ openssh-9.6p1/sshd_config_redhat 2024-07-06 07:20:29.724200629 +0200 +--- openssh-9.6p1.orig/sshd_config_redhat 2024-07-07 07:25:31.464747359 +0200 ++++ openssh-9.6p1/sshd_config_redhat 2024-07-07 07:26:28.499916527 +0200 @@ -2,9 +2,6 @@ ChallengeResponseAuthentication no @@ -2386,9 +2395,9 @@ diff -Nur openssh-9.6p1.orig/sshd_config_redhat openssh-9.6p1/sshd_config_redhat X11Forwarding yes diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h ---- openssh-9.6p1.orig/ssh-gss.h 2024-07-06 07:19:36.873049539 +0200 -+++ openssh-9.6p1/ssh-gss.h 2024-07-06 07:20:29.724200629 +0200 -@@ -97,12 +97,14 @@ +--- openssh-9.6p1.orig/ssh-gss.h 2024-07-07 07:25:31.498747460 +0200 ++++ openssh-9.6p1/ssh-gss.h 2024-07-07 07:26:28.500916530 +0200 +@@ -99,12 +99,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -2404,7 +2413,7 @@ diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h int used; int updated; } ssh_gssapi_client; -@@ -123,7 +125,7 @@ +@@ -125,7 +127,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2413,7 +2422,7 @@ diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -161,6 +163,9 @@ +@@ -173,6 +175,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2425,7 +2434,7 @@ diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h const char *); diff -Nur openssh-9.6p1.orig/version.h openssh-9.6p1/version.h --- openssh-9.6p1.orig/version.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/version.h 2024-07-06 07:20:29.725200632 +0200 ++++ openssh-9.6p1/version.h 2024-07-07 07:26:28.500916530 +0200 @@ -2,5 +2,19 @@ #define SSH_VERSION "OpenSSH_9.6" diff --git a/openssh-9.6p1-gsskex-new-api.patch b/openssh-9.6p1-gsskex-new-api.patch new file mode 100644 index 0000000..ed09319 --- /dev/null +++ b/openssh-9.6p1-gsskex-new-api.patch @@ -0,0 +1,1965 @@ +diff --color -ruNp a/gss-genr.c b/gss-genr.c +--- a/gss-genr.c 2024-05-16 15:49:43.999411060 +0200 ++++ b/gss-genr.c 2024-06-26 12:17:55.586856954 +0200 +@@ -346,6 +346,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) + (*ctx)->creds = GSS_C_NO_CREDENTIAL; + (*ctx)->client = GSS_C_NO_NAME; + (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; ++ (*ctx)->first = 1; + } + + /* Delete our context, providing it has been built correctly */ +@@ -371,6 +372,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) + gss_release_name(&ms, &(*ctx)->client); + if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->client_creds); ++ sshbuf_free((*ctx)->shared_secret); ++ sshbuf_free((*ctx)->server_pubkey); ++ sshbuf_free((*ctx)->server_host_key_blob); ++ sshbuf_free((*ctx)->server_blob); ++ explicit_bzero((*ctx)->hash, sizeof((*ctx)->hash)); ++ BN_clear_free((*ctx)->dh_client_pub); + + free(*ctx); + *ctx = NULL; +diff --color -ruNp a/kexgssc.c b/kexgssc.c +--- a/kexgssc.c 2024-05-16 15:49:43.820407648 +0200 ++++ b/kexgssc.c 2024-07-02 16:26:25.628746744 +0200 +@@ -47,566 +47,658 @@ + + #include "ssh-gss.h" + +-int +-kexgss_client(struct ssh *ssh) ++static int input_kexgss_hostkey(int, u_int32_t, struct ssh *); ++static int input_kexgss_continue(int, u_int32_t, struct ssh *); ++static int input_kexgss_complete(int, u_int32_t, struct ssh *); ++static int input_kexgss_error(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_group(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_complete(int, u_int32_t, struct ssh *); ++ ++static int ++kexgss_final(struct ssh *ssh) + { + struct kex *kex = ssh->kex; +- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, +- recv_tok = GSS_C_EMPTY_BUFFER, +- gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; +- Gssctxt *ctxt; +- OM_uint32 maj_status, min_status, ret_flags; +- struct sshbuf *server_blob = NULL; +- struct sshbuf *shared_secret = NULL; +- struct sshbuf *server_host_key_blob = NULL; ++ Gssctxt *gss = kex->gss; + struct sshbuf *empty = NULL; +- u_char *msg; +- int type = 0; +- int first = 1; ++ struct sshbuf *shared_secret = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t hashlen; +- u_char c; + int r; + +- /* Initialise our GSSAPI world */ +- ssh_gssapi_build_ctx(&ctxt); +- if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) +- == GSS_C_NO_OID) +- fatal("Couldn't identify host exchange"); +- +- if (ssh_gssapi_import_name(ctxt, kex->gss_host)) +- fatal("Couldn't import hostname"); +- +- if (kex->gss_client && +- ssh_gssapi_client_identity(ctxt, kex->gss_client)) +- fatal("Couldn't acquire client credentials"); +- +- /* Step 1 */ +- switch (kex->kex_type) { +- case KEX_GSS_GRP1_SHA1: +- case KEX_GSS_GRP14_SHA1: +- case KEX_GSS_GRP14_SHA256: +- case KEX_GSS_GRP16_SHA512: +- r = kex_dh_keypair(kex); +- break; +- case KEX_GSS_NISTP256_SHA256: +- r = kex_ecdh_keypair(kex); +- break; +- case KEX_GSS_C25519_SHA256: +- r = kex_c25519_keypair(kex); +- break; +- default: +- fatal_f("Unexpected KEX type %d", kex->kex_type); +- } +- if (r != 0) { +- ssh_gssapi_delete_ctx(&ctxt); +- return r; +- } +- +- token_ptr = GSS_C_NO_BUFFER; +- +- do { +- debug("Calling gss_init_sec_context"); +- +- maj_status = ssh_gssapi_init_ctx(ctxt, +- kex->gss_deleg_creds, token_ptr, &send_tok, +- &ret_flags); +- +- if (GSS_ERROR(maj_status)) { +- /* XXX Useles code: Missing send? */ +- if (send_tok.length != 0) { +- if ((r = sshpkt_start(ssh, +- SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, +- send_tok.length)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- } +- fatal("gss_init_context failed"); +- } +- +- /* If we've got an old receive buffer get rid of it */ +- if (token_ptr != GSS_C_NO_BUFFER) +- gss_release_buffer(&min_status, &recv_tok); +- +- if (maj_status == GSS_S_COMPLETE) { +- /* If mutual state flag is not true, kex fails */ +- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) +- fatal("Mutual authentication failed"); +- +- /* If integ avail flag is not true kex fails */ +- if (!(ret_flags & GSS_C_INTEG_FLAG)) +- fatal("Integrity check failed"); +- } +- +- /* +- * If we have data to send, then the last message that we +- * received cannot have been a 'complete'. +- */ +- if (send_tok.length != 0) { +- if (first) { +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, +- send_tok.length)) != 0 || +- (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) +- fatal("failed to construct packet: %s", ssh_err(r)); +- first = 0; +- } else { +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, +- send_tok.length)) != 0) +- fatal("failed to construct packet: %s", ssh_err(r)); +- } +- if ((r = sshpkt_send(ssh)) != 0) +- fatal("failed to send packet: %s", ssh_err(r)); +- gss_release_buffer(&min_status, &send_tok); +- +- /* If we've sent them data, they should reply */ +- do { +- type = ssh_packet_read(ssh); +- if (type == SSH2_MSG_KEXGSS_HOSTKEY) { +- u_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_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); +- +- switch (type) { +- case SSH2_MSG_KEXGSS_CONTINUE: +- debug("Received GSSAPI_CONTINUE"); +- if (maj_status == GSS_S_COMPLETE) +- fatal("GSSAPI Continue received from server when complete"); +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &recv_tok)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("Failed to read token: %s", ssh_err(r)); +- break; +- case SSH2_MSG_KEXGSS_COMPLETE: +- debug("Received GSSAPI_COMPLETE"); +- if (msg_tok.value != NULL) +- fatal("Received GSSAPI_COMPLETE twice?"); +- if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || +- (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &msg_tok)) != 0) +- fatal("Failed to read message: %s", ssh_err(r)); +- +- /* Is there a token included? */ +- if ((r = sshpkt_get_u8(ssh, &c)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- if (c) { +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc( +- ssh, &recv_tok)) != 0) +- fatal("Failed to read token: %s", ssh_err(r)); +- /* If we're already complete - protocol error */ +- if (maj_status == GSS_S_COMPLETE) +- sshpkt_disconnect(ssh, "Protocol error: received token when complete"); +- } else { +- /* No token included */ +- if (maj_status != GSS_S_COMPLETE) +- sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); +- } +- if ((r = sshpkt_get_end(ssh)) != 0) { +- fatal("Expecting end of packet."); +- } +- break; +- case SSH2_MSG_KEXGSS_ERROR: +- debug("Received Error"); +- if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || +- (r = sshpkt_get_u32(ssh, &min_status)) != 0 || +- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || +- (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt_get failed: %s", ssh_err(r)); +- fatal("GSSAPI Error: \n%.400s", msg); +- default: +- sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", +- type); +- } +- token_ptr = &recv_tok; +- } else { +- /* No data, and not complete */ +- if (maj_status != GSS_S_COMPLETE) +- fatal("Not complete, and no token output"); +- } +- } while (maj_status & GSS_S_CONTINUE_NEEDED); +- + /* + * We _must_ have received a COMPLETE message in reply from the + * server, which will have set server_blob and msg_tok + */ + +- if (type != SSH2_MSG_KEXGSS_COMPLETE) +- fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); +- + /* compute shared secret */ + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: + case KEX_GSS_GRP14_SHA256: + case KEX_GSS_GRP16_SHA512: +- r = kex_dh_dec(kex, server_blob, &shared_secret); ++ r = kex_dh_dec(kex, gss->server_blob, &shared_secret); + break; + case KEX_GSS_C25519_SHA256: +- if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80) ++ if (sshbuf_ptr(gss->server_blob)[sshbuf_len(gss->server_blob)] & 0x80) + fatal("The received key has MSB of last octet set!"); +- r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ r = kex_c25519_dec(kex, gss->server_blob, &shared_secret); + break; + case KEX_GSS_NISTP256_SHA256: +- if (sshbuf_len(server_blob) != 65) +- fatal("The received NIST-P256 key did not match" +- "expected length (expected 65, got %zu)", sshbuf_len(server_blob)); ++ if (sshbuf_len(gss->server_blob) != 65) ++ fatal("The received NIST-P256 key did not match " ++ "expected length (expected 65, got %zu)", ++ sshbuf_len(gss->server_blob)); + +- if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) ++ if (sshbuf_ptr(gss->server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) + fatal("The received NIST-P256 key does not have first octet 0x04"); + +- r = kex_ecdh_dec(kex, server_blob, &shared_secret); ++ r = kex_ecdh_dec(kex, gss->server_blob, &shared_secret); + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; + break; + } +- if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); + goto out; ++ } + + if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + + hashlen = sizeof(hash); +- if ((r = kex_gen_hash( +- kex->hash_alg, +- kex->client_version, +- kex->server_version, +- kex->my, +- kex->peer, +- (server_host_key_blob ? server_host_key_blob : empty), +- kex->client_pub, +- server_blob, +- shared_secret, +- hash, &hashlen)) != 0) ++ r = kex_gen_hash(kex->hash_alg, kex->client_version, ++ kex->server_version, kex->my, kex->peer, ++ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), ++ kex->client_pub, gss->server_blob, shared_secret, ++ hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) + fatal_f("Unexpected KEX type %d", kex->kex_type); + +- gssbuf.value = hash; +- gssbuf.length = hashlen; ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; + + /* Verify that the hash matches the MIC we just got. */ +- if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) + sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); + +- gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, &gss->msg_tok); + + if (kex->gss_deleg_creds) +- ssh_gssapi_credentials_updated(ctxt); ++ ssh_gssapi_credentials_updated(gss); + + if (gss_kex_context == NULL) +- gss_kex_context = ctxt; ++ gss_kex_context = gss; + else +- ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + ++ if (kex->gss != NULL) { ++ sshbuf_free(gss->server_host_key_blob); ++ gss->server_host_key_blob = NULL; ++ sshbuf_free(gss->server_blob); ++ gss->server_blob = NULL; ++ } + out: +- explicit_bzero(hash, sizeof(hash)); + explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); +- sshbuf_free(empty); +- sshbuf_free(server_host_key_blob); +- sshbuf_free(server_blob); ++ explicit_bzero(hash, sizeof(hash)); + sshbuf_free(shared_secret); + sshbuf_free(kex->client_pub); + kex->client_pub = NULL; + return r; + } + ++static int ++kexgss_init_ctx(struct ssh *ssh, ++ gss_buffer_desc *token_ptr) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags; ++ int r; ++ ++ debug("Calling gss_init_sec_context"); ++ ++ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, ++ token_ptr, &send_tok, &ret_flags); ++ ++ if (GSS_ERROR(gss->major)) { ++ /* XXX Useless code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&gss->minor, token_ptr); ++ ++ if (gss->major == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (gss->first) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ gss->first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("failed to send packet: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgss_complete); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); ++ return 0; ++ } ++ /* No data, and not complete */ ++ if (gss->major != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgss_init_ctx(ssh, token_ptr); ++ ++ return kexgss_final(ssh); ++} ++ + int +-kexgssgex_client(struct ssh *ssh) ++kexgss_client(struct ssh *ssh) + { + struct kex *kex = ssh->kex; +- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, +- recv_tok = GSS_C_EMPTY_BUFFER, gssbuf, +- msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; +- Gssctxt *ctxt; +- OM_uint32 maj_status, min_status, ret_flags; +- struct sshbuf *shared_secret = NULL; +- BIGNUM *p = NULL; +- BIGNUM *g = NULL; +- struct sshbuf *buf = NULL; +- struct sshbuf *server_host_key_blob = NULL; +- struct sshbuf *server_blob = NULL; +- BIGNUM *dh_server_pub = NULL; +- u_char *msg; +- int type = 0; +- int first = 1; +- u_char hash[SSH_DIGEST_MAX_LENGTH]; +- size_t hashlen; +- const BIGNUM *pub_key, *dh_p, *dh_g; +- int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; +- struct sshbuf *empty = NULL; +- u_char c; + int r; + + /* Initialise our GSSAPI world */ +- ssh_gssapi_build_ctx(&ctxt); +- if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) +- == GSS_C_NO_OID) ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) + fatal("Couldn't identify host exchange"); + +- if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) + fatal("Couldn't import hostname"); + + if (kex->gss_client && +- ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) + fatal("Couldn't acquire client credentials"); + +- debug("Doing group exchange"); +- nbits = dh_estimate(kex->dh_need * 8); ++ /* Step 1 */ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_keypair(kex); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ r = kex_ecdh_keypair(kex); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ r = kex_c25519_keypair(kex); ++ break; ++ default: ++ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ } ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return r; ++ } ++ return kexgss_init_ctx(ssh, GSS_C_NO_BUFFER); ++} + +- kex->min = DH_GRP_MIN; +- kex->max = DH_GRP_MAX; +- kex->nbits = nbits; +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || +- (r = sshpkt_put_u32(ssh, min)) != 0 || +- (r = sshpkt_put_u32(ssh, nbits)) != 0 || +- (r = sshpkt_put_u32(ssh, max)) != 0 || +- (r = sshpkt_send(ssh)) != 0) +- fatal("Failed to construct a packet: %s", ssh_err(r)); ++static int ++input_kexgss_hostkey(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ u_char *tmp = NULL; ++ size_t tmp_len = 0; ++ int r; ++ ++ debug("Received KEXGSS_HOSTKEY"); ++ if (gss->server_host_key_blob) ++ fatal("Server host key received more than once"); ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) ++ fatal("Failed to read server host key: %s", ssh_err(r)); ++ if ((gss->server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); ++ return 0; ++} + +- if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0) +- fatal("Error: %s", ssh_err(r)); ++static int ++input_kexgss_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ int r; + +- if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || +- (r = sshpkt_get_bignum2(ssh, &g)) != 0 || ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); ++ ++ debug("Received GSSAPI_CONTINUE"); ++ if (gss->major == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) +- fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); ++ fatal("Failed to read token: %s", ssh_err(r)); ++ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ return kexgss_init_ctx(ssh, &recv_tok); ++} + +- if (BN_num_bits(p) < min || BN_num_bits(p) > max) +- fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", +- min, BN_num_bits(p), max); ++static int ++input_kexgss_complete(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ u_char c; ++ int r; + +- if ((kex->dh = dh_new_group(g, p)) == NULL) +- fatal("dn_new_group() failed"); +- p = g = NULL; /* belong to kex->dh now */ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); ++ ++ debug("Received GSSAPI_COMPLETE"); ++ if (gss->msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) ++ fatal("Failed to read message: %s", ssh_err(r)); ++ ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (gss->major == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ if (gss->major != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); ++ } ++ if ((r = sshpkt_get_end(ssh)) != 0) ++ fatal("Expecting end of packet."); + +- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) +- goto out; +- DH_get0_key(kex->dh, &pub_key, NULL); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgss_init_ctx(ssh, &recv_tok); + +- token_ptr = GSS_C_NO_BUFFER; ++ return kexgss_final(ssh); ++} + +- do { +- /* Step 2 - call GSS_Init_sec_context() */ +- debug("Calling gss_init_sec_context"); +- +- maj_status = ssh_gssapi_init_ctx(ctxt, +- kex->gss_deleg_creds, token_ptr, &send_tok, +- &ret_flags); +- +- if (GSS_ERROR(maj_status)) { +- /* XXX Useles code: Missing send? */ +- if (send_tok.length != 0) { +- if ((r = sshpkt_start(ssh, +- SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, +- send_tok.length)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- } +- fatal("gss_init_context failed"); +- } ++static int ++input_kexgss_error(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ u_char *msg; ++ int r; + +- /* If we've got an old receive buffer get rid of it */ +- if (token_ptr != GSS_C_NO_BUFFER) +- gss_release_buffer(&min_status, &recv_tok); +- +- if (maj_status == GSS_S_COMPLETE) { +- /* If mutual state flag is not true, kex fails */ +- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) +- fatal("Mutual authentication failed"); +- +- /* If integ avail flag is not true kex fails */ +- if (!(ret_flags & GSS_C_INTEG_FLAG)) +- fatal("Integrity check failed"); +- } ++ debug("Received Error"); ++ if ((r = sshpkt_get_u32(ssh, &gss->major)) != 0 || ++ (r = sshpkt_get_u32(ssh, &gss->minor)) != 0 || ++ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || ++ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt_get failed: %s", ssh_err(r)); ++ fatal("GSSAPI Error: \n%.400s", msg); ++ return 0; ++} + +- /* +- * If we have data to send, then the last message that we +- * received cannot have been a 'complete'. +- */ +- if (send_tok.length != 0) { +- if (first) { +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, +- send_tok.length)) != 0 || +- (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- first = 0; +- } else { +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh,send_tok.value, +- send_tok.length)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- } +- if ((r = sshpkt_send(ssh)) != 0) +- fatal("sshpkt_send failed: %s", ssh_err(r)); +- gss_release_buffer(&min_status, &send_tok); +- +- /* If we've sent them data, they should reply */ +- do { +- type = ssh_packet_read(ssh); +- if (type == SSH2_MSG_KEXGSS_HOSTKEY) { +- u_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_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); +- +- switch (type) { +- case SSH2_MSG_KEXGSS_CONTINUE: +- debug("Received GSSAPI_CONTINUE"); +- if (maj_status == GSS_S_COMPLETE) +- fatal("GSSAPI Continue received from server when complete"); +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &recv_tok)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- break; +- case SSH2_MSG_KEXGSS_COMPLETE: +- debug("Received GSSAPI_COMPLETE"); +- if (msg_tok.value != NULL) +- fatal("Received GSSAPI_COMPLETE twice?"); +- if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || +- (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &msg_tok)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- +- /* Is there a token included? */ +- if ((r = sshpkt_get_u8(ssh, &c)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- if (c) { +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc( +- ssh, &recv_tok)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- /* If we're already complete - protocol error */ +- if (maj_status == GSS_S_COMPLETE) +- sshpkt_disconnect(ssh, "Protocol error: received token when complete"); +- } else { +- /* No token included */ +- if (maj_status != GSS_S_COMPLETE) +- sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); +- } +- break; +- case SSH2_MSG_KEXGSS_ERROR: +- debug("Received Error"); +- if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || +- (r = sshpkt_get_u32(ssh, &min_status)) != 0 || +- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || +- (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- fatal("GSSAPI Error: \n%.400s", msg); +- default: +- sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", +- type); +- } +- token_ptr = &recv_tok; +- } else { +- /* No data, and not complete */ +- if (maj_status != GSS_S_COMPLETE) +- fatal("Not complete, and no token output"); +- } +- } while (maj_status & GSS_S_CONTINUE_NEEDED); ++/*******************************************************/ ++/******************** KEXGSSGEX ************************/ ++/*******************************************************/ ++ ++int ++kexgssgex_client(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ int r; ++ ++ /* Initialise our GSSAPI world */ ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) ++ fatal("Couldn't identify host exchange"); ++ ++ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) ++ fatal("Couldn't import hostname"); ++ ++ if (kex->gss_client && ++ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) ++ fatal("Couldn't acquire client credentials"); ++ ++ debug("Doing group exchange"); ++ kex->min = DH_GRP_MIN; ++ kex->max = DH_GRP_MAX; ++ kex->nbits = dh_estimate(kex->dh_need * 8); ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->min)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->max)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("Failed to construct a packet: %s", ssh_err(r)); ++ ++ debug("Wait SSH2_MSG_KEXGSS_GROUP"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, &input_kexgssgex_group); ++ return 0; ++} ++ ++static int ++kexgssgex_final(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ struct sshbuf *buf = NULL; ++ struct sshbuf *empty = NULL; ++ struct sshbuf *shared_secret = NULL; ++ BIGNUM *dh_server_pub = NULL; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ int r; + + /* + * We _must_ have received a COMPLETE message in reply from the +- * server, which will have set dh_server_pub and msg_tok ++ * server, which will have set server_blob and msg_tok + */ + +- if (type != SSH2_MSG_KEXGSS_COMPLETE) +- fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); +- + /* 7. C verifies that the key Q_S is valid */ + /* 8. C computes shared secret */ + if ((buf = sshbuf_new()) == NULL || +- (r = sshbuf_put_stringb(buf, server_blob)) != 0 || +- (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) ++ (r = sshbuf_put_stringb(buf, gss->server_blob)) != 0 || ++ (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); + goto out; ++ } + sshbuf_free(buf); + buf = NULL; + + if ((shared_secret = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + +- if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) ++ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); + goto out; ++ } ++ + if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + ++ DH_get0_key(kex->dh, &pub_key, NULL); + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); + hashlen = sizeof(hash); +- if ((r = kexgex_hash( +- kex->hash_alg, +- kex->client_version, +- kex->server_version, +- kex->my, +- kex->peer, +- (server_host_key_blob ? server_host_key_blob : empty), +- kex->min, kex->nbits, kex->max, +- dh_p, dh_g, +- pub_key, +- dh_server_pub, +- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), +- hash, &hashlen)) != 0) ++ r = kexgex_hash(kex->hash_alg, kex->client_version, ++ kex->server_version, kex->my, kex->peer, ++ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), ++ kex->min, kex->nbits, kex->max, dh_p, dh_g, pub_key, ++ dh_server_pub, sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), ++ hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) + fatal("Failed to calculate hash: %s", ssh_err(r)); + +- gssbuf.value = hash; +- gssbuf.length = hashlen; ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; + + /* Verify that the hash matches the MIC we just got. */ +- if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) + sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); + +- gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, &gss->msg_tok); + + if (kex->gss_deleg_creds) +- ssh_gssapi_credentials_updated(ctxt); ++ ssh_gssapi_credentials_updated(gss); + + if (gss_kex_context == NULL) +- gss_kex_context = ctxt; ++ gss_kex_context = gss; + else +- ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + + /* Finally derive the keys and send them */ + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); ++ ++ if (kex->gss != NULL) { ++ sshbuf_free(gss->server_host_key_blob); ++ gss->server_host_key_blob = NULL; ++ sshbuf_free(gss->server_blob); ++ gss->server_blob = NULL; ++ } + out: +- sshbuf_free(buf); +- sshbuf_free(server_blob); +- sshbuf_free(empty); + explicit_bzero(hash, sizeof(hash)); + DH_free(kex->dh); + kex->dh = NULL; + BN_clear_free(dh_server_pub); + sshbuf_free(shared_secret); +- sshbuf_free(server_host_key_blob); + return r; + } + ++static int ++kexgssgex_init_ctx(struct ssh *ssh, ++ gss_buffer_desc *token_ptr) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ const BIGNUM *pub_key; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags; ++ int r; ++ ++ /* Step 2 - call GSS_Init_sec_context() */ ++ debug("Calling gss_init_sec_context"); ++ ++ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, ++ token_ptr, &send_tok, &ret_flags); ++ ++ if (GSS_ERROR(gss->major)) { ++ /* XXX Useless code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&gss->minor, token_ptr); ++ ++ if (gss->major == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (gss->first) { ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ gss->first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("failed to send packet: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgssgex_complete); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); ++ return 0; ++ } ++ /* No data, and not complete */ ++ if (gss->major != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgssgex_init_ctx(ssh, token_ptr); ++ ++ return kexgssgex_final(ssh); ++} ++ ++static int ++input_kexgssgex_group(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ BIGNUM *p = NULL; ++ BIGNUM *g = NULL; ++ int r; ++ ++ debug("Received SSH2_MSG_KEXGSS_GROUP"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, NULL); ++ ++ if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || ++ (r = sshpkt_get_bignum2(ssh, &g)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); ++ ++ if (BN_num_bits(p) < kex->min || BN_num_bits(p) > kex->max) ++ fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", ++ kex->min, BN_num_bits(p), kex->max); ++ ++ if ((kex->dh = dh_new_group(g, p)) == NULL) ++ fatal("dn_new_group() failed"); ++ p = g = NULL; /* belong to kex->dh now */ ++ ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ return r; ++ } ++ ++ return kexgssgex_init_ctx(ssh, GSS_C_NO_BUFFER); ++} ++ ++static int ++input_kexgssgex_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ int r; ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); ++ ++ debug("Received GSSAPI_CONTINUE"); ++ if (gss->major == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ return kexgssgex_init_ctx(ssh, &recv_tok); ++} ++ ++static int ++input_kexgssgex_complete(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ u_char c; ++ int r; ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); ++ ++ debug("Received GSSAPI_COMPLETE"); ++ if (gss->msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) ++ fatal("Failed to read message: %s", ssh_err(r)); ++ ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (gss->major == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ if (gss->major != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); ++ } ++ if ((r = sshpkt_get_end(ssh)) != 0) ++ fatal("Expecting end of packet."); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgssgex_init_ctx(ssh, &recv_tok); ++ ++ return kexgssgex_final(ssh); ++} ++ + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ +diff --color -ruNp a/kexgsss.c b/kexgsss.c +--- a/kexgsss.c 2024-05-16 15:49:43.820407648 +0200 ++++ b/kexgsss.c 2024-07-02 16:29:05.744790839 +0200 +@@ -50,33 +50,18 @@ + + extern ServerOptions options; + ++static int input_kexgss_init(int, u_int32_t, struct ssh *); ++static int input_kexgss_continue(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_groupreq(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_init(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); ++ + int + kexgss_server(struct ssh *ssh) + { + struct kex *kex = ssh->kex; +- OM_uint32 maj_status, min_status; +- +- /* +- * Some GSSAPI implementations use the input value of ret_flags (an +- * output variable) as a means of triggering mechanism specific +- * features. Initializing it to zero avoids inadvertently +- * activating this non-standard behaviour. +- */ +- +- OM_uint32 ret_flags = 0; +- 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; +- struct sshbuf *client_pubkey = NULL; +- struct sshbuf *server_pubkey = NULL; +- struct sshbuf *empty = sshbuf_new(); +- int type = 0; + gss_OID oid; + char *mechs; +- u_char hash[SSH_DIGEST_MAX_LENGTH]; +- size_t hashlen; +- int r; + + /* Initialise GSSAPI */ + +@@ -92,135 +77,91 @@ kexgss_server(struct ssh *ssh) + debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) +- fatal("Unknown gssapi mechanism"); ++ fatal("Unknown gssapi mechanism"); + + debug2_f("Acquiring credentials"); + +- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) + fatal("Unable to acquire credentials for the server"); + +- do { +- debug("Wait SSH2_MSG_KEXGSS_INIT"); +- type = ssh_packet_read(ssh); +- switch(type) { +- case SSH2_MSG_KEXGSS_INIT: +- if (gssbuf.value != NULL) +- fatal("Received KEXGSS_INIT after initialising"); +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &recv_tok)) != 0 || +- (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (kex->gss == NULL) ++ fatal("Unable to allocate memory for gss context"); ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgss_init); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); ++ debug("Wait SSH2_MSG_KEXGSS_INIT"); ++ return 0; ++} + +- switch (kex->kex_type) { +- case KEX_GSS_GRP1_SHA1: +- case KEX_GSS_GRP14_SHA1: +- case KEX_GSS_GRP14_SHA256: +- case KEX_GSS_GRP16_SHA512: +- r = kex_dh_enc(kex, client_pubkey, &server_pubkey, +- &shared_secret); +- break; +- case KEX_GSS_NISTP256_SHA256: +- r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, +- &shared_secret); +- break; +- case KEX_GSS_C25519_SHA256: +- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, +- &shared_secret); +- break; +- default: +- fatal_f("Unexpected KEX type %d", kex->kex_type); +- } +- if (r != 0) +- 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, +- &recv_tok)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- break; +- default: +- sshpkt_disconnect(ssh, +- "Protocol error: didn't expect packet type %d", +- type); +- } ++static inline void ++kexgss_accept_ctx(struct ssh *ssh, ++ gss_buffer_desc *recv_tok, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ int r; + +- maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, +- &send_tok, &ret_flags)); ++ gss->major = PRIVSEP(ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags)); ++ gss_release_buffer(&gss->minor, recv_tok); + +- gss_release_buffer(&min_status, &recv_tok); ++ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) ++ fatal("Zero length token output when incomplete"); + +- if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) +- fatal("Zero length token output when incomplete"); ++ if (gss->buf.value == NULL) ++ fatal("No client public key"); + +- if (gssbuf.value == NULL) +- fatal("No client public key"); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, send_tok); ++ } ++} + +- if (maj_status & GSS_S_CONTINUE_NEEDED) { +- debug("Sending GSSAPI_CONTINUE"); +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || +- (r = sshpkt_send(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- gss_release_buffer(&min_status, &send_tok); +- } +- } while (maj_status & GSS_S_CONTINUE_NEEDED); ++static inline int ++kexgss_final(struct ssh *ssh, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc msg_tok; ++ int r; ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); + +- if (GSS_ERROR(maj_status)) { +- if (send_tok.length > 0) { ++ if (GSS_ERROR(gss->major)) { ++ if (send_tok->length > 0) { + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } + fatal("accept_ctx died"); + } + +- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) + fatal("Mutual Authentication flag wasn't set"); + +- if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ 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(PRIVSEP(ssh_gssapi_sign(gss, &gss->buf, &msg_tok)))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || +- (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || ++ (r = sshpkt_put_stringb(ssh, gss->server_pubkey)) != 0 || + (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + +- if (send_tok.length != 0) { ++ if (send_tok->length != 0) { + if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } else { + if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ +@@ -229,59 +170,139 @@ kexgss_server(struct ssh *ssh) + if ((r = sshpkt_send(ssh)) != 0) + fatal("sshpkt_send failed: %s", ssh_err(r)); + +- gss_release_buffer(&min_status, &send_tok); +- gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, send_tok); ++ gss_release_buffer(&gss->minor, &msg_tok); + + if (gss_kex_context == NULL) +- gss_kex_context = ctxt; ++ gss_kex_context = gss; + else +- ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + +- if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ if ((r = kex_derive_keys(ssh, gss->hash, gss->hashlen, gss->shared_secret)) == 0) + r = kex_send_newkeys(ssh); + + /* If this was a rekey, then save out any delegated credentials we + * just exchanged. */ + if (options.gss_store_rekey) + ssh_gssapi_rekey_creds(); +-out: +- sshbuf_free(empty); +- explicit_bzero(hash, sizeof(hash)); +- sshbuf_free(shared_secret); +- sshbuf_free(client_pubkey); +- sshbuf_free(server_pubkey); ++ ++ if (kex->gss != NULL) { ++ explicit_bzero(gss->hash, sizeof(gss->hash)); ++ sshbuf_free(gss->shared_secret); ++ gss->shared_secret = NULL; ++ sshbuf_free(gss->server_pubkey); ++ gss->server_pubkey = NULL; ++ } + return r; + } + +-int +-kexgssgex_server(struct ssh *ssh) ++static int ++input_kexgss_init(int type, ++ u_int32_t seq, ++ struct ssh *ssh) + { + struct kex *kex = ssh->kex; +- OM_uint32 maj_status, min_status; ++ Gssctxt *gss = kex->gss; ++ struct sshbuf *empty; ++ struct sshbuf *client_pubkey = NULL; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ debug("SSH2_MSG_KEXGSS_INIT received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); + +- /* +- * Some GSSAPI implementations use the input value of ret_flags (an +- * output variable) as a means of triggering mechanism specific +- * features. Initializing it to zero avoids inadvertently +- * activating this non-standard behaviour. ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ r = kex_ecdh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ r = kex_c25519_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ default: ++ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ } ++ if (r != 0) { ++ sshbuf_free(client_pubkey); ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return r; ++ } ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ if ((empty = sshbuf_new()) == NULL) { ++ sshbuf_free(client_pubkey); ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return SSH_ERR_ALLOC_FAIL; ++ } ++ ++ /* Calculate the hash early so we can free the ++ * client_pubkey, which has reference to the parent ++ * buffer state->incoming_packet + */ ++ gss->hashlen = sizeof(gss->hash); ++ r = kex_gen_hash(kex->hash_alg, kex->client_version, kex->server_version, ++ kex->peer, kex->my, empty, client_pubkey, gss->server_pubkey, ++ gss->shared_secret, gss->hash, &gss->hashlen); ++ sshbuf_free(empty); ++ sshbuf_free(client_pubkey); ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return r; ++ } ++ ++ gss->buf.value = gss->hash; ++ gss->buf.length = gss->hashlen; ++ ++ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; + ++ return kexgss_final(ssh, &send_tok, &ret_flags); ++} ++ ++static int ++input_kexgss_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; + OM_uint32 ret_flags = 0; +- gss_buffer_desc gssbuf, recv_tok, msg_tok; +- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; +- Gssctxt *ctxt = NULL; +- struct sshbuf *shared_secret = NULL; +- int type = 0; ++ int r; ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgss_final(ssh, &send_tok, &ret_flags); ++} ++ ++/*******************************************************/ ++/******************** KEXGSSGEX ************************/ ++/*******************************************************/ ++ ++int ++kexgssgex_server(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; + gss_OID oid; + char *mechs; +- u_char hash[SSH_DIGEST_MAX_LENGTH]; +- size_t hashlen; +- BIGNUM *dh_client_pub = NULL; +- const BIGNUM *pub_key, *dh_p, *dh_g; +- int min = -1, max = -1, nbits = -1; +- int cmin = -1, cmax = -1; /* client proposal */ +- struct sshbuf *empty = sshbuf_new(); +- int r; + + /* Initialise GSSAPI */ + +@@ -289,153 +310,125 @@ kexgssgex_server(struct ssh *ssh) + * in the GSSAPI code are no longer available. This kludges them back + * into life + */ +- if (!ssh_gssapi_oid_table_ok()) +- if ((mechs = ssh_gssapi_server_mechanisms())) +- free(mechs); ++ if (!ssh_gssapi_oid_table_ok()) { ++ mechs = ssh_gssapi_server_mechanisms(); ++ free(mechs); ++ } + + debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) +- fatal("Unknown gssapi mechanism"); ++ fatal("Unknown gssapi mechanism"); + + debug2_f("Acquiring credentials"); + +- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) + fatal("Unable to acquire credentials for the server"); + +- /* 5. S generates an ephemeral key pair (do the allocations early) */ +- debug("Doing group exchange"); +- ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ); +- /* store client proposal to provide valid signature */ +- if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || +- (r = sshpkt_get_u32(ssh, &nbits)) != 0 || +- (r = sshpkt_get_u32(ssh, &cmax)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- kex->nbits = nbits; +- kex->min = cmin; +- kex->max = cmax; +- min = MAX(DH_GRP_MIN, cmin); +- max = MIN(DH_GRP_MAX, cmax); +- nbits = MAXIMUM(DH_GRP_MIN, nbits); +- nbits = MINIMUM(DH_GRP_MAX, nbits); +- 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)); +- if (kex->dh == NULL) { +- sshpkt_disconnect(ssh, "Protocol error: no matching group found"); +- fatal("Protocol error: no matching group found"); +- } ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (kex->gss == NULL) ++ fatal("Unable to allocate memory for gss context"); + +- DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || +- (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || +- (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || +- (r = sshpkt_send(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- +- if ((r = ssh_packet_write_wait(ssh)) != 0) +- fatal("ssh_packet_write_wait: %s", ssh_err(r)); +- +- /* Compute our exchange value in parallel with the client */ +- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) +- goto out; ++ debug("Doing group exchange"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, &input_kexgssgex_groupreq); ++ return 0; ++} + +- do { +- debug("Wait SSH2_MSG_GSSAPI_INIT"); +- type = ssh_packet_read(ssh); +- switch(type) { +- case SSH2_MSG_KEXGSS_INIT: +- if (dh_client_pub != NULL) +- fatal("Received KEXGSS_INIT after initialising"); +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &recv_tok)) != 0 || +- (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); ++static inline void ++kexgssgex_accept_ctx(struct ssh *ssh, ++ gss_buffer_desc *recv_tok, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ int r; + +- /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ +- break; +- case SSH2_MSG_KEXGSS_CONTINUE: +- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, +- &recv_tok)) != 0 || +- (r = sshpkt_get_end(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- break; +- default: +- sshpkt_disconnect(ssh, +- "Protocol error: didn't expect packet type %d", +- type); +- } ++ gss->major = PRIVSEP(ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags)); ++ gss_release_buffer(&gss->minor, recv_tok); + +- maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, +- &send_tok, &ret_flags)); ++ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) ++ fatal("Zero length token output when incomplete"); + +- gss_release_buffer(&min_status, &recv_tok); ++ if (gss->dh_client_pub == NULL) ++ fatal("No client public key"); + +- if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) +- fatal("Zero length token output when incomplete"); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, send_tok); ++ } ++} + +- if (dh_client_pub == NULL) +- fatal("No client public key"); ++static inline int ++kexgssgex_final(struct ssh *ssh, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc msg_tok; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ struct sshbuf *shared_secret = NULL; ++ struct sshbuf *empty = NULL; ++ int r; + +- if (maj_status & GSS_S_CONTINUE_NEEDED) { +- debug("Sending GSSAPI_CONTINUE"); +- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || +- (r = sshpkt_send(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); +- gss_release_buffer(&min_status, &send_tok); +- } +- } while (maj_status & GSS_S_CONTINUE_NEEDED); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); + +- if (GSS_ERROR(maj_status)) { +- if (send_tok.length > 0) { ++ if (GSS_ERROR(gss->major)) { ++ if (send_tok->length > 0) { + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } + fatal("accept_ctx died"); + } + +- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) + fatal("Mutual Authentication flag wasn't set"); + +- if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ if (!(*ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + + /* calculate shared secret */ +- if ((shared_secret = sshbuf_new()) == NULL) { ++ shared_secret = sshbuf_new(); ++ if (shared_secret == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) ++ if ((r = kex_dh_compute_key(kex, gss->dh_client_pub, shared_secret)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); + goto out; ++ } ++ ++ if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + + DH_get0_key(kex->dh, &pub_key, NULL); + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); + hashlen = sizeof(hash); +- if ((r = kexgex_hash( +- kex->hash_alg, +- kex->client_version, +- kex->server_version, +- kex->peer, +- kex->my, +- empty, +- cmin, nbits, cmax, +- dh_p, dh_g, +- dh_client_pub, +- pub_key, +- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), +- hash, &hashlen)) != 0) ++ r = kexgex_hash(kex->hash_alg, kex->client_version, kex->server_version, ++ kex->peer, kex->my, empty, kex->min, kex->nbits, kex->max, dh_p, dh_g, ++ gss->dh_client_pub, pub_key, sshbuf_ptr(shared_secret), ++ sshbuf_len(shared_secret), hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) + fatal("kexgex_hash failed: %s", ssh_err(r)); + +- gssbuf.value = hash; +- gssbuf.length = hashlen; ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; + +- if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(gss, &gss->buf, &msg_tok)))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || +@@ -443,24 +436,24 @@ kexgssgex_server(struct ssh *ssh) + (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + +- if (send_tok.length != 0) { ++ if (send_tok->length != 0) { + if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ +- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } else { + if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ + fatal("sshpkt failed: %s", ssh_err(r)); + } + if ((r = sshpkt_send(ssh)) != 0) +- fatal("sshpkt failed: %s", ssh_err(r)); ++ fatal("sshpkt_send failed: %s", ssh_err(r)); + +- gss_release_buffer(&min_status, &send_tok); +- gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, send_tok); ++ gss_release_buffer(&gss->minor, &msg_tok); + + if (gss_kex_context == NULL) +- gss_kex_context = ctxt; ++ gss_kex_context = gss; + else +- ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + + /* Finally derive the keys and send them */ + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) +@@ -470,13 +463,128 @@ kexgssgex_server(struct ssh *ssh) + * just exchanged. */ + if (options.gss_store_rekey) + ssh_gssapi_rekey_creds(); ++ ++ if (kex->gss != NULL) ++ BN_clear_free(gss->dh_client_pub); ++ + out: +- sshbuf_free(empty); + explicit_bzero(hash, sizeof(hash)); + DH_free(kex->dh); + kex->dh = NULL; +- BN_clear_free(dh_client_pub); + sshbuf_free(shared_secret); + return r; + } ++ ++static int ++input_kexgssgex_groupreq(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ const BIGNUM *dh_p, *dh_g; ++ int min = -1, max = -1, nbits = -1; ++ int cmin = -1, cmax = -1; /* client proposal */ ++ int r; ++ ++ /* 5. S generates an ephemeral key pair (do the allocations early) */ ++ ++ debug("SSH2_MSG_KEXGSS_GROUPREQ received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, NULL); ++ ++ /* store client proposal to provide valid signature */ ++ if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || ++ (r = sshpkt_get_u32(ssh, &nbits)) != 0 || ++ (r = sshpkt_get_u32(ssh, &cmax)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ kex->nbits = nbits; ++ kex->min = cmin; ++ kex->max = cmax; ++ min = MAX(DH_GRP_MIN, cmin); ++ max = MIN(DH_GRP_MAX, cmax); ++ nbits = MAXIMUM(DH_GRP_MIN, nbits); ++ nbits = MINIMUM(DH_GRP_MAX, nbits); ++ ++ 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)); ++ if (kex->dh == NULL) { ++ sshpkt_disconnect(ssh, "Protocol error: no matching group found"); ++ fatal("Protocol error: no matching group found"); ++ } ++ ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ if ((r = ssh_packet_write_wait(ssh)) != 0) ++ fatal("ssh_packet_write_wait: %s", ssh_err(r)); ++ ++ /* Compute our exchange value in parallel with the client */ ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ return r; ++ } ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgssgex_init); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); ++ debug("Wait SSH2_MSG_KEXGSS_INIT"); ++ return 0; ++} ++ ++static int ++input_kexgssgex_init(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ debug("SSH2_MSG_KEXGSS_INIT received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_bignum2(ssh, &gss->dh_client_pub)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgssgex_final(ssh, &send_tok, &ret_flags); ++} ++ ++static int ++input_kexgssgex_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgssgex_final(ssh, &send_tok, &ret_flags); ++} ++ + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ +diff --color -ruNp a/kex.h b/kex.h +--- a/kex.h 2024-05-16 15:49:43.986410812 +0200 ++++ b/kex.h 2024-06-18 12:19:48.580347469 +0200 +@@ -29,6 +29,10 @@ + #include "mac.h" + #include "crypto_api.h" + ++#ifdef GSSAPI ++# include "ssh-gss.h" /* Gssctxt */ ++#endif ++ + #ifdef WITH_OPENSSL + # include + # include +@@ -177,6 +181,7 @@ struct kex { + int hash_alg; + int ec_nid; + #ifdef GSSAPI ++ Gssctxt *gss; + int gss_deleg_creds; + int gss_trust_dns; + char *gss_host; +diff --color -ruNp a/ssh-gss.h b/ssh-gss.h +--- a/ssh-gss.h 2024-05-16 15:49:43.837407972 +0200 ++++ b/ssh-gss.h 2024-06-27 14:12:48.659866937 +0200 +@@ -88,6 +88,8 @@ extern char **k5users_allowed_cmds; + KEX_GSS_GRP14_SHA1_ID "," \ + KEX_GSS_GEX_SHA1_ID + ++#include "digest.h" /* SSH_DIGEST_MAX_LENGTH */ ++ + typedef struct { + char *filename; + char *envvar; +@@ -127,6 +129,16 @@ typedef struct { + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ + gss_cred_id_t client_creds; /* both */ ++ struct sshbuf *shared_secret; /* both */ ++ struct sshbuf *server_pubkey; /* server */ ++ struct sshbuf *server_blob; /* client */ ++ struct sshbuf *server_host_key_blob; /* client */ ++ gss_buffer_desc msg_tok; /* client */ ++ gss_buffer_desc buf; /* both */ ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; /* both */ ++ size_t hashlen; /* both */ ++ int first; /* client */ ++ BIGNUM *dh_client_pub; /* server (gex) */ + } Gssctxt; + + extern ssh_gssapi_mech *supported_mechs[]; diff --git a/openssh-9.6p1-pam-rhost.patch b/openssh-9.6p1-pam-rhost.patch new file mode 100644 index 0000000..b1b0d04 --- /dev/null +++ b/openssh-9.6p1-pam-rhost.patch @@ -0,0 +1,32 @@ +From 26f366e263e575c4e1a18e2e64ba418f58878b37 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +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 + diff --git a/openssh-9.8p1-systemd.patch b/openssh-9.8p1-systemd.patch new file mode 100644 index 0000000..b20624e --- /dev/null +++ b/openssh-9.8p1-systemd.patch @@ -0,0 +1,201 @@ +diff --git a/configure.ac b/configure.ac +index 379cd746b..15e2ecdb7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -907,6 +907,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) + AC_DEFINE([USE_BTMP]) + AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) ++ AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) + inet6_default_4in6=yes + case `uname -r` in + 1.*|2.0.*) +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 0457e28d0..df7290246 100644 +--- a/openbsd-compat/port-linux.c ++++ b/openbsd-compat/port-linux.c +@@ -21,16 +21,23 @@ + + #include "includes.h" + +-#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) ++#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \ ++ defined(SYSTEMD_NOTIFY) ++#include ++#include ++ + #include ++#include + #include + #include + #include + #include ++#include + + #include "log.h" + #include "xmalloc.h" + #include "port-linux.h" ++#include "misc.h" + + #ifdef WITH_SELINUX + #include +@@ -310,4 +317,90 @@ oom_adjust_restore(void) + return; + } + #endif /* LINUX_OOM_ADJUST */ +-#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ ++ ++#ifdef SYSTEMD_NOTIFY ++ ++static void ssh_systemd_notify(const char *, ...) ++ __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1))); ++ ++static void ++ssh_systemd_notify(const char *fmt, ...) ++{ ++ char *s = NULL; ++ const char *path; ++ struct stat sb; ++ struct sockaddr_un addr; ++ int fd = -1; ++ va_list ap; ++ ++ if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0) ++ return; ++ ++ va_start(ap, fmt); ++ xvasprintf(&s, fmt, ap); ++ va_end(ap); ++ ++ /* Only AF_UNIX is supported, with path or abstract sockets */ ++ if (path[0] != '/' && path[0] != '@') { ++ error_f("socket \"%s\" is not compatible with AF_UNIX", path); ++ goto out; ++ } ++ ++ if (path[0] == '/' && stat(path, &sb) != 0) { ++ error_f("socket \"%s\" stat: %s", path, strerror(errno)); ++ goto out; ++ } ++ ++ memset(&addr, 0, sizeof(addr)); ++ addr.sun_family = AF_UNIX; ++ if (strlcpy(addr.sun_path, path, ++ sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) { ++ error_f("socket path \"%s\" too long", path); ++ goto out; ++ } ++ /* Support for abstract socket */ ++ if (addr.sun_path[0] == '@') ++ addr.sun_path[0] = 0; ++ if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) { ++ error_f("socket \"%s\": %s", path, strerror(errno)); ++ goto out; ++ } ++ if (connect(fd, &addr, sizeof(addr)) != 0) { ++ error_f("socket \"%s\" connect: %s", path, strerror(errno)); ++ goto out; ++ } ++ if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) { ++ error_f("socket \"%s\" write: %s", path, strerror(errno)); ++ goto out; ++ } ++ debug_f("socket \"%s\" notified %s", path, s); ++ out: ++ if (fd != -1) ++ close(fd); ++ free(s); ++} ++ ++void ++ssh_systemd_notify_ready(void) ++{ ++ ssh_systemd_notify("READY=1"); ++} ++ ++void ++ssh_systemd_notify_reload(void) ++{ ++ struct timespec now; ++ ++ monotime_ts(&now); ++ if (now.tv_sec < 0 || now.tv_nsec < 0) { ++ error_f("monotime returned negative value"); ++ ssh_systemd_notify("RELOADING=1"); ++ } else { ++ ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu", ++ ((uint64_t)now.tv_sec * 1000000ULL) + ++ ((uint64_t)now.tv_nsec / 1000ULL)); ++ } ++} ++#endif /* SYSTEMD_NOTIFY */ ++ ++#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */ +diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h +index 3c22a854d..14064f87d 100644 +--- a/openbsd-compat/port-linux.h ++++ b/openbsd-compat/port-linux.h +@@ -30,4 +30,9 @@ void oom_adjust_restore(void); + void oom_adjust_setup(void); + #endif + ++#ifdef SYSTEMD_NOTIFY ++void ssh_systemd_notify_ready(void); ++void ssh_systemd_notify_reload(void); ++#endif ++ + #endif /* ! _PORT_LINUX_H */ +diff --git a/platform.c b/platform.c +index 4fe8744ee..9cf818153 100644 +--- a/platform.c ++++ b/platform.c +@@ -44,6 +44,14 @@ platform_pre_listen(void) + #endif + } + ++void ++platform_post_listen(void) ++{ ++#ifdef SYSTEMD_NOTIFY ++ ssh_systemd_notify_ready(); ++#endif ++} ++ + void + platform_pre_fork(void) + { +@@ -55,6 +63,9 @@ platform_pre_fork(void) + void + platform_pre_restart(void) + { ++#ifdef SYSTEMD_NOTIFY ++ ssh_systemd_notify_reload(); ++#endif + #ifdef LINUX_OOM_ADJUST + oom_adjust_restore(); + #endif +diff --git a/platform.h b/platform.h +index 7fef8c983..5dec23276 100644 +--- a/platform.h ++++ b/platform.h +@@ -21,6 +21,7 @@ + void platform_pre_listen(void); + void platform_pre_fork(void); + void platform_pre_restart(void); ++void platform_post_listen(void); + void platform_post_fork_parent(pid_t child_pid); + void platform_post_fork_child(void); + int platform_privileged_uidswap(void); +diff --git a/sshd.c b/sshd.c +index 9cbe92293..3c3f2dd6b 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -2077,6 +2077,8 @@ main(int ac, char **av) + ssh_signal(SIGTERM, sigterm_handler); + ssh_signal(SIGQUIT, sigterm_handler); + ++ platform_post_listen(); ++ + /* + * Write out the pid file after the sigterm handler + * is setup and the listen sockets are bound From 85175e1ba24c44e574e669be2f0293e779c0e464 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 10 Jul 2024 21:31:40 +0200 Subject: [PATCH 128/146] Fix s390x compilation --- openssh-9.6p1-hpn-18.3.1.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssh-9.6p1-hpn-18.3.1.patch b/openssh-9.6p1-hpn-18.3.1.patch index e9a43f8..e50801b 100644 --- a/openssh-9.6p1-hpn-18.3.1.patch +++ b/openssh-9.6p1-hpn-18.3.1.patch @@ -13533,7 +13533,7 @@ diff -Nur openssh-9.6p1.orig/umac.c openssh-9.6p1/umac.c + return (v); +} + -+#if (! __LITTLE_ENDIAN__) /* compile time warning thrown otherwise */ ++#if 0 /* compile time warning thrown otherwise */ +static __attribute__((__bounded__(__minbytes__, 1, 4))); +void umac_put_u32_le(void *vp, u_int32_t v) +{ From 0c7244d48fd3fc287530cb313800f5c7973b2df2 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Fri, 12 Jul 2024 20:31:20 +0200 Subject: [PATCH 129/146] Add scp and hpnscp symlinks in gsisshd's path --- gsi-openssh.spec | 33 +++++++++++++++++++------- openssh-9.6p1-hpn-18.3.1.patch | 43 +++++++++++++++++----------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 70a279f..ff165b1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.6p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -250,6 +250,8 @@ Requires(pre): /usr/sbin/useradd Requires: pam >= 1.0.1-3 Requires: crypto-policies >= 20220824-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 @@ -397,8 +399,8 @@ fi --sysconfdir=%{_sysconfdir}/gsissh \ --libexecdir=%{_libexecdir}/gsissh \ --datadir=%{_datadir}/gsissh \ - --with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \ - --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ + --with-default-path=%{_libexecdir}/gsissh/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \ + --with-superuser-path=%{_libexecdir}/gsissh/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_datadir}/empty.sshd \ --disable-strip \ --without-zlib-version-check \ @@ -472,12 +474,10 @@ rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent rm $RPM_BUILD_ROOT%{_bindir}/ssh-keyscan 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}/* \ $RPM_BUILD_ROOT%{_sbindir}/* \ @@ -485,13 +485,18 @@ for f in $RPM_BUILD_ROOT%{_bindir}/* \ mv $f `dirname $f`/gsi`basename $f` done -# Add symlink with alternative name for scp binary -ln -s gsiscp $RPM_BUILD_ROOT%{_bindir}/hpnscp +# 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 server %sysusers_create_compat %{SOURCE19} +semanage port -a -t ssh_port_t -p tcp 2222 2>/dev/null || : %post server if [ $1 -gt 1 ]; then @@ -509,6 +514,9 @@ 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 @@ -518,21 +526,25 @@ 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(4755,root,root) %{_libexecdir}/gsissh/ssh-keysign +%attr(4555,root,root) %{_libexecdir}/gsissh/ssh-keysign %attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8* %files clients %attr(0755,root,root) %{_bindir}/gsissh %attr(0644,root,root) %{_mandir}/man1/gsissh.1* %attr(0755,root,root) %{_bindir}/gsiscp -%{_bindir}/hpnscp %attr(0644,root,root) %{_mandir}/man1/gsiscp.1* %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config %dir %attr(0755,root,root) %{_sysconfdir}/gsissh/ssh_config.d/ %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 server %dir %attr(0711,root,root) %{_datadir}/empty.sshd @@ -560,6 +572,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Fri Jul 12 2024 Mattias Ellert - 9.6p1-3 +- Add scp and hpnscp symlinks in gsisshd's path + * Sat Jul 06 2024 Mattias Ellert - 9.6p1-2 - Based on openssh-9.6p1-1.fc41.13 diff --git a/openssh-9.6p1-hpn-18.3.1.patch b/openssh-9.6p1-hpn-18.3.1.patch index e50801b..68159b7 100644 --- a/openssh-9.6p1-hpn-18.3.1.patch +++ b/openssh-9.6p1-hpn-18.3.1.patch @@ -8177,8 +8177,8 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c if (want_subsystem) { diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c --- openssh-9.6p1.orig/compat.c 2024-07-10 13:32:39.574111737 +0200 -+++ openssh-9.6p1/compat.c 2024-07-10 13:34:02.716358582 +0200 -@@ -135,6 +135,36 @@ ++++ openssh-9.6p1/compat.c 2024-07-14 11:29:56.093866627 +0200 +@@ -135,6 +135,35 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) ssh->compat |= SSH_RH_RSASIGSHA; @@ -8188,27 +8188,26 @@ diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c + if (strstr(version, "hpn")) { + ssh->compat |= SSH_HPNSSH; + debug("Remote is HPN enabled"); -+ } -+ /* this checks to see if the remote -+ * version string indicates that we -+ * have access to hpn prefixed binaries -+ * You'll need to change this to include -+ * new major version numbers. Which is -+ * why we should figure out how to make -+ * the match pattern list work -+ */ -+ if ((strstr(version, "hpn16") != NULL) || -+ (strstr(version, "hpn17") != NULL) || -+ (strstr(version, "hpn18") != NULL)) { -+ ssh->compat |= SSH_HPNSSH_PREFIX; -+ debug("Remote uses HPNSSH prefixes."); -+ break; ++ /* this checks to see if the remote ++ * version string indicates that we ++ * have access to hpn prefixed binaries ++ * You'll need to change this to include ++ * new major version numbers. Which is ++ * why we should figure out how to make ++ * the match pattern list work ++ */ ++ if ((strstr(version, "hpn16") != NULL) || ++ (strstr(version, "hpn17") != NULL) || ++ (strstr(version, "hpn18") != NULL)) { ++ ssh->compat |= SSH_HPNSSH_PREFIX; ++ debug("Remote uses HPNSSH prefixes."); ++ } + } + /* if it's openssh and not hpn */ -+ if ((strstr(version, "OpenSSH_8.9") != NULL) || -+ (strstr(version, "OpenSSH_9") != NULL)) { ++ else if ((strstr(version, "OpenSSH_8.9") != NULL) || ++ (strstr(version, "OpenSSH_9") != NULL)) { + ssh->compat |= SSH_RESTRICT_WINDOW; -+ debug("Restricting adverstised window size."); ++ debug("Restricting advertised window size."); + } + } + debug("ssh->compat is %u", ssh->compat); @@ -8217,7 +8216,7 @@ diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c } diff -Nur openssh-9.6p1.orig/compat.h openssh-9.6p1/compat.h --- openssh-9.6p1.orig/compat.h 2024-07-10 13:32:39.574111737 +0200 -+++ openssh-9.6p1/compat.h 2024-07-10 13:34:02.716358582 +0200 ++++ openssh-9.6p1/compat.h 2024-07-14 11:29:56.093866627 +0200 @@ -46,12 +46,12 @@ /* #define unused 0x00010000 */ /* #define unused 0x00020000 */ @@ -8227,7 +8226,7 @@ diff -Nur openssh-9.6p1.orig/compat.h openssh-9.6p1/compat.h #define SSH_BUG_EXTEOF 0x00200000 #define SSH_BUG_PROBE 0x00400000 -/* #define unused 0x00800000 */ -+#define SSH_RESTRICT_WINDOW 0x00800000 /* restrict adverstised window to OpenSSH clients */ ++#define SSH_RESTRICT_WINDOW 0x00800000 /* restrict advertised window to OpenSSH clients */ #define SSH_OLD_FORWARD_ADDR 0x01000000 -/* #define unused 0x02000000 */ +#define SSH_HPNSSH_PREFIX 0x02000000 /* indicates that we have hpn prefixes binaries */ From 75b18e250aac62139028f560b0546fd2541730af Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 08:40:59 +0000 Subject: [PATCH 130/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ff165b1..f27261e 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -572,6 +572,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Thu Jul 18 2024 Fedora Release Engineering - 9.6p1-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Fri Jul 12 2024 Mattias Ellert - 9.6p1-3 - Add scp and hpnscp symlinks in gsisshd's path From f463dc835a93f640471508c3a63384c857aab4b2 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 3 Oct 2024 00:49:37 +0200 Subject: [PATCH 131/146] Based on openssh-9.8p1-3.fc41.1 --- CVE-2024-6387.patch | 18 - gsi-openssh.spec | 29 +- openssh-6.6.1p1-log-in-chroot.patch | 8 +- openssh-6.6.1p1-selinux-contexts.patch | 6 +- openssh-6.6p1-GSSAPIEnablek5users.patch | 9 +- openssh-6.6p1-allow-ip-opts.patch | 4 +- openssh-6.6p1-keycat.patch | 10 +- openssh-6.6p1-kuserok.patch | 4 +- openssh-6.6p1-privsep-selinux.patch | 23 +- openssh-6.7p1-coverity.patch | 8 +- openssh-7.1p2-audit-race-condition.patch | 13 +- openssh-7.2p2-x11.patch | 4 +- openssh-7.3p1-x11-max-displays.patch | 2 +- openssh-7.6p1-audit.patch | 183 +- openssh-7.6p1-cleanup-selinux.patch | 50 +- openssh-7.7p1-fips.patch | 73 +- openssh-7.7p1-gssapi-new-unique.patch | 12 +- openssh-7.8p1-UsePAM-warning.patch | 14 +- openssh-7.8p1-role-mls.patch | 28 +- openssh-8.0p1-crypto-policies.patch | 32 +- openssh-8.0p1-gssapi-keyex.patch | 2209 +++++++------- openssh-8.0p1-pkcs11-uri.patch | 6 +- openssh-8.0p1-preserve-pam-errors.patch | 7 +- openssh-8.7p1-minrsabits.patch | 2 +- openssh-8.7p1-negotiate-supported-algs.patch | 11 +- openssh-8.7p1-nohostsha1proof.patch | 126 +- openssh-9.0p1-evp-fips-dh.patch | 2 +- openssh-9.6p1-gsskex-new-api.patch | 34 +- ...gsissh.patch => openssh-9.8p1-gsissh.patch | 492 ++- ....1.patch => openssh-9.8p1-hpn-18.5.1.patch | 2702 +++++++++-------- openssh-9.8p1-systemd.patch | 201 -- sources | 4 +- 32 files changed, 2991 insertions(+), 3335 deletions(-) delete mode 100644 CVE-2024-6387.patch rename openssh-9.6p1-gsissh.patch => openssh-9.8p1-gsissh.patch (85%) rename openssh-9.6p1-hpn-18.3.1.patch => openssh-9.8p1-hpn-18.5.1.patch (87%) delete mode 100644 openssh-9.8p1-systemd.patch diff --git a/CVE-2024-6387.patch b/CVE-2024-6387.patch deleted file mode 100644 index 0b976c0..0000000 --- a/CVE-2024-6387.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/log.c b/log.c -index 9fc1a2e2e..191ff4a5a 100644 ---- a/log.c -+++ b/log.c -@@ -451,12 +451,14 @@ void - sshsigdie(const char *file, const char *func, int line, int showfunc, - LogLevel level, const char *suffix, const char *fmt, ...) - { -+#ifdef SYSLOG_R_SAFE_IN_SIGHAND - va_list args; - - va_start(args, fmt); - sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL, - suffix, fmt, args); - va_end(args); -+#endif - _exit(1); - } diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f27261e..afd571d 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,13 +23,13 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 9.6p1 -%global openssh_rel 3 +%global openssh_ver 9.8p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -128,8 +128,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-9.8p1-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 @@ -184,15 +182,13 @@ Patch1014: openssh-8.7p1-nohostsha1proof.patch Patch1015: openssh-9.6p1-pam-rhost.patch -Patch1016: CVE-2024-6387.patch - # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-9.6p1-gsissh.patch +Patch98: openssh-9.8p1-gsissh.patch # This is the HPN patch -# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.3.1 -Patch99: openssh-9.6p1-hpn-18.3.1.patch +# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.5.1 +Patch99: openssh-9.8p1-hpn-18.5.1.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 @@ -319,7 +315,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 @@ -348,17 +343,14 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 1013 -p1 -b .evp-fips-ecdh %patch -P 1014 -p1 -b .nosha1hostproof %patch -P 1015 -p1 -b .pam-rhost -%patch -P 1016 -p1 -b .cve-2024-6387 %patch -P 100 -p1 -b .coverity - %patch -P 98 -p1 -b .gsi %patch -P 99 -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/sysconfig/sshd!/etc/sysconfig/gsisshd!' -i sshd_config -sed 's!/etc/pam.d/sshd!/etc/pam.d/gsisshd!' -i sshd_config +sed 's!/etc/pam.d/sshd!/etc/pam.d/gsisshd!' -i sshd_config_redhat cp -p %{SOURCE99} . @@ -404,7 +396,6 @@ fi --with-privsep-path=%{_datadir}/empty.sshd \ --disable-strip \ --without-zlib-version-check \ - --with-ssl-engine \ --with-ipaddr-display \ --with-pie=no \ --without-hardening `# The hardening flags are configured by system` \ @@ -412,7 +403,7 @@ fi --with-default-pkcs11-provider=yes \ --with-security-key-builtin=yes \ --with-pam \ - --without-ssl-engine \ + --with-pam-service=gsisshd \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ --with-sandbox=seccomp_filter \ @@ -549,6 +540,7 @@ fi %files server %dir %attr(0711,root,root) %{_datadir}/empty.sshd %attr(0755,root,root) %{_sbindir}/gsisshd +%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-session %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* @@ -572,6 +564,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Fri Sep 27 2024 Mattias Ellert - 9.8p1-1 +- Based on openssh-9.8p1-3.fc41.1 + * Thu Jul 18 2024 Fedora Release Engineering - 9.6p1-3.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 941c694..0f65279 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -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); diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index eab724a..96161cb 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -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(); diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index cccb3e0..7fef831 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -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 diff --git a/openssh-6.6p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch index be8d340..d969b5c 100644 --- a/openssh-6.6p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -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, diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 529b508..4eb0998 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -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 = ""; diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index eaf4453..e43128b 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -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 , diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 8047fc3..16d98cd 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -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 + diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 01a061b..d98da28 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -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); diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index b5895f7..57ad148 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -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. */ diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index b27d7c4..6db16be 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -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)); diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 2b702d4..e28c62e 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -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. */ diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index cec5b23..c884292 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -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); -@@ -2189,7 +2189,7 @@ - } - - /* 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); diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index f7cd50f..cfe11ad 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -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 #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 diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index b1007b2..6a14cb3 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -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 +#include - #include - # ifdef HAVE_EVP_KDF_CTX_NEW - # include + #include + #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 #include @@ -77,6 +78,7 @@ - #include - #include + #ifdef WITH_OPENSSL + #include #include +#include #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 + #include + #include ++#include + #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, @@ -505,6 +516,14 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c #include #include "openbsd-compat/openssl-compat.h" #endif +@@ -69,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 @@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } @@ -518,6 +537,15 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c switch (type) { case KEY_DSA: if (*bitsp != 1024) +@@ -266,7 +267,7 @@ ask_filename(struct passwd *pw, const ch + 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_name(key_type_name)) { + #ifdef WITH_DSA @@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); @@ -537,6 +565,15 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); +@@ -3830,7 +3831,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_name(key_type_name); + type_bits_valid(type, key_type_name, &bits); diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c --- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 +++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 544932b..0b8ab02 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -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 diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index a94419e..f8d7042 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -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 diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 347766d..7c6d0ca 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -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 + * Copyright (c) 2014 Petr Lautrbach @@ -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(); diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 86c08db..fd1e59d 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -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 @@ diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 3e5ccec..82b2bfe 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1,162 +1,37 @@ -diff --git a/Makefile.in b/Makefile.in -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 \ - kexgexc.o kexgexs.o \ - kexsntrup761x25519.o sntrup761.o kexgen.o \ -+ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o +diff --color -ruNp a/auth2.c b/auth2.c +--- a/auth2.c 2024-08-28 12:35:01.189659493 +0200 ++++ b/auth2.c 2024-08-28 12:35:41.246432045 +0200 +@@ -71,6 +71,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif -@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.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 \ - 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 \ -@@ -523,7 +523,7 @@ regress-prep: - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + &method_passwd, +diff --color -ruNp a/auth2-gss.c b/auth2-gss.c +--- a/auth2-gss.c 2024-08-28 12:35:01.189659493 +0200 ++++ b/auth2-gss.c 2024-08-28 12:35:41.265432411 +0200 +@@ -51,6 +51,7 @@ + #define SSH_GSSAPI_MAX_MECHS 2048 - REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) + extern ServerOptions options; ++extern struct authmethod_cfg methodcfg_gsskeyex; + extern struct authmethod_cfg methodcfg_gssapi; - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ -diff -up a/auth.c.gsskex b/auth.c ---- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 -@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -- strcmp(method, "gssapi-with-mic") == 0) -+ strcmp(method, "gssapi-with-mic") == 0 || -+ strcmp(method, "gssapi-keyex") == 0) - 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_token(int type, u_int32_t plen, struct ssh *ssh); +@@ -59,6 +60,48 @@ static int input_gssapi_exchange_complet static int input_gssapi_errtok(int, u_int32_t, struct ssh *); -+/* + /* + * The 'gssapi_keyex' userauth mechanism. + */ +static int @@ -187,10 +62,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); @@ -198,67 +73,79 @@ index 9351e042..d6446c0c 100644 + return (authenticated); +} + - /* ++/* * 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) + */ +@@ -267,7 +310,7 @@ input_gssapi_exchange_complete(int type, 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); +@@ -315,7 +358,7 @@ input_gssapi_mic(int type, u_int32_t ple 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) +@@ -333,6 +376,11 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } +Authmethod method_gsskeyex = { -+ "gssapi-keyex", -+ NULL, ++ &methodcfg_gsskeyex, + userauth_gsskeyex, -+ &options.gss_authentication +}; + Authmethod method_gssapi = { + &methodcfg_gssapi, + userauth_gssapi, +diff --color -ruNp a/auth2-methods.c b/auth2-methods.c +--- a/auth2-methods.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/auth2-methods.c 2024-08-28 12:35:41.265432411 +0200 +@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = + &options.pubkey_authentication + }; + #ifdef GSSAPI ++struct authmethod_cfg methodcfg_gsskeyex = { ++ "gssapi-keyex", ++ NULL, ++ &options.gss_authentication ++}; + struct authmethod_cfg methodcfg_gssapi = { "gssapi-with-mic", NULL, -diff --git a/auth2.c b/auth2.c -index 0e776224..1c217268 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -73,6 +73,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; +@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod + &methodcfg_none, + &methodcfg_pubkey, #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; ++ &methodcfg_gsskeyex, + &methodcfg_gssapi, #endif - -@@ -80,6 +81,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - &method_passwd, -diff --git a/canohost.c b/canohost.c -index abea9c6e..8e81b519 100644 ---- a/canohost.c -+++ b/canohost.c + &methodcfg_passwd, +diff --color -ruNp a/auth.c b/auth.c +--- a/auth.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/auth.c 2024-08-28 12:35:41.245432026 +0200 +@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || +- strcmp(method, "gssapi-with-mic") == 0) ++ strcmp(method, "gssapi-with-mic") == 0 || ++ strcmp(method, "gssapi-keyex") == 0) + return 1; + break; + case PERMIT_FORCED_ONLY: +diff --color -ruNp a/canohost.c b/canohost.c +--- a/canohost.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/canohost.c 2024-08-28 12:35:41.246432045 +0200 @@ -35,6 +35,99 @@ #include "canohost.h" #include "misc.h" @@ -359,10 +246,9 @@ index abea9c6e..8e81b519 100644 void ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { -diff --git a/canohost.h b/canohost.h -index 26d62855..0cadc9f1 100644 ---- a/canohost.h -+++ b/canohost.h +diff --color -ruNp a/canohost.h b/canohost.h +--- a/canohost.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/canohost.h 2024-08-28 12:35:41.246432045 +0200 @@ -15,6 +15,9 @@ #ifndef _CANOHOST_H #define _CANOHOST_H @@ -373,11 +259,10 @@ index 26d62855..0cadc9f1 100644 char *get_peer_ipaddr(int); int get_peer_port(int); char *get_local_ipaddr(int); -diff --git a/clientloop.c b/clientloop.c -index ebd0dbca..1bdac6a4 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -112,6 +112,10 @@ +diff --color -ruNp a/clientloop.c b/clientloop.c +--- a/clientloop.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/clientloop.c 2024-08-28 12:35:41.246432045 +0200 +@@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -388,7 +273,7 @@ index ebd0dbca..1bdac6a4 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1379,6 +1383,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1590,6 +1594,14 @@ client_loop(struct ssh *ssh, int have_pt /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -403,11 +288,10 @@ index ebd0dbca..1bdac6a4 100644 /* Buffer input from the connection. */ if (conn_in_ready) client_process_net_input(ssh); -diff --git a/configure.ac b/configure.ac -index b689db4b..efafb6bd 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -674,6 +674,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +diff --color -ruNp a/configure.ac b/configure.ac +--- a/configure.ac 2024-08-28 12:35:01.202659743 +0200 ++++ b/configure.ac 2024-08-28 12:35:41.247432064 +0200 +@@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeL [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -438,20 +322,10 @@ index b689db4b..efafb6bd 100644 m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -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 @@ +diff --color -ruNp a/gss-genr.c b/gss-genr.c +--- a/gss-genr.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-genr.c 2024-08-28 12:35:41.248432084 +0200 +@@ -42,9 +42,33 @@ #include "sshbuf.h" #include "log.h" #include "ssh2.h" @@ -485,7 +359,7 @@ index d56257b4..763a63ff 100644 /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf return 0; } @@ -645,7 +519,7 @@ index d56257b4..763a63ff 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -218,7 +398,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -216,7 +393,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -654,11 +528,10 @@ index d56257b4..763a63ff 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -247,9 +427,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) - return (ctx->major); +@@ -246,8 +423,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } -+OM_uint32 + OM_uint32 +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) +{ + gss_buffer_desc gssbuf; @@ -689,7 +562,7 @@ index d56257b4..763a63ff 100644 + return(ctx->major); +} + - OM_uint32 ++OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { + if (ctx == NULL) @@ -698,7 +571,7 @@ index d56257b4..763a63ff 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -257,6 +471,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -255,6 +466,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -718,7 +591,7 @@ index d56257b4..763a63ff 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -271,11 +495,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co } int @@ -735,8 +608,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 && +@@ -285,6 +514,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -745,13 +618,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) +@@ -294,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); @@ -815,10 +688,303 @@ index d56257b4..763a63ff 100644 +} + #endif /* GSSAPI */ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e..8d2b677f 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c +diff --color -ruNp a/gss-serv.c b/gss-serv.c +--- a/gss-serv.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-serv.c 2024-08-28 12:35:41.248432084 +0200 +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 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 +@@ -44,17 +44,19 @@ + #include "session.h" + #include "misc.h" + #include "servconf.h" ++#include "uidswap.h" + + #include "ssh-gss.h" ++#include "monitor_wrap.h" + + extern ServerOptions options; + + static ssh_gssapi_client gssapi_client = +- { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, +- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; ++ { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, ++ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; + + ssh_gssapi_mech gssapi_null_mech = +- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; ++ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; + + #ifdef KRB5 + extern ssh_gssapi_mech gssapi_kerberos_mech; +@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss + } + + /* Unprivileged */ ++char * ++ssh_gssapi_server_mechanisms(void) { ++ if (supported_oids == NULL) ++ ssh_gssapi_prepare_supported_oids(); ++ return (ssh_gssapi_kex_mechs(supported_oids, ++ &ssh_gssapi_server_check_mech, NULL, NULL, ++ options.gss_kex_algorithms)); ++} ++ ++/* Unprivileged */ ++int ++ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, ++ const char *dummy) { ++ Gssctxt *ctx = NULL; ++ int res; ++ ++ res = !GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctx, oid)); ++ ssh_gssapi_delete_ctx(&ctx); ++ ++ return (res); ++} ++ ++/* Unprivileged */ + void + ssh_gssapi_supported_oids(gss_OID_set *oidset) + { +@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o + gss_OID_set supported; + + gss_create_empty_oid_set(&min_status, oidset); +- gss_indicate_mechs(&min_status, &supported); ++ ++ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) ++ return; + + while (supported_mechs[i]->name != NULL) { + if (GSS_ERROR(gss_test_oid_set_member(&min_status, +@@ -276,8 +303,48 @@ OM_uint32 + ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) + { + int i = 0; ++ int equal = 0; ++ gss_name_t new_name = GSS_C_NO_NAME; ++ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; ++ ++ if (options.gss_store_rekey && client->used && ctx->client_creds) { ++ if (client->mech->oid.length != ctx->oid->length || ++ (memcmp(client->mech->oid.elements, ++ ctx->oid->elements, ctx->oid->length) !=0)) { ++ debug("Rekeyed credentials have different mechanism"); ++ return GSS_S_COMPLETE; ++ } + +- gss_buffer_desc ename; ++ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &new_name, ++ NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ ++ ctx->major = gss_compare_name(&ctx->minor, client->name, ++ new_name, &equal); ++ ++ if (GSS_ERROR(ctx->major)) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ ++ if (!equal) { ++ debug("Rekeyed credentials have different name"); ++ return GSS_S_COMPLETE; ++ } ++ ++ debug("Marking rekeyed credentials for export"); ++ ++ gss_release_name(&ctx->minor, &client->name); ++ gss_release_cred(&ctx->minor, &client->creds); ++ client->name = new_name; ++ client->creds = ctx->client_creds; ++ ctx->client_creds = GSS_C_NO_CREDENTIAL; ++ client->updated = 1; ++ return GSS_S_COMPLETE; ++ } + + client->mech = NULL; + +@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + if (client->mech == NULL) + return GSS_S_FAILURE; + ++ if (ctx->client_creds && ++ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ++ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { ++ ssh_gssapi_error(ctx); ++ return (ctx->major); ++ } ++ + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, + &client->displayname, NULL))) { + ssh_gssapi_error(ctx); +@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + return (ctx->major); + } + ++ gss_release_buffer(&ctx->minor, &ename); ++ + /* We can't copy this structure, so we just move the pointer to it */ + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; +@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g + void + ssh_gssapi_cleanup_creds(void) + { +- if (gssapi_client.store.filename != NULL) { +- /* Unlink probably isn't sufficient */ +- debug("removing gssapi cred file\"%s\"", +- gssapi_client.store.filename); +- unlink(gssapi_client.store.filename); ++ krb5_ccache ccache = NULL; ++ krb5_error_code problem; ++ ++ if (gssapi_client.store.data != NULL) { ++ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { ++ debug_f("krb5_cc_resolve(): %.100s", ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { ++ debug_f("krb5_cc_destroy(): %.100s", ++ krb5_get_err_text(gssapi_client.store.data, problem)); ++ } else { ++ krb5_free_context(gssapi_client.store.data); ++ gssapi_client.store.data = NULL; ++ } + } + } + +@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int + + /* Privileged */ + int +-ssh_gssapi_userok(char *user) ++ssh_gssapi_userok(char *user, struct passwd *pw, int kex) + { + OM_uint32 lmin; + ++ (void) kex; /* used in privilege separation */ ++ + if (gssapi_client.exportedname.length == 0 || + gssapi_client.exportedname.value == NULL) { + debug("No suitable client data"); + return 0; + } + if (gssapi_client.mech && gssapi_client.mech->userok) +- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) ++ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { ++ gssapi_client.used = 1; ++ gssapi_client.store.owner = pw; + return 1; +- else { ++ } else { + /* Destroy delegated credentials if userok fails */ + gss_release_buffer(&lmin, &gssapi_client.displayname); + gss_release_buffer(&lmin, &gssapi_client.exportedname); +@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) + return (0); + } + +-/* Privileged */ +-OM_uint32 +-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) ++/* These bits are only used for rekeying. The unpriviledged child is running ++ * as the user, the monitor is root. ++ * ++ * In the child, we want to : ++ * *) Ask the monitor to store our credentials into the store we specify ++ * *) If it succeeds, maybe do a PAM update ++ */ ++ ++/* Stuff for PAM */ ++ ++#ifdef USE_PAM ++static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, ++ struct pam_response **resp, void *data) + { +- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, +- gssbuf, gssmic, NULL); ++ return (PAM_CONV_ERR); ++} ++#endif + +- return (ctx->major); ++void ++ssh_gssapi_rekey_creds(void) { ++ int ok; ++#ifdef USE_PAM ++ int ret; ++ pam_handle_t *pamh = NULL; ++ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; ++ char *envstr; ++#endif ++ ++ if (gssapi_client.store.filename == NULL && ++ gssapi_client.store.envval == NULL && ++ gssapi_client.store.envvar == NULL) ++ return; ++ ++ ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); ++ ++ if (!ok) ++ return; ++ ++ debug("Rekeyed credentials stored successfully"); ++ ++ /* Actually managing to play with the ssh pam stack from here will ++ * be next to impossible. In any case, we may want different options ++ * for rekeying. So, use our own :) ++ */ ++#ifdef USE_PAM ++ ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, ++ &pamconv, &pamh); ++ if (ret) ++ return; ++ ++ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, ++ gssapi_client.store.envval); ++ ++ ret = pam_putenv(pamh, envstr); ++ if (!ret) ++ pam_setcred(pamh, PAM_REINITIALIZE_CRED); ++ pam_end(pamh, PAM_SUCCESS); ++#endif ++} ++ ++int ++ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { ++ int ok = 0; ++ ++ /* Check we've got credentials to store */ ++ if (!gssapi_client.updated) ++ return 0; ++ ++ gssapi_client.updated = 0; ++ ++ temporarily_use_uid(gssapi_client.store.owner); ++ if (gssapi_client.mech && gssapi_client.mech->updatecreds) ++ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); ++ else ++ debug("No update function for this mechanism"); ++ ++ restore_uid(); ++ ++ return ok; + } + + /* Privileged */ +diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c +--- a/gss-serv-krb5.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-serv-krb5.c 2024-08-28 12:35:41.248432084 +0200 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ @@ -828,7 +994,7 @@ index a151bc1e..8d2b677f 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; @@ -837,7 +1003,7 @@ index a151bc1e..8d2b677f 100644 const char *errmsg; if (client->creds == NULL) { -@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl return; } @@ -868,7 +1034,7 @@ index a151bc1e..8d2b677f 100644 #ifdef USE_PAM if (options.use_pam) -@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_cc_close(krb_context, ccache); @@ -955,414 +1121,54 @@ index a151bc1e..8d2b677f 100644 }; #endif /* KRB5 */ -diff --git a/gss-serv.c b/gss-serv.c -index ab3a15f0..6ce56e92 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 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 -@@ -44,17 +44,19 @@ - #include "session.h" - #include "misc.h" - #include "servconf.h" -+#include "uidswap.h" - - #include "ssh-gss.h" -+#include "monitor_wrap.h" - - extern ServerOptions options; - - static ssh_gssapi_client gssapi_client = -- { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, -- GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; -+ { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, -+ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; - - ssh_gssapi_mech gssapi_null_mech = -- { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; -+ { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; - - #ifdef KRB5 - extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) - return (ssh_gssapi_acquire_cred(*ctx)); - } - -+/* Unprivileged */ -+char * -+ssh_gssapi_server_mechanisms(void) { -+ if (supported_oids == NULL) -+ ssh_gssapi_prepare_supported_oids(); -+ return (ssh_gssapi_kex_mechs(supported_oids, -+ &ssh_gssapi_server_check_mech, NULL, NULL, -+ options.gss_kex_algorithms)); -+} -+ -+/* Unprivileged */ -+int -+ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, -+ const char *dummy) { -+ Gssctxt *ctx = NULL; -+ int res; -+ -+ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); -+ ssh_gssapi_delete_ctx(&ctx); -+ -+ return (res); -+} -+ - /* Unprivileged */ - void - ssh_gssapi_supported_oids(gss_OID_set *oidset) -@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) - gss_OID_set supported; - - gss_create_empty_oid_set(&min_status, oidset); -- gss_indicate_mechs(&min_status, &supported); -+ -+ if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) -+ return; - - while (supported_mechs[i]->name != NULL) { - if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -276,8 +303,48 @@ OM_uint32 - ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +diff --color -ruNp a/kex.c b/kex.c +--- a/kex.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex.c 2024-08-28 12:35:41.249432103 +0200 +@@ -303,17 +303,37 @@ static int + kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { - int i = 0; -+ int equal = 0; -+ gss_name_t new_name = GSS_C_NO_NAME; -+ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; + int r; ++ int have_key = 0; ++ int ext_count = 2; + -+ if (options.gss_store_rekey && client->used && ctx->client_creds) { -+ if (client->mech->oid.length != ctx->oid->length || -+ (memcmp(client->mech->oid.elements, -+ ctx->oid->elements, ctx->oid->length) !=0)) { -+ debug("Rekeyed credentials have different mechanism"); -+ return GSS_S_COMPLETE; -+ } -+ -+ if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &new_name, -+ NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } - -- gss_buffer_desc ename; -+ ctx->major = gss_compare_name(&ctx->minor, client->name, -+ new_name, &equal); -+ -+ if (GSS_ERROR(ctx->major)) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ -+ if (!equal) { -+ debug("Rekeyed credentials have different name"); -+ return GSS_S_COMPLETE; -+ } -+ -+ debug("Marking rekeyed credentials for export"); -+ -+ gss_release_name(&ctx->minor, &client->name); -+ gss_release_cred(&ctx->minor, &client->creds); -+ client->name = new_name; -+ client->creds = ctx->client_creds; -+ ctx->client_creds = GSS_C_NO_CREDENTIAL; -+ client->updated = 1; -+ return GSS_S_COMPLETE; -+ } - - client->mech = NULL; - -@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - if (client->mech == NULL) - return GSS_S_FAILURE; - -+ if (ctx->client_creds && -+ (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, -+ ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } -+ - if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, - &client->displayname, NULL))) { - ssh_gssapi_error(ctx); -@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - return (ctx->major); - } - -+ gss_release_buffer(&ctx->minor, &ename); -+ - /* We can't copy this structure, so we just move the pointer to it */ - client->creds = ctx->client_creds; - ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - void - ssh_gssapi_cleanup_creds(void) - { -- if (gssapi_client.store.filename != NULL) { -- /* Unlink probably isn't sufficient */ -- debug("removing gssapi cred file\"%s\"", -- gssapi_client.store.filename); -- unlink(gssapi_client.store.filename); -+ krb5_ccache ccache = NULL; -+ krb5_error_code problem; -+ -+ if (gssapi_client.store.data != NULL) { -+ if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug_f("krb5_cc_resolve(): %.100s", -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug_f("krb5_cc_destroy(): %.100s", -+ krb5_get_err_text(gssapi_client.store.data, problem)); -+ } else { -+ krb5_free_context(gssapi_client.store.data); -+ gssapi_client.store.data = NULL; -+ } - } - } - -@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) - - /* Privileged */ - int --ssh_gssapi_userok(char *user) -+ssh_gssapi_userok(char *user, struct passwd *pw, int kex) - { - OM_uint32 lmin; - -+ (void) kex; /* used in privilege separation */ -+ - if (gssapi_client.exportedname.length == 0 || - gssapi_client.exportedname.value == NULL) { - debug("No suitable client data"); - return 0; - } - if (gssapi_client.mech && gssapi_client.mech->userok) -- if ((*gssapi_client.mech->userok)(&gssapi_client, user)) -+ if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { -+ gssapi_client.used = 1; -+ gssapi_client.store.owner = pw; - return 1; -- else { -+ } else { - /* 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) - return (0); - } - --/* Privileged */ --OM_uint32 --ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) -+/* These bits are only used for rekeying. The unpriviledged child is running -+ * as the user, the monitor is root. -+ * -+ * In the child, we want to : -+ * *) Ask the monitor to store our credentials into the store we specify -+ * *) If it succeeds, maybe do a PAM update -+ */ -+ -+/* Stuff for PAM */ -+ -+#ifdef USE_PAM -+static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, -+ struct pam_response **resp, void *data) - { -- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, -- gssbuf, gssmic, NULL); -+ return (PAM_CONV_ERR); -+} -+#endif - -- return (ctx->major); -+void -+ssh_gssapi_rekey_creds(void) { -+ int ok; -+#ifdef USE_PAM -+ int ret; -+ pam_handle_t *pamh = NULL; -+ struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; -+ char *envstr; -+#endif -+ -+ if (gssapi_client.store.filename == NULL && -+ gssapi_client.store.envval == NULL && -+ gssapi_client.store.envvar == NULL) -+ return; -+ -+ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -+ -+ if (!ok) -+ return; -+ -+ debug("Rekeyed credentials stored successfully"); -+ -+ /* Actually managing to play with the ssh pam stack from here will -+ * be next to impossible. In any case, we may want different options -+ * for rekeying. So, use our own :) ++#ifdef GSSAPI ++ /* ++ * Currently GSS KEX don't provide host keys as optional message, so ++ * no reasons to announce the publickey-hostbound extension + */ -+#ifdef USE_PAM -+ if (!use_privsep) { -+ debug("Not even going to try and do PAM with privsep disabled"); -+ return; ++ if (ssh->kex->gss == NULL) ++ have_key = 1; ++#endif ++ ext_count += have_key; ++ + + if (ssh->kex->server_sig_algs == NULL && + (ssh->kex->server_sig_algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) + return SSH_ERR_ALLOC_FAIL; +- if ((r = sshbuf_put_u32(m, 3)) != 0 || ++ if ((r = sshbuf_put_u32(m, ext_count)) != 0 || + (r = sshbuf_put_cstring(m, "server-sig-algs")) != 0 || +- (r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0 || +- (r = sshbuf_put_cstring(m, +- "publickey-hostbound@openssh.com")) != 0 || +- (r = sshbuf_put_cstring(m, "0")) != 0 || +- (r = sshbuf_put_cstring(m, "ping@openssh.com")) != 0 || ++ (r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0) { ++ error_fr(r, "compose"); ++ return r; + } -+ -+ ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, -+ &pamconv, &pamh); -+ if (ret) -+ return; -+ -+ xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, -+ gssapi_client.store.envval); -+ -+ ret = pam_putenv(pamh, envstr); -+ if (!ret) -+ pam_setcred(pamh, PAM_REINITIALIZE_CRED); -+ pam_end(pamh, PAM_SUCCESS); -+#endif -+} -+ -+int -+ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { -+ int ok = 0; -+ -+ /* Check we've got credentials to store */ -+ if (!gssapi_client.updated) -+ return 0; -+ -+ gssapi_client.updated = 0; -+ -+ temporarily_use_uid(gssapi_client.store.owner); -+ if (gssapi_client.mech && gssapi_client.mech->updatecreds) -+ ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); -+ else -+ debug("No update function for this mechanism"); -+ -+ restore_uid(); -+ -+ return ok; - } - - /* Privileged */ -diff --git a/kex.c b/kex.c -index ce85f043..574c7609 100644 ---- a/kex.c -+++ b/kex.c -@@ -57,6 +57,10 @@ - #include "digest.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 *); -@@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { - #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, - }; -+static const struct kexalg gss_kexalgs[] = { -+#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -+#endif -+ { NULL, 0, -1, -1}, -+}; - --char * --kex_alg_list(char sep) -+static char * -+kex_alg_list_internal(char sep, const struct kexalg *algs) - { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; - const struct kexalg *k; - -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = algs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -138,6 +156,18 @@ kex_alg_list(char sep) - return ret; - } - -+char * -+kex_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, kexalgs); -+} -+ -+char * -+kex_gss_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, gss_kexalgs); -+} -+ - static const struct kexalg * - kex_alg_by_name(const char *name) - { -@@ -147,6 +177,10 @@ kex_alg_by_name(const char *name) - if (strcmp(k->name, name) == 0) - return k; - } -+ for (k = gss_kexalgs; k->name != NULL; k++) { -+ if (strncmp(k->name, name, strlen(k->name)) == 0) -+ return k; -+ } - return NULL; - } - -@@ -315,6 +349,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) - return r; - } - -+/* Validate GSS KEX method name list */ -+int -+kex_gss_names_valid(const char *names) -+{ -+ char *s, *cp, *p; -+ -+ if (names == NULL || *names == '\0') -+ return 0; -+ s = cp = xstrdup(names); -+ for ((p = strsep(&cp, ",")); p && *p != '\0'; -+ (p = strsep(&cp, ","))) { -+ if (strncmp(p, "gss-", 4) != 0 -+ || kex_alg_by_name(p) == NULL) { -+ error("Unsupported KEX algorithm \"%.100s\"", p); -+ free(s); -+ return 0; ++ if (have_key) { ++ if ((r = sshbuf_put_cstring(m, "publickey-hostbound@openssh.com")) != 0 || ++ (r = sshbuf_put_cstring(m, "0")) != 0) { ++ error_fr(r, "compose"); ++ return r; + } + } -+ debug3("gss kex names ok: [%s]", names); -+ 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) ++ if ((r = sshbuf_put_cstring(m, "ping@openssh.com")) != 0 || + (r = sshbuf_put_cstring(m, "0")) != 0) { + error_fr(r, "compose"); + return r; +@@ -737,6 +737,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); @@ -1372,81 +1178,10 @@ index ce85f043..574c7609 100644 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 -+++ b/kex.h -@@ -102,6 +102,15 @@ enum kex_exchange { - KEX_ECDH_SHA2, - KEX_C25519_SHA256, - KEX_KEM_SNTRUP761X25519_SHA512, -+#ifdef GSSAPI -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GRP14_SHA256, -+ KEX_GSS_GRP16_SHA512, -+ KEX_GSS_GEX_SHA1, -+ KEX_GSS_NISTP256_SHA256, -+ KEX_GSS_C25519_SHA256, -+#endif - KEX_MAX - }; - -@@ -153,6 +162,12 @@ struct kex { - u_int flags; - int hash_alg; - int ec_nid; -+#ifdef GSSAPI -+ int gss_deleg_creds; -+ int gss_trust_dns; -+ char *gss_host; -+ char *gss_client; -+#endif - char *failed_choice; - 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_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_gss_names_valid(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 *); - int kex_gen_server(struct ssh *); -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+int kexgssgex_client(struct ssh *); -+int kexgssgex_server(struct ssh *); -+int kexgss_client(struct ssh *); -+int kexgss_server(struct ssh *); -+#endif - - int kex_dh_keypair(struct kex *); - int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -234,6 +257,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, - const BIGNUM *, const u_char *, size_t, - u_char *, size_t *); - -+int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, -+ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, -+ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, -+ const struct sshbuf *client_pub, const struct sshbuf *server_pub, -+ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); -+ - void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) - __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) - __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -diff --git a/kexdh.c b/kexdh.c -index 67133e33..edaa4676 100644 ---- a/kexdh.c -+++ b/kexdh.c -@@ -48,13 +48,23 @@ kex_dh_keygen(struct kex *kex) +diff --color -ruNp a/kexdh.c b/kexdh.c +--- a/kexdh.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kexdh.c 2024-08-28 12:35:41.249432103 +0200 +@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1470,10 +1205,9 @@ index 67133e33..edaa4676 100644 kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: -diff --git a/kexgen.c b/kexgen.c -index 69348b96..c0e8c2f4 100644 ---- a/kexgen.c -+++ b/kexgen.c +diff --color -ruNp a/kexgen.c b/kexgen.c +--- a/kexgen.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kexgen.c 2024-08-28 12:35:41.249432103 +0200 @@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1483,11 +1217,9 @@ index 69348b96..c0e8c2f4 100644 kex_gen_hash( int hash_alg, const struct sshbuf *client_version, -diff --git a/kexgssc.c b/kexgssc.c -new file mode 100644 -index 00000000..f6e1405e ---- /dev/null -+++ b/kexgssc.c +diff --color -ruNp a/kexgssc.c b/kexgssc.c +--- a/kexgssc.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/kexgssc.c 2024-08-28 12:35:41.250432122 +0200 @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2101,11 +1833,9 @@ index 00000000..f6e1405e +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/kexgsss.c b/kexgsss.c -new file mode 100644 -index 00000000..60bc02de ---- /dev/null -+++ b/kexgsss.c +diff --color -ruNp a/kexgsss.c b/kexgsss.c +--- a/kexgsss.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/kexgsss.c 2024-08-28 12:35:41.250432122 +0200 @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2205,7 +1935,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 +2012,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 +2049,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 +2139,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 +2161,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 +2208,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 +2274,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 || @@ -2589,11 +2319,211 @@ index 00000000..60bc02de + return r; +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/monitor.c b/monitor.c -index 2ce89fe9..ebf76c7f 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +diff --color -ruNp a/kex.h b/kex.h +--- a/kex.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex.h 2024-08-28 12:35:41.249432103 +0200 +@@ -102,6 +102,15 @@ enum kex_exchange { + KEX_ECDH_SHA2, + KEX_C25519_SHA256, + KEX_KEM_SNTRUP761X25519_SHA512, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GRP14_SHA256, ++ KEX_GSS_GRP16_SHA512, ++ KEX_GSS_GEX_SHA1, ++ KEX_GSS_NISTP256_SHA256, ++ KEX_GSS_C25519_SHA256, ++#endif + KEX_MAX + }; + +@@ -164,6 +173,12 @@ struct kex { + u_int flags; + int hash_alg; + int ec_nid; ++#ifdef GSSAPI ++ int gss_deleg_creds; ++ int gss_trust_dns; ++ char *gss_host; ++ char *gss_client; ++#endif + char *failed_choice; + int (*verify_host_key)(struct sshkey *, struct ssh *); + struct sshkey *(*load_host_public_key)(int, int, struct ssh *); +@@ -189,8 +204,10 @@ int kex_hash_from_name(const char *); + 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_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 *); +@@ -224,6 +241,12 @@ int kexgex_client(struct ssh *); + int kexgex_server(struct ssh *); + int kex_gen_client(struct ssh *); + int kex_gen_server(struct ssh *); ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++int kexgssgex_client(struct ssh *); ++int kexgssgex_server(struct ssh *); ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); ++#endif + + int kex_dh_keypair(struct kex *); + int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, +@@ -256,6 +279,12 @@ int kexgex_hash(int, const struct sshbu + const BIGNUM *, const u_char *, size_t, + u_char *, size_t *); + ++int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, ++ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, ++ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, ++ const struct sshbuf *client_pub, const struct sshbuf *server_pub, ++ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); ++ + void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); +diff --color -ruNp a/kex-names.c b/kex-names.c +--- a/kex-names.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex-names.c 2024-08-28 12:35:41.249432103 +0200 +@@ -45,6 +45,10 @@ + #include "ssherr.h" + #include "xmalloc.h" + ++#ifdef GSSAPI ++#include "ssh-gss.h" ++#endif ++ + struct kexalg { + char *name; + u_int type; +@@ -83,15 +87,28 @@ static const struct kexalg kexalgs[] = { + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, 0, -1, -1}, + }; ++static const struct kexalg gss_kexalgs[] = { ++#ifdef GSSAPI ++ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, ++#endif ++ { NULL, 0, -1, -1}, ++}; + +-char * +-kex_alg_list(char sep) ++static char * ++kex_alg_list_internal(char sep, const struct kexalg *algs) + { + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = algs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -106,6 +123,18 @@ kex_alg_list(char sep) + return ret; + } + ++char * ++kex_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, kexalgs); ++} ++ ++char * ++kex_gss_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, gss_kexalgs); ++} ++ + static const struct kexalg * + kex_alg_by_name(const char *name) + { +@@ -115,6 +144,10 @@ kex_alg_by_name(const char *name) + if (strcmp(k->name, name) == 0) + return k; + } ++ for (k = gss_kexalgs; k->name != NULL; k++) { ++ if (strncmp(k->name, name, strlen(k->name)) == 0) ++ return k; ++ } + return NULL; + } + +@@ -328,3 +361,26 @@ kex_assemble_names(char **listp, const c + free(ret); + return r; + } ++ ++/* Validate GSS KEX method name list */ ++int ++kex_gss_names_valid(const char *names) ++{ ++ char *s, *cp, *p; ++ ++ if (names == NULL || *names == '\0') ++ return 0; ++ s = cp = xstrdup(names); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (strncmp(p, "gss-", 4) != 0 ++ || kex_alg_by_name(p) == NULL) { ++ error("Unsupported KEX algorithm \"%.100s\"", p); ++ free(s); ++ return 0; ++ } ++ } ++ debug3("gss kex names ok: [%s]", names); ++ free(s); ++ return 1; ++} +diff --color -ruNp a/Makefile.in b/Makefile.in +--- a/Makefile.in 2024-08-28 12:35:01.200659705 +0200 ++++ b/Makefile.in 2024-08-28 12:35:41.244432006 +0200 +@@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + 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 \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sshbuf-io.o + +@@ -135,7 +136,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rh + 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 \ ++ 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 \ + sftp-server.o sftp-common.o \ +@@ -529,7 +530,7 @@ regress-prep: + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile + + REGRESSLIBS=libssh.a $(LIBCOMPAT) +-TESTLIBS=$(LIBS) $(CHANNELLIBS) ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) + + regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ +diff --color -ruNp a/monitor.c b/monitor.c +--- a/monitor.c 2024-08-28 12:35:01.192659551 +0200 ++++ b/monitor.c 2024-08-28 12:35:41.251432142 +0200 +@@ -143,6 +143,8 @@ int mm_answer_gss_setup_ctx(struct ssh * int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -2602,7 +2532,7 @@ index 2ce89fe9..ebf76c7f 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -220,11 +222,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2621,7 +2551,7 @@ index 2ce89fe9..ebf76c7f 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -293,6 +302,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, s /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2632,7 +2562,7 @@ index 2ce89fe9..ebf76c7f 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s +@@ -344,8 +357,15 @@ monitor_child_preauth(struct ssh *ssh, s if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(ssh, authenticated, partial, auth_method, auth_submethod); @@ -2649,7 +2579,7 @@ index 2ce89fe9..ebf76c7f 100644 if (authenticated || partial) { auth2_update_session_info(authctxt, auth_method, auth_submethod); -@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -413,6 +433,10 @@ monitor_child_postauth(struct ssh *ssh, monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2660,7 +2590,7 @@ index 2ce89fe9..ebf76c7f 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1793,6 +1817,17 @@ monitor_apply_keystate(struct ssh *ssh, # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2678,7 +2608,7 @@ index 2ce89fe9..ebf76c7f 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1885,8 +1920,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, u_char *p; int r; @@ -2689,7 +2619,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1918,8 +1953,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2700,7 +2630,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1939,6 +1974,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2708,7 +2638,7 @@ index 2ce89fe9..ebf76c7f 100644 } return (0); } -@@ -1871,8 +1900,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1950,8 +1986,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, OM_uint32 ret; int r; @@ -2719,7 +2649,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1898,13 +1927,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1977,13 +2013,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2741,7 +2671,7 @@ index 2ce89fe9..ebf76c7f 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1992,7 +2032,11 @@ mm_answer_gss_userok(struct ssh *ssh, in debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2754,7 +2684,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1921,5 +1958,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2000,5 +2044,84 @@ mm_answer_gss_userok(struct ssh *ssh, in /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2839,11 +2769,10 @@ index 2ce89fe9..ebf76c7f 100644 + #endif /* GSSAPI */ -diff --git a/monitor.h b/monitor.h -index 683e5e07..2b1a2d59 100644 ---- a/monitor.h -+++ b/monitor.h -@@ -63,6 +63,8 @@ enum monitor_reqtype { +diff --color -ruNp a/monitor.h b/monitor.h +--- a/monitor.h 2024-08-28 12:35:01.192659551 +0200 ++++ b/monitor.h 2024-08-28 12:35:41.251432142 +0200 +@@ -67,6 +67,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -2852,11 +2781,10 @@ index 683e5e07..2b1a2d59 100644 }; struct ssh; -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 001a8fa1..6edb509a 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -993,13 +993,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c +--- a/monitor_wrap.c 2024-08-28 12:35:01.192659551 +0200 ++++ b/monitor_wrap.c 2024-08-28 12:35:41.251432142 +0200 +@@ -1075,13 +1075,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -2873,7 +2801,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) +@@ -1094,6 +1096,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -2931,11 +2859,12 @@ index 001a8fa1..6edb509a 100644 +} + #endif /* GSSAPI */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 23ab096a..485590c1 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -64,8 +64,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, + + /* +diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h +--- a/monitor_wrap.h 2024-08-28 12:35:01.193659570 +0200 ++++ b/monitor_wrap.h 2024-08-28 12:35:41.251432142 +0200 +@@ -67,8 +67,10 @@ void mm_decode_activate_server_options(s OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2947,10 +2876,54 @@ index 23ab096a..485590c1 100644 #endif #ifdef USE_PAM -diff -up a/readconf.c.gsskex b/readconf.c ---- a/readconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/readconf.c 2021-08-27 12:25:42.556421509 +0200 -@@ -67,6 +67,7 @@ +diff --color -ruNp a/packet.c b/packet.c +--- a/packet.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/packet.c 2024-08-28 12:35:41.260432315 +0200 +@@ -1517,6 +1517,29 @@ ssh_packet_read(struct ssh *ssh) + return type; + } + ++/* ++ * Waits until a packet has been received, verifies that its type matches ++ * that given, and gives a fatal error and exits if there is a mismatch. ++ */ ++ ++int ++ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) ++{ ++ int r; ++ u_char type; ++ ++ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) ++ return r; ++ if (type != expected_type) { ++ if ((r = sshpkt_disconnect(ssh, ++ "Protocol error: expected packet type %d, got %d", ++ expected_type, type)) != 0) ++ return r; ++ return SSH_ERR_PROTOCOL_ERROR; ++ } ++ return 0; ++} ++ + static int + ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + { +diff --color -ruNp a/packet.h b/packet.h +--- a/packet.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/packet.h 2024-08-28 12:35:41.260432315 +0200 +@@ -124,6 +124,7 @@ int ssh_packet_send2_wrapped(struct ssh + int ssh_packet_send2(struct ssh *); + + int ssh_packet_read(struct ssh *); ++int ssh_packet_read_expect(struct ssh *, u_int type); + 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 --color -ruNp a/readconf.c b/readconf.c +--- a/readconf.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/readconf.c 2024-08-28 12:35:41.253432180 +0200 +@@ -70,6 +70,7 @@ #include "uidswap.h" #include "myproposal.h" #include "digest.h" @@ -2958,7 +2931,7 @@ diff -up a/readconf.c.gsskex b/readconf.c /* Format of the configuration file: -@@ -161,6 +162,8 @@ typedef enum { +@@ -164,6 +165,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2967,7 +2940,7 @@ diff -up a/readconf.c.gsskex b/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -206,10 +209,22 @@ static struct { +@@ -210,10 +213,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2990,7 +2963,7 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1113,10 +1128,42 @@ parse_time: +@@ -1227,10 +1242,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3033,7 +3006,7 @@ diff -up a/readconf.c.gsskex b/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2306,7 +2353,13 @@ initialize_options(Options * options) +@@ -2542,7 +2589,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3047,7 +3020,7 @@ diff -up a/readconf.c.gsskex b/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2463,8 +2516,18 @@ fill_default_options(Options * options) +@@ -2705,8 +2758,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3066,7 +3039,7 @@ diff -up a/readconf.c.gsskex b/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3246,7 +3309,14 @@ dump_client_config(Options *o, const cha +@@ -3533,7 +3596,14 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3081,10 +3054,10 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff -up a/readconf.h.gsskex b/readconf.h ---- a/readconf.h.gsskex 2021-08-27 12:05:29.248142431 +0200 -+++ b/readconf.h 2021-08-27 12:22:19.270679852 +0200 -@@ -39,7 +39,13 @@ typedef struct { +diff --color -ruNp a/readconf.h b/readconf.h +--- a/readconf.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/readconf.h 2024-08-28 12:35:41.254432199 +0200 +@@ -40,7 +40,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ @@ -3098,18 +3071,18 @@ diff -up a/readconf.h.gsskex b/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up a/servconf.c.gsskex b/servconf.c ---- a/servconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/servconf.c 2021-08-27 12:28:15.887735189 +0200 -@@ -70,6 +70,7 @@ +diff --color -ruNp a/servconf.c b/servconf.c +--- a/servconf.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/servconf.c 2024-08-28 12:35:41.255432218 +0200 +@@ -68,6 +68,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "ssh-gss.h" - static void add_listen_addr(ServerOptions *, const char *, - const char *, int); -@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions + #if !defined(SSHD_PAM_SERVICE) + # define SSHD_PAM_SERVICE "sshd" +@@ -137,8 +138,11 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3121,7 +3094,7 @@ diff -up a/servconf.c.gsskex b/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -356,10 +360,18 @@ fill_default_server_options(ServerOption +@@ -376,10 +380,18 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3140,15 +3113,15 @@ diff -up a/servconf.c.gsskex b/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -506,6 +518,7 @@ typedef enum { - sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, +@@ -558,6 +570,7 @@ typedef enum { + sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -587,12 +600,22 @@ static struct { +@@ -643,12 +656,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3171,7 +3144,7 @@ diff -up a/servconf.c.gsskex b/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1576,6 +1599,10 @@ process_server_config_line_depth(ServerO +@@ -1585,6 +1608,10 @@ process_server_config_line_depth(ServerO intptr = &options->gss_authentication; goto parse_flag; @@ -3182,7 +3155,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1584,6 +1611,22 @@ process_server_config_line_depth(ServerO +@@ -1593,6 +1620,22 @@ process_server_config_line_depth(ServerO intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3205,7 +3178,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2892,6 +2935,10 @@ dump_config(ServerOptions *o) +@@ -3178,6 +3221,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3216,11 +3189,10 @@ diff -up a/servconf.c.gsskex b/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --git a/servconf.h b/servconf.h -index 4202a2d0..3f47ea25 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -132,8 +132,11 @@ typedef struct { +diff --color -ruNp a/servconf.h b/servconf.h +--- a/servconf.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/servconf.h 2024-08-28 12:35:41.255432218 +0200 +@@ -149,8 +149,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3232,11 +3204,10 @@ index 4202a2d0..3f47ea25 100644 int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff --git a/session.c b/session.c -index 8c0e54f7..06a33442 100644 ---- a/session.c -+++ b/session.c -@@ -2678,13 +2678,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +diff --color -ruNp a/session.c b/session.c +--- a/session.c 2024-08-28 12:35:01.197659647 +0200 ++++ b/session.c 2024-08-28 12:35:41.255432218 +0200 +@@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *au #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3258,135 +3229,10 @@ index 8c0e54f7..06a33442 100644 #endif /* remove agent socket */ -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 - -+#define SSH2_MSG_KEXGSS_INIT 30 -+#define SSH2_MSG_KEXGSS_CONTINUE 31 -+#define SSH2_MSG_KEXGSS_COMPLETE 32 -+#define SSH2_MSG_KEXGSS_HOSTKEY 33 -+#define SSH2_MSG_KEXGSS_ERROR 34 -+#define SSH2_MSG_KEXGSS_GROUPREQ 40 -+#define SSH2_MSG_KEXGSS_GROUP 41 -+#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" -+#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" -+#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" -+#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" -+#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" -+#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" -+#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" -+ -+#define GSS_KEX_DEFAULT_KEX \ -+ KEX_GSS_GRP14_SHA256_ID "," \ -+ KEX_GSS_GRP16_SHA512_ID "," \ -+ KEX_GSS_NISTP256_SHA256_ID "," \ -+ KEX_GSS_C25519_SHA256_ID "," \ -+ KEX_GSS_GRP14_SHA1_ID "," \ -+ KEX_GSS_GEX_SHA1_ID -+ - typedef struct { - char *filename; - char *envvar; - char *envval; -+ struct passwd *owner; - void *data; - } ssh_gssapi_ccache; - -@@ -72,8 +92,11 @@ typedef struct { - gss_buffer_desc displayname; - gss_buffer_desc exportedname; - gss_cred_id_t creds; -+ gss_name_t name; - struct ssh_gssapi_mech_struct *mech; - ssh_gssapi_ccache store; -+ int used; -+ int updated; - } ssh_gssapi_client; - - typedef struct ssh_gssapi_mech_struct { -@@ -84,6 +107,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); - void (*storecreds) (ssh_gssapi_client *); -+ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - - typedef struct { -@@ -94,10 +118,11 @@ typedef struct { - gss_OID oid; /* client */ - gss_cred_id_t creds; /* server */ - gss_name_t client; /* server */ -- gss_cred_id_t client_creds; /* server */ -+ gss_cred_id_t client_creds; /* both */ - } Gssctxt; - - extern ssh_gssapi_mech *supported_mechs[]; -+extern Gssctxt *gss_kex_context; - - int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); - void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); - - struct sshbuf; - int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); -+int ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *, gss_buffer_desc *); - - OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); - OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, -@@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); - OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_buildmic(struct sshbuf *, const char *, - const char *, const char *, const struct sshbuf *); --int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); -+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); -+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); -+int ssh_gssapi_credentials_updated(Gssctxt *); - - /* In the server */ -+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, -+ const char *); -+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); -+char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, -+ const char *, const char *); -+gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); -+int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, -+ const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); --int ssh_gssapi_userok(char *name); -+int ssh_gssapi_userok(char *name, struct passwd *, int kex); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); - void ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - -+char *ssh_gssapi_server_mechanisms(void); -+int ssh_gssapi_oid_table_ok(void); -+ -+int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); -+void ssh_gssapi_rekey_creds(void); -+ - #endif /* GSSAPI */ - - #endif /* _SSH_GSS_H */ -diff --git a/ssh.1 b/ssh.1 -index 60de6087..db5c65bc 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -503,7 +503,13 @@ For full details of the options listed below, and their possible values, see +diff --color -ruNp a/ssh.1 b/ssh.1 +--- a/ssh.1 2024-08-28 12:35:01.207659840 +0200 ++++ b/ssh.1 2024-08-28 12:35:41.256432238 +0200 +@@ -536,7 +536,13 @@ For full details of the options listed b .It GatewayPorts .It GlobalKnownHostsFile .It GSSAPIAuthentication @@ -3400,7 +3246,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -624,6 +624,8 @@ +@@ -624,6 +630,8 @@ flag), (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3409,11 +3255,10 @@ index 60de6087..db5c65bc 100644 .Ar key (key types), .Ar key-ca-sign -diff --git a/ssh.c b/ssh.c -index 15aee569..110cf9c1 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -747,6 +747,8 @@ main(int ac, char **av) +diff --color -ruNp a/ssh.c b/ssh.c +--- a/ssh.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh.c 2024-08-28 12:35:41.256432238 +0200 +@@ -827,6 +827,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3422,7 +3267,7 @@ index 15aee569..110cf9c1 100644 else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -772,8 +774,8 @@ main(int ac, char **av) +@@ -857,8 +859,8 @@ main(int ac, char **av) } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( "cipher\ncipher-auth\ncompression\nkex\n" @@ -3433,10 +3278,9 @@ index 15aee569..110cf9c1 100644 } if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); -diff --git a/ssh_config b/ssh_config -index 5e8ef548..1ff999b6 100644 ---- a/ssh_config -+++ b/ssh_config +diff --color -ruNp a/ssh_config b/ssh_config +--- a/ssh_config 2024-08-28 12:35:01.216660014 +0200 ++++ b/ssh_config 2024-08-28 12:35:41.256432238 +0200 @@ -24,6 +24,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -3446,11 +3290,10 @@ index 5e8ef548..1ff999b6 100644 # BatchMode no # CheckHostIP no # AddressFamily any -diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..3f490697 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -766,10 +766,68 @@ The default is +diff --color -ruNp a/ssh_config.5 b/ssh_config.5 +--- a/ssh_config.5 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh_config.5 2024-08-28 12:35:41.257432257 +0200 +@@ -938,10 +938,68 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3519,21 +3362,11 @@ index 06a32d31..3f490697 100644 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -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; +diff --color -ruNp a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshconnect2.c 2024-08-28 12:35:41.258432276 +0200 +@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, st + char *all_key, *hkalgs = NULL; int r, use_known_hosts_order = 0; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3544,11 +3377,10 @@ index af00fb30..03bc87eb 100644 xxx_host = host; 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), +@@ -255,6 +260,42 @@ ssh_kex2(struct ssh *ssh, char *host, st + compression_alg_list(options.compression), hkalgs ? hkalgs : options.hostkeyalgorithms); -+ + +#if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { + /* Add the GSSAPI mechanisms currently supported on this @@ -3584,10 +3416,11 @@ index af00fb30..03bc87eb 100644 + } + } +#endif - ++ free(hkalgs); -@@ -224,17 +256,47 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + /* start key exchange */ +@@ -271,14 +312,44 @@ ssh_kex2(struct ssh *ssh, char *host, st # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; # endif @@ -3618,11 +3451,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,10 +3463,10 @@ index af00fb30..03bc87eb 100644 + free(gss); + } +#endif - if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) - fatal_r(r, "kex_prop2buf"); - -@@ -330,6 +392,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); + #ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || +@@ -368,6 +439,7 @@ static int input_gssapi_response(int typ static int input_gssapi_token(int type, u_int32_t, struct ssh *); static int input_gssapi_error(int, u_int32_t, struct ssh *); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -3644,7 +3474,7 @@ index af00fb30..03bc87eb 100644 #endif void userauth(struct ssh *, char *); -@@ -346,6 +409,11 @@ static char *authmethods_get(void); +@@ -384,6 +456,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -3656,7 +3486,7 @@ index af00fb30..03bc87eb 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -716,12 +784,32 @@ userauth_gssapi(struct ssh *ssh) +@@ -755,12 +832,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; @@ -3690,7 +3520,7 @@ index af00fb30..03bc87eb 100644 /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -730,13 +811,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -769,13 +866,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3707,7 +3537,7 @@ index af00fb30..03bc87eb 100644 if (!ok || mech == NULL) return 0; -@@ -976,6 +1059,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -1009,6 +1108,55 @@ input_gssapi_error(int type, u_int32_t p free(lang); return r; } @@ -3763,22 +3593,10 @@ index af00fb30..03bc87eb 100644 #endif /* GSSAPI */ static int -diff --git a/sshd.c b/sshd.c -index 60b2aaf7..d92f03aa 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) -- fatal_f("no hostkeys"); -- if ((r = sshpkt_send(ssh)) != 0) -+ debug3_f("no hostkeys"); -+ else if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); - } -@@ -1852,7 +1852,8 @@ main(int ac, char **av) +diff --color -ruNp a/sshd.c b/sshd.c +--- a/sshd.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshd.c 2024-08-28 12:35:41.258432276 +0200 +@@ -1551,7 +1551,8 @@ main(int ac, char **av) free(fp); } accumulate_host_timing_secret(cfg, NULL); @@ -3788,80 +3606,10 @@ index 60b2aaf7..d92f03aa 100644 logit("sshd: no hostkeys available -- exiting."); exit(1); } -@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) - - free(hkalgs); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ { -+ char *orig; -+ char *gss = NULL; -+ char *newstr = NULL; -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ /* -+ * If we don't have a host key, then there's no point advertising -+ * the other key exchange algorithms -+ */ -+ -+ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) -+ orig = NULL; -+ -+ if (options.gss_keyex) -+ gss = ssh_gssapi_server_mechanisms(); -+ else -+ gss = NULL; -+ -+ if (gss && orig) -+ xasprintf(&newstr, "%s,%s", gss, orig); -+ else if (gss) -+ newstr = gss; -+ else if (orig) -+ newstr = orig; -+ -+ /* -+ * If we've got GSSAPI mechanisms, then we've got the 'null' host -+ * key alg, but we can't tell people about it unless its the only -+ * host key algorithm we support -+ */ -+ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; -+ -+ if (newstr) -+ myproposal[PROPOSAL_KEX_ALGS] = newstr; -+ else -+ fatal("No supported key exchange algorithms"); -+ } -+#endif -+ - /* start key exchange */ - 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 - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - # endif --#endif -+# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } -+# endif -+#endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->load_host_public_key=&get_hostkey_public_by_type; -diff --git a/sshd_config b/sshd_config -index 19b7c91a..2c48105f 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys +diff --color -ruNp a/sshd_config b/sshd_config +--- a/sshd_config 2024-08-28 12:35:01.221660110 +0200 ++++ b/sshd_config 2024-08-28 12:35:41.259432296 +0200 +@@ -77,6 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes @@ -3870,11 +3618,10 @@ index 19b7c91a..2c48105f 100644 # 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 70ccea44..f6b41a2f 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -646,6 +646,11 @@ Specifies whether to automatically destroy the user's credentials cache +diff --color -ruNp a/sshd_config.5 b/sshd_config.5 +--- a/sshd_config.5 2024-08-28 12:35:01.218660052 +0200 ++++ b/sshd_config.5 2024-08-28 12:35:41.259432296 +0200 +@@ -739,6 +739,11 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -3886,7 +3633,7 @@ index 70ccea44..f6b41a2f 100644 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -660,6 +665,32 @@ machine's default store. +@@ -753,6 +758,32 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -3919,15 +3666,223 @@ index 70ccea44..f6b41a2f 100644 .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. -diff --git a/sshkey.c b/sshkey.c -index 57995ee6..fd5b7724 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -127,6 +127,75 @@ static const struct keytype keytypes[] = { - extern const struct sshkey_impl sshkey_xmss_impl; +diff --color -ruNp a/sshd-session.c b/sshd-session.c +--- a/sshd-session.c 2024-08-28 12:35:01.221660110 +0200 ++++ b/sshd-session.c 2024-08-28 12:35:41.263432373 +0200 +@@ -660,8 +660,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) +- fatal_f("no hostkeys"); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3_f("no hostkeys"); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } +@@ -1180,8 +1180,9 @@ main(int ac, char **av) + break; + } + } +- if (!have_key) +- fatal("internal error: monitor received no hostkeys"); ++ /* The GSSAPI key exchange can run without a host key */ ++ if (!have_key && !options.gss_keyex) ++ fatal("internal error: monitor received no hostkeys and GSS KEX is not configured"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; +@@ -1462,6 +1463,48 @@ do_ssh2_kex(struct ssh *ssh) + + free(hkalgs); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ { ++ char *orig; ++ char *gss = NULL; ++ char *newstr = NULL; ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ /* ++ * If we don't have a host key, then there's no point advertising ++ * the other key exchange algorithms ++ */ ++ ++ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) ++ orig = NULL; ++ ++ if (options.gss_keyex) ++ gss = ssh_gssapi_server_mechanisms(); ++ else ++ gss = NULL; ++ ++ if (gss && orig) ++ xasprintf(&newstr, "%s,%s", gss, orig); ++ else if (gss) ++ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com"); ++ else if (orig) ++ newstr = orig; ++ ++ /* ++ * If we've got GSSAPI mechanisms, then we've got the 'null' host ++ * key alg, but we can't tell people about it unless its the only ++ * host key algorithm we support ++ */ ++ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); ++ ++ if (newstr) ++ myproposal[PROPOSAL_KEX_ALGS] = newstr; ++ else ++ fatal("No supported key exchange algorithms"); ++ } ++#endif ++ + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); +@@ -1479,7 +1522,18 @@ do_ssh2_kex(struct ssh *ssh) + #ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + #endif +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } ++# endif ++#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; +diff --color -ruNp a/ssh-gss.h b/ssh-gss.h +--- a/ssh-gss.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh-gss.h 2024-08-28 12:35:41.256432238 +0200 +@@ -61,10 +61,34 @@ + + #define SSH_GSS_OIDTYPE 0x06 + ++#define SSH2_MSG_KEXGSS_INIT 30 ++#define SSH2_MSG_KEXGSS_CONTINUE 31 ++#define SSH2_MSG_KEXGSS_COMPLETE 32 ++#define SSH2_MSG_KEXGSS_HOSTKEY 33 ++#define SSH2_MSG_KEXGSS_ERROR 34 ++#define SSH2_MSG_KEXGSS_GROUPREQ 40 ++#define SSH2_MSG_KEXGSS_GROUP 41 ++#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" ++#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" ++#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" ++#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" ++#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" ++#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" ++#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" ++ ++#define GSS_KEX_DEFAULT_KEX \ ++ KEX_GSS_GRP14_SHA256_ID "," \ ++ KEX_GSS_GRP16_SHA512_ID "," \ ++ KEX_GSS_NISTP256_SHA256_ID "," \ ++ KEX_GSS_C25519_SHA256_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID "," \ ++ KEX_GSS_GEX_SHA1_ID ++ + typedef struct { + char *filename; + char *envvar; + char *envval; ++ struct passwd *owner; + void *data; + } ssh_gssapi_ccache; + +@@ -72,8 +96,11 @@ typedef struct { + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; ++ gss_name_t name; + struct ssh_gssapi_mech_struct *mech; + ssh_gssapi_ccache store; ++ int used; ++ int updated; + } ssh_gssapi_client; + + typedef struct ssh_gssapi_mech_struct { +@@ -84,6 +111,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); + void (*storecreds) (ssh_gssapi_client *); ++ int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + + typedef struct { +@@ -94,10 +122,11 @@ typedef struct { + gss_OID oid; /* client */ + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ +- gss_cred_id_t client_creds; /* server */ ++ gss_cred_id_t client_creds; /* both */ + } Gssctxt; + + extern ssh_gssapi_mech *supported_mechs[]; ++extern Gssctxt *gss_kex_context; + + int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); + void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); +@@ -108,6 +137,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( + + struct sshbuf; + int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); ++int ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *, gss_buffer_desc *); + + OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); + OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, +@@ -122,17 +152,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); + OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_buildmic(struct sshbuf *, const char *, + const char *, const char *, const struct sshbuf *); +-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); ++int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); ++OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); ++int ssh_gssapi_credentials_updated(Gssctxt *); + + /* In the server */ ++typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, ++ const char *); ++char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); ++char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, ++ const char *, const char *); ++gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); ++int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, ++ const char *); + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +-int ssh_gssapi_userok(char *name); ++int ssh_gssapi_userok(char *name, struct passwd *, int kex); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); + void ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + ++char *ssh_gssapi_server_mechanisms(void); ++int ssh_gssapi_oid_table_ok(void); ++ ++int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); ++void ssh_gssapi_rekey_creds(void); ++ + #endif /* GSSAPI */ + + #endif /* _SSH_GSS_H */ +diff --color -ruNp a/sshkey.c b/sshkey.c +--- a/sshkey.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshkey.c 2024-08-28 12:35:41.260432315 +0200 +@@ -131,6 +131,75 @@ extern const struct sshkey_impl sshkey_x extern const struct sshkey_impl sshkey_xmss_cert_impl; #endif -+ + +static int ssh_gss_equal(const struct sshkey *, const struct sshkey *) +{ + return SSH_ERR_FEATURE_UNSUPPORTED; @@ -3996,10 +3951,11 @@ index 57995ee6..fd5b7724 100644 + /* .keybits = */ 0, /* FIXME */ + /* .funcs = */ &sshkey_gss_funcs, +}; - ++ const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, -@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { + &sshkey_ed25519_cert_impl, +@@ -169,6 +238,7 @@ const struct sshkey_impl * const keyimpl &sshkey_xmss_impl, &sshkey_xmss_cert_impl, #endif @@ -4007,7 +3963,7 @@ index 57995ee6..fd5b7724 100644 NULL }; -@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -324,7 +394,7 @@ sshkey_alg_list(int certs_only, int plai for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -4016,11 +3972,10 @@ index 57995ee6..fd5b7724 100644 continue; if (!include_sigonly && impl->sigonly) continue; -diff --git a/sshkey.h b/sshkey.h -index 71a3fddc..37a43a67 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -69,6 +69,7 @@ enum sshkey_types { +diff --color -ruNp a/sshkey.h b/sshkey.h +--- a/sshkey.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshkey.h 2024-08-28 12:35:41.260432315 +0200 +@@ -71,6 +71,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -4028,47 +3983,3 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; -diff --git a/packet.h b/packet.h ---- a/packet.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/packet.h (date 1703172586447) -@@ -124,6 +124,7 @@ - int ssh_packet_send2(struct ssh *); - - 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); -diff --git a/packet.c b/packet.c ---- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/packet.c (date 1703172586447) -@@ -1425,6 +1416,29 @@ - return type; - } - -+/* -+ * Waits until a packet has been received, verifies that its type matches -+ * that given, and gives a fatal error and exits if there is a mismatch. -+ */ -+ -+int -+ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) -+{ -+ int r; -+ u_char type; -+ -+ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) -+ return r; -+ if (type != expected_type) { -+ if ((r = sshpkt_disconnect(ssh, -+ "Protocol error: expected packet type %d, got %d", -+ expected_type, type)) != 0) -+ return r; -+ return SSH_ERR_PROTOCOL_ERROR; -+ } -+ return 0; -+} -+ - static int - ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - { diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 1e7940d..9931d92 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -964,10 +964,10 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c 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 +@@ -1549,10 +1549,74 @@ add_p11_identity(struct sshkey *key, cha + idtab->nentries++; } - #ifdef ENABLE_PKCS11 +static char * +sanitize_pkcs11_provider(const char *provider) +{ @@ -978,6 +978,8 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c + if (provider == NULL) + return NULL; + ++ memset(canonical_provider, 0, sizeof(canonical_provider)); ++ + if (strlen(provider) >= strlen(PKCS11_URI_SCHEME) && + strncmp(provider, PKCS11_URI_SCHEME, + strlen(PKCS11_URI_SCHEME)) == 0) { diff --git a/openssh-8.0p1-preserve-pam-errors.patch b/openssh-8.0p1-preserve-pam-errors.patch index dbdbe93..b7ab965 100644 --- a/openssh-8.0p1-preserve-pam-errors.patch +++ b/openssh-8.0p1-preserve-pam-errors.patch @@ -27,16 +27,15 @@ diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c else if (sshpam_maxtries_reached) ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); else -@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha - plen++; +@@ -856,9 +862,11 @@ sshpam_query(void *ctx, char **name, cha free(msg); break; -+ case PAM_USER_UNKNOWN: -+ case PAM_PERM_DENIED: case PAM_ACCT_EXPIRED: + sshpam_account_status = 0; + /* FALLTHROUGH */ case PAM_MAXTRIES: ++ case PAM_USER_UNKNOWN: ++ case PAM_PERM_DENIED: - if (type == PAM_ACCT_EXPIRED) - sshpam_account_status = 0; if (type == PAM_MAXTRIES) diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index 479b55d..d8577d2 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -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 }, diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch index ee3637f..c4d86e7 100644 --- a/openssh-8.7p1-negotiate-supported-algs.patch +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -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); diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch index 6a6b63d..abc6aa4 100644 --- a/openssh-8.7p1-nohostsha1proof.patch +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -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 @@ -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); diff --git a/openssh-9.0p1-evp-fips-dh.patch b/openssh-9.0p1-evp-fips-dh.patch index d0470d9..8c70197 100644 --- a/openssh-9.0p1-evp-fips-dh.patch +++ b/openssh-9.0p1-evp-fips-dh.patch @@ -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= "); diff --git a/openssh-9.6p1-gsskex-new-api.patch b/openssh-9.6p1-gsskex-new-api.patch index ed09319..0f2eabb 100644 --- a/openssh-9.6p1-gsskex-new-api.patch +++ b/openssh-9.6p1-gsskex-new-api.patch @@ -811,7 +811,7 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c + const BIGNUM *pub_key, *dh_p, *dh_g; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t hashlen; -+ int r; ++ int r = SSH_ERR_INTERNAL_ERROR; /* * We _must_ have received a COMPLETE message in reply from the @@ -1163,8 +1163,8 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c debug2_f("Acquiring credentials"); -- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) +- if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) fatal("Unable to acquire credentials for the server"); - do { @@ -1258,9 +1258,9 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + Gssctxt *gss = ssh->kex->gss; + int r; -- maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, -- &send_tok, &ret_flags)); -+ gss->major = PRIVSEP(ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags)); +- maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, +- &send_tok, &ret_flags); ++ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); + gss_release_buffer(&gss->minor, recv_tok); - gss_release_buffer(&min_status, &recv_tok); @@ -1327,8 +1327,8 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + 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(PRIVSEP(ssh_gssapi_sign(gss, &gss->buf, &msg_tok)))) +- if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) fatal("Couldn't get MIC"); if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -1537,8 +1537,8 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c debug2_f("Acquiring credentials"); -- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) +- if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) fatal("Unable to acquire credentials for the server"); - /* 5. S generates an ephemeral key pair (do the allocations early) */ @@ -1560,7 +1560,7 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c - 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"); @@ -1621,11 +1621,11 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c - "Protocol error: didn't expect packet type %d", - type); - } -+ gss->major = PRIVSEP(ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags)); ++ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); + gss_release_buffer(&gss->minor, recv_tok); -- 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); + if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) + fatal("Zero length token output when incomplete"); @@ -1744,8 +1744,8 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + gss->buf.value = hash; + gss->buf.length = hashlen; -- if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(gss, &gss->buf, &msg_tok)))) +- if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) fatal("Couldn't get MIC"); if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -1833,7 +1833,7 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + 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"); diff --git a/openssh-9.6p1-gsissh.patch b/openssh-9.8p1-gsissh.patch similarity index 85% rename from openssh-9.6p1-gsissh.patch rename to openssh-9.8p1-gsissh.patch index a2d2eff..ecb2c4e 100644 --- a/openssh-9.6p1-gsissh.patch +++ b/openssh-9.8p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c ---- openssh-9.6p1.orig/auth2.c 2024-07-07 07:25:31.581747706 +0200 -+++ openssh-9.6p1/auth2.c 2024-07-07 07:26:28.481916473 +0200 +diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c +--- openssh-9.8p1.orig/auth2.c 2024-09-30 11:38:28.487321398 +0200 ++++ openssh-9.8p1/auth2.c 2024-10-01 08:11:48.131268544 +0200 @@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -12,7 +12,7 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c + debug("received empty username for %s", method); + if (strcmp(method, "gssapi-keyex") == 0) { + char *lname = NULL; -+ PRIVSEP(ssh_gssapi_localname(&lname)); ++ mm_ssh_gssapi_localname(&lname); + if (lname && lname[0] != '\0') { + free(user); + user = lname; @@ -37,7 +37,7 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c auth_maxtries_exceeded(ssh); - if (authctxt->attempt++ == 0) { - /* setup auth context */ -- authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); +- authctxt->pw = mm_getpwnamallow(ssh, user); + /* If first time or username changed or empty username, + setup/reset authentication context. */ + if ((authctxt->attempt++ == 0) || @@ -64,7 +64,7 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c + authctxt->pw = fakepw(); + } else { +#endif -+ authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); ++ authctxt->pw = mm_getpwnamallow(ssh, user); + if (authctxt->pw) { authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); @@ -78,16 +78,16 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c +#endif #ifdef USE_PAM if (options.use_pam) - PRIVSEP(start_pam(ssh)); -@@ -319,6 +365,7 @@ + mm_start_pam(ssh); +@@ -318,6 +364,7 @@ + ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating " : "invalid ", user); - setproctitle("%s%s", authctxt->valid ? user : "unknown", - use_privsep ? " [net]" : ""); + setproctitle("%s [net]", authctxt->valid ? user : "unknown"); + if (authctxt->attempt == 1) { authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; #ifdef WITH_SELINUX -@@ -336,9 +383,10 @@ +@@ -333,9 +380,10 @@ if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, "no authentication methods enabled"); @@ -101,18 +101,18 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c ---- openssh-9.6p1.orig/auth2-gss.c 2024-07-07 07:25:31.469747374 +0200 -+++ openssh-9.6p1/auth2-gss.c 2024-07-07 07:26:28.482916477 +0200 -@@ -52,6 +52,7 @@ - - extern ServerOptions options; +diff -Nur openssh-9.8p1.orig/auth2-gss.c openssh-9.8p1/auth2-gss.c +--- openssh-9.8p1.orig/auth2-gss.c 2024-09-30 11:38:28.368321057 +0200 ++++ openssh-9.8p1/auth2-gss.c 2024-10-01 13:47:06.876811637 +0200 +@@ -54,6 +54,7 @@ + extern struct authmethod_cfg methodcfg_gsskeyex; + extern struct authmethod_cfg methodcfg_gssapi; +static void ssh_gssapi_userauth_error(Gssctxt *ctxt, struct ssh *ssh); static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); 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); -@@ -65,8 +66,8 @@ +@@ -67,8 +68,8 @@ { Authctxt *authctxt = ssh->authctxt; int r, authenticated = 0; @@ -123,7 +123,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c u_char *p; size_t len; -@@ -77,6 +78,9 @@ +@@ -79,6 +80,9 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -133,7 +133,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c mic.value = p; mic.length = len; -@@ -87,13 +91,29 @@ +@@ -89,13 +93,28 @@ fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); @@ -147,17 +147,16 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c + gssbuf2.length = sshbuf_len(b2); + /* 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)); -+ &gssbuf, &mic))) || -+ !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, -+ &gssbuf2, &mic)))) { + if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gss_kex_context, +- &gssbuf, &mic))) +- authenticated = mm_ssh_gssapi_userok(authctxt->user, +- authctxt->pw, 1); ++ &gssbuf, &mic)) || ++ !GSS_ERROR(mm_ssh_gssapi_checkmic(gss_kex_context, ++ &gssbuf2, &mic))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { -+ authenticated = -+ PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1)); ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 1); + } + } @@ -166,7 +165,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -152,7 +172,9 @@ +@@ -154,7 +173,9 @@ return (0); } @@ -177,7 +176,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c debug2_f("disabled because of invalid user"); free(doid); return (0); -@@ -190,7 +212,7 @@ +@@ -192,7 +213,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -186,7 +185,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c u_char *p; size_t len; int r; -@@ -211,6 +233,7 @@ +@@ -213,6 +234,7 @@ free(p); if (GSS_ERROR(maj_status)) { @@ -194,7 +193,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c if (send_tok.length != 0) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || -@@ -285,6 +308,34 @@ +@@ -287,6 +309,34 @@ return 0; } @@ -205,17 +204,17 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c + char *lname = NULL; + + if ((authctxt->user == NULL) || (authctxt->user[0] == '\0')) { -+ PRIVSEP(ssh_gssapi_localname(&lname)); ++ mm_ssh_gssapi_localname(&lname); + if (lname && lname[0] != '\0') { + if (authctxt->user) free(authctxt->user); + authctxt->user = lname; + debug("set username to %s from gssapi context", lname); -+ authctxt->pw = PRIVSEP(getpwnamallow(ssh, authctxt->user)); ++ authctxt->pw = mm_getpwnamallow(ssh, authctxt->user); + if (authctxt->pw) { + authctxt->valid = 1; +#ifdef USE_PAM + if (options.use_pam) -+ PRIVSEP(start_pam(ssh)); ++ mm_start_pam(ssh); +#endif + } + } else { @@ -229,15 +228,14 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c /* * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, -@@ -295,12 +346,14 @@ +@@ -297,11 +347,13 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; - int r, authenticated; + int r, authenticated = 0; - const char *displayname; - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + if (authctxt == NULL) fatal("No authentication or GSSAPI context"); + gssapi_set_username(ssh); @@ -245,35 +243,32 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c /* * We don't need to check the status, because we're only enabled in * the dispatcher once the exchange is complete -@@ -309,8 +362,11 @@ +@@ -310,7 +362,11 @@ if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -- authctxt->pw, 1)); +- authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1); + /* user should be set if valid but we double-check here */ + if (authctxt->valid && authctxt->user && authctxt->user[0]) { -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1)); ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 1); + } - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) -@@ -362,11 +418,17 @@ + authctxt->postponed = 0; + ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); +@@ -357,10 +413,16 @@ fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); -- if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) -- 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, authctxt->pw, 0); - else + gssapi_set_username(ssh); + -+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) { ++ if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) { + if (authctxt->valid && authctxt->user && authctxt->user[0]) { -+ authenticated = -+ PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0)); ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 0); + } + } else { logit("GSSAPI MIC check failed"); @@ -281,7 +276,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c sshbuf_free(b); if (micuser != authctxt->user) -@@ -386,6 +448,26 @@ +@@ -376,6 +438,26 @@ return 0; } @@ -290,7 +285,7 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c + OM_uint32 maj, min; + int r; + -+ errstr = PRIVSEP(ssh_gssapi_last_error(ctxt, &maj, &min)); ++ errstr = mm_ssh_gssapi_last_error(ctxt, &maj, &min); + if (errstr) { + if ((r = sshpkt_start(ssh, + SSH2_MSG_USERAUTH_GSSAPI_ERROR)) != 0 || @@ -306,12 +301,12 @@ diff -Nur openssh-9.6p1.orig/auth2-gss.c openssh-9.6p1/auth2-gss.c +} + Authmethod method_gsskeyex = { - "gssapi-keyex", - NULL, -diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c ---- openssh-9.6p1.orig/auth.c 2024-07-07 07:25:31.582747709 +0200 -+++ openssh-9.6p1/auth.c 2024-07-07 07:26:28.482916477 +0200 -@@ -299,7 +299,8 @@ + &methodcfg_gsskeyex, + userauth_gsskeyex, +diff -Nur openssh-9.8p1.orig/auth.c openssh-9.8p1/auth.c +--- openssh-9.8p1.orig/auth.c 2024-09-30 11:38:28.488321400 +0200 ++++ openssh-9.8p1/auth.c 2024-09-30 11:39:17.561461794 +0200 +@@ -298,7 +298,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", @@ -321,7 +316,7 @@ diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -487,13 +488,18 @@ +@@ -486,13 +487,18 @@ #endif pw = getpwnam(user); @@ -341,9 +336,9 @@ diff -Nur openssh-9.6p1.orig/auth.c openssh-9.6p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-9.6p1.orig/auth.h openssh-9.6p1/auth.h ---- openssh-9.6p1.orig/auth.h 2024-07-07 07:25:31.582747709 +0200 -+++ openssh-9.6p1/auth.h 2024-07-07 07:26:28.483916479 +0200 +diff -Nur openssh-9.8p1.orig/auth.h openssh-9.8p1/auth.h +--- openssh-9.8p1.orig/auth.h 2024-09-30 11:38:28.489321403 +0200 ++++ openssh-9.8p1/auth.h 2024-09-30 11:39:17.561461794 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -353,10 +348,10 @@ diff -Nur openssh-9.6p1.orig/auth.h openssh-9.6p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c ---- openssh-9.6p1.orig/auth-pam.c 2024-07-07 07:25:31.623747830 +0200 -+++ openssh-9.6p1/auth-pam.c 2024-07-07 07:26:28.483916479 +0200 -@@ -252,6 +252,7 @@ +diff -Nur openssh-9.8p1.orig/auth-pam.c openssh-9.8p1/auth-pam.c +--- openssh-9.8p1.orig/auth-pam.c 2024-09-30 11:38:28.533321529 +0200 ++++ openssh-9.8p1/auth-pam.c 2024-09-30 11:39:17.562461797 +0200 +@@ -248,6 +248,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; static char *sshpam_laddr = NULL; @@ -364,7 +359,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c /* Some PAM implementations don't implement this */ #ifndef HAVE_PAM_GETENVLIST -@@ -300,6 +301,56 @@ +@@ -296,6 +297,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -421,7 +416,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c static void sshpam_password_change_required(int reqd) { -@@ -331,7 +382,7 @@ +@@ -327,7 +378,7 @@ static void import_environments(struct sshbuf *b) { @@ -430,7 +425,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c u_int n, i, num_env; int r; -@@ -347,6 +398,19 @@ +@@ -343,6 +394,19 @@ if ((r = sshbuf_get_u32(b, &n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshpam_password_change_required(n != 0); @@ -450,7 +445,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) -@@ -526,6 +590,13 @@ +@@ -522,6 +586,13 @@ if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -464,7 +459,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c if (!do_pam_account()) { /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN. * Backward compatibility for other errors. */ -@@ -550,6 +621,13 @@ +@@ -546,6 +617,13 @@ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); @@ -507,7 +502,7 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c sshpam_account_status = 0; return (sshpam_account_status); @@ -1384,6 +1476,9 @@ - pam_strerror(sshpam_handle, sshpam_err)); + expose_authinfo(__func__); sshpam_err = pam_authenticate(sshpam_handle, flags); + if (options.permit_pam_user_change) { @@ -516,9 +511,9 @@ diff -Nur openssh-9.6p1.orig/auth-pam.c openssh-9.6p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-9.6p1.orig/auth-pam.h openssh-9.6p1/auth-pam.h ---- openssh-9.6p1.orig/auth-pam.h 2024-07-07 07:25:31.437747279 +0200 -+++ openssh-9.6p1/auth-pam.h 2024-07-07 07:26:28.484916482 +0200 +diff -Nur openssh-9.8p1.orig/auth-pam.h openssh-9.8p1/auth-pam.h +--- openssh-9.8p1.orig/auth-pam.h 2024-09-30 11:38:28.333320957 +0200 ++++ openssh-9.8p1/auth-pam.h 2024-09-30 11:39:17.563461800 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -526,9 +521,9 @@ diff -Nur openssh-9.6p1.orig/auth-pam.h openssh-9.6p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-9.6p1.orig/canohost.c openssh-9.6p1/canohost.c ---- openssh-9.6p1.orig/canohost.c 2024-07-07 07:25:31.470747377 +0200 -+++ openssh-9.6p1/canohost.c 2024-07-07 07:26:28.484916482 +0200 +diff -Nur openssh-9.8p1.orig/canohost.c openssh-9.8p1/canohost.c +--- openssh-9.8p1.orig/canohost.c 2024-09-30 11:38:28.368321057 +0200 ++++ openssh-9.8p1/canohost.c 2024-09-30 11:39:17.564461803 +0200 @@ -17,6 +17,7 @@ #include #include @@ -571,9 +566,9 @@ diff -Nur openssh-9.6p1.orig/canohost.c openssh-9.6p1/canohost.c + } + } +} -diff -Nur openssh-9.6p1.orig/canohost.h openssh-9.6p1/canohost.h ---- openssh-9.6p1.orig/canohost.h 2024-07-07 07:25:31.470747377 +0200 -+++ openssh-9.6p1/canohost.h 2024-07-07 07:26:28.484916482 +0200 +diff -Nur openssh-9.8p1.orig/canohost.h openssh-9.8p1/canohost.h +--- openssh-9.8p1.orig/canohost.h 2024-09-30 11:38:28.369321060 +0200 ++++ openssh-9.8p1/canohost.h 2024-09-30 11:39:17.564461803 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -581,10 +576,10 @@ diff -Nur openssh-9.6p1.orig/canohost.h openssh-9.6p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac ---- openssh-9.6p1.orig/configure.ac 2024-07-07 07:25:31.559747641 +0200 -+++ openssh-9.6p1/configure.ac 2024-07-07 07:26:28.486916488 +0200 -@@ -4866,6 +4866,14 @@ +diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac +--- openssh-9.8p1.orig/configure.ac 2024-09-30 11:38:28.463321329 +0200 ++++ openssh-9.8p1/configure.ac 2024-09-30 11:39:17.565461806 +0200 +@@ -4909,6 +4909,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -599,7 +594,7 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4907,6 +4915,40 @@ +@@ -4950,6 +4958,40 @@ AC_SUBST([K5LIBS]) AC_SUBST([CHANNELLIBS]) @@ -640,9 +635,9 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c ---- openssh-9.6p1.orig/gss-genr.c 2024-07-07 07:25:31.626747839 +0200 -+++ openssh-9.6p1/gss-genr.c 2024-07-07 07:26:28.486916488 +0200 +diff -Nur openssh-9.8p1.orig/gss-genr.c openssh-9.8p1/gss-genr.c +--- openssh-9.8p1.orig/gss-genr.c 2024-09-30 11:38:28.535321535 +0200 ++++ openssh-9.8p1/gss-genr.c 2024-09-30 11:39:17.566461808 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -679,9 +674,9 @@ diff -Nur openssh-9.6p1.orig/gss-genr.c openssh-9.6p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c ---- openssh-9.6p1.orig/gss-serv.c 2024-07-07 07:25:31.489747433 +0200 -+++ openssh-9.6p1/gss-serv.c 2024-07-07 07:26:28.487916491 +0200 +diff -Nur openssh-9.8p1.orig/gss-serv.c openssh-9.8p1/gss-serv.c +--- openssh-9.8p1.orig/gss-serv.c 2024-09-30 11:38:28.389321117 +0200 ++++ openssh-9.8p1/gss-serv.c 2024-09-30 11:39:17.567461811 +0200 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -942,8 +937,8 @@ diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c + gssapi_client.store.envval == NULL) return; - ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -@@ -526,6 +612,18 @@ + ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); +@@ -521,6 +607,18 @@ if (ret) return; @@ -962,9 +957,9 @@ diff -Nur openssh-9.6p1.orig/gss-serv.c openssh-9.6p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-9.6p1.orig/gss-serv-gsi.c openssh-9.6p1/gss-serv-gsi.c ---- openssh-9.6p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/gss-serv-gsi.c 2024-07-07 07:26:28.488916494 +0200 +diff -Nur openssh-9.8p1.orig/gss-serv-gsi.c openssh-9.8p1/gss-serv-gsi.c +--- openssh-9.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/gss-serv-gsi.c 2024-09-30 11:39:17.567461811 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1294,9 +1289,9 @@ diff -Nur openssh-9.6p1.orig/gss-serv-gsi.c openssh-9.6p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-9.6p1.orig/gss-serv-krb5.c openssh-9.6p1/gss-serv-krb5.c ---- openssh-9.6p1.orig/gss-serv-krb5.c 2024-07-07 07:25:31.515747510 +0200 -+++ openssh-9.6p1/gss-serv-krb5.c 2024-07-07 07:26:28.488916494 +0200 +diff -Nur openssh-9.8p1.orig/gss-serv-krb5.c openssh-9.8p1/gss-serv-krb5.c +--- openssh-9.8p1.orig/gss-serv-krb5.c 2024-09-30 11:38:28.418321200 +0200 ++++ openssh-9.8p1/gss-serv-krb5.c 2024-09-30 11:39:17.568461814 +0200 @@ -379,6 +379,34 @@ return found_principal; } @@ -1350,9 +1345,9 @@ diff -Nur openssh-9.6p1.orig/gss-serv-krb5.c openssh-9.6p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c ---- openssh-9.6p1.orig/kexgsss.c 2024-07-07 07:25:31.497747457 +0200 -+++ openssh-9.6p1/kexgsss.c 2024-07-07 08:04:49.351732601 +0200 +diff -Nur openssh-9.8p1.orig/kexgsss.c openssh-9.8p1/kexgsss.c +--- openssh-9.8p1.orig/kexgsss.c 2024-09-30 11:38:28.399321146 +0200 ++++ openssh-9.8p1/kexgsss.c 2024-09-30 15:10:29.856045413 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1365,8 +1360,8 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c debug2_f("Acquiring credentials"); -- if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&kex->gss, oid)))) { +- if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) { + kex_gss_send_error(kex->gss, ssh); fatal("Unable to acquire credentials for the server"); + } @@ -1408,7 +1403,7 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c + OM_uint32 maj, min; + int r; + -+ errstr = PRIVSEP(ssh_gssapi_last_error(ctxt, &maj, &min)); ++ errstr = mm_ssh_gssapi_last_error(ctxt, &maj, &min); + if (errstr) { + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_ERROR)) != 0 || + (r = sshpkt_put_u32(ssh, maj)) != 0 || @@ -1425,20 +1420,20 @@ diff -Nur openssh-9.6p1.orig/kexgsss.c openssh-9.6p1/kexgsss.c +} + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in ---- openssh-9.6p1.orig/Makefile.in 2024-07-07 07:25:31.584747715 +0200 -+++ openssh-9.6p1/Makefile.in 2024-07-07 07:26:28.489916497 +0200 -@@ -130,6 +130,7 @@ +diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in +--- openssh-9.8p1.orig/Makefile.in 2024-09-30 11:38:28.491321409 +0200 ++++ openssh-9.8p1/Makefile.in 2024-09-30 11:43:22.688163055 +0200 +@@ -138,6 +138,7 @@ 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 kexgsss.o \ + monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ - srclimit.o sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c ---- openssh-9.6p1.orig/misc.c 2024-07-07 07:25:31.628747845 +0200 -+++ openssh-9.6p1/misc.c 2024-07-07 07:26:28.490916500 +0200 +diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c +--- openssh-9.8p1.orig/misc.c 2024-09-30 11:38:28.537321541 +0200 ++++ openssh-9.8p1/misc.c 2024-09-30 11:39:17.570461820 +0200 @@ -419,11 +419,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1498,10 +1493,10 @@ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h ---- openssh-9.6p1.orig/misc.h 2024-07-07 07:25:31.534747567 +0200 -+++ openssh-9.6p1/misc.h 2024-07-07 07:26:28.490916500 +0200 -@@ -103,6 +103,7 @@ +diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h +--- openssh-9.8p1.orig/misc.h 2024-09-30 11:38:28.435321249 +0200 ++++ openssh-9.8p1/misc.h 2024-09-30 11:39:17.570461820 +0200 +@@ -111,6 +111,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1509,10 +1504,10 @@ diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c ---- openssh-9.6p1.orig/monitor.c 2024-07-07 07:25:31.628747845 +0200 -+++ openssh-9.6p1/monitor.c 2024-07-07 07:26:28.491916503 +0200 -@@ -149,6 +149,9 @@ +diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c +--- openssh-9.8p1.orig/monitor.c 2024-09-30 11:38:28.537321541 +0200 ++++ openssh-9.8p1/monitor.c 2024-09-30 11:39:17.571461823 +0200 +@@ -147,6 +147,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1522,7 +1517,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -201,7 +204,7 @@ +@@ -200,7 +203,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1531,7 +1526,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -209,7 +212,7 @@ +@@ -208,7 +211,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1540,7 +1535,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -233,8 +236,11 @@ +@@ -232,8 +235,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1553,7 +1548,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -244,6 +250,8 @@ +@@ -243,6 +249,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1562,7 +1557,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -324,6 +332,8 @@ +@@ -323,6 +331,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1571,7 +1566,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -453,6 +463,8 @@ +@@ -457,6 +467,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1580,7 +1575,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -781,14 +793,17 @@ +@@ -811,14 +823,17 @@ debug3_f("entering"); @@ -1601,7 +1596,7 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2144,6 +2159,79 @@ +@@ -2159,6 +2174,79 @@ } int @@ -1681,9 +1676,9 @@ diff -Nur openssh-9.6p1.orig/monitor.c openssh-9.6p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-9.6p1.orig/monitor.h openssh-9.6p1/monitor.h ---- openssh-9.6p1.orig/monitor.h 2024-07-07 07:25:31.585747718 +0200 -+++ openssh-9.6p1/monitor.h 2024-07-07 07:26:28.492916506 +0200 +diff -Nur openssh-9.8p1.orig/monitor.h openssh-9.8p1/monitor.h +--- openssh-9.8p1.orig/monitor.h 2024-09-30 11:38:28.492321412 +0200 ++++ openssh-9.8p1/monitor.h 2024-09-30 11:39:17.571461823 +0200 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1695,10 +1690,10 @@ diff -Nur openssh-9.6p1.orig/monitor.h openssh-9.6p1/monitor.h }; struct ssh; -diff -Nur openssh-9.6p1.orig/monitor_wrap.c openssh-9.6p1/monitor_wrap.c ---- openssh-9.6p1.orig/monitor_wrap.c 2024-07-07 07:25:31.592747738 +0200 -+++ openssh-9.6p1/monitor_wrap.c 2024-07-07 07:26:28.492916506 +0200 -@@ -1083,6 +1083,94 @@ +diff -Nur openssh-9.8p1.orig/monitor_wrap.c openssh-9.8p1/monitor_wrap.c +--- openssh-9.8p1.orig/monitor_wrap.c 2024-09-30 11:38:28.499321432 +0200 ++++ openssh-9.8p1/monitor_wrap.c 2024-09-30 11:39:17.572461826 +0200 +@@ -1139,6 +1139,94 @@ return (authenticated); } @@ -1793,10 +1788,10 @@ diff -Nur openssh-9.6p1.orig/monitor_wrap.c openssh-9.6p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-9.6p1.orig/monitor_wrap.h openssh-9.6p1/monitor_wrap.h ---- openssh-9.6p1.orig/monitor_wrap.h 2024-07-07 07:25:31.592747738 +0200 -+++ openssh-9.6p1/monitor_wrap.h 2024-07-07 07:26:28.493916509 +0200 -@@ -73,6 +73,10 @@ +diff -Nur openssh-9.8p1.orig/monitor_wrap.h openssh-9.8p1/monitor_wrap.h +--- openssh-9.8p1.orig/monitor_wrap.h 2024-09-30 11:38:28.499321432 +0200 ++++ openssh-9.8p1/monitor_wrap.h 2024-09-30 11:39:17.572461826 +0200 +@@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1807,10 +1802,10 @@ diff -Nur openssh-9.6p1.orig/monitor_wrap.h openssh-9.6p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c ---- openssh-9.6p1.orig/readconf.c 2024-07-07 07:25:31.629747848 +0200 -+++ openssh-9.6p1/readconf.c 2024-07-07 07:26:28.493916509 +0200 -@@ -2723,11 +2723,11 @@ +diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c +--- openssh-9.8p1.orig/readconf.c 2024-09-30 11:38:28.539321546 +0200 ++++ openssh-9.8p1/readconf.c 2024-09-30 11:39:17.573461828 +0200 +@@ -2760,11 +2760,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1825,9 +1820,9 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h ---- openssh-9.6p1.orig/readconf.h 2024-07-07 07:25:31.477747397 +0200 -+++ openssh-9.6p1/readconf.h 2024-07-07 07:26:28.494916512 +0200 +diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h +--- openssh-9.8p1.orig/readconf.h 2024-09-30 11:38:28.377321083 +0200 ++++ openssh-9.8p1/readconf.h 2024-09-30 11:39:17.574461831 +0200 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1837,18 +1832,18 @@ diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c ---- openssh-9.6p1.orig/servconf.c 2024-07-07 07:25:31.630747851 +0200 -+++ openssh-9.6p1/servconf.c 2024-07-07 07:26:28.495916515 +0200 -@@ -92,6 +92,7 @@ - +diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c +--- openssh-9.8p1.orig/servconf.c 2024-09-30 11:38:28.539321546 +0200 ++++ openssh-9.8p1/servconf.c 2024-09-30 14:09:25.379481790 +0200 +@@ -95,6 +95,7 @@ /* Portable-specific options */ options->use_pam = -1; + options->pam_service_name = NULL; + options->permit_pam_user_change = -1; /* Standard Options */ options->num_ports = 0; -@@ -138,9 +139,11 @@ +@@ -141,9 +142,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1860,16 +1855,16 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -294,6 +297,8 @@ - /* Portable-specific options */ - if (options->use_pam == -1) +@@ -312,6 +315,8 @@ options->use_pam = 0; + if (options->pam_service_name == NULL) + options->pam_service_name = xstrdup(SSHD_PAM_SERVICE); + if (options->permit_pam_user_change == -1) + options->permit_pam_user_change = 0; /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -375,13 +380,17 @@ +@@ -393,13 +398,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1889,18 +1884,18 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -528,7 +537,7 @@ +@@ -567,7 +576,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ -- sUsePAM, -+ sUsePAM, sPermitPAMUserChange, +- sUsePAM, sPAMServiceName, ++ sUsePAM, sPAMServiceName, sPermitPAMUserChange, /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -547,6 +556,9 @@ - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, +@@ -587,6 +596,9 @@ sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, + sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, @@ -1908,18 +1903,19 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -580,8 +592,10 @@ - /* Portable-specific options */ +@@ -622,9 +634,11 @@ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, + { "pamservicename", sPAMServiceName, SSHCFG_ALL }, + { "permitpamuserchange", sPermitPAMUserChange, SSHCFG_GLOBAL }, #else { "usepam", sUnsupported, SSHCFG_GLOBAL }, + { "pamservicename", sUnsupported, SSHCFG_ALL }, + { "permitpamuserchange", sUnsupported, SSHCFG_GLOBAL }, #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -634,8 +648,15 @@ +@@ -677,8 +691,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1935,7 +1931,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -643,8 +664,11 @@ +@@ -686,8 +707,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1947,7 +1943,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -716,6 +740,8 @@ +@@ -761,6 +785,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1956,9 +1952,9 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1418,6 +1444,10 @@ - intptr = &options->use_pam; - goto parse_flag; +@@ -1387,6 +1413,10 @@ + *charptr = xstrdup(arg); + break; + case sPermitPAMUserChange: + intptr = &options->permit_pam_user_change; @@ -1967,7 +1963,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1669,6 +1699,10 @@ +@@ -1638,6 +1668,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1978,7 +1974,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1677,6 +1711,10 @@ +@@ -1646,6 +1680,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1989,7 +1985,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1697,6 +1735,12 @@ +@@ -1666,6 +1704,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -2002,7 +1998,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2806,6 +2850,7 @@ +@@ -2925,6 +2969,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2010,10 +2006,10 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h ---- openssh-9.6p1.orig/servconf.h 2024-07-07 07:25:31.526747543 +0200 -+++ openssh-9.6p1/servconf.h 2024-07-07 07:26:28.495916515 +0200 -@@ -144,9 +144,12 @@ +diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h +--- openssh-9.8p1.orig/servconf.h 2024-09-30 11:38:28.431321237 +0200 ++++ openssh-9.8p1/servconf.h 2024-09-30 11:44:57.129433237 +0200 +@@ -154,9 +154,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2026,18 +2022,18 @@ diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -207,6 +210,7 @@ - char *adm_forced_command; +@@ -220,6 +223,7 @@ int use_pam; /* Enable auth via PAM */ + char *pam_service_name; + int permit_pam_user_change; /* Allow PAM to change user name */ int permit_tun; -diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 ---- openssh-9.6p1.orig/ssh.1 2024-07-07 07:25:31.608747786 +0200 -+++ openssh-9.6p1/ssh.1 2024-07-07 07:26:28.496916518 +0200 -@@ -1528,6 +1528,18 @@ +diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 +--- openssh-9.8p1.orig/ssh.1 2024-09-30 11:38:28.517321483 +0200 ++++ openssh-9.8p1/ssh.1 2024-09-30 11:39:17.577461840 +0200 +@@ -1521,6 +1521,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2056,9 +2052,9 @@ diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c ---- openssh-9.6p1.orig/ssh.c 2024-07-07 07:25:31.602747768 +0200 -+++ openssh-9.6p1/ssh.c 2024-07-07 07:26:28.496916518 +0200 +diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c +--- openssh-9.8p1.orig/ssh.c 2024-09-30 11:38:28.511321466 +0200 ++++ openssh-9.8p1/ssh.c 2024-09-30 11:39:17.578461843 +0200 @@ -573,6 +573,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2112,9 +2108,9 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-9.6p1.orig/ssh_config openssh-9.6p1/ssh_config ---- openssh-9.6p1.orig/ssh_config 2024-07-07 07:25:31.479747403 +0200 -+++ openssh-9.6p1/ssh_config 2024-07-07 07:26:28.496916518 +0200 +diff -Nur openssh-9.8p1.orig/ssh_config openssh-9.8p1/ssh_config +--- openssh-9.8p1.orig/ssh_config 2024-09-30 11:38:28.380321091 +0200 ++++ openssh-9.8p1/ssh_config 2024-09-30 11:39:17.578461843 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2128,9 +2124,9 @@ diff -Nur openssh-9.6p1.orig/ssh_config openssh-9.6p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP no -diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 ---- openssh-9.6p1.orig/ssh_config.5 2024-07-07 07:25:31.551747617 +0200 -+++ openssh-9.6p1/ssh_config.5 2024-07-07 07:26:28.497916521 +0200 +diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 +--- openssh-9.8p1.orig/ssh_config.5 2024-09-30 11:38:28.454321303 +0200 ++++ openssh-9.8p1/ssh_config.5 2024-09-30 11:39:17.579461846 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2144,7 +2140,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -921,7 +927,7 @@ +@@ -931,7 +937,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2153,7 +2149,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -929,12 +935,12 @@ +@@ -939,12 +945,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2168,7 +2164,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1582,7 +1588,7 @@ +@@ -1595,7 +1601,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2177,10 +2173,10 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c ---- openssh-9.6p1.orig/sshconnect2.c 2024-07-07 07:25:31.620747821 +0200 -+++ openssh-9.6p1/sshconnect2.c 2024-07-07 07:26:28.498916524 +0200 -@@ -863,6 +863,11 @@ +diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c +--- openssh-9.8p1.orig/sshconnect2.c 2024-09-30 11:38:28.530321521 +0200 ++++ openssh-9.8p1/sshconnect2.c 2024-09-30 11:39:17.580461848 +0200 +@@ -854,6 +854,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2192,7 +2188,7 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -971,7 +976,8 @@ +@@ -962,7 +967,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2202,7 +2198,7 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1138,6 +1144,20 @@ +@@ -1129,6 +1135,20 @@ return r; } @@ -2223,7 +2219,7 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1160,6 +1180,12 @@ +@@ -1151,6 +1171,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2236,7 +2232,7 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1173,7 +1199,9 @@ +@@ -1164,7 +1190,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2247,10 +2243,10 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 ---- openssh-9.6p1.orig/sshd.8 2024-07-07 07:25:31.494747448 +0200 -+++ openssh-9.6p1/sshd.8 2024-07-07 07:26:28.498916524 +0200 -@@ -839,6 +839,29 @@ +diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 +--- openssh-9.8p1.orig/sshd.8 2024-09-30 11:38:28.395321134 +0200 ++++ openssh-9.8p1/sshd.8 2024-09-30 11:39:17.580461848 +0200 +@@ -836,6 +836,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2280,21 +2276,9 @@ diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c ---- openssh-9.6p1.orig/sshd.c 2024-07-07 07:25:31.631747854 +0200 -+++ openssh-9.6p1/sshd.c 2024-07-07 07:26:28.498916524 +0200 -@@ -2431,7 +2431,7 @@ - #endif - - #ifdef GSSAPI -- if (options.gss_authentication) { -+ if (options.gss_authentication && options.gss_deleg_creds) { - temporarily_use_uid(authctxt->pw); - authctxt->krb5_set_env = ssh_gssapi_storecreds(); - restore_uid(); -diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config ---- openssh-9.6p1.orig/sshd_config 2024-07-07 07:25:31.517747516 +0200 -+++ openssh-9.6p1/sshd_config 2024-07-07 07:26:28.499916527 +0200 +diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config +--- openssh-9.8p1.orig/sshd_config 2024-09-30 11:38:28.419321203 +0200 ++++ openssh-9.8p1/sshd_config 2024-09-30 11:39:17.582461854 +0200 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2320,10 +2304,10 @@ diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 ---- openssh-9.6p1.orig/sshd_config.5 2024-07-07 07:25:31.552747620 +0200 -+++ openssh-9.6p1/sshd_config.5 2024-07-07 07:26:28.499916527 +0200 -@@ -716,15 +716,34 @@ +diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 +--- openssh-9.8p1.orig/sshd_config.5 2024-09-30 11:38:28.455321306 +0200 ++++ openssh-9.8p1/sshd_config.5 2024-09-30 11:39:17.582461854 +0200 +@@ -724,15 +724,34 @@ to allow the client to select the address to which the forwarding is bound. The default is .Cm no . @@ -2359,7 +2343,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 .It Cm GSSAPIEnablek5users Specifies whether to look at .k5users file for GSSAPI authentication access control. Further details are described in -@@ -735,7 +754,7 @@ +@@ -743,7 +762,7 @@ Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. The default is @@ -2368,7 +2352,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -1900,6 +1919,12 @@ +@@ -2017,6 +2036,12 @@ as a non-root user. The default is .Cm no . @@ -2381,9 +2365,9 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-9.6p1.orig/sshd_config_redhat openssh-9.6p1/sshd_config_redhat ---- openssh-9.6p1.orig/sshd_config_redhat 2024-07-07 07:25:31.464747359 +0200 -+++ openssh-9.6p1/sshd_config_redhat 2024-07-07 07:26:28.499916527 +0200 +diff -Nur openssh-9.8p1.orig/sshd_config_redhat openssh-9.8p1/sshd_config_redhat +--- openssh-9.8p1.orig/sshd_config_redhat 2024-09-30 11:38:28.362321040 +0200 ++++ openssh-9.8p1/sshd_config_redhat 2024-09-30 11:39:17.583461857 +0200 @@ -2,9 +2,6 @@ ChallengeResponseAuthentication no @@ -2394,9 +2378,21 @@ diff -Nur openssh-9.6p1.orig/sshd_config_redhat openssh-9.6p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h ---- openssh-9.6p1.orig/ssh-gss.h 2024-07-07 07:25:31.498747460 +0200 -+++ openssh-9.6p1/ssh-gss.h 2024-07-07 07:26:28.500916530 +0200 +diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c +--- openssh-9.8p1.orig/sshd-session.c 2024-09-30 11:38:28.541321552 +0200 ++++ openssh-9.8p1/sshd-session.c 2024-09-30 11:48:44.155082722 +0200 +@@ -1437,7 +1437,7 @@ + #endif + + #ifdef GSSAPI +- if (options.gss_authentication) { ++ if (options.gss_authentication && options.gss_deleg_creds) { + temporarily_use_uid(authctxt->pw); + authctxt->krb5_set_env = ssh_gssapi_storecreds(); + restore_uid(); +diff -Nur openssh-9.8p1.orig/ssh-gss.h openssh-9.8p1/ssh-gss.h +--- openssh-9.8p1.orig/ssh-gss.h 2024-09-30 11:38:28.400321149 +0200 ++++ openssh-9.8p1/ssh-gss.h 2024-09-30 11:39:17.583461857 +0200 @@ -99,12 +99,14 @@ } ssh_gssapi_ccache; @@ -2422,7 +2418,7 @@ diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -173,6 +175,9 @@ +@@ -172,6 +174,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2432,12 +2428,12 @@ diff -Nur openssh-9.6p1.orig/ssh-gss.h openssh-9.6p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-9.6p1.orig/version.h openssh-9.6p1/version.h ---- openssh-9.6p1.orig/version.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/version.h 2024-07-07 07:26:28.500916530 +0200 +diff -Nur openssh-9.8p1.orig/version.h openssh-9.8p1/version.h +--- openssh-9.8p1.orig/version.h 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/version.h 2024-09-30 11:39:17.584461860 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_9.6" + #define SSH_VERSION "OpenSSH_9.8" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-9.6p1-hpn-18.3.1.patch b/openssh-9.8p1-hpn-18.5.1.patch similarity index 87% rename from openssh-9.6p1-hpn-18.3.1.patch rename to openssh-9.8p1-hpn-18.5.1.patch index 68159b7..0952a56 100644 --- a/openssh-9.6p1-hpn-18.3.1.patch +++ b/openssh-9.8p1-hpn-18.5.1.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c ---- openssh-9.6p1.orig/auth2.c 2024-07-10 13:32:39.592111791 +0200 -+++ openssh-9.6p1/auth2.c 2024-07-10 13:38:36.540172663 +0200 +diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c +--- openssh-9.8p1.orig/auth2.c 2024-09-30 16:02:22.611024465 +0200 ++++ openssh-9.8p1/auth2.c 2024-10-01 08:51:48.548148424 +0200 @@ -52,6 +52,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -41,10 +41,10 @@ diff -Nur openssh-9.6p1.orig/auth2.c openssh-9.6p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c ---- openssh-9.6p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/binn.c 2024-07-10 13:34:02.707358556 +0200 -@@ -0,0 +1,3496 @@ +diff -Nur openssh-9.8p1.orig/binn.c openssh-9.8p1/binn.c +--- openssh-9.8p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/binn.c 2024-09-30 16:03:39.142245236 +0200 +@@ -0,0 +1,3541 @@ +#include +#include +#include @@ -55,11 +55,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +#define UNUSED(x) (void)(x) +#define roundval(dbl) dbl >= 0.0 ? (int)(dbl + 0.5) : ((dbl - (double)(int)dbl) <= -0.5 ? (int)dbl : (int)(dbl - 0.5)) + ++// magic number: 0x1F 0xb1 0x22 0x1F => 0x1FB1221F or 0x1F22B11F ++// because the BINN_STORAGE_NOBYTES (binary 000) may not have so many sub-types (BINN_STORAGE_HAS_MORE = 0x10) +#define BINN_MAGIC 0x1F22B11F + -+#define MAX_BINN_HEADER 9 -+#define MIN_BINN_SIZE 3 -+#define CHUNK_SIZE 256 ++#define MAX_BINN_HEADER 9 // [1:type][4:size][4:count] ++#define MIN_BINN_SIZE 3 // [1:type][1:size][1:count] ++#define CHUNK_SIZE 256 // 1024 + +#define BINN_STRUCT 1 +#define BINN_BUFFER 2 @@ -116,14 +118,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + unsigned char *dest = (unsigned char *) pdest; + dest[0] = source[1]; + dest[1] = source[0]; -+#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#else // if BYTE_ORDER == BIG_ENDIAN +#ifdef BINN_ONLY_ALIGNED_ACCESS -+ if ((uintptr_t)psource % 2 == 0){ /* address aligned to 16 bit */ ++ if ((uintptr_t)psource % 2 == 0){ // address aligned to 16 bit + *pdest = *psource; + } else { + unsigned char *source = (unsigned char *) psource; + unsigned char *dest = (unsigned char *) pdest; -+ dest[0] = source[0]; /* indexes are the same */ ++ dest[0] = source[0]; // indexes are the same + dest[1] = source[1]; + } +#else @@ -140,14 +142,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + dest[1] = source[2]; + dest[2] = source[1]; + dest[3] = source[0]; -+#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#else // if BYTE_ORDER == BIG_ENDIAN +#ifdef BINN_ONLY_ALIGNED_ACCESS -+ if ((uintptr_t)psource % 4 == 0){ /* address aligned to 32 bit */ ++ if ((uintptr_t)psource % 4 == 0){ // address aligned to 32 bit + *pdest = *psource; + } else { + unsigned char *source = (unsigned char *) psource; + unsigned char *dest = (unsigned char *) pdest; -+ dest[0] = source[0]; /* indexes are the same */ ++ dest[0] = source[0]; // indexes are the same + dest[1] = source[1]; + dest[2] = source[2]; + dest[3] = source[3]; @@ -166,16 +168,16 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + for (i=0; i < 8; i++) { + dest[i] = source[7-i]; + } -+#else /* if BYTE_ORDER == BIG_ENDIAN */ ++#else // if BYTE_ORDER == BIG_ENDIAN +#ifdef BINN_ONLY_ALIGNED_ACCESS -+ if ((uintptr_t)psource % 8 == 0){ /* address aligned to 64 bit */ ++ if ((uintptr_t)psource % 8 == 0){ // address aligned to 64 bit + *pdest = *psource; + } else { + unsigned char *source = (unsigned char *) psource; + unsigned char *dest = (unsigned char *) pdest; + int i; + for (i=0; i < 8; i++) { -+ dest[i] = source[i]; /* indexes are the same */ ++ dest[i] = source[i]; // indexes are the same + } + } +#else @@ -191,7 +193,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +#define strnicmp strncasecmp +#endif + -+BINN_PRIVATE BOOL IsValidBinnHeader(void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize); ++BINN_PRIVATE BOOL IsValidBinnHeader(const void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize); + +/***************************************************************************/ + @@ -228,7 +230,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BINN_PRIVATE void * binn_memdup(void *src, int size) { ++BINN_PRIVATE void * binn_memdup(const void *src, int size) { + void *dest; + + if (src == NULL || size <= 0) return NULL; @@ -252,7 +254,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +int APIENTRY binn_create_type(int storage_type, int data_type_index) { + if (data_type_index < 0) return -1; -+ if ((storage_type < BINN_STORAGE_MIN) || (storage_type > BINN_STORAGE_MAX)) return -1; ++ if (storage_type < BINN_STORAGE_MIN || storage_type > BINN_STORAGE_MAX) return -1; + if (data_type_index < 16) + return storage_type | data_type_index; + else if (data_type_index < 4096) { @@ -283,8 +285,8 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + extra_type = long_type & BINN_TYPE_MASK16; + extra_type >>= 4; + } else if (long_type & BINN_STORAGE_VIRTUAL) { -+ /* storage_type = BINN_STORAGE_VIRTUAL; */ -+ /* extra_type = xxx; */ ++ //storage_type = BINN_STORAGE_VIRTUAL; ++ //extra_type = xxx; + long_type &= 0xffff; + goto again; + } else { @@ -315,7 +317,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + goto loc_exit; + } + -+ if ((item == NULL) || (size < 0)) goto loc_exit; ++ if (item == NULL || size < 0) goto loc_exit; + if (size < MIN_BINN_SIZE) { + if (pointer) goto loc_exit; + else size = 0; @@ -325,24 +327,23 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + if (pointer) { + item->pre_allocated = TRUE; -+ item->pbuf = pointer; -+ item->alloc_size = size; + } else { + item->pre_allocated = FALSE; + if (size == 0) size = CHUNK_SIZE; + pointer = binn_malloc(size); + if (pointer == 0) return INVALID_BINN; -+ item->pbuf = pointer; -+ item->alloc_size = size; + } + ++ item->pbuf = pointer; ++ item->alloc_size = size; ++ + item->header = BINN_MAGIC; -+ /* item->allocated = FALSE; -- already zeroed */ ++ //item->allocated = FALSE; -- already zeroed + item->writable = TRUE; -+ item->used_size = MAX_BINN_HEADER; /* save space for the header */ ++ item->used_size = MAX_BINN_HEADER; // save space for the header + item->type = type; -+ /* item->count = 0; -- already zeroed */ -+ item->dirty = TRUE; /* the header is not written to the buffer */ ++ //item->count = 0; -- already zeroed ++ item->dirty = TRUE; // the header is not written to the buffer + + retval = TRUE; + @@ -412,7 +413,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+binn * APIENTRY binn_copy(void *old) { ++binn * APIENTRY binn_copy(const void *old) { + int type, count, size, header_size; + unsigned char *old_ptr = binn_ptr(old); + binn *item; @@ -434,23 +435,39 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+BOOL APIENTRY binn_load(void *data, binn *value) { ++// deprecated: unsecure. the size can be corrupted accidentally or intentionally ++BOOL APIENTRY binn_load(const void *data, binn *value) { + -+ if ((data == NULL) || (value == NULL)) return FALSE; ++ if (data == NULL || value == NULL) return FALSE; + memset(value, 0, sizeof(binn)); + value->header = BINN_MAGIC; -+ /* value->allocated = FALSE; -- already zeroed */ -+ /* value->writable = FALSE; */ ++ //value->allocated = FALSE; -- already zeroed ++ //value->writable = FALSE; + + if (binn_is_valid(data, &value->type, &value->count, &value->size) == FALSE) return FALSE; -+ value->ptr = data; ++ value->ptr = (void*) data; ++ return TRUE; ++ ++} ++ ++BOOL APIENTRY binn_load_ex(const void *data, int size, binn *value) { ++ ++ if (data == NULL || value == NULL || size <= 0) return FALSE; ++ memset(value, 0, sizeof(binn)); ++ value->header = BINN_MAGIC; ++ //value->allocated = FALSE; -- already zeroed ++ //value->writable = FALSE; ++ ++ if (binn_is_valid_ex(data, &value->type, &value->count, &size) == FALSE) return FALSE; ++ value->ptr = (void*) data; ++ value->size = size; + return TRUE; + +} + +/*************************************************************************************/ + -+binn * APIENTRY binn_open(void *data) { ++binn * APIENTRY binn_open(const void *data) { + binn *item; + + item = (binn*) binn_malloc(sizeof(binn)); @@ -465,9 +482,24 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +} + ++binn * APIENTRY binn_open_ex(const void *data, int size) { ++ binn *item; ++ ++ item = (binn*) binn_malloc(sizeof(binn)); ++ ++ if (binn_load_ex(data, size, item) == FALSE) { ++ free_fn(item); ++ return NULL; ++ } ++ ++ item->allocated = TRUE; ++ return item; ++ ++} ++ +/***************************************************************************/ + -+BINN_PRIVATE int binn_get_ptr_type(void *ptr) { ++BINN_PRIVATE int binn_get_ptr_type(const void *ptr) { + + if (ptr == NULL) return 0; + @@ -482,7 +514,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BOOL APIENTRY binn_is_struct(void *ptr) { ++BOOL APIENTRY binn_is_struct(const void *ptr) { + + if (ptr == NULL) return FALSE; + @@ -501,8 +533,8 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + calc_size = alloc_size; + while (calc_size < needed_size) { -+ calc_size <<= 1; /* same as *= 2 */ -+ /* calc_size += CHUNK_SIZE; -- this is slower than the above line, because there are more reallocations */ ++ calc_size <<= 1; // same as *= 2 ++ //calc_size += CHUNK_SIZE; -- this is slower than the above line, because there are more reallocations + } + return calc_size; + @@ -566,7 +598,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (storage_type) { + case BINN_STORAGE_NOBYTES: -+ /* p += 0; */ ++ //p += 0; + break; + case BINN_STORAGE_BYTE: + p ++; @@ -594,7 +626,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + p += DataSize; + if (storage_type == BINN_STORAGE_STRING) { -+ p++; /* null terminator. */ ++ p++; // null terminator. + } + break; + case BINN_STORAGE_CONTAINER: @@ -605,15 +637,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + copy_be32((u32*)&DataSize, (u32*)p); + DataSize &= 0x7FFFFFFF; + } -+ DataSize--; /* remove the type byte already added before */ ++ DataSize--; // remove the type byte already added before + p += DataSize; + break; + default: + return 0; + } + -+ if (p > plimit) return 0; -+ + return p; + +} @@ -639,6 +669,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + int id, extra_bytes; + + p = *pp; ++ if (p > plimit) return 0; + + c = *p++; + @@ -693,15 +724,15 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + plimit = p + size - 1; + p += header_size; + -+ /* search for the ID in all the arguments. */ ++ // search for the ID in all the arguments. + for (i = 0; i < numitems; i++) { + int32 = read_map_id(&p, plimit); + if (p > plimit) break; -+ /* Compare if the IDs are equal. */ ++ // Compare if the IDs are equal. + if (int32 == id) return p; -+ /* xxx */ ++ // xxx + p = AdvanceDataPos(p, plimit); -+ if ((p == 0) || (p < base)) break; ++ if (p == 0 || p < base) break; + } + + return NULL; @@ -720,27 +751,27 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + keylen = strlen(key); + -+ /* search for the key in all the arguments. */ ++ // search for the key in all the arguments. + for (i = 0; i < numitems; i++) { ++ if (p > plimit) break; + len = *((unsigned char *)p); + p++; -+ if (p > plimit) break; -+ /* Compare if the strings are equal. */ ++ if (p + len > plimit) break; ++ // Compare if the strings are equal. + if (len > 0) { -+ if (strnicmp((char*)p, key, len) == 0) { /* note that there is no null terminator here */ ++ if (strnicmp((char*)p, key, len) == 0) { // note that there is no null terminator here + if (keylen == len) { + p += len; + return p; + } + } + p += len; -+ if (p > plimit) break; -+ } else if (len == keylen) { /* in the case of empty string: "" */ ++ } else if (len == keylen) { // in the case of empty string: "" + return p; + } -+ /* xxx */ ++ // xxx + p = AdvanceDataPos(p, plimit); -+ if ((p == 0) || (p < base)) break; ++ if (p == 0 || p < base) break; + } + + return NULL; @@ -755,9 +786,9 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +BINN_PRIVATE BOOL binn_list_add_raw(binn *item, int type, void *pvalue, int size) { + -+ if ((item == NULL) || (item->type != BINN_LIST) || (item->writable == FALSE)) return FALSE; ++ if (item == NULL || item->type != BINN_LIST || item->writable == FALSE) return FALSE; + -+ /* if (CheckAllocation(item, 4) == FALSE) return FALSE; // 4 bytes used for data_store and data_format. */ ++ //if (CheckAllocation(item, 4) == FALSE) return FALSE; // 4 bytes used for data_store and data_format. + + if (AddValue(item, type, pvalue, size) == FALSE) return FALSE; + @@ -773,26 +804,26 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + unsigned char *p, len; + int int32; + -+ if ((item == NULL) || (item->type != BINN_OBJECT) || (item->writable == FALSE)) return FALSE; ++ if (item == NULL || item->type != BINN_OBJECT || item->writable == FALSE) return FALSE; + + if (key == NULL) return FALSE; + int32 = strlen(key); + if (int32 > 255) return FALSE; + -+ /* is the key already in it? */ ++ // is the key already in it? + p = SearchForKey(item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, key); + if (p) return FALSE; + -+ /* start adding it */ ++ // start adding it + -+ if (CheckAllocation(item, 1 + int32) == FALSE) return FALSE; /* bytes used for the key size and the key itself. */ ++ if (CheckAllocation(item, 1 + int32) == FALSE) return FALSE; // bytes used for the key size and the key itself. + + p = ((unsigned char *) item->pbuf) + item->used_size; + len = int32; + *p = len; + p++; + memcpy(p, key, int32); -+ int32++; /* now contains the strlen + 1 byte for the len */ ++ int32++; // now contains the strlen + 1 byte for the len + item->used_size += int32; + + if (AddValue(item, type, pvalue, size) == FALSE) { @@ -812,15 +843,15 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + unsigned char *base, *p, sign; + int id_size; + -+ if ((item == NULL) || (item->type != BINN_MAP) || (item->writable == FALSE)) return FALSE; ++ if (item == NULL || item->type != BINN_MAP || item->writable == FALSE) return FALSE; + -+ /* is the ID already in it? */ ++ // is the ID already in it? + p = SearchForID(item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, id); + if (p) return FALSE; + -+ /* start adding it */ ++ // start adding it + -+ if (CheckAllocation(item, 5) == FALSE) return FALSE; /* max 5 bytes used for the id. */ ++ if (CheckAllocation(item, 5) == FALSE) return FALSE; // max 5 bytes used for the id. + + p = base = ((unsigned char *) item->pbuf) + item->used_size; + @@ -906,7 +937,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + goto loc_positive; + } + -+/* loc_negative: */ ++//loc_negative: + + if (vint >= INT8_MIN) { + type2 = BINN_INT8; @@ -935,7 +966,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + pvalue = (char *) psource; + -+ if ((type2) && (type2 != type)) { ++ if (type2 && type2 != type) { + *ptype = type2; + storage_type2 = binn_get_write_storage(type2); + *pstorage_type = storage_type2; @@ -966,14 +997,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + break; + case BINN_STORAGE_BLOB: + case BINN_STORAGE_STRING: -+ if (size == 0) break; /* the 2 above are allowed to have 0 length */ ++ if (size == 0) break; // the 2 above are allowed to have 0 length + /* fall through */ + default: + return FALSE; + } + } + -+ if ((type_family(type) == BINN_FAMILY_INT) && (item->disable_int_compression == FALSE)) ++ if (type_family(type) == BINN_FAMILY_INT && item->disable_int_compression == FALSE) + pvalue = compress_int(&storage_type, &type, pvalue); + + switch (storage_type) { @@ -999,13 +1030,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + break; + case BINN_STORAGE_BLOB: + if (size < 0) return FALSE; -+ /* if (size == 0) ... */ -+ ArgSize = size + 4; /* at least this size */ ++ //if (size == 0) ... ++ ArgSize = size + 4; // at least this size + break; + case BINN_STORAGE_STRING: + if (size < 0) return FALSE; + if (size == 0) size = strlen2( (char *) pvalue); -+ ArgSize = size + 5; /* at least this size */ ++ ArgSize = size + 5; // at least this size + break; + case BINN_STORAGE_CONTAINER: + if (size <= 0) return FALSE; @@ -1015,13 +1046,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return FALSE; + } + -+ ArgSize += 2; /* at least 2 bytes used for data_type. */ ++ ArgSize += 2; // at least 2 bytes used for data_type. + if (CheckAllocation(item, ArgSize) == FALSE) return FALSE; + -+ /* Gets the pointer to the next place in buffer */ ++ // Gets the pointer to the next place in buffer + p = ((unsigned char *) item->pbuf) + item->used_size; + -+ /* If the data is not a container, store the data type */ ++ // If the data is not a container, store the data type + if (storage_type != BINN_STORAGE_CONTAINER) { + if (type > 255) { + u16 type16 = type; @@ -1037,7 +1068,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (storage_type) { + case BINN_STORAGE_NOBYTES: -+ /* Nothing to do. */ ++ // Nothing to do. + break; + case BINN_STORAGE_BYTE: + *((char *) p) = *((char *) pvalue); @@ -1071,7 +1102,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + if (storage_type == BINN_STORAGE_STRING) { + p += size; + *((char *) p) = (char) 0; -+ size++; /* null terminator */ ++ size++; // null terminator + } + item->used_size += size; + break; @@ -1097,9 +1128,9 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +#ifndef BINN_DISABLE_SMALL_HEADER + + p = ((unsigned char *) item->pbuf) + MAX_BINN_HEADER; -+ size = item->used_size - MAX_BINN_HEADER + 3; /* at least 3 bytes for the header */ ++ size = item->used_size - MAX_BINN_HEADER + 3; // at least 3 bytes for the header + -+ /* write the count */ ++ // write the count + if (item->count > 127) { + p -= 4; + size += 3; @@ -1110,7 +1141,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + *p = (unsigned char) item->count; + } + -+ /* write the size */ ++ // write the size + if (size > 127) { + p -= 4; + size += 3; @@ -1121,11 +1152,11 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + *p = (unsigned char) size; + } + -+ /* write the type. */ ++ // write the type. + p--; + *p = (unsigned char) item->type; + -+ /* set the values */ ++ // set the values + item->ptr = p; + item->size = size; + @@ -1135,14 +1166,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + p = (unsigned char *) item->pbuf; + -+ /* write the type. */ ++ // write the type. + byte = item->type; + *p = byte; p++; -+ /* write the size */ ++ // write the size + int32 = item->used_size | 0x80000000; + copy_be32((u32*)p, (u32*)&int32); + p+=4; -+ /* write the count */ ++ // write the count + int32 = item->count | 0x80000000; + copy_be32((u32*)p, (u32*)&int32); + @@ -1163,7 +1194,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + if (item == NULL) return; + -+ if ((item->writable) && (item->pre_allocated == FALSE)) { ++ if (item->writable && item->pre_allocated == FALSE) { + free_fn(item->pbuf); + } + @@ -1179,7 +1210,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +} + +/***************************************************************************/ -+/* free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later */ ++// free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later +void * APIENTRY binn_release(binn *item) { + void *data; + @@ -1205,7 +1236,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BINN_PRIVATE BOOL IsValidBinnHeader(void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize) { ++BINN_PRIVATE BOOL IsValidBinnHeader(const void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize) { + unsigned char byte, *p, *plimit=0; + int int32, type, size, count; + @@ -1214,10 +1245,11 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + p = (unsigned char *) pbuf; + + if (psize && *psize > 0) { ++ if (*psize < MIN_BINN_SIZE) return FALSE; + plimit = p + *psize - 1; + } + -+ /* get the type */ ++ // get the type + byte = *p; p++; + if ((byte & BINN_STORAGE_MASK) != BINN_STORAGE_CONTAINER) return FALSE; + if (byte & BINN_STORAGE_HAS_MORE) return FALSE; @@ -1232,7 +1264,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return FALSE; + } + -+ /* get the size */ ++ // get the size + if (plimit && p > plimit) return FALSE; + int32 = *((unsigned char*)p); + if (int32 & 0x80) { @@ -1245,7 +1277,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + size = int32; + -+ /* get the count */ ++ // get the count + if (plimit && p > plimit) return FALSE; + int32 = *((unsigned char*)p); + if (int32 & 0x80) { @@ -1258,31 +1290,19 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + count = int32; + -+#if 0 -+ /* get the size */ -+ copy_be32((u32*)&size, (u32*)p); -+ size &= 0x7FFFFFFF; -+ p+=4; ++ if (size < MIN_BINN_SIZE || count < 0) return FALSE; + -+ /* get the count */ -+ copy_be32((u32*)&count, (u32*)p); -+ count &= 0x7FFFFFFF; -+ p+=4; -+#endif -+ -+ if ((size < MIN_BINN_SIZE) || (count < 0)) return FALSE; -+ -+ /* return the values */ ++ // return the values + if (ptype) *ptype = type; + if (pcount) *pcount = count; -+ if (psize && *psize==0) *psize = size; ++ if (psize) *psize = size; + if (pheadersize) *pheadersize = (int) (p - (unsigned char*)pbuf); + return TRUE; +} + +/***************************************************************************/ + -+BINN_PRIVATE int binn_buf_type(void *pbuf) { ++BINN_PRIVATE int binn_buf_type(const void *pbuf) { + int type; + + if (!IsValidBinnHeader(pbuf, &type, NULL, NULL, NULL)) return INVALID_BINN; @@ -1293,7 +1313,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BINN_PRIVATE int binn_buf_count(void *pbuf) { ++BINN_PRIVATE int binn_buf_count(const void *pbuf) { + int nitems; + + if (!IsValidBinnHeader(pbuf, NULL, &nitems, NULL, NULL)) return 0; @@ -1304,7 +1324,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BINN_PRIVATE int binn_buf_size(void *pbuf) { ++BINN_PRIVATE int binn_buf_size(const void *pbuf) { + int size=0; + + if (!IsValidBinnHeader(pbuf, NULL, NULL, &size, NULL)) return 0; @@ -1315,7 +1335,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+void * APIENTRY binn_ptr(void *ptr) { ++void * APIENTRY binn_ptr(const void *ptr) { + binn *item; + + switch (binn_get_ptr_type(ptr)) { @@ -1326,7 +1346,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + return item->ptr; + case BINN_BUFFER: -+ return ptr; ++ return (void*)ptr; + default: + return NULL; + } @@ -1335,7 +1355,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+int APIENTRY binn_size(void *ptr) { ++int APIENTRY binn_size(const void *ptr) { + binn *item; + + switch (binn_get_ptr_type(ptr)) { @@ -1355,7 +1375,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+int APIENTRY binn_type(void *ptr) { ++int APIENTRY binn_type(const void *ptr) { + binn *item; + + switch (binn_get_ptr_type(ptr)) { @@ -1372,7 +1392,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+int APIENTRY binn_count(void *ptr) { ++int APIENTRY binn_count(const void *ptr) { + binn *item; + + switch (binn_get_ptr_type(ptr)) { @@ -1389,73 +1409,83 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BOOL APIENTRY binn_is_valid_ex(void *ptr, int *ptype, int *pcount, int *psize) { ++// the container can be smaller than the informed size ++BINN_PRIVATE BOOL binn_is_valid_ex2(const void *ptr, int *ptype, int *pcount, int *psize) { + int i, type, count, size, header_size; + unsigned char *p, *plimit, *base, len; -+ void *pbuf; + -+ pbuf = binn_ptr(ptr); -+ if (pbuf == NULL) return FALSE; ++ if (ptr == NULL) return FALSE; + -+ /* is there an informed size? */ ++ // is there an informed size? + if (psize && *psize > 0) { + size = *psize; + } else { + size = 0; + } + -+ if (!IsValidBinnHeader(pbuf, &type, &count, &size, &header_size)) return FALSE; ++ if (!IsValidBinnHeader(ptr, &type, &count, &size, &header_size)) return FALSE; + -+ /* is there an informed size? */ ++ // is there an informed size? + if (psize && *psize > 0) { -+ /* is it the same as the one in the buffer? */ -+ if (size != *psize) return FALSE; ++ // is it bigger than the buffer? ++ if (size > *psize) return FALSE; + } -+ /* is there an informed count? */ ++ // is there an informed count? + if (pcount && *pcount > 0) { -+ /* is it the same as the one in the buffer? */ ++ // is it the same as the one in the buffer? + if (count != *pcount) return FALSE; + } -+ /* is there an informed type? */ ++ // is there an informed type? + if (ptype && *ptype != 0) { -+ /* is it the same as the one in the buffer? */ ++ // is it the same as the one in the buffer? + if (type != *ptype) return FALSE; + } + -+ /* it could compare the content size with the size informed on the header */ -+ -+ p = (unsigned char *)pbuf; ++ p = (unsigned char *)ptr; + base = p; -+ plimit = p + size; ++ plimit = p + size - 1; + + p += header_size; + -+ /* process all the arguments. */ ++ // process each (key and) value + for (i = 0; i < count; i++) { + switch (type) { + case BINN_OBJECT: -+ /* gets the string size (argument name) */ ++ if (p > plimit) goto Invalid; ++ // get the key (string) size + len = *p; + p++; -+ /* if (len == 0) goto Invalid; */ -+ /* increment the used space */ ++ //if (len == 0) goto Invalid; ++ // advance over the key + p += len; + break; + case BINN_MAP: -+ /* increment the used space */ ++ // advance over the key + read_map_id(&p, plimit); + break; -+ /* case BINN_LIST: */ -+ /* break; */ ++ case BINN_LIST: ++ // no key ++ break; ++ default: ++ goto Invalid; ++ } ++ // check the value ++ if (p > plimit) goto Invalid; ++ if ((*p & BINN_STORAGE_MASK) == BINN_STORAGE_CONTAINER) { ++ // recursively check the internal container ++ int size2 = plimit - p + 1; // maximum container size ++ if (binn_is_valid_ex2(p, NULL, NULL, &size2) == FALSE) goto Invalid; ++ p += size2; ++ } else { ++ // advance over the value ++ p = AdvanceDataPos(p, plimit); ++ if (p == 0 || p < base) goto Invalid; + } -+ /* xxx */ -+ p = AdvanceDataPos(p, plimit); -+ if ((p == 0) || (p < base)) goto Invalid; + } + -+ if (ptype && *ptype==0) *ptype = type; ++ if (ptype && *ptype==0) *ptype = type; + if (pcount && *pcount==0) *pcount = count; -+ if (psize && *psize==0) *psize = size; ++ if (psize) *psize = size; + return TRUE; + +Invalid: @@ -1463,9 +1493,32 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +} + ++// the container must have the informed size, if informed ++BOOL APIENTRY binn_is_valid_ex(const void *ptr, int *ptype, int *pcount, int *psize) { ++ int size; ++ ++ if (psize && *psize > 0) { ++ size = *psize; ++ } else { ++ size = 0; ++ } ++ ++ if (binn_is_valid_ex2(ptr, ptype, pcount, &size) == FALSE) return FALSE; ++ ++ if (psize) { ++ if (*psize > 0) { ++ if (size != *psize) return FALSE; ++ } else if (*psize==0) { ++ *psize = size; ++ } ++ } ++ ++ return TRUE; ++} ++ +/***************************************************************************/ + -+BOOL APIENTRY binn_is_valid(void *ptr, int *ptype, int *pcount, int *psize) { ++BOOL APIENTRY binn_is_valid(const void *ptr, int *ptype, int *pcount, int *psize) { + + if (ptype) *ptype = 0; + if (pcount) *pcount = 0; @@ -1479,78 +1532,87 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/*** INTERNAL FUNCTIONS ****************************************************/ +/***************************************************************************/ + -+BINN_PRIVATE BOOL GetValue(unsigned char *p, binn *value) { ++BINN_PRIVATE BOOL GetValue(unsigned char *p, unsigned char *plimit, binn *value) { + unsigned char byte; -+ int data_type, storage_type; /* , extra_type; */ ++ int data_type, storage_type; //, extra_type; + int DataSize; + void *p2; + + if (value == NULL) return FALSE; + memset(value, 0, sizeof(binn)); + value->header = BINN_MAGIC; -+ /* value->allocated = FALSE; -- already zeroed */ -+ /* value->writable = FALSE; */ ++ //value->allocated = FALSE; -- already zeroed ++ //value->writable = FALSE; + -+ /* saves for use with BINN_STORAGE_CONTAINER */ ++ // saves for use with BINN_STORAGE_CONTAINER + p2 = p; + -+ /* read the data type */ ++ // read the data type ++ if (p > plimit) return FALSE; + byte = *p; p++; + storage_type = byte & BINN_STORAGE_MASK; + if (byte & BINN_STORAGE_HAS_MORE) { + data_type = byte << 8; ++ if (p > plimit) return FALSE; + byte = *p; p++; + data_type |= byte; -+ /* extra_type = data_type & BINN_TYPE_MASK16; */ ++ //extra_type = data_type & BINN_TYPE_MASK16; + } else { + data_type = byte; -+ /* extra_type = byte & BINN_TYPE_MASK; */ ++ //extra_type = byte & BINN_TYPE_MASK; + } + -+ /* value->storage_type = storage_type; */ ++ //value->storage_type = storage_type; + value->type = data_type; + + switch (storage_type) { + case BINN_STORAGE_NOBYTES: + break; + case BINN_STORAGE_BYTE: ++ if (p > plimit) return FALSE; + value->vuint8 = *((unsigned char *) p); -+ value->ptr = p; /* value->ptr = &value->vuint8; */ ++ value->ptr = p; //value->ptr = &value->vuint8; + break; + case BINN_STORAGE_WORD: ++ if (p + 1 > plimit) return FALSE; + copy_be16((u16*)&value->vint16, (u16*)p); + value->ptr = &value->vint16; + break; + case BINN_STORAGE_DWORD: ++ if (p + 3 > plimit) return FALSE; + copy_be32((u32*)&value->vint32, (u32*)p); + value->ptr = &value->vint32; + break; + case BINN_STORAGE_QWORD: ++ if (p + 7 > plimit) return FALSE; + copy_be64((u64*)&value->vint64, (u64*)p); + value->ptr = &value->vint64; + break; + case BINN_STORAGE_BLOB: + case BINN_STORAGE_STRING: ++ if (p > plimit) return FALSE; + DataSize = *((unsigned char*)p); + if (DataSize & 0x80) { ++ if (p + 3 > plimit) return FALSE; + copy_be32((u32*)&DataSize, (u32*)p); + DataSize &= 0x7FFFFFFF; + p+=4; + } else { + p++; + } ++ if (p + DataSize - 1 > plimit) return FALSE; + value->size = DataSize; + value->ptr = p; + break; + case BINN_STORAGE_CONTAINER: -+ value->ptr = p2; /* <-- it returns the pointer to the container, not the data */ ++ value->ptr = p2; // <-- it returns the pointer to the container, not the data + if (IsValidBinnHeader(p2, NULL, &value->count, &value->size, NULL) == FALSE) return FALSE; + break; + default: + return FALSE; + } + -+ /* convert the returned value, if needed */ ++ // convert the returned value, if needed + + switch (value->type) { + case BINN_TRUE: @@ -1566,12 +1628,12 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +#ifdef BINN_EXTENDED + case BINN_SINGLE_STR: + value->type = BINN_SINGLE; -+ value->vfloat = (float) atof((const char*)value->ptr); /* converts from string to double, and then to float */ ++ value->vfloat = (float) atof((const char*)value->ptr); // converts from string to double, and then to float + value->ptr = &value->vfloat; + break; + case BINN_DOUBLE_STR: + value->type = BINN_DOUBLE; -+ value->vdouble = atof((const char*)value->ptr); /* converts from string to double */ ++ value->vdouble = atof((const char*)value->ptr); // converts from string to double + value->ptr = &value->vdouble; + break; +#endif @@ -1592,8 +1654,8 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +#if BYTE_ORDER == LITTLE_ENDIAN + -+/* on little-endian devices we store the value so we can return a pointer to integers. */ -+/* it's valid only for single-threaded apps. multi-threaded apps must use the _get_ functions instead. */ ++// on little-endian devices we store the value so we can return a pointer to integers. ++// it's valid only for single-threaded apps. multi-threaded apps must use the _get_ functions instead. + +binn local_value; + @@ -1603,14 +1665,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (binn_get_read_storage(value->type)) { + case BINN_STORAGE_NOBYTES: -+ /* return a valid pointer */ ++ // return a valid pointer + case BINN_STORAGE_WORD: + case BINN_STORAGE_DWORD: + case BINN_STORAGE_QWORD: -+ return &local_value.vint32; /* returns the pointer to the converted value, from big-endian to little-endian */ ++ return &local_value.vint32; // returns the pointer to the converted value, from big-endian to little-endian + } + -+ return value->ptr; /* returns from the on stack value to be thread-safe (for list, map, object, string and blob) */ ++ return value->ptr; // returns from the on stack value to be thread-safe (for list, map, object, string and blob) + +} + @@ -1620,78 +1682,82 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/*** READ FUNCTIONS ********************************************************/ +/***************************************************************************/ + -+BOOL APIENTRY binn_object_get_value(void *ptr, const char *key, binn *value) { ++BOOL APIENTRY binn_object_get_value(const void *ptr, const char *key, binn *value) { + int type, count, size=0, header_size; -+ unsigned char *p; ++ unsigned char *p, *plimit; + + ptr = binn_ptr(ptr); -+ if ((ptr == 0) || (key == 0) || (value == 0)) return FALSE; ++ if (ptr == NULL || key == NULL || value == NULL) return FALSE; + -+ /* check the header */ ++ // check the header + if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; + + if (type != BINN_OBJECT) return FALSE; + if (count == 0) return FALSE; + + p = (unsigned char *) ptr; ++ plimit = p + size - 1; ++ + p = SearchForKey(p, header_size, size, count, key); + if (p == FALSE) return FALSE; + -+ return GetValue(p, value); ++ return GetValue(p, plimit, value); + +} + +/***************************************************************************/ + -+BOOL APIENTRY binn_map_get_value(void* ptr, int id, binn *value) { ++BOOL APIENTRY binn_map_get_value(const void *ptr, int id, binn *value) { + int type, count, size=0, header_size; -+ unsigned char *p; ++ unsigned char *p, *plimit; + + ptr = binn_ptr(ptr); -+ if ((ptr == 0) || (value == 0)) return FALSE; ++ if (ptr == NULL || value == NULL) return FALSE; + -+ /* check the header */ ++ // check the header + if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; + + if (type != BINN_MAP) return FALSE; + if (count == 0) return FALSE; + + p = (unsigned char *) ptr; ++ plimit = p + size - 1; ++ + p = SearchForID(p, header_size, size, count, id); + if (p == FALSE) return FALSE; + -+ return GetValue(p, value); ++ return GetValue(p, plimit, value); + +} + +/***************************************************************************/ + -+BOOL APIENTRY binn_list_get_value(void* ptr, int pos, binn *value) { ++BOOL APIENTRY binn_list_get_value(const void *ptr, int pos, binn *value) { + int i, type, count, size=0, header_size; + unsigned char *p, *plimit, *base; + + ptr = binn_ptr(ptr); -+ if ((ptr == 0) || (value == 0)) return FALSE; ++ if (ptr == NULL || value == NULL) return FALSE; + -+ /* check the header */ ++ // check the header + if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; + + if (type != BINN_LIST) return FALSE; + if (count == 0) return FALSE; -+ if ((pos <= 0) | (pos > count)) return FALSE; -+ pos--; /* convert from base 1 to base 0 */ ++ if (pos <= 0 || pos > count) return FALSE; ++ pos--; // convert from base 1 to base 0 + + p = (unsigned char *) ptr; + base = p; -+ plimit = p + size; ++ plimit = p + size - 1; + p += header_size; + + for (i = 0; i < pos; i++) { + p = AdvanceDataPos(p, plimit); -+ if ((p == 0) || (p < base)) return FALSE; ++ if (p == 0 || p < base) return FALSE; + } + -+ return GetValue(p, value); ++ return GetValue(p, plimit, value); + +} + @@ -1699,17 +1765,17 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/*** READ PAIR BY POSITION *************************************************/ +/***************************************************************************/ + -+BINN_PRIVATE BOOL binn_read_pair(int expected_type, void *ptr, int pos, int *pid, char *pkey, binn *value) { ++BINN_PRIVATE BOOL binn_read_pair(int expected_type, const void *ptr, int pos, int *pid, char *pkey, binn *value) { + int type, count, size=0, header_size; + int i, int32, id = 0, counter=0; + unsigned char *p, *plimit, *base, *key = NULL, len = 0; + + ptr = binn_ptr(ptr); + -+ /* check the header */ ++ // check the header + if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; + -+ if ((type != expected_type) || (count == 0) || (pos < 1) || (pos > count)) return FALSE; ++ if (type != expected_type || count == 0 || pos < 1 || pos > count) return FALSE; + + p = (unsigned char *) ptr; + base = p; @@ -1733,9 +1799,9 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + counter++; + if (counter == pos) goto found; -+ /* */ ++ // + p = AdvanceDataPos(p, plimit); -+ if ((p == 0) || (p < base)) return FALSE; ++ if (p == 0 || p < base) return FALSE; + } + + return FALSE; @@ -1754,13 +1820,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + break; + } + -+ return GetValue(p, value); ++ return GetValue(p, plimit, value); + +} + +/***************************************************************************/ + -+BOOL APIENTRY binn_map_get_pair(void *ptr, int pos, int *pid, binn *value) { ++BOOL APIENTRY binn_map_get_pair(const void *ptr, int pos, int *pid, binn *value) { + + return binn_read_pair(BINN_MAP, ptr, pos, pid, NULL, value); + @@ -1768,7 +1834,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BOOL APIENTRY binn_object_get_pair(void *ptr, int pos, char *pkey, binn *value) { ++BOOL APIENTRY binn_object_get_pair(const void *ptr, int pos, char *pkey, binn *value) { + + return binn_read_pair(BINN_OBJECT, ptr, pos, NULL, pkey, value); + @@ -1776,7 +1842,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+binn * APIENTRY binn_map_pair(void *map, int pos, int *pid) { ++binn * APIENTRY binn_map_pair(const void *map, int pos, int *pid) { + binn *value; + + value = (binn *) binn_malloc(sizeof(binn)); @@ -1793,7 +1859,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+binn * APIENTRY binn_object_pair(void *obj, int pos, char *pkey) { ++binn * APIENTRY binn_object_pair(const void *obj, int pos, char *pkey) { + binn *value; + + value = (binn *) binn_malloc(sizeof(binn)); @@ -1811,7 +1877,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/***************************************************************************/ +/***************************************************************************/ + -+void * APIENTRY binn_map_read_pair(void *ptr, int pos, int *pid, int *ptype, int *psize) { ++void * APIENTRY binn_map_read_pair(const void *ptr, int pos, int *pid, int *ptype, int *psize) { + binn value; + + if (binn_map_get_pair(ptr, pos, pid, &value) == FALSE) return NULL; @@ -1827,7 +1893,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+void * APIENTRY binn_object_read_pair(void *ptr, int pos, char *pkey, int *ptype, int *psize) { ++void * APIENTRY binn_object_read_pair(const void *ptr, int pos, char *pkey, int *ptype, int *psize) { + binn value; + + if (binn_object_get_pair(ptr, pos, pkey, &value) == FALSE) return NULL; @@ -1845,18 +1911,18 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/*** SEQUENTIAL READ FUNCTIONS *********************************************/ +/***************************************************************************/ + -+BOOL APIENTRY binn_iter_init(binn_iter *iter, void *ptr, int expected_type) { ++BOOL APIENTRY binn_iter_init(binn_iter *iter, const void *ptr, int expected_type) { + int type, count, size=0, header_size; + + ptr = binn_ptr(ptr); -+ if ((ptr == 0) || (iter == 0)) return FALSE; ++ if (ptr == NULL || iter == NULL) return FALSE; + memset(iter, 0, sizeof(binn_iter)); + -+ /* check the header */ ++ // check the header + if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; + + if (type != expected_type) return FALSE; -+ /* if (count == 0) return FALSE; -- should not be used */ ++ //if (count == 0) return FALSE; -- should not be used + + iter->plimit = (unsigned char *)ptr + size - 1; + iter->pnext = (unsigned char *)ptr + header_size; @@ -1872,7 +1938,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +BOOL APIENTRY binn_list_next(binn_iter *iter, binn *value) { + unsigned char *pnow; + -+ if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != BINN_LIST)) return FALSE; ++ if (iter == NULL || iter->pnext == NULL || iter->pnext > iter->plimit || iter->current > iter->count || iter->type != BINN_LIST) return FALSE; + + iter->current++; + if (iter->current > iter->count) return FALSE; @@ -1881,7 +1947,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + iter->pnext = AdvanceDataPos(pnow, iter->plimit); + if (iter->pnext != 0 && iter->pnext < pnow) return FALSE; + -+ return GetValue(pnow, value); ++ return GetValue(pnow, iter->plimit, value); + +} + @@ -1892,7 +1958,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + unsigned char *p, *key; + unsigned short len; + -+ if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != expected_type)) return FALSE; ++ if (iter == NULL || iter->pnext == NULL || iter->pnext > iter->plimit || iter->current > iter->count || iter->type != expected_type) return FALSE; + + iter->current++; + if (iter->current > iter->count) return FALSE; @@ -1921,7 +1987,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + iter->pnext = AdvanceDataPos(p, iter->plimit); + if (iter->pnext != 0 && iter->pnext < p) return FALSE; + -+ return GetValue(p, value); ++ return GetValue(p, iter->plimit, value); + +} + @@ -2121,14 +2187,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +#ifdef BINN_EXTENDED + case BINN_SINGLE: + f1 = **(float**)ppvalue; -+ d1 = f1; /* convert from float (32bits) to double (64bits) */ ++ d1 = f1; // convert from float (32bits) to double (64bits) + type = BINN_SINGLE_STR; + goto conv_double; + case BINN_DOUBLE: + d1 = **(double**)ppvalue; + type = BINN_DOUBLE_STR; +conv_double: -+ /* the '%.17e' is more precise than the '%g' */ ++ // the '%.17e' is more precise than the '%g' + snprintf(pstr, 127, "%.17e", d1); + *ppvalue = pstr; + *ptype = type; @@ -2141,13 +2207,13 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + snprintf(sptr, 127, "%E", **ppvalue); + *ppvalue = sptr; + */ -+ return TRUE; /* ! temporary */ ++ return TRUE; //! temporary + break; + + case BINN_DATE: + case BINN_DATETIME: + case BINN_TIME: -+ return TRUE; /* ! temporary */ ++ return TRUE; //! temporary + break; + + case BINN_BOOL: @@ -2187,9 +2253,9 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + case BINN_FLOAT32: + case BINN_FLOAT64: -+ /* case BINN_SINGLE: */ ++ //case BINN_SINGLE: + case BINN_SINGLE_STR: -+ /* case BINN_DOUBLE: */ ++ //case BINN_DOUBLE: + case BINN_DOUBLE_STR: + return BINN_FAMILY_FLOAT; + @@ -2222,7 +2288,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return BINN_FAMILY_NULL; + + default: -+ /* if it wasn't found */ ++ // if it wasn't found + return BINN_FAMILY_NONE; + } + @@ -2253,7 +2319,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+BINN_PRIVATE BOOL copy_raw_value(void *psource, void *pdest, int data_store) { ++BINN_PRIVATE BOOL copy_raw_value(const void *psource, void *pdest, int data_store) { + + switch (data_store) { + case BINN_STORAGE_NOBYTES: @@ -2285,7 +2351,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+BINN_PRIVATE BOOL copy_int_value(void *psource, void *pdest, int source_type, int dest_type) { ++BINN_PRIVATE BOOL copy_int_value(const void *psource, void *pdest, int source_type, int dest_type) { + uint64 vuint64 = 0; int64 vint64 = 0; + + switch (source_type) { @@ -2320,12 +2386,12 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + } + + -+ /* copy from int64 to uint64, if possible */ ++ // copy from int64 to uint64, if possible + -+ if ((int_type(source_type) == BINN_UNSIGNED_INT) && (int_type(dest_type) == BINN_SIGNED_INT)) { ++ if (int_type(source_type) == BINN_UNSIGNED_INT && int_type(dest_type) == BINN_SIGNED_INT) { + if (vuint64 > INT64_MAX) return FALSE; + vint64 = vuint64; -+ } else if ((int_type(source_type) == BINN_SIGNED_INT) && (int_type(dest_type) == BINN_UNSIGNED_INT)) { ++ } else if (int_type(source_type) == BINN_SIGNED_INT && int_type(dest_type) == BINN_UNSIGNED_INT) { + if (vint64 < 0) return FALSE; + vuint64 = vint64; + } @@ -2333,15 +2399,15 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (dest_type) { + case BINN_INT8: -+ if ((vint64 < INT8_MIN) || (vint64 > INT8_MAX)) return FALSE; ++ if (vint64 < INT8_MIN || vint64 > INT8_MAX) return FALSE; + *(signed char *)pdest = (signed char) vint64; + break; + case BINN_INT16: -+ if ((vint64 < INT16_MIN) || (vint64 > INT16_MAX)) return FALSE; ++ if (vint64 < INT16_MIN || vint64 > INT16_MAX) return FALSE; + *(short *)pdest = (short) vint64; + break; + case BINN_INT32: -+ if ((vint64 < INT32_MIN) || (vint64 > INT32_MAX)) return FALSE; ++ if (vint64 < INT32_MIN || vint64 > INT32_MAX) return FALSE; + *(int *)pdest = (int) vint64; + break; + case BINN_INT64: @@ -2374,7 +2440,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+BINN_PRIVATE BOOL copy_float_value(void *psource, void *pdest, int source_type) { ++BINN_PRIVATE BOOL copy_float_value(const void *psource, void *pdest, int source_type, int dest_type) { + + switch (source_type) { + case BINN_FLOAT32: @@ -2393,27 +2459,27 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+BINN_PRIVATE void zero_value(void *pvalue, int type) { -+ /* int size=0; */ ++BINN_PRIVATE void zero_value(const void *pvalue, int type) { ++ //int size=0; + + switch (binn_get_read_storage(type)) { + case BINN_STORAGE_NOBYTES: + break; + case BINN_STORAGE_BYTE: + *((char *) pvalue) = 0; -+ /* size=1; */ ++ //size=1; + break; + case BINN_STORAGE_WORD: + *((short *) pvalue) = 0; -+ /* size=2; */ ++ //size=2; + break; + case BINN_STORAGE_DWORD: + *((int *) pvalue) = 0; -+ /* size=4; */ ++ //size=4; + break; + case BINN_STORAGE_QWORD: + *((uint64 *) pvalue) = 0; -+ /* size=8; */ ++ //size=8; + break; + case BINN_STORAGE_BLOB: + case BINN_STORAGE_STRING: @@ -2422,7 +2488,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + break; + } + -+ /* if (size>0) memset(pvalue, 0, size); */ ++ //if (size>0) memset(pvalue, 0, size); + +} + @@ -2432,10 +2498,10 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + if (type_family(source_type) != type_family(dest_type)) return FALSE; + -+ if ((type_family(source_type) == BINN_FAMILY_INT) && (source_type != dest_type)) { ++ if (type_family(source_type) == BINN_FAMILY_INT && source_type != dest_type) { + return copy_int_value(psource, pdest, source_type, dest_type); -+ } else if ((type_family(source_type) == BINN_FAMILY_FLOAT) && (source_type != dest_type)) { -+ return copy_float_value(psource, pdest, source_type); ++ } else if (type_family(source_type) == BINN_FAMILY_FLOAT && source_type != dest_type) { ++ return copy_float_value(psource, pdest, source_type, dest_type); + } else { + return copy_raw_value(psource, pdest, data_store); + } @@ -2476,7 +2542,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+/* this function is used by the wrappers */ ++// this function is used by the wrappers +BOOL APIENTRY binn_add_value(binn *item, int binn_type, int id, char *name, int type, void *pvalue, int size) { + + switch (binn_type) { @@ -2530,7 +2596,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/*** READ FUNCTIONS ******************************************************************/ +/*************************************************************************************/ + -+binn * APIENTRY binn_list_value(void *ptr, int pos) { ++binn * APIENTRY binn_list_value(const void *ptr, int pos) { + binn *value; + + value = (binn *) binn_malloc(sizeof(binn)); @@ -2547,7 +2613,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+binn * APIENTRY binn_map_value(void *ptr, int id) { ++binn * APIENTRY binn_map_value(const void *ptr, int id) { + binn *value; + + value = (binn *) binn_malloc(sizeof(binn)); @@ -2564,7 +2630,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/*************************************************************************************/ + -+binn * APIENTRY binn_object_value(void *ptr, const char *key) { ++binn * APIENTRY binn_object_value(const void *ptr, const char *key) { + binn *value; + + value = (binn *) binn_malloc(sizeof(binn)); @@ -2582,7 +2648,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/***************************************************************************/ +/***************************************************************************/ + -+void * APIENTRY binn_list_read(void *list, int pos, int *ptype, int *psize) { ++void * APIENTRY binn_list_read(const void *list, int pos, int *ptype, int *psize) { + binn value; + + if (binn_list_get_value(list, pos, &value) == FALSE) return NULL; @@ -2598,7 +2664,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+void * APIENTRY binn_map_read(void *map, int id, int *ptype, int *psize) { ++void * APIENTRY binn_map_read(const void *map, int id, int *ptype, int *psize) { + binn value; + + if (binn_map_get_value(map, id, &value) == FALSE) return NULL; @@ -2614,7 +2680,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+void * APIENTRY binn_object_read(void *obj, const char *key, int *ptype, int *psize) { ++void * APIENTRY binn_object_read(const void *obj, const char *key, int *ptype, int *psize) { + binn value; + + if (binn_object_get_value(obj, key, &value) == FALSE) return NULL; @@ -2631,12 +2697,12 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/***************************************************************************/ +/***************************************************************************/ + -+BOOL APIENTRY binn_list_get(void *ptr, int pos, int type, void *pvalue, int *psize) { ++BOOL APIENTRY binn_list_get(const void *ptr, int pos, int type, void *pvalue, int *psize) { + binn value; + int storage_type; + + storage_type = binn_get_read_storage(type); -+ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ if (storage_type != BINN_STORAGE_NOBYTES && pvalue == NULL) return FALSE; + + zero_value(pvalue, type); + @@ -2652,12 +2718,12 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+BOOL APIENTRY binn_map_get(void *ptr, int id, int type, void *pvalue, int *psize) { ++BOOL APIENTRY binn_map_get(const void *ptr, int id, int type, void *pvalue, int *psize) { + binn value; + int storage_type; + + storage_type = binn_get_read_storage(type); -+ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ if (storage_type != BINN_STORAGE_NOBYTES && pvalue == NULL) return FALSE; + + zero_value(pvalue, type); + @@ -2673,14 +2739,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+/* if (binn_object_get(obj, "multiplier", BINN_INT32, &multiplier, NULL) == FALSE) xxx; */ ++// if (binn_object_get(obj, "multiplier", BINN_INT32, &multiplier, NULL) == FALSE) xxx; + -+BOOL APIENTRY binn_object_get(void *ptr, const char *key, int type, void *pvalue, int *psize) { ++BOOL APIENTRY binn_object_get(const void *ptr, const char *key, int type, void *pvalue, int *psize) { + binn value; + int storage_type; + + storage_type = binn_get_read_storage(type); -+ if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; ++ if (storage_type != BINN_STORAGE_NOBYTES && pvalue == NULL) return FALSE; + + zero_value(pvalue, type); + @@ -2697,14 +2763,14 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +/***************************************************************************/ +/***************************************************************************/ + -+/* these functions below may not be implemented as inline functions, because */ -+/* they use a lot of space, even for the variable. so they will be exported. */ ++// these functions below may not be implemented as inline functions, because ++// they use a lot of space, even for the variable. so they will be exported. + -+/* but what about using as static? */ -+/* is there any problem with wrappers? can these wrappers implement these functions using the header? */ -+/* if as static, will they be present even on modules that don't use the functions? */ ++// but what about using as static? ++// is there any problem with wrappers? can these wrappers implement these functions using the header? ++// if as static, will they be present even on modules that don't use the functions? + -+signed char APIENTRY binn_list_int8(void *list, int pos) { ++signed char APIENTRY binn_list_int8(const void *list, int pos) { + signed char value; + + binn_list_get(list, pos, BINN_INT8, &value, NULL); @@ -2712,7 +2778,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+short APIENTRY binn_list_int16(void *list, int pos) { ++short APIENTRY binn_list_int16(const void *list, int pos) { + short value; + + binn_list_get(list, pos, BINN_INT16, &value, NULL); @@ -2720,7 +2786,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int APIENTRY binn_list_int32(void *list, int pos) { ++int APIENTRY binn_list_int32(const void *list, int pos) { + int value; + + binn_list_get(list, pos, BINN_INT32, &value, NULL); @@ -2728,7 +2794,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int64 APIENTRY binn_list_int64(void *list, int pos) { ++int64 APIENTRY binn_list_int64(const void *list, int pos) { + int64 value; + + binn_list_get(list, pos, BINN_INT64, &value, NULL); @@ -2736,7 +2802,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned char APIENTRY binn_list_uint8(void *list, int pos) { ++unsigned char APIENTRY binn_list_uint8(const void *list, int pos) { + unsigned char value; + + binn_list_get(list, pos, BINN_UINT8, &value, NULL); @@ -2744,7 +2810,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned short APIENTRY binn_list_uint16(void *list, int pos) { ++unsigned short APIENTRY binn_list_uint16(const void *list, int pos) { + unsigned short value; + + binn_list_get(list, pos, BINN_UINT16, &value, NULL); @@ -2752,7 +2818,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned int APIENTRY binn_list_uint32(void *list, int pos) { ++unsigned int APIENTRY binn_list_uint32(const void *list, int pos) { + unsigned int value; + + binn_list_get(list, pos, BINN_UINT32, &value, NULL); @@ -2760,7 +2826,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+uint64 APIENTRY binn_list_uint64(void *list, int pos) { ++uint64 APIENTRY binn_list_uint64(const void *list, int pos) { + uint64 value; + + binn_list_get(list, pos, BINN_UINT64, &value, NULL); @@ -2768,7 +2834,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+float APIENTRY binn_list_float(void *list, int pos) { ++float APIENTRY binn_list_float(const void *list, int pos) { + float value; + + binn_list_get(list, pos, BINN_FLOAT32, &value, NULL); @@ -2776,7 +2842,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+double APIENTRY binn_list_double(void *list, int pos) { ++double APIENTRY binn_list_double(const void *list, int pos) { + double value; + + binn_list_get(list, pos, BINN_FLOAT64, &value, NULL); @@ -2784,21 +2850,21 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+BOOL APIENTRY binn_list_bool(void *list, int pos) { -+ BOOL value; ++BOOL APIENTRY binn_list_bool(const void *list, int pos) { ++ BOOL value = TRUE; + + binn_list_get(list, pos, BINN_BOOL, &value, NULL); + + return value; +} + -+BOOL APIENTRY binn_list_null(void *list, int pos) { ++BOOL APIENTRY binn_list_null(const void *list, int pos) { + + return binn_list_get(list, pos, BINN_NULL, NULL, NULL); + +} + -+char * APIENTRY binn_list_str(void *list, int pos) { ++char * APIENTRY binn_list_str(const void *list, int pos) { + char *value; + + binn_list_get(list, pos, BINN_STRING, &value, NULL); @@ -2806,7 +2872,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_list_blob(void *list, int pos, int *psize) { ++void * APIENTRY binn_list_blob(const void *list, int pos, int *psize) { + void *value; + + binn_list_get(list, pos, BINN_BLOB, &value, psize); @@ -2814,7 +2880,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_list_list(void *list, int pos) { ++void * APIENTRY binn_list_list(const void *list, int pos) { + void *value; + + binn_list_get(list, pos, BINN_LIST, &value, NULL); @@ -2822,7 +2888,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_list_map(void *list, int pos) { ++void * APIENTRY binn_list_map(const void *list, int pos) { + void *value; + + binn_list_get(list, pos, BINN_MAP, &value, NULL); @@ -2830,7 +2896,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_list_object(void *list, int pos) { ++void * APIENTRY binn_list_object(const void *list, int pos) { + void *value; + + binn_list_get(list, pos, BINN_OBJECT, &value, NULL); @@ -2840,7 +2906,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+signed char APIENTRY binn_map_int8(void *map, int id) { ++signed char APIENTRY binn_map_int8(const void *map, int id) { + signed char value; + + binn_map_get(map, id, BINN_INT8, &value, NULL); @@ -2848,7 +2914,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+short APIENTRY binn_map_int16(void *map, int id) { ++short APIENTRY binn_map_int16(const void *map, int id) { + short value; + + binn_map_get(map, id, BINN_INT16, &value, NULL); @@ -2856,7 +2922,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int APIENTRY binn_map_int32(void *map, int id) { ++int APIENTRY binn_map_int32(const void *map, int id) { + int value; + + binn_map_get(map, id, BINN_INT32, &value, NULL); @@ -2864,7 +2930,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int64 APIENTRY binn_map_int64(void *map, int id) { ++int64 APIENTRY binn_map_int64(const void *map, int id) { + int64 value; + + binn_map_get(map, id, BINN_INT64, &value, NULL); @@ -2872,7 +2938,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned char APIENTRY binn_map_uint8(void *map, int id) { ++unsigned char APIENTRY binn_map_uint8(const void *map, int id) { + unsigned char value; + + binn_map_get(map, id, BINN_UINT8, &value, NULL); @@ -2880,7 +2946,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned short APIENTRY binn_map_uint16(void *map, int id) { ++unsigned short APIENTRY binn_map_uint16(const void *map, int id) { + unsigned short value; + + binn_map_get(map, id, BINN_UINT16, &value, NULL); @@ -2888,7 +2954,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned int APIENTRY binn_map_uint32(void *map, int id) { ++unsigned int APIENTRY binn_map_uint32(const void *map, int id) { + unsigned int value; + + binn_map_get(map, id, BINN_UINT32, &value, NULL); @@ -2896,7 +2962,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+uint64 APIENTRY binn_map_uint64(void *map, int id) { ++uint64 APIENTRY binn_map_uint64(const void *map, int id) { + uint64 value; + + binn_map_get(map, id, BINN_UINT64, &value, NULL); @@ -2904,7 +2970,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+float APIENTRY binn_map_float(void *map, int id) { ++float APIENTRY binn_map_float(const void *map, int id) { + float value; + + binn_map_get(map, id, BINN_FLOAT32, &value, NULL); @@ -2912,7 +2978,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+double APIENTRY binn_map_double(void *map, int id) { ++double APIENTRY binn_map_double(const void *map, int id) { + double value; + + binn_map_get(map, id, BINN_FLOAT64, &value, NULL); @@ -2920,21 +2986,21 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+BOOL APIENTRY binn_map_bool(void *map, int id) { -+ BOOL value; ++BOOL APIENTRY binn_map_bool(const void *map, int id) { ++ BOOL value = TRUE; + + binn_map_get(map, id, BINN_BOOL, &value, NULL); + + return value; +} + -+BOOL APIENTRY binn_map_null(void *map, int id) { ++BOOL APIENTRY binn_map_null(const void *map, int id) { + + return binn_map_get(map, id, BINN_NULL, NULL, NULL); + +} + -+char * APIENTRY binn_map_str(void *map, int id) { ++char * APIENTRY binn_map_str(const void *map, int id) { + char *value; + + binn_map_get(map, id, BINN_STRING, &value, NULL); @@ -2942,7 +3008,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_map_blob(void *map, int id, int *psize) { ++void * APIENTRY binn_map_blob(const void *map, int id, int *psize) { + void *value; + + binn_map_get(map, id, BINN_BLOB, &value, psize); @@ -2950,7 +3016,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_map_list(void *map, int id) { ++void * APIENTRY binn_map_list(const void *map, int id) { + void *value; + + binn_map_get(map, id, BINN_LIST, &value, NULL); @@ -2958,7 +3024,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_map_map(void *map, int id) { ++void * APIENTRY binn_map_map(const void *map, int id) { + void *value; + + binn_map_get(map, id, BINN_MAP, &value, NULL); @@ -2966,7 +3032,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_map_object(void *map, int id) { ++void * APIENTRY binn_map_object(const void *map, int id) { + void *value; + + binn_map_get(map, id, BINN_OBJECT, &value, NULL); @@ -2976,7 +3042,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +/***************************************************************************/ + -+signed char APIENTRY binn_object_int8(void *obj, const char *key) { ++signed char APIENTRY binn_object_int8(const void *obj, const char *key) { + signed char value; + + binn_object_get(obj, key, BINN_INT8, &value, NULL); @@ -2984,7 +3050,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+short APIENTRY binn_object_int16(void *obj, const char *key) { ++short APIENTRY binn_object_int16(const void *obj, const char *key) { + short value; + + binn_object_get(obj, key, BINN_INT16, &value, NULL); @@ -2992,7 +3058,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int APIENTRY binn_object_int32(void *obj, const char *key) { ++int APIENTRY binn_object_int32(const void *obj, const char *key) { + int value; + + binn_object_get(obj, key, BINN_INT32, &value, NULL); @@ -3000,7 +3066,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+int64 APIENTRY binn_object_int64(void *obj, const char *key) { ++int64 APIENTRY binn_object_int64(const void *obj, const char *key) { + int64 value; + + binn_object_get(obj, key, BINN_INT64, &value, NULL); @@ -3008,7 +3074,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned char APIENTRY binn_object_uint8(void *obj, const char *key) { ++unsigned char APIENTRY binn_object_uint8(const void *obj, const char *key) { + unsigned char value; + + binn_object_get(obj, key, BINN_UINT8, &value, NULL); @@ -3016,7 +3082,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned short APIENTRY binn_object_uint16(void *obj, const char *key) { ++unsigned short APIENTRY binn_object_uint16(const void *obj, const char *key) { + unsigned short value; + + binn_object_get(obj, key, BINN_UINT16, &value, NULL); @@ -3024,7 +3090,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+unsigned int APIENTRY binn_object_uint32(void *obj, const char *key) { ++unsigned int APIENTRY binn_object_uint32(const void *obj, const char *key) { + unsigned int value; + + binn_object_get(obj, key, BINN_UINT32, &value, NULL); @@ -3032,7 +3098,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+uint64 APIENTRY binn_object_uint64(void *obj, const char *key) { ++uint64 APIENTRY binn_object_uint64(const void *obj, const char *key) { + uint64 value; + + binn_object_get(obj, key, BINN_UINT64, &value, NULL); @@ -3040,7 +3106,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+float APIENTRY binn_object_float(void *obj, const char *key) { ++float APIENTRY binn_object_float(const void *obj, const char *key) { + float value; + + binn_object_get(obj, key, BINN_FLOAT32, &value, NULL); @@ -3048,7 +3114,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+double APIENTRY binn_object_double(void *obj, const char *key) { ++double APIENTRY binn_object_double(const void *obj, const char *key) { + double value; + + binn_object_get(obj, key, BINN_FLOAT64, &value, NULL); @@ -3056,21 +3122,21 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+BOOL APIENTRY binn_object_bool(void *obj, const char *key) { -+ BOOL value; ++BOOL APIENTRY binn_object_bool(const void *obj, const char *key) { ++ BOOL value = TRUE; + + binn_object_get(obj, key, BINN_BOOL, &value, NULL); + + return value; +} + -+BOOL APIENTRY binn_object_null(void *obj, const char *key) { ++BOOL APIENTRY binn_object_null(const void *obj, const char *key) { + + return binn_object_get(obj, key, BINN_NULL, NULL, NULL); + +} + -+char * APIENTRY binn_object_str(void *obj, const char *key) { ++char * APIENTRY binn_object_str(const void *obj, const char *key) { + char *value; + + binn_object_get(obj, key, BINN_STRING, &value, NULL); @@ -3078,7 +3144,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_object_blob(void *obj, const char *key, int *psize) { ++void * APIENTRY binn_object_blob(const void *obj, const char *key, int *psize) { + void *value; + + binn_object_get(obj, key, BINN_BLOB, &value, psize); @@ -3086,7 +3152,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_object_list(void *obj, const char *key) { ++void * APIENTRY binn_object_list(const void *obj, const char *key) { + void *value; + + binn_object_get(obj, key, BINN_LIST, &value, NULL); @@ -3094,7 +3160,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_object_map(void *obj, const char *key) { ++void * APIENTRY binn_object_map(const void *obj, const char *key) { + void *value; + + binn_object_get(obj, key, BINN_MAP, &value, NULL); @@ -3102,7 +3168,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + return value; +} + -+void * APIENTRY binn_object_object(void *obj, const char *key) { ++void * APIENTRY binn_object_object(const void *obj, const char *key) { + void *value; + + binn_object_get(obj, key, BINN_OBJECT, &value, NULL); @@ -3120,7 +3186,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + memset(item, 0, sizeof(binn)); + item->header = BINN_MAGIC; + item->allocated = TRUE; -+ /* item->writable = FALSE; -- already zeroed */ ++ //item->writable = FALSE; -- already zeroed + } + return item; +} @@ -3240,7 +3306,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + retval = TRUE; + + for (; *p; p++) { -+ if ( (*p < '0') || (*p > '9') ) { ++ if ( (*p < '0' || *p > '9') ) { + retval = FALSE; + } + } @@ -3260,9 +3326,9 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + retval = TRUE; + + for (; *p; p++) { -+ if ((*p == '.') || (*p == ',')) { ++ if (*p == '.' || *p == ',') { + if (!number_found) retval = FALSE; -+ } else if ( (*p >= '0') && (*p <= '9') ) { ++ } else if ( *p >= '0' && *p <= '9' ) { + number_found = TRUE; + } else { + return FALSE; @@ -3283,12 +3349,12 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + if (stricmp(str, "true") == 0) goto loc_true; + if (stricmp(str, "yes") == 0) goto loc_true; + if (stricmp(str, "on") == 0) goto loc_true; -+ /* if (stricmp(str, "1") == 0) goto loc_true; */ ++ //if (stricmp(str, "1") == 0) goto loc_true; + + if (stricmp(str, "false") == 0) goto loc_false; + if (stricmp(str, "no") == 0) goto loc_false; + if (stricmp(str, "off") == 0) goto loc_false; -+ /* if (stricmp(str, "0") == 0) goto loc_false; */ ++ //if (stricmp(str, "0") == 0) goto loc_false; + + if (is_integer(str)) { + vint = atoi64(str); @@ -3312,27 +3378,6 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +} + -+/* these three functions are used to -+ * suppress warnings about implicit conversions -+ * in binn_get_int32 and binn_get_int64 -+ * CJR 2/9/2023 -+ */ -+ -+float -+binn_cvt_int2float (int value) { -+ return (float)value; -+} -+ -+float -+binn_cvt_long2float (long int value) { -+ return (float)value; -+} -+ -+float -+binn_cvt_long2dbl (long int value) { -+ return (long long int)value; -+} -+ +/*************************************************************************************/ + +BOOL APIENTRY binn_get_int32(binn *value, int *pint) { @@ -3345,11 +3390,11 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (value->type) { + case BINN_FLOAT: -+ if ((value->vfloat < binn_cvt_int2float(INT32_MIN)) || (value->vfloat > binn_cvt_int2float(INT32_MAX))) return FALSE; ++ if (value->vfloat < (float)INT32_MIN || value->vfloat > (float)INT32_MAX) return FALSE; + *pint = roundval(value->vfloat); + break; + case BINN_DOUBLE: -+ if ((value->vdouble < INT32_MIN) || (value->vdouble > INT32_MAX)) return FALSE; ++ if (value->vdouble < (double)INT32_MIN || value->vdouble > (double)INT32_MAX) return FALSE; + *pint = roundval(value->vdouble); + break; + case BINN_STRING: @@ -3382,11 +3427,11 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + + switch (value->type) { + case BINN_FLOAT: -+ if ((value->vfloat < binn_cvt_long2float(INT64_MIN)) || (value->vfloat > binn_cvt_long2float(INT64_MAX))) return FALSE; ++ if (value->vfloat < (float)INT64_MIN || value->vfloat > (float)INT64_MAX) return FALSE; + *pint = roundval(value->vfloat); + break; + case BINN_DOUBLE: -+ if ((value->vdouble < binn_cvt_long2dbl(INT64_MIN)) || (value->vdouble > binn_cvt_long2dbl(INT64_MAX))) return FALSE; ++ if (value->vdouble < (double)INT64_MIN || value->vdouble > (double)INT64_MAX) return FALSE; + *pint = roundval(value->vdouble); + break; + case BINN_STRING: @@ -3512,7 +3557,7 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c + +loc_convert_value: + -+ /* value->vint64 = 0; */ ++ //value->vint64 = 0; + value->ptr = strdup(buf); + if (value->ptr == NULL) return NULL; + value->freefn = free; @@ -3541,20 +3586,19 @@ diff -Nur openssh-9.6p1.orig/binn.c openssh-9.6p1/binn.c +} + +/*************************************************************************************/ -diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h ---- openssh-9.6p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/binn.h 2024-07-10 13:34:02.708358559 +0200 -@@ -0,0 +1,944 @@ +diff -Nur openssh-9.8p1.orig/binn.h openssh-9.8p1/binn.h +--- openssh-9.8p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/binn.h 2024-09-30 16:03:39.145245244 +0200 +@@ -0,0 +1,945 @@ + -+/* TO ENABLE INLINE FUNCTIONS: */ -+/* ON MSVC: enable the 'Inline Function Expansion' (/Ob2) compiler option, and maybe the */ -+/* 'Whole Program Optimitazion' (/GL), that requires the */ -+/* 'Link Time Code Generation' (/LTCG) linker option to be enabled too */ ++// TO ENABLE INLINE FUNCTIONS: ++// ON MSVC: enable the 'Inline Function Expansion' (/Ob2) compiler option, and maybe the ++// 'Whole Program Optimitazion' (/GL), that requires the ++// 'Link Time Code Generation' (/LTCG) linker option to be enabled too + +#ifndef BINN_H +#define BINN_H -+#include -+#include "config.h" ++ +#ifdef __cplusplus +extern "C" { +#endif @@ -3585,7 +3629,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + #ifdef _WIN32 + #define APIENTRY __stdcall + #else -+ /* #define APIENTRY __attribute__((stdcall)) */ ++ //#define APIENTRY __attribute__((stdcall)) + #define APIENTRY + #endif +#endif @@ -3602,7 +3646,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + #define INLINE __inline + #define ALWAYS_INLINE __forceinline +#else -+ /* you can change to 'extern inline' if using the gcc option -flto */ ++ // you can change to 'extern inline' if using the gcc option -flto + #define INLINE static inline + #define ALWAYS_INLINE static inline __attribute__((always_inline)) +#endif @@ -3628,18 +3672,18 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#endif + + -+/* BINN CONSTANTS ---------------------------------------- */ ++// BINN CONSTANTS ---------------------------------------- + +#define INVALID_BINN 0 + -+/* Storage Data Types ------------------------------------ */ ++// Storage Data Types ------------------------------------ + +#define BINN_STORAGE_NOBYTES 0x00 -+#define BINN_STORAGE_BYTE 0x20 /* 8 bits */ -+#define BINN_STORAGE_WORD 0x40 /* 16 bits -- the endianess (byte order) is automatically corrected */ -+#define BINN_STORAGE_DWORD 0x60 /* 32 bits -- the endianess (byte order) is automatically corrected */ -+#define BINN_STORAGE_QWORD 0x80 /* 64 bits -- the endianess (byte order) is automatically corrected */ -+#define BINN_STORAGE_STRING 0xA0 /* Are stored with null termination */ ++#define BINN_STORAGE_BYTE 0x20 // 8 bits ++#define BINN_STORAGE_WORD 0x40 // 16 bits -- the endianess (byte order) is automatically corrected ++#define BINN_STORAGE_DWORD 0x60 // 32 bits -- the endianess (byte order) is automatically corrected ++#define BINN_STORAGE_QWORD 0x80 // 64 bits -- the endianess (byte order) is automatically corrected ++#define BINN_STORAGE_STRING 0xA0 // Are stored with null termination +#define BINN_STORAGE_BLOB 0xC0 +#define BINN_STORAGE_CONTAINER 0xE0 +#define BINN_STORAGE_VIRTUAL 0x80000 @@ -3656,7 +3700,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_MAX_VALUE_MASK 0xFFFFF + + -+/* Data Formats ------------------------------------------ */ ++// Data Formats ------------------------------------------ + +#define BINN_LIST 0xE0 +#define BINN_MAP 0xE1 @@ -3666,54 +3710,54 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_TRUE 0x01 +#define BINN_FALSE 0x02 + -+#define BINN_UINT8 0x20 /* (BYTE) (unsigned byte) Is the default format for the BYTE type */ -+#define BINN_INT8 0x21 /* (BYTE) (signed byte, from -128 to +127. The 0x80 is the sign bit, so the range in hex is from 0x80 [-128] to 0x7F [127], being 0x00 = 0 and 0xFF = -1) */ -+#define BINN_UINT16 0x40 /* (WORD) (unsigned integer) Is the default format for the WORD type */ -+#define BINN_INT16 0x41 /* (WORD) (signed integer) */ -+#define BINN_UINT32 0x60 /* (DWORD) (unsigned integer) Is the default format for the DWORD type */ -+#define BINN_INT32 0x61 /* (DWORD) (signed integer) */ -+#define BINN_UINT64 0x80 /* (QWORD) (unsigned integer) Is the default format for the QWORD type */ -+#define BINN_INT64 0x81 /* (QWORD) (signed integer) */ ++#define BINN_UINT8 0x20 // (BYTE) (unsigned byte) Is the default format for the BYTE type ++#define BINN_INT8 0x21 // (BYTE) (signed byte, from -128 to +127. The 0x80 is the sign bit, so the range in hex is from 0x80 [-128] to 0x7F [127], being 0x00 = 0 and 0xFF = -1) ++#define BINN_UINT16 0x40 // (WORD) (unsigned integer) Is the default format for the WORD type ++#define BINN_INT16 0x41 // (WORD) (signed integer) ++#define BINN_UINT32 0x60 // (DWORD) (unsigned integer) Is the default format for the DWORD type ++#define BINN_INT32 0x61 // (DWORD) (signed integer) ++#define BINN_UINT64 0x80 // (QWORD) (unsigned integer) Is the default format for the QWORD type ++#define BINN_INT64 0x81 // (QWORD) (signed integer) + +#define BINN_SCHAR BINN_INT8 +#define BINN_UCHAR BINN_UINT8 + -+#define BINN_STRING 0xA0 /* (STRING) Raw String */ -+#define BINN_DATETIME 0xA1 /* (STRING) iso8601 format -- YYYY-MM-DD HH:MM:SS */ -+#define BINN_DATE 0xA2 /* (STRING) iso8601 format -- YYYY-MM-DD */ -+#define BINN_TIME 0xA3 /* (STRING) iso8601 format -- HH:MM:SS */ -+#define BINN_DECIMAL 0xA4 /* (STRING) High precision number - used for generic decimal values and for those ones that cannot be represented in the float64 format. */ -+#define BINN_CURRENCYSTR 0xA5 /* (STRING) With currency unit/symbol - check for some iso standard format */ -+#define BINN_SINGLE_STR 0xA6 /* (STRING) Can be restored to float32 */ -+#define BINN_DOUBLE_STR 0xA7 /* (STRING) May be restored to float64 */ ++#define BINN_STRING 0xA0 // (STRING) Raw String ++#define BINN_DATETIME 0xA1 // (STRING) iso8601 format -- YYYY-MM-DD HH:MM:SS ++#define BINN_DATE 0xA2 // (STRING) iso8601 format -- YYYY-MM-DD ++#define BINN_TIME 0xA3 // (STRING) iso8601 format -- HH:MM:SS ++#define BINN_DECIMAL 0xA4 // (STRING) High precision number - used for generic decimal values and for those ones that cannot be represented in the float64 format. ++#define BINN_CURRENCYSTR 0xA5 // (STRING) With currency unit/symbol - check for some iso standard format ++#define BINN_SINGLE_STR 0xA6 // (STRING) Can be restored to float32 ++#define BINN_DOUBLE_STR 0xA7 // (STRING) May be restored to float64 + -+#define BINN_FLOAT32 0x62 /* (DWORD) */ -+#define BINN_FLOAT64 0x82 /* (QWORD) */ ++#define BINN_FLOAT32 0x62 // (DWORD) ++#define BINN_FLOAT64 0x82 // (QWORD) +#define BINN_FLOAT BINN_FLOAT32 +#define BINN_SINGLE BINN_FLOAT32 +#define BINN_DOUBLE BINN_FLOAT64 + -+#define BINN_CURRENCY 0x83 /* (QWORD) */ ++#define BINN_CURRENCY 0x83 // (QWORD) + -+#define BINN_BLOB 0xC0 /* (BLOB) Raw Blob */ ++#define BINN_BLOB 0xC0 // (BLOB) Raw Blob + + -+/* virtual types: */ ++// virtual types: + -+#define BINN_BOOL 0x80061 /* (DWORD) The value may be 0 or 1 */ ++#define BINN_BOOL 0x80061 // (DWORD) The value may be 0 or 1 + +#ifdef BINN_EXTENDED -+/* #define BINN_SINGLE 0x800A1 // (STRING) Can be restored to float32 */ -+/* #define BINN_DOUBLE 0x800A2 // (STRING) May be restored to float64 */ ++//#define BINN_SINGLE 0x800A1 // (STRING) Can be restored to float32 ++//#define BINN_DOUBLE 0x800A2 // (STRING) May be restored to float64 +#endif + -+/* #define BINN_BINN 0x800E1 // (CONTAINER) */ -+/* #define BINN_BINN_BUFFER 0x800C1 // (BLOB) user binn. it's not open by the parser */ ++//#define BINN_BINN 0x800E1 // (CONTAINER) ++//#define BINN_BINN_BUFFER 0x800C1 // (BLOB) user binn. it's not open by the parser + + -+/* extended content types: */ ++// extended content types: + -+/* strings: */ ++// strings: + +#define BINN_HTML 0xB001 +#define BINN_XML 0xB002 @@ -3721,7 +3765,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_JAVASCRIPT 0xB004 +#define BINN_CSS 0xB005 + -+/* blobs: */ ++// blobs: + +#define BINN_JPEG 0xD001 +#define BINN_GIF 0xD002 @@ -3729,7 +3773,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_BMP 0xD004 + + -+/* type families */ ++// type families +#define BINN_FAMILY_NONE 0x00 +#define BINN_FAMILY_NULL 0xf1 +#define BINN_FAMILY_INT 0xf2 @@ -3739,7 +3783,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_FAMILY_BOOL 0xf6 +#define BINN_FAMILY_BINN 0xf7 + -+/* integer types related to signal */ ++// integer types related to signal +#define BINN_SIGNED_INT 11 +#define BINN_UNSIGNED_INT 22 + @@ -3749,27 +3793,27 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define BINN_TRANSIENT ((binn_mem_free)-1) + + -+/* --- BINN STRUCTURE -------------------------------------------------------------- */ ++// --- BINN STRUCTURE -------------------------------------------------------------- + + +struct binn_struct { -+ int header; /* this struct header holds the magic number (BINN_MAGIC) that identifies this memory block as a binn structure */ -+ BOOL allocated; /* the struct can be allocated using malloc_fn() or can be on the stack */ -+ BOOL writable; /* did it was create for writing? it can use the pbuf if not unified with ptr */ -+ BOOL dirty; /* the container header is not written to the buffer */ -+ /* */ -+ void *pbuf; /* use *ptr below? */ ++ int header; // this struct header holds the magic number (BINN_MAGIC) that identifies this memory block as a binn structure ++ BOOL allocated; // the struct can be allocated using malloc_fn() or can be on the stack ++ BOOL writable; // did it was create for writing? it can use the pbuf if not unified with ptr ++ BOOL dirty; // the container header is not written to the buffer ++ // ++ void *pbuf; // use *ptr below? + BOOL pre_allocated; + int alloc_size; + int used_size; -+ /* */ ++ // + int type; + void *ptr; + int size; + int count; -+ /* */ -+ binn_mem_free freefn; /* used only when type == BINN_STRING or BINN_BLOB */ -+ /* */ ++ // ++ binn_mem_free freefn; // used only when type == BINN_STRING or BINN_BLOB ++ // + union { + signed char vint8; + signed short vint16; @@ -3779,20 +3823,20 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + unsigned short vuint16; + unsigned int vuint32; + uint64 vuint64; -+ /* */ ++ // + signed char vchar; + unsigned char vuchar; + signed short vshort; + unsigned short vushort; + signed int vint; + unsigned int vuint; -+ /* */ ++ // + float vfloat; + double vdouble; -+ /* */ ++ // + BOOL vbool; + }; -+ /* */ ++ // + BOOL disable_int_compression; +}; + @@ -3800,7 +3844,7 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + + + -+/* --- GENERAL FUNCTIONS ---------------------------------------------------------- */ ++// --- GENERAL FUNCTIONS ---------------------------------------------------------- + +char * APIENTRY binn_version(); + @@ -3815,22 +3859,22 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +BOOL APIENTRY binn_is_container(binn *item); + + -+/* --- WRITE FUNCTIONS ------------------------------------------------------------ */ ++// --- WRITE FUNCTIONS ------------------------------------------------------------ + -+/* create a new binn allocating memory for the structure */ ++// create a new binn allocating memory for the structure +binn * APIENTRY binn_new(int type, int size, void *buffer); +binn * APIENTRY binn_list(); +binn * APIENTRY binn_map(); +binn * APIENTRY binn_object(); + -+/* create a new binn storing the structure on the stack */ ++// create a new binn storing the structure on the stack +BOOL APIENTRY binn_create(binn *item, int type, int size, void *buffer); +BOOL APIENTRY binn_create_list(binn *list); +BOOL APIENTRY binn_create_map(binn *map); +BOOL APIENTRY binn_create_object(binn *object); + -+/* create a new binn as a copy from another */ -+binn * APIENTRY binn_copy(void *old); ++// create a new binn as a copy from another ++binn * APIENTRY binn_copy(const void *old); + + +BOOL APIENTRY binn_list_add_new(binn *list, binn *value); @@ -3838,20 +3882,20 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +BOOL APIENTRY binn_object_set_new(binn *obj, const char *key, binn *value); + + -+/* extended interface */ ++// extended interface + +BOOL APIENTRY binn_list_add(binn *list, int type, void *pvalue, int size); +BOOL APIENTRY binn_map_set(binn *map, int id, int type, void *pvalue, int size); +BOOL APIENTRY binn_object_set(binn *obj, const char *key, int type, void *pvalue, int size); + + -+/* release memory */ ++// release memory + +void APIENTRY binn_free(binn *item); -+void * APIENTRY binn_release(binn *item); /* free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later */ ++void * APIENTRY binn_release(binn *item); // free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later + + -+/* --- CREATING VALUES --------------------------------------------------- */ ++// --- CREATING VALUES --------------------------------------------------- + +binn * APIENTRY binn_value(int type, void *pvalue, int size, binn_mem_free freefn); + @@ -3899,22 +3943,22 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +} + + -+/* --- READ FUNCTIONS ------------------------------------------------------------- */ ++// --- READ FUNCTIONS ------------------------------------------------------------- + -+/* these functions accept pointer to the binn structure and pointer to the binn buffer */ -+void * APIENTRY binn_ptr(void *ptr); -+int APIENTRY binn_size(void *ptr); -+int APIENTRY binn_type(void *ptr); -+int APIENTRY binn_count(void *ptr); ++// these functions accept pointer to the binn structure and pointer to the binn buffer ++void * APIENTRY binn_ptr(const void *ptr); ++int APIENTRY binn_size(const void *ptr); ++int APIENTRY binn_type(const void *ptr); ++int APIENTRY binn_count(const void *ptr); + -+BOOL APIENTRY binn_is_valid(void *ptr, int *ptype, int *pcount, int *psize); ++BOOL APIENTRY binn_is_valid(const void *ptr, int *ptype, int *pcount, int *psize); +/* the function returns the values (type, count and size) and they don't need to be + initialized. these values are read from the buffer. example: + + int type, count, size; + result = binn_is_valid(ptr, &type, &count, &size); +*/ -+BOOL APIENTRY binn_is_valid_ex(void *ptr, int *ptype, int *pcount, int *psize); ++BOOL APIENTRY binn_is_valid_ex(const void *ptr, int *ptype, int *pcount, int *psize); +/* if some value is informed (type, count or size) then the function will check if + the value returned from the serialized data matches the informed value. otherwise + the values must be initialized to zero. example: @@ -3923,117 +3967,119 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + result = binn_is_valid_ex(ptr, &type, &count, &size); +*/ + -+BOOL APIENTRY binn_is_struct(void *ptr); ++BOOL APIENTRY binn_is_struct(const void *ptr); + + -+/* Loading a binn buffer into a binn value - this is optional */ ++// Loading a binn buffer into a binn value - this is optional + -+BOOL APIENTRY binn_load(void *data, binn *item); /* on stack */ -+binn * APIENTRY binn_open(void *data); /* allocated */ ++binn * APIENTRY binn_open(const void *data); // allocated - unsecure ++binn * APIENTRY binn_open_ex(const void *data, int size); // allocated - secure ++BOOL APIENTRY binn_load(const void *data, binn *item); // on stack - unsecure ++BOOL APIENTRY binn_load_ex(const void *data, int size, binn *value); // secure + + -+/* easiest interface to use, but don't check if the value is there */ ++// easiest interface to use, but don't check if the value is there + -+signed char APIENTRY binn_list_int8(void *list, int pos); -+short APIENTRY binn_list_int16(void *list, int pos); -+int APIENTRY binn_list_int32(void *list, int pos); -+int64 APIENTRY binn_list_int64(void *list, int pos); -+unsigned char APIENTRY binn_list_uint8(void *list, int pos); -+unsigned short APIENTRY binn_list_uint16(void *list, int pos); -+unsigned int APIENTRY binn_list_uint32(void *list, int pos); -+uint64 APIENTRY binn_list_uint64(void *list, int pos); -+float APIENTRY binn_list_float(void *list, int pos); -+double APIENTRY binn_list_double(void *list, int pos); -+BOOL APIENTRY binn_list_bool(void *list, int pos); -+BOOL APIENTRY binn_list_null(void *list, int pos); -+char * APIENTRY binn_list_str(void *list, int pos); -+void * APIENTRY binn_list_blob(void *list, int pos, int *psize); -+void * APIENTRY binn_list_list(void *list, int pos); -+void * APIENTRY binn_list_map(void *list, int pos); -+void * APIENTRY binn_list_object(void *list, int pos); ++signed char APIENTRY binn_list_int8(const void *list, int pos); ++short APIENTRY binn_list_int16(const void *list, int pos); ++int APIENTRY binn_list_int32(const void *list, int pos); ++int64 APIENTRY binn_list_int64(const void *list, int pos); ++unsigned char APIENTRY binn_list_uint8(const void *list, int pos); ++unsigned short APIENTRY binn_list_uint16(const void *list, int pos); ++unsigned int APIENTRY binn_list_uint32(const void *list, int pos); ++uint64 APIENTRY binn_list_uint64(const void *list, int pos); ++float APIENTRY binn_list_float(const void *list, int pos); ++double APIENTRY binn_list_double(const void *list, int pos); ++BOOL APIENTRY binn_list_bool(const void *list, int pos); ++BOOL APIENTRY binn_list_null(const void *list, int pos); ++char * APIENTRY binn_list_str(const void *list, int pos); ++void * APIENTRY binn_list_blob(const void *list, int pos, int *psize); ++void * APIENTRY binn_list_list(const void *list, int pos); ++void * APIENTRY binn_list_map(const void *list, int pos); ++void * APIENTRY binn_list_object(const void *list, int pos); + -+signed char APIENTRY binn_map_int8(void *map, int id); -+short APIENTRY binn_map_int16(void *map, int id); -+int APIENTRY binn_map_int32(void *map, int id); -+int64 APIENTRY binn_map_int64(void *map, int id); -+unsigned char APIENTRY binn_map_uint8(void *map, int id); -+unsigned short APIENTRY binn_map_uint16(void *map, int id); -+unsigned int APIENTRY binn_map_uint32(void *map, int id); -+uint64 APIENTRY binn_map_uint64(void *map, int id); -+float APIENTRY binn_map_float(void *map, int id); -+double APIENTRY binn_map_double(void *map, int id); -+BOOL APIENTRY binn_map_bool(void *map, int id); -+BOOL APIENTRY binn_map_null(void *map, int id); -+char * APIENTRY binn_map_str(void *map, int id); -+void * APIENTRY binn_map_blob(void *map, int id, int *psize); -+void * APIENTRY binn_map_list(void *map, int id); -+void * APIENTRY binn_map_map(void *map, int id); -+void * APIENTRY binn_map_object(void *map, int id); ++signed char APIENTRY binn_map_int8(const void *map, int id); ++short APIENTRY binn_map_int16(const void *map, int id); ++int APIENTRY binn_map_int32(const void *map, int id); ++int64 APIENTRY binn_map_int64(const void *map, int id); ++unsigned char APIENTRY binn_map_uint8(const void *map, int id); ++unsigned short APIENTRY binn_map_uint16(const void *map, int id); ++unsigned int APIENTRY binn_map_uint32(const void *map, int id); ++uint64 APIENTRY binn_map_uint64(const void *map, int id); ++float APIENTRY binn_map_float(const void *map, int id); ++double APIENTRY binn_map_double(const void *map, int id); ++BOOL APIENTRY binn_map_bool(const void *map, int id); ++BOOL APIENTRY binn_map_null(const void *map, int id); ++char * APIENTRY binn_map_str(const void *map, int id); ++void * APIENTRY binn_map_blob(const void *map, int id, int *psize); ++void * APIENTRY binn_map_list(const void *map, int id); ++void * APIENTRY binn_map_map(const void *map, int id); ++void * APIENTRY binn_map_object(const void *map, int id); + -+signed char APIENTRY binn_object_int8(void *obj, const char *key); -+short APIENTRY binn_object_int16(void *obj, const char *key); -+int APIENTRY binn_object_int32(void *obj, const char *key); -+int64 APIENTRY binn_object_int64(void *obj, const char *key); -+unsigned char APIENTRY binn_object_uint8(void *obj, const char *key); -+unsigned short APIENTRY binn_object_uint16(void *obj, const char *key); -+unsigned int APIENTRY binn_object_uint32(void *obj, const char *key); -+uint64 APIENTRY binn_object_uint64(void *obj, const char *key); -+float APIENTRY binn_object_float(void *obj, const char *key); -+double APIENTRY binn_object_double(void *obj, const char *key); -+BOOL APIENTRY binn_object_bool(void *obj, const char *key); -+BOOL APIENTRY binn_object_null(void *obj, const char *key); -+char * APIENTRY binn_object_str(void *obj, const char *key); -+void * APIENTRY binn_object_blob(void *obj, const char *key, int *psize); -+void * APIENTRY binn_object_list(void *obj, const char *key); -+void * APIENTRY binn_object_map(void *obj, const char *key); -+void * APIENTRY binn_object_object(void *obj, const char *key); ++signed char APIENTRY binn_object_int8(const void *obj, const char *key); ++short APIENTRY binn_object_int16(const void *obj, const char *key); ++int APIENTRY binn_object_int32(const void *obj, const char *key); ++int64 APIENTRY binn_object_int64(const void *obj, const char *key); ++unsigned char APIENTRY binn_object_uint8(const void *obj, const char *key); ++unsigned short APIENTRY binn_object_uint16(const void *obj, const char *key); ++unsigned int APIENTRY binn_object_uint32(const void *obj, const char *key); ++uint64 APIENTRY binn_object_uint64(const void *obj, const char *key); ++float APIENTRY binn_object_float(const void *obj, const char *key); ++double APIENTRY binn_object_double(const void *obj, const char *key); ++BOOL APIENTRY binn_object_bool(const void *obj, const char *key); ++BOOL APIENTRY binn_object_null(const void *obj, const char *key); ++char * APIENTRY binn_object_str(const void *obj, const char *key); ++void * APIENTRY binn_object_blob(const void *obj, const char *key, int *psize); ++void * APIENTRY binn_object_list(const void *obj, const char *key); ++void * APIENTRY binn_object_map(const void *obj, const char *key); ++void * APIENTRY binn_object_object(const void *obj, const char *key); + + -+/* return a pointer to an allocated binn structure - must be released with the free() function or equivalent set in binn_set_alloc_functions() */ -+binn * APIENTRY binn_list_value(void *list, int pos); -+binn * APIENTRY binn_map_value(void *map, int id); -+binn * APIENTRY binn_object_value(void *obj, const char *key); ++// return a pointer to an allocated binn structure - must be released with the free() function or equivalent set in binn_set_alloc_functions() ++binn * APIENTRY binn_list_value(const void *list, int pos); ++binn * APIENTRY binn_map_value(const void *map, int id); ++binn * APIENTRY binn_object_value(const void *obj, const char *key); + -+/* read the value to a binn structure on the stack */ -+BOOL APIENTRY binn_list_get_value(void* list, int pos, binn *value); -+BOOL APIENTRY binn_map_get_value(void* map, int id, binn *value); -+BOOL APIENTRY binn_object_get_value(void *obj, const char *key, binn *value); ++// read the value to a binn structure on the stack ++BOOL APIENTRY binn_list_get_value(const void *list, int pos, binn *value); ++BOOL APIENTRY binn_map_get_value(const void *map, int id, binn *value); ++BOOL APIENTRY binn_object_get_value(const void *obj, const char *key, binn *value); + -+/* single interface - these functions check the data type */ -+BOOL APIENTRY binn_list_get(void *list, int pos, int type, void *pvalue, int *psize); -+BOOL APIENTRY binn_map_get(void *map, int id, int type, void *pvalue, int *psize); -+BOOL APIENTRY binn_object_get(void *obj, const char *key, int type, void *pvalue, int *psize); ++// single interface - these functions check the data type ++BOOL APIENTRY binn_list_get(const void *list, int pos, int type, void *pvalue, int *psize); ++BOOL APIENTRY binn_map_get(const void *map, int id, int type, void *pvalue, int *psize); ++BOOL APIENTRY binn_object_get(const void *obj, const char *key, int type, void *pvalue, int *psize); + -+/* these 3 functions return a pointer to the value and the data type */ -+/* they are thread-safe on big-endian devices */ -+/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ -+/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ -+void * APIENTRY binn_list_read(void *list, int pos, int *ptype, int *psize); -+void * APIENTRY binn_map_read(void *map, int id, int *ptype, int *psize); -+void * APIENTRY binn_object_read(void *obj, const char *key, int *ptype, int *psize); ++// these 3 functions return a pointer to the value and the data type ++// they are thread-safe on big-endian devices ++// on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings ++// the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications ++void * APIENTRY binn_list_read(const void *list, int pos, int *ptype, int *psize); ++void * APIENTRY binn_map_read(const void *map, int id, int *ptype, int *psize); ++void * APIENTRY binn_object_read(const void *obj, const char *key, int *ptype, int *psize); + + -+/* READ PAIR FUNCTIONS */ ++// READ PAIR FUNCTIONS + -+/* these functions use base 1 in the 'pos' argument */ ++// these functions use base 1 in the 'pos' argument + -+/* on stack */ -+BOOL APIENTRY binn_map_get_pair(void *map, int pos, int *pid, binn *value); -+BOOL APIENTRY binn_object_get_pair(void *obj, int pos, char *pkey, binn *value); /* must free the memory returned in the pkey */ ++// on stack ++BOOL APIENTRY binn_map_get_pair(const void *map, int pos, int *pid, binn *value); ++BOOL APIENTRY binn_object_get_pair(const void *obj, int pos, char *pkey, binn *value); // the key must be declared as: char key[256]; + -+/* allocated */ -+binn * APIENTRY binn_map_pair(void *map, int pos, int *pid); -+binn * APIENTRY binn_object_pair(void *obj, int pos, char *pkey); /* must free the memory returned in the pkey */ ++// allocated ++binn * APIENTRY binn_map_pair(const void *map, int pos, int *pid); ++binn * APIENTRY binn_object_pair(const void *obj, int pos, char *pkey); // the key must be declared as: char key[256]; + -+/* these 2 functions return a pointer to the value and the data type */ -+/* they are thread-safe on big-endian devices */ -+/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ -+/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ -+void * APIENTRY binn_map_read_pair(void *ptr, int pos, int *pid, int *ptype, int *psize); -+void * APIENTRY binn_object_read_pair(void *ptr, int pos, char *pkey, int *ptype, int *psize); ++// these 2 functions return a pointer to the value and the data type ++// they are thread-safe on big-endian devices ++// on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings ++// the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications ++void * APIENTRY binn_map_read_pair(const void *ptr, int pos, int *pid, int *ptype, int *psize); ++void * APIENTRY binn_object_read_pair(const void *ptr, int pos, char *pkey, int *ptype, int *psize); + + -+/* SEQUENTIAL READ FUNCTIONS */ ++// SEQUENTIAL READ FUNCTIONS + +typedef struct binn_iter_struct { + unsigned char *pnext; @@ -4043,34 +4089,34 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + int current; +} binn_iter; + -+BOOL APIENTRY binn_iter_init(binn_iter *iter, void *pbuf, int type); ++BOOL APIENTRY binn_iter_init(binn_iter *iter, const void *pbuf, int type); + -+/* allocated */ ++// allocated +binn * APIENTRY binn_list_next_value(binn_iter *iter); +binn * APIENTRY binn_map_next_value(binn_iter *iter, int *pid); -+binn * APIENTRY binn_object_next_value(binn_iter *iter, char *pkey); /* the key must be declared as: char key[256]; */ ++binn * APIENTRY binn_object_next_value(binn_iter *iter, char *pkey); // the key must be declared as: char key[256]; + -+/* on stack */ ++// on stack +BOOL APIENTRY binn_list_next(binn_iter *iter, binn *value); +BOOL APIENTRY binn_map_next(binn_iter *iter, int *pid, binn *value); -+BOOL APIENTRY binn_object_next(binn_iter *iter, char *pkey, binn *value); /* the key must be declared as: char key[256]; */ ++BOOL APIENTRY binn_object_next(binn_iter *iter, char *pkey, binn *value); // the key must be declared as: char key[256]; + -+/* these 3 functions return a pointer to the value and the data type */ -+/* they are thread-safe on big-endian devices */ -+/* on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings */ -+/* the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications */ ++// these 3 functions return a pointer to the value and the data type ++// they are thread-safe on big-endian devices ++// on little-endian devices they are thread-safe only to return pointers to list, map, object, blob and strings ++// the returned pointer to 16, 32 and 64 bits values must be used only by single-threaded applications +void * APIENTRY binn_list_read_next(binn_iter *iter, int *ptype, int *psize); +void * APIENTRY binn_map_read_next(binn_iter *iter, int *pid, int *ptype, int *psize); -+void * APIENTRY binn_object_read_next(binn_iter *iter, char *pkey, int *ptype, int *psize); /* the key must be declared as: char key[256]; */ ++void * APIENTRY binn_object_read_next(binn_iter *iter, char *pkey, int *ptype, int *psize); // the key must be declared as: char key[256]; + + -+/* --- MACROS ------------------------------------------------------------ */ ++// --- MACROS ------------------------------------------------------------ + + +#define binn_is_writable(item) (item)->writable; + + -+/* set values on stack allocated binn structures */ ++// set values on stack allocated binn structures + +#define binn_set_null(item) do { (item)->type = BINN_NULL; } while (0) + @@ -4085,25 +4131,25 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +#define binn_set_float(item,value) do { (item)->type = BINN_FLOAT; (item)->vfloat = value; (item)->ptr = &((item)->vfloat); } while (0) +#define binn_set_double(item,value) do { (item)->type = BINN_DOUBLE; (item)->vdouble = value; (item)->ptr = &((item)->vdouble); } while (0) + -+/* #define binn_set_string(item,str,pfree) do { (item)->type = BINN_STRING; (item)->ptr = str; (item)->freefn = pfree; } while (0) */ -+/* #define binn_set_blob(item,ptr,size,pfree) do { (item)->type = BINN_BLOB; (item)->ptr = ptr; (item)->freefn = pfree; (item)->size = size; } while (0) */ ++//#define binn_set_string(item,str,pfree) do { (item)->type = BINN_STRING; (item)->ptr = str; (item)->freefn = pfree; } while (0) ++//#define binn_set_blob(item,ptr,size,pfree) do { (item)->type = BINN_BLOB; (item)->ptr = ptr; (item)->freefn = pfree; (item)->size = size; } while (0) +BOOL APIENTRY binn_set_string(binn *item, char *str, binn_mem_free pfree); +BOOL APIENTRY binn_set_blob(binn *item, void *ptr, int size, binn_mem_free pfree); + + -+/* #define binn_double(value) { (item)->type = BINN_DOUBLE; (item)->vdouble = value; (item)->ptr = &((item)->vdouble) } */ ++//#define binn_double(value) { (item)->type = BINN_DOUBLE; (item)->vdouble = value; (item)->ptr = &((item)->vdouble) } + + + -+/* FOREACH MACROS */ -+/* -------------- */ -+/* */ -+/* We must use these declarations inside the functions that will use the macros: */ -+/* */ -+/* binn_iter iter; */ -+/* binn value; */ -+/* char key[256]; // only for objects */ -+/* int id; // only for maps */ ++// FOREACH MACROS ++// -------------- ++// ++// We must use these declarations inside the functions that will use the macros: ++// ++// binn_iter iter; ++// binn value; ++// char key[256]; // only for objects ++// int id; // only for maps + +#define binn_object_foreach(object, key, value) \ + binn_iter_init(&iter, object, BINN_OBJECT); \ @@ -4117,11 +4163,11 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h + binn_iter_init(&iter, list, BINN_LIST); \ + while (binn_list_next(&iter, &value)) + -+/* If you need nested foreach loops, use the macros below for the nested loop */ -+/* Also we need to add an additional declaration on the function to hold the iterator */ -+/* We can add in the same line as the first iterator: */ -+/* */ -+/* binn_iter iter, iter2; */ ++// If you need nested foreach loops, use the macros below for the nested loop ++// Also we need to add an additional declaration on the function to hold the iterator ++// We can add in the same line as the first iterator: ++// ++// binn_iter iter, iter2; + +#define binn_object_foreach2(object, key, value) \ + binn_iter_init(&iter2, object, BINN_OBJECT); \ @@ -4313,157 +4359,157 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +/*** GET FUNCTIONS *******************************************************************/ +/*************************************************************************************/ + -+ALWAYS_INLINE BOOL binn_list_get_int8(void *list, int pos, signed char *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_int8(const void *list, int pos, signed char *pvalue) { + return binn_list_get(list, pos, BINN_INT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_int16(void *list, int pos, short *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_int16(const void *list, int pos, short *pvalue) { + return binn_list_get(list, pos, BINN_INT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_int32(void *list, int pos, int *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_int32(const void *list, int pos, int *pvalue) { + return binn_list_get(list, pos, BINN_INT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_int64(void *list, int pos, int64 *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_int64(const void *list, int pos, int64 *pvalue) { + return binn_list_get(list, pos, BINN_INT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_uint8(void *list, int pos, unsigned char *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_uint8(const void *list, int pos, unsigned char *pvalue) { + return binn_list_get(list, pos, BINN_UINT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_uint16(void *list, int pos, unsigned short *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_uint16(const void *list, int pos, unsigned short *pvalue) { + return binn_list_get(list, pos, BINN_UINT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_uint32(void *list, int pos, unsigned int *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_uint32(const void *list, int pos, unsigned int *pvalue) { + return binn_list_get(list, pos, BINN_UINT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_uint64(void *list, int pos, uint64 *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_uint64(const void *list, int pos, uint64 *pvalue) { + return binn_list_get(list, pos, BINN_UINT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_float(void *list, int pos, float *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_float(const void *list, int pos, float *pvalue) { + return binn_list_get(list, pos, BINN_FLOAT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_double(void *list, int pos, double *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_double(const void *list, int pos, double *pvalue) { + return binn_list_get(list, pos, BINN_FLOAT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_bool(void *list, int pos, BOOL *pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_bool(const void *list, int pos, BOOL *pvalue) { + return binn_list_get(list, pos, BINN_BOOL, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_str(void *list, int pos, char **pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_str(const void *list, int pos, char **pvalue) { + return binn_list_get(list, pos, BINN_STRING, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_blob(void *list, int pos, void **pvalue, int *psize) { ++ALWAYS_INLINE BOOL binn_list_get_blob(const void *list, int pos, void **pvalue, int *psize) { + return binn_list_get(list, pos, BINN_BLOB, pvalue, psize); +} -+ALWAYS_INLINE BOOL binn_list_get_list(void *list, int pos, void **pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_list(const void *list, int pos, void **pvalue) { + return binn_list_get(list, pos, BINN_LIST, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_map(void *list, int pos, void **pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_map(const void *list, int pos, void **pvalue) { + return binn_list_get(list, pos, BINN_MAP, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_list_get_object(void *list, int pos, void **pvalue) { ++ALWAYS_INLINE BOOL binn_list_get_object(const void *list, int pos, void **pvalue) { + return binn_list_get(list, pos, BINN_OBJECT, pvalue, NULL); +} + +/***************************************************************************/ + -+ALWAYS_INLINE BOOL binn_map_get_int8(void *map, int id, signed char *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_int8(const void *map, int id, signed char *pvalue) { + return binn_map_get(map, id, BINN_INT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_int16(void *map, int id, short *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_int16(const void *map, int id, short *pvalue) { + return binn_map_get(map, id, BINN_INT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_int32(void *map, int id, int *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_int32(const void *map, int id, int *pvalue) { + return binn_map_get(map, id, BINN_INT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_int64(void *map, int id, int64 *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_int64(const void *map, int id, int64 *pvalue) { + return binn_map_get(map, id, BINN_INT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_uint8(void *map, int id, unsigned char *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_uint8(const void *map, int id, unsigned char *pvalue) { + return binn_map_get(map, id, BINN_UINT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_uint16(void *map, int id, unsigned short *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_uint16(const void *map, int id, unsigned short *pvalue) { + return binn_map_get(map, id, BINN_UINT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_uint32(void *map, int id, unsigned int *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_uint32(const void *map, int id, unsigned int *pvalue) { + return binn_map_get(map, id, BINN_UINT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_uint64(void *map, int id, uint64 *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_uint64(const void *map, int id, uint64 *pvalue) { + return binn_map_get(map, id, BINN_UINT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_float(void *map, int id, float *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_float(const void *map, int id, float *pvalue) { + return binn_map_get(map, id, BINN_FLOAT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_double(void *map, int id, double *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_double(const void *map, int id, double *pvalue) { + return binn_map_get(map, id, BINN_FLOAT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_bool(void *map, int id, BOOL *pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_bool(const void *map, int id, BOOL *pvalue) { + return binn_map_get(map, id, BINN_BOOL, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_str(void *map, int id, char **pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_str(const void *map, int id, char **pvalue) { + return binn_map_get(map, id, BINN_STRING, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_blob(void *map, int id, void **pvalue, int *psize) { ++ALWAYS_INLINE BOOL binn_map_get_blob(const void *map, int id, void **pvalue, int *psize) { + return binn_map_get(map, id, BINN_BLOB, pvalue, psize); +} -+ALWAYS_INLINE BOOL binn_map_get_list(void *map, int id, void **pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_list(const void *map, int id, void **pvalue) { + return binn_map_get(map, id, BINN_LIST, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_map(void *map, int id, void **pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_map(const void *map, int id, void **pvalue) { + return binn_map_get(map, id, BINN_MAP, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_map_get_object(void *map, int id, void **pvalue) { ++ALWAYS_INLINE BOOL binn_map_get_object(const void *map, int id, void **pvalue) { + return binn_map_get(map, id, BINN_OBJECT, pvalue, NULL); +} + +/***************************************************************************/ + -+/* usage: */ -+/* if (binn_object_get_int32(obj, "key", &value) == FALSE) xxx; */ ++// usage: ++// if (binn_object_get_int32(obj, "key", &value) == FALSE) xxx; + -+ALWAYS_INLINE BOOL binn_object_get_int8(void *obj, const char *key, signed char *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_int8(const void *obj, const char *key, signed char *pvalue) { + return binn_object_get(obj, key, BINN_INT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_int16(void *obj, const char *key, short *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_int16(const void *obj, const char *key, short *pvalue) { + return binn_object_get(obj, key, BINN_INT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_int32(void *obj, const char *key, int *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_int32(const void *obj, const char *key, int *pvalue) { + return binn_object_get(obj, key, BINN_INT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_int64(void *obj, const char *key, int64 *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_int64(const void *obj, const char *key, int64 *pvalue) { + return binn_object_get(obj, key, BINN_INT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_uint8(void *obj, const char *key, unsigned char *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_uint8(const void *obj, const char *key, unsigned char *pvalue) { + return binn_object_get(obj, key, BINN_UINT8, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_uint16(void *obj, const char *key, unsigned short *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_uint16(const void *obj, const char *key, unsigned short *pvalue) { + return binn_object_get(obj, key, BINN_UINT16, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_uint32(void *obj, const char *key, unsigned int *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_uint32(const void *obj, const char *key, unsigned int *pvalue) { + return binn_object_get(obj, key, BINN_UINT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_uint64(void *obj, const char *key, uint64 *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_uint64(const void *obj, const char *key, uint64 *pvalue) { + return binn_object_get(obj, key, BINN_UINT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_float(void *obj, const char *key, float *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_float(const void *obj, const char *key, float *pvalue) { + return binn_object_get(obj, key, BINN_FLOAT32, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_double(void *obj, const char *key, double *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_double(const void *obj, const char *key, double *pvalue) { + return binn_object_get(obj, key, BINN_FLOAT64, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_bool(void *obj, const char *key, BOOL *pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_bool(const void *obj, const char *key, BOOL *pvalue) { + return binn_object_get(obj, key, BINN_BOOL, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_str(void *obj, const char *key, char **pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_str(const void *obj, const char *key, char **pvalue) { + return binn_object_get(obj, key, BINN_STRING, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_blob(void *obj, const char *key, void **pvalue, int *psize) { ++ALWAYS_INLINE BOOL binn_object_get_blob(const void *obj, const char *key, void **pvalue, int *psize) { + return binn_object_get(obj, key, BINN_BLOB, pvalue, psize); +} -+ALWAYS_INLINE BOOL binn_object_get_list(void *obj, const char *key, void **pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_list(const void *obj, const char *key, void **pvalue) { + return binn_object_get(obj, key, BINN_LIST, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_map(void *obj, const char *key, void **pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_map(const void *obj, const char *key, void **pvalue) { + return binn_object_get(obj, key, BINN_MAP, pvalue, NULL); +} -+ALWAYS_INLINE BOOL binn_object_get_object(void *obj, const char *key, void **pvalue) { ++ALWAYS_INLINE BOOL binn_object_get_object(const void *obj, const char *key, void **pvalue) { + return binn_object_get(obj, key, BINN_OBJECT, pvalue, NULL); +} + @@ -4475,24 +4521,24 @@ diff -Nur openssh-9.6p1.orig/binn.h openssh-9.6p1/binn.h +BOOL APIENTRY binn_get_bool(binn *value, BOOL *pbool); +char * APIENTRY binn_get_str(binn *value); + -+/* boolean string values: */ -+/* 1, true, yes, on */ -+/* 0, false, no, off */ ++// boolean string values: ++// 1, true, yes, on ++// 0, false, no, off + -+/* boolean number values: */ -+/* !=0 [true] */ -+/* ==0 [false] */ ++// boolean number values: ++// !=0 [true] ++// ==0 [false] + + +#ifdef __cplusplus +} +#endif + -+#endif /* BINN_H */ -diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c ---- openssh-9.6p1.orig/channels.c 2024-07-10 13:32:39.521111580 +0200 -+++ openssh-9.6p1/channels.c 2024-07-10 13:45:10.402355836 +0200 -@@ -104,6 +104,11 @@ ++#endif //BINN_H +diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c +--- openssh-9.8p1.orig/channels.c 2024-09-30 16:02:22.534024243 +0200 ++++ openssh-9.8p1/channels.c 2024-10-01 08:56:07.524893574 +0200 +@@ -97,6 +97,11 @@ /* Minimum port number for X11 forwarding */ #define X11_PORT_MIN 6000 @@ -4504,7 +4550,7 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c /* Per-channel callback for pre/post IO actions */ typedef void chan_fn(struct ssh *, Channel *c); -@@ -229,6 +234,9 @@ +@@ -225,6 +230,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -4514,17 +4560,24 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c /* -- channel core */ void -@@ -484,6 +492,9 @@ +@@ -519,6 +527,16 @@ (c->output = sshbuf_new()) == NULL || (c->extended = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); ++ ++ /* these buffers are important in terms of tracking channel ++ * buffer usage so label and type them with descriptive names */ + sshbuf_relabel(c->input, "channel input"); ++ sshbuf_type(c->input, BUF_CHANNEL_INPUT); + sshbuf_relabel(c->output, "channel output"); ++ sshbuf_type(c->output, BUF_CHANNEL_OUTPUT); + sshbuf_relabel(c->extended, "channel extended"); ++ sshbuf_type(c->extended, BUF_CHANNEL_EXTENDED); ++ if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) fatal_fr(r, "sshbuf_set_max_size"); c->ostate = CHAN_OUTPUT_OPEN; -@@ -495,6 +506,7 @@ +@@ -530,6 +548,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -4532,7 +4585,7 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1220,6 +1232,33 @@ +@@ -1255,6 +1274,33 @@ c->io_want = SSH_CHAN_IO_SOCK_W; } @@ -4566,45 +4619,19 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c) { -@@ -2321,24 +2360,55 @@ - { - int r; - -+ /* going back to a set denominator of 2. Prior versions had a -+ * dynamic denominator based on the size of the buffer. This may -+ * have been helpful in some situations but it isn't helping in -+ * the general case -cjr 6/30/23 */ - if (c->type == SSH_CHANNEL_OPEN && - !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && - ((c->local_window_max - c->local_window > +@@ -2362,18 +2408,29 @@ c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { -+ u_int addition = 0; ++ int addition = 0; + u_int32_t tcpwinsz = channel_tcpwinsz(ssh); + /* adjust max window size if we are in a dynamic environment + * and the tcp receive buffer is larger than the ssh window */ + if (c->dynamic_window && (tcpwinsz > c->local_window_max)) { -+ if (c->hpn_buffer_limit) { -+ /* limit window growth to prevent buffer issues -+ * still not sure what is causing the buffer issues -+ * but it may be an issue with c->local_consumed not being -+ * handled properly in the cases of bottenecked IO to the -+ * wfd endpoint. This does have an impact on throughput -+ * as we're essentially maxing out local_window_max to -+ * half of the window size */ -+ addition = (tcpwinsz/2 - c->local_window_max); -+ } -+ else { -+ /* aggressively grow the window */ -+ addition = tcpwinsz - c->local_window_max; -+ } ++ /* aggressively grow the window */ ++ addition = tcpwinsz - c->local_window_max; + c->local_window_max += addition; -+ /* doesn't look like we need these -+ * sshbuf_set_window_max(c->output, c->local_window_max); -+ * sshbuf_set_window_max(c->input, c->local_window_max); -+ */ -+ debug("Channel %d: Window growth to %d by %d bytes",c->self, ++ debug_f("Channel %d: Window growth to %d by %d bytes",c->self, + c->local_window_max, addition); + } if (!c->have_remote_id) @@ -4625,7 +4652,7 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c c->local_consumed = 0; } return 1; -@@ -2926,9 +2996,7 @@ +@@ -2959,9 +3016,7 @@ * in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) @@ -4636,7 +4663,7 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c else chan_ibuf_empty(ssh, c); } -@@ -3638,7 +3706,7 @@ +@@ -3670,7 +3725,7 @@ error_fr(r, "parse adjust"); ssh_packet_disconnect(ssh, "Invalid window adjust message"); } @@ -4645,7 +4672,7 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c if ((new_rwin = c->remote_window + adjust) < c->remote_window) { fatal("channel %d: adjust %u overflows remote window %u", c->self, adjust, c->remote_window); -@@ -3753,6 +3821,13 @@ +@@ -3785,6 +3840,13 @@ return addr; } @@ -4659,19 +4686,18 @@ diff -Nur openssh-9.6p1.orig/channels.c openssh-9.6p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -diff -Nur openssh-9.6p1.orig/channels.h openssh-9.6p1/channels.h ---- openssh-9.6p1.orig/channels.h 2024-07-10 13:32:39.484111470 +0200 -+++ openssh-9.6p1/channels.h 2024-07-10 13:34:02.710358565 +0200 -@@ -174,6 +174,8 @@ +diff -Nur openssh-9.8p1.orig/channels.h openssh-9.8p1/channels.h +--- openssh-9.8p1.orig/channels.h 2024-09-30 16:02:22.494024127 +0200 ++++ openssh-9.8p1/channels.h 2024-09-30 16:03:39.147245250 +0200 +@@ -173,6 +173,7 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; + int dynamic_window; -+ int hpn_buffer_limit; int extended_usage; int single_connection; -@@ -255,7 +257,7 @@ +@@ -254,7 +255,7 @@ #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) /* Read buffer size */ @@ -4680,16 +4706,16 @@ diff -Nur openssh-9.6p1.orig/channels.h openssh-9.6p1/channels.h /* Maximum size for direct reads to buffers */ #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -398,4 +400,6 @@ +@@ -396,4 +397,6 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); +/* hpn handler */ +void channel_set_hpn_disabled(int); #endif -diff -Nur openssh-9.6p1.orig/cipher.c openssh-9.6p1/cipher.c ---- openssh-9.6p1.orig/cipher.c 2024-07-10 13:32:39.541111639 +0200 -+++ openssh-9.6p1/cipher.c 2024-07-10 13:50:07.565252024 +0200 +diff -Nur openssh-9.8p1.orig/cipher.c openssh-9.8p1/cipher.c +--- openssh-9.8p1.orig/cipher.c 2024-09-30 16:02:22.556024306 +0200 ++++ openssh-9.8p1/cipher.c 2024-10-01 09:00:13.211602019 +0200 @@ -48,23 +48,39 @@ #include "sshbuf.h" #include "ssherr.h" @@ -4985,9 +5011,9 @@ diff -Nur openssh-9.6p1.orig/cipher.c openssh-9.6p1/cipher.c #endif freezero(cc, sizeof(*cc)); } -diff -Nur openssh-9.6p1.orig/cipher-chachapoly.c openssh-9.6p1/cipher-chachapoly.c ---- openssh-9.6p1.orig/cipher-chachapoly.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/cipher-chachapoly.c 2024-07-10 13:34:02.711358567 +0200 +diff -Nur openssh-9.8p1.orig/cipher-chachapoly.c openssh-9.8p1/cipher-chachapoly.c +--- openssh-9.8p1.orig/cipher-chachapoly.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/cipher-chachapoly.c 2024-09-30 16:03:39.149245256 +0200 @@ -88,7 +88,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5006,9 +5032,9 @@ diff -Nur openssh-9.6p1.orig/cipher-chachapoly.c openssh-9.6p1/cipher-chachapoly poly_key); } r = 0; -diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto.c openssh-9.6p1/cipher-chachapoly-libcrypto.c ---- openssh-9.6p1.orig/cipher-chachapoly-libcrypto.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/cipher-chachapoly-libcrypto.c 2024-07-10 13:34:02.711358567 +0200 +diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto.c openssh-9.8p1/cipher-chachapoly-libcrypto.c +--- openssh-9.8p1.orig/cipher-chachapoly-libcrypto.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/cipher-chachapoly-libcrypto.c 2024-10-01 09:02:21.651972382 +0200 @@ -34,8 +34,17 @@ #include "ssherr.h" #include "cipher-chachapoly.h" @@ -5071,9 +5097,9 @@ diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto.c openssh-9.6p1/cipher- poly_key); } r = 0; -diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.6p1/cipher-chachapoly-libcrypto-mt.c ---- openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-chachapoly-libcrypto-mt.c 2024-07-10 13:34:02.712358571 +0200 +diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.8p1/cipher-chachapoly-libcrypto-mt.c +--- openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-chachapoly-libcrypto-mt.c 2024-09-30 16:03:39.149245256 +0200 @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5770,9 +5796,9 @@ diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.6p1/ciph +#endif +} +#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */ -diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.6p1/cipher-chachapoly-libcrypto-mt.h ---- openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-chachapoly-libcrypto-mt.h 2024-07-10 13:34:02.712358571 +0200 +diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.8p1/cipher-chachapoly-libcrypto-mt.h +--- openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-chachapoly-libcrypto-mt.h 2024-09-30 16:03:39.149245256 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5819,9 +5845,9 @@ diff -Nur openssh-9.6p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.6p1/ciph + __attribute__((__bounded__(__buffer__, 4, 5))); + +#endif /* CHACHA_POLY_LIBCRYPTO_MT_H */ -diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c ---- openssh-9.6p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-ctr-mt.c 2024-07-10 13:58:24.488736203 +0200 +diff -Nur openssh-9.8p1.orig/cipher-ctr-mt.c openssh-9.8p1/cipher-ctr-mt.c +--- openssh-9.8p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-ctr-mt.c 2024-09-30 16:03:39.150245259 +0200 @@ -0,0 +1,677 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -5896,8 +5922,8 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c + +/*-------------------- TUNABLES --------------------*/ +/* maximum number of threads and queues */ -+#define MAX_THREADS 4 -+#define MAX_NUMKQ (MAX_THREADS + 1) ++#define MAX_THREADS 4 ++#define MAX_NUMKQ (MAX_THREADS + 1) + +/* Number of pregen threads to use */ +/* this is a default value. The actual number is @@ -5934,9 +5960,9 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c +#endif +/*-------------------- END TUNABLES --------------------*/ + -+#define HAVE_NONE 0 -+#define HAVE_KEY 1 -+#define HAVE_IV 2 ++#define HAVE_NONE 0 ++#define HAVE_KEY 1 ++#define HAVE_IV 2 +int X = 0; + +const EVP_CIPHER *evp_aes_ctr_mt(void); @@ -5954,24 +5980,24 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c +struct kq { + u_char keys[KQLEN][AES_BLOCK_SIZE]; /* [32768][16B] */ + u_char ctr[AES_BLOCK_SIZE]; /* 16B */ -+ u_char pad0[CACHELINE_LEN]; ++ u_char pad0[CACHELINE_LEN]; + pthread_mutex_t lock; + pthread_cond_t cond; -+ int qstate; -+ u_char pad1[CACHELINE_LEN]; ++ int qstate; ++ u_char pad1[CACHELINE_LEN]; +}; + +/* Context struct */ +struct ssh_aes_ctr_ctx_mt +{ + long unsigned int struct_id; -+ int keylen; ++ int keylen; + int state; + int qidx; + int ridx; -+ int id[MAX_THREADS]; /* 32 */ -+ AES_KEY aes_key; -+ const u_char *orig_key; ++ int id[MAX_THREADS]; /* 32 */ ++ AES_KEY aes_key; ++ const u_char *orig_key; + u_char aes_counter[AES_BLOCK_SIZE]; /* 16B */ + pthread_t tid[MAX_THREADS]; /* 32 */ + pthread_rwlock_t tid_lock; @@ -5987,7 +6013,7 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c + * free the contexts in stop_and_prejoin + */ +struct aes_mt_ctx_ptrs { -+ pthread_t tid; ++ pthread_t tid; + EVP_CIPHER_CTX *pointer; /* 32 */ + UT_hash_handle hh; +}; @@ -6500,9 +6526,9 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt.c openssh-9.6p1/cipher-ctr-mt.c + return aes_ctr; +} +#endif /* OSSL Check */ -diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.c openssh-9.6p1/cipher-ctr-mt-functions.c ---- openssh-9.6p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-ctr-mt-functions.c 2024-07-10 13:34:02.713358574 +0200 +diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.c openssh-9.8p1/cipher-ctr-mt-functions.c +--- openssh-9.8p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-ctr-mt-functions.c 2024-09-30 16:03:39.150245259 +0200 @@ -0,0 +1,668 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7172,9 +7198,9 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.c openssh-9.6p1/cipher-ctr- +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.h openssh-9.6p1/cipher-ctr-mt-functions.h ---- openssh-9.6p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-ctr-mt-functions.h 2024-07-10 13:34:02.714358576 +0200 +diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.h openssh-9.8p1/cipher-ctr-mt-functions.h +--- openssh-9.8p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-ctr-mt-functions.h 2024-09-30 16:03:39.150245259 +0200 @@ -0,0 +1,142 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7318,9 +7344,9 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-functions.h openssh-9.6p1/cipher-ctr- + +#endif /* WITH OPENSSL */ +#endif /* CTR_MT_FUNCS */ -diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-provider.c openssh-9.6p1/cipher-ctr-mt-provider.c ---- openssh-9.6p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-ctr-mt-provider.c 2024-07-10 13:34:02.714358576 +0200 +diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-provider.c openssh-9.8p1/cipher-ctr-mt-provider.c +--- openssh-9.8p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-ctr-mt-provider.c 2024-09-30 16:03:39.151245261 +0200 @@ -0,0 +1,390 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7712,9 +7738,9 @@ diff -Nur openssh-9.6p1.orig/cipher-ctr-mt-provider.c openssh-9.6p1/cipher-ctr-m +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.6p1.orig/cipher.h openssh-9.6p1/cipher.h ---- openssh-9.6p1.orig/cipher.h 2024-07-10 13:32:39.541111639 +0200 -+++ openssh-9.6p1/cipher.h 2024-07-10 13:34:02.714358576 +0200 +diff -Nur openssh-9.8p1.orig/cipher.h openssh-9.8p1/cipher.h +--- openssh-9.8p1.orig/cipher.h 2024-09-30 16:02:22.556024306 +0200 ++++ openssh-9.8p1/cipher.h 2024-09-30 16:26:15.533157716 +0200 @@ -42,11 +42,17 @@ #include #endif @@ -7771,9 +7797,9 @@ diff -Nur openssh-9.6p1.orig/cipher.h openssh-9.6p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-9.6p1.orig/cipher-switch.c openssh-9.6p1/cipher-switch.c ---- openssh-9.6p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-switch.c 2024-07-10 13:34:02.715358579 +0200 +diff -Nur openssh-9.8p1.orig/cipher-switch.c openssh-9.8p1/cipher-switch.c +--- openssh-9.8p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-switch.c 2024-09-30 16:03:39.151245261 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -7848,9 +7874,9 @@ diff -Nur openssh-9.6p1.orig/cipher-switch.c openssh-9.6p1/cipher-switch.c + } +#endif +} -diff -Nur openssh-9.6p1.orig/cipher-switch.h openssh-9.6p1/cipher-switch.h ---- openssh-9.6p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/cipher-switch.h 2024-07-10 13:34:02.715358579 +0200 +diff -Nur openssh-9.8p1.orig/cipher-switch.h openssh-9.8p1/cipher-switch.h +--- openssh-9.8p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/cipher-switch.h 2024-09-30 16:03:39.152245264 +0200 @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 The Board of Trustees of Carnegie Mellon University. @@ -7870,9 +7896,9 @@ diff -Nur openssh-9.6p1.orig/cipher-switch.h openssh-9.6p1/cipher-switch.h + */ + +void cipher_switch (struct ssh *); -diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c ---- openssh-9.6p1.orig/clientloop.c 2024-07-10 13:32:39.581111758 +0200 -+++ openssh-9.6p1/clientloop.c 2024-07-10 13:34:02.716358582 +0200 +diff -Nur openssh-9.8p1.orig/clientloop.c openssh-9.8p1/clientloop.c +--- openssh-9.8p1.orig/clientloop.c 2024-09-30 16:02:22.434023954 +0200 ++++ openssh-9.8p1/clientloop.c 2024-09-30 16:03:39.153245267 +0200 @@ -114,6 +114,7 @@ #include "msg.h" #include "ssherr.h" @@ -7881,7 +7907,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -172,6 +173,10 @@ +@@ -171,6 +172,10 @@ static void client_init_dispatch(struct ssh *ssh); int session_ident = -1; @@ -7892,25 +7918,24 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c /* Track escape per proto2 channel */ struct escape_filter_ctx { -@@ -199,6 +204,9 @@ +@@ -197,6 +202,8 @@ + static struct global_confirms global_confirms = TAILQ_HEAD_INITIALIZER(global_confirms); - void ssh_process_session2_setup(int, int, int, struct sshbuf *); -+ +void client_request_metrics(struct ssh *); + static void quit_message(const char *fmt, ...) __attribute__((__format__ (printf, 1, 2))); -@@ -1453,6 +1461,7 @@ +@@ -1452,6 +1459,7 @@ double start_time, total_time; - int channel_did_enqueue = 0, r, len; + int channel_did_enqueue = 0, r; u_int64_t ibytes, obytes; + time_t previous_time; int conn_in_ready, conn_out_ready; sigset_t bsigset, osigset; -@@ -1494,6 +1503,7 @@ +@@ -1493,6 +1501,7 @@ client_repledge(); start_time = monotime_double(); @@ -7918,7 +7943,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c /* Initialize variables. */ last_was_cr = 1; -@@ -1539,6 +1549,8 @@ +@@ -1534,6 +1543,8 @@ } schedule_server_alive_check(); @@ -7927,7 +7952,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGHUP) == -1 || -@@ -1549,6 +1561,12 @@ +@@ -1544,6 +1555,12 @@ /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { @@ -7940,7 +7965,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c channel_did_enqueue = 0; /* Process buffered packets sent by the server. */ -@@ -1641,6 +1659,10 @@ +@@ -1636,6 +1653,10 @@ } } } @@ -7951,7 +7976,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c free(pfd); /* Terminate the session. */ -@@ -2684,6 +2706,167 @@ +@@ -2647,6 +2668,167 @@ return 1; } @@ -8026,7 +8051,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c + kernel_version = binn_object_int32((void *)blob, "kernel_version"); + + /* create a string of the data from the binn object blob */ -+ metrics_read_binn_object((void *)blob, &metricsstring); ++ metrics_read_binn_object((void *)blob, metricsstring); + + /* have we printed the header? */ + if (metrics_hdr_remote_flag == 0) { @@ -8071,7 +8096,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c + metrics_write_binn_object(&local_tcp_info, metricsobj); + + /* create a string of the data from the binn object metricsobj */ -+ metrics_read_binn_object((void *)metricsobj, &metricsstring); ++ metrics_read_binn_object((void *)metricsobj, metricsstring); + + /* get the kernel version printing the header */ + kernel_version = binn_object_int32(metricsobj, "kernel_version"); @@ -8119,19 +8144,7 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c static int client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) { -@@ -2739,6 +2922,11 @@ - if ((c = channel_lookup(ssh, id)) == NULL) - fatal_f("channel %d: unknown channel", id); - -+ if (options.hpn_buffer_limit) { -+ debug_f("Limiting receive buffer size"); -+ c->hpn_buffer_limit = 1; -+ } -+ - ssh_packet_set_interactive(ssh, want_tty, - options.ip_qos_interactive, options.ip_qos_bulk); - -@@ -2809,6 +2997,43 @@ +@@ -2772,6 +2954,43 @@ len = sshbuf_len(cmd); if (len > 0) { @@ -8175,9 +8188,9 @@ diff -Nur openssh-9.6p1.orig/clientloop.c openssh-9.6p1/clientloop.c if (len > 900) len = 900; if (want_subsystem) { -diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c ---- openssh-9.6p1.orig/compat.c 2024-07-10 13:32:39.574111737 +0200 -+++ openssh-9.6p1/compat.c 2024-07-14 11:29:56.093866627 +0200 +diff -Nur openssh-9.8p1.orig/compat.c openssh-9.8p1/compat.c +--- openssh-9.8p1.orig/compat.c 2024-09-30 16:02:22.594024416 +0200 ++++ openssh-9.8p1/compat.c 2024-10-01 09:15:43.262288236 +0200 @@ -135,6 +135,35 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) @@ -8214,9 +8227,9 @@ diff -Nur openssh-9.6p1.orig/compat.c openssh-9.6p1/compat.c return; } } -diff -Nur openssh-9.6p1.orig/compat.h openssh-9.6p1/compat.h ---- openssh-9.6p1.orig/compat.h 2024-07-10 13:32:39.574111737 +0200 -+++ openssh-9.6p1/compat.h 2024-07-14 11:29:56.093866627 +0200 +diff -Nur openssh-9.8p1.orig/compat.h openssh-9.8p1/compat.h +--- openssh-9.8p1.orig/compat.h 2024-09-30 16:02:22.594024416 +0200 ++++ openssh-9.8p1/compat.h 2024-10-01 09:16:03.734347588 +0200 @@ -46,12 +46,12 @@ /* #define unused 0x00010000 */ /* #define unused 0x00020000 */ @@ -8233,10 +8246,10 @@ diff -Nur openssh-9.6p1.orig/compat.h openssh-9.6p1/compat.h #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 -diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac ---- openssh-9.6p1.orig/configure.ac 2024-07-10 13:32:39.595111799 +0200 -+++ openssh-9.6p1/configure.ac 2024-07-10 13:34:02.718358588 +0200 -@@ -2909,8 +2909,8 @@ +diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac +--- openssh-9.8p1.orig/configure.ac 2024-09-30 16:02:22.614024473 +0200 ++++ openssh-9.8p1/configure.ac 2024-09-30 16:03:39.155245273 +0200 +@@ -2936,8 +2936,8 @@ 200*) # LibreSSL lver=`echo "$sslver" | sed 's/.*libressl-//'` case "$lver" in @@ -8247,20 +8260,15 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac ;; *) ;; # Assume all other versions are good. esac -@@ -2918,10 +2918,12 @@ - 300*) +@@ -2946,6 +2946,7 @@ # OpenSSL 3; we use the 1.1x API - CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" -+ AC_DEFINE([WITH_OPENSSL3], [1], [With OpenSSL3]) - ;; - 301*|302*|303*) - # OpenSSL development branch; request 1.1x API + # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" + AC_DEFINE([WITH_OPENSSL3], [1], [With OpenSSL3]) ;; *) AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_showver")]) -@@ -3039,6 +3041,30 @@ +@@ -3063,6 +3064,30 @@ EVP_CIPHER_CTX_set_iv \ ]) @@ -8291,9 +8299,9 @@ diff -Nur openssh-9.6p1.orig/configure.ac openssh-9.6p1/configure.ac if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -diff -Nur openssh-9.6p1.orig/defines.h openssh-9.6p1/defines.h ---- openssh-9.6p1.orig/defines.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/defines.h 2024-07-10 13:34:02.718358588 +0200 +diff -Nur openssh-9.8p1.orig/defines.h openssh-9.8p1/defines.h +--- openssh-9.8p1.orig/defines.h 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/defines.h 2024-09-30 16:03:39.155245273 +0200 @@ -889,7 +889,7 @@ #endif @@ -8303,9 +8311,9 @@ diff -Nur openssh-9.6p1.orig/defines.h openssh-9.6p1/defines.h #endif /* -diff -Nur openssh-9.6p1.orig/digest.h openssh-9.6p1/digest.h ---- openssh-9.6p1.orig/digest.h 2024-07-10 13:32:39.511111550 +0200 -+++ openssh-9.6p1/digest.h 2024-07-10 13:34:02.719358591 +0200 +diff -Nur openssh-9.8p1.orig/digest.h openssh-9.8p1/digest.h +--- openssh-9.8p1.orig/digest.h 2024-09-30 16:02:22.523024211 +0200 ++++ openssh-9.8p1/digest.h 2024-09-30 16:03:39.156245276 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -8316,9 +8324,9 @@ diff -Nur openssh-9.6p1.orig/digest.h openssh-9.6p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-9.6p1.orig/digest-openssl.c openssh-9.6p1/digest-openssl.c ---- openssh-9.6p1.orig/digest-openssl.c 2024-07-10 13:32:39.511111550 +0200 -+++ openssh-9.6p1/digest-openssl.c 2024-07-10 13:34:02.719358591 +0200 +diff -Nur openssh-9.8p1.orig/digest-openssl.c openssh-9.8p1/digest-openssl.c +--- openssh-9.8p1.orig/digest-openssl.c 2024-09-30 16:02:22.523024211 +0200 ++++ openssh-9.8p1/digest-openssl.c 2024-09-30 16:03:39.156245276 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -8327,9 +8335,9 @@ diff -Nur openssh-9.6p1.orig/digest-openssl.c openssh-9.6p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-9.6p1.orig/FUNDING.yml openssh-9.6p1/FUNDING.yml ---- openssh-9.6p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/FUNDING.yml 2024-07-10 13:34:02.719358591 +0200 +diff -Nur openssh-9.8p1.orig/FUNDING.yml openssh-9.8p1/FUNDING.yml +--- openssh-9.8p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/FUNDING.yml 2024-09-30 16:03:39.156245276 +0200 @@ -0,0 +1,12 @@ +# These are supported funding model platforms + @@ -8343,9 +8351,9 @@ diff -Nur openssh-9.6p1.orig/FUNDING.yml openssh-9.6p1/FUNDING.yml +#issuehunt: # Replace with a single IssueHunt username +#otechie: # Replace with a single Otechie username +#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -diff -Nur openssh-9.6p1.orig/HPN-README openssh-9.6p1/HPN-README ---- openssh-9.6p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/HPN-README 2024-07-10 13:34:02.719358591 +0200 +diff -Nur openssh-9.8p1.orig/HPN-README openssh-9.8p1/HPN-README +--- openssh-9.8p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/HPN-README 2024-09-30 16:03:39.156245276 +0200 @@ -0,0 +1,170 @@ +Notes: + @@ -8517,9 +8525,9 @@ diff -Nur openssh-9.6p1.orig/HPN-README openssh-9.6p1/HPN-README + + +Edited: October 11, 2023 -diff -Nur openssh-9.6p1.orig/HPNSSHInstallation.txt openssh-9.6p1/HPNSSHInstallation.txt ---- openssh-9.6p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/HPNSSHInstallation.txt 2024-07-10 13:34:02.720358594 +0200 +diff -Nur openssh-9.8p1.orig/HPNSSHInstallation.txt openssh-9.8p1/HPNSSHInstallation.txt +--- openssh-9.8p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/HPNSSHInstallation.txt 2024-09-30 16:03:39.156245276 +0200 @@ -0,0 +1,354 @@ +HPN-SSH Installation + @@ -8875,10 +8883,10 @@ diff -Nur openssh-9.6p1.orig/HPNSSHInstallation.txt openssh-9.6p1/HPNSSHInstalla +restorecon /usr/bin/hpnssh-agent +restorecon /usr/bin/hpnssh-keygen +restorecon /etc/pam.d/hpnsshd -diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c ---- openssh-9.6p1.orig/kex.c 2024-07-10 13:32:39.570111725 +0200 -+++ openssh-9.6p1/kex.c 2024-07-10 13:34:02.720358594 +0200 -@@ -65,6 +65,7 @@ +diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c +--- openssh-9.8p1.orig/kex.c 2024-09-30 16:02:22.589024401 +0200 ++++ openssh-9.8p1/kex.c 2024-09-30 16:03:39.157245279 +0200 +@@ -66,6 +66,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -8886,7 +8894,7 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c #include "digest.h" #include "xmalloc.h" #include "audit.h" -@@ -1037,11 +1038,68 @@ +@@ -774,17 +775,83 @@ free(kex); } @@ -8937,9 +8945,12 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c int kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) { - int r; - +- int r; ++ int r = 0; ++ +#ifdef WITH_OPENSSL ++ char * orig_ctos = proposal[PROPOSAL_ENC_ALGS_CTOS]; ++ char * orig_stoc = proposal[PROPOSAL_ENC_ALGS_STOC]; + proposal[PROPOSAL_ENC_ALGS_CTOS] = + patch_list(proposal[PROPOSAL_ENC_ALGS_CTOS]); + proposal[PROPOSAL_ENC_ALGS_STOC] = @@ -8951,11 +8962,26 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c + * freeable. + */ +#endif -+ + if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0) - return r; +- return r; ++ goto restoreProposal; ssh->kex->flags = KEX_INITIAL; -@@ -1240,6 +1298,11 @@ + kex_reset_dispatch(ssh); + ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); +- return 0; ++ restoreProposal: ++#ifdef WITH_OPENSSL ++ free(proposal[PROPOSAL_ENC_ALGS_CTOS]); ++ free(proposal[PROPOSAL_ENC_ALGS_STOC]); ++ proposal[PROPOSAL_ENC_ALGS_CTOS] = orig_ctos; ++ proposal[PROPOSAL_ENC_ALGS_STOC] = orig_stoc; ++#endif ++ return r; + } + + int +@@ -975,6 +1042,11 @@ int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; @@ -8967,7 +8993,7 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) -@@ -1316,6 +1379,31 @@ +@@ -1051,6 +1123,31 @@ peer[nenc] = NULL; goto out; } @@ -8999,7 +9025,7 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c authlen = cipher_authlen(newkeys->enc.cipher); /* ignore mac for authenticated encryption */ if (authlen == 0 && -@@ -1331,11 +1419,43 @@ +@@ -1066,11 +1163,43 @@ peer[ncomp] = NULL; goto out; } @@ -9043,7 +9069,7 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { -@@ -1683,7 +1803,7 @@ +@@ -1430,7 +1559,7 @@ if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", @@ -9052,7 +9078,7 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c version_addendum == NULL ? "" : " ", version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; -@@ -1819,9 +1939,24 @@ +@@ -1566,9 +1695,24 @@ r = SSH_ERR_INVALID_FORMAT; goto out; } @@ -9077,9 +9103,9 @@ diff -Nur openssh-9.6p1.orig/kex.c openssh-9.6p1/kex.c mismatch = 0; switch (remote_major) { -diff -Nur openssh-9.6p1.orig/mac.c openssh-9.6p1/mac.c ---- openssh-9.6p1.orig/mac.c 2024-07-10 13:32:39.542111642 +0200 -+++ openssh-9.6p1/mac.c 2024-07-10 13:34:02.720358594 +0200 +diff -Nur openssh-9.8p1.orig/mac.c openssh-9.8p1/mac.c +--- openssh-9.8p1.orig/mac.c 2024-09-30 16:02:22.557024309 +0200 ++++ openssh-9.8p1/mac.c 2024-09-30 16:03:39.158245282 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -9088,10 +9114,10 @@ diff -Nur openssh-9.6p1.orig/mac.c openssh-9.6p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in ---- openssh-9.6p1.orig/Makefile.in 2024-07-10 13:32:39.597111805 +0200 -+++ openssh-9.6p1/Makefile.in 2024-07-10 13:34:02.721358597 +0200 -@@ -49,7 +49,7 @@ +diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in +--- openssh-9.8p1.orig/Makefile.in 2024-09-30 16:02:22.616024479 +0200 ++++ openssh-9.8p1/Makefile.in 2024-10-01 09:22:44.089508215 +0200 +@@ -51,7 +51,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ @@ -9100,7 +9126,7 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ -@@ -97,7 +97,7 @@ +@@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ @@ -9109,15 +9135,15 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -@@ -107,6 +107,7 @@ +@@ -109,6 +109,7 @@ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + cipher-chachapoly-libcrypto-mt.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ -@@ -114,12 +115,13 @@ + kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +@@ -116,12 +117,13 @@ kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ @@ -9131,10 +9157,10 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in - sshconnect.o sshconnect2.o mux.o $(SKOBJS) + sshconnect.o sshconnect2.o mux.o cipher-switch.o $(SKOBJS) - SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ - audit.o audit-bsm.o audit-linux.o platform.o \ -@@ -135,7 +137,7 @@ - srclimit.o sftp-server.o sftp-common.o \ + SSHDOBJS=sshd.o \ + platform-listen.o \ +@@ -143,7 +145,7 @@ + sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o uidswap.o $(SKOBJS) @@ -9142,8 +9168,8 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o -@@ -214,7 +216,7 @@ - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) +@@ -225,7 +227,7 @@ + $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) - $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -9151,9 +9177,9 @@ diff -Nur openssh-9.6p1.orig/Makefile.in openssh-9.6p1/Makefile.in ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) -diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c ---- openssh-9.6p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/metrics.c 2024-07-10 13:34:02.721358597 +0200 +diff -Nur openssh-9.8p1.orig/metrics.c openssh-9.8p1/metrics.c +--- openssh-9.8p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/metrics.c 2024-09-30 16:03:39.159245285 +0200 @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9410,7 +9436,7 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + * the object will not necessarily have all of the elements. If it's empty it + * current just spits out 0. This isn't optimal as 0 can also be a valid value */ +void -+metrics_read_binn_object (void *binnobj, char **output) { ++metrics_read_binn_object (void *binnobj, char *output) { + int len = 0; + int buflen = 1023; + int kernel_version = 0; @@ -9421,7 +9447,7 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + kernel_version = binn_object_uint32(binnobj, "kernel_version"); + + /* base set of metrics */ -+ len = snprintf(*output, buflen, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", ++ len = snprintf(output, buflen, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", + binn_object_uint8(binnobj, "tcpi_state"), + binn_object_uint8(binnobj, "tcpi_ca_state"), + binn_object_uint8(binnobj, "tcpi_retransmits"), @@ -9462,28 +9488,28 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + * the remote kernel version. Only necessary under linux*/ +#ifdef __linux__ + if (kernel_version >= KERNEL_VERSION(3,15,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %llu, %llu", ++ len += snprintf(output+len, (buflen-len), ", %llu, %llu", + binn_object_uint64(binnobj, "tcpi_max_pacing_rate"), + binn_object_uint64(binnobj, "tcpi_pacing_rate") + ); + } + + if (kernel_version >= KERNEL_VERSION(4,1,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %llu, %llu", ++ len += snprintf(output+len, (buflen-len), ", %llu, %llu", + binn_object_uint64(binnobj, "tcpi_bytes_acked"), + binn_object_uint64(binnobj, "tcpi_bytes_received") + ); + } + + if (kernel_version >= KERNEL_VERSION(4,2,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ len += snprintf(output+len, (buflen-len), ", %d, %d", + binn_object_uint32(binnobj, "tcpi_segs_in"), + binn_object_uint32(binnobj, "tcpi_segs_out") + ); + } + + if (kernel_version >= KERNEL_VERSION(4,6,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d, %d, %d, %d", ++ len += snprintf(output+len, (buflen-len), ", %d, %d, %d, %d", + binn_object_uint32(binnobj, "tcpi_notsent_bytes"), + binn_object_uint32(binnobj, "tcpi_min_rtt"), + binn_object_uint32(binnobj, "tcpi_data_segs_in"), @@ -9492,14 +9518,14 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + } + + if (kernel_version >= KERNEL_VERSION(4,9,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d, %llu", ++ len += snprintf(output+len, (buflen-len), ", %d, %llu", + binn_object_uint8(binnobj, "tcpi_delivery_rate_app_limited"), + binn_object_uint64(binnobj, "tcpi_delivery_rate") + ); + } + + if (kernel_version >= KERNEL_VERSION(4,10,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %llu, %llu, %llu", ++ len += snprintf(output+len, (buflen-len), ", %llu, %llu, %llu", + binn_object_uint64(binnobj, "tcpi_busy_time"), + binn_object_uint64(binnobj, "tcpi_sndbuf_limited"), + binn_object_uint64(binnobj, "tcpi_rwnd_limited") @@ -9507,14 +9533,14 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + } + + if (kernel_version >= KERNEL_VERSION(4,18,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ len += snprintf(output+len, (buflen-len), ", %d, %d", + binn_object_uint32(binnobj, "tcpi_delivered"), + binn_object_uint32(binnobj, "tcpi_delivered_ce") + ); + } + + if (kernel_version >= KERNEL_VERSION(4,19,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %llu, %llu, %d, %d", ++ len += snprintf(output+len, (buflen-len), ", %llu, %llu, %d, %d", + binn_object_uint64(binnobj, "tcpi_bytes_sent"), + binn_object_uint64(binnobj, "tcpi_bytes_retrans"), + binn_object_uint32(binnobj, "tcpi_dsack_dups"), @@ -9523,14 +9549,14 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c + } + + if (kernel_version >= KERNEL_VERSION(5,4,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d, %d", ++ len += snprintf(output+len, (buflen-len), ", %d, %d", + binn_object_uint32(binnobj, "tcpi_snd_wnd"), + binn_object_uint32(binnobj, "tcpi_rcv_ooopack") + ); + } + + if (kernel_version >= KERNEL_VERSION(5,5,0)) { -+ len += snprintf(*output+len, (buflen-len), ", %d", ++ len += snprintf(output+len, (buflen-len), ", %d", + binn_object_uint8(binnobj, "tcpi_fastopen_client_fail") + ); + } @@ -9599,9 +9625,9 @@ diff -Nur openssh-9.6p1.orig/metrics.c openssh-9.6p1/metrics.c +#endif /* ifdef __linux__ */ + fprintf(fptr, "\n\n"); +} -diff -Nur openssh-9.6p1.orig/metrics.h openssh-9.6p1/metrics.h ---- openssh-9.6p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/metrics.h 2024-07-10 13:34:02.721358597 +0200 +diff -Nur openssh-9.8p1.orig/metrics.h openssh-9.8p1/metrics.h +--- openssh-9.8p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/metrics.h 2024-09-30 16:03:39.159245285 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9643,14 +9669,14 @@ diff -Nur openssh-9.6p1.orig/metrics.h openssh-9.6p1/metrics.h +#endif + +void metrics_write_binn_object(struct tcp_info *, struct binn_struct *); -+void metrics_read_binn_object(void *, char **); ++void metrics_read_binn_object(void *, char *); +void metrics_print_header(FILE *, char *, int); + + +#endif /* define metrics_h */ -diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c ---- openssh-9.6p1.orig/misc.c 2024-07-10 13:32:39.597111805 +0200 -+++ openssh-9.6p1/misc.c 2024-07-10 13:34:02.722358600 +0200 +diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c +--- openssh-9.8p1.orig/misc.c 2024-09-30 16:02:22.617024482 +0200 ++++ openssh-9.8p1/misc.c 2024-09-30 16:03:39.159245285 +0200 @@ -77,6 +77,29 @@ #include "ssherr.h" #include "platform.h" @@ -9681,7 +9707,7 @@ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c /* remove newline at end of string */ char * chop(char *s) -@@ -1635,20 +1658,6 @@ +@@ -1649,20 +1672,6 @@ return (v); } @@ -9702,7 +9728,7 @@ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c u_int16_t get_u16(const void *vp) { -@@ -1688,17 +1697,6 @@ +@@ -1702,17 +1711,6 @@ } void @@ -9720,10 +9746,10 @@ diff -Nur openssh-9.6p1.orig/misc.c openssh-9.6p1/misc.c put_u16(void *vp, u_int16_t v) { u_char *p = (u_char *)vp; -diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h ---- openssh-9.6p1.orig/misc.h 2024-07-10 13:32:39.598111808 +0200 -+++ openssh-9.6p1/misc.h 2024-07-10 13:34:02.722358600 +0200 -@@ -158,12 +158,6 @@ +diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h +--- openssh-9.8p1.orig/misc.h 2024-09-30 16:02:22.617024482 +0200 ++++ openssh-9.8p1/misc.h 2024-09-30 16:03:39.160245287 +0200 +@@ -166,12 +166,6 @@ void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); @@ -9736,7 +9762,7 @@ diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h struct bwlimit { size_t buflen; u_int64_t rate; /* desired rate in kbit/s */ -@@ -248,4 +242,16 @@ +@@ -258,4 +252,16 @@ /* On OpenBSD time_t is int64_t which is long long. */ /* #define SSH_TIME_T_MAX LLONG_MAX */ @@ -9753,20 +9779,22 @@ diff -Nur openssh-9.6p1.orig/misc.h openssh-9.6p1/misc.h +void read_mem_stats(struct statm_t *, int); + #endif /* _MISC_H */ -diff -Nur openssh-9.6p1.orig/myproposal.h openssh-9.6p1/myproposal.h ---- openssh-9.6p1.orig/myproposal.h 2024-07-10 13:32:39.557111687 +0200 -+++ openssh-9.6p1/myproposal.h 2024-07-10 13:34:02.722358600 +0200 -@@ -69,6 +69,7 @@ +diff -Nur openssh-9.8p1.orig/myproposal.h openssh-9.8p1/myproposal.h +--- openssh-9.8p1.orig/myproposal.h 2024-09-30 16:02:22.575024361 +0200 ++++ openssh-9.8p1/myproposal.h 2024-09-30 16:03:39.161245290 +0200 +@@ -69,7 +69,8 @@ "rsa-sha2-256" #define KEX_SERVER_ENCRYPT \ +- "chacha20-poly1305@openssh.com," \ + "chacha20-poly1305-mt@hpnssh.org," \ - "chacha20-poly1305@openssh.com," \ ++ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr," \ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" -diff -Nur openssh-9.6p1.orig/num.c openssh-9.6p1/num.c ---- openssh-9.6p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/num.c 2024-07-10 13:34:02.722358600 +0200 + +diff -Nur openssh-9.8p1.orig/num.c openssh-9.8p1/num.c +--- openssh-9.8p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/num.c 2024-09-30 16:03:39.161245290 +0200 @@ -0,0 +1,156 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9924,9 +9952,9 @@ diff -Nur openssh-9.6p1.orig/num.c openssh-9.6p1/num.c +implement_provnum(size_t, OSSL_PARAM_UNSIGNED_INTEGER) + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.6p1.orig/num.h openssh-9.6p1/num.h ---- openssh-9.6p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/num.h 2024-07-10 13:34:02.723358603 +0200 +diff -Nur openssh-9.8p1.orig/num.h openssh-9.8p1/num.h +--- openssh-9.8p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/num.h 2024-09-30 16:03:39.161245290 +0200 @@ -0,0 +1,15 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9943,9 +9971,9 @@ diff -Nur openssh-9.6p1.orig/num.h openssh-9.6p1/num.h +#define PROVNUM_E_TOOBIG -2 +#define PROVNUM_E_UNSUPPORTED -3 +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.6p1.orig/ossl3-provider-err.c openssh-9.6p1/ossl3-provider-err.c ---- openssh-9.6p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/ossl3-provider-err.c 2024-07-10 13:34:02.723358603 +0200 +diff -Nur openssh-9.8p1.orig/ossl3-provider-err.c openssh-9.8p1/ossl3-provider-err.c +--- openssh-9.8p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/ossl3-provider-err.c 2024-09-30 16:03:39.162245293 +0200 @@ -0,0 +1,108 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10055,9 +10083,9 @@ diff -Nur openssh-9.6p1.orig/ossl3-provider-err.c openssh-9.6p1/ossl3-provider-e +} + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.6p1.orig/ossl3-provider-err.h openssh-9.6p1/ossl3-provider-err.h ---- openssh-9.6p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/ossl3-provider-err.h 2024-07-10 13:34:02.723358603 +0200 +diff -Nur openssh-9.8p1.orig/ossl3-provider-err.h openssh-9.8p1/ossl3-provider-err.h +--- openssh-9.8p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/ossl3-provider-err.h 2024-09-30 16:03:39.162245293 +0200 @@ -0,0 +1,73 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10132,9 +10160,9 @@ diff -Nur openssh-9.6p1.orig/ossl3-provider-err.h openssh-9.6p1/ossl3-provider-e +void proverr_set_error(const struct proverr_functions_st *handle, + uint32_t reason, const char *fmt, ...); +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c ---- openssh-9.6p1.orig/packet.c 2024-07-10 13:32:39.545111651 +0200 -+++ openssh-9.6p1/packet.c 2024-07-10 15:20:04.337115780 +0200 +diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c +--- openssh-9.8p1.orig/packet.c 2024-09-30 16:02:22.560024318 +0200 ++++ openssh-9.8p1/packet.c 2024-09-30 16:03:39.163245296 +0200 @@ -63,6 +63,9 @@ #endif #include @@ -10167,16 +10195,20 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c struct packet_state { u_int32_t seqnr; -@@ -241,12 +257,19 @@ +@@ -241,12 +257,23 @@ (state->outgoing_packet = sshbuf_new()) == NULL || (state->incoming_packet = sshbuf_new()) == NULL) goto fail; + /* these buffers are important in terms of tracking buffer usage -+ * so we explicitly label them with descriptive names */ ++ * so we explicitly label and type them with descriptive names */ + sshbuf_relabel(state->input, "input"); ++ sshbuf_type(state->input, BUF_PACKET_INPUT); + sshbuf_relabel(state->incoming_packet, "inpacket"); ++ sshbuf_type(state->incoming_packet, BUF_PACKET_INCOMING); + sshbuf_relabel(state->output, "output"); ++ sshbuf_type(state->output, BUF_PACKET_OUTPUT); + sshbuf_relabel(state->outgoing_packet, "outpacket"); ++ sshbuf_type(state->outgoing_packet, BUF_PACKET_OUTGOING); + TAILQ_INIT(&state->outgoing); TAILQ_INIT(&ssh->private_keys); @@ -10188,7 +10220,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c state->packet_timeout_ms = -1; state->p_send.packets = state->p_read.packets = 0; state->initialized = 1; -@@ -294,7 +317,7 @@ +@@ -294,7 +321,7 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) { struct session_state *state; @@ -10197,7 +10229,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c int r; if (none == NULL) { -@@ -311,9 +334,11 @@ +@@ -311,9 +338,11 @@ state->connection_in = fd_in; state->connection_out = fd_out; if ((r = cipher_init(&state->send_context, none, @@ -10211,7 +10243,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c error_fr(r, "cipher_init failed"); free(ssh); /* XXX need ssh_free_session_state? */ return NULL; -@@ -384,7 +409,7 @@ +@@ -384,7 +413,7 @@ if (state->packet_discard_mac) { char buf[1024]; @@ -10220,7 +10252,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c if (dlen > state->packet_discard_mac_already) dlen -= state->packet_discard_mac_already; -@@ -885,6 +910,7 @@ +@@ -977,6 +1006,7 @@ const char *wmsg; int r, crypt_type; const char *dir = mode == MODE_OUT ? "out" : "in"; @@ -10228,7 +10260,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c debug2_f("mode %d", mode); -@@ -923,12 +949,32 @@ +@@ -1015,12 +1045,32 @@ if ((r = mac_init(mac)) != 0) return r; } @@ -10263,7 +10295,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c return r; if (!state->cipher_warning_done && (wmsg = cipher_warning_message(*ccp)) != NULL) { -@@ -953,23 +999,45 @@ +@@ -1045,23 +1095,45 @@ } comp->enabled = 1; } @@ -10323,7 +10355,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c #define MAX_PACKETS (1U<<31) static int ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) -@@ -996,6 +1064,14 @@ +@@ -1088,6 +1160,14 @@ if (state->p_send.packets == 0 && state->p_read.packets == 0) return 0; @@ -10338,7 +10370,18 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c /* Time-based rekeying */ if (state->rekey_interval != 0 && (int64_t)state->rekey_time + state->rekey_interval <= monotime()) -@@ -1354,7 +1430,7 @@ +@@ -1294,8 +1374,8 @@ + sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) + goto out; + if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp, +- sshbuf_ptr(state->outgoing_packet), +- len - aadlen, aadlen, authlen)) != 0) ++ sshbuf_ptr(state->outgoing_packet), len - aadlen, aadlen, authlen)) ++ != 0) + goto out; + /* append unencrypted MAC */ + if (mac && mac->enabled) { +@@ -1446,7 +1526,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain = 0; struct pollfd pfd; @@ -10347,7 +10390,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c struct timeval start; struct timespec timespec, *timespecp = NULL; -@@ -1481,7 +1557,7 @@ +@@ -1573,7 +1653,7 @@ return 0; /* packet is incomplete */ state->packlen = PEEK_U32(cp); if (state->packlen < 4 + 1 || @@ -10356,7 +10399,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c return SSH_ERR_MESSAGE_INCOMPLETE; } need = state->packlen + 4; -@@ -1540,7 +1616,7 @@ +@@ -1632,7 +1712,7 @@ sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) return 0; if (state->packlen < 1 + 4 || @@ -10365,7 +10408,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c #ifdef PACKET_DEBUG sshbuf_dump(state->input, stderr); #endif -@@ -1567,7 +1643,7 @@ +@@ -1659,7 +1739,7 @@ goto out; state->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet)); if (state->packlen < 1 + 4 || @@ -10374,7 +10417,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c #ifdef PACKET_DEBUG fprintf(stderr, "input: \n"); sshbuf_dump(state->input, stderr); -@@ -1576,7 +1652,7 @@ +@@ -1668,7 +1748,7 @@ #endif logit("Bad packet length %u.", state->packlen); return ssh_packet_start_discard(ssh, enc, mac, 0, @@ -10383,7 +10426,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c } if ((r = sshbuf_consume(state->input, block_size)) != 0) goto out; -@@ -1599,7 +1675,7 @@ +@@ -1691,7 +1771,7 @@ logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); return ssh_packet_start_discard(ssh, enc, mac, 0, @@ -10392,7 +10435,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c } /* * check if the entire packet has been received and -@@ -1643,11 +1719,11 @@ +@@ -1735,11 +1815,11 @@ if (r != SSH_ERR_MAC_INVALID) goto out; logit("Corrupted MAC on input."); @@ -10406,7 +10449,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c } /* Remove MAC from input buffer */ DBG(debug("MAC #%d ok", state->p_read.seqnr)); -@@ -1862,7 +1938,7 @@ +@@ -1954,7 +2034,7 @@ int r; size_t rlen; @@ -10415,7 +10458,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c return r; if (state->packet_discard) { -@@ -1941,17 +2017,21 @@ +@@ -2033,17 +2113,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -10437,7 +10480,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -1993,6 +2073,24 @@ +@@ -2085,6 +2169,24 @@ logdie_f("should have exited"); } @@ -10462,7 +10505,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -2247,10 +2345,19 @@ +@@ -2339,10 +2441,19 @@ ssh->kex->server = 1; /* XXX unify? */ } @@ -10482,7 +10525,7 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c } void * -@@ -2868,3 +2975,17 @@ +@@ -2960,3 +3071,17 @@ ssh->state->extra_pad = pad; return 0; } @@ -10500,10 +10543,10 @@ diff -Nur openssh-9.6p1.orig/packet.c openssh-9.6p1/packet.c +{ + return ssh->state->receive_context; +} -diff -Nur openssh-9.6p1.orig/packet.h openssh-9.6p1/packet.h ---- openssh-9.6p1.orig/packet.h 2024-07-10 13:32:39.546111654 +0200 -+++ openssh-9.6p1/packet.h 2024-07-10 13:34:02.724358606 +0200 -@@ -86,6 +86,20 @@ +diff -Nur openssh-9.8p1.orig/packet.h openssh-9.8p1/packet.h +--- openssh-9.8p1.orig/packet.h 2024-09-30 16:02:22.560024318 +0200 ++++ openssh-9.8p1/packet.h 2024-09-30 16:03:39.163245296 +0200 +@@ -86,6 +86,17 @@ /* APP data */ void *app_data; @@ -10518,13 +10561,10 @@ diff -Nur openssh-9.6p1.orig/packet.h openssh-9.6p1/packet.h + + /* track if we have disabled the mac as well */ + int none_mac; -+ -+ /* use the less agressive window growth option */ -+ int hpn_buffer_limit; }; typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, -@@ -158,6 +172,8 @@ +@@ -156,6 +167,8 @@ int ssh_packet_set_maxsize(struct ssh *, u_int); u_int ssh_packet_get_maxsize(struct ssh *); @@ -10533,7 +10573,7 @@ diff -Nur openssh-9.6p1.orig/packet.h openssh-9.6p1/packet.h int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); -@@ -172,6 +188,13 @@ +@@ -171,6 +184,13 @@ void *ssh_packet_get_input(struct ssh *); void *ssh_packet_get_output(struct ssh *); @@ -10547,9 +10587,9 @@ diff -Nur openssh-9.6p1.orig/packet.h openssh-9.6p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-9.6p1.orig/poly1305.c openssh-9.6p1/poly1305.c ---- openssh-9.6p1.orig/poly1305.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/poly1305.c 2024-07-10 13:34:02.724358606 +0200 +diff -Nur openssh-9.8p1.orig/poly1305.c openssh-9.8p1/poly1305.c +--- openssh-9.8p1.orig/poly1305.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/poly1305.c 2024-09-30 16:03:39.164245299 +0200 @@ -13,6 +13,16 @@ #include "poly1305.h" @@ -10581,9 +10621,9 @@ diff -Nur openssh-9.6p1.orig/poly1305.c openssh-9.6p1/poly1305.c U32TO8_LE(&out[12], f3); } +#endif /* OPENSSL_HAVE_POLY_EVP */ -diff -Nur openssh-9.6p1.orig/poly1305.h openssh-9.6p1/poly1305.h ---- openssh-9.6p1.orig/poly1305.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/poly1305.h 2024-07-10 13:34:02.724358606 +0200 +diff -Nur openssh-9.8p1.orig/poly1305.h openssh-9.8p1/poly1305.h +--- openssh-9.8p1.orig/poly1305.h 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/poly1305.h 2024-09-30 16:03:39.164245299 +0200 @@ -13,8 +13,15 @@ #define POLY1305_KEYLEN 32 #define POLY1305_TAGLEN 16 @@ -10601,9 +10641,9 @@ diff -Nur openssh-9.6p1.orig/poly1305.h openssh-9.6p1/poly1305.h __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); -diff -Nur openssh-9.6p1.orig/progressmeter.c openssh-9.6p1/progressmeter.c ---- openssh-9.6p1.orig/progressmeter.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/progressmeter.c 2024-07-10 13:34:02.725358609 +0200 +diff -Nur openssh-9.8p1.orig/progressmeter.c openssh-9.8p1/progressmeter.c +--- openssh-9.8p1.orig/progressmeter.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/progressmeter.c 2024-09-30 16:03:39.165245302 +0200 @@ -66,6 +66,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -10662,9 +10702,9 @@ diff -Nur openssh-9.6p1.orig/progressmeter.c openssh-9.6p1/progressmeter.c } static void -diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c ---- openssh-9.6p1.orig/readconf.c 2024-07-10 13:32:39.600111814 +0200 -+++ openssh-9.6p1/readconf.c 2024-07-10 13:34:02.725358609 +0200 +diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c +--- openssh-9.8p1.orig/readconf.c 2024-09-30 16:02:22.619024488 +0200 ++++ openssh-9.8p1/readconf.c 2024-09-30 16:35:58.686841931 +0200 @@ -72,6 +72,7 @@ #include "myproposal.h" #include "digest.h" @@ -10673,24 +10713,25 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c /* Format of the configuration file: -@@ -173,6 +174,9 @@ +@@ -173,6 +174,10 @@ oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oRemoteCommand, + oTcpRcvBufPoll, oHPNDisabled, -+ oNoneEnabled, oNoneMacEnabled, oNoneSwitch, oHPNBufferLimit, ++ oNoneEnabled, oNoneMacEnabled, oNoneSwitch, ++ oDisableMTAES, + oMetrics, oMetricsPath, oMetricsInterval, oFallback, oFallbackPort, oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, -@@ -319,6 +323,15 @@ +@@ -319,6 +324,15 @@ { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, + { "noneenabled", oNoneEnabled }, + { "nonemacenabled", oNoneMacEnabled }, + { "noneswitch", oNoneSwitch }, -+ { "hpnbufferlimit", oHPNBufferLimit }, ++ { "disablemtaes", oDisableMTAES }, + { "metrics", oMetrics }, + { "metricspath", oMetricsPath }, + { "metricsinterval", oMetricsInterval }, @@ -10699,7 +10740,7 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c { "sessiontype", oSessionType }, { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, -@@ -341,6 +354,8 @@ +@@ -341,6 +355,8 @@ { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, @@ -10708,7 +10749,7 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c { "requiredrsasize", oRequiredRSASize }, { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, -@@ -539,7 +554,7 @@ +@@ -539,7 +555,7 @@ if (port == 0) { sp = getservbyname(SSH_SERVICE_NAME, "tcp"); @@ -10717,7 +10758,7 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c } return port; } -@@ -1271,6 +1286,63 @@ +@@ -1288,6 +1304,63 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -10737,8 +10778,8 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c + intptr = &options->nonemac_enabled; + goto parse_flag; + -+ case oHPNBufferLimit: -+ intptr = &options->hpn_buffer_limit; ++ case oDisableMTAES: ++ intptr = &options->disable_multithreaded; + goto parse_flag; + + case oMetrics: @@ -10781,32 +10822,30 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -2641,6 +2713,17 @@ +@@ -2678,6 +2751,17 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; + options->none_switch = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; ++ options->disable_multithreaded = -1; + options->metrics = -1; + options->metrics_path = NULL; + options->metrics_interval = -1; + options->hpn_disabled = -1; -+ options->hpn_buffer_limit = -1; + options->fallback = -1; + options->fallback_port = -1; + options->tcp_rcv_buf_poll = -1; options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2822,8 +2905,37 @@ +@@ -2861,8 +2945,37 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; -+ if (options->hpn_buffer_limit == -1) -+ options->hpn_buffer_limit = 0; + if (options->tcp_rcv_buf_poll == -1) + options->tcp_rcv_buf_poll = 1; + if (options->none_switch == -1) @@ -10824,6 +10863,8 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c + fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); + options->nonemac_enabled = 0; + } ++ if (options->disable_multithreaded == -1) ++ options->disable_multithreaded = 0; + if (options->metrics == -1) + options->metrics = 0; + if (options->metrics_interval == -1) @@ -10837,20 +10878,19 @@ diff -Nur openssh-9.6p1.orig/readconf.c openssh-9.6p1/readconf.c if (options->control_persist == -1) { options->control_persist = 0; options->control_persist_timeout = 0; -diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h ---- openssh-9.6p1.orig/readconf.h 2024-07-10 13:32:39.600111814 +0200 -+++ openssh-9.6p1/readconf.h 2024-07-10 13:34:02.726358612 +0200 -@@ -56,6 +56,9 @@ +diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h +--- openssh-9.8p1.orig/readconf.h 2024-09-30 16:02:22.619024488 +0200 ++++ openssh-9.8p1/readconf.h 2024-10-01 10:20:11.459528169 +0200 +@@ -56,6 +56,8 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ + int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ + int hpn_disabled; /* Switch to disable HPN buffer management */ -+ int hpn_buffer_limit; /* limit local_window_max to 1/2 receive buffer */ int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ -@@ -129,6 +132,16 @@ +@@ -129,6 +131,17 @@ int enable_ssh_keysign; int64_t rekey_limit; int rekey_interval; @@ -10858,6 +10898,7 @@ diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h + int none_switch; /* Use none cipher */ + int none_enabled; /* Allow none to be used */ + int nonemac_enabled; /* Allow none to be used */ ++ int disable_multithreaded; /* Disable multithreaded aes-ctr */ + int metrics; /* enable metrics */ + int metrics_interval; /* time in seconds between polls */ + char *metrics_path; /* path for the metrics files */ @@ -10867,9 +10908,9 @@ diff -Nur openssh-9.6p1.orig/readconf.h openssh-9.6p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-9.6p1.orig/README.md openssh-9.6p1/README.md ---- openssh-9.6p1.orig/README.md 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/README.md 2024-07-10 13:34:02.726358612 +0200 +diff -Nur openssh-9.8p1.orig/README.md openssh-9.8p1/README.md +--- openssh-9.8p1.orig/README.md 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/README.md 2024-09-30 16:03:39.167245307 +0200 @@ -1,12 +1,16 @@ -# Portable OpenSSH +# HPNSSH: Based on Portable OpenSSH @@ -10941,9 +10982,9 @@ diff -Nur openssh-9.6p1.orig/README.md openssh-9.6p1/README.md ## Development -diff -Nur openssh-9.6p1.orig/sandbox-seccomp-filter.c openssh-9.6p1/sandbox-seccomp-filter.c ---- openssh-9.6p1.orig/sandbox-seccomp-filter.c 2024-07-10 13:32:39.558111689 +0200 -+++ openssh-9.6p1/sandbox-seccomp-filter.c 2024-07-10 13:34:02.726358612 +0200 +diff -Nur openssh-9.8p1.orig/sandbox-seccomp-filter.c openssh-9.8p1/sandbox-seccomp-filter.c +--- openssh-9.8p1.orig/sandbox-seccomp-filter.c 2024-09-30 16:02:22.576024364 +0200 ++++ openssh-9.8p1/sandbox-seccomp-filter.c 2024-09-30 16:03:39.168245311 +0200 @@ -295,6 +295,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -10964,9 +11005,9 @@ diff -Nur openssh-9.6p1.orig/sandbox-seccomp-filter.c openssh-9.6p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-9.6p1.orig/scp.1 openssh-9.6p1/scp.1 ---- openssh-9.6p1.orig/scp.1 2024-07-10 13:32:39.528111600 +0200 -+++ openssh-9.6p1/scp.1 2024-07-10 14:33:54.369943270 +0200 +diff -Nur openssh-9.8p1.orig/scp.1 openssh-9.8p1/scp.1 +--- openssh-9.8p1.orig/scp.1 2024-09-30 16:02:22.541024263 +0200 ++++ openssh-9.8p1/scp.1 2024-10-01 13:10:54.653458405 +0200 @@ -18,7 +18,7 @@ .Nd OpenSSH secure file copy .Sh SYNOPSIS @@ -10976,18 +11017,31 @@ diff -Nur openssh-9.6p1.orig/scp.1 openssh-9.6p1/scp.1 .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config -@@ -252,6 +252,10 @@ +@@ -252,6 +252,9 @@ Note that .Nm follows symbolic links encountered in the tree traversal. +.It Fl Z +Resume failed or interrupted transfer. Identical files will be skipped. Remote must have resume option. -+.Nm -+only option. ++HPN-SSH only option. .It Fl S Ar program Name of .Ar program -@@ -285,10 +289,13 @@ +@@ -259,6 +262,13 @@ + The program must understand + .Xr ssh 1 + options. ++.It Fl z Ar program ++Path to hpnscp on remote system. Useful if remote has multiple scp installs. ++For example, using the resume option but the default remote scp does not have the resume option. ++Use -z to point the version that does - e.g. -z /opt/hpnssh/bin/hpnscp. ++HPN-SSH only option. ++.It Fl s ++Use the SFTP protocol for transfers rather than the original scp protocol. + .It Fl T + Disable strict filename checking. + By default when copying files from a remote host to a local directory +@@ -285,10 +295,13 @@ .It Cm nrequests Ns = Ns Ar value Controls how many concurrent SFTP read or write requests may be in progress at any point in time during a download or upload. @@ -11002,7 +11056,7 @@ diff -Nur openssh-9.6p1.orig/scp.1 openssh-9.6p1/scp.1 By default a 32KB buffer is used. .El .El -@@ -322,6 +329,7 @@ +@@ -322,6 +335,7 @@ .Sh AUTHORS .An Timo Rinne Aq Mt tri@iki.fi .An Tatu Ylonen Aq Mt ylo@cs.hut.fi @@ -11010,9 +11064,9 @@ diff -Nur openssh-9.6p1.orig/scp.1 openssh-9.6p1/scp.1 .Sh CAVEATS The legacy SCP protocol (selected by the .Fl O -diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c ---- openssh-9.6p1.orig/scp.c 2024-07-10 13:32:39.530111606 +0200 -+++ openssh-9.6p1/scp.c 2024-07-10 14:15:34.032723487 +0200 +diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c +--- openssh-9.8p1.orig/scp.c 2024-09-30 16:02:22.544024272 +0200 ++++ openssh-9.8p1/scp.c 2024-09-30 16:03:39.170245316 +0200 @@ -17,6 +17,7 @@ /* * Copyright (c) 1999 Theo de Raadt. All rights reserved. @@ -11063,7 +11117,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c static void killchild(int signo) { -@@ -234,6 +256,9 @@ +@@ -236,6 +258,9 @@ int status; pid_t pid; @@ -11073,7 +11127,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (a->num == 0) fatal("do_local_cmd: no arguments"); -@@ -460,6 +485,8 @@ +@@ -462,6 +487,8 @@ void tolocal(int, char *[], enum scp_mode_e, char *sftp_direct); void toremote(int, char *[], enum scp_mode_e, char *sftp_direct); void usage(void); @@ -11082,7 +11136,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c void source_sftp(int, char *, char *, struct sftp_conn *); void sink_sftp(int, char *, const char *, struct sftp_conn *); -@@ -478,11 +505,18 @@ +@@ -480,11 +507,18 @@ char *sftp_direct = NULL; long long llv; @@ -11101,7 +11155,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c /* Copy argv, because we modify it */ argv0 = argv[0]; newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); -@@ -506,7 +540,7 @@ +@@ -508,7 +542,7 @@ fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -11110,7 +11164,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c switch (ch) { /* User-visible flags. */ case '1': -@@ -587,24 +621,36 @@ +@@ -589,31 +623,43 @@ addargs(&remote_remote_args, "-q"); showprogress = 0; break; @@ -11124,35 +11178,59 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c case 'X': /* Please keep in sync with sftp.c -X */ if (strncmp(optarg, "buffer=", 7) == 0) { - r = scan_scaled(optarg + 7, &llv); +- r = scan_scaled(optarg + 7, &llv); - if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { -+ /* don't ask for a buffer larger than the maximum -+ * size that SFTP can handle */ -+ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { - r = -1; - errno = EINVAL; - } - if (r == -1) { +- r = -1; +- errno = EINVAL; +- } +- if (r == -1) { - fatal("Invalid buffer size \"%s\": %s", - optarg + 7, strerror(errno)); -+ fatal("Invalid buffer size. Must be between 1B and 255KB." -+ "\"%s\": %s", optarg + 7, strerror(errno)); - } - sftp_copy_buflen = (size_t)llv; - } else if (strncmp(optarg, "nrequests=", 10) == 0) { +- } +- sftp_copy_buflen = (size_t)llv; +- } else if (strncmp(optarg, "nrequests=", 10) == 0) { - llv = strtonum(optarg + 10, 1, 256 * 1024, -+ /* more than 10k to 15k requests starts stalling the connection -+ * 8192 * default buffer size is 256MB of outstanding data. -+ * if users need more then they need to up the buffer size */ -+ llv = strtonum(optarg + 10, 1, 8 * 1024, - &errstr); - if (errstr != NULL) { +- &errstr); +- if (errstr != NULL) { - fatal("Invalid number of requests " -+ fatal("Invalid number of requests. Must be between 1 and 8192. " - "\"%s\": %s", optarg + 10, errstr); - } - sftp_nrequests = (size_t)llv; -@@ -692,11 +738,20 @@ +- "\"%s\": %s", optarg + 10, errstr); +- } +- sftp_nrequests = (size_t)llv; +- } else { +- fatal("Invalid -X option"); +- } +- break; ++ r = scan_scaled(optarg + 7, &llv); ++ /* don't ask for a buffer larger than the maximum ++ * size that SFTP can handle */ ++ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { ++ r = -1; ++ errno = EINVAL; ++ } ++ if (r == -1) { ++ fatal("Invalid buffer size. Must be between 1B and 255KB." ++ "\"%s\": %s", optarg + 7, strerror(errno)); ++ } ++ sftp_copy_buflen = (size_t)llv; ++ } else if (strncmp(optarg, "nrequests=", 10) == 0) { ++ /* more than 10k to 15k requests starts stalling the connection ++ * 8192 * default buffer size is 256MB of outstanding data. ++ * if users need more then they need to up the buffer size */ ++ llv = strtonum(optarg + 10, 1, 8 * 1024, ++ &errstr); ++ if (errstr != NULL) { ++ fatal("Invalid number of requests. Must be between 1 and 8192. " ++ "\"%s\": %s", optarg + 10, errstr); ++ } ++ sftp_nrequests = (size_t)llv; ++ } else { ++ fatal("Invalid -X option"); ++ } ++ break; + + /* Server options. */ + case 'd': +@@ -694,11 +740,20 @@ remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ @@ -11178,7 +11256,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c (void) ssh_signal(SIGPIPE, lostconn); if (colon(argv[argc - 1])) /* Dest is remote host. */ -@@ -1321,6 +1376,74 @@ +@@ -1323,6 +1378,74 @@ free(src); } @@ -11253,7 +11331,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c /* Prepare remote path, handling ~ by assuming cwd is the homedir */ static char * prepare_remote_path(struct sftp_conn *conn, const char *path) -@@ -1404,14 +1527,23 @@ +@@ -1406,14 +1529,23 @@ struct stat stb; static BUF buffer; BUF *bp; @@ -11279,7 +11357,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') -@@ -1433,6 +1565,14 @@ +@@ -1435,6 +1567,14 @@ unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: @@ -11294,7 +11372,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c break; case S_IFDIR: if (iamrecursive) { -@@ -1454,14 +1594,133 @@ +@@ -1456,14 +1596,133 @@ goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) @@ -11434,7 +11512,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); -@@ -1469,13 +1728,17 @@ +@@ -1471,13 +1730,17 @@ } continue; } @@ -11456,7 +11534,12 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { -@@ -1672,24 +1935,36 @@ +@@ -1670,28 +1933,41 @@ + (sizeof(type) == 8 && (val) > INT64_MAX) || \ + (sizeof(type) != 4 && sizeof(type) != 8)) + ++ + void sink(int argc, char **argv, const char *src) { static BUF buffer; @@ -11496,7 +11579,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) SCREWUP("Unexpected off_t/time_t size"); -@@ -1705,9 +1980,16 @@ +@@ -1707,9 +1983,16 @@ if (targetshouldbedirectory) verifydir(targ); @@ -11513,7 +11596,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (src != NULL && !iamrecursive && !Tflag) { /* * Prepare to try to restrict incoming filenames to match -@@ -1716,7 +1998,12 @@ +@@ -1718,7 +2001,12 @@ if (brace_expand(src, &patterns, &npatterns) != 0) fatal_f("could not expand pattern"); } @@ -11526,7 +11609,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c cp = buf; if (atomicio(read, remin, cp, 1) != 1) goto done; -@@ -1744,6 +2031,9 @@ +@@ -1746,6 +2034,9 @@ continue; } if (buf[0] == 'E') { @@ -11536,7 +11619,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c (void) atomicio(vwrite, remout, "", 1); goto done; } -@@ -1751,6 +2041,9 @@ +@@ -1753,6 +2044,9 @@ *--cp = 0; cp = buf; @@ -11546,7 +11629,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (*cp == 'T') { setimes++; cp++; -@@ -1778,9 +2071,19 @@ +@@ -1780,9 +2074,19 @@ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); @@ -11566,7 +11649,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". -@@ -1796,6 +2099,18 @@ +@@ -1798,6 +2102,18 @@ SCREWUP("expected control record"); } mode = 0; @@ -11585,7 +11668,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); -@@ -1806,6 +2121,10 @@ +@@ -1808,6 +2124,10 @@ if (*cp++ != ' ') SCREWUP("mode not delimited"); @@ -11596,7 +11679,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (!isdigit((unsigned char)*cp)) SCREWUP("size not present"); ull = strtoull(cp, &cp, 10); -@@ -1815,11 +2134,32 @@ +@@ -1817,11 +2137,32 @@ SCREWUP("size out of range"); size = (off_t)ull; @@ -11629,7 +11712,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (npatterns > 0) { for (n = 0; n < npatterns; n++) { if (strcmp(patterns[n], cp) == 0 || -@@ -1889,11 +2229,195 @@ +@@ -1891,11 +2232,195 @@ } omode = mode; mode |= S_IWUSR; @@ -11826,7 +11909,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; -@@ -1908,13 +2432,17 @@ +@@ -1910,13 +2435,17 @@ */ statbytes = 0; if (showprogress) @@ -11848,7 +11931,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); -@@ -1949,8 +2477,78 @@ +@@ -1951,8 +2480,78 @@ wrerr = 1; } if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && @@ -11928,7 +12011,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD -@@ -1985,8 +2583,17 @@ +@@ -1987,8 +2586,17 @@ } } /* If no error was noted then signal success for this file */ @@ -11947,7 +12030,7 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c } done: for (n = 0; n < npatterns; n++) -@@ -2130,11 +2737,19 @@ +@@ -2132,11 +2740,20 @@ void usage(void) { @@ -11964,10 +12047,11 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c " [-P port] [-S program] [-X sftp_option] source ... target\n"); exit(1); +#endif ++ } void -@@ -2273,6 +2888,18 @@ +@@ -2275,6 +2892,18 @@ exit(1); } @@ -11986,10 +12070,10 @@ diff -Nur openssh-9.6p1.orig/scp.c openssh-9.6p1/scp.c void cleanup_exit(int i) { -diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c ---- openssh-9.6p1.orig/servconf.c 2024-07-10 13:32:39.601111817 +0200 -+++ openssh-9.6p1/servconf.c 2024-07-10 14:16:52.654947762 +0200 -@@ -199,6 +199,11 @@ +diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c +--- openssh-9.8p1.orig/servconf.c 2024-09-30 16:02:22.620024491 +0200 ++++ openssh-9.8p1/servconf.c 2024-10-01 09:37:00.637000944 +0200 +@@ -214,6 +214,11 @@ options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; @@ -11997,11 +12081,11 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c + options->hpn_disabled = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; -+ options->hpn_buffer_limit = -1; ++ options->disable_multithreaded = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -464,6 +469,18 @@ +@@ -504,6 +509,18 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -12013,23 +12097,23 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c + debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); + options->nonemac_enabled = 0; + } ++ if (options->disable_multithreaded == -1) ++ options->disable_multithreaded = 0; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; -+ if (options->hpn_buffer_limit == -1) -+ options->hpn_buffer_limit = 0; if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -545,6 +562,8 @@ +@@ -584,6 +601,8 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, -+ sNoneEnabled, sNoneMacEnabled, sHPNBufferLimit, -+ sTcpRcvBufPoll, sHPNDisabled, ++ sNoneEnabled, sNoneMacEnabled, sTcpRcvBufPoll, sHPNDisabled, ++ sDisableMTAES, sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -746,6 +765,11 @@ +@@ -791,6 +810,11 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -12037,11 +12121,11 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c + { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, + { "noneenabled", sNoneEnabled, SSHCFG_ALL }, + { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, -+ { "hpnbufferlimit", sHPNBufferLimit, SSHCFG_ALL }, ++ { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -808,6 +832,7 @@ +@@ -854,6 +878,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -12049,7 +12133,7 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1604,12 +1629,32 @@ +@@ -1573,12 +1598,32 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -12075,31 +12159,32 @@ diff -Nur openssh-9.6p1.orig/servconf.c openssh-9.6p1/servconf.c + intptr = &options->nonemac_enabled; + goto parse_flag; + -+ case sHPNBufferLimit: -+ intptr = &options->hpn_buffer_limit; -+ goto parse_flag; ++ case sDisableMTAES: ++ intptr = &options->disable_multithreaded; ++ goto parse_flag; + case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-9.6p1.orig/servconf.h openssh-9.6p1/servconf.h ---- openssh-9.6p1.orig/servconf.h 2024-07-10 13:32:39.601111817 +0200 -+++ openssh-9.6p1/servconf.h 2024-07-10 13:34:02.728358618 +0200 -@@ -211,6 +211,11 @@ - - int use_pam; /* Enable auth via PAM */ +diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h +--- openssh-9.8p1.orig/servconf.h 2024-09-30 16:02:22.621024494 +0200 ++++ openssh-9.8p1/servconf.h 2024-10-01 09:38:49.188317659 +0200 +@@ -225,6 +225,12 @@ + char *pam_service_name; int permit_pam_user_change; /* Allow PAM to change user name */ + + int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int none_enabled; /* Enable NONE cipher switch */ + int nonemac_enabled; /* Enable NONE MAC switch */ -+ int hpn_buffer_limit; /* limit local_window_max to 1/2 receive buffer */ - ++ int disable_multithreaded; /* Disable multithreaded aes-ctr cipher */ ++ int permit_tun; -diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c ---- openssh-9.6p1.orig/serverloop.c 2024-07-10 13:32:39.588111779 +0200 -+++ openssh-9.6p1/serverloop.c 2024-07-10 14:18:04.600152988 +0200 + char **permitted_opens; /* May also be one of PERMITOPEN_* */ +diff -Nur openssh-9.8p1.orig/serverloop.c openssh-9.8p1/serverloop.c +--- openssh-9.8p1.orig/serverloop.c 2024-09-30 16:02:22.607024453 +0200 ++++ openssh-9.8p1/serverloop.c 2024-10-01 09:39:20.858410057 +0200 @@ -81,6 +81,8 @@ #include "serverloop.h" #include "ssherr.h" @@ -12109,7 +12194,7 @@ diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c extern ServerOptions options; -@@ -347,6 +349,7 @@ +@@ -326,6 +328,7 @@ sigset_t bsigset, osigset; debug("Entering interactive session for SSH2."); @@ -12117,21 +12202,11 @@ diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) error_f("bsigset setup: %s", strerror(errno)); -@@ -385,7 +388,9 @@ - error_f("osigset sigprocmask: %s", strerror(errno)); - - if (received_sigterm) { -+ sshpkt_final_log_entry(ssh); - logit("Exiting on signal %d", (int)received_sigterm); -+ sshpkt_final_log_entry(ssh); - /* Clean up sessions, utmp, etc. */ - cleanup_exit(255); - } -@@ -403,9 +408,15 @@ +@@ -370,9 +373,15 @@ collect_children(ssh); free(pfd); -+ /* write final log entry */ ++ /* write final log entry (do we need this here? -cjr)*/ + sshpkt_final_log_entry(ssh); + /* free all channels, no more reads and writes */ @@ -12143,18 +12218,16 @@ diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(ssh, NULL); } -@@ -607,6 +618,10 @@ +@@ -574,6 +583,8 @@ c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); + if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled)) + c->dynamic_window = 1; -+ if (options.hpn_buffer_limit) -+ c->hpn_buffer_limit = 1; if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(ssh, c); -@@ -675,6 +690,67 @@ +@@ -642,6 +653,67 @@ return 0; } @@ -12222,7 +12295,7 @@ diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c static int server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) { -@@ -854,6 +930,10 @@ +@@ -818,6 +890,10 @@ success = 1; } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { success = server_input_hostkeys_prove(ssh, &resp); @@ -12233,9 +12306,9 @@ diff -Nur openssh-9.6p1.orig/serverloop.c openssh-9.6p1/serverloop.c } /* XXX sshpkt_get_end() */ if (want_reply) { -diff -Nur openssh-9.6p1.orig/session.c openssh-9.6p1/session.c ---- openssh-9.6p1.orig/session.c 2024-07-10 13:32:39.552111672 +0200 -+++ openssh-9.6p1/session.c 2024-07-10 13:34:02.729358621 +0200 +diff -Nur openssh-9.8p1.orig/session.c openssh-9.8p1/session.c +--- openssh-9.8p1.orig/session.c 2024-09-30 16:02:22.566024335 +0200 ++++ openssh-9.8p1/session.c 2024-09-30 16:03:39.174245328 +0200 @@ -94,6 +94,7 @@ #include "monitor_wrap.h" #include "sftp.h" @@ -12244,7 +12317,7 @@ diff -Nur openssh-9.6p1.orig/session.c openssh-9.6p1/session.c #if defined(KRB5) && defined(USE_AFS) #include -@@ -226,6 +227,7 @@ +@@ -237,6 +238,7 @@ goto authsock_err; /* Allocate a channel for the authentication agent socket. */ @@ -12252,32 +12325,29 @@ diff -Nur openssh-9.6p1.orig/session.c openssh-9.6p1/session.c nc = channel_new(ssh, "auth-listener", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, -@@ -553,6 +555,8 @@ +@@ -564,6 +566,9 @@ session_set_fds(ssh, s, inout[1], inout[1], err[1], s->is_subsystem, 0); #endif + /* switch to the parallel ciphers if necessary */ -+ cipher_switch(ssh); ++ if (options.disable_multithreaded == 0) ++ cipher_switch(ssh); return 0; } -@@ -666,6 +670,8 @@ +@@ -677,6 +682,9 @@ ssh_packet_set_interactive(ssh, 1, options.ip_qos_interactive, options.ip_qos_bulk); session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); + /* switch to the parallel cipher if appropriate */ -+ cipher_switch(ssh); ++ if (options.disable_multithreaded == 0) ++ cipher_switch(ssh); return 0; } -@@ -2884,4 +2890,3 @@ - remote = ssh_remote_ipaddr(ssh); - return remote; - } -- -diff -Nur openssh-9.6p1.orig/sftp.1 openssh-9.6p1/sftp.1 ---- openssh-9.6p1.orig/sftp.1 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/sftp.1 2024-07-10 13:34:02.730358624 +0200 +diff -Nur openssh-9.8p1.orig/sftp.1 openssh-9.8p1/sftp.1 +--- openssh-9.8p1.orig/sftp.1 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/sftp.1 2024-10-01 11:22:00.648462200 +0200 @@ -299,7 +299,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed @@ -12303,10 +12373,10 @@ diff -Nur openssh-9.6p1.orig/sftp.1 openssh-9.6p1/sftp.1 By default a 32KB buffer is used. .El .El -diff -Nur openssh-9.6p1.orig/sftp.c openssh-9.6p1/sftp.c ---- openssh-9.6p1.orig/sftp.c 2024-07-10 13:32:39.531111609 +0200 -+++ openssh-9.6p1/sftp.c 2024-07-10 14:19:56.850473846 +0200 -@@ -2562,23 +2562,28 @@ +diff -Nur openssh-9.8p1.orig/sftp.c openssh-9.8p1/sftp.c +--- openssh-9.8p1.orig/sftp.c 2024-09-30 16:02:22.545024274 +0200 ++++ openssh-9.8p1/sftp.c 2024-10-01 09:50:10.979301433 +0200 +@@ -2566,23 +2566,28 @@ replacearg(&args, 0, "%s", ssh_program); break; case 'X': @@ -12341,9 +12411,9 @@ diff -Nur openssh-9.6p1.orig/sftp.c openssh-9.6p1/sftp.c "\"%s\": %s", optarg + 10, errstr); } num_requests = (size_t)llv; -diff -Nur openssh-9.6p1.orig/sftp-client.c openssh-9.6p1/sftp-client.c ---- openssh-9.6p1.orig/sftp-client.c 2024-07-10 13:32:39.531111609 +0200 -+++ openssh-9.6p1/sftp-client.c 2024-07-10 13:34:02.731358627 +0200 +diff -Nur openssh-9.8p1.orig/sftp-client.c openssh-9.8p1/sftp-client.c +--- openssh-9.8p1.orig/sftp-client.c 2024-09-30 16:02:22.545024274 +0200 ++++ openssh-9.8p1/sftp-client.c 2024-09-30 16:03:39.175245331 +0200 @@ -72,7 +72,8 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -12354,10 +12424,25 @@ diff -Nur openssh-9.6p1.orig/sftp-client.c openssh-9.6p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 ---- openssh-9.6p1.orig/ssh.1 2024-07-10 13:32:39.601111817 +0200 -+++ openssh-9.6p1/ssh.1 2024-07-10 13:34:02.731358627 +0200 -@@ -524,6 +524,7 @@ +diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 +--- openssh-9.8p1.orig/ssh.1 2024-09-30 16:02:22.622024497 +0200 ++++ openssh-9.8p1/ssh.1 2024-09-30 16:35:12.408708175 +0200 +@@ -77,6 +77,14 @@ + X11 connections, arbitrary TCP ports and + .Ux Ns -domain + sockets can also be forwarded over the secure channel. ++.Nm ++is binary compatible with the more well known OpenSSH and uses the same configuration ++directives, methods, and keywords except where noted with the exception of the default port. ++HPN-SSH servers, by default, use port 2222 for connection, and as such, ++.Nm ++clients ++attempt to connect on that port. If the connection attempt on port 2222 fails it will fallback to ++port 22. Please see the -p switch for more information. + .Pp + .Nm + connects and logs into the specified +@@ -524,11 +532,13 @@ .It ControlMaster .It ControlPath .It ControlPersist @@ -12365,16 +12450,21 @@ diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 .It DynamicForward .It EnableSSHKeysign .It EnableEscapeCommandline -@@ -552,6 +553,8 @@ + .It EscapeChar + .It ExitOnForwardFailure ++.It FallbackPort + .It FingerprintHash + .It ForkAfterAuthentication + .It ForwardAgent +@@ -552,6 +562,7 @@ .It HostKeyAlgorithms .It HostKeyAlias .It Hostname +.It HPNDisabled* -+.It HPNBufferLimit* .It IdentitiesOnly .It IdentityAgent .It IdentityFile -@@ -568,7 +571,13 @@ +@@ -568,7 +579,13 @@ .It LogVerbose .It MACs .It Match @@ -12388,7 +12478,7 @@ diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 .It NumberOfPasswordPrompts .It PasswordAuthentication .It PermitLocalCommand -@@ -599,6 +608,7 @@ +@@ -599,6 +616,7 @@ .It StrictHostKeyChecking .It SyslogFacility .It TCPKeepAlive @@ -12396,27 +12486,41 @@ diff -Nur openssh-9.6p1.orig/ssh.1 openssh-9.6p1/ssh.1 .It Tunnel .It TunnelDevice .It UpdateHostKeys -@@ -607,6 +617,8 @@ +@@ -607,6 +625,8 @@ .It VerifyHostKeyDNS .It VisualHostKey .It XAuthLocation +.Pp -+.It * Hpnssh specific configuration option. ++.It * Hpnssh specific configuration option. .El .Pp .It Fl P Ar tag -@@ -1825,3 +1837,7 @@ +@@ -623,6 +643,13 @@ + Port to connect to on the remote host. + This can be specified on a + per-host basis in the configuration file. ++HPN-SSH uses a default port of 2222. It will automatically ++fallback to use the SSH standard port 22 if it cannot connect ++on port 2222. This fallback behaviour can be modified with the ++FallbackPort option. Note: if outbound port 2222 is ++blocked it may appear that the hpnssh client is non-responsive. In that event, ++either specify the correct port or use the ConnectTimeout option ++to trigger the port fallback more quickly. + .Pp + .It Fl Q Ar query_option + Queries for the algorithms supported by one of the following features: +@@ -1814,3 +1841,7 @@ created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. +Chris Rapier, Michael Stevens, Ben Bennet, and Mike Tasota developed +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science -+Foundation. -diff -Nur openssh-9.6p1.orig/ssh_api.c openssh-9.6p1/ssh_api.c ---- openssh-9.6p1.orig/ssh_api.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh_api.c 2024-07-10 13:34:02.732358630 +0200 -@@ -410,7 +410,7 @@ ++Foundation. +diff -Nur openssh-9.8p1.orig/ssh_api.c openssh-9.8p1/ssh_api.c +--- openssh-9.8p1.orig/ssh_api.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/ssh_api.c 2024-09-30 16:03:39.177245336 +0200 +@@ -425,7 +425,7 @@ char *cp; int r; @@ -12425,43 +12529,29 @@ diff -Nur openssh-9.6p1.orig/ssh_api.c openssh-9.6p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c ---- openssh-9.6p1.orig/sshbuf.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/sshbuf.c 2024-07-10 13:34:02.732358630 +0200 -@@ -27,6 +27,20 @@ +diff -Nur openssh-9.8p1.orig/sshbuf.c openssh-9.8p1/sshbuf.c +--- openssh-9.8p1.orig/sshbuf.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/sshbuf.c 2024-09-30 16:03:39.177245336 +0200 +@@ -27,6 +27,9 @@ #define SSHBUF_INTERNAL #include "sshbuf.h" #include "misc.h" +/* #include "log.h" */ + +#define BUF_WATERSHED 256*1024 -+ -+#ifdef SSHBUF_DEBUG -+# define SSHBUF_TELL(what) do { \ -+ printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \ -+ __FILE__, __LINE__, __func__, what, \ -+ buf->size, buf->alloc, buf->off, buf->max_size); \ -+ fflush(stdout); \ -+ } while (0) -+#else -+# define SSHBUF_TELL(what) -+#endif #ifdef SSHBUF_DEBUG # define SSHBUF_TELL(what) do { \ -@@ -45,12 +59,27 @@ - size_t off; /* First available byte is buf->d + buf->off */ - size_t size; /* Last byte is buf->d + buf->size - 1 */ - size_t max_size; /* Maximum size of buffer */ -+ size_t window_max; /* channel window max */ - size_t alloc; /* Total bytes allocated to buf->d */ +@@ -49,8 +52,29 @@ int readonly; /* Refers to external, const data */ u_int refcount; /* Tracks self and number of child buffers */ struct sshbuf *parent; /* If child, pointer to parent */ + char label[MAX_LABEL_LEN]; /* String for buffer label - debugging use */ -+ struct timeval buf_ts; /* creation time of buffer */ ++ int type; /* type of buffer enum (sshbuf_types)*/ }; ++/* update the label string for a given sshbuf. Useful ++ * for debugging */ +void +sshbuf_relabel(struct sshbuf *buf, const char *label) +{ @@ -12469,15 +12559,20 @@ diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c + strncpy(buf->label, label, MAX_LABEL_LEN-1); +} + -+float time_diff(struct timeval *start, struct timeval *end) ++/* set the type (from enum sshbuf_type) of the given sshbuf. ++ * The purpose is to allow different classes of buffers to ++ * follow different code paths if necessary */ ++void ++sshbuf_type(struct sshbuf *buf, int type) +{ -+ return (end->tv_sec - start->tv_sec) + 1e-6*(end->tv_usec - start->tv_usec); ++ if (type < BUF_MAX_TYPE) ++ buf->type = type; +} + static inline int sshbuf_check_sanity(const struct sshbuf *buf) { -@@ -89,7 +118,7 @@ +@@ -89,7 +113,7 @@ } struct sshbuf * @@ -12486,7 +12581,7 @@ diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c { struct sshbuf *ret; -@@ -100,6 +129,8 @@ +@@ -100,6 +124,8 @@ ret->readonly = 0; ret->refcount = 1; ret->parent = NULL; @@ -12495,97 +12590,27 @@ diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) { free(ret); return NULL; -@@ -218,7 +249,7 @@ - size_t - sshbuf_max_size(const struct sshbuf *buf) - { -- return buf->max_size; -+ return buf->max_size / 2; - } - - size_t -@@ -240,13 +271,18 @@ - } - - int --sshbuf_set_max_size(struct sshbuf *buf, size_t max_size) -+sshbuf_set_max_size(struct sshbuf *buf, size_t requested_size) - { -- size_t rlen; -+ size_t rlen, max_size = requested_size * 2; - u_char *dp; - int r; - -- SSHBUF_DBG(("set max buf = %p len = %zu", buf, max_size)); -+ /* -+ * Note that we set the actual allocation limit to be 2x the requested -+ * size. This is to avoid some pathological compaction behaviour later -+ * when a buffer is at capacity and has small drains/fills on it. -+ */ -+ SSHBUF_DBG(("set max buf = %p requested = %zu", buf, requested_size)); - if ((r = sshbuf_check_sanity(buf)) != 0) - return r; - if (max_size == buf->max_size) -@@ -255,9 +291,17 @@ - return SSH_ERR_BUFFER_READ_ONLY; - if (max_size > SSHBUF_SIZE_MAX) - return SSH_ERR_NO_BUFFER_SPACE; -- /* pack and realloc if necessary */ -- sshbuf_maybe_pack(buf, max_size < buf->size); -- if (max_size < buf->alloc && max_size > buf->size) { -+ /* -+ * Always pack as it makes everything that follows easier. -+ * Potentially expensive, but this should seldom be called on buffers -+ * that already contain data. -+ */ -+ sshbuf_maybe_pack(buf, 1); -+ /* Refuse setting a maximum below current amount of data in buffer */ -+ if (requested_size < buf->size) -+ return SSH_ERR_NO_BUFFER_SPACE; -+ /* Shrink alloc if the existing allocation is larger than requested */ -+ if (requested_size < buf->alloc) { - if (buf->size < SSHBUF_SIZE_INIT) - rlen = SSHBUF_SIZE_INIT; - else -@@ -271,8 +315,6 @@ - buf->alloc = rlen; - } - SSHBUF_TELL("new-max"); -- if (max_size < buf->alloc) -- return SSH_ERR_NO_BUFFER_SPACE; - buf->max_size = max_size; - return 0; - } -@@ -290,7 +332,7 @@ +@@ -290,7 +316,18 @@ { if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1) return 0; - return buf->max_size - (buf->size - buf->off); -+ return (buf->max_size / 2) - (buf->size - buf->off); ++ /* we need to reserve a small amount of overhead on the input buffer ++ * or we can enter into a pathological state during bulk ++ * data transfers. We use a fraction of the max size as we want it to scale ++ * with the size of the input buffer. If we do it for all of the buffers ++ * we fail the regression unit tests. This seems like a reasonable ++ * solution. Of course, I still need to figure out *why* this is ++ * happening and come up with an actual fix. TODO ++ * cjr 4/19/2024 */ ++ if (buf->type == BUF_CHANNEL_INPUT) ++ return buf->max_size / 1.05 - (buf->size - buf->off); ++ else ++ return buf->max_size - (buf->size - buf->off); } const u_char * -@@ -320,11 +362,18 @@ - return SSH_ERR_BUFFER_READ_ONLY; - SSHBUF_TELL("check"); - /* Check that len is reasonable and that max_size + available < len */ -- if (len > buf->max_size || buf->max_size - len < buf->size - buf->off) -+ if (len > (buf->max_size / 2) || -+ (buf->max_size / 2) - len < buf->size - buf->off) - return SSH_ERR_NO_BUFFER_SPACE; - return 0; - } - -+void -+sshbuf_set_window_max(struct sshbuf *buf, size_t len) -+{ -+ buf->window_max = len; -+} -+ - int - sshbuf_allocate(struct sshbuf *buf, size_t len) - { -@@ -350,9 +399,42 @@ +@@ -350,9 +387,36 @@ */ need = len + buf->size - buf->alloc; rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC); @@ -12593,52 +12618,45 @@ diff -Nur openssh-9.6p1.orig/sshbuf.c openssh-9.6p1/sshbuf.c + * slowly. It's knows that it needs to grow but it only does so 32K + * at a time. This means a lot of calls to realloc and memcpy which + * kills performance until the buffer reaches some maximum size. -+ * so we explicitly test for a buffer that's trying to grow and -+ * if it is then we push the growth to whatever the adjusted value of -+ * local_window_max happens to be. This significantly reduces overhead ++ * So we explicitly test for a buffer that's trying to grow and ++ * if it is then we push the growth by 4MB at a time. This can result in ++ * the buffer being over allocated (in terms of actual needs) but the ++ * process is fast. This significantly reduces overhead + * and improves performance. In this case we look for a buffer that is trying + * to grow larger than BUF_WATERSHED (256*1024 taken from PACKET_MAX_SIZE) -+ * and where the local_window_max isn't zero (which is usally in the Channels -+ * struct but we copied it into the shhbuf as window_max). If it is zero or -+ * the buffer is smaller than BUF_WATERSHED we just use the -+ * normal value for need. We also don't want to grow the buffer past -+ * what we need (the size of window_max) so if the current allocation (in -+ * buf->alloc) is greater than window_max we skip it. -+ * -+ * Turns out the extra functions on the following conditional aren't needed -+ * -cjr 04/06/23 ++ * and explcitly check that the buffer is being used for inbound outbound ++ * channel buffering. ++ * Updated for 18.4.1 -cjr 04/20/24 + */ -+ if (rlen > BUF_WATERSHED) { -+ /* debug_f ("Prior: label: %s, %p, rlen is %zu need is %zu win_max is %zu max_size is %zu", -+ buf->label, buf, rlen, need, buf->window_max, buf->max_size); */ ++ if (rlen > BUF_WATERSHED && (buf->type == BUF_CHANNEL_OUTPUT || buf->type == BUF_CHANNEL_INPUT)) { ++ /* debug_f ("Prior: label: %s, %p, rlen is %zu need is %zu max_size is %zu", ++ buf->label, buf, rlen, need, buf->max_size); */ + /* easiest thing to do is grow the nuffer by 4MB each time. It might end + * up being somewhat overallocated but works quickly */ + need = (4*1024*1024); + rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC); -+ /* debug_f ("Post: label: %s, %p, rlen is %zu need is %zu win_max is %zu max_size is %zu", */ -+ /* buf->label, buf, rlen, need, buf->window_max, buf->max_size); */ ++ /* debug_f ("Post: label: %s, %p, rlen is %zu need is %zu max_size is %zu", */ ++ /* buf->label, buf, rlen, need, buf->max_size); */ + } SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen)); -- if (rlen > buf->max_size) -- rlen = buf->alloc + need; + + /* rlen might be above the max allocation */ -+ if (rlen > buf->max_size) { + if (rlen > buf->max_size) +- rlen = buf->alloc + need; + rlen = buf->max_size; -+ /* debug_f("set rlen to %zu", buf->max_size);*/ -+ } ++ SSHBUF_DBG(("adjusted rlen %zu", rlen)); if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) { SSHBUF_DBG(("realloc fail")); -diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h ---- openssh-9.6p1.orig/sshbuf.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/sshbuf.h 2024-07-10 13:34:02.732358630 +0200 -@@ -28,10 +28,12 @@ +diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h +--- openssh-9.8p1.orig/sshbuf.h 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/sshbuf.h 2024-09-30 16:03:39.177245336 +0200 +@@ -28,18 +28,49 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ -#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ -+#define SSHBUF_SIZE_MAX 0xFFFFFFF /* Hard maximum size 256MB */ ++#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size 128MB */ #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ @@ -12647,12 +12665,23 @@ diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h struct sshbuf; -@@ -39,7 +41,18 @@ ++enum buffer_types { ++ BUF_CHANNEL_OUTPUT, ++ BUF_CHANNEL_INPUT, ++ BUF_CHANNEL_EXTENDED, ++ BUF_PACKET_INPUT, ++ BUF_PACKET_INCOMING, ++ BUF_PACKET_OUTPUT, ++ BUF_PACKET_OUTGOING, ++ BUF_MAX_TYPE ++}; ++ + /* * Create a new sshbuf buffer. * Returns pointer to buffer on success, or NULL on allocation failure. */ -struct sshbuf *sshbuf_new(void); -+/* struct sshbuf *sshbuf_new(void); */ ++/* struct sshbuf *sshbuf_new(void);*/ + +/* + * Create a new labeled sshbuf buffer. @@ -12664,10 +12693,17 @@ diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h + * relabel the sshbuf struct + */ +void sshbuf_relabel(struct sshbuf *, const char *); ++ ++/* ++ * assign a type (from the buffer_types enum) to ++ * the buffer. Used to quickly identify the purpose of ++ * the buffer. ++ */ ++void sshbuf_type(struct sshbuf *, int); /* * Create a new, read-only sshbuf buffer from existing data. -@@ -75,12 +88,13 @@ +@@ -75,12 +106,13 @@ void sshbuf_reset(struct sshbuf *buf); /* @@ -12683,7 +12719,7 @@ diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size); -@@ -344,6 +358,9 @@ +@@ -344,6 +376,9 @@ ((u_char *)(p))[1] = __v & 0xff; \ } while (0) @@ -12693,9 +12729,9 @@ diff -Nur openssh-9.6p1.orig/sshbuf.h openssh-9.6p1/sshbuf.h /* Internal definitions follow. Exposed for regress tests */ #ifdef SSHBUF_INTERNAL -diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c ---- openssh-9.6p1.orig/ssh.c 2024-07-10 13:32:39.602111820 +0200 -+++ openssh-9.6p1/ssh.c 2024-07-10 13:34:02.733358633 +0200 +diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c +--- openssh-9.8p1.orig/ssh.c 2024-09-30 16:02:22.622024497 +0200 ++++ openssh-9.8p1/ssh.c 2024-09-30 16:03:39.178245339 +0200 @@ -109,6 +109,7 @@ #include "ssherr.h" #include "myproposal.h" @@ -12753,7 +12789,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c if (addrs != NULL) freeaddrinfo(addrs); -@@ -1892,7 +1923,7 @@ +@@ -1896,7 +1927,7 @@ /* Do fork() after authentication. Used by "ssh -f" */ static void @@ -12762,13 +12798,14 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c { if (need_controlpersist_detach) control_persist_detach(); -@@ -1902,17 +1933,20 @@ +@@ -1906,17 +1937,21 @@ fatal("daemon() failed: %.200s", strerror(errno)); if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1) error_f("stdfd_devnull failed"); + /* we do the cipher switch here in the event that the client + is forking or has a delayed fork */ -+ cipher_switch(ssh); ++ if (options.disable_multithreaded == 0) ++ cipher_switch(ssh); } static void @@ -12785,7 +12822,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c } else { debug2_f("%d expected forwarding replies remaining", forward_confirms_pending); -@@ -1979,7 +2013,7 @@ +@@ -1983,7 +2018,7 @@ "for listen port %d", rfwd->listen_port); } } @@ -12794,7 +12831,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c } static void -@@ -2006,7 +2040,7 @@ +@@ -2010,7 +2045,7 @@ } debug_f("tunnel forward established, id=%d", id); @@ -12803,7 +12840,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c } static void -@@ -2207,6 +2241,15 @@ +@@ -2211,6 +2246,15 @@ NULL, fileno(stdin), command, environ); } @@ -12819,7 +12856,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2228,6 +2271,7 @@ +@@ -2232,6 +2276,7 @@ window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { @@ -12827,7 +12864,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2236,6 +2280,16 @@ +@@ -2240,6 +2285,12 @@ window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); @@ -12836,15 +12873,11 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c + c->dynamic_window = 1; + debug("Enabled Dynamic Window Scaling"); + } -+ -+ if (options.hpn_buffer_limit) -+ c->hpn_buffer_limit = 1; -+ + debug3_f("channel_new: %d", c->self); channel_send_open(ssh, c->self); -@@ -2252,6 +2306,13 @@ +@@ -2256,6 +2307,13 @@ int r, interactive, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -12858,7 +12891,7 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -@@ -2350,7 +2411,13 @@ +@@ -2354,7 +2412,14 @@ debug("deferring postauth fork until remote forward " "confirmation received"); } else @@ -12869,13 +12902,14 @@ diff -Nur openssh-9.6p1.orig/ssh.c openssh-9.6p1/ssh.c + * one of our parallel versions. If the client is + * forking then we handle it in fork_postauth() + */ -+ cipher_switch(ssh); ++ if (options.disable_multithreaded == 0) ++ cipher_switch(ssh); } return client_loop(ssh, tty_flag, tty_flag ? -diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 ---- openssh-9.6p1.orig/ssh_config.5 2024-07-10 13:32:39.603111823 +0200 -+++ openssh-9.6p1/ssh_config.5 2024-07-10 13:34:02.734358636 +0200 +diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 +--- openssh-9.8p1.orig/ssh_config.5 2024-09-30 16:02:22.623024499 +0200 ++++ openssh-9.8p1/ssh_config.5 2024-09-30 16:03:39.179245342 +0200 @@ -62,6 +62,19 @@ .Pq Pa /etc/ssh/ssh_config .El @@ -12896,19 +12930,17 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 Unless noted otherwise, for each parameter, the first obtained value will be used. The configuration files contain sections separated by -@@ -700,6 +713,11 @@ - then the backgrounded master connection will automatically terminate - after it has remained idle (with no client connections) for the - specified time. -+.It Cm DisableMTAES -+Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher -+back to the stock single-threaded AES-CTR cipher. This may prove to be more -+effcient in some circumstances. Default is -+.Cm no. HPNSSH only. - .It Cm DynamicForward - Specifies that a TCP port on the local machine be forwarded - over the secure channel, and the application -@@ -1111,6 +1129,20 @@ +@@ -795,6 +808,9 @@ + or + .Cm no + (the default). ++.It Cm FallbackPort ++Specifies the port hpnssh should try to connect to if it fails connecting to the ++default hpnsshd port of 2222. The default is port 22. HPN-SSH only. + .It Cm FingerprintHash + Specifies the hash algorithm used when displaying key fingerprints. + Valid options are: +@@ -1121,6 +1137,11 @@ .Cm Hostname specifications). The default is the name given on the command line. @@ -12916,20 +12948,11 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 +In some situations, such as transfers on a local area network, the impact +of the HPN code produces a net decrease in performance. In these cases it is +helpful to disable the HPN functionality. By default HPNDisabled is set to -+.Cm no. HPNSSH only. -+.It Cm HPNBufferLimit -+This option will force the hpnssh receive buffer to grow more slowly and limits -+the growth to one half of the TCP receive buffer. This option can prove useful -+in situation where a high speed path with larger RTTs are writing to a slower -+device or file system. Enabling this option will reduce performance but may provide -+a more stable connection. The option only impacts the receiving side of the connection. -+For example, a client receiving data from a server but not a client sending data. -+By default this option is set to +.Cm no. HPNSSH only. .It Cm IdentitiesOnly Specifies that .Xr ssh 1 -@@ -1484,6 +1516,63 @@ +@@ -1497,6 +1518,63 @@ .Pp The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -12993,7 +13016,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .It Cm NoHostAuthenticationForLocalhost Disable host authentication for localhost (loopback addresses). The argument to this keyword must be -@@ -1491,6 +1580,36 @@ +@@ -1504,6 +1582,36 @@ or .Cm no (the default). @@ -13030,7 +13053,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. -@@ -2048,6 +2167,12 @@ +@@ -2061,6 +2169,12 @@ Specify a configuration tag name that may be later used by a .Cm Match directive to select a block of configuration. @@ -13043,7 +13066,7 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 .It Cm Tunnel Request .Xr tun 4 -@@ -2404,3 +2529,11 @@ +@@ -2417,3 +2531,11 @@ created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -13055,9 +13078,9 @@ diff -Nur openssh-9.6p1.orig/ssh_config.5 openssh-9.6p1/ssh_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c ---- openssh-9.6p1.orig/sshconnect2.c 2024-07-10 13:32:39.603111823 +0200 -+++ openssh-9.6p1/sshconnect2.c 2024-07-10 13:34:02.734358636 +0200 +diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c +--- openssh-9.8p1.orig/sshconnect2.c 2024-09-30 16:02:22.623024499 +0200 ++++ openssh-9.8p1/sshconnect2.c 2024-09-30 16:03:39.180245345 +0200 @@ -76,6 +76,7 @@ #include "utf8.h" #include "ssh-sk.h" @@ -13080,7 +13103,7 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c * SSH2 key exchange */ -@@ -582,6 +590,42 @@ +@@ -573,6 +581,42 @@ if (!authctxt.success) fatal("Authentication failed."); @@ -13123,10 +13146,10 @@ diff -Nur openssh-9.6p1.orig/sshconnect2.c openssh-9.6p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 ---- openssh-9.6p1.orig/sshd.8 2024-07-10 13:32:39.603111823 +0200 -+++ openssh-9.6p1/sshd.8 2024-07-10 13:34:02.734358636 +0200 -@@ -1078,3 +1078,7 @@ +diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 +--- openssh-9.8p1.orig/sshd.8 2024-09-30 16:02:22.624024502 +0200 ++++ openssh-9.8p1/sshd.8 2024-09-30 16:03:39.181245348 +0200 +@@ -1075,3 +1075,7 @@ protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. @@ -13134,10 +13157,10 @@ diff -Nur openssh-9.6p1.orig/sshd.8 openssh-9.6p1/sshd.8 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c ---- openssh-9.6p1.orig/sshd.c 2024-07-10 13:32:39.604111826 +0200 -+++ openssh-9.6p1/sshd.c 2024-07-10 13:34:02.735358639 +0200 -@@ -1093,6 +1093,8 @@ +diff -Nur openssh-9.8p1.orig/sshd.c openssh-9.8p1/sshd.c +--- openssh-9.8p1.orig/sshd.c 2024-09-30 16:02:22.578024370 +0200 ++++ openssh-9.8p1/sshd.c 2024-09-30 16:03:39.182245351 +0200 +@@ -753,6 +753,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -13146,7 +13169,7 @@ diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1138,6 +1140,10 @@ +@@ -798,6 +800,10 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -13157,7 +13180,7 @@ diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1876,6 +1882,19 @@ +@@ -1421,6 +1427,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -13177,31 +13200,9 @@ diff -Nur openssh-9.6p1.orig/sshd.c openssh-9.6p1/sshd.c /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && -@@ -2359,6 +2378,9 @@ - rdomain == NULL ? "" : "\""); - free(laddr); - -+ /* set the HPN options for the child */ -+ channel_set_hpn_disabled(options.hpn_disabled); -+ - /* - * We don't want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is -@@ -2545,6 +2567,11 @@ - struct kex *kex; - int r; - -+ if (options.none_enabled == 1) -+ debug("WARNING: None cipher enabled"); -+ if (options.nonemac_enabled == 1) -+ debug("WARNING: None MAC enabled"); -+ - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config ---- openssh-9.6p1.orig/sshd_config 2024-07-10 13:32:39.604111826 +0200 -+++ openssh-9.6p1/sshd_config 2024-07-10 13:34:02.735358639 +0200 +diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config +--- openssh-9.8p1.orig/sshd_config 2024-09-30 16:02:22.624024502 +0200 ++++ openssh-9.8p1/sshd_config 2024-10-02 15:40:20.779644727 +0200 @@ -19,6 +19,7 @@ # semanage port -a -t ssh_port_t -p tcp #PORTNUMBER # @@ -13210,7 +13211,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: -@@ -127,6 +128,24 @@ +@@ -127,6 +128,19 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -13226,18 +13227,13 @@ diff -Nur openssh-9.6p1.orig/sshd_config openssh-9.6p1/sshd_config + +# allow the use of the none MAC +#NoneMacEnabled no -+ -+# clamp the server's receive buffer to -+# 1/2 the tcp receive window. This may be useful -+# in some environments. -+#HPNBufferLimit no + # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 ---- openssh-9.6p1.orig/sshd_config.5 2024-07-10 13:32:39.605111829 +0200 -+++ openssh-9.6p1/sshd_config.5 2024-07-10 13:34:02.736358642 +0200 +diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 +--- openssh-9.8p1.orig/sshd_config.5 2024-09-30 16:02:22.624024502 +0200 ++++ openssh-9.8p1/sshd_config.5 2024-09-30 16:03:39.183245354 +0200 @@ -56,6 +56,16 @@ .Pq \&" in order to represent arguments containing spaces. @@ -13255,7 +13251,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): -@@ -659,6 +669,10 @@ +@@ -667,6 +677,10 @@ TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. @@ -13266,7 +13262,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -892,6 +906,21 @@ +@@ -900,6 +914,11 @@ The default for this option is: The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . @@ -13275,20 +13271,10 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 +of the HPN code produces a net decrease in performance. In these cases it is +helpful to disable the HPN functionality. By default HPNDisabled is set to +.CM no. -+.It Cm HPNBufferLimit -+This option will force the hpnssh receive buffer to grow more slowly and limits -+the growth to one half of the TCP receive buffer. This option can prove useful -+in situation where a high speed path with larger RTTs are writing to a slower -+device or file system. Enabling this option will reduce performance but may provide -+a more stable connection. The option only impacts the receiving side of the connection. -+For example, a client receiving data from a server but not a client sending data. If -+enabled on a server this will impact all incoming connections. -+By default this option is set to -+.Cm no. HPNSSH only. .It Cm IgnoreRhosts Specifies whether to ignore per-user .Pa .rhosts -@@ -1393,6 +1422,19 @@ +@@ -1408,6 +1427,19 @@ key exchange methods. The default is .Pa /etc/moduli . @@ -13305,10 +13291,10 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 +protection against man-in-the-middle attacks. As with NoneEnabled all authentication +remains encrypted and integrity is ensured. Default is +.Cm no. - .It Cm PasswordAuthentication - Specifies whether password authentication is allowed. - The default is -@@ -1835,6 +1877,13 @@ + .It Cm PAMServiceName + Specifies the service name used for Pluggable Authentication Modules (PAM) + authentication, authorisation and session controls when +@@ -1952,6 +1984,13 @@ .Pp To disable TCP keepalive messages, the value should be set to .Cm no . @@ -13322,7 +13308,7 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -2133,3 +2182,11 @@ +@@ -2250,3 +2289,11 @@ and .An Markus Friedl contributed support for privilege separation. @@ -13334,9 +13320,55 @@ diff -Nur openssh-9.6p1.orig/sshd_config.5 openssh-9.6p1/sshd_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.6p1.orig/ssh.h openssh-9.6p1/ssh.h ---- openssh-9.6p1.orig/ssh.h 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh.h 2024-07-10 13:34:02.736358642 +0200 +diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c +--- openssh-9.8p1.orig/sshd-session.c 2024-09-30 16:02:22.625024505 +0200 ++++ openssh-9.8p1/sshd-session.c 2024-09-30 16:03:39.184245357 +0200 +@@ -1158,6 +1158,20 @@ + } + endpwent(); + ++ /* get NONE options */ ++ if (options.none_enabled == 1) { ++ char *old_ciphers = options.ciphers; ++ xasprintf(&options.ciphers, "%s,none", old_ciphers); ++ free(old_ciphers); ++ ++ /* only enable the none MAC in context of the none cipher -cjr */ ++ if (options.nonemac_enabled == 1) { ++ char *old_macs = options.macs; ++ xasprintf(&options.macs, "%s,none", old_macs); ++ free(old_macs); ++ } ++ } ++ + if (!debug_flag) { + startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); + close(REEXEC_STARTUP_PIPE_FD); +@@ -1365,6 +1379,9 @@ + rdomain == NULL ? "" : "\""); + free(laddr); + ++ /* set the HPN options for the child */ ++ channel_set_hpn_disabled(options.hpn_disabled); ++ + /* + * We don't want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is +@@ -1525,6 +1542,11 @@ + struct kex *kex; + int r; + ++ if (options.none_enabled == 1) ++ debug("WARNING: None cipher enabled"); ++ if (options.nonemac_enabled == 1) ++ debug("WARNING: None MAC enabled"); ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +diff -Nur openssh-9.8p1.orig/ssh.h openssh-9.8p1/ssh.h +--- openssh-9.8p1.orig/ssh.h 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/ssh.h 2024-09-30 16:03:39.185245360 +0200 @@ -17,6 +17,7 @@ /* Default port number. */ @@ -13354,10 +13386,10 @@ diff -Nur openssh-9.6p1.orig/ssh.h openssh-9.6p1/ssh.h /* * Name of the environment variable containing the process ID of the -diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c ---- openssh-9.6p1.orig/sshkey.c 2024-07-10 13:32:39.561111698 +0200 -+++ openssh-9.6p1/sshkey.c 2024-07-10 13:34:02.737358645 +0200 -@@ -1780,7 +1780,8 @@ +diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c +--- openssh-9.8p1.orig/sshkey.c 2024-09-30 16:02:22.579024372 +0200 ++++ openssh-9.8p1/sshkey.c 2024-09-30 16:03:39.185245360 +0200 +@@ -1784,7 +1784,8 @@ stderr); #endif if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13367,7 +13399,7 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c goto out; /* Serialise and encrypt the private key using the ephemeral key */ -@@ -1915,7 +1916,8 @@ +@@ -1919,7 +1920,8 @@ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13377,7 +13409,7 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c goto out; #ifdef DEBUG_PK fprintf(stderr, "%s: key+iv\n", __func__); -@@ -2983,6 +2985,13 @@ +@@ -2987,6 +2989,13 @@ kdfname = "none"; } else if (ciphername == NULL) ciphername = DEFAULT_CIPHERNAME; @@ -13391,7 +13423,7 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; -@@ -3018,7 +3027,7 @@ +@@ -3022,7 +3031,7 @@ goto out; } if ((r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13400,7 +13432,7 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c goto out; if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || -@@ -3205,6 +3214,8 @@ +@@ -3209,6 +3218,8 @@ (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) goto out; @@ -13409,7 +13441,7 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; -@@ -3260,7 +3271,7 @@ +@@ -3264,7 +3275,7 @@ /* decrypt private portion of key */ if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || (r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13418,9 +13450,9 @@ diff -Nur openssh-9.6p1.orig/sshkey.c openssh-9.6p1/sshkey.c goto out; if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), encrypted_len, 0, authlen)) != 0) { -diff -Nur openssh-9.6p1.orig/sshkey-xmss.c openssh-9.6p1/sshkey-xmss.c ---- openssh-9.6p1.orig/sshkey-xmss.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/sshkey-xmss.c 2024-07-10 13:34:02.737358645 +0200 +diff -Nur openssh-9.8p1.orig/sshkey-xmss.c openssh-9.8p1/sshkey-xmss.c +--- openssh-9.8p1.orig/sshkey-xmss.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/sshkey-xmss.c 2024-09-30 16:03:39.186245362 +0200 @@ -903,9 +903,29 @@ state->enc_keyiv == NULL || state->enc_ciphername == NULL) @@ -13505,9 +13537,9 @@ diff -Nur openssh-9.6p1.orig/sshkey-xmss.c openssh-9.6p1/sshkey-xmss.c (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), encrypted_len, aadlen, authlen)) != 0) goto out; -diff -Nur openssh-9.6p1.orig/umac.c openssh-9.6p1/umac.c ---- openssh-9.6p1.orig/umac.c 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/umac.c 2024-07-10 13:34:02.738358648 +0200 +diff -Nur openssh-9.8p1.orig/umac.c openssh-9.8p1/umac.c +--- openssh-9.8p1.orig/umac.c 2024-07-01 06:36:28.000000000 +0200 ++++ openssh-9.8p1/umac.c 2024-10-01 09:50:36.972376774 +0200 @@ -134,15 +134,48 @@ /* --- Endian Conversion --- Forcing assembly on some platforms */ /* ---------------------------------------------------------------------- */ @@ -13560,9 +13592,9 @@ diff -Nur openssh-9.6p1.orig/umac.c openssh-9.6p1/umac.c #define STORE_UINT32_BIG(p,v) put_u32(p, v) /* ---------------------------------------------------------------------- */ -diff -Nur openssh-9.6p1.orig/uthash.h openssh-9.6p1/uthash.h ---- openssh-9.6p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.6p1/uthash.h 2024-07-10 13:34:02.738358648 +0200 +diff -Nur openssh-9.8p1.orig/uthash.h openssh-9.8p1/uthash.h +--- openssh-9.8p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.8p1/uthash.h 2024-09-30 16:03:39.187245365 +0200 @@ -0,0 +1,1140 @@ +/* +Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ @@ -14704,14 +14736,14 @@ diff -Nur openssh-9.6p1.orig/uthash.h openssh-9.6p1/uthash.h +} UT_hash_handle; + +#endif /* UTHASH_H */ -diff -Nur openssh-9.6p1.orig/version.h openssh-9.6p1/version.h ---- openssh-9.6p1.orig/version.h 2024-07-10 13:32:39.605111829 +0200 -+++ openssh-9.6p1/version.h 2024-07-10 14:25:00.449370077 +0200 +diff -Nur openssh-9.8p1.orig/version.h openssh-9.8p1/version.h +--- openssh-9.8p1.orig/version.h 2024-09-30 16:02:22.625024505 +0200 ++++ openssh-9.8p1/version.h 2024-10-01 10:07:08.736253374 +0200 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" #define GSI_PORTABLE "c-GSI" -+#define SSH_HPN "-hpn18.3.1" ++#define SSH_HPN "_hpn18.5.1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ - GSI_VERSION KRB5_VERSION + GSI_VERSION KRB5_VERSION SSH_HPN diff --git a/openssh-9.8p1-systemd.patch b/openssh-9.8p1-systemd.patch deleted file mode 100644 index b20624e..0000000 --- a/openssh-9.8p1-systemd.patch +++ /dev/null @@ -1,201 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 379cd746b..15e2ecdb7 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -907,6 +907,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) - AC_DEFINE([USE_BTMP]) - AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) -+ AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) - inet6_default_4in6=yes - case `uname -r` in - 1.*|2.0.*) -diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 0457e28d0..df7290246 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -21,16 +21,23 @@ - - #include "includes.h" - --#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) -+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \ -+ defined(SYSTEMD_NOTIFY) -+#include -+#include -+ - #include -+#include - #include - #include - #include - #include -+#include - - #include "log.h" - #include "xmalloc.h" - #include "port-linux.h" -+#include "misc.h" - - #ifdef WITH_SELINUX - #include -@@ -310,4 +317,90 @@ oom_adjust_restore(void) - return; - } - #endif /* LINUX_OOM_ADJUST */ --#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -+ -+#ifdef SYSTEMD_NOTIFY -+ -+static void ssh_systemd_notify(const char *, ...) -+ __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1))); -+ -+static void -+ssh_systemd_notify(const char *fmt, ...) -+{ -+ char *s = NULL; -+ const char *path; -+ struct stat sb; -+ struct sockaddr_un addr; -+ int fd = -1; -+ va_list ap; -+ -+ if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0) -+ return; -+ -+ va_start(ap, fmt); -+ xvasprintf(&s, fmt, ap); -+ va_end(ap); -+ -+ /* Only AF_UNIX is supported, with path or abstract sockets */ -+ if (path[0] != '/' && path[0] != '@') { -+ error_f("socket \"%s\" is not compatible with AF_UNIX", path); -+ goto out; -+ } -+ -+ if (path[0] == '/' && stat(path, &sb) != 0) { -+ error_f("socket \"%s\" stat: %s", path, strerror(errno)); -+ goto out; -+ } -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sun_family = AF_UNIX; -+ if (strlcpy(addr.sun_path, path, -+ sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) { -+ error_f("socket path \"%s\" too long", path); -+ goto out; -+ } -+ /* Support for abstract socket */ -+ if (addr.sun_path[0] == '@') -+ addr.sun_path[0] = 0; -+ if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) { -+ error_f("socket \"%s\": %s", path, strerror(errno)); -+ goto out; -+ } -+ if (connect(fd, &addr, sizeof(addr)) != 0) { -+ error_f("socket \"%s\" connect: %s", path, strerror(errno)); -+ goto out; -+ } -+ if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) { -+ error_f("socket \"%s\" write: %s", path, strerror(errno)); -+ goto out; -+ } -+ debug_f("socket \"%s\" notified %s", path, s); -+ out: -+ if (fd != -1) -+ close(fd); -+ free(s); -+} -+ -+void -+ssh_systemd_notify_ready(void) -+{ -+ ssh_systemd_notify("READY=1"); -+} -+ -+void -+ssh_systemd_notify_reload(void) -+{ -+ struct timespec now; -+ -+ monotime_ts(&now); -+ if (now.tv_sec < 0 || now.tv_nsec < 0) { -+ error_f("monotime returned negative value"); -+ ssh_systemd_notify("RELOADING=1"); -+ } else { -+ ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu", -+ ((uint64_t)now.tv_sec * 1000000ULL) + -+ ((uint64_t)now.tv_nsec / 1000ULL)); -+ } -+} -+#endif /* SYSTEMD_NOTIFY */ -+ -+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */ -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 3c22a854d..14064f87d 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -30,4 +30,9 @@ void oom_adjust_restore(void); - void oom_adjust_setup(void); - #endif - -+#ifdef SYSTEMD_NOTIFY -+void ssh_systemd_notify_ready(void); -+void ssh_systemd_notify_reload(void); -+#endif -+ - #endif /* ! _PORT_LINUX_H */ -diff --git a/platform.c b/platform.c -index 4fe8744ee..9cf818153 100644 ---- a/platform.c -+++ b/platform.c -@@ -44,6 +44,14 @@ platform_pre_listen(void) - #endif - } - -+void -+platform_post_listen(void) -+{ -+#ifdef SYSTEMD_NOTIFY -+ ssh_systemd_notify_ready(); -+#endif -+} -+ - void - platform_pre_fork(void) - { -@@ -55,6 +63,9 @@ platform_pre_fork(void) - void - platform_pre_restart(void) - { -+#ifdef SYSTEMD_NOTIFY -+ ssh_systemd_notify_reload(); -+#endif - #ifdef LINUX_OOM_ADJUST - oom_adjust_restore(); - #endif -diff --git a/platform.h b/platform.h -index 7fef8c983..5dec23276 100644 ---- a/platform.h -+++ b/platform.h -@@ -21,6 +21,7 @@ - void platform_pre_listen(void); - void platform_pre_fork(void); - void platform_pre_restart(void); -+void platform_post_listen(void); - void platform_post_fork_parent(pid_t child_pid); - void platform_post_fork_child(void); - int platform_privileged_uidswap(void); -diff --git a/sshd.c b/sshd.c -index 9cbe92293..3c3f2dd6b 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2077,6 +2077,8 @@ main(int ac, char **av) - ssh_signal(SIGTERM, sigterm_handler); - ssh_signal(SIGQUIT, sigterm_handler); - -+ platform_post_listen(); -+ - /* - * Write out the pid file after the sigterm handler - * is setup and the listen sockets are bound diff --git a/sources b/sources index b461406..1f1ded8 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-9.6p1.tar.gz) = 0ebf81e39914c3a90d7777a001ec7376a94b37e6024baf3e972c58f0982b7ddef942315f5e01d56c00ff95603b4a20ee561ab918ecc55511df007ac138160509 -SHA512 (openssh-9.6p1.tar.gz.asc) = aec5a5bd6ce480a8e5b5879dc55f8186aec90fe61f085aa92ad7d07f324574aa781be09c83b7443a32848d091fd44fb12c1842d49cee77afc351e550ffcc096d +SHA512 (openssh-9.8p1.tar.gz) = 95dec2f18e58eb47994f3de4430253e0665e185564b65088ca5f4108870e05feddef8cda8d3c0a4b75f18b98cc2c024df0e27de53b48c1a16da8da483cb8292a +SHA512 (openssh-9.8p1.tar.gz.asc) = 4df1f1be2c6ab7f3aebaedd0a773b0e8c8929abb30cd3415873ad55d012cfa113f792e888e5e772dd468c394aeb7e35d62893a514dbc0ab1a03acd79918657f7 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From c81b691d2c61abc4885898f2b321f3d4ae543ab6 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Thu, 3 Oct 2024 00:52:03 +0200 Subject: [PATCH 132/146] Based on openssh-9.8p1-4.fc42 --- gsi-openssh.spec | 10 +- ....patch => openssh-9.6p1-gssapi-keyex.patch | 1937 ++++++++-------- openssh-9.6p1-gsskex-new-api.patch | 1965 ----------------- 3 files changed, 1074 insertions(+), 2838 deletions(-) rename openssh-8.0p1-gssapi-keyex.patch => openssh-9.6p1-gssapi-keyex.patch (76%) delete mode 100644 openssh-9.6p1-gsskex-new-api.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index afd571d..a07c006 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.8p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -96,7 +96,7 @@ Patch711: openssh-7.8p1-UsePAM-warning.patch # Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 -Patch800: openssh-8.0p1-gssapi-keyex.patch +Patch800: openssh-9.6p1-gssapi-keyex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html Patch801: openssh-6.6p1-force_krb.patch # add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) @@ -107,8 +107,6 @@ 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 @@ -303,7 +301,6 @@ 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 @@ -564,6 +561,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Wed Oct 02 2024 Mattias Ellert - 9.8p1-2 +- Based on openssh-9.8p1-4.fc42 + * Fri Sep 27 2024 Mattias Ellert - 9.8p1-1 - Based on openssh-9.8p1-3.fc41.1 diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-9.6p1-gssapi-keyex.patch similarity index 76% rename from openssh-8.0p1-gssapi-keyex.patch rename to openssh-9.6p1-gssapi-keyex.patch index 82b2bfe..e63b258 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-9.6p1-gssapi-keyex.patch @@ -1,6 +1,6 @@ diff --color -ruNp a/auth2.c b/auth2.c ---- a/auth2.c 2024-08-28 12:35:01.189659493 +0200 -+++ b/auth2.c 2024-08-28 12:35:41.246432045 +0200 +--- a/auth2.c 2024-09-16 11:45:56.858133241 +0200 ++++ b/auth2.c 2024-09-16 11:46:34.688939755 +0200 @@ -71,6 +71,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; @@ -18,8 +18,8 @@ diff --color -ruNp a/auth2.c b/auth2.c #endif &method_passwd, diff --color -ruNp a/auth2-gss.c b/auth2-gss.c ---- a/auth2-gss.c 2024-08-28 12:35:01.189659493 +0200 -+++ b/auth2-gss.c 2024-08-28 12:35:41.265432411 +0200 +--- a/auth2-gss.c 2024-09-16 11:45:56.858133241 +0200 ++++ b/auth2-gss.c 2024-09-16 11:46:34.689939776 +0200 @@ -51,6 +51,7 @@ #define SSH_GSSAPI_MAX_MECHS 2048 @@ -109,7 +109,7 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c userauth_gssapi, diff --color -ruNp a/auth2-methods.c b/auth2-methods.c --- a/auth2-methods.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/auth2-methods.c 2024-08-28 12:35:41.265432411 +0200 ++++ b/auth2-methods.c 2024-09-16 11:46:34.689939776 +0200 @@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = &options.pubkey_authentication }; @@ -132,7 +132,7 @@ diff --color -ruNp a/auth2-methods.c b/auth2-methods.c &methodcfg_passwd, diff --color -ruNp a/auth.c b/auth.c --- a/auth.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/auth.c 2024-08-28 12:35:41.245432026 +0200 ++++ b/auth.c 2024-09-16 11:46:34.690939798 +0200 @@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || @@ -145,7 +145,7 @@ diff --color -ruNp a/auth.c b/auth.c case PERMIT_FORCED_ONLY: diff --color -ruNp a/canohost.c b/canohost.c --- a/canohost.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/canohost.c 2024-08-28 12:35:41.246432045 +0200 ++++ b/canohost.c 2024-09-16 11:46:34.690939798 +0200 @@ -35,6 +35,99 @@ #include "canohost.h" #include "misc.h" @@ -248,7 +248,7 @@ diff --color -ruNp a/canohost.c b/canohost.c { diff --color -ruNp a/canohost.h b/canohost.h --- a/canohost.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/canohost.h 2024-08-28 12:35:41.246432045 +0200 ++++ b/canohost.h 2024-09-16 11:46:34.690939798 +0200 @@ -15,6 +15,9 @@ #ifndef _CANOHOST_H #define _CANOHOST_H @@ -261,7 +261,7 @@ diff --color -ruNp a/canohost.h b/canohost.h char *get_local_ipaddr(int); diff --color -ruNp a/clientloop.c b/clientloop.c --- a/clientloop.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/clientloop.c 2024-08-28 12:35:41.246432045 +0200 ++++ b/clientloop.c 2024-09-16 11:46:34.690939798 +0200 @@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -289,8 +289,8 @@ diff --color -ruNp a/clientloop.c b/clientloop.c if (conn_in_ready) client_process_net_input(ssh); diff --color -ruNp a/configure.ac b/configure.ac ---- a/configure.ac 2024-08-28 12:35:01.202659743 +0200 -+++ b/configure.ac 2024-08-28 12:35:41.247432064 +0200 +--- a/configure.ac 2024-09-16 11:45:56.870133497 +0200 ++++ b/configure.ac 2024-09-16 11:46:34.691939819 +0200 @@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeL [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], @@ -324,7 +324,7 @@ diff --color -ruNp a/configure.ac b/configure.ac AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --color -ruNp a/gss-genr.c b/gss-genr.c --- a/gss-genr.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-genr.c 2024-08-28 12:35:41.248432084 +0200 ++++ b/gss-genr.c 2024-09-16 11:46:34.708940181 +0200 @@ -42,9 +42,33 @@ #include "sshbuf.h" #include "log.h" @@ -519,7 +519,28 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -216,7 +393,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de +@@ -168,6 +345,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) + (*ctx)->creds = GSS_C_NO_CREDENTIAL; + (*ctx)->client = GSS_C_NO_NAME; + (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; ++ (*ctx)->first = 1; + } + + /* Delete our context, providing it has been built correctly */ +@@ -193,6 +371,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) + gss_release_name(&ms, &(*ctx)->client); + if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->client_creds); ++ sshbuf_free((*ctx)->shared_secret); ++ sshbuf_free((*ctx)->server_pubkey); ++ sshbuf_free((*ctx)->server_host_key_blob); ++ sshbuf_free((*ctx)->server_blob); ++ explicit_bzero((*ctx)->hash, sizeof((*ctx)->hash)); ++ BN_clear_free((*ctx)->dh_client_pub); + + free(*ctx); + *ctx = NULL; +@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -528,7 +549,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -246,8 +423,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -246,8 +430,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -571,7 +592,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -255,6 +466,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -591,7 +612,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -271,11 +495,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co +@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co } int @@ -609,7 +630,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -285,6 +514,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -285,6 +521,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -620,7 +641,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -294,10 +527,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -690,7 +711,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c #endif /* GSSAPI */ diff --color -ruNp a/gss-serv.c b/gss-serv.c --- a/gss-serv.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-serv.c 2024-08-28 12:35:41.248432084 +0200 ++++ b/gss-serv.c 2024-09-16 11:46:34.692939840 +0200 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ @@ -984,7 +1005,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c /* Privileged */ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c --- a/gss-serv-krb5.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-serv-krb5.c 2024-08-28 12:35:41.248432084 +0200 ++++ b/gss-serv-krb5.c 2024-09-16 11:46:34.692939840 +0200 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ @@ -1123,8 +1144,8 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c #endif /* KRB5 */ diff --color -ruNp a/kex.c b/kex.c --- a/kex.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex.c 2024-08-28 12:35:41.249432103 +0200 -@@ -303,17 +303,37 @@ static int ++++ b/kex.c 2024-09-16 11:46:34.692939840 +0200 +@@ -297,17 +297,37 @@ static int kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { int r; @@ -1168,7 +1189,7 @@ diff --color -ruNp a/kex.c b/kex.c (r = sshbuf_put_cstring(m, "0")) != 0) { error_fr(r, "compose"); return r; -@@ -737,6 +737,9 @@ kex_free(struct kex *kex) +@@ -737,6 +757,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); @@ -1180,7 +1201,7 @@ diff --color -ruNp a/kex.c b/kex.c free(kex->failed_choice); diff --color -ruNp a/kexdh.c b/kexdh.c --- a/kexdh.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kexdh.c 2024-08-28 12:35:41.249432103 +0200 ++++ b/kexdh.c 2024-09-16 11:46:34.693939862 +0200 @@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { @@ -1207,7 +1228,7 @@ diff --color -ruNp a/kexdh.c b/kexdh.c case KEX_DH_GRP18_SHA512: diff --color -ruNp a/kexgen.c b/kexgen.c --- a/kexgen.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kexgen.c 2024-08-28 12:35:41.249432103 +0200 ++++ b/kexgen.c 2024-09-16 11:46:34.693939862 +0200 @@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1219,8 +1240,8 @@ diff --color -ruNp a/kexgen.c b/kexgen.c const struct sshbuf *client_version, diff --color -ruNp a/kexgssc.c b/kexgssc.c --- a/kexgssc.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgssc.c 2024-08-28 12:35:41.250432122 +0200 -@@ -0,0 +1,612 @@ ++++ b/kexgssc.c 2024-09-16 11:46:34.709940203 +0200 +@@ -0,0 +1,704 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1270,38 +1291,206 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c + +#include "ssh-gss.h" + ++static int input_kexgss_hostkey(int, u_int32_t, struct ssh *); ++static int input_kexgss_continue(int, u_int32_t, struct ssh *); ++static int input_kexgss_complete(int, u_int32_t, struct ssh *); ++static int input_kexgss_error(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_group(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_complete(int, u_int32_t, struct ssh *); ++ ++static int ++kexgss_final(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ struct sshbuf *empty = NULL; ++ struct sshbuf *shared_secret = NULL; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ int r; ++ ++ /* ++ * We _must_ have received a COMPLETE message in reply from the ++ * server, which will have set server_blob and msg_tok ++ */ ++ ++ /* compute shared secret */ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_dec(kex, gss->server_blob, &shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ if (sshbuf_ptr(gss->server_blob)[sshbuf_len(gss->server_blob)] & 0x80) ++ fatal("The received key has MSB of last octet set!"); ++ r = kex_c25519_dec(kex, gss->server_blob, &shared_secret); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ if (sshbuf_len(gss->server_blob) != 65) ++ fatal("The received NIST-P256 key did not match " ++ "expected length (expected 65, got %zu)", ++ sshbuf_len(gss->server_blob)); ++ ++ if (sshbuf_ptr(gss->server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) ++ fatal("The received NIST-P256 key does not have first octet 0x04"); ++ ++ r = kex_ecdh_dec(kex, gss->server_blob, &shared_secret); ++ break; ++ default: ++ r = SSH_ERR_INVALID_ARGUMENT; ++ break; ++ } ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ goto out; ++ } ++ ++ if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ hashlen = sizeof(hash); ++ r = kex_gen_hash(kex->hash_alg, kex->client_version, ++ kex->server_version, kex->my, kex->peer, ++ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), ++ kex->client_pub, gss->server_blob, shared_secret, ++ hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) ++ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; ++ ++ /* Verify that the hash matches the MIC we just got. */ ++ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) ++ sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); ++ ++ gss_release_buffer(&gss->minor, &gss->msg_tok); ++ ++ if (kex->gss_deleg_creds) ++ ssh_gssapi_credentials_updated(gss); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = gss; ++ else ++ ssh_gssapi_delete_ctx(&kex->gss); ++ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++ ++ if (kex->gss != NULL) { ++ sshbuf_free(gss->server_host_key_blob); ++ gss->server_host_key_blob = NULL; ++ sshbuf_free(gss->server_blob); ++ gss->server_blob = NULL; ++ } ++out: ++ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); ++ explicit_bzero(hash, sizeof(hash)); ++ sshbuf_free(shared_secret); ++ sshbuf_free(kex->client_pub); ++ kex->client_pub = NULL; ++ return r; ++} ++ ++static int ++kexgss_init_ctx(struct ssh *ssh, ++ gss_buffer_desc *token_ptr) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags; ++ int r; ++ ++ debug("Calling gss_init_sec_context"); ++ ++ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, ++ token_ptr, &send_tok, &ret_flags); ++ ++ if (GSS_ERROR(gss->major)) { ++ /* XXX Useless code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } ++ ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&gss->minor, token_ptr); ++ ++ if (gss->major == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); ++ ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (gss->first) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ gss->first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("failed to send packet: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgss_complete); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); ++ return 0; ++ } ++ /* No data, and not complete */ ++ if (gss->major != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgss_init_ctx(ssh, token_ptr); ++ ++ return kexgss_final(ssh); ++} ++ +int +kexgss_client(struct ssh *ssh) +{ + struct kex *kex = ssh->kex; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, -+ recv_tok = GSS_C_EMPTY_BUFFER, -+ gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; -+ Gssctxt *ctxt; -+ OM_uint32 maj_status, min_status, ret_flags; -+ struct sshbuf *server_blob = NULL; -+ struct sshbuf *shared_secret = NULL; -+ struct sshbuf *server_host_key_blob = NULL; -+ struct sshbuf *empty = NULL; -+ u_char *msg; -+ int type = 0; -+ int first = 1; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ u_char c; + int r; + + /* Initialise our GSSAPI world */ -+ ssh_gssapi_build_ctx(&ctxt); -+ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) -+ == GSS_C_NO_OID) ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) + fatal("Couldn't identify host exchange"); + -+ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) ++ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) + fatal("Couldn't import hostname"); + + if (kex->gss_client && -+ ssh_gssapi_client_identity(ctxt, kex->gss_client)) ++ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) + fatal("Couldn't acquire client credentials"); + + /* Step 1 */ @@ -1322,521 +1511,445 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c + fatal_f("Unexpected KEX type %d", kex->kex_type); + } + if (r != 0) { -+ ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + return r; + } ++ return kexgss_init_ctx(ssh, GSS_C_NO_BUFFER); ++} + -+ token_ptr = GSS_C_NO_BUFFER; ++static int ++input_kexgss_hostkey(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ u_char *tmp = NULL; ++ size_t tmp_len = 0; ++ int r; + -+ do { -+ debug("Calling gss_init_sec_context"); ++ debug("Received KEXGSS_HOSTKEY"); ++ if (gss->server_host_key_blob) ++ fatal("Server host key received more than once"); ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) ++ fatal("Failed to read server host key: %s", ssh_err(r)); ++ if ((gss->server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); ++ return 0; ++} + -+ maj_status = ssh_gssapi_init_ctx(ctxt, -+ kex->gss_deleg_creds, token_ptr, &send_tok, -+ &ret_flags); ++static int ++input_kexgss_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ int r; + -+ if (GSS_ERROR(maj_status)) { -+ /* XXX Useles code: Missing send? */ -+ if (send_tok.length != 0) { -+ if ((r = sshpkt_start(ssh, -+ SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, -+ send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ fatal("gss_init_context failed"); -+ } ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); + -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ gss_release_buffer(&min_status, &recv_tok); ++ debug("Received GSSAPI_CONTINUE"); ++ if (gss->major == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ return kexgss_init_ctx(ssh, &recv_tok); ++} + -+ if (maj_status == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); ++static int ++input_kexgss_complete(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ u_char c; ++ int r; + -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); + -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (first) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, -+ send_tok.length)) != 0 || -+ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ first = 0; -+ } else { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, -+ send_tok.length)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ } -+ if ((r = sshpkt_send(ssh)) != 0) -+ fatal("failed to send packet: %s", ssh_err(r)); -+ gss_release_buffer(&min_status, &send_tok); ++ debug("Received GSSAPI_COMPLETE"); ++ if (gss->msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) ++ fatal("Failed to read message: %s", ssh_err(r)); + -+ /* If we've sent them data, they should reply */ -+ do { -+ type = ssh_packet_read(ssh); -+ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ u_char *tmp = NULL; -+ size_t tmp_len = 0; ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (gss->major == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ if (gss->major != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); ++ } ++ if ((r = sshpkt_get_end(ssh)) != 0) ++ fatal("Expecting end of packet."); + -+ debug("Received KEXGSS_HOSTKEY"); -+ if (server_host_key_blob) -+ fatal("Server host key received more than once"); -+ 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); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgss_init_ctx(ssh, &recv_tok); + -+ switch (type) { -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ debug("Received GSSAPI_CONTINUE"); -+ if (maj_status == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("Failed to read token: %s", ssh_err(r)); -+ break; -+ case SSH2_MSG_KEXGSS_COMPLETE: -+ debug("Received GSSAPI_COMPLETE"); -+ if (msg_tok.value != NULL) -+ fatal("Received GSSAPI_COMPLETE twice?"); -+ if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || -+ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &msg_tok)) != 0) -+ fatal("Failed to read message: %s", ssh_err(r)); ++ return kexgss_final(ssh); ++} + -+ /* Is there a token included? */ -+ if ((r = sshpkt_get_u8(ssh, &c)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ if (c) { -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc( -+ ssh, &recv_tok)) != 0) -+ fatal("Failed to read token: %s", ssh_err(r)); -+ /* If we're already complete - protocol error */ -+ if (maj_status == GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -+ } else { -+ /* No token included */ -+ if (maj_status != GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -+ } -+ if ((r = sshpkt_get_end(ssh)) != 0) { -+ fatal("Expecting end of packet."); -+ } -+ break; -+ case SSH2_MSG_KEXGSS_ERROR: -+ debug("Received Error"); -+ if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || -+ (r = sshpkt_get_u32(ssh, &min_status)) != 0 || -+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || -+ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt_get failed: %s", ssh_err(r)); -+ fatal("GSSAPI Error: \n%.400s", msg); -+ default: -+ sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", -+ type); -+ } -+ token_ptr = &recv_tok; -+ } else { -+ /* No data, and not complete */ -+ if (maj_status != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); ++static int ++input_kexgss_error(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ u_char *msg; ++ int r; ++ ++ debug("Received Error"); ++ if ((r = sshpkt_get_u32(ssh, &gss->major)) != 0 || ++ (r = sshpkt_get_u32(ssh, &gss->minor)) != 0 || ++ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || ++ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt_get failed: %s", ssh_err(r)); ++ fatal("GSSAPI Error: \n%.400s", msg); ++ return 0; ++} ++ ++/*******************************************************/ ++/******************** KEXGSSGEX ************************/ ++/*******************************************************/ ++ ++int ++kexgssgex_client(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ int r; ++ ++ /* Initialise our GSSAPI world */ ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) ++ fatal("Couldn't identify host exchange"); ++ ++ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) ++ fatal("Couldn't import hostname"); ++ ++ if (kex->gss_client && ++ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) ++ fatal("Couldn't acquire client credentials"); ++ ++ debug("Doing group exchange"); ++ kex->min = DH_GRP_MIN; ++ kex->max = DH_GRP_MAX; ++ kex->nbits = dh_estimate(kex->dh_need * 8); ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->min)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || ++ (r = sshpkt_put_u32(ssh, kex->max)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("Failed to construct a packet: %s", ssh_err(r)); ++ ++ debug("Wait SSH2_MSG_KEXGSS_GROUP"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, &input_kexgssgex_group); ++ return 0; ++} ++ ++static int ++kexgssgex_final(struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ struct sshbuf *buf = NULL; ++ struct sshbuf *empty = NULL; ++ struct sshbuf *shared_secret = NULL; ++ BIGNUM *dh_server_pub = NULL; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ int r = SSH_ERR_INTERNAL_ERROR; + + /* + * We _must_ have received a COMPLETE message in reply from the + * server, which will have set server_blob and msg_tok + */ + -+ if (type != SSH2_MSG_KEXGSS_COMPLETE) -+ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -+ -+ /* compute shared secret */ -+ switch (kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: -+ r = kex_dh_dec(kex, server_blob, &shared_secret); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80) -+ fatal("The received key has MSB of last octet set!"); -+ r = kex_c25519_dec(kex, server_blob, &shared_secret); -+ break; -+ case KEX_GSS_NISTP256_SHA256: -+ if (sshbuf_len(server_blob) != 65) -+ fatal("The received NIST-P256 key did not match" -+ "expected length (expected 65, got %zu)", sshbuf_len(server_blob)); -+ -+ if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) -+ fatal("The received NIST-P256 key does not have first octet 0x04"); -+ -+ r = kex_ecdh_dec(kex, server_blob, &shared_secret); -+ break; -+ default: -+ r = SSH_ERR_INVALID_ARGUMENT; -+ break; -+ } -+ if (r != 0) ++ /* 7. C verifies that the key Q_S is valid */ ++ /* 8. C computes shared secret */ ++ if ((buf = sshbuf_new()) == NULL || ++ (r = sshbuf_put_stringb(buf, gss->server_blob)) != 0 || ++ (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); + goto out; ++ } ++ sshbuf_free(buf); ++ buf = NULL; + -+ if ((empty = sshbuf_new()) == NULL) { ++ if ((shared_secret = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + -+ hashlen = sizeof(hash); -+ if ((r = kex_gen_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->my, -+ kex->peer, -+ (server_host_key_blob ? server_host_key_blob : empty), -+ kex->client_pub, -+ server_blob, -+ shared_secret, -+ hash, &hashlen)) != 0) -+ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ goto out; ++ } + -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; ++ if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ hashlen = sizeof(hash); ++ r = kexgex_hash(kex->hash_alg, kex->client_version, ++ kex->server_version, kex->my, kex->peer, ++ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), ++ kex->min, kex->nbits, kex->max, dh_p, dh_g, pub_key, ++ dh_server_pub, sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), ++ hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) ++ fatal("Failed to calculate hash: %s", ssh_err(r)); ++ ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; + + /* Verify that the hash matches the MIC we just got. */ -+ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) + sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); + -+ gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, &gss->msg_tok); + + if (kex->gss_deleg_creds) -+ ssh_gssapi_credentials_updated(ctxt); ++ ssh_gssapi_credentials_updated(gss); + + if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; ++ gss_kex_context = gss; + else -+ ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + ++ /* Finally derive the keys and send them */ + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + ++ if (kex->gss != NULL) { ++ sshbuf_free(gss->server_host_key_blob); ++ gss->server_host_key_blob = NULL; ++ sshbuf_free(gss->server_blob); ++ gss->server_blob = NULL; ++ } +out: + explicit_bzero(hash, sizeof(hash)); -+ explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); -+ sshbuf_free(empty); -+ sshbuf_free(server_host_key_blob); -+ sshbuf_free(server_blob); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ BN_clear_free(dh_server_pub); + sshbuf_free(shared_secret); -+ sshbuf_free(kex->client_pub); -+ kex->client_pub = NULL; + return r; +} + -+int -+kexgssgex_client(struct ssh *ssh) ++static int ++kexgssgex_init_ctx(struct ssh *ssh, ++ gss_buffer_desc *token_ptr) +{ + struct kex *kex = ssh->kex; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, -+ recv_tok = GSS_C_EMPTY_BUFFER, gssbuf, -+ msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; -+ Gssctxt *ctxt; -+ OM_uint32 maj_status, min_status, ret_flags; -+ struct sshbuf *shared_secret = NULL; -+ BIGNUM *p = NULL; -+ BIGNUM *g = NULL; -+ struct sshbuf *buf = NULL; -+ struct sshbuf *server_host_key_blob = NULL; -+ struct sshbuf *server_blob = NULL; -+ BIGNUM *dh_server_pub = NULL; -+ u_char *msg; -+ int type = 0; -+ int first = 1; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ const BIGNUM *pub_key, *dh_p, *dh_g; -+ int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; -+ struct sshbuf *empty = NULL; -+ u_char c; ++ Gssctxt *gss = kex->gss; ++ const BIGNUM *pub_key; ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags; + int r; + -+ /* Initialise our GSSAPI world */ -+ ssh_gssapi_build_ctx(&ctxt); -+ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) -+ == GSS_C_NO_OID) -+ fatal("Couldn't identify host exchange"); ++ /* Step 2 - call GSS_Init_sec_context() */ ++ debug("Calling gss_init_sec_context"); + -+ if (ssh_gssapi_import_name(ctxt, kex->gss_host)) -+ fatal("Couldn't import hostname"); ++ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, ++ token_ptr, &send_tok, &ret_flags); + -+ if (kex->gss_client && -+ ssh_gssapi_client_identity(ctxt, kex->gss_client)) -+ fatal("Couldn't acquire client credentials"); ++ if (GSS_ERROR(gss->major)) { ++ /* XXX Useless code: Missing send? */ ++ if (send_tok.length != 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("gss_init_context failed"); ++ } + -+ debug("Doing group exchange"); -+ nbits = dh_estimate(kex->dh_need * 8); ++ /* If we've got an old receive buffer get rid of it */ ++ if (token_ptr != GSS_C_NO_BUFFER) ++ gss_release_buffer(&gss->minor, token_ptr); + -+ kex->min = DH_GRP_MIN; -+ kex->max = DH_GRP_MAX; -+ kex->nbits = nbits; -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || -+ (r = sshpkt_put_u32(ssh, min)) != 0 || -+ (r = sshpkt_put_u32(ssh, nbits)) != 0 || -+ (r = sshpkt_put_u32(ssh, max)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("Failed to construct a packet: %s", ssh_err(r)); ++ if (gss->major == GSS_S_COMPLETE) { ++ /* If mutual state flag is not true, kex fails */ ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual authentication failed"); + -+ if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0) -+ fatal("Error: %s", ssh_err(r)); ++ /* If integ avail flag is not true kex fails */ ++ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity check failed"); ++ } ++ ++ /* ++ * If we have data to send, then the last message that we ++ * received cannot have been a 'complete'. ++ */ ++ if (send_tok.length != 0) { ++ if (gss->first) { ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ gss->first = 0; ++ } else { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ fatal("failed to construct packet: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("failed to send packet: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, &send_tok); ++ ++ /* If we've sent them data, they should reply */ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgssgex_complete); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); ++ return 0; ++ } ++ /* No data, and not complete */ ++ if (gss->major != GSS_S_COMPLETE) ++ fatal("Not complete, and no token output"); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgssgex_init_ctx(ssh, token_ptr); ++ ++ return kexgssgex_final(ssh); ++} ++ ++static int ++input_kexgssgex_group(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ BIGNUM *p = NULL; ++ BIGNUM *g = NULL; ++ int r; ++ ++ debug("Received SSH2_MSG_KEXGSS_GROUP"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, NULL); + + if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || + (r = sshpkt_get_bignum2(ssh, &g)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); + -+ if (BN_num_bits(p) < min || BN_num_bits(p) > max) ++ if (BN_num_bits(p) < kex->min || BN_num_bits(p) > kex->max) + fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", -+ min, BN_num_bits(p), max); ++ kex->min, BN_num_bits(p), kex->max); + + if ((kex->dh = dh_new_group(g, p)) == NULL) + fatal("dn_new_group() failed"); + p = g = NULL; /* belong to kex->dh now */ + -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ DH_get0_key(kex->dh, &pub_key, NULL); ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ return r; ++ } + -+ token_ptr = GSS_C_NO_BUFFER; ++ return kexgssgex_init_ctx(ssh, GSS_C_NO_BUFFER); ++} + -+ do { -+ /* Step 2 - call GSS_Init_sec_context() */ -+ debug("Calling gss_init_sec_context"); ++static int ++input_kexgssgex_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ int r; + -+ maj_status = ssh_gssapi_init_ctx(ctxt, -+ kex->gss_deleg_creds, token_ptr, &send_tok, -+ &ret_flags); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); + -+ if (GSS_ERROR(maj_status)) { -+ /* XXX Useles code: Missing send? */ -+ if (send_tok.length != 0) { -+ if ((r = sshpkt_start(ssh, -+ SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, -+ send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ fatal("gss_init_context failed"); -+ } -+ -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ gss_release_buffer(&min_status, &recv_tok); -+ -+ if (maj_status == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); -+ -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } -+ -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (first) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, -+ send_tok.length)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ first = 0; -+ } else { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh,send_tok.value, -+ send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ if ((r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt_send failed: %s", ssh_err(r)); -+ gss_release_buffer(&min_status, &send_tok); -+ -+ /* If we've sent them data, they should reply */ -+ do { -+ type = ssh_packet_read(ssh); -+ if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ u_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_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); -+ -+ switch (type) { -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ debug("Received GSSAPI_CONTINUE"); -+ if (maj_status == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ break; -+ case SSH2_MSG_KEXGSS_COMPLETE: -+ debug("Received GSSAPI_COMPLETE"); -+ if (msg_tok.value != NULL) -+ fatal("Received GSSAPI_COMPLETE twice?"); -+ if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || -+ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &msg_tok)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ /* Is there a token included? */ -+ if ((r = sshpkt_get_u8(ssh, &c)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ if (c) { -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc( -+ ssh, &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ /* If we're already complete - protocol error */ -+ if (maj_status == GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -+ } else { -+ /* No token included */ -+ if (maj_status != GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -+ } -+ break; -+ case SSH2_MSG_KEXGSS_ERROR: -+ debug("Received Error"); -+ if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || -+ (r = sshpkt_get_u32(ssh, &min_status)) != 0 || -+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || -+ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ fatal("GSSAPI Error: \n%.400s", msg); -+ default: -+ sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", -+ type); -+ } -+ token_ptr = &recv_tok; -+ } else { -+ /* No data, and not complete */ -+ if (maj_status != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ /* -+ * We _must_ have received a COMPLETE message in reply from the -+ * server, which will have set dh_server_pub and msg_tok -+ */ -+ -+ if (type != SSH2_MSG_KEXGSS_COMPLETE) ++ debug("Received GSSAPI_CONTINUE"); ++ if (gss->major == GSS_S_COMPLETE) ++ fatal("GSSAPI Continue received from server when complete"); ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) + fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); ++ return kexgssgex_init_ctx(ssh, &recv_tok); ++} + -+ /* 7. C verifies that the key Q_S is valid */ -+ /* 8. C computes shared secret */ -+ if ((buf = sshbuf_new()) == NULL || -+ (r = sshbuf_put_stringb(buf, server_blob)) != 0 || -+ (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) -+ goto out; -+ sshbuf_free(buf); -+ buf = NULL; ++static int ++input_kexgssgex_complete(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; ++ u_char c; ++ int r; + -+ if ((shared_secret = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); ++ ++ debug("Received GSSAPI_COMPLETE"); ++ if (gss->msg_tok.value != NULL) ++ fatal("Received GSSAPI_COMPLETE twice?"); ++ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || ++ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) ++ fatal("Failed to read message: %s", ssh_err(r)); ++ ++ /* Is there a token included? */ ++ if ((r = sshpkt_get_u8(ssh, &c)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ if (c) { ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) ++ fatal("Failed to read token: %s", ssh_err(r)); ++ /* If we're already complete - protocol error */ ++ if (gss->major == GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); ++ } else { ++ if (gss->major != GSS_S_COMPLETE) ++ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); + } ++ if ((r = sshpkt_get_end(ssh)) != 0) ++ fatal("Expecting end of packet."); + -+ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) -+ goto out; -+ if ((empty = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return kexgssgex_init_ctx(ssh, &recv_tok); + -+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); -+ hashlen = sizeof(hash); -+ if ((r = kexgex_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->my, -+ kex->peer, -+ (server_host_key_blob ? server_host_key_blob : empty), -+ kex->min, kex->nbits, kex->max, -+ dh_p, dh_g, -+ pub_key, -+ dh_server_pub, -+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), -+ hash, &hashlen)) != 0) -+ fatal("Failed to calculate hash: %s", ssh_err(r)); -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ /* Verify that the hash matches the MIC we just got. */ -+ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) -+ sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); -+ -+ gss_release_buffer(&min_status, &msg_tok); -+ -+ if (kex->gss_deleg_creds) -+ ssh_gssapi_credentials_updated(ctxt); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ /* Finally derive the keys and send them */ -+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) -+ r = kex_send_newkeys(ssh); -+out: -+ sshbuf_free(buf); -+ sshbuf_free(server_blob); -+ sshbuf_free(empty); -+ explicit_bzero(hash, sizeof(hash)); -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ BN_clear_free(dh_server_pub); -+ sshbuf_free(shared_secret); -+ sshbuf_free(server_host_key_blob); -+ return r; ++ return kexgssgex_final(ssh); +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --color -ruNp a/kexgsss.c b/kexgsss.c --- a/kexgsss.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgsss.c 2024-08-28 12:35:41.250432122 +0200 -@@ -0,0 +1,482 @@ ++++ b/kexgsss.c 2024-09-16 11:46:34.710940224 +0200 +@@ -0,0 +1,590 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1889,33 +2002,18 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + +extern ServerOptions options; + ++static int input_kexgss_init(int, u_int32_t, struct ssh *); ++static int input_kexgss_continue(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_groupreq(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_init(int, u_int32_t, struct ssh *); ++static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); ++ +int +kexgss_server(struct ssh *ssh) +{ + struct kex *kex = ssh->kex; -+ OM_uint32 maj_status, min_status; -+ -+ /* -+ * Some GSSAPI implementations use the input value of ret_flags (an -+ * output variable) as a means of triggering mechanism specific -+ * features. Initializing it to zero avoids inadvertently -+ * activating this non-standard behaviour. -+ */ -+ -+ OM_uint32 ret_flags = 0; -+ 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; -+ struct sshbuf *client_pubkey = NULL; -+ struct sshbuf *server_pubkey = NULL; -+ struct sshbuf *empty = sshbuf_new(); -+ int type = 0; + gss_OID oid; + char *mechs; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ int r; + + /* Initialise GSSAPI */ + @@ -1931,135 +2029,91 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) -+ fatal("Unknown gssapi mechanism"); ++ fatal("Unknown gssapi mechanism"); + + debug2_f("Acquiring credentials"); + -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) + fatal("Unable to acquire credentials for the server"); + -+ do { -+ debug("Wait SSH2_MSG_KEXGSS_INIT"); -+ type = ssh_packet_read(ssh); -+ switch(type) { -+ case SSH2_MSG_KEXGSS_INIT: -+ if (gssbuf.value != NULL) -+ fatal("Received KEXGSS_INIT after initialising"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (kex->gss == NULL) ++ fatal("Unable to allocate memory for gss context"); + -+ switch (kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: -+ r = kex_dh_enc(kex, client_pubkey, &server_pubkey, -+ &shared_secret); -+ break; -+ case KEX_GSS_NISTP256_SHA256: -+ r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, -+ &shared_secret); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, -+ &shared_secret); -+ break; -+ default: -+ fatal_f("Unexpected KEX type %d", kex->kex_type); -+ } -+ if (r != 0) -+ goto out; ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgss_init); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); ++ debug("Wait SSH2_MSG_KEXGSS_INIT"); ++ return 0; ++} + -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++static inline void ++kexgss_accept_ctx(struct ssh *ssh, ++ gss_buffer_desc *recv_tok, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ int r; + -+ /* 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; ++ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); ++ gss_release_buffer(&gss->minor, recv_tok); + -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; ++ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) ++ fatal("Zero length token output when incomplete"); + -+ sshbuf_free(client_pubkey); -+ client_pubkey = NULL; ++ if (gss->buf.value == NULL) ++ fatal("No client public key"); + -+ break; -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ break; -+ default: -+ sshpkt_disconnect(ssh, -+ "Protocol error: didn't expect packet type %d", -+ type); -+ } ++ if (gss->major & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, send_tok); ++ } ++} + -+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags); ++static inline int ++kexgss_final(struct ssh *ssh, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc msg_tok; ++ int r; + -+ gss_release_buffer(&min_status, &recv_tok); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); + -+ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -+ fatal("Zero length token output when incomplete"); -+ -+ if (gssbuf.value == NULL) -+ fatal("No client public key"); -+ -+ if (maj_status & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); ++ if (GSS_ERROR(gss->major)) { ++ if (send_tok->length > 0) { + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ gss_release_buffer(&min_status, &send_tok); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length > 0) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } + fatal("accept_ctx died"); + } + -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) ++ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) + fatal("Mutual Authentication flag wasn't set"); + -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) ++ if (!(*ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + -+ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || -+ (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || ++ (r = sshpkt_put_stringb(ssh, gss->server_pubkey)) != 0 || + (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + -+ if (send_tok.length != 0) { ++ if (send_tok->length != 0) { + if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); + } else { + if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ @@ -2068,59 +2122,139 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + if ((r = sshpkt_send(ssh)) != 0) + fatal("sshpkt_send failed: %s", ssh_err(r)); + -+ gss_release_buffer(&min_status, &send_tok); -+ gss_release_buffer(&min_status, &msg_tok); ++ gss_release_buffer(&gss->minor, send_tok); ++ gss_release_buffer(&gss->minor, &msg_tok); + + if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; ++ gss_kex_context = gss; + else -+ ssh_gssapi_delete_ctx(&ctxt); ++ ssh_gssapi_delete_ctx(&kex->gss); + -+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ if ((r = kex_derive_keys(ssh, gss->hash, gss->hashlen, gss->shared_secret)) == 0) + r = kex_send_newkeys(ssh); + + /* If this was a rekey, then save out any delegated credentials we + * just exchanged. */ + if (options.gss_store_rekey) + ssh_gssapi_rekey_creds(); -+out: -+ sshbuf_free(empty); -+ explicit_bzero(hash, sizeof(hash)); -+ sshbuf_free(shared_secret); -+ sshbuf_free(client_pubkey); -+ sshbuf_free(server_pubkey); ++ ++ if (kex->gss != NULL) { ++ explicit_bzero(gss->hash, sizeof(gss->hash)); ++ sshbuf_free(gss->shared_secret); ++ gss->shared_secret = NULL; ++ sshbuf_free(gss->server_pubkey); ++ gss->server_pubkey = NULL; ++ } + return r; +} + ++static int ++input_kexgss_init(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ struct sshbuf *empty; ++ struct sshbuf *client_pubkey = NULL; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ debug("SSH2_MSG_KEXGSS_INIT received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ switch (kex->kex_type) { ++ case KEX_GSS_GRP1_SHA1: ++ case KEX_GSS_GRP14_SHA1: ++ case KEX_GSS_GRP14_SHA256: ++ case KEX_GSS_GRP16_SHA512: ++ r = kex_dh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ case KEX_GSS_NISTP256_SHA256: ++ r = kex_ecdh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ case KEX_GSS_C25519_SHA256: ++ r = kex_c25519_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); ++ break; ++ default: ++ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ } ++ if (r != 0) { ++ sshbuf_free(client_pubkey); ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return r; ++ } ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ if ((empty = sshbuf_new()) == NULL) { ++ sshbuf_free(client_pubkey); ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return SSH_ERR_ALLOC_FAIL; ++ } ++ ++ /* Calculate the hash early so we can free the ++ * client_pubkey, which has reference to the parent ++ * buffer state->incoming_packet ++ */ ++ gss->hashlen = sizeof(gss->hash); ++ r = kex_gen_hash(kex->hash_alg, kex->client_version, kex->server_version, ++ kex->peer, kex->my, empty, client_pubkey, gss->server_pubkey, ++ gss->shared_secret, gss->hash, &gss->hashlen); ++ sshbuf_free(empty); ++ sshbuf_free(client_pubkey); ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ return r; ++ } ++ ++ gss->buf.value = gss->hash; ++ gss->buf.length = gss->hashlen; ++ ++ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgss_final(ssh, &send_tok, &ret_flags); ++} ++ ++static int ++input_kexgss_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgss_final(ssh, &send_tok, &ret_flags); ++} ++ ++/*******************************************************/ ++/******************** KEXGSSGEX ************************/ ++/*******************************************************/ ++ +int +kexgssgex_server(struct ssh *ssh) +{ + struct kex *kex = ssh->kex; -+ OM_uint32 maj_status, min_status; -+ -+ /* -+ * Some GSSAPI implementations use the input value of ret_flags (an -+ * output variable) as a means of triggering mechanism specific -+ * features. Initializing it to zero avoids inadvertently -+ * activating this non-standard behaviour. -+ */ -+ -+ OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf, recv_tok, msg_tok; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ Gssctxt *ctxt = NULL; -+ struct sshbuf *shared_secret = NULL; -+ int type = 0; + gss_OID oid; + char *mechs; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ BIGNUM *dh_client_pub = NULL; -+ const BIGNUM *pub_key, *dh_p, *dh_g; -+ int min = -1, max = -1, nbits = -1; -+ int cmin = -1, cmax = -1; /* client proposal */ -+ struct sshbuf *empty = sshbuf_new(); -+ int r; + + /* Initialise GSSAPI */ + @@ -2128,29 +2262,194 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + * in the GSSAPI code are no longer available. This kludges them back + * into life + */ -+ if (!ssh_gssapi_oid_table_ok()) -+ if ((mechs = ssh_gssapi_server_mechanisms())) -+ free(mechs); ++ if (!ssh_gssapi_oid_table_ok()) { ++ mechs = ssh_gssapi_server_mechanisms(); ++ free(mechs); ++ } + + debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) -+ fatal("Unknown gssapi mechanism"); ++ fatal("Unknown gssapi mechanism"); + + debug2_f("Acquiring credentials"); + -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) + fatal("Unable to acquire credentials for the server"); + -+ /* 5. S generates an ephemeral key pair (do the allocations early) */ ++ ssh_gssapi_build_ctx(&kex->gss); ++ if (kex->gss == NULL) ++ fatal("Unable to allocate memory for gss context"); ++ + debug("Doing group exchange"); -+ ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, &input_kexgssgex_groupreq); ++ return 0; ++} ++ ++static inline void ++kexgssgex_accept_ctx(struct ssh *ssh, ++ gss_buffer_desc *recv_tok, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ int r; ++ ++ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); ++ gss_release_buffer(&gss->minor, recv_tok); ++ ++ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) ++ fatal("Zero length token output when incomplete"); ++ ++ if (gss->dh_client_pub == NULL) ++ fatal("No client public key"); ++ ++ if (gss->major & GSS_S_CONTINUE_NEEDED) { ++ debug("Sending GSSAPI_CONTINUE"); ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ gss_release_buffer(&gss->minor, send_tok); ++ } ++} ++ ++static inline int ++kexgssgex_final(struct ssh *ssh, ++ gss_buffer_desc *send_tok, ++ OM_uint32 *ret_flags) ++{ ++ struct kex *kex = ssh->kex; ++ Gssctxt *gss = kex->gss; ++ gss_buffer_desc msg_tok; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ const BIGNUM *pub_key, *dh_p, *dh_g; ++ struct sshbuf *shared_secret = NULL; ++ struct sshbuf *empty = NULL; ++ int r; ++ ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); ++ ++ if (GSS_ERROR(gss->major)) { ++ if (send_tok->length > 0) { ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ fatal("accept_ctx died"); ++ } ++ ++ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) ++ fatal("Mutual Authentication flag wasn't set"); ++ ++ if (!(*ret_flags & GSS_C_INTEG_FLAG)) ++ fatal("Integrity flag wasn't set"); ++ ++ /* calculate shared secret */ ++ shared_secret = sshbuf_new(); ++ if (shared_secret == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ if ((r = kex_dh_compute_key(kex, gss->dh_client_pub, shared_secret)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ goto out; ++ } ++ ++ if ((empty = sshbuf_new()) == NULL) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ r = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ DH_get0_key(kex->dh, &pub_key, NULL); ++ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); ++ hashlen = sizeof(hash); ++ r = kexgex_hash(kex->hash_alg, kex->client_version, kex->server_version, ++ kex->peer, kex->my, empty, kex->min, kex->nbits, kex->max, dh_p, dh_g, ++ gss->dh_client_pub, pub_key, sshbuf_ptr(shared_secret), ++ sshbuf_len(shared_secret), hash, &hashlen); ++ sshbuf_free(empty); ++ if (r != 0) ++ fatal("kexgex_hash failed: %s", ssh_err(r)); ++ ++ gss->buf.value = hash; ++ gss->buf.length = hashlen; ++ ++ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) ++ fatal("Couldn't get MIC"); ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || ++ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || ++ (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ if (send_tok->length != 0) { ++ if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ ++ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } else { ++ if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ } ++ if ((r = sshpkt_send(ssh)) != 0) ++ fatal("sshpkt_send failed: %s", ssh_err(r)); ++ ++ gss_release_buffer(&gss->minor, send_tok); ++ gss_release_buffer(&gss->minor, &msg_tok); ++ ++ if (gss_kex_context == NULL) ++ gss_kex_context = gss; ++ else ++ ssh_gssapi_delete_ctx(&kex->gss); ++ ++ /* Finally derive the keys and send them */ ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) ++ r = kex_send_newkeys(ssh); ++ ++ /* If this was a rekey, then save out any delegated credentials we ++ * just exchanged. */ ++ if (options.gss_store_rekey) ++ ssh_gssapi_rekey_creds(); ++ ++ if (kex->gss != NULL) ++ BN_clear_free(gss->dh_client_pub); ++ ++out: ++ explicit_bzero(hash, sizeof(hash)); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ sshbuf_free(shared_secret); ++ return r; ++} ++ ++static int ++input_kexgssgex_groupreq(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ struct kex *kex = ssh->kex; ++ const BIGNUM *dh_p, *dh_g; ++ int min = -1, max = -1, nbits = -1; ++ int cmin = -1, cmax = -1; /* client proposal */ ++ int r; ++ ++ /* 5. S generates an ephemeral key pair (do the allocations early) */ ++ ++ debug("SSH2_MSG_KEXGSS_GROUPREQ received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, NULL); ++ + /* store client proposal to provide valid signature */ + if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || + (r = sshpkt_get_u32(ssh, &nbits)) != 0 || + (r = sshpkt_get_u32(ssh, &cmax)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); ++ + kex->nbits = nbits; + kex->min = cmin; + kex->max = cmax; @@ -2158,9 +2457,10 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + max = MIN(DH_GRP_MAX, cmax); + nbits = MAXIMUM(DH_GRP_MIN, nbits); + nbits = MINIMUM(DH_GRP_MAX, nbits); ++ + if (max < min || nbits < min || max < nbits) -+ fatal("GSS_GEX, bad parameters: %d !< %d !< %d", -+ min, nbits, max); ++ fatal("GSS_GEX, bad parameters: %d !< %d !< %d", min, nbits, max); ++ + kex->dh = mm_choose_dh(min, nbits, max); + if (kex->dh == NULL) { + sshpkt_disconnect(ssh, "Protocol error: no matching group found"); @@ -2178,151 +2478,83 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + fatal("ssh_packet_write_wait: %s", ssh_err(r)); + + /* Compute our exchange value in parallel with the client */ -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ -+ do { -+ debug("Wait SSH2_MSG_GSSAPI_INIT"); -+ type = ssh_packet_read(ssh); -+ switch(type) { -+ case SSH2_MSG_KEXGSS_INIT: -+ if (dh_client_pub != NULL) -+ fatal("Received KEXGSS_INIT after initialising"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ break; -+ case SSH2_MSG_KEXGSS_CONTINUE: -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -+ &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ break; -+ default: -+ sshpkt_disconnect(ssh, -+ "Protocol error: didn't expect packet type %d", -+ type); -+ } -+ -+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags); -+ -+ gss_release_buffer(&min_status, &recv_tok); -+ -+ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -+ fatal("Zero length token output when incomplete"); -+ -+ if (dh_client_pub == NULL) -+ fatal("No client public key"); -+ -+ if (maj_status & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ gss_release_buffer(&min_status, &send_tok); -+ } -+ } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ -+ if (GSS_ERROR(maj_status)) { -+ if (send_tok.length > 0) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ fatal("accept_ctx died"); ++ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { ++ ssh_gssapi_delete_ctx(&kex->gss); ++ DH_free(kex->dh); ++ kex->dh = NULL; ++ return r; + } + -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual Authentication flag wasn't set"); -+ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity flag wasn't set"); -+ -+ /* calculate shared secret */ -+ if ((shared_secret = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) -+ goto out; -+ -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); -+ hashlen = sizeof(hash); -+ if ((r = kexgex_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->peer, -+ kex->my, -+ empty, -+ cmin, nbits, cmax, -+ dh_p, dh_g, -+ dh_client_pub, -+ pub_key, -+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), -+ hash, &hashlen)) != 0) -+ fatal("kexgex_hash failed: %s", ssh_err(r)); -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ 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 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || -+ (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ if (send_tok.length != 0) { -+ if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } else { -+ if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ if ((r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ gss_release_buffer(&min_status, &send_tok); -+ gss_release_buffer(&min_status, &msg_tok); -+ -+ if (gss_kex_context == NULL) -+ gss_kex_context = ctxt; -+ else -+ ssh_gssapi_delete_ctx(&ctxt); -+ -+ /* Finally derive the keys and send them */ -+ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) -+ r = kex_send_newkeys(ssh); -+ -+ /* If this was a rekey, then save out any delegated credentials we -+ * just exchanged. */ -+ if (options.gss_store_rekey) -+ ssh_gssapi_rekey_creds(); -+out: -+ sshbuf_free(empty); -+ explicit_bzero(hash, sizeof(hash)); -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ BN_clear_free(dh_client_pub); -+ sshbuf_free(shared_secret); -+ return r; ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgssgex_init); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); ++ debug("Wait SSH2_MSG_KEXGSS_INIT"); ++ return 0; +} ++ ++static int ++input_kexgssgex_init(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ debug("SSH2_MSG_KEXGSS_INIT received"); ++ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_bignum2(ssh, &gss->dh_client_pub)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgssgex_final(ssh, &send_tok, &ret_flags); ++} ++ ++static int ++input_kexgssgex_continue(int type, ++ u_int32_t seq, ++ struct ssh *ssh) ++{ ++ Gssctxt *gss = ssh->kex->gss; ++ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ret_flags = 0; ++ int r; ++ ++ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || ++ (r = sshpkt_get_end(ssh)) != 0) ++ fatal("sshpkt failed: %s", ssh_err(r)); ++ ++ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); ++ if (gss->major & GSS_S_CONTINUE_NEEDED) ++ return 0; ++ ++ return kexgssgex_final(ssh, &send_tok, &ret_flags); ++} ++ +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --color -ruNp a/kex.h b/kex.h --- a/kex.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex.h 2024-08-28 12:35:41.249432103 +0200 -@@ -102,6 +102,15 @@ enum kex_exchange { ++++ b/kex.h 2024-09-16 11:46:34.710940224 +0200 +@@ -29,6 +29,10 @@ + #include "mac.h" + #include "crypto_api.h" + ++#ifdef GSSAPI ++# include "ssh-gss.h" /* Gssctxt */ ++#endif ++ + #ifdef WITH_OPENSSL + # include + # include +@@ -102,6 +106,15 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, KEX_KEM_SNTRUP761X25519_SHA512, @@ -2338,11 +2570,12 @@ diff --color -ruNp a/kex.h b/kex.h KEX_MAX }; -@@ -164,6 +173,12 @@ struct kex { +@@ -164,6 +177,13 @@ struct kex { u_int flags; int hash_alg; int ec_nid; +#ifdef GSSAPI ++ Gssctxt *gss; + int gss_deleg_creds; + int gss_trust_dns; + char *gss_host; @@ -2351,7 +2584,7 @@ diff --color -ruNp a/kex.h b/kex.h char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -189,8 +204,10 @@ int kex_hash_from_name(const char *); +@@ -189,8 +209,10 @@ int kex_hash_from_name(const char *); int kex_nid_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); @@ -2362,7 +2595,7 @@ diff --color -ruNp a/kex.h b/kex.h 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 *); -@@ -224,6 +241,12 @@ int kexgex_client(struct ssh *); +@@ -224,6 +246,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -2375,7 +2608,7 @@ diff --color -ruNp a/kex.h b/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -256,6 +279,12 @@ int kexgex_hash(int, const struct sshbu +@@ -256,6 +284,12 @@ int kexgex_hash(int, const struct sshbu const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -2390,7 +2623,7 @@ diff --color -ruNp a/kex.h b/kex.h __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --color -ruNp a/kex-names.c b/kex-names.c --- a/kex-names.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex-names.c 2024-08-28 12:35:41.249432103 +0200 ++++ b/kex-names.c 2024-09-16 11:46:34.694939883 +0200 @@ -45,6 +45,10 @@ #include "ssherr.h" #include "xmalloc.h" @@ -2492,8 +2725,8 @@ diff --color -ruNp a/kex-names.c b/kex-names.c + return 1; +} diff --color -ruNp a/Makefile.in b/Makefile.in ---- a/Makefile.in 2024-08-28 12:35:01.200659705 +0200 -+++ b/Makefile.in 2024-08-28 12:35:41.244432006 +0200 +--- a/Makefile.in 2024-09-16 11:45:56.868133454 +0200 ++++ b/Makefile.in 2024-09-16 11:46:34.695939904 +0200 @@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ @@ -2521,8 +2754,8 @@ diff --color -ruNp a/Makefile.in b/Makefile.in regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ diff --color -ruNp a/monitor.c b/monitor.c ---- a/monitor.c 2024-08-28 12:35:01.192659551 +0200 -+++ b/monitor.c 2024-08-28 12:35:41.251432142 +0200 +--- a/monitor.c 2024-09-16 11:45:56.861133305 +0200 ++++ b/monitor.c 2024-09-16 11:46:34.696939926 +0200 @@ -143,6 +143,8 @@ int mm_answer_gss_setup_ctx(struct ssh * int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); @@ -2770,8 +3003,8 @@ diff --color -ruNp a/monitor.c b/monitor.c #endif /* GSSAPI */ diff --color -ruNp a/monitor.h b/monitor.h ---- a/monitor.h 2024-08-28 12:35:01.192659551 +0200 -+++ b/monitor.h 2024-08-28 12:35:41.251432142 +0200 +--- a/monitor.h 2024-09-16 11:45:56.861133305 +0200 ++++ b/monitor.h 2024-09-16 11:46:34.696939926 +0200 @@ -67,6 +67,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -2782,8 +3015,8 @@ diff --color -ruNp a/monitor.h b/monitor.h struct ssh; diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c ---- a/monitor_wrap.c 2024-08-28 12:35:01.192659551 +0200 -+++ b/monitor_wrap.c 2024-08-28 12:35:41.251432142 +0200 +--- a/monitor_wrap.c 2024-09-16 11:45:56.862133326 +0200 ++++ b/monitor_wrap.c 2024-09-16 11:46:34.697939947 +0200 @@ -1075,13 +1075,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } @@ -2862,8 +3095,8 @@ diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c /* diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h ---- a/monitor_wrap.h 2024-08-28 12:35:01.193659570 +0200 -+++ b/monitor_wrap.h 2024-08-28 12:35:41.251432142 +0200 +--- a/monitor_wrap.h 2024-09-16 11:45:56.862133326 +0200 ++++ b/monitor_wrap.h 2024-09-16 11:46:34.697939947 +0200 @@ -67,8 +67,10 @@ void mm_decode_activate_server_options(s OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -2876,53 +3109,9 @@ diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h #endif #ifdef USE_PAM -diff --color -ruNp a/packet.c b/packet.c ---- a/packet.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/packet.c 2024-08-28 12:35:41.260432315 +0200 -@@ -1517,6 +1517,29 @@ ssh_packet_read(struct ssh *ssh) - return type; - } - -+/* -+ * Waits until a packet has been received, verifies that its type matches -+ * that given, and gives a fatal error and exits if there is a mismatch. -+ */ -+ -+int -+ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) -+{ -+ int r; -+ u_char type; -+ -+ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) -+ return r; -+ if (type != expected_type) { -+ if ((r = sshpkt_disconnect(ssh, -+ "Protocol error: expected packet type %d, got %d", -+ expected_type, type)) != 0) -+ return r; -+ return SSH_ERR_PROTOCOL_ERROR; -+ } -+ return 0; -+} -+ - static int - ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - { -diff --color -ruNp a/packet.h b/packet.h ---- a/packet.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/packet.h 2024-08-28 12:35:41.260432315 +0200 -@@ -124,6 +124,7 @@ int ssh_packet_send2_wrapped(struct ssh - int ssh_packet_send2(struct ssh *); - - int ssh_packet_read(struct ssh *); -+int ssh_packet_read_expect(struct ssh *, u_int type); - 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 --color -ruNp a/readconf.c b/readconf.c --- a/readconf.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/readconf.c 2024-08-28 12:35:41.253432180 +0200 ++++ b/readconf.c 2024-09-16 11:46:34.699939990 +0200 @@ -70,6 +70,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -3056,7 +3245,7 @@ diff --color -ruNp a/readconf.c b/readconf.c dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); diff --color -ruNp a/readconf.h b/readconf.h --- a/readconf.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/readconf.h 2024-08-28 12:35:41.254432199 +0200 ++++ b/readconf.h 2024-09-16 11:46:34.699939990 +0200 @@ -40,7 +40,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ @@ -3073,7 +3262,7 @@ diff --color -ruNp a/readconf.h b/readconf.h int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --color -ruNp a/servconf.c b/servconf.c --- a/servconf.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/servconf.c 2024-08-28 12:35:41.255432218 +0200 ++++ b/servconf.c 2024-09-16 11:46:34.700940011 +0200 @@ -68,6 +68,7 @@ #include "auth.h" #include "myproposal.h" @@ -3191,7 +3380,7 @@ diff --color -ruNp a/servconf.c b/servconf.c dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --color -ruNp a/servconf.h b/servconf.h --- a/servconf.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/servconf.h 2024-08-28 12:35:41.255432218 +0200 ++++ b/servconf.h 2024-09-16 11:46:34.700940011 +0200 @@ -149,8 +149,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -3205,8 +3394,8 @@ diff --color -ruNp a/servconf.h b/servconf.h * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --color -ruNp a/session.c b/session.c ---- a/session.c 2024-08-28 12:35:01.197659647 +0200 -+++ b/session.c 2024-08-28 12:35:41.255432218 +0200 +--- a/session.c 2024-09-16 11:45:56.866133411 +0200 ++++ b/session.c 2024-09-16 11:46:34.701940032 +0200 @@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *au #ifdef KRB5 @@ -3230,8 +3419,8 @@ diff --color -ruNp a/session.c b/session.c /* remove agent socket */ diff --color -ruNp a/ssh.1 b/ssh.1 ---- a/ssh.1 2024-08-28 12:35:01.207659840 +0200 -+++ b/ssh.1 2024-08-28 12:35:41.256432238 +0200 +--- a/ssh.1 2024-09-16 11:45:56.875133603 +0200 ++++ b/ssh.1 2024-09-16 11:46:34.701940032 +0200 @@ -536,7 +536,13 @@ For full details of the options listed b .It GatewayPorts .It GlobalKnownHostsFile @@ -3257,7 +3446,7 @@ diff --color -ruNp a/ssh.1 b/ssh.1 .Ar key-ca-sign diff --color -ruNp a/ssh.c b/ssh.c --- a/ssh.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh.c 2024-08-28 12:35:41.256432238 +0200 ++++ b/ssh.c 2024-09-16 11:46:34.702940054 +0200 @@ -827,6 +827,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) @@ -3279,8 +3468,8 @@ diff --color -ruNp a/ssh.c b/ssh.c if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); diff --color -ruNp a/ssh_config b/ssh_config ---- a/ssh_config 2024-08-28 12:35:01.216660014 +0200 -+++ b/ssh_config 2024-08-28 12:35:41.256432238 +0200 +--- a/ssh_config 2024-09-16 11:45:56.884133795 +0200 ++++ b/ssh_config 2024-09-16 11:46:34.702940054 +0200 @@ -24,6 +24,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no @@ -3292,7 +3481,7 @@ diff --color -ruNp a/ssh_config b/ssh_config # AddressFamily any diff --color -ruNp a/ssh_config.5 b/ssh_config.5 --- a/ssh_config.5 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh_config.5 2024-08-28 12:35:41.257432257 +0200 ++++ b/ssh_config.5 2024-09-16 11:46:34.703940075 +0200 @@ -938,10 +938,68 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -3364,7 +3553,7 @@ diff --color -ruNp a/ssh_config.5 b/ssh_config.5 .Xr ssh 1 diff --color -ruNp a/sshconnect2.c b/sshconnect2.c --- a/sshconnect2.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshconnect2.c 2024-08-28 12:35:41.258432276 +0200 ++++ b/sshconnect2.c 2024-09-16 11:46:34.703940075 +0200 @@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, st char *all_key, *hkalgs = NULL; int r, use_known_hosts_order = 0; @@ -3595,7 +3784,7 @@ diff --color -ruNp a/sshconnect2.c b/sshconnect2.c static int diff --color -ruNp a/sshd.c b/sshd.c --- a/sshd.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshd.c 2024-08-28 12:35:41.258432276 +0200 ++++ b/sshd.c 2024-09-16 11:46:34.704940096 +0200 @@ -1551,7 +1551,8 @@ main(int ac, char **av) free(fp); } @@ -3607,8 +3796,8 @@ diff --color -ruNp a/sshd.c b/sshd.c exit(1); } diff --color -ruNp a/sshd_config b/sshd_config ---- a/sshd_config 2024-08-28 12:35:01.221660110 +0200 -+++ b/sshd_config 2024-08-28 12:35:41.259432296 +0200 +--- a/sshd_config 2024-09-16 11:45:56.888133880 +0200 ++++ b/sshd_config 2024-09-16 11:46:34.704940096 +0200 @@ -77,6 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no @@ -3619,8 +3808,8 @@ diff --color -ruNp a/sshd_config b/sshd_config # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --color -ruNp a/sshd_config.5 b/sshd_config.5 ---- a/sshd_config.5 2024-08-28 12:35:01.218660052 +0200 -+++ b/sshd_config.5 2024-08-28 12:35:41.259432296 +0200 +--- a/sshd_config.5 2024-09-16 11:45:56.885133816 +0200 ++++ b/sshd_config.5 2024-09-16 11:46:34.704940096 +0200 @@ -739,6 +739,11 @@ Specifies whether to automatically destr on logout. The default is @@ -3667,8 +3856,8 @@ diff --color -ruNp a/sshd_config.5 b/sshd_config.5 Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. diff --color -ruNp a/sshd-session.c b/sshd-session.c ---- a/sshd-session.c 2024-08-28 12:35:01.221660110 +0200 -+++ b/sshd-session.c 2024-08-28 12:35:41.263432373 +0200 +--- a/sshd-session.c 2024-09-16 11:45:56.888133880 +0200 ++++ b/sshd-session.c 2024-09-16 11:46:34.705940118 +0200 @@ -660,8 +660,8 @@ notify_hostkeys(struct ssh *ssh) } debug3_f("sent %u hostkeys", nkeys); @@ -3763,8 +3952,8 @@ diff --color -ruNp a/sshd-session.c b/sshd-session.c kex->load_host_public_key=&get_hostkey_public_by_type; diff --color -ruNp a/ssh-gss.h b/ssh-gss.h --- a/ssh-gss.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh-gss.h 2024-08-28 12:35:41.256432238 +0200 -@@ -61,10 +61,34 @@ ++++ b/ssh-gss.h 2024-09-16 11:46:34.710940224 +0200 +@@ -61,10 +61,36 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -3790,6 +3979,8 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h + KEX_GSS_C25519_SHA256_ID "," \ + KEX_GSS_GRP14_SHA1_ID "," \ + KEX_GSS_GEX_SHA1_ID ++ ++#include "digest.h" /* SSH_DIGEST_MAX_LENGTH */ + typedef struct { char *filename; @@ -3799,7 +3990,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h void *data; } ssh_gssapi_ccache; -@@ -72,8 +96,11 @@ typedef struct { +@@ -72,8 +98,11 @@ typedef struct { gss_buffer_desc displayname; gss_buffer_desc exportedname; gss_cred_id_t creds; @@ -3811,7 +4002,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h } ssh_gssapi_client; typedef struct ssh_gssapi_mech_struct { -@@ -84,6 +111,7 @@ typedef struct ssh_gssapi_mech_struct { +@@ -84,6 +113,7 @@ typedef struct ssh_gssapi_mech_struct { int (*userok) (ssh_gssapi_client *, char *); int (*localname) (ssh_gssapi_client *, char **); void (*storecreds) (ssh_gssapi_client *); @@ -3819,12 +4010,22 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h } ssh_gssapi_mech; typedef struct { -@@ -94,10 +122,11 @@ typedef struct { +@@ -94,10 +124,21 @@ typedef struct { gss_OID oid; /* client */ gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ - gss_cred_id_t client_creds; /* server */ + gss_cred_id_t client_creds; /* both */ ++ struct sshbuf *shared_secret; /* both */ ++ struct sshbuf *server_pubkey; /* server */ ++ struct sshbuf *server_blob; /* client */ ++ struct sshbuf *server_host_key_blob; /* client */ ++ gss_buffer_desc msg_tok; /* client */ ++ gss_buffer_desc buf; /* both */ ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; /* both */ ++ size_t hashlen; /* both */ ++ int first; /* client */ ++ BIGNUM *dh_client_pub; /* server (gex) */ } Gssctxt; extern ssh_gssapi_mech *supported_mechs[]; @@ -3832,7 +4033,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -108,6 +137,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( +@@ -108,6 +149,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -3840,7 +4041,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, -@@ -122,17 +152,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); +@@ -122,17 +164,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(struct sshbuf *, const char *, const char *, const char *, const struct sshbuf *); @@ -3878,7 +4079,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h #endif /* _SSH_GSS_H */ diff --color -ruNp a/sshkey.c b/sshkey.c --- a/sshkey.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshkey.c 2024-08-28 12:35:41.260432315 +0200 ++++ b/sshkey.c 2024-09-16 11:46:34.706940139 +0200 @@ -131,6 +131,75 @@ extern const struct sshkey_impl sshkey_x extern const struct sshkey_impl sshkey_xmss_cert_impl; #endif @@ -3974,7 +4175,7 @@ diff --color -ruNp a/sshkey.c b/sshkey.c continue; diff --color -ruNp a/sshkey.h b/sshkey.h --- a/sshkey.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshkey.h 2024-08-28 12:35:41.260432315 +0200 ++++ b/sshkey.h 2024-09-16 11:46:34.706940139 +0200 @@ -71,6 +71,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, diff --git a/openssh-9.6p1-gsskex-new-api.patch b/openssh-9.6p1-gsskex-new-api.patch deleted file mode 100644 index 0f2eabb..0000000 --- a/openssh-9.6p1-gsskex-new-api.patch +++ /dev/null @@ -1,1965 +0,0 @@ -diff --color -ruNp a/gss-genr.c b/gss-genr.c ---- a/gss-genr.c 2024-05-16 15:49:43.999411060 +0200 -+++ b/gss-genr.c 2024-06-26 12:17:55.586856954 +0200 -@@ -346,6 +346,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) - (*ctx)->creds = GSS_C_NO_CREDENTIAL; - (*ctx)->client = GSS_C_NO_NAME; - (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; -+ (*ctx)->first = 1; - } - - /* Delete our context, providing it has been built correctly */ -@@ -371,6 +372,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) - gss_release_name(&ms, &(*ctx)->client); - if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms, &(*ctx)->client_creds); -+ sshbuf_free((*ctx)->shared_secret); -+ sshbuf_free((*ctx)->server_pubkey); -+ sshbuf_free((*ctx)->server_host_key_blob); -+ sshbuf_free((*ctx)->server_blob); -+ explicit_bzero((*ctx)->hash, sizeof((*ctx)->hash)); -+ BN_clear_free((*ctx)->dh_client_pub); - - free(*ctx); - *ctx = NULL; -diff --color -ruNp a/kexgssc.c b/kexgssc.c ---- a/kexgssc.c 2024-05-16 15:49:43.820407648 +0200 -+++ b/kexgssc.c 2024-07-02 16:26:25.628746744 +0200 -@@ -47,566 +47,658 @@ - - #include "ssh-gss.h" - --int --kexgss_client(struct ssh *ssh) -+static int input_kexgss_hostkey(int, u_int32_t, struct ssh *); -+static int input_kexgss_continue(int, u_int32_t, struct ssh *); -+static int input_kexgss_complete(int, u_int32_t, struct ssh *); -+static int input_kexgss_error(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_group(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_complete(int, u_int32_t, struct ssh *); -+ -+static int -+kexgss_final(struct ssh *ssh) - { - struct kex *kex = ssh->kex; -- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, -- recv_tok = GSS_C_EMPTY_BUFFER, -- gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; -- Gssctxt *ctxt; -- OM_uint32 maj_status, min_status, ret_flags; -- struct sshbuf *server_blob = NULL; -- struct sshbuf *shared_secret = NULL; -- struct sshbuf *server_host_key_blob = NULL; -+ Gssctxt *gss = kex->gss; - struct sshbuf *empty = NULL; -- u_char *msg; -- int type = 0; -- int first = 1; -+ struct sshbuf *shared_secret = NULL; - u_char hash[SSH_DIGEST_MAX_LENGTH]; - size_t hashlen; -- u_char c; - int r; - -- /* Initialise our GSSAPI world */ -- ssh_gssapi_build_ctx(&ctxt); -- if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) -- == GSS_C_NO_OID) -- fatal("Couldn't identify host exchange"); -- -- if (ssh_gssapi_import_name(ctxt, kex->gss_host)) -- fatal("Couldn't import hostname"); -- -- if (kex->gss_client && -- ssh_gssapi_client_identity(ctxt, kex->gss_client)) -- fatal("Couldn't acquire client credentials"); -- -- /* Step 1 */ -- switch (kex->kex_type) { -- case KEX_GSS_GRP1_SHA1: -- case KEX_GSS_GRP14_SHA1: -- case KEX_GSS_GRP14_SHA256: -- case KEX_GSS_GRP16_SHA512: -- r = kex_dh_keypair(kex); -- break; -- case KEX_GSS_NISTP256_SHA256: -- r = kex_ecdh_keypair(kex); -- break; -- case KEX_GSS_C25519_SHA256: -- r = kex_c25519_keypair(kex); -- break; -- default: -- fatal_f("Unexpected KEX type %d", kex->kex_type); -- } -- if (r != 0) { -- ssh_gssapi_delete_ctx(&ctxt); -- return r; -- } -- -- token_ptr = GSS_C_NO_BUFFER; -- -- do { -- debug("Calling gss_init_sec_context"); -- -- maj_status = ssh_gssapi_init_ctx(ctxt, -- kex->gss_deleg_creds, token_ptr, &send_tok, -- &ret_flags); -- -- if (GSS_ERROR(maj_status)) { -- /* XXX Useles code: Missing send? */ -- if (send_tok.length != 0) { -- if ((r = sshpkt_start(ssh, -- SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, -- send_tok.length)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- } -- fatal("gss_init_context failed"); -- } -- -- /* If we've got an old receive buffer get rid of it */ -- if (token_ptr != GSS_C_NO_BUFFER) -- gss_release_buffer(&min_status, &recv_tok); -- -- if (maj_status == GSS_S_COMPLETE) { -- /* If mutual state flag is not true, kex fails */ -- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -- fatal("Mutual authentication failed"); -- -- /* If integ avail flag is not true kex fails */ -- if (!(ret_flags & GSS_C_INTEG_FLAG)) -- fatal("Integrity check failed"); -- } -- -- /* -- * If we have data to send, then the last message that we -- * received cannot have been a 'complete'. -- */ -- if (send_tok.length != 0) { -- if (first) { -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, -- send_tok.length)) != 0 || -- (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) -- fatal("failed to construct packet: %s", ssh_err(r)); -- first = 0; -- } else { -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, -- send_tok.length)) != 0) -- fatal("failed to construct packet: %s", ssh_err(r)); -- } -- if ((r = sshpkt_send(ssh)) != 0) -- fatal("failed to send packet: %s", ssh_err(r)); -- gss_release_buffer(&min_status, &send_tok); -- -- /* If we've sent them data, they should reply */ -- do { -- type = ssh_packet_read(ssh); -- if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -- u_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_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); -- -- switch (type) { -- case SSH2_MSG_KEXGSS_CONTINUE: -- debug("Received GSSAPI_CONTINUE"); -- if (maj_status == GSS_S_COMPLETE) -- fatal("GSSAPI Continue received from server when complete"); -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &recv_tok)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("Failed to read token: %s", ssh_err(r)); -- break; -- case SSH2_MSG_KEXGSS_COMPLETE: -- debug("Received GSSAPI_COMPLETE"); -- if (msg_tok.value != NULL) -- fatal("Received GSSAPI_COMPLETE twice?"); -- if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || -- (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &msg_tok)) != 0) -- fatal("Failed to read message: %s", ssh_err(r)); -- -- /* Is there a token included? */ -- if ((r = sshpkt_get_u8(ssh, &c)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- if (c) { -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc( -- ssh, &recv_tok)) != 0) -- fatal("Failed to read token: %s", ssh_err(r)); -- /* If we're already complete - protocol error */ -- if (maj_status == GSS_S_COMPLETE) -- sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -- } else { -- /* No token included */ -- if (maj_status != GSS_S_COMPLETE) -- sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -- } -- if ((r = sshpkt_get_end(ssh)) != 0) { -- fatal("Expecting end of packet."); -- } -- break; -- case SSH2_MSG_KEXGSS_ERROR: -- debug("Received Error"); -- if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || -- (r = sshpkt_get_u32(ssh, &min_status)) != 0 || -- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || -- (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt_get failed: %s", ssh_err(r)); -- fatal("GSSAPI Error: \n%.400s", msg); -- default: -- sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", -- type); -- } -- token_ptr = &recv_tok; -- } else { -- /* No data, and not complete */ -- if (maj_status != GSS_S_COMPLETE) -- fatal("Not complete, and no token output"); -- } -- } while (maj_status & GSS_S_CONTINUE_NEEDED); -- - /* - * We _must_ have received a COMPLETE message in reply from the - * server, which will have set server_blob and msg_tok - */ - -- if (type != SSH2_MSG_KEXGSS_COMPLETE) -- fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -- - /* compute shared secret */ - switch (kex->kex_type) { - case KEX_GSS_GRP1_SHA1: - case KEX_GSS_GRP14_SHA1: - case KEX_GSS_GRP14_SHA256: - case KEX_GSS_GRP16_SHA512: -- r = kex_dh_dec(kex, server_blob, &shared_secret); -+ r = kex_dh_dec(kex, gss->server_blob, &shared_secret); - break; - case KEX_GSS_C25519_SHA256: -- if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80) -+ if (sshbuf_ptr(gss->server_blob)[sshbuf_len(gss->server_blob)] & 0x80) - fatal("The received key has MSB of last octet set!"); -- r = kex_c25519_dec(kex, server_blob, &shared_secret); -+ r = kex_c25519_dec(kex, gss->server_blob, &shared_secret); - break; - case KEX_GSS_NISTP256_SHA256: -- if (sshbuf_len(server_blob) != 65) -- fatal("The received NIST-P256 key did not match" -- "expected length (expected 65, got %zu)", sshbuf_len(server_blob)); -+ if (sshbuf_len(gss->server_blob) != 65) -+ fatal("The received NIST-P256 key did not match " -+ "expected length (expected 65, got %zu)", -+ sshbuf_len(gss->server_blob)); - -- if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) -+ if (sshbuf_ptr(gss->server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) - fatal("The received NIST-P256 key does not have first octet 0x04"); - -- r = kex_ecdh_dec(kex, server_blob, &shared_secret); -+ r = kex_ecdh_dec(kex, gss->server_blob, &shared_secret); - break; - default: - r = SSH_ERR_INVALID_ARGUMENT; - break; - } -- if (r != 0) -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); - goto out; -+ } - - if ((empty = sshbuf_new()) == NULL) { -+ ssh_gssapi_delete_ctx(&kex->gss); - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - - hashlen = sizeof(hash); -- if ((r = kex_gen_hash( -- kex->hash_alg, -- kex->client_version, -- kex->server_version, -- kex->my, -- kex->peer, -- (server_host_key_blob ? server_host_key_blob : empty), -- kex->client_pub, -- server_blob, -- shared_secret, -- hash, &hashlen)) != 0) -+ r = kex_gen_hash(kex->hash_alg, kex->client_version, -+ kex->server_version, kex->my, kex->peer, -+ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), -+ kex->client_pub, gss->server_blob, shared_secret, -+ hash, &hashlen); -+ sshbuf_free(empty); -+ if (r != 0) - fatal_f("Unexpected KEX type %d", kex->kex_type); - -- gssbuf.value = hash; -- gssbuf.length = hashlen; -+ gss->buf.value = hash; -+ gss->buf.length = hashlen; - - /* Verify that the hash matches the MIC we just got. */ -- if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) -+ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) - sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); - -- gss_release_buffer(&min_status, &msg_tok); -+ gss_release_buffer(&gss->minor, &gss->msg_tok); - - if (kex->gss_deleg_creds) -- ssh_gssapi_credentials_updated(ctxt); -+ ssh_gssapi_credentials_updated(gss); - - if (gss_kex_context == NULL) -- gss_kex_context = ctxt; -+ gss_kex_context = gss; - else -- ssh_gssapi_delete_ctx(&ctxt); -+ ssh_gssapi_delete_ctx(&kex->gss); - - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); - -+ if (kex->gss != NULL) { -+ sshbuf_free(gss->server_host_key_blob); -+ gss->server_host_key_blob = NULL; -+ sshbuf_free(gss->server_blob); -+ gss->server_blob = NULL; -+ } - out: -- explicit_bzero(hash, sizeof(hash)); - explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); -- sshbuf_free(empty); -- sshbuf_free(server_host_key_blob); -- sshbuf_free(server_blob); -+ explicit_bzero(hash, sizeof(hash)); - sshbuf_free(shared_secret); - sshbuf_free(kex->client_pub); - kex->client_pub = NULL; - return r; - } - -+static int -+kexgss_init_ctx(struct ssh *ssh, -+ gss_buffer_desc *token_ptr) -+{ -+ struct kex *kex = ssh->kex; -+ Gssctxt *gss = kex->gss; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ret_flags; -+ int r; -+ -+ debug("Calling gss_init_sec_context"); -+ -+ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, -+ token_ptr, &send_tok, &ret_flags); -+ -+ if (GSS_ERROR(gss->major)) { -+ /* XXX Useless code: Missing send? */ -+ if (send_tok.length != 0) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ fatal("gss_init_context failed"); -+ } -+ -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ gss_release_buffer(&gss->minor, token_ptr); -+ -+ if (gss->major == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); -+ -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } -+ -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (gss->first) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ gss->first = 0; -+ } else { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ } -+ if ((r = sshpkt_send(ssh)) != 0) -+ fatal("failed to send packet: %s", ssh_err(r)); -+ gss_release_buffer(&gss->minor, &send_tok); -+ -+ /* If we've sent them data, they should reply */ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgss_complete); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); -+ return 0; -+ } -+ /* No data, and not complete */ -+ if (gss->major != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return kexgss_init_ctx(ssh, token_ptr); -+ -+ return kexgss_final(ssh); -+} -+ - int --kexgssgex_client(struct ssh *ssh) -+kexgss_client(struct ssh *ssh) - { - struct kex *kex = ssh->kex; -- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, -- recv_tok = GSS_C_EMPTY_BUFFER, gssbuf, -- msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; -- Gssctxt *ctxt; -- OM_uint32 maj_status, min_status, ret_flags; -- struct sshbuf *shared_secret = NULL; -- BIGNUM *p = NULL; -- BIGNUM *g = NULL; -- struct sshbuf *buf = NULL; -- struct sshbuf *server_host_key_blob = NULL; -- struct sshbuf *server_blob = NULL; -- BIGNUM *dh_server_pub = NULL; -- u_char *msg; -- int type = 0; -- int first = 1; -- u_char hash[SSH_DIGEST_MAX_LENGTH]; -- size_t hashlen; -- const BIGNUM *pub_key, *dh_p, *dh_g; -- int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; -- struct sshbuf *empty = NULL; -- u_char c; - int r; - - /* Initialise our GSSAPI world */ -- ssh_gssapi_build_ctx(&ctxt); -- if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) -- == GSS_C_NO_OID) -+ ssh_gssapi_build_ctx(&kex->gss); -+ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) - fatal("Couldn't identify host exchange"); - -- if (ssh_gssapi_import_name(ctxt, kex->gss_host)) -+ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) - fatal("Couldn't import hostname"); - - if (kex->gss_client && -- ssh_gssapi_client_identity(ctxt, kex->gss_client)) -+ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) - fatal("Couldn't acquire client credentials"); - -- debug("Doing group exchange"); -- nbits = dh_estimate(kex->dh_need * 8); -+ /* Step 1 */ -+ switch (kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: -+ r = kex_dh_keypair(kex); -+ break; -+ case KEX_GSS_NISTP256_SHA256: -+ r = kex_ecdh_keypair(kex); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ r = kex_c25519_keypair(kex); -+ break; -+ default: -+ fatal_f("Unexpected KEX type %d", kex->kex_type); -+ } -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); -+ return r; -+ } -+ return kexgss_init_ctx(ssh, GSS_C_NO_BUFFER); -+} - -- kex->min = DH_GRP_MIN; -- kex->max = DH_GRP_MAX; -- kex->nbits = nbits; -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || -- (r = sshpkt_put_u32(ssh, min)) != 0 || -- (r = sshpkt_put_u32(ssh, nbits)) != 0 || -- (r = sshpkt_put_u32(ssh, max)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -- fatal("Failed to construct a packet: %s", ssh_err(r)); -+static int -+input_kexgss_hostkey(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ u_char *tmp = NULL; -+ size_t tmp_len = 0; -+ int r; -+ -+ debug("Received KEXGSS_HOSTKEY"); -+ if (gss->server_host_key_blob) -+ fatal("Server host key received more than once"); -+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) -+ fatal("Failed to read server host key: %s", ssh_err(r)); -+ if ((gss->server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) -+ fatal("sshbuf_from failed"); -+ return 0; -+} - -- if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0) -- fatal("Error: %s", ssh_err(r)); -+static int -+input_kexgss_continue(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; -+ int r; - -- if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || -- (r = sshpkt_get_bignum2(ssh, &g)) != 0 || -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); -+ -+ debug("Received GSSAPI_CONTINUE"); -+ if (gss->major == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || - (r = sshpkt_get_end(ssh)) != 0) -- fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); -+ fatal("Failed to read token: %s", ssh_err(r)); -+ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) -+ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -+ return kexgss_init_ctx(ssh, &recv_tok); -+} - -- if (BN_num_bits(p) < min || BN_num_bits(p) > max) -- fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", -- min, BN_num_bits(p), max); -+static int -+input_kexgss_complete(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; -+ u_char c; -+ int r; - -- if ((kex->dh = dh_new_group(g, p)) == NULL) -- fatal("dn_new_group() failed"); -- p = g = NULL; /* belong to kex->dh now */ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); -+ -+ debug("Received GSSAPI_COMPLETE"); -+ if (gss->msg_tok.value != NULL) -+ fatal("Received GSSAPI_COMPLETE twice?"); -+ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || -+ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) -+ fatal("Failed to read message: %s", ssh_err(r)); -+ -+ /* Is there a token included? */ -+ if ((r = sshpkt_get_u8(ssh, &c)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ if (c) { -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) -+ fatal("Failed to read token: %s", ssh_err(r)); -+ /* If we're already complete - protocol error */ -+ if (gss->major == GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -+ } else { -+ if (gss->major != GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -+ } -+ if ((r = sshpkt_get_end(ssh)) != 0) -+ fatal("Expecting end of packet."); - -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -- goto out; -- DH_get0_key(kex->dh, &pub_key, NULL); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return kexgss_init_ctx(ssh, &recv_tok); - -- token_ptr = GSS_C_NO_BUFFER; -+ return kexgss_final(ssh); -+} - -- do { -- /* Step 2 - call GSS_Init_sec_context() */ -- debug("Calling gss_init_sec_context"); -- -- maj_status = ssh_gssapi_init_ctx(ctxt, -- kex->gss_deleg_creds, token_ptr, &send_tok, -- &ret_flags); -- -- if (GSS_ERROR(maj_status)) { -- /* XXX Useles code: Missing send? */ -- if (send_tok.length != 0) { -- if ((r = sshpkt_start(ssh, -- SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, -- send_tok.length)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- } -- fatal("gss_init_context failed"); -- } -+static int -+input_kexgss_error(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ u_char *msg; -+ int r; - -- /* If we've got an old receive buffer get rid of it */ -- if (token_ptr != GSS_C_NO_BUFFER) -- gss_release_buffer(&min_status, &recv_tok); -- -- if (maj_status == GSS_S_COMPLETE) { -- /* If mutual state flag is not true, kex fails */ -- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -- fatal("Mutual authentication failed"); -- -- /* If integ avail flag is not true kex fails */ -- if (!(ret_flags & GSS_C_INTEG_FLAG)) -- fatal("Integrity check failed"); -- } -+ debug("Received Error"); -+ if ((r = sshpkt_get_u32(ssh, &gss->major)) != 0 || -+ (r = sshpkt_get_u32(ssh, &gss->minor)) != 0 || -+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || -+ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt_get failed: %s", ssh_err(r)); -+ fatal("GSSAPI Error: \n%.400s", msg); -+ return 0; -+} - -- /* -- * If we have data to send, then the last message that we -- * received cannot have been a 'complete'. -- */ -- if (send_tok.length != 0) { -- if (first) { -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, -- send_tok.length)) != 0 || -- (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- first = 0; -- } else { -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh,send_tok.value, -- send_tok.length)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- } -- if ((r = sshpkt_send(ssh)) != 0) -- fatal("sshpkt_send failed: %s", ssh_err(r)); -- gss_release_buffer(&min_status, &send_tok); -- -- /* If we've sent them data, they should reply */ -- do { -- type = ssh_packet_read(ssh); -- if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -- u_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_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); -- -- switch (type) { -- case SSH2_MSG_KEXGSS_CONTINUE: -- debug("Received GSSAPI_CONTINUE"); -- if (maj_status == GSS_S_COMPLETE) -- fatal("GSSAPI Continue received from server when complete"); -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &recv_tok)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- break; -- case SSH2_MSG_KEXGSS_COMPLETE: -- debug("Received GSSAPI_COMPLETE"); -- if (msg_tok.value != NULL) -- fatal("Received GSSAPI_COMPLETE twice?"); -- if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || -- (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &msg_tok)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- -- /* Is there a token included? */ -- if ((r = sshpkt_get_u8(ssh, &c)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- if (c) { -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc( -- ssh, &recv_tok)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- /* If we're already complete - protocol error */ -- if (maj_status == GSS_S_COMPLETE) -- sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -- } else { -- /* No token included */ -- if (maj_status != GSS_S_COMPLETE) -- sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -- } -- break; -- case SSH2_MSG_KEXGSS_ERROR: -- debug("Received Error"); -- if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || -- (r = sshpkt_get_u32(ssh, &min_status)) != 0 || -- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || -- (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- fatal("GSSAPI Error: \n%.400s", msg); -- default: -- sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", -- type); -- } -- token_ptr = &recv_tok; -- } else { -- /* No data, and not complete */ -- if (maj_status != GSS_S_COMPLETE) -- fatal("Not complete, and no token output"); -- } -- } while (maj_status & GSS_S_CONTINUE_NEEDED); -+/*******************************************************/ -+/******************** KEXGSSGEX ************************/ -+/*******************************************************/ -+ -+int -+kexgssgex_client(struct ssh *ssh) -+{ -+ struct kex *kex = ssh->kex; -+ int r; -+ -+ /* Initialise our GSSAPI world */ -+ ssh_gssapi_build_ctx(&kex->gss); -+ if (ssh_gssapi_id_kex(kex->gss, kex->name, kex->kex_type) == GSS_C_NO_OID) -+ fatal("Couldn't identify host exchange"); -+ -+ if (ssh_gssapi_import_name(kex->gss, kex->gss_host)) -+ fatal("Couldn't import hostname"); -+ -+ if (kex->gss_client && -+ ssh_gssapi_client_identity(kex->gss, kex->gss_client)) -+ fatal("Couldn't acquire client credentials"); -+ -+ debug("Doing group exchange"); -+ kex->min = DH_GRP_MIN; -+ kex->max = DH_GRP_MAX; -+ kex->nbits = dh_estimate(kex->dh_need * 8); -+ -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || -+ (r = sshpkt_put_u32(ssh, kex->min)) != 0 || -+ (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || -+ (r = sshpkt_put_u32(ssh, kex->max)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("Failed to construct a packet: %s", ssh_err(r)); -+ -+ debug("Wait SSH2_MSG_KEXGSS_GROUP"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, &input_kexgssgex_group); -+ return 0; -+} -+ -+static int -+kexgssgex_final(struct ssh *ssh) -+{ -+ struct kex *kex = ssh->kex; -+ Gssctxt *gss = kex->gss; -+ struct sshbuf *buf = NULL; -+ struct sshbuf *empty = NULL; -+ struct sshbuf *shared_secret = NULL; -+ BIGNUM *dh_server_pub = NULL; -+ const BIGNUM *pub_key, *dh_p, *dh_g; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ int r = SSH_ERR_INTERNAL_ERROR; - - /* - * We _must_ have received a COMPLETE message in reply from the -- * server, which will have set dh_server_pub and msg_tok -+ * server, which will have set server_blob and msg_tok - */ - -- if (type != SSH2_MSG_KEXGSS_COMPLETE) -- fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -- - /* 7. C verifies that the key Q_S is valid */ - /* 8. C computes shared secret */ - if ((buf = sshbuf_new()) == NULL || -- (r = sshbuf_put_stringb(buf, server_blob)) != 0 || -- (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) -+ (r = sshbuf_put_stringb(buf, gss->server_blob)) != 0 || -+ (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); - goto out; -+ } - sshbuf_free(buf); - buf = NULL; - - if ((shared_secret = sshbuf_new()) == NULL) { -+ ssh_gssapi_delete_ctx(&kex->gss); - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - -- if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) -+ if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); - goto out; -+ } -+ - if ((empty = sshbuf_new()) == NULL) { -+ ssh_gssapi_delete_ctx(&kex->gss); - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - -+ DH_get0_key(kex->dh, &pub_key, NULL); - DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); - hashlen = sizeof(hash); -- if ((r = kexgex_hash( -- kex->hash_alg, -- kex->client_version, -- kex->server_version, -- kex->my, -- kex->peer, -- (server_host_key_blob ? server_host_key_blob : empty), -- kex->min, kex->nbits, kex->max, -- dh_p, dh_g, -- pub_key, -- dh_server_pub, -- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), -- hash, &hashlen)) != 0) -+ r = kexgex_hash(kex->hash_alg, kex->client_version, -+ kex->server_version, kex->my, kex->peer, -+ (gss->server_host_key_blob ? gss->server_host_key_blob : empty), -+ kex->min, kex->nbits, kex->max, dh_p, dh_g, pub_key, -+ dh_server_pub, sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), -+ hash, &hashlen); -+ sshbuf_free(empty); -+ if (r != 0) - fatal("Failed to calculate hash: %s", ssh_err(r)); - -- gssbuf.value = hash; -- gssbuf.length = hashlen; -+ gss->buf.value = hash; -+ gss->buf.length = hashlen; - - /* Verify that the hash matches the MIC we just got. */ -- if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) -+ if (GSS_ERROR(ssh_gssapi_checkmic(gss, &gss->buf, &gss->msg_tok))) - sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); - -- gss_release_buffer(&min_status, &msg_tok); -+ gss_release_buffer(&gss->minor, &gss->msg_tok); - - if (kex->gss_deleg_creds) -- ssh_gssapi_credentials_updated(ctxt); -+ ssh_gssapi_credentials_updated(gss); - - if (gss_kex_context == NULL) -- gss_kex_context = ctxt; -+ gss_kex_context = gss; - else -- ssh_gssapi_delete_ctx(&ctxt); -+ ssh_gssapi_delete_ctx(&kex->gss); - - /* Finally derive the keys and send them */ - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); -+ -+ if (kex->gss != NULL) { -+ sshbuf_free(gss->server_host_key_blob); -+ gss->server_host_key_blob = NULL; -+ sshbuf_free(gss->server_blob); -+ gss->server_blob = NULL; -+ } - out: -- sshbuf_free(buf); -- sshbuf_free(server_blob); -- sshbuf_free(empty); - explicit_bzero(hash, sizeof(hash)); - DH_free(kex->dh); - kex->dh = NULL; - BN_clear_free(dh_server_pub); - sshbuf_free(shared_secret); -- sshbuf_free(server_host_key_blob); - return r; - } - -+static int -+kexgssgex_init_ctx(struct ssh *ssh, -+ gss_buffer_desc *token_ptr) -+{ -+ struct kex *kex = ssh->kex; -+ Gssctxt *gss = kex->gss; -+ const BIGNUM *pub_key; -+ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ret_flags; -+ int r; -+ -+ /* Step 2 - call GSS_Init_sec_context() */ -+ debug("Calling gss_init_sec_context"); -+ -+ gss->major = ssh_gssapi_init_ctx(gss, kex->gss_deleg_creds, -+ token_ptr, &send_tok, &ret_flags); -+ -+ if (GSS_ERROR(gss->major)) { -+ /* XXX Useless code: Missing send? */ -+ if (send_tok.length != 0) { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ } -+ fatal("gss_init_context failed"); -+ } -+ -+ /* If we've got an old receive buffer get rid of it */ -+ if (token_ptr != GSS_C_NO_BUFFER) -+ gss_release_buffer(&gss->minor, token_ptr); -+ -+ if (gss->major == GSS_S_COMPLETE) { -+ /* If mutual state flag is not true, kex fails */ -+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ fatal("Mutual authentication failed"); -+ -+ /* If integ avail flag is not true kex fails */ -+ if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ fatal("Integrity check failed"); -+ } -+ -+ /* -+ * If we have data to send, then the last message that we -+ * received cannot have been a 'complete'. -+ */ -+ if (send_tok.length != 0) { -+ if (gss->first) { -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ gss->first = 0; -+ } else { -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ fatal("failed to construct packet: %s", ssh_err(r)); -+ } -+ if ((r = sshpkt_send(ssh)) != 0) -+ fatal("failed to send packet: %s", ssh_err(r)); -+ gss_release_buffer(&gss->minor, &send_tok); -+ -+ /* If we've sent them data, they should reply */ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, &input_kexgss_hostkey); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, &input_kexgssgex_complete); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, &input_kexgss_error); -+ return 0; -+ } -+ /* No data, and not complete */ -+ if (gss->major != GSS_S_COMPLETE) -+ fatal("Not complete, and no token output"); -+ -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return kexgssgex_init_ctx(ssh, token_ptr); -+ -+ return kexgssgex_final(ssh); -+} -+ -+static int -+input_kexgssgex_group(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ struct kex *kex = ssh->kex; -+ BIGNUM *p = NULL; -+ BIGNUM *g = NULL; -+ int r; -+ -+ debug("Received SSH2_MSG_KEXGSS_GROUP"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUP, NULL); -+ -+ if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || -+ (r = sshpkt_get_bignum2(ssh, &g)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); -+ -+ if (BN_num_bits(p) < kex->min || BN_num_bits(p) > kex->max) -+ fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", -+ kex->min, BN_num_bits(p), kex->max); -+ -+ if ((kex->dh = dh_new_group(g, p)) == NULL) -+ fatal("dn_new_group() failed"); -+ p = g = NULL; /* belong to kex->dh now */ -+ -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ return r; -+ } -+ -+ return kexgssgex_init_ctx(ssh, GSS_C_NO_BUFFER); -+} -+ -+static int -+input_kexgssgex_continue(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; -+ int r; -+ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); -+ -+ debug("Received GSSAPI_CONTINUE"); -+ if (gss->major == GSS_S_COMPLETE) -+ fatal("GSSAPI Continue received from server when complete"); -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("Failed to read token: %s", ssh_err(r)); -+ if (!(gss->major & GSS_S_CONTINUE_NEEDED)) -+ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); -+ return kexgssgex_init_ctx(ssh, &recv_tok); -+} -+ -+static int -+input_kexgssgex_complete(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; -+ u_char c; -+ int r; -+ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_HOSTKEY, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_COMPLETE, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_ERROR, NULL); -+ -+ debug("Received GSSAPI_COMPLETE"); -+ if (gss->msg_tok.value != NULL) -+ fatal("Received GSSAPI_COMPLETE twice?"); -+ if ((r = sshpkt_getb_froms(ssh, &gss->server_blob)) != 0 || -+ (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &gss->msg_tok)) != 0) -+ fatal("Failed to read message: %s", ssh_err(r)); -+ -+ /* Is there a token included? */ -+ if ((r = sshpkt_get_u8(ssh, &c)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ if (c) { -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0) -+ fatal("Failed to read token: %s", ssh_err(r)); -+ /* If we're already complete - protocol error */ -+ if (gss->major == GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: received token when complete"); -+ } else { -+ if (gss->major != GSS_S_COMPLETE) -+ sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); -+ } -+ if ((r = sshpkt_get_end(ssh)) != 0) -+ fatal("Expecting end of packet."); -+ -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return kexgssgex_init_ctx(ssh, &recv_tok); -+ -+ return kexgssgex_final(ssh); -+} -+ - #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --color -ruNp a/kexgsss.c b/kexgsss.c ---- a/kexgsss.c 2024-05-16 15:49:43.820407648 +0200 -+++ b/kexgsss.c 2024-07-02 16:29:05.744790839 +0200 -@@ -50,33 +50,18 @@ - - extern ServerOptions options; - -+static int input_kexgss_init(int, u_int32_t, struct ssh *); -+static int input_kexgss_continue(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_groupreq(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_init(int, u_int32_t, struct ssh *); -+static int input_kexgssgex_continue(int, u_int32_t, struct ssh *); -+ - int - kexgss_server(struct ssh *ssh) - { - struct kex *kex = ssh->kex; -- OM_uint32 maj_status, min_status; -- -- /* -- * Some GSSAPI implementations use the input value of ret_flags (an -- * output variable) as a means of triggering mechanism specific -- * features. Initializing it to zero avoids inadvertently -- * activating this non-standard behaviour. -- */ -- -- OM_uint32 ret_flags = 0; -- 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; -- struct sshbuf *client_pubkey = NULL; -- struct sshbuf *server_pubkey = NULL; -- struct sshbuf *empty = sshbuf_new(); -- int type = 0; - gss_OID oid; - char *mechs; -- u_char hash[SSH_DIGEST_MAX_LENGTH]; -- size_t hashlen; -- int r; - - /* Initialise GSSAPI */ - -@@ -92,135 +77,91 @@ kexgss_server(struct ssh *ssh) - debug2_f("Identifying %s", kex->name); - oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); - if (oid == GSS_C_NO_OID) -- fatal("Unknown gssapi mechanism"); -+ fatal("Unknown gssapi mechanism"); - - debug2_f("Acquiring credentials"); - -- if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) - fatal("Unable to acquire credentials for the server"); - -- do { -- debug("Wait SSH2_MSG_KEXGSS_INIT"); -- type = ssh_packet_read(ssh); -- switch(type) { -- case SSH2_MSG_KEXGSS_INIT: -- if (gssbuf.value != NULL) -- fatal("Received KEXGSS_INIT after initialising"); -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &recv_tok)) != 0 || -- (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -+ ssh_gssapi_build_ctx(&kex->gss); -+ if (kex->gss == NULL) -+ fatal("Unable to allocate memory for gss context"); -+ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgss_init); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgss_continue); -+ debug("Wait SSH2_MSG_KEXGSS_INIT"); -+ return 0; -+} - -- switch (kex->kex_type) { -- case KEX_GSS_GRP1_SHA1: -- case KEX_GSS_GRP14_SHA1: -- case KEX_GSS_GRP14_SHA256: -- case KEX_GSS_GRP16_SHA512: -- r = kex_dh_enc(kex, client_pubkey, &server_pubkey, -- &shared_secret); -- break; -- case KEX_GSS_NISTP256_SHA256: -- r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, -- &shared_secret); -- break; -- case KEX_GSS_C25519_SHA256: -- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, -- &shared_secret); -- break; -- default: -- fatal_f("Unexpected KEX type %d", kex->kex_type); -- } -- if (r != 0) -- 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, -- &recv_tok)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- break; -- default: -- sshpkt_disconnect(ssh, -- "Protocol error: didn't expect packet type %d", -- type); -- } -+static inline void -+kexgss_accept_ctx(struct ssh *ssh, -+ gss_buffer_desc *recv_tok, -+ gss_buffer_desc *send_tok, -+ OM_uint32 *ret_flags) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ int r; - -- maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -- &send_tok, &ret_flags); -+ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); -+ gss_release_buffer(&gss->minor, recv_tok); - -- gss_release_buffer(&min_status, &recv_tok); -+ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) -+ fatal("Zero length token output when incomplete"); - -- if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -- fatal("Zero length token output when incomplete"); -+ if (gss->buf.value == NULL) -+ fatal("No client public key"); - -- if (gssbuf.value == NULL) -- fatal("No client public key"); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ gss_release_buffer(&gss->minor, send_tok); -+ } -+} - -- if (maj_status & GSS_S_CONTINUE_NEEDED) { -- debug("Sending GSSAPI_CONTINUE"); -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- gss_release_buffer(&min_status, &send_tok); -- } -- } while (maj_status & GSS_S_CONTINUE_NEEDED); -+static inline int -+kexgss_final(struct ssh *ssh, -+ gss_buffer_desc *send_tok, -+ OM_uint32 *ret_flags) -+{ -+ struct kex *kex = ssh->kex; -+ Gssctxt *gss = kex->gss; -+ gss_buffer_desc msg_tok; -+ int r; -+ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); - -- if (GSS_ERROR(maj_status)) { -- if (send_tok.length > 0) { -+ if (GSS_ERROR(gss->major)) { -+ if (send_tok->length > 0) { - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || - (r = sshpkt_send(ssh)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - } - fatal("accept_ctx died"); - } - -- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) - fatal("Mutual Authentication flag wasn't set"); - -- if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ if (!(*ret_flags & GSS_C_INTEG_FLAG)) - fatal("Integrity flag wasn't set"); - -- if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) -+ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) - fatal("Couldn't get MIC"); - - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || -- (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || -+ (r = sshpkt_put_stringb(ssh, gss->server_pubkey)) != 0 || - (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - -- if (send_tok.length != 0) { -+ if (send_tok->length != 0) { - if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - } else { - if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ -@@ -229,59 +170,139 @@ kexgss_server(struct ssh *ssh) - if ((r = sshpkt_send(ssh)) != 0) - fatal("sshpkt_send failed: %s", ssh_err(r)); - -- gss_release_buffer(&min_status, &send_tok); -- gss_release_buffer(&min_status, &msg_tok); -+ gss_release_buffer(&gss->minor, send_tok); -+ gss_release_buffer(&gss->minor, &msg_tok); - - if (gss_kex_context == NULL) -- gss_kex_context = ctxt; -+ gss_kex_context = gss; - else -- ssh_gssapi_delete_ctx(&ctxt); -+ ssh_gssapi_delete_ctx(&kex->gss); - -- if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) -+ if ((r = kex_derive_keys(ssh, gss->hash, gss->hashlen, gss->shared_secret)) == 0) - r = kex_send_newkeys(ssh); - - /* If this was a rekey, then save out any delegated credentials we - * just exchanged. */ - if (options.gss_store_rekey) - ssh_gssapi_rekey_creds(); --out: -- sshbuf_free(empty); -- explicit_bzero(hash, sizeof(hash)); -- sshbuf_free(shared_secret); -- sshbuf_free(client_pubkey); -- sshbuf_free(server_pubkey); -+ -+ if (kex->gss != NULL) { -+ explicit_bzero(gss->hash, sizeof(gss->hash)); -+ sshbuf_free(gss->shared_secret); -+ gss->shared_secret = NULL; -+ sshbuf_free(gss->server_pubkey); -+ gss->server_pubkey = NULL; -+ } - return r; - } - --int --kexgssgex_server(struct ssh *ssh) -+static int -+input_kexgss_init(int type, -+ u_int32_t seq, -+ struct ssh *ssh) - { - struct kex *kex = ssh->kex; -- OM_uint32 maj_status, min_status; -+ Gssctxt *gss = kex->gss; -+ struct sshbuf *empty; -+ struct sshbuf *client_pubkey = NULL; -+ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ret_flags = 0; -+ int r; -+ -+ debug("SSH2_MSG_KEXGSS_INIT received"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); - -- /* -- * Some GSSAPI implementations use the input value of ret_flags (an -- * output variable) as a means of triggering mechanism specific -- * features. Initializing it to zero avoids inadvertently -- * activating this non-standard behaviour. -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || -+ (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ switch (kex->kex_type) { -+ case KEX_GSS_GRP1_SHA1: -+ case KEX_GSS_GRP14_SHA1: -+ case KEX_GSS_GRP14_SHA256: -+ case KEX_GSS_GRP16_SHA512: -+ r = kex_dh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); -+ break; -+ case KEX_GSS_NISTP256_SHA256: -+ r = kex_ecdh_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); -+ break; -+ case KEX_GSS_C25519_SHA256: -+ r = kex_c25519_enc(kex, client_pubkey, &gss->server_pubkey, &gss->shared_secret); -+ break; -+ default: -+ fatal_f("Unexpected KEX type %d", kex->kex_type); -+ } -+ if (r != 0) { -+ sshbuf_free(client_pubkey); -+ ssh_gssapi_delete_ctx(&kex->gss); -+ return r; -+ } -+ -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ -+ if ((empty = sshbuf_new()) == NULL) { -+ sshbuf_free(client_pubkey); -+ ssh_gssapi_delete_ctx(&kex->gss); -+ return SSH_ERR_ALLOC_FAIL; -+ } -+ -+ /* Calculate the hash early so we can free the -+ * client_pubkey, which has reference to the parent -+ * buffer state->incoming_packet - */ -+ gss->hashlen = sizeof(gss->hash); -+ r = kex_gen_hash(kex->hash_alg, kex->client_version, kex->server_version, -+ kex->peer, kex->my, empty, client_pubkey, gss->server_pubkey, -+ gss->shared_secret, gss->hash, &gss->hashlen); -+ sshbuf_free(empty); -+ sshbuf_free(client_pubkey); -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); -+ return r; -+ } -+ -+ gss->buf.value = gss->hash; -+ gss->buf.length = gss->hashlen; -+ -+ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return 0; - -+ return kexgss_final(ssh, &send_tok, &ret_flags); -+} -+ -+static int -+input_kexgss_continue(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; - OM_uint32 ret_flags = 0; -- gss_buffer_desc gssbuf, recv_tok, msg_tok; -- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; -- Gssctxt *ctxt = NULL; -- struct sshbuf *shared_secret = NULL; -- int type = 0; -+ int r; -+ -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ kexgss_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return 0; -+ -+ return kexgss_final(ssh, &send_tok, &ret_flags); -+} -+ -+/*******************************************************/ -+/******************** KEXGSSGEX ************************/ -+/*******************************************************/ -+ -+int -+kexgssgex_server(struct ssh *ssh) -+{ -+ struct kex *kex = ssh->kex; - gss_OID oid; - char *mechs; -- u_char hash[SSH_DIGEST_MAX_LENGTH]; -- size_t hashlen; -- BIGNUM *dh_client_pub = NULL; -- const BIGNUM *pub_key, *dh_p, *dh_g; -- int min = -1, max = -1, nbits = -1; -- int cmin = -1, cmax = -1; /* client proposal */ -- struct sshbuf *empty = sshbuf_new(); -- int r; - - /* Initialise GSSAPI */ - -@@ -289,153 +310,125 @@ kexgssgex_server(struct ssh *ssh) - * in the GSSAPI code are no longer available. This kludges them back - * into life - */ -- if (!ssh_gssapi_oid_table_ok()) -- if ((mechs = ssh_gssapi_server_mechanisms())) -- free(mechs); -+ if (!ssh_gssapi_oid_table_ok()) { -+ mechs = ssh_gssapi_server_mechanisms(); -+ free(mechs); -+ } - - debug2_f("Identifying %s", kex->name); - oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); - if (oid == GSS_C_NO_OID) -- fatal("Unknown gssapi mechanism"); -+ fatal("Unknown gssapi mechanism"); - - debug2_f("Acquiring credentials"); - -- if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&kex->gss, oid))) - fatal("Unable to acquire credentials for the server"); - -- /* 5. S generates an ephemeral key pair (do the allocations early) */ -- debug("Doing group exchange"); -- ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ); -- /* store client proposal to provide valid signature */ -- if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || -- (r = sshpkt_get_u32(ssh, &nbits)) != 0 || -- (r = sshpkt_get_u32(ssh, &cmax)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- kex->nbits = nbits; -- kex->min = cmin; -- kex->max = cmax; -- min = MAX(DH_GRP_MIN, cmin); -- max = MIN(DH_GRP_MAX, cmax); -- nbits = MAXIMUM(DH_GRP_MIN, nbits); -- nbits = MINIMUM(DH_GRP_MAX, nbits); -- if (max < min || nbits < min || max < nbits) -- fatal("GSS_GEX, bad parameters: %d !< %d !< %d", -- 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"); -- } -+ ssh_gssapi_build_ctx(&kex->gss); -+ if (kex->gss == NULL) -+ fatal("Unable to allocate memory for gss context"); - -- DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || -- (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || -- (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- -- if ((r = ssh_packet_write_wait(ssh)) != 0) -- fatal("ssh_packet_write_wait: %s", ssh_err(r)); -- -- /* Compute our exchange value in parallel with the client */ -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -- goto out; -+ debug("Doing group exchange"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, &input_kexgssgex_groupreq); -+ return 0; -+} - -- do { -- debug("Wait SSH2_MSG_GSSAPI_INIT"); -- type = ssh_packet_read(ssh); -- switch(type) { -- case SSH2_MSG_KEXGSS_INIT: -- if (dh_client_pub != NULL) -- fatal("Received KEXGSS_INIT after initialising"); -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &recv_tok)) != 0 || -- (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -+static inline void -+kexgssgex_accept_ctx(struct ssh *ssh, -+ gss_buffer_desc *recv_tok, -+ gss_buffer_desc *send_tok, -+ OM_uint32 *ret_flags) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ int r; - -- /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -- break; -- case SSH2_MSG_KEXGSS_CONTINUE: -- if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, -- &recv_tok)) != 0 || -- (r = sshpkt_get_end(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- break; -- default: -- sshpkt_disconnect(ssh, -- "Protocol error: didn't expect packet type %d", -- type); -- } -+ gss->major = mm_ssh_gssapi_accept_ctx(gss, recv_tok, send_tok, ret_flags); -+ gss_release_buffer(&gss->minor, recv_tok); - -- maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -- &send_tok, &ret_flags); -+ if (gss->major != GSS_S_COMPLETE && send_tok->length == 0) -+ fatal("Zero length token output when incomplete"); - -- gss_release_buffer(&min_status, &recv_tok); -+ if (gss->dh_client_pub == NULL) -+ fatal("No client public key"); - -- if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) -- fatal("Zero length token output when incomplete"); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) { -+ debug("Sending GSSAPI_CONTINUE"); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ gss_release_buffer(&gss->minor, send_tok); -+ } -+} - -- if (dh_client_pub == NULL) -- fatal("No client public key"); -+static inline int -+kexgssgex_final(struct ssh *ssh, -+ gss_buffer_desc *send_tok, -+ OM_uint32 *ret_flags) -+{ -+ struct kex *kex = ssh->kex; -+ Gssctxt *gss = kex->gss; -+ gss_buffer_desc msg_tok; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t hashlen; -+ const BIGNUM *pub_key, *dh_p, *dh_g; -+ struct sshbuf *shared_secret = NULL; -+ struct sshbuf *empty = NULL; -+ int r; - -- if (maj_status & GSS_S_CONTINUE_NEEDED) { -- debug("Sending GSSAPI_CONTINUE"); -- if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -- gss_release_buffer(&min_status, &send_tok); -- } -- } while (maj_status & GSS_S_CONTINUE_NEEDED); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); - -- if (GSS_ERROR(maj_status)) { -- if (send_tok.length > 0) { -+ if (GSS_ERROR(gss->major)) { -+ if (send_tok->length > 0) { - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0 || - (r = sshpkt_send(ssh)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - } - fatal("accept_ctx died"); - } - -- if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -+ if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) - fatal("Mutual Authentication flag wasn't set"); - -- if (!(ret_flags & GSS_C_INTEG_FLAG)) -+ if (!(*ret_flags & GSS_C_INTEG_FLAG)) - fatal("Integrity flag wasn't set"); - - /* calculate shared secret */ -- if ((shared_secret = sshbuf_new()) == NULL) { -+ shared_secret = sshbuf_new(); -+ if (shared_secret == NULL) { -+ ssh_gssapi_delete_ctx(&kex->gss); - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) -+ if ((r = kex_dh_compute_key(kex, gss->dh_client_pub, shared_secret)) != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); - goto out; -+ } -+ -+ if ((empty = sshbuf_new()) == NULL) { -+ ssh_gssapi_delete_ctx(&kex->gss); -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } - - DH_get0_key(kex->dh, &pub_key, NULL); - DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); - hashlen = sizeof(hash); -- if ((r = kexgex_hash( -- kex->hash_alg, -- kex->client_version, -- kex->server_version, -- kex->peer, -- kex->my, -- empty, -- cmin, nbits, cmax, -- dh_p, dh_g, -- dh_client_pub, -- pub_key, -- sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), -- hash, &hashlen)) != 0) -+ r = kexgex_hash(kex->hash_alg, kex->client_version, kex->server_version, -+ kex->peer, kex->my, empty, kex->min, kex->nbits, kex->max, dh_p, dh_g, -+ gss->dh_client_pub, pub_key, sshbuf_ptr(shared_secret), -+ sshbuf_len(shared_secret), hash, &hashlen); -+ sshbuf_free(empty); -+ if (r != 0) - fatal("kexgex_hash failed: %s", ssh_err(r)); - -- gssbuf.value = hash; -- gssbuf.length = hashlen; -+ gss->buf.value = hash; -+ gss->buf.length = hashlen; - -- if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) -+ if (GSS_ERROR(mm_ssh_gssapi_sign(gss, &gss->buf, &msg_tok))) - fatal("Couldn't get MIC"); - - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || -@@ -443,24 +436,24 @@ kexgssgex_server(struct ssh *ssh) - (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - -- if (send_tok.length != 0) { -+ if (send_tok->length != 0) { - if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ -- (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) -+ (r = sshpkt_put_string(ssh, send_tok->value, send_tok->length)) != 0) - fatal("sshpkt failed: %s", ssh_err(r)); - } else { - if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ - fatal("sshpkt failed: %s", ssh_err(r)); - } - if ((r = sshpkt_send(ssh)) != 0) -- fatal("sshpkt failed: %s", ssh_err(r)); -+ fatal("sshpkt_send failed: %s", ssh_err(r)); - -- gss_release_buffer(&min_status, &send_tok); -- gss_release_buffer(&min_status, &msg_tok); -+ gss_release_buffer(&gss->minor, send_tok); -+ gss_release_buffer(&gss->minor, &msg_tok); - - if (gss_kex_context == NULL) -- gss_kex_context = ctxt; -+ gss_kex_context = gss; - else -- ssh_gssapi_delete_ctx(&ctxt); -+ ssh_gssapi_delete_ctx(&kex->gss); - - /* Finally derive the keys and send them */ - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) -@@ -470,13 +463,128 @@ kexgssgex_server(struct ssh *ssh) - * just exchanged. */ - if (options.gss_store_rekey) - ssh_gssapi_rekey_creds(); -+ -+ if (kex->gss != NULL) -+ BN_clear_free(gss->dh_client_pub); -+ - out: -- sshbuf_free(empty); - explicit_bzero(hash, sizeof(hash)); - DH_free(kex->dh); - kex->dh = NULL; -- BN_clear_free(dh_client_pub); - sshbuf_free(shared_secret); - return r; - } -+ -+static int -+input_kexgssgex_groupreq(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ struct kex *kex = ssh->kex; -+ const BIGNUM *dh_p, *dh_g; -+ int min = -1, max = -1, nbits = -1; -+ int cmin = -1, cmax = -1; /* client proposal */ -+ int r; -+ -+ /* 5. S generates an ephemeral key pair (do the allocations early) */ -+ -+ debug("SSH2_MSG_KEXGSS_GROUPREQ received"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_GROUPREQ, NULL); -+ -+ /* store client proposal to provide valid signature */ -+ if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || -+ (r = sshpkt_get_u32(ssh, &nbits)) != 0 || -+ (r = sshpkt_get_u32(ssh, &cmax)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ kex->nbits = nbits; -+ kex->min = cmin; -+ kex->max = cmax; -+ min = MAX(DH_GRP_MIN, cmin); -+ max = MIN(DH_GRP_MAX, cmax); -+ nbits = MAXIMUM(DH_GRP_MIN, nbits); -+ nbits = MINIMUM(DH_GRP_MAX, nbits); -+ -+ if (max < min || nbits < min || max < nbits) -+ fatal("GSS_GEX, bad parameters: %d !< %d !< %d", 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"); -+ } -+ -+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ if ((r = ssh_packet_write_wait(ssh)) != 0) -+ fatal("ssh_packet_write_wait: %s", ssh_err(r)); -+ -+ /* Compute our exchange value in parallel with the client */ -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) { -+ ssh_gssapi_delete_ctx(&kex->gss); -+ DH_free(kex->dh); -+ kex->dh = NULL; -+ return r; -+ } -+ -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, &input_kexgssgex_init); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, &input_kexgssgex_continue); -+ debug("Wait SSH2_MSG_KEXGSS_INIT"); -+ return 0; -+} -+ -+static int -+input_kexgssgex_init(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ret_flags = 0; -+ int r; -+ -+ debug("SSH2_MSG_KEXGSS_INIT received"); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); -+ -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || -+ (r = sshpkt_get_bignum2(ssh, &gss->dh_client_pub)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ -+ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return 0; -+ -+ return kexgssgex_final(ssh, &send_tok, &ret_flags); -+} -+ -+static int -+input_kexgssgex_continue(int type, -+ u_int32_t seq, -+ struct ssh *ssh) -+{ -+ Gssctxt *gss = ssh->kex->gss; -+ gss_buffer_desc recv_tok, send_tok = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ret_flags = 0; -+ int r; -+ -+ if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, &recv_tok)) != 0 || -+ (r = sshpkt_get_end(ssh)) != 0) -+ fatal("sshpkt failed: %s", ssh_err(r)); -+ -+ kexgssgex_accept_ctx(ssh, &recv_tok, &send_tok, &ret_flags); -+ if (gss->major & GSS_S_CONTINUE_NEEDED) -+ return 0; -+ -+ return kexgssgex_final(ssh, &send_tok, &ret_flags); -+} -+ - #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --color -ruNp a/kex.h b/kex.h ---- a/kex.h 2024-05-16 15:49:43.986410812 +0200 -+++ b/kex.h 2024-06-18 12:19:48.580347469 +0200 -@@ -29,6 +29,10 @@ - #include "mac.h" - #include "crypto_api.h" - -+#ifdef GSSAPI -+# include "ssh-gss.h" /* Gssctxt */ -+#endif -+ - #ifdef WITH_OPENSSL - # include - # include -@@ -177,6 +181,7 @@ struct kex { - int hash_alg; - int ec_nid; - #ifdef GSSAPI -+ Gssctxt *gss; - int gss_deleg_creds; - int gss_trust_dns; - char *gss_host; -diff --color -ruNp a/ssh-gss.h b/ssh-gss.h ---- a/ssh-gss.h 2024-05-16 15:49:43.837407972 +0200 -+++ b/ssh-gss.h 2024-06-27 14:12:48.659866937 +0200 -@@ -88,6 +88,8 @@ extern char **k5users_allowed_cmds; - KEX_GSS_GRP14_SHA1_ID "," \ - KEX_GSS_GEX_SHA1_ID - -+#include "digest.h" /* SSH_DIGEST_MAX_LENGTH */ -+ - typedef struct { - char *filename; - char *envvar; -@@ -127,6 +129,16 @@ typedef struct { - gss_cred_id_t creds; /* server */ - gss_name_t client; /* server */ - gss_cred_id_t client_creds; /* both */ -+ struct sshbuf *shared_secret; /* both */ -+ struct sshbuf *server_pubkey; /* server */ -+ struct sshbuf *server_blob; /* client */ -+ struct sshbuf *server_host_key_blob; /* client */ -+ gss_buffer_desc msg_tok; /* client */ -+ gss_buffer_desc buf; /* both */ -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; /* both */ -+ size_t hashlen; /* both */ -+ int first; /* client */ -+ BIGNUM *dh_client_pub; /* server (gex) */ - } Gssctxt; - - extern ssh_gssapi_mech *supported_mechs[]; From 480372390cb559e3b85e341410c411097d6806f8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 05:17:11 +0000 Subject: [PATCH 133/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index a07c006..e1e70b1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -561,6 +561,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Fri Jan 17 2025 Fedora Release Engineering - 9.8p1-2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Wed Oct 02 2024 Mattias Ellert - 9.8p1-2 - Based on openssh-9.8p1-4.fc42 From 06032544b5fabeea4bb159c2ae1e3ed8ae201cf3 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Tue, 21 Jan 2025 09:58:09 +0100 Subject: [PATCH 134/146] Based on openssh-9.9p1-5.fc42 / openssh-9.9p1-1.fc41 --- gsi-openssh.spec | 49 +- gsisshd-keygen@.service | 3 + gsisshd.service | 3 + gsisshd@.service | 3 + openssh-6.6p1-allow-ip-opts.patch | 2 +- openssh-6.7p1-coverity.patch | 16 - openssh-7.6p1-audit.patch | 97 +- openssh-7.7p1-fips.patch | 83 +- openssh-8.0p1-crypto-policies.patch | 12 +- openssh-8.0p1-pkcs11-uri.patch | 44 +- openssh-8.7p1-audit-hostname.patch | 106 -- openssh-8.7p1-nohostsha1proof.patch | 41 - openssh-9.0p1-audit-log.patch | 133 +- openssh-9.0p1-evp-fips-ecdh.patch | 207 --- ....patch => openssh-9.0p1-evp-fips-kex.patch | 307 +++- openssh-9.3p1-merged-openssl-evp.patch | 1237 ----------------- openssh-9.6p1-gssapi-keyex.patch | 40 +- ...gsissh.patch => openssh-9.9p1-gsissh.patch | 313 ++--- ....1.patch => openssh-9.9p1-hpn-18.6.0.patch | 797 +++++------ openssh-9.9p1-mlkembe.patch | 98 ++ openssh-9.9p1-separate-keysign.patch | 12 + sources | 4 +- 22 files changed, 1291 insertions(+), 2316 deletions(-) delete mode 100644 openssh-8.7p1-audit-hostname.patch delete mode 100644 openssh-9.0p1-evp-fips-ecdh.patch rename openssh-9.0p1-evp-fips-dh.patch => openssh-9.0p1-evp-fips-kex.patch (50%) delete mode 100644 openssh-9.3p1-merged-openssl-evp.patch rename openssh-9.8p1-gsissh.patch => openssh-9.9p1-gsissh.patch (89%) rename openssh-9.8p1-hpn-18.5.1.patch => openssh-9.9p1-hpn-18.6.0.patch (96%) create mode 100644 openssh-9.9p1-mlkembe.patch create mode 100644 openssh-9.9p1-separate-keysign.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index e1e70b1..1060509 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,13 +23,13 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 9.8p1 -%global openssh_rel 2 +%global openssh_ver 9.9p1 +%global openssh_rel 1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -60,8 +60,6 @@ Patch200: openssh-7.6p1-audit.patch Patch201: openssh-7.1p2-audit-race-condition.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2049947 Patch202: openssh-9.0p1-audit-log.patch -# Correctly audit hostname and IP address -Patch203: openssh-8.7p1-audit-hostname.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-7.8p1-role-mls.patch @@ -139,9 +137,6 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # Mention crypto-policies in manual pages (#1668325) # clarify rhbz#2068423 on the man page of ssh_config Patch962: openssh-8.0p1-crypto-policies.patch -# Use OpenSSL high-level API to produce and verify signatures (#1707485) -# TODO fix the comment above ^ -Patch963: openssh-9.3p1-merged-openssl-evp.patch # Use OpenSSL KDF (#1631761) Patch964: openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work @@ -174,19 +169,22 @@ Patch1002: openssh-8.7p1-ssh-manpage.patch # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch -Patch1012: openssh-9.0p1-evp-fips-dh.patch -Patch1013: openssh-9.0p1-evp-fips-ecdh.patch +Patch1012: openssh-9.0p1-evp-fips-kex.patch Patch1014: openssh-8.7p1-nohostsha1proof.patch Patch1015: openssh-9.6p1-pam-rhost.patch +Patch1016: openssh-9.9p1-separate-keysign.patch +# upstream cf3e48ee8ba1beeccddd2f203b558fa102be67a2 +# upstream 0c3927c45f8a57b511c874c4d51a8c89414f74ef +Patch1017: openssh-9.9p1-mlkembe.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-9.8p1-gsissh.patch +Patch98: openssh-9.9p1-gsissh.patch # This is the HPN patch -# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.5.1 -Patch99: openssh-9.8p1-hpn-18.5.1.patch +# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.6.0 +Patch99: openssh-9.9p1-hpn-18.6.0.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 @@ -235,6 +233,10 @@ 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} + %package server Summary: SSH server daemon with GSI authentication Provides: gsissh-server = %{version}-%{release} @@ -270,6 +272,11 @@ 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 @@ -317,7 +324,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 951 -p1 -b .pkcs11-uri %patch -P 953 -p1 -b .scp-ipv6 %patch -P 962 -p1 -b .crypto-policies -%patch -P 963 -p1 -b .openssl-evp %patch -P 964 -p1 -b .openssl-kdf %patch -P 965 -p1 -b .visibility %patch -P 966 -p1 -b .x11-ipv6 @@ -331,15 +337,15 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 200 -p1 -b .audit %patch -P 201 -p1 -b .audit-race %patch -P 202 -p1 -b .audit-log -%patch -P 203 -p1 -b .audit-hostname %patch -P 700 -p1 -b .fips %patch -P 1002 -p1 -b .ssh-manpage %patch -P 1006 -p1 -b .negotiate-supported-algs %patch -P 1012 -p1 -b .evp-fips-dh -%patch -P 1013 -p1 -b .evp-fips-ecdh %patch -P 1014 -p1 -b .nosha1hostproof %patch -P 1015 -p1 -b .pam-rhost +%patch -P 1016 -p1 -b .sep-keysign +%patch -P 1017 -p1 -b .mlkembe %patch -P 100 -p1 -b .coverity %patch -P 98 -p1 -b .gsi @@ -468,7 +474,9 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/ssh-keyscan.1* rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-pkcs11-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 @@ -514,8 +522,6 @@ 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(4555,root,root) %{_libexecdir}/gsissh/ssh-keysign -%attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8* %files clients %attr(0755,root,root) %{_bindir}/gsissh @@ -534,6 +540,10 @@ fi %{_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 %attr(0755,root,root) %{_sbindir}/gsisshd @@ -561,6 +571,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Mon Jan 20 2025 Mattias Ellert - 9.9p1-1 +- Based on openssh-9.9p1-5.fc42 / openssh-9.9p1-1.fc41 + * Fri Jan 17 2025 Fedora Release Engineering - 9.8p1-2.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/gsisshd-keygen@.service b/gsisshd-keygen@.service index 6b2898b..62a1898 100644 --- a/gsisshd-keygen@.service +++ b/gsisshd-keygen@.service @@ -4,6 +4,9 @@ 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 diff --git a/gsisshd.service b/gsisshd.service index 6272ced..55dd115 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -9,6 +9,9 @@ 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 diff --git a/gsisshd@.service b/gsisshd@.service index 8a3fff2..acc3d85 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -8,6 +8,9 @@ After=gsisshd-keygen.target 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 StandardInput=socket diff --git a/openssh-6.6p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch index d969b5c..995e04e 100644 --- a/openssh-6.6p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -38,5 +38,5 @@ diff -up openssh/sshd.c.ip-opts openssh/sshd.c + } + } while (i < option_size); } - return; #endif /* IP_OPTIONS */ + } diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index d98da28..ffe0c69 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -73,22 +73,6 @@ diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); # endif -@@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con - - memset(&ut, 0, sizeof(ut)); - /* strncpy because we don't necessarily want nul termination */ -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut.ut_user, username, sizeof(ut.ut_user)); - strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); - -@@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con - ut.ut_pid = getpid(); - - /* strncpy because we don't necessarily want nul termination */ -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); - - if (ssh_packet_connection_is_on_socket(ssh) && diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c --- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100 +++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100 diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index c884292..2c7ddc5 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1086,7 +1086,7 @@ diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in --- openssh-8.6p1/Makefile.in.audit 2021-04-19 16:47:35.731061937 +0200 +++ openssh-8.6p1/Makefile.in 2021-04-19 16:47:35.756062129 +0200 @@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o @@ -2056,7 +2056,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -260,8 +261,8 @@ struct sshbuf *loginmsg; +@@ -260,8 +261,44 @@ struct sshbuf *loginmsg; struct sshbuf *loginmsg; /* Prototypes for various functions defined later in this file. */ @@ -2064,6 +2064,42 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c -void demote_sensitive_data(void); +void destroy_sensitive_data(struct ssh *); +void demote_sensitive_data(struct ssh *); ++ ++static int ++sshkey_is_private(const struct sshkey *k) ++{ ++ switch (k->type) { ++#ifdef WITH_OPENSSL ++ case KEY_RSA_CERT: ++ case KEY_RSA: { ++ const BIGNUM *d; ++ const RSA *rsa = EVP_PKEY_get0_RSA(k->pkey); ++ RSA_get0_key(rsa, NULL, NULL, &d); ++ return d != NULL; ++ } ++ case KEY_DSA_CERT: ++ case KEY_DSA: { ++ const BIGNUM *priv_key; ++ DSA_get0_key(k->dsa, NULL, &priv_key); ++ return priv_key != NULL; ++ } ++#ifdef OPENSSL_HAS_ECC ++ case KEY_ECDSA_CERT: ++ case KEY_ECDSA: { ++ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(k->pkey); ++ return EC_KEY_get0_private_key(ecdsa) != NULL; ++ } ++#endif /* OPENSSL_HAS_ECC */ ++#endif /* WITH_OPENSSL */ ++ case KEY_ED25519_CERT: ++ case KEY_ED25519: ++ return (k->ed25519_pk != NULL); ++ default: ++ /* fatal("key_is_private: bad key type %d", k->type); */ ++ return 0; ++ } ++} ++ static void do_ssh2_kex(struct ssh *); /* @@ -2222,7 +2258,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c if (the_active_state != NULL && the_authctxt != NULL) { @@ -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 && mm_is_monitor()) @@ -2231,57 +2267,4 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c + mm_is_monitor()) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif - _exit(i); -diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c ---- openssh-8.6p1/sshkey.c.audit 2021-04-19 16:47:35.741062014 +0200 -+++ openssh-8.6p1/sshkey.c 2021-04-19 16:47:35.759062152 +0200 -@@ -371,6 +371,38 @@ sshkey_type_is_valid_ca(int type) - } - - int -+sshkey_is_private(const struct sshkey *k) -+{ -+ switch (k->type) { -+#ifdef WITH_OPENSSL -+ case KEY_RSA_CERT: -+ case KEY_RSA: { -+ const BIGNUM *d; -+ RSA_get0_key(k->rsa, NULL, NULL, &d); -+ return d != NULL; -+ } -+ case KEY_DSA_CERT: -+ case KEY_DSA: { -+ const BIGNUM *priv_key; -+ DSA_get0_key(k->dsa, NULL, &priv_key); -+ return priv_key != NULL; -+ } -+#ifdef OPENSSL_HAS_ECC -+ case KEY_ECDSA_CERT: -+ case KEY_ECDSA: -+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; -+#endif /* OPENSSL_HAS_ECC */ -+#endif /* WITH_OPENSSL */ -+ case KEY_ED25519_CERT: -+ case KEY_ED25519: -+ return (k->ed25519_pk != NULL); -+ default: -+ /* fatal("key_is_private: bad key type %d", k->type); */ -+ return 0; -+ } -+} -+ -+int - sshkey_is_cert(const struct sshkey *k) - { - if (k == NULL) -diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h ---- openssh-8.6p1/sshkey.h.audit 2021-04-19 16:47:35.741062014 +0200 -+++ openssh-8.6p1/sshkey.h 2021-04-19 16:47:35.759062152 +0200 -@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshke - int sshkey_unshield_private(struct sshkey *); - - int sshkey_type_from_name(const char *); -+int sshkey_is_private(const struct sshkey *); - int sshkey_is_cert(const struct sshkey *); - int sshkey_is_sk(const struct sshkey *); - int sshkey_type_is_cert(int); + /* Override default fatal exit value when auth was attempted */ diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 6a14cb3..5d8da08 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -427,9 +427,9 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c --- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 +++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 @@ -36,6 +36,7 @@ + #include + #include #include - #include - #include +#include #endif @@ -544,13 +544,13 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c - name = _PATH_SSH_CLIENT_ID_ED25519; + name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519; else { - switch (sshkey_type_from_name(key_type_name)) { + switch (sshkey_type_from_shortname(key_type_name)) { #ifdef WITH_DSA @@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); } -+ type = sshkey_type_from_name(key_types[i].key_type); ++ 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)) { @@ -561,7 +561,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c + printf("%s ", key_types[i].key_type_display); fflush(stdout); -- type = sshkey_type_from_name(key_types[i].key_type); +- 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)); @@ -572,31 +572,31 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c - 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_name(key_type_name); + type = sshkey_type_from_shortname(key_type_name); type_bits_valid(type, key_type_name, &bits); diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c --- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 +++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 @@ -33,6 +33,7 @@ + + #include #include - #include - #include +#include #include #include @@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA goto out; - - if (EVP_PKEY_keygen(ctx, &res) <= 0) { + } + 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 -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c ---- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200 -+++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200 +diff -up openssh-9.9p1/kexgen.c.xxx openssh-9.9p1/kexgen.c +--- openssh-9.9p1/kexgen.c.xxx 2024-10-09 10:35:56.285946080 +0200 ++++ openssh-9.9p1/kexgen.c 2024-10-09 10:41:52.792597194 +0200 @@ -31,6 +31,7 @@ #include #include @@ -605,7 +605,7 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c #include "sshkey.h" #include "kex.h" -@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh) +@@ -115,13 +116,28 @@ kex_gen_client(struct ssh *ssh) break; #endif case KEX_C25519_SHA256: @@ -624,11 +624,20 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c + 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; -@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t +@@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t break; #endif case KEX_C25519_SHA256: @@ -649,11 +658,22 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c + } 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; -@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s +@@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t s break; #endif case KEX_C25519_SHA256: @@ -676,6 +696,17 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c + } 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: @@ -713,3 +744,23 @@ diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; +diff -up openssh-9.9p1/kex.c.xxx openssh-9.9p1/kex.c +--- openssh-9.9p1/kex.c.xxx 2024-10-11 12:44:08.087426597 +0200 ++++ openssh-9.9p1/kex.c 2024-10-11 14:00:10.404714521 +0200 +@@ -40,6 +40,7 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include + # ifdef HAVE_EVP_KDF_CTX_NEW + # include + # include +@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh + + /* 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/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index fd1e59d..a666c5c 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -166,8 +166,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x +.Pp 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 + The selected algorithm will be the first algorithm in this list that +@@ -1338,29 +1343,17 @@ Multiple algorithms must be comma-separa .Pp If the specified list begins with a .Sq + @@ -187,7 +187,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x -.Pp -The default is: -.Bd -literal -offset indent --sntrup761x25519-sha512@openssh.com, +-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, +-mlkem768x25519-sha256, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -517,13 +518,14 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The supported algorithms are: .Pp -@@ -1075,16 +1080,6 @@ ecdh-sha2-nistp521 +@@ -1075,17 +1080,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent --sntrup761x25519-sha512@openssh.com, +-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, +-mlkem768x25519-sha256, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 9931d92..bdc4722 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1353,9 +1353,17 @@ diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-c for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c ---- openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh-pkcs11.c 2024-01-12 14:28:09.170975480 +0100 +diff -up openssh-9.9p1/ssh-pkcs11.c.xxx openssh-9.9p1/ssh-pkcs11.c +--- openssh-9.9p1/ssh-pkcs11.c.xxx 2024-10-09 11:56:35.890126144 +0200 ++++ openssh-9.9p1/ssh-pkcs11.c 2024-10-09 11:56:48.528459585 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #define CRYPTOKI_COMPAT + #include "pkcs11.h" @@ -55,8 +55,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1556,7 +1564,7 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,60 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1573,13 +1581,17 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c + + /* sanity - is it a RSA key with associated app_data? */ + switch (key->type) { -+ case KEY_RSA: -+ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ case KEY_RSA: { ++ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); ++ k11 = RSA_get_ex_data(rsa, rsa_idx); + break; ++ } +#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: -+ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ case KEY_ECDSA: { ++ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); ++ k11 = EC_KEY_get_ex_data(ecdsa, ec_key_idx); + break; ++ } +#endif + default: + error("Unknown key type %d", key->type); @@ -1733,9 +1745,9 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c + k11->label[label_attrib->ulValueLen] = 0; + } + - RSA_set_method(rsa, rsa_method); - RSA_set_ex_data(rsa, rsa_idx, k11); - return (0); + if (RSA_set_method(rsa, rsa_method) != 1) + fatal_f("RSA_set_method failed"); + if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) @@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -1766,9 +1778,9 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c + k11->label[label_attrib->ulValueLen] = 0; + } + - EC_KEY_set_method(ec, ec_key_method); - EC_KEY_set_ex_data(ec, ec_key_idx, k11); - + if (EC_KEY_set_method(ec, ec_key_method) != 1) + fatal_f("EC_KEY_set_method failed"); + if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) @@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider } #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1895,7 +1907,7 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c key = sshkey_new(KEY_UNSPEC); @@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - ec = NULL; /* now owned by key */ + key->flags |= SSHKEY_FLAG_EXT; fail: - for (i = 0; i < 3; i++) @@ -1979,7 +1991,7 @@ diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c key = sshkey_new(KEY_UNSPEC); @@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - rsa = NULL; /* now owned by key */ + key->flags |= SSHKEY_FLAG_EXT; fail: - for (i = 0; i < 3; i++) diff --git a/openssh-8.7p1-audit-hostname.patch b/openssh-8.7p1-audit-hostname.patch deleted file mode 100644 index e450c00..0000000 --- a/openssh-8.7p1-audit-hostname.patch +++ /dev/null @@ -1,106 +0,0 @@ -diff --color -ruNp a/audit-linux.c b/audit-linux.c ---- a/audit-linux.c 2024-05-09 12:38:08.843017319 +0200 -+++ b/audit-linux.c 2024-05-09 12:47:05.162267634 +0200 -@@ -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 c - } - 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); - -@@ -181,9 +181,11 @@ audit_run_command(struct ssh *ssh, const - { - if (!user_login_count++) - linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), - "ssh", 1, AUDIT_USER_LOGIN); - linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), - "ssh", 1, AUDIT_USER_START); - return 0; -@@ -193,10 +195,12 @@ void - audit_end_command(struct ssh *ssh, int handle, const char *command) - { - linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ options.use_dns ? remote_hostname(ssh) : NULL, - 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, -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), - "ssh", 1, AUDIT_USER_LOGOUT); - } -@@ -211,19 +215,27 @@ 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); - } - -@@ -236,6 +248,7 @@ audit_event(struct ssh *ssh, ssh_audit_e - linux_audit_user_auth(-1, audit_username(), - ssh_remote_ipaddr(ssh), "ssh", 0, event); - linux_audit_user_logxxx(-1, audit_username(), -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); - break; - case SSH_AUTH_FAIL_PASSWD: -@@ -254,9 +267,11 @@ audit_event(struct ssh *ssh, ssh_audit_e - if (user_login_count) { - while (user_login_count--) - linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), - "ssh", 1, AUDIT_USER_END); - linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), - "ssh", 1, AUDIT_USER_LOGOUT); - } -@@ -265,6 +280,7 @@ audit_event(struct ssh *ssh, ssh_audit_e - case SSH_CONNECTION_ABANDON: - case SSH_INVALID_USER: - linux_audit_user_logxxx(-1, audit_username(), -+ options.use_dns ? remote_hostname(ssh) : NULL, - ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); - break; - default: diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch index abc6aa4..dae0932 100644 --- a/openssh-8.7p1-nohostsha1proof.patch +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -94,47 +94,6 @@ diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c is_proof ? "hostkey proof" : "KEX", siglen); sshbuf_reset(m); -diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh ---- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck 2023-01-25 14:26:52.885963113 +0100 -+++ openssh-8.7p1/regress/cert-userkey.sh 2023-01-25 14:27:25.757219800 +0100 -@@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us - cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak - cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak - --PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` -+#ssh-dss keys are incompatible with DEFAULT crypto policy -+PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` - EXTRA_TYPES="" - rsa="" - -diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile ---- openssh-8.7p1/regress/Makefile.sshrsacheck 2023-01-20 13:07:54.169676051 +0100 -+++ openssh-8.7p1/regress/Makefile 2023-01-20 13:07:54.290677074 +0100 -@@ -2,7 +2,8 @@ - - tests: prep file-tests t-exec unit - --REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 -+#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping -+REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12 - - # File based tests - file-tests: $(REGRESS_TARGETS) -diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh ---- openssh-8.7p1/regress/test-exec.sh.sshrsacheck 2023-01-25 14:24:54.778040819 +0100 -+++ openssh-8.7p1/regress/test-exec.sh 2023-01-25 14:26:39.500858590 +0100 -@@ -581,8 +581,9 @@ maybe_filter_sk() { - fi - } - --SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk` --SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk` -+#ssh-dss keys are incompatible with DEFAULT crypto policy -+SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'` -+SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'` - - for t in ${SSH_KEYTYPES}; do - # generate user key diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c --- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100 +++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100 diff --git a/openssh-9.0p1-audit-log.patch b/openssh-9.0p1-audit-log.patch index fbf5094..ae9550f 100644 --- a/openssh-9.0p1-audit-log.patch +++ b/openssh-9.0p1-audit-log.patch @@ -52,9 +52,27 @@ diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h void audit_key(struct ssh *, int, int *, const struct sshkey *); void audit_unsupported(struct ssh *, int); void audit_kex(struct ssh *, int, char *, char *, char *, char *); -diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c ---- openssh-9.0p1/audit-linux.c.patch 2022-10-24 15:02:16.544858331 +0200 -+++ openssh-9.0p1/audit-linux.c 2022-10-24 15:21:58.165303951 +0200 +diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c +--- openssh-9.9p1/audit-linux.c.xxx 2024-10-15 11:49:48.092151974 +0200 ++++ openssh-9.9p1/audit-linux.c 2024-10-15 12:08:17.179158343 +0200 +@@ -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 c + } + 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: } @@ -117,3 +135,112 @@ diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c out: saved_errno = errno; audit_close(audit_fd); +@@ -179,26 +211,34 @@ audit_connection_from(const char *host, + 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_e + 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_e + 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/openssh-9.0p1-evp-fips-ecdh.patch b/openssh-9.0p1-evp-fips-ecdh.patch deleted file mode 100644 index 0313c6f..0000000 --- a/openssh-9.0p1-evp-fips-ecdh.patch +++ /dev/null @@ -1,207 +0,0 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c ---- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200 -+++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200 -@@ -35,17 +35,57 @@ - #include - - #include -+#include -+#include -+#include -+#include - - #include "sshkey.h" - #include "kex.h" - #include "sshbuf.h" - #include "digest.h" - #include "ssherr.h" -+#include "log.h" - - static int - kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, - const EC_GROUP *, struct sshbuf **); - -+static EC_KEY * -+generate_ec_keys(int ec_nid) -+{ -+ EC_KEY *client_key = NULL; -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ OSSL_PARAM_BLD *param_bld = NULL; -+ OSSL_PARAM *params = NULL; -+ const char *group_name; -+ -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) -+ goto out; -+ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL || -+ OSSL_PARAM_BLD_push_utf8_string(param_bld, -+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 || -+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { -+ error_f("Could not create OSSL_PARAM"); -+ goto out; -+ } -+ if (EVP_PKEY_keygen_init(ctx) != 1 || -+ EVP_PKEY_CTX_set_params(ctx, params) != 1 || -+ EVP_PKEY_generate(ctx, &pkey) != 1 || -+ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) { -+ error_f("Could not generate ec keys"); -+ goto out; -+ } -+out: -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(ctx); -+ OSSL_PARAM_BLD_free(param_bld); -+ OSSL_PARAM_free(params); -+ return client_key; -+} -+ - int - kex_ecdh_keypair(struct kex *kex) - { -@@ -55,11 +95,7 @@ - struct sshbuf *buf = NULL; - int r; - -- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { -- r = SSH_ERR_ALLOC_FAIL; -- goto out; -- } -- if (EC_KEY_generate_key(client_key) != 1) { -+ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -@@ -101,11 +137,7 @@ - *server_blobp = NULL; - *shared_secretp = NULL; - -- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { -- r = SSH_ERR_ALLOC_FAIL; -- goto out; -- } -- if (EC_KEY_generate_key(server_key) != 1) { -+ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -@@ -140,11 +172,21 @@ - { - struct sshbuf *buf = NULL; - BIGNUM *shared_secret = NULL; -- EC_POINT *dh_pub = NULL; -- u_char *kbuf = NULL; -- size_t klen = 0; -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL; -+ OSSL_PARAM_BLD *param_bld = NULL; -+ OSSL_PARAM *params = NULL; -+ u_char *kbuf = NULL, *pub = NULL; -+ size_t klen = 0, publen; -+ const char *group_name; - int r; - -+ /* import EC_KEY to EVP_PKEY */ -+ if ((r = ssh_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) { -+ error_f("Could not create EVP_PKEY"); -+ goto out; -+ } -+ - *shared_secretp = NULL; - - if ((buf = sshbuf_new()) == NULL) { -@@ -153,45 +195,82 @@ - } - if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) - goto out; -- if ((dh_pub = EC_POINT_new(group)) == NULL) { -+ -+ /* the public key is in the buffer in octet string UNCOMPRESSED -+ * format. See sshbuf_put_ec */ -+ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0) -+ goto out; -+ sshbuf_reset(buf); -+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) { -+ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (OSSL_PARAM_BLD_push_octet_string(param_bld, -+ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 || -+ OSSL_PARAM_BLD_push_utf8_string(param_bld, -+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 || -+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { -+ error_f("Failed to set params for dh_pkey"); -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (EVP_PKEY_fromdata_init(ctx) != 1 || -+ EVP_PKEY_fromdata(ctx, &dh_pkey, -+ EVP_PKEY_PUBLIC_KEY, params) != 1 || -+ EVP_PKEY_public_check(ctx) != 1) { -+ error_f("Peer public key import failed"); -+ r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- sshbuf_reset(buf); - - #ifdef DEBUG_KEXECDH - fputs("public key:\n", stderr); -- sshkey_dump_ec_point(group, dh_pub); -+ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL); - #endif -- if (sshkey_ec_validate_public(group, dh_pub) != 0) { -- r = SSH_ERR_MESSAGE_INCOMPLETE; -+ EVP_PKEY_CTX_free(ctx); -+ ctx = NULL; -+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL || -+ EVP_PKEY_derive_init(ctx) != 1 || -+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 || -+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) { -+ error_f("Failed to get derive information"); -+ r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- klen = (EC_GROUP_get_degree(group) + 7) / 8; -- if ((kbuf = malloc(klen)) == NULL || -- (shared_secret = BN_new()) == NULL) { -+ if ((kbuf = malloc(klen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen || -- BN_bin2bn(kbuf, klen, shared_secret) == NULL) { -+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - #ifdef DEBUG_KEXECDH - dump_digest("shared secret", kbuf, klen); - #endif -+ if ((shared_secret = BN_new()) == NULL || -+ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } - if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0) - goto out; - *shared_secretp = buf; - buf = NULL; - out: -- EC_POINT_clear_free(dh_pub); -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_free(dh_pkey); -+ OSSL_PARAM_BLD_free(param_bld); -+ OSSL_PARAM_free(params); - BN_clear_free(shared_secret); - freezero(kbuf, klen); -+ freezero(pub, publen); - sshbuf_free(buf); - return r; - } diff --git a/openssh-9.0p1-evp-fips-dh.patch b/openssh-9.0p1-evp-fips-kex.patch similarity index 50% rename from openssh-9.0p1-evp-fips-dh.patch rename to openssh-9.0p1-evp-fips-kex.patch index 8c70197..36fd1cf 100644 --- a/openssh-9.0p1-evp-fips-dh.patch +++ b/openssh-9.0p1-evp-fips-kex.patch @@ -128,7 +128,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c --- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200 +++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200 -@@ -1623,3 +1623,47 @@ +@@ -1623,3 +1623,142 @@ return r; } @@ -137,6 +137,101 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + * 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) @@ -281,12 +376,220 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ -@@ -283,6 +286,8 @@ +@@ -283,6 +286,9@@ 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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c +--- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200 ++++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200 +@@ -35,17 +35,57 @@ + #include + + #include ++#include ++#include ++#include ++#include + + #include "sshkey.h" + #include "kex.h" + #include "sshbuf.h" + #include "digest.h" + #include "ssherr.h" ++#include "log.h" + + static int + kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, + const EC_GROUP *, struct sshbuf **); + ++static EC_KEY * ++generate_ec_keys(int ec_nid) ++{ ++ EC_KEY *client_key = NULL; ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++ const char *group_name; ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) ++ goto out; ++ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL || ++ OSSL_PARAM_BLD_push_utf8_string(param_bld, ++ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 || ++ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { ++ error_f("Could not create OSSL_PARAM"); ++ goto out; ++ } ++ if (EVP_PKEY_keygen_init(ctx) != 1 || ++ EVP_PKEY_CTX_set_params(ctx, params) != 1 || ++ EVP_PKEY_generate(ctx, &pkey) != 1 || ++ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) { ++ error_f("Could not generate ec keys"); ++ goto out; ++ } ++out: ++ EVP_PKEY_free(pkey); ++ EVP_PKEY_CTX_free(ctx); ++ OSSL_PARAM_BLD_free(param_bld); ++ OSSL_PARAM_free(params); ++ return client_key; ++} ++ + int + kex_ecdh_keypair(struct kex *kex) + { +@@ -55,11 +95,7 @@ + struct sshbuf *buf = NULL; + int r; + +- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { +- r = SSH_ERR_ALLOC_FAIL; +- goto out; +- } +- if (EC_KEY_generate_key(client_key) != 1) { ++ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +@@ -101,11 +137,7 @@ + *server_blobp = NULL; + *shared_secretp = NULL; + +- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { +- r = SSH_ERR_ALLOC_FAIL; +- goto out; +- } +- if (EC_KEY_generate_key(server_key) != 1) { ++ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +@@ -140,11 +172,21 @@ + { + struct sshbuf *buf = NULL; + BIGNUM *shared_secret = NULL; +- EC_POINT *dh_pub = NULL; +- u_char *kbuf = NULL; +- size_t klen = 0; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *pkey = NULL, *dh_pkey = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++ u_char *kbuf = NULL, *pub = NULL; ++ size_t klen = 0, publen; ++ const char *group_name; + int r; + ++ /* import EC_KEY to EVP_PKEY */ ++ if ((r = 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 @@ + } + 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; + } diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch deleted file mode 100644 index 6a30485..0000000 --- a/openssh-9.3p1-merged-openssl-evp.patch +++ /dev/null @@ -1,1237 +0,0 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest.h openssh-9.3p1-patched/digest.h ---- openssh-9.3p1/digest.h 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1-patched/digest.h 2023-06-06 15:52:25.602551466 +0200 -@@ -32,6 +32,12 @@ - struct sshbuf; - struct ssh_digest_ctx; - -+#ifdef WITH_OPENSSL -+#include -+/* 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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest-openssl.c openssh-9.3p1-patched/digest-openssl.c ---- openssh-9.3p1/digest-openssl.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1-patched/digest-openssl.c 2023-06-06 15:52:25.601551454 +0200 -@@ -64,6 +64,22 @@ - { -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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-dss.c openssh-9.3p1-patched/ssh-dss.c ---- openssh-9.3p1/ssh-dss.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1-patched/ssh-dss.c 2023-06-06 15:52:25.624551743 +0200 -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -261,11 +263,15 @@ - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, 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) -@@ -276,17 +282,23 @@ - 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 ((ret = ssh_create_evp_dss(key, &pkey)) != 0) -+ return ret; -+ 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); -@@ -319,7 +331,7 @@ - *lenp = len; - ret = 0; - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - DSA_SIG_free(sig); - sshbuf_free(b); - return ret; -@@ -331,20 +343,20 @@ - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -+ EVP_PKEY *pkey = NULL; - DSA_SIG *dsig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; -- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; -- size_t len, hlen = 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; -- if (hlen == 0) -- return SSH_ERR_INTERNAL_ERROR; - - /* fetch signature */ - if ((b = sshbuf_from(sig, siglen)) == NULL) -@@ -386,25 +398,28 @@ - } - sig_r = sig_s = NULL; /* transferred */ - -- /* sha1 the data */ -- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, -- digest, sizeof(digest))) != 0) -+ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; -- -- switch (DSA_do_verify(digest, hlen, dsig, 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(dsig, &psig)) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - -+ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) -+ goto out; -+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, -+ sigb, slen); -+ EVP_PKEY_free(pkey); -+ - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - DSA_SIG_free(dsig); - BN_clear_free(sig_r); - BN_clear_free(sig_s); -@@ -415,6 +430,65 @@ - return ret; - } - -+int -+ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) -+{ -+ OSSL_PARAM_BLD *param_bld = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; -+ int ret = 0; -+ -+ if (k == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ DSA_get0_pqg(k->dsa, &p, &q, &g); -+ DSA_get0_key(k->dsa, &pub, &priv); -+ -+ if (p != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (q != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (g != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (pub != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, -+ OSSL_PKEY_PARAM_PUB_KEY, -+ pub) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (priv != 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); -+ return ret; -+} -+ - static const struct sshkey_impl_funcs sshkey_dss_funcs = { - /* .size = */ ssh_dss_size, - /* .alloc = */ ssh_dss_alloc, -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-ecdsa.c openssh-9.3p1-patched/ssh-ecdsa.c ---- openssh-9.3p1/ssh-ecdsa.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1-patched/ssh-ecdsa.c 2023-06-06 15:52:25.626551768 +0200 -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -44,6 +44,9 @@ - #include "digest.h" - #define SSHKEY_INTERNAL - #include "sshkey.h" -+#ifdef ENABLE_PKCS11 -+#include "ssh-pkcs11.h" -+#endif - - #include "openbsd-compat/openssl-compat.h" - -@@ -126,19 +128,29 @@ - static int - ssh_ecdsa_generate(struct sshkey *k, int bits) - { -- EC_KEY *private; -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *res = NULL; - - if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) - return SSH_ERR_KEY_LENGTH; -- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) -+ -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if (EC_KEY_generate_key(private) != 1) { -- EC_KEY_free(private); -+ -+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0 -+ || EVP_PKEY_keygen(ctx, &res) <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); - return SSH_ERR_LIBCRYPTO_ERROR; - } -- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); -- k->ecdsa = private; -- return 0; -+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ k->ecdsa = EVP_PKEY_get1_EC_KEY(res); -+ if (k->ecdsa) -+ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE); -+ -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); -+ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR; - } - - static int -@@ -228,11 +240,13 @@ - const u_char *data, size_t dlen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) - { -+ EVP_PKEY *pkey = NULL; - ECDSA_SIG *esig = 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, hlen; -+ int len; - struct sshbuf *b = NULL, *bb = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; - -@@ -245,18 +259,33 @@ - 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 || -- (hlen = 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, dlen, -- digest, sizeof(digest))) != 0) -+ -+#ifdef ENABLE_PKCS11 -+ if (is_ecdsa_pkcs11(key->ecdsa)) { -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) -+ return SSH_ERR_ALLOC_FAIL; -+ } else { -+#endif -+ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) -+ return ret; -+#ifdef ENABLE_PKCS11 -+ } -+#endif -+ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, -+ dlen); -+ EVP_PKEY_free(pkey); -+ if (ret < 0) { - goto out; -+ } - -- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { -+ psig = sigb; -+ if (d2i_ECDSA_SIG(&esig, &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; -@@ -280,7 +309,7 @@ - *lenp = len; - ret = 0; - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - sshbuf_free(b); - sshbuf_free(bb); - ECDSA_SIG_free(esig); -@@ -293,22 +322,21 @@ - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -+ EVP_PKEY *pkey = NULL; - ECDSA_SIG *esig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; -- int hash_alg; -- u_char digest[SSH_DIGEST_MAX_LENGTH]; -- size_t hlen; -+ 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - -- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || -- (hlen = 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 */ -@@ -344,28 +372,33 @@ - } - 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(esig, NULL)) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- if ((ret = ssh_digest_memory(hash_alg, data, dlen, -- digest, sizeof(digest))) != 0) -- goto out; -- -- switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) { -- case 1: -- ret = 0; -- break; -- case 0: -- ret = SSH_ERR_SIGNATURE_INVALID; -+ if ((sigb = malloc(len)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; - goto out; -- default: -+ } -+ psig = sigb; -+ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - -+ if (sshbuf_len(sigbuf) != 0) { -+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; -+ goto out; -+ } -+ -+ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) -+ goto out; -+ ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len); -+ EVP_PKEY_free(pkey); -+ - out: -- explicit_bzero(digest, sizeof(digest)); -+ free(sigb); - sshbuf_free(sigbuf); - sshbuf_free(b); - ECDSA_SIG_free(esig); -@@ -375,6 +408,79 @@ - return ret; - } - -+int -+ssh_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; -+} -+ - /* NB. not static; used by ECDSA-SK */ - const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { - /* .size = */ ssh_ecdsa_size, -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.c openssh-9.3p1-patched/sshkey.c ---- openssh-9.3p1/sshkey.c 2023-06-06 15:53:36.608444190 +0200 -+++ openssh-9.3p1-patched/sshkey.c 2023-06-06 15:52:25.625551756 +0200 -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - #endif - - #include "crypto_api.h" -@@ -575,6 +577,86 @@ - } - - #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; -+ size_t len; -+ -+ if (sigp == NULL || lenp == NULL) { -+ return SSH_ERR_INVALID_ARGUMENT; -+ } -+ -+ slen = EVP_PKEY_get_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_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg), -+ NULL, pkey) != 1 || -+ EVP_DigestSignUpdate(ctx, data, datalen) != 1 || -+ EVP_DigestSignFinal(ctx, sig, &len) != 1) { -+ 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_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg), -+ NULL, pkey) != 1 || -+ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto done; -+ } -+ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen); -+ 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) -@@ -3763,3 +3845,27 @@ - return 0; - } - #endif /* WITH_XMSS */ -+ -+#ifdef WITH_OPENSSL -+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; -+} -+#endif /* WITH_OPENSSL */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.h openssh-9.3p1-patched/sshkey.h ---- openssh-9.3p1/sshkey.h 2023-06-06 15:53:36.608444190 +0200 -+++ openssh-9.3p1-patched/sshkey.h 2023-06-06 15:52:25.626551768 +0200 -@@ -31,6 +31,9 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include -+#include -+#include - # ifdef OPENSSL_HAS_ECC - # include - # include -@@ -266,6 +266,10 @@ - const char *sshkey_ssh_name_plain(const struct sshkey *); - int sshkey_names_valid2(const char *, int, 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 **); -@@ -324,6 +331,13 @@ - - void sshkey_sig_details_free(struct sshkey_sig_details *); - -+#ifdef WITH_OPENSSL -+EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *); -+int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **); -+int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **); -+int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **); -+#endif /* WITH_OPENSSL */ -+ - #ifdef SSHKEY_INTERNAL - int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); - void sshkey_sk_cleanup(struct sshkey *k); -@@ -338,6 +352,10 @@ - #endif - #endif - -+#ifdef ENABLE_PKCS11 -+int pkcs11_get_ecdsa_idx(void); -+#endif -+ - #if !defined(WITH_OPENSSL) - # undef RSA - # undef DSA -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c ---- a/ssh-pkcs11.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/ssh-pkcs11.c (date 1703110934679) -@@ -620,8 +620,24 @@ - - return (0); - } -+ -+int -+is_ecdsa_pkcs11(EC_KEY *ecdsa) -+{ -+ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL) -+ return 1; -+ return 0; -+} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -+int -+is_rsa_pkcs11(RSA *rsa) -+{ -+ if (RSA_get_ex_data(rsa, rsa_idx) != NULL) -+ return 1; -+ return 0; -+} -+ - /* remove trailing spaces. Note, that this does NOT guarantee the buffer - * will be null terminated if there are no trailing spaces! */ - static char * -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c ---- a/ssh-pkcs11-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/ssh-pkcs11-client.c (date 1703110830967) -@@ -402,8 +402,36 @@ - if (helper->nrsa == 0 && helper->nec == 0) - helper_terminate(helper); - } -+ -+int -+is_ecdsa_pkcs11(EC_KEY *ecdsa) -+{ -+ const EC_KEY_METHOD *meth; -+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen, -+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL; -+ -+ meth = EC_KEY_get_method(ecdsa); -+ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig); -+ if (sign_sig == ecdsa_do_sign) -+ return 1; -+ return 0; -+} - #endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ - -+int -+is_rsa_pkcs11(RSA *rsa) -+{ -+ const RSA_METHOD *meth; -+ int (*priv_enc)(int flen, const unsigned char *from, -+ unsigned char *to, RSA *rsa, int padding) = NULL; -+ -+ meth = RSA_get_method(rsa); -+ priv_enc = RSA_meth_get_priv_enc(meth); -+ if (priv_enc == rsa_encrypt) -+ return 1; -+ return 0; -+} -+ - /* redirect private key crypto operations to the ssh-pkcs11-helper */ - static void - wrap_key(struct helper *helper, struct sshkey *k) -diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h ---- a/ssh-pkcs11.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/ssh-pkcs11.h (date 1703111023334) -@@ -38,6 +38,12 @@ - /* Only available in ssh-pkcs11-client.c so far */ - int pkcs11_make_cert(const struct sshkey *, - const struct sshkey *, struct sshkey **); -+ -+#ifdef HAVE_EC_KEY_METHOD_NEW -+int is_ecdsa_pkcs11(EC_KEY *ecdsa); -+#endif -+int is_rsa_pkcs11(RSA *rsa); -+ - #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) - #undef ENABLE_PKCS11 - #endif -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-rsa.c openssh-9.3p1-patched/ssh-rsa.c ---- openssh-9.3p1/ssh-rsa.c 2023-03-15 22:28:19.000000000 +0100 -+++ openssh-9.3p1-patched/ssh-rsa.c 2023-06-06 15:52:25.627551781 +0200 -@@ -23,6 +23,8 @@ - - #include - #include -+#include -+#include - - #include - #include -@@ -36,10 +36,13 @@ - #include "sshkey.h" - #include "digest.h" - #include "log.h" -+#ifdef ENABLE_PKCS11 -+#include "ssh-pkcs11.h" -+#endif - - #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 u_int - ssh_rsa_size(const struct sshkey *key) -@@ -131,27 +133,50 @@ - static int - ssh_rsa_generate(struct sshkey *k, int bits) - { -- RSA *private = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *res = NULL; - BIGNUM *f4 = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; - - if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || - bits > SSHBUF_MAX_BIGNUM * 8) - return SSH_ERR_KEY_LENGTH; -- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { -+ -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL -+ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (!BN_set_word(f4, RSA_F4) || -- !RSA_generate_key_ex(private, bits, f4, NULL)) { -+ -+ if (EVP_PKEY_keygen_init(ctx) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { -+ ret = SSH_ERR_KEY_LENGTH; -+ goto out; -+ } -+ -+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0) -+ goto out; -+ -+ if (EVP_PKEY_keygen(ctx, &res) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ -+ k->rsa = EVP_PKEY_get1_RSA(res); -+ if (k->rsa) { -+ ret = 0; -+ } else { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- k->rsa = private; -- private = NULL; -- ret = 0; - out: -- RSA_free(private); -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(res); - BN_free(f4); - return ret; - } -@@ -317,21 +342,6 @@ - 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) - { -@@ -393,11 +403,10 @@ - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) - { -- const BIGNUM *rsa_n; -- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; -- size_t slen = 0; -- u_int hlen, 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) -@@ -409,33 +418,33 @@ - hash_alg = SSH_DIGEST_SHA1; - else - hash_alg = rsa_hash_id_from_keyname(alg); -+ - 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 ((hlen = 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; -- goto out; -+#ifdef ENABLE_PKCS11 -+ if (is_rsa_pkcs11(key->rsa)) { -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) -+ return SSH_ERR_ALLOC_FAIL; -+ } else { -+#endif -+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) -+ return ret; -+#ifdef ENABLE_PKCS11 - } -- -- if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { -- ret = SSH_ERR_LIBCRYPTO_ERROR; -+#endif -+ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, -+ datalen); -+ EVP_PKEY_free(pkey); -+ if (ret < 0) { - goto out; - } -+ - if (len < slen) { - size_t diff = slen - len; - memmove(sig + diff, sig, len); -@@ -444,6 +453,7 @@ - ret = SSH_ERR_INTERNAL_ERROR; - goto out; - } -+ - /* encode signature */ - if ((b = sshbuf_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; -@@ -464,7 +474,6 @@ - *lenp = len; - ret = 0; - out: -- explicit_bzero(digest, sizeof(digest)); - freezero(sig, slen); - sshbuf_free(b); - return ret; -@@ -476,10 +485,10 @@ - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) - { -- 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, hlen; -+ size_t len = 0, diff, modlen; - struct sshbuf *b = NULL; - u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; - -@@ -487,8 +496,7 @@ - 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) -@@ -540,16 +548,13 @@ - explicit_bzero(sigblob, diff); - len = modlen; - } -- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { -- ret = SSH_ERR_INTERNAL_ERROR; -- goto out; -- } -- if ((ret = ssh_digest_memory(hash_alg, data, dlen, -- digest, sizeof(digest))) != 0) -+ -+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) - goto out; - -- ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, -- key->rsa); -+ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); -+ EVP_PKEY_free(pkey); -+ - out: - freezero(sigblob, len); - free(sigtype); -@@ -558,125 +563,110 @@ - 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; -+ 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; -- } -- rsasize = RSA_size(rsa); -+ rsasize = EVP_PKEY_get_size(pkey); - 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; - } - -+int -+ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) -+{ -+ OSSL_PARAM_BLD *param_bld = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ int ret = 0; -+ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL; -+ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; -+ -+ if (k == NULL) -+ return SSH_ERR_INVALID_ARGUMENT; -+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL || -+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ RSA_get0_key(k->rsa, &n, &e, &d); -+ RSA_get0_factors(k->rsa, &p, &q); -+ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); -+ -+ if (n != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (e != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (d != NULL && -+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+ /* setting this to param_build makes the creation process fail */ -+ if (p != NULL && -+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) { -+ debug2_f("failed to add 'p' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (q != NULL && -+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) { -+ debug2_f("failed to add 'q' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (dmp1 != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) { -+ debug2_f("failed to add 'dmp1' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (dmq1 != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) { -+ debug2_f("failed to add 'dmq1' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ if (iqmp != NULL && -+ EVP_PKEY_set_bn_param(*pkey, -+ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) { -+ debug2_f("failed to add 'iqmp' param"); -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ -+out: -+ OSSL_PARAM_BLD_free(param_bld); -+ EVP_PKEY_CTX_free(ctx); -+ return ret; -+} -+ - static const struct sshkey_impl_funcs sshkey_rsa_funcs = { - /* .size = */ ssh_rsa_size, - /* .alloc = */ ssh_rsa_alloc, diff --git a/openssh-9.6p1-gssapi-keyex.patch b/openssh-9.6p1-gssapi-keyex.patch index e63b258..ef1f97e 100644 --- a/openssh-9.6p1-gssapi-keyex.patch +++ b/openssh-9.6p1-gssapi-keyex.patch @@ -1240,8 +1240,8 @@ diff --color -ruNp a/kexgen.c b/kexgen.c const struct sshbuf *client_version, diff --color -ruNp a/kexgssc.c b/kexgssc.c --- a/kexgssc.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgssc.c 2024-09-16 11:46:34.709940203 +0200 -@@ -0,0 +1,704 @@ ++++ b/kexgssc.c 2024-10-14 15:18:02.491798105 +0200 +@@ -0,0 +1,706 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1603,6 +1603,7 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c + if (gss->major & GSS_S_CONTINUE_NEEDED) + return kexgss_init_ctx(ssh, &recv_tok); + ++ gss_release_buffer(&gss->minor, &recv_tok); + return kexgss_final(ssh); +} + @@ -1942,14 +1943,15 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c + if (gss->major & GSS_S_CONTINUE_NEEDED) + return kexgssgex_init_ctx(ssh, &recv_tok); + ++ gss_release_buffer(&gss->minor, &recv_tok); + return kexgssgex_final(ssh); +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --color -ruNp a/kexgsss.c b/kexgsss.c --- a/kexgsss.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgsss.c 2024-09-16 11:46:34.710940224 +0200 -@@ -0,0 +1,590 @@ ++++ b/kexgsss.c 2024-10-14 15:18:02.491798105 +0200 +@@ -0,0 +1,601 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2082,6 +2084,9 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + struct kex *kex = ssh->kex; + Gssctxt *gss = kex->gss; + gss_buffer_desc msg_tok; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t hashlen; ++ struct sshbuf *shared_secret = NULL; + int r; + + ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_INIT, NULL); @@ -2125,12 +2130,18 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + gss_release_buffer(&gss->minor, send_tok); + gss_release_buffer(&gss->minor, &msg_tok); + ++ hashlen = gss->hashlen; ++ memcpy(hash, gss->hash, hashlen); ++ explicit_bzero(gss->hash, sizeof(gss->hash)); ++ shared_secret = gss->shared_secret; ++ gss->shared_secret = NULL; ++ + if (gss_kex_context == NULL) + gss_kex_context = gss; + else + ssh_gssapi_delete_ctx(&kex->gss); + -+ if ((r = kex_derive_keys(ssh, gss->hash, gss->hashlen, gss->shared_secret)) == 0) ++ if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + + /* If this was a rekey, then save out any delegated credentials we @@ -2139,12 +2150,11 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + ssh_gssapi_rekey_creds(); + + if (kex->gss != NULL) { -+ explicit_bzero(gss->hash, sizeof(gss->hash)); -+ sshbuf_free(gss->shared_secret); -+ gss->shared_secret = NULL; + sshbuf_free(gss->server_pubkey); + gss->server_pubkey = NULL; + } ++ explicit_bzero(hash, sizeof(hash)); ++ sshbuf_free(shared_secret); + return r; +} + @@ -2187,7 +2197,8 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + } + if (r != 0) { + sshbuf_free(client_pubkey); -+ ssh_gssapi_delete_ctx(&kex->gss); ++ gss_release_buffer(&gss->minor, &recv_tok); ++ ssh_gssapi_delete_ctx(&kex->gss); + return r; + } + @@ -2195,6 +2206,7 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + + if ((empty = sshbuf_new()) == NULL) { + sshbuf_free(client_pubkey); ++ gss_release_buffer(&gss->minor, &recv_tok); + ssh_gssapi_delete_ctx(&kex->gss); + return SSH_ERR_ALLOC_FAIL; + } @@ -2210,6 +2222,7 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c + sshbuf_free(empty); + sshbuf_free(client_pubkey); + if (r != 0) { ++ gss_release_buffer(&gss->minor, &recv_tok); + ssh_gssapi_delete_ctx(&kex->gss); + return r; + } @@ -2555,9 +2568,9 @@ diff --color -ruNp a/kex.h b/kex.h # include # include @@ -102,6 +106,15 @@ enum kex_exchange { - KEX_ECDH_SHA2, KEX_C25519_SHA256, KEX_KEM_SNTRUP761X25519_SHA512, + KEX_KEM_MLKEM768X25519_SHA256, +#ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, @@ -2730,7 +2743,7 @@ diff --color -ruNp a/Makefile.in b/Makefile.in @@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ - kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o @@ -3609,7 +3622,7 @@ diff --color -ruNp a/sshconnect2.c b/sshconnect2.c free(hkalgs); /* start key exchange */ -@@ -271,14 +312,44 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -271,15 +312,45 @@ ssh_kex2(struct ssh *ssh, char *host, st # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; # endif @@ -3628,6 +3641,7 @@ diff --color -ruNp a/sshconnect2.c b/sshconnect2.c +#endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3949,7 +3963,7 @@ diff --color -ruNp a/sshd-session.c b/sshd-session.c +#endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->load_host_public_key=&get_hostkey_public_by_type; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; diff --color -ruNp a/ssh-gss.h b/ssh-gss.h --- a/ssh-gss.h 2024-07-01 06:36:28.000000000 +0200 +++ b/ssh-gss.h 2024-09-16 11:46:34.710940224 +0200 diff --git a/openssh-9.8p1-gsissh.patch b/openssh-9.9p1-gsissh.patch similarity index 89% rename from openssh-9.8p1-gsissh.patch rename to openssh-9.9p1-gsissh.patch index ecb2c4e..7f60393 100644 --- a/openssh-9.8p1-gsissh.patch +++ b/openssh-9.9p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c ---- openssh-9.8p1.orig/auth2.c 2024-09-30 11:38:28.487321398 +0200 -+++ openssh-9.8p1/auth2.c 2024-10-01 08:11:48.131268544 +0200 +diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c +--- openssh-9.9p1.orig/auth2.c 2025-01-20 19:52:47.907052307 +0100 ++++ openssh-9.9p1/auth2.c 2025-01-20 20:23:17.232729940 +0100 @@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -101,9 +101,9 @@ diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-9.8p1.orig/auth2-gss.c openssh-9.8p1/auth2-gss.c ---- openssh-9.8p1.orig/auth2-gss.c 2024-09-30 11:38:28.368321057 +0200 -+++ openssh-9.8p1/auth2-gss.c 2024-10-01 13:47:06.876811637 +0200 +diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c +--- openssh-9.9p1.orig/auth2-gss.c 2025-01-20 19:52:47.769051955 +0100 ++++ openssh-9.9p1/auth2-gss.c 2025-01-20 20:23:17.233729943 +0100 @@ -54,6 +54,7 @@ extern struct authmethod_cfg methodcfg_gsskeyex; extern struct authmethod_cfg methodcfg_gssapi; @@ -303,9 +303,9 @@ diff -Nur openssh-9.8p1.orig/auth2-gss.c openssh-9.8p1/auth2-gss.c Authmethod method_gsskeyex = { &methodcfg_gsskeyex, userauth_gsskeyex, -diff -Nur openssh-9.8p1.orig/auth.c openssh-9.8p1/auth.c ---- openssh-9.8p1.orig/auth.c 2024-09-30 11:38:28.488321400 +0200 -+++ openssh-9.8p1/auth.c 2024-09-30 11:39:17.561461794 +0200 +diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c +--- openssh-9.9p1.orig/auth.c 2025-01-20 19:52:47.908052310 +0100 ++++ openssh-9.9p1/auth.c 2025-01-20 20:23:17.233729943 +0100 @@ -298,7 +298,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -316,7 +316,7 @@ diff -Nur openssh-9.8p1.orig/auth.c openssh-9.8p1/auth.c ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), extra != NULL ? ": " : "", -@@ -486,13 +487,18 @@ +@@ -490,13 +491,18 @@ #endif pw = getpwnam(user); @@ -336,9 +336,9 @@ diff -Nur openssh-9.8p1.orig/auth.c openssh-9.8p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-9.8p1.orig/auth.h openssh-9.8p1/auth.h ---- openssh-9.8p1.orig/auth.h 2024-09-30 11:38:28.489321403 +0200 -+++ openssh-9.8p1/auth.h 2024-09-30 11:39:17.561461794 +0200 +diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h +--- openssh-9.9p1.orig/auth.h 2025-01-20 19:52:47.909052313 +0100 ++++ openssh-9.9p1/auth.h 2025-01-20 20:23:17.234729946 +0100 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -348,9 +348,9 @@ diff -Nur openssh-9.8p1.orig/auth.h openssh-9.8p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-9.8p1.orig/auth-pam.c openssh-9.8p1/auth-pam.c ---- openssh-9.8p1.orig/auth-pam.c 2024-09-30 11:38:28.533321529 +0200 -+++ openssh-9.8p1/auth-pam.c 2024-09-30 11:39:17.562461797 +0200 +diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c +--- openssh-9.9p1.orig/auth-pam.c 2025-01-20 19:52:47.954052427 +0100 ++++ openssh-9.9p1/auth-pam.c 2025-01-20 20:23:17.264730023 +0100 @@ -248,6 +248,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; @@ -511,9 +511,9 @@ diff -Nur openssh-9.8p1.orig/auth-pam.c openssh-9.8p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-9.8p1.orig/auth-pam.h openssh-9.8p1/auth-pam.h ---- openssh-9.8p1.orig/auth-pam.h 2024-09-30 11:38:28.333320957 +0200 -+++ openssh-9.8p1/auth-pam.h 2024-09-30 11:39:17.563461800 +0200 +diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h +--- openssh-9.9p1.orig/auth-pam.h 2025-01-20 19:52:47.713051809 +0100 ++++ openssh-9.9p1/auth-pam.h 2025-01-20 20:23:17.264730023 +0100 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -521,9 +521,9 @@ diff -Nur openssh-9.8p1.orig/auth-pam.h openssh-9.8p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-9.8p1.orig/canohost.c openssh-9.8p1/canohost.c ---- openssh-9.8p1.orig/canohost.c 2024-09-30 11:38:28.368321057 +0200 -+++ openssh-9.8p1/canohost.c 2024-09-30 11:39:17.564461803 +0200 +diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c +--- openssh-9.9p1.orig/canohost.c 2025-01-20 19:52:47.770051957 +0100 ++++ openssh-9.9p1/canohost.c 2025-01-20 20:23:17.265730026 +0100 @@ -17,6 +17,7 @@ #include #include @@ -566,9 +566,9 @@ diff -Nur openssh-9.8p1.orig/canohost.c openssh-9.8p1/canohost.c + } + } +} -diff -Nur openssh-9.8p1.orig/canohost.h openssh-9.8p1/canohost.h ---- openssh-9.8p1.orig/canohost.h 2024-09-30 11:38:28.369321060 +0200 -+++ openssh-9.8p1/canohost.h 2024-09-30 11:39:17.564461803 +0200 +diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h +--- openssh-9.9p1.orig/canohost.h 2025-01-20 19:52:47.770051957 +0100 ++++ openssh-9.9p1/canohost.h 2025-01-20 20:23:17.265730026 +0100 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -576,10 +576,10 @@ diff -Nur openssh-9.8p1.orig/canohost.h openssh-9.8p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac ---- openssh-9.8p1.orig/configure.ac 2024-09-30 11:38:28.463321329 +0200 -+++ openssh-9.8p1/configure.ac 2024-09-30 11:39:17.565461806 +0200 -@@ -4909,6 +4909,14 @@ +diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac +--- openssh-9.9p1.orig/configure.ac 2025-01-20 19:52:47.872052217 +0100 ++++ openssh-9.9p1/configure.ac 2025-01-20 20:23:17.266730028 +0100 +@@ -4920,6 +4920,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -594,7 +594,7 @@ diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4950,6 +4958,40 @@ +@@ -4961,6 +4969,40 @@ AC_SUBST([K5LIBS]) AC_SUBST([CHANNELLIBS]) @@ -635,9 +635,9 @@ diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-9.8p1.orig/gss-genr.c openssh-9.8p1/gss-genr.c ---- openssh-9.8p1.orig/gss-genr.c 2024-09-30 11:38:28.535321535 +0200 -+++ openssh-9.8p1/gss-genr.c 2024-09-30 11:39:17.566461808 +0200 +diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c +--- openssh-9.9p1.orig/gss-genr.c 2025-01-20 19:52:47.962052448 +0100 ++++ openssh-9.9p1/gss-genr.c 2025-01-20 20:23:17.267730031 +0100 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -674,9 +674,9 @@ diff -Nur openssh-9.8p1.orig/gss-genr.c openssh-9.8p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-9.8p1.orig/gss-serv.c openssh-9.8p1/gss-serv.c ---- openssh-9.8p1.orig/gss-serv.c 2024-09-30 11:38:28.389321117 +0200 -+++ openssh-9.8p1/gss-serv.c 2024-09-30 11:39:17.567461811 +0200 +diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c +--- openssh-9.9p1.orig/gss-serv.c 2025-01-20 19:52:47.802052038 +0100 ++++ openssh-9.9p1/gss-serv.c 2025-01-20 20:23:17.268730033 +0100 @@ -50,10 +50,12 @@ #include "monitor_wrap.h" @@ -957,9 +957,9 @@ diff -Nur openssh-9.8p1.orig/gss-serv.c openssh-9.8p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-9.8p1.orig/gss-serv-gsi.c openssh-9.8p1/gss-serv-gsi.c ---- openssh-9.8p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/gss-serv-gsi.c 2024-09-30 11:39:17.567461811 +0200 +diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c +--- openssh-9.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/gss-serv-gsi.c 2025-01-20 20:23:17.268730033 +0100 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1289,9 +1289,9 @@ diff -Nur openssh-9.8p1.orig/gss-serv-gsi.c openssh-9.8p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-9.8p1.orig/gss-serv-krb5.c openssh-9.8p1/gss-serv-krb5.c ---- openssh-9.8p1.orig/gss-serv-krb5.c 2024-09-30 11:38:28.418321200 +0200 -+++ openssh-9.8p1/gss-serv-krb5.c 2024-09-30 11:39:17.568461814 +0200 +diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c +--- openssh-9.9p1.orig/gss-serv-krb5.c 2025-01-20 19:52:47.824052094 +0100 ++++ openssh-9.9p1/gss-serv-krb5.c 2025-01-20 20:23:17.269730036 +0100 @@ -379,6 +379,34 @@ return found_principal; } @@ -1345,9 +1345,9 @@ diff -Nur openssh-9.8p1.orig/gss-serv-krb5.c openssh-9.8p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-9.8p1.orig/kexgsss.c openssh-9.8p1/kexgsss.c ---- openssh-9.8p1.orig/kexgsss.c 2024-09-30 11:38:28.399321146 +0200 -+++ openssh-9.8p1/kexgsss.c 2024-09-30 15:10:29.856045413 +0200 +diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c +--- openssh-9.9p1.orig/kexgsss.c 2025-01-20 19:52:47.785051995 +0100 ++++ openssh-9.9p1/kexgsss.c 2025-01-21 07:14:03.079570547 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1368,16 +1368,7 @@ diff -Nur openssh-9.8p1.orig/kexgsss.c openssh-9.8p1/kexgsss.c ssh_gssapi_build_ctx(&kex->gss); if (kex->gss == NULL) -@@ -127,7 +130,7 @@ - gss_buffer_desc *send_tok, - OM_uint32 *ret_flags) - { -- struct kex *kex = ssh->kex; -+struct kex *kex = ssh->kex; - Gssctxt *gss = kex->gss; - gss_buffer_desc msg_tok; - int r; -@@ -136,13 +139,14 @@ +@@ -139,13 +142,14 @@ ssh_dispatch_set(ssh, SSH2_MSG_KEXGSS_CONTINUE, NULL); if (GSS_ERROR(gss->major)) { @@ -1393,7 +1384,7 @@ diff -Nur openssh-9.8p1.orig/kexgsss.c openssh-9.8p1/kexgsss.c } if (!(*ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -587,4 +591,26 @@ +@@ -598,4 +602,26 @@ return kexgssgex_final(ssh, &send_tok, &ret_flags); } @@ -1420,9 +1411,9 @@ diff -Nur openssh-9.8p1.orig/kexgsss.c openssh-9.8p1/kexgsss.c +} + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in ---- openssh-9.8p1.orig/Makefile.in 2024-09-30 11:38:28.491321409 +0200 -+++ openssh-9.8p1/Makefile.in 2024-09-30 11:43:22.688163055 +0200 +diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in +--- openssh-9.9p1.orig/Makefile.in 2025-01-20 19:52:47.911052318 +0100 ++++ openssh-9.9p1/Makefile.in 2025-01-20 20:23:17.270730038 +0100 @@ -138,6 +138,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ @@ -1431,9 +1422,9 @@ diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c ---- openssh-9.8p1.orig/misc.c 2024-09-30 11:38:28.537321541 +0200 -+++ openssh-9.8p1/misc.c 2024-09-30 11:39:17.570461820 +0200 +diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c +--- openssh-9.9p1.orig/misc.c 2025-01-20 19:52:47.963052451 +0100 ++++ openssh-9.9p1/misc.c 2025-01-20 20:23:17.271730041 +0100 @@ -419,11 +419,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1493,9 +1484,9 @@ diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h ---- openssh-9.8p1.orig/misc.h 2024-09-30 11:38:28.435321249 +0200 -+++ openssh-9.8p1/misc.h 2024-09-30 11:39:17.570461820 +0200 +diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h +--- openssh-9.9p1.orig/misc.h 2025-01-20 19:52:47.840052135 +0100 ++++ openssh-9.9p1/misc.h 2025-01-20 20:23:17.272730043 +0100 @@ -111,6 +111,7 @@ void sock_set_v6only(int); @@ -1504,10 +1495,10 @@ diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c ---- openssh-9.8p1.orig/monitor.c 2024-09-30 11:38:28.537321541 +0200 -+++ openssh-9.8p1/monitor.c 2024-09-30 11:39:17.571461823 +0200 -@@ -147,6 +147,9 @@ +diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c +--- openssh-9.9p1.orig/monitor.c 2025-01-20 19:52:47.964052453 +0100 ++++ openssh-9.9p1/monitor.c 2025-01-20 20:23:17.273730046 +0100 +@@ -148,6 +148,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1517,7 +1508,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -200,7 +203,7 @@ +@@ -201,7 +204,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1526,7 +1517,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -208,7 +211,7 @@ +@@ -209,7 +212,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1535,7 +1526,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -232,8 +235,11 @@ +@@ -233,8 +236,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1548,7 +1539,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c #endif {0, 0, NULL} }; -@@ -243,6 +249,8 @@ +@@ -244,6 +250,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1557,7 +1548,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif #ifdef WITH_OPENSSL -@@ -323,6 +331,8 @@ +@@ -324,6 +332,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1566,7 +1557,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -457,6 +467,8 @@ +@@ -458,6 +468,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1575,7 +1566,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -811,14 +823,17 @@ +@@ -812,14 +824,17 @@ debug3_f("entering"); @@ -1596,7 +1587,7 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2159,6 +2174,79 @@ +@@ -2170,6 +2185,79 @@ } int @@ -1676,9 +1667,9 @@ diff -Nur openssh-9.8p1.orig/monitor.c openssh-9.8p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-9.8p1.orig/monitor.h openssh-9.8p1/monitor.h ---- openssh-9.8p1.orig/monitor.h 2024-09-30 11:38:28.492321412 +0200 -+++ openssh-9.8p1/monitor.h 2024-09-30 11:39:17.571461823 +0200 +diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h +--- openssh-9.9p1.orig/monitor.h 2025-01-20 19:52:47.912052320 +0100 ++++ openssh-9.9p1/monitor.h 2025-01-20 20:23:17.273730046 +0100 @@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, @@ -1690,9 +1681,9 @@ diff -Nur openssh-9.8p1.orig/monitor.h openssh-9.8p1/monitor.h }; struct ssh; -diff -Nur openssh-9.8p1.orig/monitor_wrap.c openssh-9.8p1/monitor_wrap.c ---- openssh-9.8p1.orig/monitor_wrap.c 2024-09-30 11:38:28.499321432 +0200 -+++ openssh-9.8p1/monitor_wrap.c 2024-09-30 11:39:17.572461826 +0200 +diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c +--- openssh-9.9p1.orig/monitor_wrap.c 2025-01-20 19:52:47.918052335 +0100 ++++ openssh-9.9p1/monitor_wrap.c 2025-01-20 20:23:17.274730049 +0100 @@ -1139,6 +1139,94 @@ return (authenticated); } @@ -1788,9 +1779,9 @@ diff -Nur openssh-9.8p1.orig/monitor_wrap.c openssh-9.8p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-9.8p1.orig/monitor_wrap.h openssh-9.8p1/monitor_wrap.h ---- openssh-9.8p1.orig/monitor_wrap.h 2024-09-30 11:38:28.499321432 +0200 -+++ openssh-9.8p1/monitor_wrap.h 2024-09-30 11:39:17.572461826 +0200 +diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h +--- openssh-9.9p1.orig/monitor_wrap.h 2025-01-20 19:52:47.918052335 +0100 ++++ openssh-9.9p1/monitor_wrap.h 2025-01-20 20:23:17.274730049 +0100 @@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1802,10 +1793,10 @@ diff -Nur openssh-9.8p1.orig/monitor_wrap.h openssh-9.8p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c ---- openssh-9.8p1.orig/readconf.c 2024-09-30 11:38:28.539321546 +0200 -+++ openssh-9.8p1/readconf.c 2024-09-30 11:39:17.573461828 +0200 -@@ -2760,11 +2760,11 @@ +diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c +--- openssh-9.9p1.orig/readconf.c 2025-01-20 19:52:47.966052458 +0100 ++++ openssh-9.9p1/readconf.c 2025-01-20 20:23:17.275730051 +0100 +@@ -2794,11 +2794,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1820,9 +1811,9 @@ diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h ---- openssh-9.8p1.orig/readconf.h 2024-09-30 11:38:28.377321083 +0200 -+++ openssh-9.8p1/readconf.h 2024-09-30 11:39:17.574461831 +0200 +diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h +--- openssh-9.9p1.orig/readconf.h 2025-01-20 19:52:47.790052008 +0100 ++++ openssh-9.9p1/readconf.h 2025-01-20 20:23:17.276730054 +0100 @@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ @@ -1832,9 +1823,9 @@ diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c ---- openssh-9.8p1.orig/servconf.c 2024-09-30 11:38:28.539321546 +0200 -+++ openssh-9.8p1/servconf.c 2024-09-30 14:09:25.379481790 +0200 +diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c +--- openssh-9.9p1.orig/servconf.c 2025-01-20 19:52:47.966052458 +0100 ++++ openssh-9.9p1/servconf.c 2025-01-20 20:23:17.277730056 +0100 @@ -95,6 +95,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1855,7 +1846,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; -@@ -312,6 +315,8 @@ +@@ -314,6 +317,8 @@ options->use_pam = 0; if (options->pam_service_name == NULL) options->pam_service_name = xstrdup(SSHD_PAM_SERVICE); @@ -1864,7 +1855,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -393,13 +398,17 @@ +@@ -395,13 +400,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1884,7 +1875,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -567,7 +576,7 @@ +@@ -573,7 +582,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1893,7 +1884,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -587,6 +596,9 @@ +@@ -593,6 +602,9 @@ sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1903,7 +1894,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -622,9 +634,11 @@ +@@ -628,9 +640,11 @@ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, { "pamservicename", sPAMServiceName, SSHCFG_ALL }, @@ -1915,7 +1906,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -677,8 +691,15 @@ +@@ -683,8 +697,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1931,7 +1922,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -686,8 +707,11 @@ +@@ -692,8 +713,11 @@ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, @@ -1943,7 +1934,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -761,6 +785,8 @@ +@@ -767,6 +791,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1952,7 +1943,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1387,6 +1413,10 @@ +@@ -1407,6 +1433,10 @@ *charptr = xstrdup(arg); break; @@ -1963,7 +1954,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1638,6 +1668,10 @@ +@@ -1658,6 +1688,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1974,7 +1965,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1646,6 +1680,10 @@ +@@ -1666,6 +1700,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1985,7 +1976,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1666,6 +1704,12 @@ +@@ -1686,6 +1724,12 @@ options->gss_kex_algorithms = xstrdup(arg); break; @@ -1998,7 +1989,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2925,6 +2969,7 @@ +@@ -2950,6 +2994,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2006,10 +1997,10 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h ---- openssh-9.8p1.orig/servconf.h 2024-09-30 11:38:28.431321237 +0200 -+++ openssh-9.8p1/servconf.h 2024-09-30 11:44:57.129433237 +0200 -@@ -154,9 +154,12 @@ +diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h +--- openssh-9.9p1.orig/servconf.h 2025-01-20 19:52:47.836052125 +0100 ++++ openssh-9.9p1/servconf.h 2025-01-20 20:23:17.278730059 +0100 +@@ -155,9 +155,12 @@ * be stored in per-session ccache */ int use_kuserok; int enable_k5users; @@ -2022,7 +2013,7 @@ diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -220,6 +223,7 @@ +@@ -221,6 +224,7 @@ int use_pam; /* Enable auth via PAM */ char *pam_service_name; @@ -2030,10 +2021,10 @@ diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h int permit_tun; -diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 ---- openssh-9.8p1.orig/ssh.1 2024-09-30 11:38:28.517321483 +0200 -+++ openssh-9.8p1/ssh.1 2024-09-30 11:39:17.577461840 +0200 -@@ -1521,6 +1521,18 @@ +diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +--- openssh-9.9p1.orig/ssh.1 2025-01-20 19:52:47.941052394 +0100 ++++ openssh-9.9p1/ssh.1 2025-01-20 20:23:17.279730061 +0100 +@@ -1523,6 +1523,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2052,9 +2043,9 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c ---- openssh-9.8p1.orig/ssh.c 2024-09-30 11:38:28.511321466 +0200 -+++ openssh-9.8p1/ssh.c 2024-09-30 11:39:17.578461843 +0200 +diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c +--- openssh-9.9p1.orig/ssh.c 2025-01-20 19:52:47.926052356 +0100 ++++ openssh-9.9p1/ssh.c 2025-01-20 20:23:17.280730064 +0100 @@ -573,6 +573,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); @@ -2108,9 +2099,9 @@ diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-9.8p1.orig/ssh_config openssh-9.8p1/ssh_config ---- openssh-9.8p1.orig/ssh_config 2024-09-30 11:38:28.380321091 +0200 -+++ openssh-9.8p1/ssh_config 2024-09-30 11:39:17.578461843 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config +--- openssh-9.9p1.orig/ssh_config 2025-01-20 19:52:47.793052015 +0100 ++++ openssh-9.9p1/ssh_config 2025-01-20 20:23:17.281730067 +0100 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2124,9 +2115,9 @@ diff -Nur openssh-9.8p1.orig/ssh_config openssh-9.8p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP no -diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 ---- openssh-9.8p1.orig/ssh_config.5 2024-09-30 11:38:28.454321303 +0200 -+++ openssh-9.8p1/ssh_config.5 2024-09-30 11:39:17.579461846 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1.orig/ssh_config.5 2025-01-20 19:52:47.956052433 +0100 ++++ openssh-9.9p1/ssh_config.5 2025-01-20 20:23:17.282730069 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2164,7 +2155,7 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1595,7 +1601,7 @@ +@@ -1600,7 +1606,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2173,10 +2164,10 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c ---- openssh-9.8p1.orig/sshconnect2.c 2024-09-30 11:38:28.530321521 +0200 -+++ openssh-9.8p1/sshconnect2.c 2024-09-30 11:39:17.580461848 +0200 -@@ -854,6 +854,11 @@ +diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c +--- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 19:52:47.951052420 +0100 ++++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:23:17.283730071 +0100 +@@ -855,6 +855,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2188,7 +2179,7 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -962,7 +967,8 @@ +@@ -963,7 +968,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2198,7 +2189,7 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1129,6 +1135,20 @@ +@@ -1130,6 +1136,20 @@ return r; } @@ -2219,7 +2210,7 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1151,6 +1171,12 @@ +@@ -1152,6 +1172,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2232,7 +2223,7 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1164,7 +1190,9 @@ +@@ -1165,7 +1191,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2243,10 +2234,10 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 ---- openssh-9.8p1.orig/sshd.8 2024-09-30 11:38:28.395321134 +0200 -+++ openssh-9.8p1/sshd.8 2024-09-30 11:39:17.580461848 +0200 -@@ -836,6 +836,29 @@ +diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 +--- openssh-9.9p1.orig/sshd.8 2025-01-20 19:52:47.807052051 +0100 ++++ openssh-9.9p1/sshd.8 2025-01-20 20:23:17.283730071 +0100 +@@ -840,6 +840,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2276,9 +2267,9 @@ diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config ---- openssh-9.8p1.orig/sshd_config 2024-09-30 11:38:28.419321203 +0200 -+++ openssh-9.8p1/sshd_config 2024-09-30 11:39:17.582461854 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config +--- openssh-9.9p1.orig/sshd_config 2025-01-20 19:52:47.826052099 +0100 ++++ openssh-9.9p1/sshd_config 2025-01-20 20:23:17.284730074 +0100 @@ -76,10 +76,11 @@ #KerberosUseKuserok yes @@ -2304,9 +2295,9 @@ diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 ---- openssh-9.8p1.orig/sshd_config.5 2024-09-30 11:38:28.455321306 +0200 -+++ openssh-9.8p1/sshd_config.5 2024-09-30 11:39:17.582461854 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 +--- openssh-9.9p1.orig/sshd_config.5 2025-01-20 19:52:47.870052212 +0100 ++++ openssh-9.9p1/sshd_config.5 2025-01-20 20:23:17.284730074 +0100 @@ -724,15 +724,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2352,7 +2343,7 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -2017,6 +2036,12 @@ +@@ -2041,6 +2060,12 @@ as a non-root user. The default is .Cm no . @@ -2365,9 +2356,9 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-9.8p1.orig/sshd_config_redhat openssh-9.8p1/sshd_config_redhat ---- openssh-9.8p1.orig/sshd_config_redhat 2024-09-30 11:38:28.362321040 +0200 -+++ openssh-9.8p1/sshd_config_redhat 2024-09-30 11:39:17.583461857 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat +--- openssh-9.9p1.orig/sshd_config_redhat 2025-01-20 19:52:47.764051942 +0100 ++++ openssh-9.9p1/sshd_config_redhat 2025-01-20 20:23:17.285730077 +0100 @@ -2,9 +2,6 @@ ChallengeResponseAuthentication no @@ -2378,10 +2369,10 @@ diff -Nur openssh-9.8p1.orig/sshd_config_redhat openssh-9.8p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c ---- openssh-9.8p1.orig/sshd-session.c 2024-09-30 11:38:28.541321552 +0200 -+++ openssh-9.8p1/sshd-session.c 2024-09-30 11:48:44.155082722 +0200 -@@ -1437,7 +1437,7 @@ +diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c +--- openssh-9.9p1.orig/sshd-session.c 2025-01-20 19:52:47.968052463 +0100 ++++ openssh-9.9p1/sshd-session.c 2025-01-20 20:23:17.285730077 +0100 +@@ -1487,7 +1487,7 @@ #endif #ifdef GSSAPI @@ -2390,9 +2381,9 @@ diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-9.8p1.orig/ssh-gss.h openssh-9.8p1/ssh-gss.h ---- openssh-9.8p1.orig/ssh-gss.h 2024-09-30 11:38:28.400321149 +0200 -+++ openssh-9.8p1/ssh-gss.h 2024-09-30 11:39:17.583461857 +0200 +diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h +--- openssh-9.9p1.orig/ssh-gss.h 2025-01-20 19:52:47.805052046 +0100 ++++ openssh-9.9p1/ssh-gss.h 2025-01-20 20:23:17.286730079 +0100 @@ -99,12 +99,14 @@ } ssh_gssapi_ccache; @@ -2428,12 +2419,12 @@ diff -Nur openssh-9.8p1.orig/ssh-gss.h openssh-9.8p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-9.8p1.orig/version.h openssh-9.8p1/version.h ---- openssh-9.8p1.orig/version.h 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/version.h 2024-09-30 11:39:17.584461860 +0200 +diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h +--- openssh-9.9p1.orig/version.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/version.h 2025-01-20 20:23:17.286730079 +0100 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_9.8" + #define SSH_VERSION "OpenSSH_9.9" +#ifdef GSI +#define GSI_VERSION " GSI" diff --git a/openssh-9.8p1-hpn-18.5.1.patch b/openssh-9.9p1-hpn-18.6.0.patch similarity index 96% rename from openssh-9.8p1-hpn-18.5.1.patch rename to openssh-9.9p1-hpn-18.6.0.patch index 0952a56..da663c9 100644 --- a/openssh-9.8p1-hpn-18.5.1.patch +++ b/openssh-9.9p1-hpn-18.6.0.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c ---- openssh-9.8p1.orig/auth2.c 2024-09-30 16:02:22.611024465 +0200 -+++ openssh-9.8p1/auth2.c 2024-10-01 08:51:48.548148424 +0200 +diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c +--- openssh-9.9p1.orig/auth2.c 2025-01-20 20:48:33.444582227 +0100 ++++ openssh-9.9p1/auth2.c 2025-01-20 21:54:08.570687857 +0100 @@ -52,6 +52,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -41,9 +41,9 @@ diff -Nur openssh-9.8p1.orig/auth2.c openssh-9.8p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-9.8p1.orig/binn.c openssh-9.8p1/binn.c ---- openssh-9.8p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/binn.c 2024-09-30 16:03:39.142245236 +0200 +diff -Nur openssh-9.9p1.orig/binn.c openssh-9.9p1/binn.c +--- openssh-9.9p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/binn.c 2025-01-20 20:50:04.564813761 +0100 @@ -0,0 +1,3541 @@ +#include +#include @@ -3586,9 +3586,9 @@ diff -Nur openssh-9.8p1.orig/binn.c openssh-9.8p1/binn.c +} + +/*************************************************************************************/ -diff -Nur openssh-9.8p1.orig/binn.h openssh-9.8p1/binn.h ---- openssh-9.8p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/binn.h 2024-09-30 16:03:39.145245244 +0200 +diff -Nur openssh-9.9p1.orig/binn.h openssh-9.9p1/binn.h +--- openssh-9.9p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/binn.h 2025-01-20 20:50:04.565813763 +0100 @@ -0,0 +1,945 @@ + +// TO ENABLE INLINE FUNCTIONS: @@ -4535,9 +4535,9 @@ diff -Nur openssh-9.8p1.orig/binn.h openssh-9.8p1/binn.h +#endif + +#endif //BINN_H -diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c ---- openssh-9.8p1.orig/channels.c 2024-09-30 16:02:22.534024243 +0200 -+++ openssh-9.8p1/channels.c 2024-10-01 08:56:07.524893574 +0200 +diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c +--- openssh-9.9p1.orig/channels.c 2025-01-20 20:48:33.373582047 +0100 ++++ openssh-9.9p1/channels.c 2025-01-20 21:55:22.938880541 +0100 @@ -97,6 +97,11 @@ /* Minimum port number for X11 forwarding */ #define X11_PORT_MIN 6000 @@ -4585,7 +4585,7 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1255,6 +1274,33 @@ +@@ -1257,6 +1276,33 @@ c->io_want = SSH_CHAN_IO_SOCK_W; } @@ -4619,7 +4619,7 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c) { -@@ -2362,18 +2408,29 @@ +@@ -2364,18 +2410,29 @@ c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { @@ -4652,7 +4652,7 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c c->local_consumed = 0; } return 1; -@@ -2959,9 +3016,7 @@ +@@ -2961,9 +3018,7 @@ * in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) @@ -4663,7 +4663,7 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c else chan_ibuf_empty(ssh, c); } -@@ -3670,7 +3725,7 @@ +@@ -3672,7 +3727,7 @@ error_fr(r, "parse adjust"); ssh_packet_disconnect(ssh, "Invalid window adjust message"); } @@ -4672,7 +4672,7 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c if ((new_rwin = c->remote_window + adjust) < c->remote_window) { fatal("channel %d: adjust %u overflows remote window %u", c->self, adjust, c->remote_window); -@@ -3785,6 +3840,13 @@ +@@ -3787,6 +3842,13 @@ return addr; } @@ -4686,10 +4686,10 @@ diff -Nur openssh-9.8p1.orig/channels.c openssh-9.8p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -diff -Nur openssh-9.8p1.orig/channels.h openssh-9.8p1/channels.h ---- openssh-9.8p1.orig/channels.h 2024-09-30 16:02:22.494024127 +0200 -+++ openssh-9.8p1/channels.h 2024-09-30 16:03:39.147245250 +0200 -@@ -173,6 +173,7 @@ +diff -Nur openssh-9.9p1.orig/channels.h openssh-9.9p1/channels.h +--- openssh-9.9p1.orig/channels.h 2025-01-20 20:48:33.343581971 +0100 ++++ openssh-9.9p1/channels.h 2025-01-20 20:50:04.567813768 +0100 +@@ -175,6 +175,7 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; @@ -4697,7 +4697,7 @@ diff -Nur openssh-9.8p1.orig/channels.h openssh-9.8p1/channels.h int extended_usage; int single_connection; -@@ -254,7 +255,7 @@ +@@ -256,7 +257,7 @@ #define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W) /* Read buffer size */ @@ -4706,16 +4706,16 @@ diff -Nur openssh-9.8p1.orig/channels.h openssh-9.8p1/channels.h /* Maximum size for direct reads to buffers */ #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -396,4 +397,6 @@ +@@ -398,4 +399,6 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); +/* hpn handler */ +void channel_set_hpn_disabled(int); #endif -diff -Nur openssh-9.8p1.orig/cipher.c openssh-9.8p1/cipher.c ---- openssh-9.8p1.orig/cipher.c 2024-09-30 16:02:22.556024306 +0200 -+++ openssh-9.8p1/cipher.c 2024-10-01 09:00:13.211602019 +0200 +diff -Nur openssh-9.9p1.orig/cipher.c openssh-9.9p1/cipher.c +--- openssh-9.9p1.orig/cipher.c 2025-01-20 20:48:33.392582095 +0100 ++++ openssh-9.9p1/cipher.c 2025-01-20 21:56:16.253016900 +0100 @@ -48,23 +48,39 @@ #include "sshbuf.h" #include "ssherr.h" @@ -5011,9 +5011,9 @@ diff -Nur openssh-9.8p1.orig/cipher.c openssh-9.8p1/cipher.c #endif freezero(cc, sizeof(*cc)); } -diff -Nur openssh-9.8p1.orig/cipher-chachapoly.c openssh-9.8p1/cipher-chachapoly.c ---- openssh-9.8p1.orig/cipher-chachapoly.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/cipher-chachapoly.c 2024-09-30 16:03:39.149245256 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly.c openssh-9.9p1/cipher-chachapoly.c +--- openssh-9.9p1.orig/cipher-chachapoly.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/cipher-chachapoly.c 2025-01-20 20:50:04.569813773 +0100 @@ -88,7 +88,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5032,9 +5032,9 @@ diff -Nur openssh-9.8p1.orig/cipher-chachapoly.c openssh-9.8p1/cipher-chachapoly poly_key); } r = 0; -diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto.c openssh-9.8p1/cipher-chachapoly-libcrypto.c ---- openssh-9.8p1.orig/cipher-chachapoly-libcrypto.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/cipher-chachapoly-libcrypto.c 2024-10-01 09:02:21.651972382 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher-chachapoly-libcrypto.c +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto.c 2025-01-20 21:59:09.157459134 +0100 @@ -34,8 +34,17 @@ #include "ssherr.h" #include "cipher-chachapoly.h" @@ -5097,9 +5097,9 @@ diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto.c openssh-9.8p1/cipher- poly_key); } r = 0; -diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.8p1/cipher-chachapoly-libcrypto-mt.c ---- openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-chachapoly-libcrypto-mt.c 2024-09-30 16:03:39.149245256 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c 2025-01-20 20:50:04.570813776 +0100 @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5796,9 +5796,9 @@ diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.8p1/ciph +#endif +} +#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */ -diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.8p1/cipher-chachapoly-libcrypto-mt.h ---- openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-chachapoly-libcrypto-mt.h 2024-09-30 16:03:39.149245256 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h 2025-01-20 20:50:04.571813779 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5845,9 +5845,9 @@ diff -Nur openssh-9.8p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.8p1/ciph + __attribute__((__bounded__(__buffer__, 4, 5))); + +#endif /* CHACHA_POLY_LIBCRYPTO_MT_H */ -diff -Nur openssh-9.8p1.orig/cipher-ctr-mt.c openssh-9.8p1/cipher-ctr-mt.c ---- openssh-9.8p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-ctr-mt.c 2024-09-30 16:03:39.150245259 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt.c openssh-9.9p1/cipher-ctr-mt.c +--- openssh-9.9p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt.c 2025-01-20 20:50:04.571813779 +0100 @@ -0,0 +1,677 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -6526,9 +6526,9 @@ diff -Nur openssh-9.8p1.orig/cipher-ctr-mt.c openssh-9.8p1/cipher-ctr-mt.c + return aes_ctr; +} +#endif /* OSSL Check */ -diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.c openssh-9.8p1/cipher-ctr-mt-functions.c ---- openssh-9.8p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-ctr-mt-functions.c 2024-09-30 16:03:39.150245259 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.c openssh-9.9p1/cipher-ctr-mt-functions.c +--- openssh-9.9p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-functions.c 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,668 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7198,9 +7198,9 @@ diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.c openssh-9.8p1/cipher-ctr- +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.h openssh-9.8p1/cipher-ctr-mt-functions.h ---- openssh-9.8p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-ctr-mt-functions.h 2024-09-30 16:03:39.150245259 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.h openssh-9.9p1/cipher-ctr-mt-functions.h +--- openssh-9.9p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-functions.h 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,142 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7344,9 +7344,9 @@ diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-functions.h openssh-9.8p1/cipher-ctr- + +#endif /* WITH OPENSSL */ +#endif /* CTR_MT_FUNCS */ -diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-provider.c openssh-9.8p1/cipher-ctr-mt-provider.c ---- openssh-9.8p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-ctr-mt-provider.c 2024-09-30 16:03:39.151245261 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-provider.c openssh-9.9p1/cipher-ctr-mt-provider.c +--- openssh-9.9p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-provider.c 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,390 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7738,9 +7738,9 @@ diff -Nur openssh-9.8p1.orig/cipher-ctr-mt-provider.c openssh-9.8p1/cipher-ctr-m +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.8p1.orig/cipher.h openssh-9.8p1/cipher.h ---- openssh-9.8p1.orig/cipher.h 2024-09-30 16:02:22.556024306 +0200 -+++ openssh-9.8p1/cipher.h 2024-09-30 16:26:15.533157716 +0200 +diff -Nur openssh-9.9p1.orig/cipher.h openssh-9.9p1/cipher.h +--- openssh-9.9p1.orig/cipher.h 2025-01-20 20:48:33.392582095 +0100 ++++ openssh-9.9p1/cipher.h 2025-01-20 20:59:21.957234646 +0100 @@ -42,11 +42,17 @@ #include #endif @@ -7797,9 +7797,9 @@ diff -Nur openssh-9.8p1.orig/cipher.h openssh-9.8p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-9.8p1.orig/cipher-switch.c openssh-9.8p1/cipher-switch.c ---- openssh-9.8p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-switch.c 2024-09-30 16:03:39.151245261 +0200 +diff -Nur openssh-9.9p1.orig/cipher-switch.c openssh-9.9p1/cipher-switch.c +--- openssh-9.9p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-switch.c 2025-01-20 20:50:04.573813784 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -7874,9 +7874,9 @@ diff -Nur openssh-9.8p1.orig/cipher-switch.c openssh-9.8p1/cipher-switch.c + } +#endif +} -diff -Nur openssh-9.8p1.orig/cipher-switch.h openssh-9.8p1/cipher-switch.h ---- openssh-9.8p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/cipher-switch.h 2024-09-30 16:03:39.152245264 +0200 +diff -Nur openssh-9.9p1.orig/cipher-switch.h openssh-9.9p1/cipher-switch.h +--- openssh-9.9p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-switch.h 2025-01-20 20:50:04.574813786 +0100 @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 The Board of Trustees of Carnegie Mellon University. @@ -7896,9 +7896,9 @@ diff -Nur openssh-9.8p1.orig/cipher-switch.h openssh-9.8p1/cipher-switch.h + */ + +void cipher_switch (struct ssh *); -diff -Nur openssh-9.8p1.orig/clientloop.c openssh-9.8p1/clientloop.c ---- openssh-9.8p1.orig/clientloop.c 2024-09-30 16:02:22.434023954 +0200 -+++ openssh-9.8p1/clientloop.c 2024-09-30 16:03:39.153245267 +0200 +diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c +--- openssh-9.9p1.orig/clientloop.c 2025-01-20 20:48:33.290581837 +0100 ++++ openssh-9.9p1/clientloop.c 2025-01-20 20:50:04.575813789 +0100 @@ -114,6 +114,7 @@ #include "msg.h" #include "ssherr.h" @@ -8188,9 +8188,9 @@ diff -Nur openssh-9.8p1.orig/clientloop.c openssh-9.8p1/clientloop.c if (len > 900) len = 900; if (want_subsystem) { -diff -Nur openssh-9.8p1.orig/compat.c openssh-9.8p1/compat.c ---- openssh-9.8p1.orig/compat.c 2024-09-30 16:02:22.594024416 +0200 -+++ openssh-9.8p1/compat.c 2024-10-01 09:15:43.262288236 +0200 +diff -Nur openssh-9.9p1.orig/compat.c openssh-9.9p1/compat.c +--- openssh-9.9p1.orig/compat.c 2025-01-20 20:48:33.422582171 +0100 ++++ openssh-9.9p1/compat.c 2025-01-20 22:39:30.315877553 +0100 @@ -135,6 +135,35 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) @@ -8218,7 +8218,7 @@ diff -Nur openssh-9.8p1.orig/compat.c openssh-9.8p1/compat.c + } + /* if it's openssh and not hpn */ + else if ((strstr(version, "OpenSSH_8.9") != NULL) || -+ (strstr(version, "OpenSSH_9") != NULL)) { ++ (strstr(version, "OpenSSH_9") != NULL)) { + ssh->compat |= SSH_RESTRICT_WINDOW; + debug("Restricting advertised window size."); + } @@ -8227,9 +8227,9 @@ diff -Nur openssh-9.8p1.orig/compat.c openssh-9.8p1/compat.c return; } } -diff -Nur openssh-9.8p1.orig/compat.h openssh-9.8p1/compat.h ---- openssh-9.8p1.orig/compat.h 2024-09-30 16:02:22.594024416 +0200 -+++ openssh-9.8p1/compat.h 2024-10-01 09:16:03.734347588 +0200 +diff -Nur openssh-9.9p1.orig/compat.h openssh-9.9p1/compat.h +--- openssh-9.9p1.orig/compat.h 2025-01-20 20:48:33.423582174 +0100 ++++ openssh-9.9p1/compat.h 2025-01-20 22:36:35.778448062 +0100 @@ -46,12 +46,12 @@ /* #define unused 0x00010000 */ /* #define unused 0x00020000 */ @@ -8246,10 +8246,10 @@ diff -Nur openssh-9.8p1.orig/compat.h openssh-9.8p1/compat.h #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 -diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac ---- openssh-9.8p1.orig/configure.ac 2024-09-30 16:02:22.614024473 +0200 -+++ openssh-9.8p1/configure.ac 2024-09-30 16:03:39.155245273 +0200 -@@ -2936,8 +2936,8 @@ +diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac +--- openssh-9.9p1.orig/configure.ac 2025-01-20 20:48:33.447582234 +0100 ++++ openssh-9.9p1/configure.ac 2025-01-20 20:50:04.577813794 +0100 +@@ -2945,8 +2945,8 @@ 200*) # LibreSSL lver=`echo "$sslver" | sed 's/.*libressl-//'` case "$lver" in @@ -8260,7 +8260,7 @@ diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac ;; *) ;; # Assume all other versions are good. esac -@@ -2946,6 +2946,7 @@ +@@ -2955,6 +2955,7 @@ # OpenSSL 3; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" @@ -8268,7 +8268,7 @@ diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac ;; *) AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_showver")]) -@@ -3063,6 +3064,30 @@ +@@ -3074,6 +3075,30 @@ EVP_CIPHER_CTX_set_iv \ ]) @@ -8299,9 +8299,9 @@ diff -Nur openssh-9.8p1.orig/configure.ac openssh-9.8p1/configure.ac if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -diff -Nur openssh-9.8p1.orig/defines.h openssh-9.8p1/defines.h ---- openssh-9.8p1.orig/defines.h 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/defines.h 2024-09-30 16:03:39.155245273 +0200 +diff -Nur openssh-9.9p1.orig/defines.h openssh-9.9p1/defines.h +--- openssh-9.9p1.orig/defines.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/defines.h 2025-01-20 20:50:04.578813797 +0100 @@ -889,7 +889,7 @@ #endif @@ -8311,9 +8311,9 @@ diff -Nur openssh-9.8p1.orig/defines.h openssh-9.8p1/defines.h #endif /* -diff -Nur openssh-9.8p1.orig/digest.h openssh-9.8p1/digest.h ---- openssh-9.8p1.orig/digest.h 2024-09-30 16:02:22.523024211 +0200 -+++ openssh-9.8p1/digest.h 2024-09-30 16:03:39.156245276 +0200 +diff -Nur openssh-9.9p1.orig/digest.h openssh-9.9p1/digest.h +--- openssh-9.9p1.orig/digest.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/digest.h 2025-01-20 20:50:04.578813797 +0100 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -8324,9 +8324,9 @@ diff -Nur openssh-9.8p1.orig/digest.h openssh-9.8p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-9.8p1.orig/digest-openssl.c openssh-9.8p1/digest-openssl.c ---- openssh-9.8p1.orig/digest-openssl.c 2024-09-30 16:02:22.523024211 +0200 -+++ openssh-9.8p1/digest-openssl.c 2024-09-30 16:03:39.156245276 +0200 +diff -Nur openssh-9.9p1.orig/digest-openssl.c openssh-9.9p1/digest-openssl.c +--- openssh-9.9p1.orig/digest-openssl.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/digest-openssl.c 2025-01-20 20:50:04.578813797 +0100 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -8335,9 +8335,9 @@ diff -Nur openssh-9.8p1.orig/digest-openssl.c openssh-9.8p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-9.8p1.orig/FUNDING.yml openssh-9.8p1/FUNDING.yml ---- openssh-9.8p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/FUNDING.yml 2024-09-30 16:03:39.156245276 +0200 +diff -Nur openssh-9.9p1.orig/FUNDING.yml openssh-9.9p1/FUNDING.yml +--- openssh-9.9p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/FUNDING.yml 2025-01-20 20:50:04.578813797 +0100 @@ -0,0 +1,12 @@ +# These are supported funding model platforms + @@ -8351,9 +8351,9 @@ diff -Nur openssh-9.8p1.orig/FUNDING.yml openssh-9.8p1/FUNDING.yml +#issuehunt: # Replace with a single IssueHunt username +#otechie: # Replace with a single Otechie username +#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -diff -Nur openssh-9.8p1.orig/HPN-README openssh-9.8p1/HPN-README ---- openssh-9.8p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/HPN-README 2024-09-30 16:03:39.156245276 +0200 +diff -Nur openssh-9.9p1.orig/HPN-README openssh-9.9p1/HPN-README +--- openssh-9.9p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/HPN-README 2025-01-20 20:50:04.578813797 +0100 @@ -0,0 +1,170 @@ +Notes: + @@ -8525,9 +8525,9 @@ diff -Nur openssh-9.8p1.orig/HPN-README openssh-9.8p1/HPN-README + + +Edited: October 11, 2023 -diff -Nur openssh-9.8p1.orig/HPNSSHInstallation.txt openssh-9.8p1/HPNSSHInstallation.txt ---- openssh-9.8p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/HPNSSHInstallation.txt 2024-09-30 16:03:39.156245276 +0200 +diff -Nur openssh-9.9p1.orig/HPNSSHInstallation.txt openssh-9.9p1/HPNSSHInstallation.txt +--- openssh-9.9p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/HPNSSHInstallation.txt 2025-01-20 20:50:04.579813799 +0100 @@ -0,0 +1,354 @@ +HPN-SSH Installation + @@ -8658,7 +8658,7 @@ diff -Nur openssh-9.8p1.orig/HPNSSHInstallation.txt openssh-9.8p1/HPNSSHInstalla +hpnsshd.service.in. You can use this file by copying it to +/libsystemd/system/hpnsshd.service instead of copying the above text. + -+Then create the defaults file at /etc/defaults/hpnsshd with the following content: ++Then create the defaults file at /etc/default/hpnsshd with the following content: +# Default settings for openssh-server. +# Options to pass to sshd +SSHD_OPTS= @@ -8883,10 +8883,10 @@ diff -Nur openssh-9.8p1.orig/HPNSSHInstallation.txt openssh-9.8p1/HPNSSHInstalla +restorecon /usr/bin/hpnssh-agent +restorecon /usr/bin/hpnssh-keygen +restorecon /etc/pam.d/hpnsshd -diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c ---- openssh-9.8p1.orig/kex.c 2024-09-30 16:02:22.589024401 +0200 -+++ openssh-9.8p1/kex.c 2024-09-30 16:03:39.157245279 +0200 -@@ -66,6 +66,7 @@ +diff -Nur openssh-9.9p1.orig/kex.c openssh-9.9p1/kex.c +--- openssh-9.9p1.orig/kex.c 2025-01-20 20:48:33.420582166 +0100 ++++ openssh-9.9p1/kex.c 2025-01-20 20:50:04.579813799 +0100 +@@ -67,6 +67,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -8894,7 +8894,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c #include "digest.h" #include "xmalloc.h" #include "audit.h" -@@ -774,17 +775,83 @@ +@@ -775,17 +776,83 @@ free(kex); } @@ -8970,7 +8970,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c kex_reset_dispatch(ssh); ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); - return 0; -+ restoreProposal: ++ restoreProposal: +#ifdef WITH_OPENSSL + free(proposal[PROPOSAL_ENC_ALGS_CTOS]); + free(proposal[PROPOSAL_ENC_ALGS_STOC]); @@ -8981,7 +8981,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c } int -@@ -975,6 +1042,11 @@ +@@ -974,6 +1041,11 @@ int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; @@ -8993,7 +8993,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) -@@ -1051,6 +1123,31 @@ +@@ -1050,6 +1122,31 @@ peer[nenc] = NULL; goto out; } @@ -9025,7 +9025,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c authlen = cipher_authlen(newkeys->enc.cipher); /* ignore mac for authenticated encryption */ if (authlen == 0 && -@@ -1066,11 +1163,43 @@ +@@ -1065,11 +1162,43 @@ peer[ncomp] = NULL; goto out; } @@ -9069,7 +9069,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { -@@ -1430,7 +1559,7 @@ +@@ -1429,7 +1558,7 @@ if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", @@ -9078,7 +9078,7 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c version_addendum == NULL ? "" : " ", version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; -@@ -1566,9 +1695,24 @@ +@@ -1565,9 +1694,24 @@ r = SSH_ERR_INVALID_FORMAT; goto out; } @@ -9103,9 +9103,9 @@ diff -Nur openssh-9.8p1.orig/kex.c openssh-9.8p1/kex.c mismatch = 0; switch (remote_major) { -diff -Nur openssh-9.8p1.orig/mac.c openssh-9.8p1/mac.c ---- openssh-9.8p1.orig/mac.c 2024-09-30 16:02:22.557024309 +0200 -+++ openssh-9.8p1/mac.c 2024-09-30 16:03:39.158245282 +0200 +diff -Nur openssh-9.9p1.orig/mac.c openssh-9.9p1/mac.c +--- openssh-9.9p1.orig/mac.c 2025-01-20 20:48:33.394582100 +0100 ++++ openssh-9.9p1/mac.c 2025-01-20 20:50:04.580813802 +0100 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -9114,9 +9114,9 @@ diff -Nur openssh-9.8p1.orig/mac.c openssh-9.8p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in ---- openssh-9.8p1.orig/Makefile.in 2024-09-30 16:02:22.616024479 +0200 -+++ openssh-9.8p1/Makefile.in 2024-10-01 09:22:44.089508215 +0200 +diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in +--- openssh-9.9p1.orig/Makefile.in 2025-01-20 20:48:33.449582239 +0100 ++++ openssh-9.9p1/Makefile.in 2025-01-20 21:02:30.432714955 +0100 @@ -51,7 +51,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ @@ -9144,7 +9144,7 @@ diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in hmac.o ed25519.o hash.o \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ @@ -116,12 +117,13 @@ - kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o auditstub.o @@ -9177,9 +9177,9 @@ diff -Nur openssh-9.8p1.orig/Makefile.in openssh-9.8p1/Makefile.in ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) -diff -Nur openssh-9.8p1.orig/metrics.c openssh-9.8p1/metrics.c ---- openssh-9.8p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/metrics.c 2024-09-30 16:03:39.159245285 +0200 +diff -Nur openssh-9.9p1.orig/metrics.c openssh-9.9p1/metrics.c +--- openssh-9.9p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/metrics.c 2025-01-20 20:50:04.581813804 +0100 @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9625,9 +9625,9 @@ diff -Nur openssh-9.8p1.orig/metrics.c openssh-9.8p1/metrics.c +#endif /* ifdef __linux__ */ + fprintf(fptr, "\n\n"); +} -diff -Nur openssh-9.8p1.orig/metrics.h openssh-9.8p1/metrics.h ---- openssh-9.8p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/metrics.h 2024-09-30 16:03:39.159245285 +0200 +diff -Nur openssh-9.9p1.orig/metrics.h openssh-9.9p1/metrics.h +--- openssh-9.9p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/metrics.h 2025-01-20 20:50:04.581813804 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9674,9 +9674,9 @@ diff -Nur openssh-9.8p1.orig/metrics.h openssh-9.8p1/metrics.h + + +#endif /* define metrics_h */ -diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c ---- openssh-9.8p1.orig/misc.c 2024-09-30 16:02:22.617024482 +0200 -+++ openssh-9.8p1/misc.c 2024-09-30 16:03:39.159245285 +0200 +diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c +--- openssh-9.9p1.orig/misc.c 2025-01-20 20:48:33.449582239 +0100 ++++ openssh-9.9p1/misc.c 2025-01-20 20:50:04.582813807 +0100 @@ -77,6 +77,29 @@ #include "ssherr.h" #include "platform.h" @@ -9746,9 +9746,9 @@ diff -Nur openssh-9.8p1.orig/misc.c openssh-9.8p1/misc.c put_u16(void *vp, u_int16_t v) { u_char *p = (u_char *)vp; -diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h ---- openssh-9.8p1.orig/misc.h 2024-09-30 16:02:22.617024482 +0200 -+++ openssh-9.8p1/misc.h 2024-09-30 16:03:39.160245287 +0200 +diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h +--- openssh-9.9p1.orig/misc.h 2025-01-20 20:48:33.450582242 +0100 ++++ openssh-9.9p1/misc.h 2025-01-20 20:50:04.582813807 +0100 @@ -166,12 +166,6 @@ void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); @@ -9779,10 +9779,10 @@ diff -Nur openssh-9.8p1.orig/misc.h openssh-9.8p1/misc.h +void read_mem_stats(struct statm_t *, int); + #endif /* _MISC_H */ -diff -Nur openssh-9.8p1.orig/myproposal.h openssh-9.8p1/myproposal.h ---- openssh-9.8p1.orig/myproposal.h 2024-09-30 16:02:22.575024361 +0200 -+++ openssh-9.8p1/myproposal.h 2024-09-30 16:03:39.161245290 +0200 -@@ -69,7 +69,8 @@ +diff -Nur openssh-9.9p1.orig/myproposal.h openssh-9.9p1/myproposal.h +--- openssh-9.9p1.orig/myproposal.h 2025-01-20 20:48:33.407582133 +0100 ++++ openssh-9.9p1/myproposal.h 2025-01-20 20:50:04.583813809 +0100 +@@ -71,7 +71,8 @@ "rsa-sha2-256" #define KEX_SERVER_ENCRYPT \ @@ -9792,9 +9792,9 @@ diff -Nur openssh-9.8p1.orig/myproposal.h openssh-9.8p1/myproposal.h "aes128-ctr,aes192-ctr,aes256-ctr," \ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" -diff -Nur openssh-9.8p1.orig/num.c openssh-9.8p1/num.c ---- openssh-9.8p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/num.c 2024-09-30 16:03:39.161245290 +0200 +diff -Nur openssh-9.9p1.orig/num.c openssh-9.9p1/num.c +--- openssh-9.9p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/num.c 2025-01-20 20:50:04.583813809 +0100 @@ -0,0 +1,156 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9952,9 +9952,9 @@ diff -Nur openssh-9.8p1.orig/num.c openssh-9.8p1/num.c +implement_provnum(size_t, OSSL_PARAM_UNSIGNED_INTEGER) + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.8p1.orig/num.h openssh-9.8p1/num.h ---- openssh-9.8p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/num.h 2024-09-30 16:03:39.161245290 +0200 +diff -Nur openssh-9.9p1.orig/num.h openssh-9.9p1/num.h +--- openssh-9.9p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/num.h 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,15 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9971,9 +9971,9 @@ diff -Nur openssh-9.8p1.orig/num.h openssh-9.8p1/num.h +#define PROVNUM_E_TOOBIG -2 +#define PROVNUM_E_UNSUPPORTED -3 +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.8p1.orig/ossl3-provider-err.c openssh-9.8p1/ossl3-provider-err.c ---- openssh-9.8p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/ossl3-provider-err.c 2024-09-30 16:03:39.162245293 +0200 +diff -Nur openssh-9.9p1.orig/ossl3-provider-err.c openssh-9.9p1/ossl3-provider-err.c +--- openssh-9.9p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/ossl3-provider-err.c 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,108 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10083,9 +10083,9 @@ diff -Nur openssh-9.8p1.orig/ossl3-provider-err.c openssh-9.8p1/ossl3-provider-e +} + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.8p1.orig/ossl3-provider-err.h openssh-9.8p1/ossl3-provider-err.h ---- openssh-9.8p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/ossl3-provider-err.h 2024-09-30 16:03:39.162245293 +0200 +diff -Nur openssh-9.9p1.orig/ossl3-provider-err.h openssh-9.9p1/ossl3-provider-err.h +--- openssh-9.9p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/ossl3-provider-err.h 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,73 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10160,9 +10160,9 @@ diff -Nur openssh-9.8p1.orig/ossl3-provider-err.h openssh-9.8p1/ossl3-provider-e +void proverr_set_error(const struct proverr_functions_st *handle, + uint32_t reason, const char *fmt, ...); +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c ---- openssh-9.8p1.orig/packet.c 2024-09-30 16:02:22.560024318 +0200 -+++ openssh-9.8p1/packet.c 2024-09-30 16:03:39.163245296 +0200 +diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c +--- openssh-9.9p1.orig/packet.c 2025-01-20 20:48:33.396582105 +0100 ++++ openssh-9.9p1/packet.c 2025-01-20 20:50:04.585813814 +0100 @@ -63,6 +63,9 @@ #endif #include @@ -10295,7 +10295,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c return r; if (!state->cipher_warning_done && (wmsg = cipher_warning_message(*ccp)) != NULL) { -@@ -1045,23 +1095,45 @@ +@@ -1044,23 +1094,45 @@ } comp->enabled = 1; } @@ -10355,7 +10355,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c #define MAX_PACKETS (1U<<31) static int ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) -@@ -1088,6 +1160,14 @@ +@@ -1087,6 +1159,14 @@ if (state->p_send.packets == 0 && state->p_read.packets == 0) return 0; @@ -10370,7 +10370,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c /* Time-based rekeying */ if (state->rekey_interval != 0 && (int64_t)state->rekey_time + state->rekey_interval <= monotime()) -@@ -1294,8 +1374,8 @@ +@@ -1293,8 +1373,8 @@ sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) goto out; if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp, @@ -10381,7 +10381,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c goto out; /* append unencrypted MAC */ if (mac && mac->enabled) { -@@ -1446,7 +1526,7 @@ +@@ -1445,7 +1525,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain = 0; struct pollfd pfd; @@ -10390,7 +10390,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c struct timeval start; struct timespec timespec, *timespecp = NULL; -@@ -1573,7 +1653,7 @@ +@@ -1549,7 +1629,7 @@ return 0; /* packet is incomplete */ state->packlen = PEEK_U32(cp); if (state->packlen < 4 + 1 || @@ -10399,7 +10399,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c return SSH_ERR_MESSAGE_INCOMPLETE; } need = state->packlen + 4; -@@ -1632,7 +1712,7 @@ +@@ -1608,7 +1688,7 @@ sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) return 0; if (state->packlen < 1 + 4 || @@ -10408,7 +10408,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c #ifdef PACKET_DEBUG sshbuf_dump(state->input, stderr); #endif -@@ -1659,7 +1739,7 @@ +@@ -1635,7 +1715,7 @@ goto out; state->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet)); if (state->packlen < 1 + 4 || @@ -10417,7 +10417,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c #ifdef PACKET_DEBUG fprintf(stderr, "input: \n"); sshbuf_dump(state->input, stderr); -@@ -1668,7 +1748,7 @@ +@@ -1644,7 +1724,7 @@ #endif logit("Bad packet length %u.", state->packlen); return ssh_packet_start_discard(ssh, enc, mac, 0, @@ -10426,7 +10426,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c } if ((r = sshbuf_consume(state->input, block_size)) != 0) goto out; -@@ -1691,7 +1771,7 @@ +@@ -1667,7 +1747,7 @@ logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); return ssh_packet_start_discard(ssh, enc, mac, 0, @@ -10435,7 +10435,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c } /* * check if the entire packet has been received and -@@ -1735,11 +1815,11 @@ +@@ -1711,11 +1791,11 @@ if (r != SSH_ERR_MAC_INVALID) goto out; logit("Corrupted MAC on input."); @@ -10449,7 +10449,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c } /* Remove MAC from input buffer */ DBG(debug("MAC #%d ok", state->p_read.seqnr)); -@@ -1954,7 +2034,7 @@ +@@ -1930,7 +2010,7 @@ int r; size_t rlen; @@ -10458,7 +10458,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c return r; if (state->packet_discard) { -@@ -2033,17 +2113,21 @@ +@@ -2009,17 +2089,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -10480,7 +10480,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -2085,6 +2169,24 @@ +@@ -2061,6 +2145,24 @@ logdie_f("should have exited"); } @@ -10505,7 +10505,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -2339,10 +2441,19 @@ +@@ -2315,10 +2417,19 @@ ssh->kex->server = 1; /* XXX unify? */ } @@ -10525,7 +10525,7 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c } void * -@@ -2960,3 +3071,17 @@ +@@ -2941,3 +3052,17 @@ ssh->state->extra_pad = pad; return 0; } @@ -10543,10 +10543,10 @@ diff -Nur openssh-9.8p1.orig/packet.c openssh-9.8p1/packet.c +{ + return ssh->state->receive_context; +} -diff -Nur openssh-9.8p1.orig/packet.h openssh-9.8p1/packet.h ---- openssh-9.8p1.orig/packet.h 2024-09-30 16:02:22.560024318 +0200 -+++ openssh-9.8p1/packet.h 2024-09-30 16:03:39.163245296 +0200 -@@ -86,6 +86,17 @@ +diff -Nur openssh-9.9p1.orig/packet.h openssh-9.9p1/packet.h +--- openssh-9.9p1.orig/packet.h 2025-01-20 20:48:33.397582108 +0100 ++++ openssh-9.9p1/packet.h 2025-01-20 20:50:04.585813814 +0100 +@@ -88,6 +88,17 @@ /* APP data */ void *app_data; @@ -10564,7 +10564,7 @@ diff -Nur openssh-9.8p1.orig/packet.h openssh-9.8p1/packet.h }; typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, -@@ -156,6 +167,8 @@ +@@ -157,6 +168,8 @@ int ssh_packet_set_maxsize(struct ssh *, u_int); u_int ssh_packet_get_maxsize(struct ssh *); @@ -10573,7 +10573,7 @@ diff -Nur openssh-9.8p1.orig/packet.h openssh-9.8p1/packet.h int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); -@@ -171,6 +184,13 @@ +@@ -172,6 +185,13 @@ void *ssh_packet_get_input(struct ssh *); void *ssh_packet_get_output(struct ssh *); @@ -10587,9 +10587,9 @@ diff -Nur openssh-9.8p1.orig/packet.h openssh-9.8p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-9.8p1.orig/poly1305.c openssh-9.8p1/poly1305.c ---- openssh-9.8p1.orig/poly1305.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/poly1305.c 2024-09-30 16:03:39.164245299 +0200 +diff -Nur openssh-9.9p1.orig/poly1305.c openssh-9.9p1/poly1305.c +--- openssh-9.9p1.orig/poly1305.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/poly1305.c 2025-01-20 20:50:04.586813817 +0100 @@ -13,6 +13,16 @@ #include "poly1305.h" @@ -10621,9 +10621,9 @@ diff -Nur openssh-9.8p1.orig/poly1305.c openssh-9.8p1/poly1305.c U32TO8_LE(&out[12], f3); } +#endif /* OPENSSL_HAVE_POLY_EVP */ -diff -Nur openssh-9.8p1.orig/poly1305.h openssh-9.8p1/poly1305.h ---- openssh-9.8p1.orig/poly1305.h 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/poly1305.h 2024-09-30 16:03:39.164245299 +0200 +diff -Nur openssh-9.9p1.orig/poly1305.h openssh-9.9p1/poly1305.h +--- openssh-9.9p1.orig/poly1305.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/poly1305.h 2025-01-20 20:50:04.586813817 +0100 @@ -13,8 +13,15 @@ #define POLY1305_KEYLEN 32 #define POLY1305_TAGLEN 16 @@ -10641,9 +10641,9 @@ diff -Nur openssh-9.8p1.orig/poly1305.h openssh-9.8p1/poly1305.h __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); -diff -Nur openssh-9.8p1.orig/progressmeter.c openssh-9.8p1/progressmeter.c ---- openssh-9.8p1.orig/progressmeter.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/progressmeter.c 2024-09-30 16:03:39.165245302 +0200 +diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c +--- openssh-9.9p1.orig/progressmeter.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/progressmeter.c 2025-01-20 20:50:04.586813817 +0100 @@ -66,6 +66,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ @@ -10702,9 +10702,9 @@ diff -Nur openssh-9.8p1.orig/progressmeter.c openssh-9.8p1/progressmeter.c } static void -diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c ---- openssh-9.8p1.orig/readconf.c 2024-09-30 16:02:22.619024488 +0200 -+++ openssh-9.8p1/readconf.c 2024-09-30 16:35:58.686841931 +0200 +diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c +--- openssh-9.9p1.orig/readconf.c 2025-01-20 20:48:33.452582247 +0100 ++++ openssh-9.9p1/readconf.c 2025-01-20 21:03:08.963813150 +0100 @@ -72,6 +72,7 @@ #include "myproposal.h" #include "digest.h" @@ -10758,7 +10758,7 @@ diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c } return port; } -@@ -1288,6 +1304,63 @@ +@@ -1317,6 +1333,63 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -10822,7 +10822,7 @@ diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -2678,6 +2751,17 @@ +@@ -2712,6 +2785,17 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; @@ -10840,7 +10840,7 @@ diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2861,8 +2945,37 @@ +@@ -2895,8 +2979,37 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -10878,9 +10878,9 @@ diff -Nur openssh-9.8p1.orig/readconf.c openssh-9.8p1/readconf.c if (options->control_persist == -1) { options->control_persist = 0; options->control_persist_timeout = 0; -diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h ---- openssh-9.8p1.orig/readconf.h 2024-09-30 16:02:22.619024488 +0200 -+++ openssh-9.8p1/readconf.h 2024-10-01 10:20:11.459528169 +0200 +diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h +--- openssh-9.9p1.orig/readconf.h 2025-01-20 20:48:33.452582247 +0100 ++++ openssh-9.9p1/readconf.h 2025-01-21 07:26:17.608445051 +0100 @@ -56,6 +56,8 @@ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ @@ -10908,9 +10908,9 @@ diff -Nur openssh-9.8p1.orig/readconf.h openssh-9.8p1/readconf.h int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-9.8p1.orig/README.md openssh-9.8p1/README.md ---- openssh-9.8p1.orig/README.md 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/README.md 2024-09-30 16:03:39.167245307 +0200 +diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md +--- openssh-9.9p1.orig/README.md 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/README.md 2025-01-20 20:50:04.588813822 +0100 @@ -1,12 +1,16 @@ -# Portable OpenSSH +# HPNSSH: Based on Portable OpenSSH @@ -10954,27 +10954,32 @@ diff -Nur openssh-9.8p1.orig/README.md openssh-9.8p1/README.md ``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. -@@ -44,8 +48,8 @@ +@@ -44,8 +48,9 @@ Releases include a pre-built copy of the ``configure`` script and may be built using: ``` -tar zxvf openssh-X.YpZ.tar.gz -cd openssh +tar zxvf hpnssh-X.YpZ.tar.gz -+cd hpnssh ++cd hpn-ssh ++autoreconf -f -i ./configure # [options] make && make tests ``` -@@ -57,7 +61,7 @@ +@@ -57,9 +62,9 @@ If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: ``` -git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git +-cd openssh-portable +-autoreconf +git clone https://github.com/rapier1/hpn-ssh - cd openssh-portable - autoreconf ++cd hpn-ssh ++autoreconf -f -i ./configure -@@ -76,6 +80,7 @@ + make && make tests + ``` +@@ -76,6 +81,7 @@ ``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp. ``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported. ``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support. @@ -10982,9 +10987,9 @@ diff -Nur openssh-9.8p1.orig/README.md openssh-9.8p1/README.md ## Development -diff -Nur openssh-9.8p1.orig/sandbox-seccomp-filter.c openssh-9.8p1/sandbox-seccomp-filter.c ---- openssh-9.8p1.orig/sandbox-seccomp-filter.c 2024-09-30 16:02:22.576024364 +0200 -+++ openssh-9.8p1/sandbox-seccomp-filter.c 2024-09-30 16:03:39.168245311 +0200 +diff -Nur openssh-9.9p1.orig/sandbox-seccomp-filter.c openssh-9.9p1/sandbox-seccomp-filter.c +--- openssh-9.9p1.orig/sandbox-seccomp-filter.c 2025-01-20 20:48:33.408582135 +0100 ++++ openssh-9.9p1/sandbox-seccomp-filter.c 2025-01-20 20:50:04.589813825 +0100 @@ -295,6 +295,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -11005,9 +11010,9 @@ diff -Nur openssh-9.8p1.orig/sandbox-seccomp-filter.c openssh-9.8p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-9.8p1.orig/scp.1 openssh-9.8p1/scp.1 ---- openssh-9.8p1.orig/scp.1 2024-09-30 16:02:22.541024263 +0200 -+++ openssh-9.8p1/scp.1 2024-10-01 13:10:54.653458405 +0200 +diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 +--- openssh-9.9p1.orig/scp.1 2025-01-20 20:48:33.380582065 +0100 ++++ openssh-9.9p1/scp.1 2025-01-20 22:18:33.595608452 +0100 @@ -18,7 +18,7 @@ .Nd OpenSSH secure file copy .Sh SYNOPSIS @@ -11064,9 +11069,9 @@ diff -Nur openssh-9.8p1.orig/scp.1 openssh-9.8p1/scp.1 .Sh CAVEATS The legacy SCP protocol (selected by the .Fl O -diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c ---- openssh-9.8p1.orig/scp.c 2024-09-30 16:02:22.544024272 +0200 -+++ openssh-9.8p1/scp.c 2024-09-30 16:03:39.170245316 +0200 +diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c +--- openssh-9.9p1.orig/scp.c 2025-01-20 20:48:33.382582070 +0100 ++++ openssh-9.9p1/scp.c 2025-01-21 07:44:00.216159475 +0100 @@ -17,6 +17,7 @@ /* * Copyright (c) 1999 Theo de Raadt. All rights reserved. @@ -11164,7 +11169,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c switch (ch) { /* User-visible flags. */ case '1': -@@ -589,31 +623,43 @@ +@@ -589,24 +623,36 @@ addargs(&remote_remote_args, "-q"); showprogress = 0; break; @@ -11178,80 +11183,52 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c case 'X': /* Please keep in sync with sftp.c -X */ if (strncmp(optarg, "buffer=", 7) == 0) { -- r = scan_scaled(optarg + 7, &llv); + r = scan_scaled(optarg + 7, &llv); - if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { -- r = -1; -- errno = EINVAL; -- } -- if (r == -1) { ++ /* don't ask for a buffer larger than the maximum ++ * size that SFTP can handle */ ++ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { + r = -1; + errno = EINVAL; + } + if (r == -1) { - fatal("Invalid buffer size \"%s\": %s", -- optarg + 7, strerror(errno)); -- } -- sftp_copy_buflen = (size_t)llv; -- } else if (strncmp(optarg, "nrequests=", 10) == 0) { ++ fatal("Invalid buffer size. Must be between 1B and 255KB. \"%s\": %s", + optarg + 7, strerror(errno)); + } + sftp_copy_buflen = (size_t)llv; + } else if (strncmp(optarg, "nrequests=", 10) == 0) { - llv = strtonum(optarg + 10, 1, 256 * 1024, -- &errstr); -- if (errstr != NULL) { ++ /* more than 10k to 15k requests starts stalling the connection ++ * 8192 * default buffer size is 256MB of outstanding data. ++ * if users need more then they need to up the buffer size */ ++ llv = strtonum(optarg + 10, 1, 8 * 1024, + &errstr); + if (errstr != NULL) { - fatal("Invalid number of requests " -- "\"%s\": %s", optarg + 10, errstr); -- } -- sftp_nrequests = (size_t)llv; -- } else { -- fatal("Invalid -X option"); -- } -- break; -+ r = scan_scaled(optarg + 7, &llv); -+ /* don't ask for a buffer larger than the maximum -+ * size that SFTP can handle */ -+ if (r == 0 && (llv <= 0 || llv > (SFTP_MAX_MSG_LENGTH - 1024))) { -+ r = -1; -+ errno = EINVAL; -+ } -+ if (r == -1) { -+ fatal("Invalid buffer size. Must be between 1B and 255KB." -+ "\"%s\": %s", optarg + 7, strerror(errno)); -+ } -+ sftp_copy_buflen = (size_t)llv; -+ } else if (strncmp(optarg, "nrequests=", 10) == 0) { -+ /* more than 10k to 15k requests starts stalling the connection -+ * 8192 * default buffer size is 256MB of outstanding data. -+ * if users need more then they need to up the buffer size */ -+ llv = strtonum(optarg + 10, 1, 8 * 1024, -+ &errstr); -+ if (errstr != NULL) { -+ fatal("Invalid number of requests. Must be between 1 and 8192. " -+ "\"%s\": %s", optarg + 10, errstr); -+ } -+ sftp_nrequests = (size_t)llv; -+ } else { -+ fatal("Invalid -X option"); -+ } -+ break; - - /* Server options. */ - case 'd': ++ fatal("Invalid number of requests. Must be between 1 and 8192. " + "\"%s\": %s", optarg + 10, errstr); + } + sftp_nrequests = (size_t)llv; @@ -694,11 +740,20 @@ remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", -- verbose_mode ? " -v" : "", -- iamrecursive ? " -r" : "", pflag ? " -p" : "", -- targetshouldbedirectory ? " -d" : ""); -- + /* In the event of an hpn to hpn connection the scp + * command is rewritten to hpnscp. This happens in + * clientloop.c -cjr 12/12/2022 */ + + (void) snprintf(cmd, sizeof cmd, "%s%s%s%s%s%s", -+ remote_path ? remote_path : "scp", -+ verbose_mode ? " -v" : "", -+ iamrecursive ? " -r" : "", -+ pflag ? " -p" : "", -+ targetshouldbedirectory ? " -d" : "", -+ resume_flag ? " -Z" : ""); ++ remote_path ? remote_path : "scp", + verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", +- targetshouldbedirectory ? " -d" : ""); ++ targetshouldbedirectory ? " -d" : "", ++ resume_flag ? " -Z" : ""); + +#ifdef DEBUG -+ fprintf(stderr, "%s: Sending cmd %s\n", hostname, cmd); ++ fprintf(stderr, "%s: Sending cmd %s\n", hostname, cmd); +#endif (void) ssh_signal(SIGPIPE, lostconn); @@ -11534,12 +11511,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { -@@ -1670,28 +1933,41 @@ - (sizeof(type) == 8 && (val) > INT64_MAX) || \ - (sizeof(type) != 4 && sizeof(type) != 8)) - -+ - void +@@ -1674,24 +1937,36 @@ sink(int argc, char **argv, const char *src) { static BUF buffer; @@ -11579,7 +11551,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) SCREWUP("Unexpected off_t/time_t size"); -@@ -1707,9 +1983,16 @@ +@@ -1707,9 +1982,16 @@ if (targetshouldbedirectory) verifydir(targ); @@ -11596,11 +11568,9 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (src != NULL && !iamrecursive && !Tflag) { /* * Prepare to try to restrict incoming filenames to match -@@ -1718,7 +2001,12 @@ - if (brace_expand(src, &patterns, &npatterns) != 0) +@@ -1719,6 +2001,10 @@ fatal_f("could not expand pattern"); } -+ for (first = 1;; first = 0) { + bad_match_flag = 0; /* used in resume mode. */ +#ifdef DEBUG @@ -11609,7 +11579,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c cp = buf; if (atomicio(read, remin, cp, 1) != 1) goto done; -@@ -1746,6 +2034,9 @@ +@@ -1746,6 +2032,9 @@ continue; } if (buf[0] == 'E') { @@ -11619,7 +11589,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c (void) atomicio(vwrite, remout, "", 1); goto done; } -@@ -1753,6 +2044,9 @@ +@@ -1753,6 +2042,9 @@ *--cp = 0; cp = buf; @@ -11629,7 +11599,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (*cp == 'T') { setimes++; cp++; -@@ -1780,9 +2074,19 @@ +@@ -1780,9 +2072,19 @@ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); @@ -11649,7 +11619,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". -@@ -1798,6 +2102,18 @@ +@@ -1798,6 +2100,18 @@ SCREWUP("expected control record"); } mode = 0; @@ -11668,7 +11638,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); -@@ -1808,6 +2124,10 @@ +@@ -1808,6 +2122,10 @@ if (*cp++ != ' ') SCREWUP("mode not delimited"); @@ -11679,7 +11649,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (!isdigit((unsigned char)*cp)) SCREWUP("size not present"); ull = strtoull(cp, &cp, 10); -@@ -1817,11 +2137,32 @@ +@@ -1817,11 +2135,32 @@ SCREWUP("size out of range"); size = (off_t)ull; @@ -11712,7 +11682,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (npatterns > 0) { for (n = 0; n < npatterns; n++) { if (strcmp(patterns[n], cp) == 0 || -@@ -1891,11 +2232,195 @@ +@@ -1891,11 +2230,195 @@ } omode = mode; mode |= S_IWUSR; @@ -11881,7 +11851,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c + fprintf(stderr, "%s match status is M\n", hostname); +#endif + bad_match_flag = 0; /* while this is set at the beginning of the -+ * loop I'm setting it here explicitly as well */ ++ * loop I'm setting it here explicitly as well */ + } + } + @@ -11909,7 +11879,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; -@@ -1910,13 +2435,17 @@ +@@ -1910,13 +2433,17 @@ */ statbytes = 0; if (showprogress) @@ -11931,7 +11901,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); -@@ -1951,8 +2480,78 @@ +@@ -1951,8 +2478,78 @@ wrerr = 1; } if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && @@ -11939,7 +11909,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c + ftruncate(ofd, xfer_size) != 0) note_err("%s: truncate: %s", np, strerror(errno)); + -+ /* if np_tmp isn't set then we don't have a resume file to cat */ ++ /* if np_tmp isn't set then we don't have a resume file to cat */ + /* likewise, bad match flag means no resume flag */ +#ifdef DEBUG + fprintf (stderr, "%s: resume_flag: %d, np_tmp: %s, bad_match_flag: %d\n", @@ -12011,7 +11981,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD -@@ -1987,8 +2586,17 @@ +@@ -1987,8 +2584,17 @@ } } /* If no error was noted then signal success for this file */ @@ -12030,7 +12000,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c } done: for (n = 0; n < npatterns; n++) -@@ -2132,11 +2740,20 @@ +@@ -2132,11 +2738,20 @@ void usage(void) { @@ -12051,7 +12021,7 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c } void -@@ -2275,6 +2892,18 @@ +@@ -2275,6 +2890,18 @@ exit(1); } @@ -12070,10 +12040,10 @@ diff -Nur openssh-9.8p1.orig/scp.c openssh-9.8p1/scp.c void cleanup_exit(int i) { -diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c ---- openssh-9.8p1.orig/servconf.c 2024-09-30 16:02:22.620024491 +0200 -+++ openssh-9.8p1/servconf.c 2024-10-01 09:37:00.637000944 +0200 -@@ -214,6 +214,11 @@ +diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c +--- openssh-9.9p1.orig/servconf.c 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/servconf.c 2025-01-20 22:27:14.328008145 +0100 +@@ -215,6 +215,11 @@ options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; @@ -12085,7 +12055,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -504,6 +509,18 @@ +@@ -508,6 +513,18 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -12104,7 +12074,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -584,6 +601,8 @@ +@@ -590,6 +607,8 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -12113,7 +12083,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -791,6 +810,11 @@ +@@ -797,6 +816,11 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -12125,7 +12095,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -854,6 +878,7 @@ +@@ -861,6 +885,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -12133,7 +12103,7 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1573,12 +1598,32 @@ +@@ -1593,12 +1618,32 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -12166,14 +12136,14 @@ diff -Nur openssh-9.8p1.orig/servconf.c openssh-9.8p1/servconf.c case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; -diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h ---- openssh-9.8p1.orig/servconf.h 2024-09-30 16:02:22.621024494 +0200 -+++ openssh-9.8p1/servconf.h 2024-10-01 09:38:49.188317659 +0200 -@@ -225,6 +225,12 @@ +diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h +--- openssh-9.9p1.orig/servconf.h 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/servconf.h 2025-01-20 22:28:39.829229874 +0100 +@@ -226,6 +226,12 @@ char *pam_service_name; int permit_pam_user_change; /* Allow PAM to change user name */ -+ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ ++ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int none_enabled; /* Enable NONE cipher switch */ + int nonemac_enabled; /* Enable NONE MAC switch */ @@ -12182,9 +12152,9 @@ diff -Nur openssh-9.8p1.orig/servconf.h openssh-9.8p1/servconf.h int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-9.8p1.orig/serverloop.c openssh-9.8p1/serverloop.c ---- openssh-9.8p1.orig/serverloop.c 2024-09-30 16:02:22.607024453 +0200 -+++ openssh-9.8p1/serverloop.c 2024-10-01 09:39:20.858410057 +0200 +diff -Nur openssh-9.9p1.orig/serverloop.c openssh-9.9p1/serverloop.c +--- openssh-9.9p1.orig/serverloop.c 2025-01-20 20:48:33.440582216 +0100 ++++ openssh-9.9p1/serverloop.c 2025-01-20 22:30:36.463532350 +0100 @@ -81,6 +81,8 @@ #include "serverloop.h" #include "ssherr.h" @@ -12306,9 +12276,9 @@ diff -Nur openssh-9.8p1.orig/serverloop.c openssh-9.8p1/serverloop.c } /* XXX sshpkt_get_end() */ if (want_reply) { -diff -Nur openssh-9.8p1.orig/session.c openssh-9.8p1/session.c ---- openssh-9.8p1.orig/session.c 2024-09-30 16:02:22.566024335 +0200 -+++ openssh-9.8p1/session.c 2024-09-30 16:03:39.174245328 +0200 +diff -Nur openssh-9.9p1.orig/session.c openssh-9.9p1/session.c +--- openssh-9.9p1.orig/session.c 2025-01-20 20:48:33.402582120 +0100 ++++ openssh-9.9p1/session.c 2025-01-20 20:50:04.595813840 +0100 @@ -94,6 +94,7 @@ #include "monitor_wrap.h" #include "sftp.h" @@ -12345,9 +12315,9 @@ diff -Nur openssh-9.8p1.orig/session.c openssh-9.8p1/session.c return 0; } -diff -Nur openssh-9.8p1.orig/sftp.1 openssh-9.8p1/sftp.1 ---- openssh-9.8p1.orig/sftp.1 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/sftp.1 2024-10-01 11:22:00.648462200 +0200 +diff -Nur openssh-9.9p1.orig/sftp.1 openssh-9.9p1/sftp.1 +--- openssh-9.9p1.orig/sftp.1 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sftp.1 2025-01-20 20:50:04.595813840 +0100 @@ -299,7 +299,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed @@ -12373,15 +12343,11 @@ diff -Nur openssh-9.8p1.orig/sftp.1 openssh-9.8p1/sftp.1 By default a 32KB buffer is used. .El .El -diff -Nur openssh-9.8p1.orig/sftp.c openssh-9.8p1/sftp.c ---- openssh-9.8p1.orig/sftp.c 2024-09-30 16:02:22.545024274 +0200 -+++ openssh-9.8p1/sftp.c 2024-10-01 09:50:10.979301433 +0200 -@@ -2566,23 +2566,28 @@ - replacearg(&args, 0, "%s", ssh_program); - break; - case 'X': -- /* Please keep in sync with ssh.c -X */ -+ /* Please keep in sync with scp.c -X */ +diff -Nur openssh-9.9p1.orig/sftp.c openssh-9.9p1/sftp.c +--- openssh-9.9p1.orig/sftp.c 2025-01-20 20:48:33.383582072 +0100 ++++ openssh-9.9p1/sftp.c 2025-01-20 20:50:04.596813843 +0100 +@@ -2569,20 +2569,25 @@ + /* Please keep in sync with ssh.c -X */ if (strncmp(optarg, "buffer=", 7) == 0) { r = scan_scaled(optarg + 7, &llv); - if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { @@ -12411,9 +12377,9 @@ diff -Nur openssh-9.8p1.orig/sftp.c openssh-9.8p1/sftp.c "\"%s\": %s", optarg + 10, errstr); } num_requests = (size_t)llv; -diff -Nur openssh-9.8p1.orig/sftp-client.c openssh-9.8p1/sftp-client.c ---- openssh-9.8p1.orig/sftp-client.c 2024-09-30 16:02:22.545024274 +0200 -+++ openssh-9.8p1/sftp-client.c 2024-09-30 16:03:39.175245331 +0200 +diff -Nur openssh-9.9p1.orig/sftp-client.c openssh-9.9p1/sftp-client.c +--- openssh-9.9p1.orig/sftp-client.c 2025-01-20 20:48:33.382582070 +0100 ++++ openssh-9.9p1/sftp-client.c 2025-01-20 20:50:04.596813843 +0100 @@ -72,7 +72,8 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -12424,9 +12390,9 @@ diff -Nur openssh-9.8p1.orig/sftp-client.c openssh-9.8p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 ---- openssh-9.8p1.orig/ssh.1 2024-09-30 16:02:22.622024497 +0200 -+++ openssh-9.8p1/ssh.1 2024-09-30 16:35:12.408708175 +0200 +diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +--- openssh-9.9p1.orig/ssh.1 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/ssh.1 2025-01-20 21:06:00.112249282 +0100 @@ -77,6 +77,14 @@ X11 connections, arbitrary TCP ports and .Ux Ns -domain @@ -12442,7 +12408,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .Pp .Nm connects and logs into the specified -@@ -524,11 +532,13 @@ +@@ -526,11 +534,13 @@ .It ControlMaster .It ControlPath .It ControlPersist @@ -12456,7 +12422,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .It FingerprintHash .It ForkAfterAuthentication .It ForwardAgent -@@ -552,6 +562,7 @@ +@@ -554,6 +564,7 @@ .It HostKeyAlgorithms .It HostKeyAlias .It Hostname @@ -12464,7 +12430,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .It IdentitiesOnly .It IdentityAgent .It IdentityFile -@@ -568,7 +579,13 @@ +@@ -570,7 +581,13 @@ .It LogVerbose .It MACs .It Match @@ -12478,7 +12444,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .It NumberOfPasswordPrompts .It PasswordAuthentication .It PermitLocalCommand -@@ -599,6 +616,7 @@ +@@ -601,6 +618,7 @@ .It StrictHostKeyChecking .It SyslogFacility .It TCPKeepAlive @@ -12486,7 +12452,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .It Tunnel .It TunnelDevice .It UpdateHostKeys -@@ -607,6 +625,8 @@ +@@ -609,6 +627,8 @@ .It VerifyHostKeyDNS .It VisualHostKey .It XAuthLocation @@ -12495,7 +12461,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .El .Pp .It Fl P Ar tag -@@ -623,6 +643,13 @@ +@@ -625,6 +645,13 @@ Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. @@ -12509,7 +12475,7 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 .Pp .It Fl Q Ar query_option Queries for the algorithms supported by one of the following features: -@@ -1814,3 +1841,7 @@ +@@ -1816,3 +1843,7 @@ created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -12517,10 +12483,10 @@ diff -Nur openssh-9.8p1.orig/ssh.1 openssh-9.8p1/ssh.1 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-9.8p1.orig/ssh_api.c openssh-9.8p1/ssh_api.c ---- openssh-9.8p1.orig/ssh_api.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/ssh_api.c 2024-09-30 16:03:39.177245336 +0200 -@@ -425,7 +425,7 @@ +diff -Nur openssh-9.9p1.orig/ssh_api.c openssh-9.9p1/ssh_api.c +--- openssh-9.9p1.orig/ssh_api.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/ssh_api.c 2025-01-20 20:50:04.598813848 +0100 +@@ -427,7 +427,7 @@ char *cp; int r; @@ -12529,9 +12495,9 @@ diff -Nur openssh-9.8p1.orig/ssh_api.c openssh-9.8p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-9.8p1.orig/sshbuf.c openssh-9.8p1/sshbuf.c ---- openssh-9.8p1.orig/sshbuf.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/sshbuf.c 2024-09-30 16:03:39.177245336 +0200 +diff -Nur openssh-9.9p1.orig/sshbuf.c openssh-9.9p1/sshbuf.c +--- openssh-9.9p1.orig/sshbuf.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshbuf.c 2025-01-20 20:50:04.598813848 +0100 @@ -27,6 +27,9 @@ #define SSHBUF_INTERNAL #include "sshbuf.h" @@ -12572,7 +12538,7 @@ diff -Nur openssh-9.8p1.orig/sshbuf.c openssh-9.8p1/sshbuf.c static inline int sshbuf_check_sanity(const struct sshbuf *buf) { -@@ -89,7 +113,7 @@ +@@ -90,7 +114,7 @@ } struct sshbuf * @@ -12581,7 +12547,7 @@ diff -Nur openssh-9.8p1.orig/sshbuf.c openssh-9.8p1/sshbuf.c { struct sshbuf *ret; -@@ -100,6 +124,8 @@ +@@ -101,6 +125,8 @@ ret->readonly = 0; ret->refcount = 1; ret->parent = NULL; @@ -12648,10 +12614,10 @@ diff -Nur openssh-9.8p1.orig/sshbuf.c openssh-9.8p1/sshbuf.c SSHBUF_DBG(("adjusted rlen %zu", rlen)); if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) { SSHBUF_DBG(("realloc fail")); -diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h ---- openssh-9.8p1.orig/sshbuf.h 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/sshbuf.h 2024-09-30 16:03:39.177245336 +0200 -@@ -28,18 +28,49 @@ +diff -Nur openssh-9.9p1.orig/sshbuf.h openssh-9.9p1/sshbuf.h +--- openssh-9.9p1.orig/sshbuf.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshbuf.h 2025-01-20 20:50:04.598813848 +0100 +@@ -29,18 +29,49 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -12660,7 +12626,7 @@ diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ -+#define MAX_LABEL_LEN 64 /*maximum size of sshbuf label */ ++#define MAX_LABEL_LEN 64 /*maximum size of sshbuf label */ +#define sshbuf_new() sshbuf_new_label(__func__) struct sshbuf; @@ -12703,7 +12669,7 @@ diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h /* * Create a new, read-only sshbuf buffer from existing data. -@@ -75,12 +106,13 @@ +@@ -76,12 +107,13 @@ void sshbuf_reset(struct sshbuf *buf); /* @@ -12719,7 +12685,7 @@ diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size); -@@ -344,6 +376,9 @@ +@@ -346,6 +378,9 @@ ((u_char *)(p))[1] = __v & 0xff; \ } while (0) @@ -12729,9 +12695,9 @@ diff -Nur openssh-9.8p1.orig/sshbuf.h openssh-9.8p1/sshbuf.h /* Internal definitions follow. Exposed for regress tests */ #ifdef SSHBUF_INTERNAL -diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c ---- openssh-9.8p1.orig/ssh.c 2024-09-30 16:02:22.622024497 +0200 -+++ openssh-9.8p1/ssh.c 2024-09-30 16:03:39.178245339 +0200 +diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c +--- openssh-9.9p1.orig/ssh.c 2025-01-20 20:48:33.454582252 +0100 ++++ openssh-9.9p1/ssh.c 2025-01-20 20:50:04.599813850 +0100 @@ -109,6 +109,7 @@ #include "ssherr.h" #include "myproposal.h" @@ -12907,9 +12873,9 @@ diff -Nur openssh-9.8p1.orig/ssh.c openssh-9.8p1/ssh.c } return client_loop(ssh, tty_flag, tty_flag ? -diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 ---- openssh-9.8p1.orig/ssh_config.5 2024-09-30 16:02:22.623024499 +0200 -+++ openssh-9.8p1/ssh_config.5 2024-09-30 16:03:39.179245342 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1.orig/ssh_config.5 2025-01-20 20:48:33.454582252 +0100 ++++ openssh-9.9p1/ssh_config.5 2025-01-20 20:50:04.600813853 +0100 @@ -62,6 +62,19 @@ .Pq Pa /etc/ssh/ssh_config .El @@ -12952,7 +12918,7 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 .It Cm IdentitiesOnly Specifies that .Xr ssh 1 -@@ -1497,6 +1518,63 @@ +@@ -1502,6 +1523,63 @@ .Pp The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -13016,7 +12982,7 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 .It Cm NoHostAuthenticationForLocalhost Disable host authentication for localhost (loopback addresses). The argument to this keyword must be -@@ -1504,6 +1582,36 @@ +@@ -1509,6 +1587,36 @@ or .Cm no (the default). @@ -13053,7 +13019,7 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. -@@ -2061,6 +2169,12 @@ +@@ -2066,6 +2174,12 @@ Specify a configuration tag name that may be later used by a .Cm Match directive to select a block of configuration. @@ -13066,7 +13032,7 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 .It Cm Tunnel Request .Xr tun 4 -@@ -2417,3 +2531,11 @@ +@@ -2424,3 +2538,11 @@ created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -13078,9 +13044,9 @@ diff -Nur openssh-9.8p1.orig/ssh_config.5 openssh-9.8p1/ssh_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c ---- openssh-9.8p1.orig/sshconnect2.c 2024-09-30 16:02:22.623024499 +0200 -+++ openssh-9.8p1/sshconnect2.c 2024-09-30 16:03:39.180245345 +0200 +diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c +--- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 20:48:33.455582254 +0100 ++++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:50:04.601813855 +0100 @@ -76,6 +76,7 @@ #include "utf8.h" #include "ssh-sk.h" @@ -13103,7 +13069,7 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c * SSH2 key exchange */ -@@ -573,6 +581,42 @@ +@@ -574,6 +582,42 @@ if (!authctxt.success) fatal("Authentication failed."); @@ -13146,10 +13112,10 @@ diff -Nur openssh-9.8p1.orig/sshconnect2.c openssh-9.8p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 ---- openssh-9.8p1.orig/sshd.8 2024-09-30 16:02:22.624024502 +0200 -+++ openssh-9.8p1/sshd.8 2024-09-30 16:03:39.181245348 +0200 -@@ -1075,3 +1075,7 @@ +diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 +--- openssh-9.9p1.orig/sshd.8 2025-01-20 20:48:33.455582254 +0100 ++++ openssh-9.9p1/sshd.8 2025-01-20 20:50:04.601813855 +0100 +@@ -1079,3 +1079,7 @@ protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. @@ -13157,10 +13123,10 @@ diff -Nur openssh-9.8p1.orig/sshd.8 openssh-9.8p1/sshd.8 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-9.8p1.orig/sshd.c openssh-9.8p1/sshd.c ---- openssh-9.8p1.orig/sshd.c 2024-09-30 16:02:22.578024370 +0200 -+++ openssh-9.8p1/sshd.c 2024-09-30 16:03:39.182245351 +0200 -@@ -753,6 +753,8 @@ +diff -Nur openssh-9.9p1.orig/sshd.c openssh-9.9p1/sshd.c +--- openssh-9.9p1.orig/sshd.c 2025-01-20 20:48:33.410582141 +0100 ++++ openssh-9.9p1/sshd.c 2025-01-20 20:50:04.602813858 +0100 +@@ -760,6 +760,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -13169,7 +13135,7 @@ diff -Nur openssh-9.8p1.orig/sshd.c openssh-9.8p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -798,6 +800,10 @@ +@@ -805,6 +807,10 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -13180,7 +13146,7 @@ diff -Nur openssh-9.8p1.orig/sshd.c openssh-9.8p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1421,6 +1427,19 @@ +@@ -1428,6 +1434,19 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -13200,18 +13166,19 @@ diff -Nur openssh-9.8p1.orig/sshd.c openssh-9.8p1/sshd.c /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && -diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config ---- openssh-9.8p1.orig/sshd_config 2024-09-30 16:02:22.624024502 +0200 -+++ openssh-9.8p1/sshd_config 2024-10-02 15:40:20.779644727 +0200 -@@ -19,6 +19,7 @@ +diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config +--- openssh-9.9p1.orig/sshd_config 2025-01-20 20:48:33.456582257 +0100 ++++ openssh-9.9p1/sshd_config 2025-01-20 21:06:55.293389906 +0100 +@@ -18,7 +18,7 @@ + # SELinux about this change. # semanage port -a -t ssh_port_t -p tcp #PORTNUMBER # - #Port 22 +-#Port 22 +Port 2222 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: -@@ -127,6 +128,19 @@ +@@ -127,6 +127,19 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -13231,9 +13198,9 @@ diff -Nur openssh-9.8p1.orig/sshd_config openssh-9.8p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 ---- openssh-9.8p1.orig/sshd_config.5 2024-09-30 16:02:22.624024502 +0200 -+++ openssh-9.8p1/sshd_config.5 2024-09-30 16:03:39.183245354 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 +--- openssh-9.9p1.orig/sshd_config.5 2025-01-20 20:48:33.456582257 +0100 ++++ openssh-9.9p1/sshd_config.5 2025-01-20 20:50:04.604813863 +0100 @@ -56,6 +56,16 @@ .Pq \&" in order to represent arguments containing spaces. @@ -13274,7 +13241,7 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 .It Cm IgnoreRhosts Specifies whether to ignore per-user .Pa .rhosts -@@ -1408,6 +1427,19 @@ +@@ -1415,6 +1434,19 @@ key exchange methods. The default is .Pa /etc/moduli . @@ -13294,7 +13261,7 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 .It Cm PAMServiceName Specifies the service name used for Pluggable Authentication Modules (PAM) authentication, authorisation and session controls when -@@ -1952,6 +1984,13 @@ +@@ -1976,6 +2008,13 @@ .Pp To disable TCP keepalive messages, the value should be set to .Cm no . @@ -13308,7 +13275,7 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -2250,3 +2289,11 @@ +@@ -2274,3 +2313,11 @@ and .An Markus Friedl contributed support for privilege separation. @@ -13320,10 +13287,10 @@ diff -Nur openssh-9.8p1.orig/sshd_config.5 openssh-9.8p1/sshd_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c ---- openssh-9.8p1.orig/sshd-session.c 2024-09-30 16:02:22.625024505 +0200 -+++ openssh-9.8p1/sshd-session.c 2024-09-30 16:03:39.184245357 +0200 -@@ -1158,6 +1158,20 @@ +diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c +--- openssh-9.9p1.orig/sshd-session.c 2025-01-20 20:48:33.457582259 +0100 ++++ openssh-9.9p1/sshd-session.c 2025-01-20 20:50:04.604813863 +0100 +@@ -1196,6 +1196,20 @@ } endpwent(); @@ -13344,7 +13311,7 @@ diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c if (!debug_flag) { startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); close(REEXEC_STARTUP_PIPE_FD); -@@ -1365,6 +1379,9 @@ +@@ -1403,6 +1417,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -13354,7 +13321,7 @@ diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -1525,6 +1542,11 @@ +@@ -1575,6 +1592,11 @@ struct kex *kex; int r; @@ -13366,9 +13333,9 @@ diff -Nur openssh-9.8p1.orig/sshd-session.c openssh-9.8p1/sshd-session.c if (options.rekey_limit || options.rekey_interval) ssh_packet_set_rekey_limits(ssh, options.rekey_limit, options.rekey_interval); -diff -Nur openssh-9.8p1.orig/ssh.h openssh-9.8p1/ssh.h ---- openssh-9.8p1.orig/ssh.h 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/ssh.h 2024-09-30 16:03:39.185245360 +0200 +diff -Nur openssh-9.9p1.orig/ssh.h openssh-9.9p1/ssh.h +--- openssh-9.9p1.orig/ssh.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/ssh.h 2025-01-20 20:50:04.605813865 +0100 @@ -17,6 +17,7 @@ /* Default port number. */ @@ -13386,10 +13353,10 @@ diff -Nur openssh-9.8p1.orig/ssh.h openssh-9.8p1/ssh.h /* * Name of the environment variable containing the process ID of the -diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c ---- openssh-9.8p1.orig/sshkey.c 2024-09-30 16:02:22.579024372 +0200 -+++ openssh-9.8p1/sshkey.c 2024-09-30 16:03:39.185245360 +0200 -@@ -1784,7 +1784,8 @@ +diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c +--- openssh-9.9p1.orig/sshkey.c 2025-01-20 20:48:33.411582143 +0100 ++++ openssh-9.9p1/sshkey.c 2025-01-20 20:50:04.606813868 +0100 +@@ -1778,7 +1778,8 @@ stderr); #endif if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13399,7 +13366,7 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c goto out; /* Serialise and encrypt the private key using the ephemeral key */ -@@ -1919,7 +1920,8 @@ +@@ -1913,7 +1914,8 @@ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13409,7 +13376,7 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c goto out; #ifdef DEBUG_PK fprintf(stderr, "%s: key+iv\n", __func__); -@@ -2987,6 +2989,13 @@ +@@ -2981,6 +2983,13 @@ kdfname = "none"; } else if (ciphername == NULL) ciphername = DEFAULT_CIPHERNAME; @@ -13423,7 +13390,7 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; -@@ -3022,7 +3031,7 @@ +@@ -3016,7 +3025,7 @@ goto out; } if ((r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13432,7 +13399,7 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c goto out; if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || -@@ -3209,6 +3218,8 @@ +@@ -3203,6 +3212,8 @@ (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) goto out; @@ -13441,7 +13408,7 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; -@@ -3264,7 +3275,7 @@ +@@ -3258,7 +3269,7 @@ /* decrypt private portion of key */ if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || (r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13450,9 +13417,9 @@ diff -Nur openssh-9.8p1.orig/sshkey.c openssh-9.8p1/sshkey.c goto out; if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), encrypted_len, 0, authlen)) != 0) { -diff -Nur openssh-9.8p1.orig/sshkey-xmss.c openssh-9.8p1/sshkey-xmss.c ---- openssh-9.8p1.orig/sshkey-xmss.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/sshkey-xmss.c 2024-09-30 16:03:39.186245362 +0200 +diff -Nur openssh-9.9p1.orig/sshkey-xmss.c openssh-9.9p1/sshkey-xmss.c +--- openssh-9.9p1.orig/sshkey-xmss.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshkey-xmss.c 2025-01-20 20:50:04.606813868 +0100 @@ -903,9 +903,29 @@ state->enc_keyiv == NULL || state->enc_ciphername == NULL) @@ -13537,9 +13504,9 @@ diff -Nur openssh-9.8p1.orig/sshkey-xmss.c openssh-9.8p1/sshkey-xmss.c (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), encrypted_len, aadlen, authlen)) != 0) goto out; -diff -Nur openssh-9.8p1.orig/umac.c openssh-9.8p1/umac.c ---- openssh-9.8p1.orig/umac.c 2024-07-01 06:36:28.000000000 +0200 -+++ openssh-9.8p1/umac.c 2024-10-01 09:50:36.972376774 +0200 +diff -Nur openssh-9.9p1.orig/umac.c openssh-9.9p1/umac.c +--- openssh-9.9p1.orig/umac.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/umac.c 2025-01-20 20:50:04.607813871 +0100 @@ -134,15 +134,48 @@ /* --- Endian Conversion --- Forcing assembly on some platforms */ /* ---------------------------------------------------------------------- */ @@ -13592,9 +13559,9 @@ diff -Nur openssh-9.8p1.orig/umac.c openssh-9.8p1/umac.c #define STORE_UINT32_BIG(p,v) put_u32(p, v) /* ---------------------------------------------------------------------- */ -diff -Nur openssh-9.8p1.orig/uthash.h openssh-9.8p1/uthash.h ---- openssh-9.8p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.8p1/uthash.h 2024-09-30 16:03:39.187245365 +0200 +diff -Nur openssh-9.9p1.orig/uthash.h openssh-9.9p1/uthash.h +--- openssh-9.9p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/uthash.h 2025-01-20 20:50:04.608813873 +0100 @@ -0,0 +1,1140 @@ +/* +Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ @@ -14736,14 +14703,14 @@ diff -Nur openssh-9.8p1.orig/uthash.h openssh-9.8p1/uthash.h +} UT_hash_handle; + +#endif /* UTHASH_H */ -diff -Nur openssh-9.8p1.orig/version.h openssh-9.8p1/version.h ---- openssh-9.8p1.orig/version.h 2024-09-30 16:02:22.625024505 +0200 -+++ openssh-9.8p1/version.h 2024-10-01 10:07:08.736253374 +0200 +diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h +--- openssh-9.9p1.orig/version.h 2025-01-20 20:48:33.457582259 +0100 ++++ openssh-9.9p1/version.h 2025-01-20 21:09:18.648755010 +0100 @@ -16,5 +16,6 @@ #define SSH_PORTABLE "p1" #define GSI_PORTABLE "c-GSI" -+#define SSH_HPN "_hpn18.5.1" - #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ -- GSI_VERSION KRB5_VERSION -+ GSI_VERSION KRB5_VERSION SSH_HPN +-#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ ++#define SSH_HPN "_hpn18.6.0" ++#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE SSH_HPN \ + GSI_VERSION KRB5_VERSION diff --git a/openssh-9.9p1-mlkembe.patch b/openssh-9.9p1-mlkembe.patch new file mode 100644 index 0000000..aa0c26c --- /dev/null +++ b/openssh-9.9p1-mlkembe.patch @@ -0,0 +1,98 @@ +diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c +index 679446e9..2b5d3960 100644 +--- a/kexmlkem768x25519.c ++++ b/kexmlkem768x25519.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: kexmlkem768x25519.c,v 1.1 2024/09/02 12:13:56 djm Exp $ */ ++/* $OpenBSD: kexmlkem768x25519.c,v 1.2 2024/10/27 02:06:59 djm Exp $ */ + /* + * Copyright (c) 2023 Markus Friedl. All rights reserved. + * +@@ -34,6 +34,9 @@ + #include + #include + #include ++#ifdef HAVE_ENDIAN_H ++# include ++#endif + + #include "sshkey.h" + #include "kex.h" +diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h +index a82d60e8..b8ac1436 100644 +--- a/libcrux_mlkem768_sha3.h ++++ b/libcrux_mlkem768_sha3.h +@@ -1,4 +1,5 @@ +-/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.1 2024/09/02 12:13:56 djm Exp $ */ ++/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.2 2024/10/27 02:06:01 djm Exp $ */ ++ + /* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */ + + /* +@@ -160,18 +161,19 @@ static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, + // CORE STUFF (conversions, endianness, ...) + + static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { ++ v = htole64(v); + memcpy(buf, &v, sizeof(v)); + } + static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + uint64_t v; + memcpy(&v, buf, sizeof(v)); +- return v; ++ return le64toh(v); + } + + static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { + uint32_t v; + memcpy(&v, buf, sizeof(v)); +- return v; ++ return le32toh(v); + } + + static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +diff --git a/mlkem768.sh b/mlkem768.sh +index 2fdc2831..3d12b2ed 100644 +--- a/mlkem768.sh ++++ b/mlkem768.sh +@@ -1,9 +1,10 @@ + #!/bin/sh +-# $OpenBSD: mlkem768.sh,v 1.2 2024/09/04 05:11:33 djm Exp $ ++# $OpenBSD: mlkem768.sh,v 1.3 2024/10/27 02:06:01 djm Exp $ + # Placed in the Public Domain. + # + +-WANT_LIBCRUX_REVISION="origin/main" ++#WANT_LIBCRUX_REVISION="origin/main" ++WANT_LIBCRUX_REVISION="84c5d87b3092c59294345aa269ceefe0eb97cc35" + + FILES=" + libcrux/libcrux-ml-kem/cg/eurydice_glue.h +@@ -47,6 +48,7 @@ echo '#define KRML_NOINLINE __attribute__((noinline, unused))' + echo '#define KRML_HOST_EPRINTF(...)' + echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' + echo ++ + for i in $FILES; do + echo "/* from $i */" + # Changes to all files: +@@ -56,11 +58,16 @@ for i in $FILES; do + -e 's/[ ]*$//' \ + $i | \ + case "$i" in +- # XXX per-file handling goes here. ++ */libcrux-ml-kem/cg/eurydice_glue.h) ++ # Replace endian functions with versions that work. ++ perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | ++ perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | ++ perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' ++ ;; + # Default: pass through. + *) +- cat +- ;; ++ cat ++ ;; + esac + echo + done diff --git a/openssh-9.9p1-separate-keysign.patch b/openssh-9.9p1-separate-keysign.patch new file mode 100644 index 0000000..ff0e35f --- /dev/null +++ b/openssh-9.9p1-separate-keysign.patch @@ -0,0 +1,12 @@ +diff -up openssh-9.9p1/ssh_config.5.xxx openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1/ssh_config.5.xxx 2024-10-11 12:01:14.260566303 +0200 ++++ openssh-9.9p1/ssh_config.5 2024-10-11 12:01:59.725654775 +0200 +@@ -759,7 +759,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 ~ ) . diff --git a/sources b/sources index 1f1ded8..e88b6d9 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-9.8p1.tar.gz) = 95dec2f18e58eb47994f3de4430253e0665e185564b65088ca5f4108870e05feddef8cda8d3c0a4b75f18b98cc2c024df0e27de53b48c1a16da8da483cb8292a -SHA512 (openssh-9.8p1.tar.gz.asc) = 4df1f1be2c6ab7f3aebaedd0a773b0e8c8929abb30cd3415873ad55d012cfa113f792e888e5e772dd468c394aeb7e35d62893a514dbc0ab1a03acd79918657f7 +SHA512 (openssh-9.9p1.tar.gz) = 3cc0ed97f3e29ecbd882eca79239f02eb5a1606fce4f3119ddc3c5e86128aa3ff12dc85000879fccc87b60e7d651cfe37376607ac66075fede2118deaa685d6d +SHA512 (openssh-9.9p1.tar.gz.asc) = 916e975c54eb68c0b2f0b0006522b241cbe54c4caa88d31537a6278490c93d9d732c2ab3a080ac084bf75cbdd5402901ec68583cbe7c7cde4a8e40e7a8b78c28 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 9e253dc61c0bc1969af2d2767bb109fd7cf999b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 1 Feb 2025 19:54:26 +0100 Subject: [PATCH 135/146] Add explicit BR: libxcrypt-devel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- gsi-openssh.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 1060509..def41e3 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -29,7 +29,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: %{openssh_rel}%{?dist}.1 Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -199,6 +199,7 @@ BuildRequires: systemd-rpm-macros BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel +BuildRequires: libxcrypt-devel Recommends: p11-kit %if %{kerberos5} @@ -571,6 +572,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Sat Feb 01 2025 Björn Esser - 9.9p1-1.1 +- Add explicit BR: libxcrypt-devel + * Mon Jan 20 2025 Mattias Ellert - 9.9p1-1 - Based on openssh-9.9p1-5.fc42 / openssh-9.9p1-1.fc41 From 3c2a11925bfca5fad2682c0581a8fe607423a5f0 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 5 Feb 2025 11:43:01 +0100 Subject: [PATCH 136/146] Based on openssh-9.9p1-7.fc42 / openssh-9.9p1-2.fc41 --- gsi-openssh.spec | 12 +- openssh-9.9p1-match-regression.patch | 463 +++++++++++++++++++++++++++ 2 files changed, 472 insertions(+), 3 deletions(-) create mode 100644 openssh-9.9p1-match-regression.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index def41e3..01f1110 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,12 +24,12 @@ %global libedit 1 %global openssh_ver 9.9p1 -%global openssh_rel 1 +%global openssh_rel 2 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -177,6 +177,9 @@ Patch1016: openssh-9.9p1-separate-keysign.patch # upstream cf3e48ee8ba1beeccddd2f203b558fa102be67a2 # upstream 0c3927c45f8a57b511c874c4d51a8c89414f74ef Patch1017: openssh-9.9p1-mlkembe.patch +# upstream 3f02368e8e9121847727c46b280efc280e5eb615 +# upstream 67a115e7a56dbdc3f5a58c64b29231151f3670f5 +Patch1020: openssh-9.9p1-match-regression.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -347,6 +350,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 1015 -p1 -b .pam-rhost %patch -P 1016 -p1 -b .sep-keysign %patch -P 1017 -p1 -b .mlkembe +%patch -P 1020 -p1 -b .match %patch -P 100 -p1 -b .coverity %patch -P 98 -p1 -b .gsi @@ -362,7 +366,6 @@ autoreconf %build %set_build_flags -CFLAGS="$CFLAGS"; export CFLAGS %if %{pie} %ifarch s390 s390x sparc sparcv9 sparc64 CFLAGS="$CFLAGS -fPIC" @@ -572,6 +575,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Wed Feb 05 2025 Mattias Ellert - 9.9p1-2 +- Based on openssh-9.9p1-7.fc42 / openssh-9.9p1-2.fc41 + * Sat Feb 01 2025 Björn Esser - 9.9p1-1.1 - Add explicit BR: libxcrypt-devel diff --git a/openssh-9.9p1-match-regression.patch b/openssh-9.9p1-match-regression.patch new file mode 100644 index 0000000..d724401 --- /dev/null +++ b/openssh-9.9p1-match-regression.patch @@ -0,0 +1,463 @@ +diff --git a/misc.c b/misc.c +index afdf5142..1b4b55c5 100644 +--- a/misc.c ++++ b/misc.c +@@ -107,6 +107,27 @@ rtrim(char *s) + } + } + ++/* ++ * returns pointer to character after 'prefix' in 's' or otherwise NULL ++ * if the prefix is not present. ++ */ ++const char * ++strprefix(const char *s, const char *prefix, int ignorecase) ++{ ++ size_t prefixlen; ++ ++ if ((prefixlen = strlen(prefix)) == 0) ++ return s; ++ if (ignorecase) { ++ if (strncasecmp(s, prefix, prefixlen) != 0) ++ return NULL; ++ } else { ++ if (strncmp(s, prefix, prefixlen) != 0) ++ return NULL; ++ } ++ return s + prefixlen; ++} ++ + /* set/unset filedescriptor to non-blocking */ + int + set_nonblock(int fd) +diff --git a/misc.h b/misc.h +index 11340389..efecdf1a 100644 +--- a/misc.h ++++ b/misc.h +@@ -56,6 +56,7 @@ struct ForwardOptions { + char *chop(char *); + void rtrim(char *); + void skip_space(char **); ++const char *strprefix(const char *, const char *, int); + char *strdelim(char **); + char *strdelimw(char **); + int set_nonblock(int); +diff --git a/readconf.c b/readconf.c +index 3d9cc6db..9f559269 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -710,7 +710,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + struct passwd *pw, const char *host_arg, const char *original_host, + int final_pass, int *want_final_pass, const char *filename, int linenum) + { +- char *arg, *oattrib, *attrib, *cmd, *host, *criteria; ++ char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; + const char *ruser; + int r, this_result, result = 1, attributes = 0, negate; + +@@ -731,7 +731,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + + debug2("checking match for '%s' host %s originally %s", + full_line, host, original_host); +- while ((oattrib = attrib = argv_next(acp, avp)) != NULL) { ++ while ((attrib = argv_next(acp, avp)) != NULL) { ++ attrib = oattrib = xstrdup(attrib); + /* Terminate on comment */ + if (*attrib == '#') { + argv_consume(acp); +@@ -777,9 +778,23 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + this_result ? "" : "not ", oattrib); + continue; + } ++ ++ /* Keep this list in sync with below */ ++ if (strprefix(attrib, "host=", 1) != NULL || ++ strprefix(attrib, "originalhost=", 1) != NULL || ++ strprefix(attrib, "user=", 1) != NULL || ++ strprefix(attrib, "localuser=", 1) != NULL || ++ strprefix(attrib, "localnetwork=", 1) != NULL || ++ strprefix(attrib, "tagged=", 1) != NULL || ++ strprefix(attrib, "exec=", 1) != NULL) { ++ arg = strchr(attrib, '='); ++ *(arg++) = '\0'; ++ } else { ++ arg = argv_next(acp, avp); ++ } ++ + /* All other criteria require an argument */ +- if ((arg = argv_next(acp, avp)) == NULL || +- *arg == '\0' || *arg == '#') { ++ if (arg == NULL || *arg == '\0' || *arg == '#') { + error("Missing Match criteria for %s", attrib); + result = -1; + goto out; +@@ -856,6 +871,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + criteria == NULL ? "" : criteria, + criteria == NULL ? "" : "\""); + free(criteria); ++ free(oattrib); ++ oattrib = attrib = NULL; + } + if (attributes == 0) { + error("One or more attributes required for Match"); +@@ -865,6 +882,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + out: + if (result != -1) + debug2("match %sfound", result ? "" : "not "); ++ free(oattrib); + free(host); + return result; + } +diff --git a/servconf.c b/servconf.c +index 89b8413e..dd774f46 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: servconf.c,v 1.418 2024/09/15 03:09:44 djm Exp $ */ ++/* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */ + /* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved +@@ -1033,7 +1033,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + int line, struct connection_info *ci) + { + int result = 1, attributes = 0, port; +- char *arg, *attrib; ++ char *arg, *attrib = NULL, *oattrib; + + if (ci == NULL) + debug3("checking syntax for 'Match %s'", full_line); +@@ -1047,7 +1047,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + ci->laddress ? ci->laddress : "(null)", ci->lport); + } + +- while ((attrib = argv_next(acp, avp)) != NULL) { ++ while ((oattrib = argv_next(acp, avp)) != NULL) { ++ attrib = xstrdup(oattrib); + /* Terminate on comment */ + if (*attrib == '#') { + argv_consume(acp); /* mark all arguments consumed */ +@@ -1062,11 +1063,13 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + *arg != '\0' && *arg != '#')) { + error("'all' cannot be combined with other " + "Match attributes"); +- return -1; ++ result = -1; ++ goto out; + } + if (arg != NULL && *arg == '#') + argv_consume(acp); /* consume remaining args */ +- return 1; ++ result = 1; ++ goto out; + } + /* Criterion "invalid-user" also has no argument */ + if (strcasecmp(attrib, "invalid-user") == 0) { +@@ -1078,11 +1081,26 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + debug("matched invalid-user at line %d", line); + continue; + } ++ ++ /* Keep this list in sync with below */ ++ if (strprefix(attrib, "user=", 1) != NULL || ++ strprefix(attrib, "group=", 1) != NULL || ++ strprefix(attrib, "host=", 1) != NULL || ++ strprefix(attrib, "address=", 1) != NULL || ++ strprefix(attrib, "localaddress=", 1) != NULL || ++ strprefix(attrib, "localport=", 1) != NULL || ++ strprefix(attrib, "rdomain=", 1) != NULL) { ++ arg = strchr(attrib, '='); ++ *(arg++) = '\0'; ++ } else { ++ arg = argv_next(acp, avp); ++ } ++ + /* All other criteria require an argument */ +- if ((arg = argv_next(acp, avp)) == NULL || +- *arg == '\0' || *arg == '#') { ++ if (arg == NULL || *arg == '\0' || *arg == '#') { + error("Missing Match criteria for %s", attrib); +- return -1; ++ result = -1; ++ goto out; + } + if (strcasecmp(attrib, "user") == 0) { + if (ci == NULL || (ci->test && ci->user == NULL)) { +@@ -1105,7 +1123,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + match_test_missing_fatal("Group", "user"); + switch (match_cfg_line_group(arg, line, ci->user)) { + case -1: +- return -1; ++ result = -1; ++ goto out; + case 0: + result = 0; + } +@@ -1141,7 +1160,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + result = 0; + break; + case -2: +- return -1; ++ result = -1; ++ goto out; + } + } else if (strcasecmp(attrib, "localaddress") == 0){ + if (ci == NULL || (ci->test && ci->laddress == NULL)) { +@@ -1166,13 +1186,15 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + result = 0; + break; + case -2: +- return -1; ++ result = -1; ++ goto out; + } + } else if (strcasecmp(attrib, "localport") == 0) { + if ((port = a2port(arg)) == -1) { + error("Invalid LocalPort '%s' on Match line", + arg); +- return -1; ++ result = -1; ++ goto out; + } + if (ci == NULL || (ci->test && ci->lport == -1)) { + result = 0; +@@ -1200,16 +1222,21 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + debug("user %.100s matched 'RDomain %.100s' at " + "line %d", ci->rdomain, arg, line); + } else { +- error("Unsupported Match attribute %s", attrib); +- return -1; ++ error("Unsupported Match attribute %s", oattrib); ++ result = -1; ++ goto out; + } ++ free(attrib); ++ attrib = NULL; + } + if (attributes == 0) { + error("One or more attributes required for Match"); + return -1; + } +- if (ci != NULL) ++ out: ++ if (ci != NULL && result != -1) + debug3("match %sfound", result ? "" : "not "); ++ free(attrib); + return result; + } + +diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh +index d442cdd6..97fd816f 100644 +--- a/regress/cfginclude.sh ++++ b/regress/cfginclude.sh +@@ -1,4 +1,4 @@ +-# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ ++# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="config include" +@@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF + Match host a + Hostname aa + +-Match host b # comment ++Match host=b # comment + Hostname bb + Include $OBJ/ssh_config.i.* + +@@ -18,7 +18,7 @@ Match host c + Include $OBJ/ssh_config.i.* + Hostname cc + +-Match host m ++Match host=m !user xxxyfake + Include $OBJ/ssh_config.i.* # comment + + Host d +@@ -41,7 +41,7 @@ Match host xxxxxx + _EOF + + cat > $OBJ/ssh_config.i.1 << _EOF +-Match host a ++Match host=a + Hostname aaa + + Match host b +@@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF + Match host a + Hostname aaaa + +-Match host b ++Match host=b !user blahblahfake + Hostname bbbb + +-Match host c ++Match host=c + Hostname cccc + + Host d +@@ -142,7 +142,7 @@ trial a aa + + # cleanup + rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out +-# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ ++# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="config include" +diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh +index 05a66685..2737a5f9 100644 +--- a/regress/cfgmatch.sh ++++ b/regress/cfgmatch.sh +@@ -1,4 +1,4 @@ +-# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ ++# $OpenBSD: cfgmatch.sh,v 1.14 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="sshd_config match" +@@ -26,7 +26,7 @@ start_client() + kill $client_pid + fatal "timeout waiting for background ssh" + fi +- done ++ done + } + + stop_client() +@@ -119,40 +119,42 @@ stop_client + # requires knowledge of actual group memberships user running the test). + params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ + localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" +-cp $OBJ/sshd_proxy_bak $OBJ/sshd_config +-echo 'Banner /nomatch' >>$OBJ/sshd_config +-for i in $params; do +- config=`echo $i | cut -f1 -d:` +- criteria=`echo $i | cut -f2 -d:` +- value=`echo $i | cut -f3 -d:` +- cat >>$OBJ/sshd_config </dev/null || \ ++ fail "validate config for w/out spec" ++ ++ # Test matching each criteria. ++ for i in $params; do ++ testcriteria=`echo $i | cut -f2 -d:` ++ expected=/`echo $i | cut -f3 -d:` ++ spec="" ++ for j in $params; do ++ config=`echo $j | cut -f1 -d:` ++ criteria=`echo $j | cut -f2 -d:` ++ value=`echo $j | cut -f3 -d:` ++ if [ "$criteria" = "$testcriteria" ]; then ++ spec="$criteria=$value,$spec" ++ else ++ spec="$criteria=1$value,$spec" ++ fi ++ done ++ trace "test spec $spec" ++ result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ ++ awk '$1=="banner"{print $2}'` ++ if [ "$result" != "$expected" ]; then ++ fail "match $config expected $expected got $result" + fi + done +- trace "test spec $spec" +- result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ +- awk '$1=="banner"{print $2}'` +- if [ "$result" != "$expected" ]; then +- fail "match $config expected $expected got $result" +- fi + done +diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh +index 518a703d..f67c3caa 100644 +--- a/regress/servcfginclude.sh ++++ b/regress/servcfginclude.sh +@@ -4,14 +4,14 @@ tid="server config include" + + cat > $OBJ/sshd_config.i << _EOF + HostKey $OBJ/host.ssh-ed25519 +-Match host a ++Match host=a + Banner /aa + + Match host b + Banner /bb + Include $OBJ/sshd_config.i.* # comment + +-Match host c ++Match host=c + Include $OBJ/sshd_config.i.* # comment + Banner /cc + +@@ -25,7 +25,7 @@ Match Host e + Banner /ee + Include $OBJ/sshd_config.i.* + +-Match Host f ++Match Host=f + Include $OBJ/sshd_config.i.* + Banner /ff + +@@ -47,13 +47,13 @@ Match host b + Match host c + Banner /ccc + +-Match Host d ++Match Host=d + Banner /ddd + + Match Host e + Banner /eee + +-Match Host f ++Match Host=f + Banner /fff + _EOF + +@@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF + Match host a + Banner /aaaa + +-Match host b ++Match host=b + Banner /bbbb + + Match host c # comment + Banner /cccc + +-Match Host d ++Match Host=d + Banner /dddd + + Match Host e From 6f3daee4f0618076cb81249c3a27501d81d166f5 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 5 Feb 2025 12:58:20 +0100 Subject: [PATCH 137/146] Based on openssh-9.9p1-8.fc42 --- gsi-openssh.spec | 7 +++++-- openssh-7.7p1-redhat.patch => openssh-8.7p1-redhat.patch | 2 +- openssh-9.9p1-gsissh.patch | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) rename openssh-7.7p1-redhat.patch => openssh-8.7p1-redhat.patch (99%) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 01f1110..9a340d9 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.9p1 -%global openssh_rel 2 +%global openssh_rel 3 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -84,7 +84,7 @@ 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 +Patch707: openssh-8.7p1-redhat.patch # warn users for unsupported UsePAM=no (#757545) Patch711: openssh-7.8p1-UsePAM-warning.patch @@ -575,6 +575,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Wed Feb 05 2025 Mattias Ellert - 9.9p1-3 +- Based on openssh-9.9p1-8.fc42 + * Wed Feb 05 2025 Mattias Ellert - 9.9p1-2 - Based on openssh-9.9p1-7.fc42 / openssh-9.9p1-2.fc41 diff --git a/openssh-7.7p1-redhat.patch b/openssh-8.7p1-redhat.patch similarity index 99% rename from openssh-7.7p1-redhat.patch rename to openssh-8.7p1-redhat.patch index 1d77f90..4e9d108 100644 --- a/openssh-7.7p1-redhat.patch +++ b/openssh-8.7p1-redhat.patch @@ -83,7 +83,7 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat @@ -0,0 +1,15 @@ +SyslogFacility AUTHPRIV + -+ChallengeResponseAuthentication no ++KbdInteractiveAuthentication no + +GSSAPIAuthentication yes +GSSAPICleanupCredentials no diff --git a/openssh-9.9p1-gsissh.patch b/openssh-9.9p1-gsissh.patch index 7f60393..5e2d011 100644 --- a/openssh-9.9p1-gsissh.patch +++ b/openssh-9.9p1-gsissh.patch @@ -2361,7 +2361,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat +++ openssh-9.9p1/sshd_config_redhat 2025-01-20 20:23:17.285730077 +0100 @@ -2,9 +2,6 @@ - ChallengeResponseAuthentication no + KbdInteractiveAuthentication no -GSSAPIAuthentication yes -GSSAPICleanupCredentials no From 850caa568b8a0bdda6df8eb773c88d5305184de1 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 5 Mar 2025 14:14:30 +0100 Subject: [PATCH 138/146] Based on openssh-9.9p1-9.fc42 --- gsi-openssh.spec | 9 +- openssh-9.9p1-match-regression.patch | 10 +- openssh-9.9p2-error_processing.patch | 152 +++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 openssh-9.9p2-error_processing.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 9a340d9..95abd24 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,7 +24,7 @@ %global libedit 1 %global openssh_ver 9.9p1 -%global openssh_rel 3 +%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh @@ -180,6 +180,9 @@ Patch1017: openssh-9.9p1-mlkembe.patch # upstream 3f02368e8e9121847727c46b280efc280e5eb615 # upstream 67a115e7a56dbdc3f5a58c64b29231151f3670f5 Patch1020: openssh-9.9p1-match-regression.patch +# upstream 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 +# upstream 0832aac79517611dd4de93ad0a83577994d9c907 +Patch1021: openssh-9.9p2-error_processing.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -351,6 +354,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 1016 -p1 -b .sep-keysign %patch -P 1017 -p1 -b .mlkembe %patch -P 1020 -p1 -b .match +%patch -P 1021 -p1 -b .errcode_set %patch -P 100 -p1 -b .coverity %patch -P 98 -p1 -b .gsi @@ -575,6 +579,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Wed Mar 05 2025 Mattias Ellert - 9.9p1-4 +- Based on openssh-9.9p1-9.fc42 + * Wed Feb 05 2025 Mattias Ellert - 9.9p1-3 - Based on openssh-9.9p1-8.fc42 diff --git a/openssh-9.9p1-match-regression.patch b/openssh-9.9p1-match-regression.patch index d724401..73ea964 100644 --- a/openssh-9.9p1-match-regression.patch +++ b/openssh-9.9p1-match-regression.patch @@ -137,7 +137,7 @@ index 89b8413e..dd774f46 100644 /* Terminate on comment */ if (*attrib == '#') { argv_consume(acp); /* mark all arguments consumed */ -@@ -1062,11 +1063,13 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, +@@ -1062,16 +1063,20 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, *arg != '\0' && *arg != '#')) { error("'all' cannot be combined with other " "Match attributes"); @@ -153,6 +153,14 @@ index 89b8413e..dd774f46 100644 } /* Criterion "invalid-user" also has no argument */ if (strcasecmp(attrib, "invalid-user") == 0) { +- if (ci == NULL) ++ if (ci == NULL) { ++ result = 0; + continue; ++ } + if (ci->user_invalid == 0) + result = 0; + else @@ -1078,11 +1081,26 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, debug("matched invalid-user at line %d", line); continue; diff --git a/openssh-9.9p2-error_processing.patch b/openssh-9.9p2-error_processing.patch new file mode 100644 index 0000000..692c6ac --- /dev/null +++ b/openssh-9.9p2-error_processing.patch @@ -0,0 +1,152 @@ +diff --git a/krl.c b/krl.c +index e2efdf06..0d0f6953 100644 +--- a/krl.c ++++ b/krl.c +@@ -674,6 +674,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + if (rs->lo - bitmap_start > INT_MAX) { ++ r = SSH_ERR_INVALID_FORMAT; + error_f("insane bitmap gap"); + goto out; + } +@@ -1059,6 +1060,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp) + } + + if ((krl = ssh_krl_init()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; + error_f("alloc failed"); + goto out; + } +diff --git a/packet.c b/packet.c +index 486f8515..9dea2cfc 100644 +--- a/packet.c ++++ b/packet.c +@@ -1864,6 +1864,14 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + if ((r = sshpkt_get_string_direct(ssh, &d, &len)) != 0) + return r; + DBG(debug("Received SSH2_MSG_PING len %zu", len)); ++ if (!ssh->state->after_authentication) { ++ DBG(debug("Won't reply to PING in preauth")); ++ break; ++ } ++ if (ssh_packet_is_rekeying(ssh)) { ++ DBG(debug("Won't reply to PING during KEX")); ++ break; ++ } + if ((r = sshpkt_start(ssh, SSH2_MSG_PONG)) != 0 || + (r = sshpkt_put_string(ssh, d, len)) != 0 || + (r = sshpkt_send(ssh)) != 0) +diff --git a/ssh-agent.c b/ssh-agent.c +index 48973b2c..c27c5a95 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1220,6 +1220,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + "restrict-destination-v00@openssh.com") == 0) { + if (*dcsp != NULL) { + error_f("%s already set", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_froms(m, &b)) != 0) { +@@ -1229,6 +1230,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + while (sshbuf_len(b) != 0) { + if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) { + error_f("too many %s constraints", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + *dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1, +@@ -1246,6 +1248,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + } + if (*certs != NULL) { + error_f("%s already set", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_get_u8(m, &v)) != 0 || +@@ -1257,6 +1260,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + while (sshbuf_len(b) != 0) { + if (*ncerts >= AGENT_MAX_EXT_CERTS) { + error_f("too many %s constraints", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + *certs = xrecallocarray(*certs, *ncerts, *ncerts + 1, +@@ -1757,6 +1761,7 @@ process_ext_session_bind(SocketEntry *e) + /* record new key/sid */ + if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) { + error_f("too many session IDs recorded"); ++ r = -1; + goto out; + } + e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids, +diff --git a/ssh-sk-client.c b/ssh-sk-client.c +index 321fe53a..06fad221 100644 +--- a/ssh-sk-client.c ++++ b/ssh-sk-client.c +@@ -439,6 +439,7 @@ sshsk_load_resident(const char *provider_path, const char *device, + } + if ((srk = calloc(1, sizeof(*srk))) == NULL) { + error_f("calloc failed"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + srk->key = key; +@@ -450,6 +451,7 @@ sshsk_load_resident(const char *provider_path, const char *device, + if ((tmp = recallocarray(srks, nsrks, nsrks + 1, + sizeof(*srks))) == NULL) { + error_f("recallocarray keys failed"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + debug_f("srks[%zu]: %s %s uidlen %zu", nsrks, +diff --git a/sshconnect2.c b/sshconnect2.c +index a69c4da1..1ee6000a 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -99,7 +99,7 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) + options.required_rsa_size)) != 0) + fatal_r(r, "Bad server host key"); + if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, +- xxx_conn_info) == -1) ++ xxx_conn_info) != 0) + fatal("Host key verification failed."); + return 0; + } +@@ -699,6 +699,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + + if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { + debug_f("server sent unknown pkalg %s", pkalg); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { +@@ -709,6 +710,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + error("input_userauth_pk_ok: type mismatch " + "for decoded key (received %d, expected %d)", + key->type, pktype); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + +@@ -728,6 +730,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + SSH_FP_DEFAULT); + error_f("server replied with unknown key: %s %s", + sshkey_type(key), fp == NULL ? "" : fp); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + ident = format_identity(id); +diff --git a/sshsig.c b/sshsig.c +index 6e03c0b0..3da005d6 100644 +--- a/sshsig.c ++++ b/sshsig.c +@@ -879,6 +879,7 @@ cert_filter_principals(const char *path, u_long linenum, + } + if ((principals = sshbuf_dup_string(nprincipals)) == NULL) { + error_f("buffer error"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* success */ From beffeababdabf42a621a45f8e5b4e374d45317d8 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Wed, 5 Mar 2025 14:28:17 +0100 Subject: [PATCH 139/146] Based on openssh-9.9p1-11.fc43 --- gsi-openssh.spec | 11 +- openssh-7.7p1-gssapi-new-unique.patch | 5 +- openssh-9.9p1-openssl-mlkem.patch | 385 ++++++++++++++++++++++++++ openssh-9.9p2-error_processing.patch | 9 + 4 files changed, 406 insertions(+), 4 deletions(-) create mode 100644 openssh-9.9p1-openssl-mlkem.patch diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 95abd24..cdf61c4 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -24,12 +24,11 @@ %global libedit 1 %global openssh_ver 9.9p1 -%global openssh_rel 4 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist} +Release: 5%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -182,7 +181,10 @@ Patch1017: openssh-9.9p1-mlkembe.patch Patch1020: openssh-9.9p1-match-regression.patch # upstream 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 # upstream 0832aac79517611dd4de93ad0a83577994d9c907 +# added https://www.openwall.com/lists/oss-security/2025/02/22/1 Patch1021: openssh-9.9p2-error_processing.patch +# Downstream patch, OpenSSL based MLKEM implementation +Patch1022: openssh-9.9p1-openssl-mlkem.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream @@ -206,6 +208,7 @@ BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel BuildRequires: libxcrypt-devel +BuildRequires: oqsprovider Recommends: p11-kit %if %{kerberos5} @@ -355,6 +358,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} %patch -P 1017 -p1 -b .mlkembe %patch -P 1020 -p1 -b .match %patch -P 1021 -p1 -b .errcode_set +%patch -P 1022 -p1 -b .openssl-mlkem %patch -P 100 -p1 -b .coverity %patch -P 98 -p1 -b .gsi @@ -579,6 +583,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Wed Mar 05 2025 Mattias Ellert - 9.9p1-5 +- Based on openssh-9.9p1-11.fc43 + * Wed Mar 05 2025 Mattias Ellert - 9.9p1-4 - Based on openssh-9.9p1-9.fc42 diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 0b8ab02..34b9b9d 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -126,7 +126,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -238,36 +281,189 @@ krb5_cleanup_proc(Authctxt *authctxt) } } @@ -149,7 +149,8 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c + old = *dsc; + + i = asprintf(dsc, "%s%s", *dsc, src); -+ if (i == -1 || src == NULL) { ++ if (i == -1) { ++ *dsc = old; + free(src); + return -1; + } diff --git a/openssh-9.9p1-openssl-mlkem.patch b/openssh-9.9p1-openssl-mlkem.patch new file mode 100644 index 0000000..e39bb67 --- /dev/null +++ b/openssh-9.9p1-openssl-mlkem.patch @@ -0,0 +1,385 @@ +diff --git a/kex-names.c b/kex-names.c +index ec840c1f..c0d3be11 100644 +--- a/kex-names.c ++++ b/kex-names.c +@@ -90,6 +90,19 @@ static const struct kexalg 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) + { +@@ -98,6 +111,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); +@@ -117,6 +133,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 ++#include ++#include ++ ++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 diff --git a/openssh-9.9p2-error_processing.patch b/openssh-9.9p2-error_processing.patch index 692c6ac..dd71716 100644 --- a/openssh-9.9p2-error_processing.patch +++ b/openssh-9.9p2-error_processing.patch @@ -73,6 +73,15 @@ index 48973b2c..c27c5a95 100644 goto out; } *certs = xrecallocarray(*certs, *ncerts, *ncerts + 1, +@@ -1360,6 +1360,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; + } @@ -1757,6 +1761,7 @@ process_ext_session_bind(SocketEntry *e) /* record new key/sid */ if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) { From 4205fcb9442de13a2a9978c27c6feb4fc8ca2622 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 20 Apr 2025 05:56:15 +0200 Subject: [PATCH 140/146] Based on openssh-9.9p1-15.fc43 --- gsi-openssh.spec | 11 +++++++---- gsisshd.sysconfig | 1 + openssh-8.7p1-redhat.patch | 10 ++++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index cdf61c4..cb7ced2 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -196,19 +196,19 @@ Patch99: openssh-9.9p1-hpn-18.6.0.patch License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant Requires: /sbin/nologin +Requires: openssl-libs >= 3.5.0 BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel -BuildRequires: openssl-devel >= 0.9.8j +BuildRequires: openssl-devel >= 3.5.0 BuildRequires: systemd-devel BuildRequires: systemd-rpm-macros BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel BuildRequires: libxcrypt-devel -BuildRequires: oqsprovider Recommends: p11-kit %if %{kerberos5} @@ -406,8 +406,8 @@ fi --sysconfdir=%{_sysconfdir}/gsissh \ --libexecdir=%{_libexecdir}/gsissh \ --datadir=%{_datadir}/gsissh \ - --with-default-path=%{_libexecdir}/gsissh/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \ - --with-superuser-path=%{_libexecdir}/gsissh/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ + --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 \ --disable-strip \ --without-zlib-version-check \ @@ -583,6 +583,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Sun Apr 20 2025 Mattias Ellert - 9.9p1-5 +- Based on openssh-9.9p1-15.fc43 + * Wed Mar 05 2025 Mattias Ellert - 9.9p1-5 - Based on openssh-9.9p1-11.fc43 diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index 7e106f4..e968b50 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -8,3 +8,4 @@ #SSH_RSA_BITS=3072 #SSH_ECDSA_BITS=256 +OPTIONS="" diff --git a/openssh-8.7p1-redhat.patch b/openssh-8.7p1-redhat.patch index 4e9d108..a4c11b5 100644 --- a/openssh-8.7p1-redhat.patch +++ b/openssh-8.7p1-redhat.patch @@ -15,7 +15,7 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat --- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100 +++ openssh/ssh_config_redhat 2020-02-13 18:13:39.180641839 +0100 -@@ -0,0 +1,15 @@ +@@ -0,0 +1,18 @@ +# The options here are in the "Match final block" to be applied as the last +# options and could be potentially overwritten by the user configuration +Match final all @@ -29,6 +29,9 @@ diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat +# mode correctly we set this to yes. + ForwardX11Trusted yes + ++# rhbz#2352653 - export COLORTERM ++ SendEnv COLORTERM ++ +# Uncomment this if you want to use .local domain +# Host *.local diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0 @@ -80,7 +83,7 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat --- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100 +++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100 -@@ -0,0 +1,15 @@ +@@ -0,0 +1,18 @@ +SyslogFacility AUTHPRIV + +KbdInteractiveAuthentication no @@ -92,6 +95,9 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat + +X11Forwarding yes + ++# rhbz#2352653 - accept COLORTERM ++ AcceptEnv COLORTERM ++ +# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd, +# as it is more configurable and versatile than the built-in version. +PrintMotd no From 6a6b9524b271b2b23c9adee30d48053161431fa6 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Sun, 20 Apr 2025 06:13:54 +0200 Subject: [PATCH 141/146] Bump release --- gsi-openssh.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index cb7ced2..b61f6d3 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 5%{?dist} +Release: 6%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -583,7 +583,7 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog -* Sun Apr 20 2025 Mattias Ellert - 9.9p1-5 +* Sun Apr 20 2025 Mattias Ellert - 9.9p1-6 - Based on openssh-9.9p1-15.fc43 * Wed Mar 05 2025 Mattias Ellert - 9.9p1-5 From dff7de33ab86afdc6e3951a17c9e38cfa632c4b1 Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 16 Jun 2025 05:31:00 +0200 Subject: [PATCH 142/146] Based on openssh-10.0p1-3.fc43 --- ...patch => 0001-openssh-7.8p1-role-mls.patch | 445 ++- ...> 0002-openssh-6.6p1-privsep-selinux.patch | 94 +- ...t.patch => 0003-openssh-6.6p1-keycat.patch | 226 +- ... => 0004-openssh-6.6p1-allow-ip-opts.patch | 21 +- ....patch => 0005-openssh-5.9p1-ipv6man.patch | 31 +- 0006-openssh-5.8p2-sigpipe.patch | 26 + ...-x11.patch => 0007-openssh-7.2p2-x11.patch | 31 +- ... 0008-openssh-5.1p1-askpass-progress.patch | 41 +- ...0009-openssh-4.3p2-askpass-grab-info.patch | 21 +- ...t.patch => 0010-openssh-8.7p1-redhat.patch | 109 +- ...=> 0011-openssh-7.8p1-UsePAM-warning.patch | 31 +- ...h => 0012-openssh-9.6p1-gssapi-keyex.patch | 2232 ++++++------ ...atch => 0013-openssh-6.6p1-force_krb.patch | 39 +- ...0014-openssh-7.7p1-gssapi-new-unique.patch | 316 +- ...0015-openssh-7.2p2-k5login_directory.patch | 31 +- ....patch => 0016-openssh-6.6p1-kuserok.patch | 135 +- 0017-openssh-6.4p1-fromto-remote.patch | 28 + ...018-openssh-6.6.1p1-selinux-contexts.patch | 50 +- ...> 0019-openssh-6.6.1p1-log-in-chroot.patch | 178 +- ...h-6.6.1p1-scp-non-existing-directory.patch | 27 + ...21-openssh-6.6p1-GSSAPIEnablek5users.patch | 107 +- 0022-openssh-6.8p1-sshdT-output.patch | 25 + ...-openssh-6.7p1-sftp-force-permission.patch | 41 +- ...=> 0024-openssh-7.2p2-s390-closefrom.patch | 22 +- ... 0025-openssh-7.3p1-x11-max-displays.patch | 152 +- ...> 0026-openssh-7.6p1-cleanup-selinux.patch | 169 +- 0027-openssh-7.5p1-sandbox.patch | 58 + ...tch => 0028-openssh-8.0p1-pkcs11-uri.patch | 3216 +++++++++-------- ...patch => 0029-openssh-7.8p1-scp-ipv6.patch | 15 +- ...> 0030-openssh-8.0p1-crypto-policies.patch | 92 +- ...ch => 0031-openssh-8.0p1-openssl-kdf.patch | 26 +- ...tch => 0032-openssh-8.2p1-visibility.patch | 22 +- ... 0033-openssh-8.2p1-x11-without-ipv6.patch | 25 +- ...34-openssh-8.0p1-preserve-pam-errors.patch | 29 +- ...> 0035-openssh-8.7p1-scp-kill-switch.patch | 39 +- ... => 0036-openssh-8.7p1-recursive-scp.patch | 86 +- ...tch => 0037-openssh-8.7p1-minrsabits.patch | 27 +- 0038-openssh-8.7p1-ibmca.patch | 25 + ...it.patch => 0039-openssh-7.6p1-audit.patch | 1030 +++--- ...0-openssh-7.1p2-audit-race-condition.patch | 59 +- ...atch => 0041-openssh-9.0p1-audit-log.patch | 127 +- ...ips.patch => 0042-openssh-7.7p1-fips.patch | 781 ++-- 0043-openssh-8.7p1-ssh-manpage.patch | 47 + ...enssh-8.7p1-negotiate-supported-algs.patch | 41 +- ...h => 0045-openssh-9.0p1-evp-fips-kex.patch | 109 +- ...> 0046-openssh-8.7p1-nohostsha1proof.patch | 161 +- 0047-openssh-9.6p1-pam-rhost.patch | 25 + 0048-openssh-9.9p1-separate-keysign.patch | 25 + ... => 0049-openssh-9.9p1-openssl-mlkem.patch | 21 +- 0050-openssh-9.9p2-error_processing.patch | 25 + ...error-for-non-supported-private-keys.patch | 27 + ...ore-bad-hostkeys-in-known_hosts-file.patch | 86 + ...-authentication-indicators-in-GSSAPI.patch | 450 +++ 1000-openssh-coverity.patch | 257 ++ ....patch => 2000-openssh-10.0p1-gsissh.patch | 440 +-- ...ch => 2001-openssh-10.0p1-hpn-18.7.0.patch | 1254 ++++--- gsi-openssh.spec | 229 +- openssh-5.8p2-sigpipe.patch | 14 - openssh-6.4p1-fromto-remote.patch | 16 - ...h-6.6.1p1-scp-non-existing-directory.patch | 14 - openssh-6.7p1-coverity.patch | 248 -- openssh-6.8p1-sshdT-output.patch | 12 - openssh-7.5p1-sandbox.patch | 86 - openssh-8.0p1-keygen-strip-doseol.patch | 12 - openssh-8.7p1-ibmca.patch | 11 - openssh-8.7p1-ssh-manpage.patch | 53 - openssh-9.6p1-pam-rhost.patch | 32 - openssh-9.9p1-match-regression.patch | 471 --- openssh-9.9p1-mlkembe.patch | 98 - openssh-9.9p1-separate-keysign.patch | 12 - openssh-9.9p2-error_processing.patch | 161 - 71 files changed, 7826 insertions(+), 6896 deletions(-) rename openssh-7.8p1-role-mls.patch => 0001-openssh-7.8p1-role-mls.patch (80%) rename openssh-6.6p1-privsep-selinux.patch => 0002-openssh-6.6p1-privsep-selinux.patch (52%) rename openssh-6.6p1-keycat.patch => 0003-openssh-6.6p1-keycat.patch (77%) rename openssh-6.6p1-allow-ip-opts.patch => 0004-openssh-6.6p1-allow-ip-opts.patch (68%) rename openssh-5.9p1-ipv6man.patch => 0005-openssh-5.9p1-ipv6man.patch (54%) create mode 100644 0006-openssh-5.8p2-sigpipe.patch rename openssh-7.2p2-x11.patch => 0007-openssh-7.2p2-x11.patch (71%) rename openssh-5.1p1-askpass-progress.patch => 0008-openssh-5.1p1-askpass-progress.patch (66%) rename openssh-4.3p2-askpass-grab-info.patch => 0009-openssh-4.3p2-askpass-grab-info.patch (53%) rename openssh-8.7p1-redhat.patch => 0010-openssh-8.7p1-redhat.patch (67%) rename openssh-7.8p1-UsePAM-warning.patch => 0011-openssh-7.8p1-UsePAM-warning.patch (50%) rename openssh-9.6p1-gssapi-keyex.patch => 0012-openssh-9.6p1-gssapi-keyex.patch (89%) rename openssh-6.6p1-force_krb.patch => 0013-openssh-6.6p1-force_krb.patch (88%) rename openssh-7.7p1-gssapi-new-unique.patch => 0014-openssh-7.7p1-gssapi-new-unique.patch (79%) rename openssh-7.2p2-k5login_directory.patch => 0015-openssh-7.2p2-k5login_directory.patch (74%) rename openssh-6.6p1-kuserok.patch => 0016-openssh-6.6p1-kuserok.patch (80%) create mode 100644 0017-openssh-6.4p1-fromto-remote.patch rename openssh-6.6.1p1-selinux-contexts.patch => 0018-openssh-6.6.1p1-selinux-contexts.patch (73%) rename openssh-6.6.1p1-log-in-chroot.patch => 0019-openssh-6.6.1p1-log-in-chroot.patch (54%) create mode 100644 0020-openssh-6.6.1p1-scp-non-existing-directory.patch rename openssh-6.6p1-GSSAPIEnablek5users.patch => 0021-openssh-6.6p1-GSSAPIEnablek5users.patch (61%) create mode 100644 0022-openssh-6.8p1-sshdT-output.patch rename openssh-6.7p1-sftp-force-permission.patch => 0023-openssh-6.7p1-sftp-force-permission.patch (72%) rename openssh-7.2p2-s390-closefrom.patch => 0024-openssh-7.2p2-s390-closefrom.patch (66%) rename openssh-7.3p1-x11-max-displays.patch => 0025-openssh-7.3p1-x11-max-displays.patch (53%) rename openssh-7.6p1-cleanup-selinux.patch => 0026-openssh-7.6p1-cleanup-selinux.patch (65%) create mode 100644 0027-openssh-7.5p1-sandbox.patch rename openssh-8.0p1-pkcs11-uri.patch => 0028-openssh-8.0p1-pkcs11-uri.patch (90%) rename openssh-7.8p1-scp-ipv6.patch => 0029-openssh-7.8p1-scp-ipv6.patch (51%) rename openssh-8.0p1-crypto-policies.patch => 0030-openssh-8.0p1-crypto-policies.patch (90%) rename openssh-8.0p1-openssl-kdf.patch => 0031-openssh-8.0p1-openssl-kdf.patch (84%) rename openssh-8.2p1-visibility.patch => 0032-openssh-8.2p1-visibility.patch (62%) rename openssh-8.2p1-x11-without-ipv6.patch => 0033-openssh-8.2p1-x11-without-ipv6.patch (55%) rename openssh-8.0p1-preserve-pam-errors.patch => 0034-openssh-8.0p1-preserve-pam-errors.patch (67%) rename openssh-8.7p1-scp-kill-switch.patch => 0035-openssh-8.7p1-scp-kill-switch.patch (57%) rename openssh-8.7p1-recursive-scp.patch => 0036-openssh-8.7p1-recursive-scp.patch (73%) rename openssh-8.7p1-minrsabits.patch => 0037-openssh-8.7p1-minrsabits.patch (63%) create mode 100644 0038-openssh-8.7p1-ibmca.patch rename openssh-7.6p1-audit.patch => 0039-openssh-7.6p1-audit.patch (83%) rename openssh-7.1p2-audit-race-condition.patch => 0040-openssh-7.1p2-audit-race-condition.patch (73%) rename openssh-9.0p1-audit-log.patch => 0041-openssh-9.0p1-audit-log.patch (85%) rename openssh-7.7p1-fips.patch => 0042-openssh-7.7p1-fips.patch (77%) create mode 100644 0043-openssh-8.7p1-ssh-manpage.patch rename openssh-8.7p1-negotiate-supported-algs.patch => 0044-openssh-8.7p1-negotiate-supported-algs.patch (74%) rename openssh-9.0p1-evp-fips-kex.patch => 0045-openssh-9.0p1-evp-fips-kex.patch (90%) rename openssh-8.7p1-nohostsha1proof.patch => 0046-openssh-8.7p1-nohostsha1proof.patch (69%) create mode 100644 0047-openssh-9.6p1-pam-rhost.patch create mode 100644 0048-openssh-9.9p1-separate-keysign.patch rename openssh-9.9p1-openssl-mlkem.patch => 0049-openssh-9.9p1-openssl-mlkem.patch (94%) create mode 100644 0050-openssh-9.9p2-error_processing.patch create mode 100644 0051-Provide-better-error-for-non-supported-private-keys.patch create mode 100644 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch create mode 100644 0053-support-authentication-indicators-in-GSSAPI.patch create mode 100644 1000-openssh-coverity.patch rename openssh-9.9p1-gsissh.patch => 2000-openssh-10.0p1-gsissh.patch (86%) rename openssh-9.9p1-hpn-18.6.0.patch => 2001-openssh-10.0p1-hpn-18.7.0.patch (94%) delete mode 100644 openssh-5.8p2-sigpipe.patch delete mode 100644 openssh-6.4p1-fromto-remote.patch delete mode 100644 openssh-6.6.1p1-scp-non-existing-directory.patch delete mode 100644 openssh-6.7p1-coverity.patch delete mode 100644 openssh-6.8p1-sshdT-output.patch delete mode 100644 openssh-7.5p1-sandbox.patch delete mode 100644 openssh-8.0p1-keygen-strip-doseol.patch delete mode 100644 openssh-8.7p1-ibmca.patch delete mode 100644 openssh-8.7p1-ssh-manpage.patch delete mode 100644 openssh-9.6p1-pam-rhost.patch delete mode 100644 openssh-9.9p1-match-regression.patch delete mode 100644 openssh-9.9p1-mlkembe.patch delete mode 100644 openssh-9.9p1-separate-keysign.patch delete mode 100644 openssh-9.9p2-error_processing.patch diff --git a/openssh-7.8p1-role-mls.patch b/0001-openssh-7.8p1-role-mls.patch similarity index 80% rename from openssh-7.8p1-role-mls.patch rename to 0001-openssh-7.8p1-role-mls.patch index 7c6d0ca..c08e414 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/0001-openssh-7.8p1-role-mls.patch @@ -1,46 +1,75 @@ -diff -up openssh/auth2.c.role-mls openssh/auth2.c ---- openssh/auth2.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth2.c 2018-08-22 11:14:56.815430916 +0200 -@@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32 - Authctxt *authctxt = ssh->authctxt; - Authmethod *m = NULL; - char *user = NULL, *service = NULL, *method = NULL, *style = NULL; +From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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; +#ifdef WITH_SELINUX -+ char *role = NULL; ++ char *role; +#endif - int r, authenticated = 0; - double tstart = monotime_double(); -@@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32 - debug("userauth-request for user %s service %s method %s", user, service, method); - debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = 0; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -@@ -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; -+#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 -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c ---- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 -@@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple + /* Method lists for multiple authentication */ + char **auth_methods; /* modified from server config */ +diff --git a/auth2-gss.c b/auth2-gss.c +index 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) Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; int r, authenticated = 0; @@ -48,7 +77,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c struct sshbuf *b; gss_buffer_desc mic, gssbuf; u_char *p; -@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -300,7 +301,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) fatal_f("sshbuf_new failed"); mic.value = p; mic.length = len; @@ -63,7 +92,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c "gssapi-with-mic", ssh->kex->session_id); if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -@@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -313,6 +320,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) logit("GSSAPI MIC check failed"); sshbuf_free(b); @@ -72,10 +101,11 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c free(mic.value); 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 -@@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh) +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) /* reconstruct packet */ if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -92,10 +122,11 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || -diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.role-mls 2018-08-22 11:14:56.816430924 +0200 -+++ openssh/auth2-pubkey.c 2018-08-22 11:17:07.331483958 +0200 -@@ -169,9 +169,16 @@ userauth_pubkey(struct ssh *ssh) +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index aa24fda0..267a27d2 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -206,9 +206,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) goto done; } /* reconstruct packet */ @@ -114,47 +145,51 @@ diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || -diff -up openssh/auth.h.role-mls openssh/auth.h ---- openssh/auth.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth.h 2018-08-22 11:14:56.816430924 +0200 -@@ -65,6 +65,9 @@ struct Authctxt { - char *service; - struct passwd *pw; /* set if 'valid' */ - char *style; +diff --git a/auth2.c b/auth2.c +index 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; +#ifdef WITH_SELINUX -+ char *role; ++ char *role = NULL; +#endif + int r, authenticated = 0; + double tstart = monotime_double(); - /* Method lists for multiple authentication */ - char **auth_methods; /* modified from server config */ -diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c ---- openssh/auth-pam.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth-pam.c 2018-08-22 11:14:56.816430924 +0200 -@@ -1172,7 +1172,7 @@ is_pam_session_open(void) - * during the ssh authentication process. - */ - int --do_pam_putenv(char *name, char *value) -+do_pam_putenv(char *name, const char *value) - { - int ret = 1; - char *compound; -diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h ---- openssh/auth-pam.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth-pam.h 2018-08-22 11:14:56.817430932 +0200 -@@ -33,7 +33,7 @@ u_int do_pam_account(void); - void do_pam_session(struct ssh *); - void do_pam_setcred(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 -up openssh/misc.c.role-mls openssh/misc.c ---- openssh/misc.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/misc.c 2018-08-22 11:14:56.817430932 +0200 -@@ -542,6 +542,7 @@ char * +@@ -284,6 +287,11 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = 0; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + +@@ -313,7 +321,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) + setproctitle("%s [net]", authctxt->valid ? user : "unknown"); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; ++#ifdef WITH_SELINUX ++ authctxt->role = role ? xstrdup(role) : NULL; ++#endif + mm_inform_authserv(service, style); ++#ifdef WITH_SELINUX ++ mm_inform_authrole(role); ++#endif + userauth_banner(ssh); + if ((r = kex_server_update_ext_info(ssh)) != 0) + fatal_fr(r, "kex_server_update_ext_info failed"); +diff --git a/misc.c b/misc.c +index dd0bd032..c932f9bb 100644 +--- a/misc.c ++++ b/misc.c +@@ -806,6 +806,7 @@ char * colon(char *cp) { int flag = 0; @@ -162,7 +197,7 @@ diff -up openssh/misc.c.role-mls openssh/misc.c if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -557,6 +558,13 @@ colon(char *cp) +@@ -821,6 +822,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -176,10 +211,11 @@ diff -up openssh/misc.c.role-mls openssh/misc.c } return NULL; } -diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c ---- openssh-8.6p1/monitor.c.role-mls 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/monitor.c 2021-05-21 14:21:56.719414087 +0200 -@@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st +diff --git a/monitor.c b/monitor.c +index 2179553d..02b3eaaa 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); @@ -189,7 +225,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); -@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -194,6 +197,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}, @@ -199,7 +235,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in +@@ -912,6 +918,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -209,7 +245,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -877,6 +886,26 @@ key_base_type_match(const char *method, +@@ -986,6 +995,26 @@ key_base_type_match(const char *method, const struct sshkey *key, return found; } @@ -236,16 +272,16 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, +@@ -1358,7 +1387,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) struct sshbuf *b; - struct sshkey *hostkey = NULL; + struct sshkey *hostkey = NULL; const u_char *p; - char *userstyle, *cp; + char *userstyle, *s, *cp; size_t len; u_char type; int hostbound = 0, r, fail = 0; -@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, +@@ -1389,6 +1418,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -254,7 +290,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char +@@ -1439,7 +1470,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, { struct sshbuf *b; const u_char *p; @@ -263,7 +299,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c size_t len; int r, fail = 0; u_char type; -@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char +@@ -1460,6 +1491,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -272,12 +308,13 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh/monitor.h.role-mls openssh/monitor.h ---- openssh/monitor.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/monitor.h 2018-08-22 11:14:56.818430941 +0200 -@@ -55,6 +55,10 @@ enum monitor_reqtype { - MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, +diff --git a/monitor.h b/monitor.h +index 3f8a9bea..9dcd9c29 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -56,6 +56,10 @@ enum monitor_reqtype { MONITOR_REQ_TERM = 50, + MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52, +#ifdef WITH_SELINUX + MONITOR_REQ_AUTHROLE = 80, @@ -286,10 +323,11 @@ diff -up openssh/monitor.h.role-mls openssh/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.role-mls 2018-08-22 11:14:56.818430941 +0200 -+++ openssh/monitor_wrap.c 2018-08-22 11:21:47.938747968 +0200 -@@ -390,6 +390,27 @@ mm_inform_authserv(char *service, char * +diff --git a/monitor_wrap.c b/monitor_wrap.c +index bd900b2f..ef3ab1b1 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -442,6 +442,27 @@ mm_inform_authserv(char *service, char *style) sshbuf_free(m); } @@ -317,10 +355,11 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c /* Do the password authentication */ int mm_auth_password(struct ssh *ssh, char *password) -diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.role-mls 2018-08-22 11:14:56.818430941 +0200 -+++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200 -@@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int); +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 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 *, const u_char *, size_t, const char *, const char *, const char *, u_int compat); void mm_inform_authserv(char *, char *); @@ -330,10 +369,11 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h struct passwd *mm_getpwnamallow(struct ssh *, const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); -diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in ---- openssh/openbsd-compat/Makefile.in.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/Makefile.in 2018-08-22 11:14:56.819430949 +0200 -@@ -92,7 +92,8 @@ PORTS= port-aix.o \ +diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in +index 1d549954..78e6fa5b 100644 +--- a/openbsd-compat/Makefile.in ++++ b/openbsd-compat/Makefile.in +@@ -100,7 +100,8 @@ PORTS= port-aix.o \ port-prngd.o \ port-solaris.o \ port-net.o \ @@ -343,78 +383,11 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make .c.o: $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c ---- openssh/openbsd-compat/port-linux.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.c 2018-08-22 11:14:56.819430949 +0200 -@@ -100,37 +100,6 @@ ssh_selinux_getctxbyname(char *pwname) - return sc; - } - --/* Set the execution context to the default for the specified user */ --void --ssh_selinux_setup_exec_context(char *pwname) --{ -- char *user_ctx = NULL; -- -- if (!ssh_selinux_enabled()) -- return; -- -- debug3("%s: setting execution context", __func__); -- -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to set SELinux execution " -- "context for %s", __func__, pwname); -- break; -- default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); -- } -- } -- if (user_ctx != NULL) -- freecon(user_ctx); -- -- debug3("%s: done", __func__); --} -- - /* Set the TTY context for the specified user */ - void - ssh_selinux_setup_pty(char *pwname, const char *tty) -@@ -145,7 +114,11 @@ ssh_selinux_setup_pty(char *pwname, cons - - debug3("%s: setting TTY context on %s", __func__, tty); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -+ if (getexeccon(&user_ctx) != 0) { -+ error_f("getexeccon: %s", strerror(errno)); -+ goto out; -+ } -+ - - /* XXX: should these calls fatal() upon failure in enforcing mode? */ - -diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/port-linux.h ---- openssh/openbsd-compat/port-linux.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.h 2018-08-22 11:14:56.819430949 +0200 -@@ -20,9 +20,10 @@ - #ifdef WITH_SELINUX - int ssh_selinux_enabled(void); - void ssh_selinux_setup_pty(char *, const char *); --void ssh_selinux_setup_exec_context(char *); - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); -+ -+void sshd_selinux_setup_exec_context(char *); - #endif - - #ifdef LINUX_OOM_ADJUST -diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c ---- openssh/openbsd-compat/port-linux-sshd.c.role-mls 2018-08-22 11:14:56.819430949 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2018-08-22 11:14:56.819430949 +0200 +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 @@ +/* + * Copyright (c) 2005 Daniel Walsh @@ -836,10 +809,82 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa +#endif +#endif + -diff -up openssh/platform.c.role-mls openssh/platform.c ---- openssh/platform.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/platform.c 2018-08-22 11:14:56.819430949 +0200 -@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(stru +diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c +index 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) } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -848,10 +893,11 @@ diff -up openssh/platform.c.role-mls openssh/platform.c #endif } -diff -up openssh/sshd.c.role-mls openssh/sshd.c ---- openssh/sshd-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) +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) restore_uid(); } #endif @@ -861,3 +907,6 @@ diff -up openssh/sshd.c.role-mls openssh/sshd.c #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(); +-- +2.49.0 + diff --git a/openssh-6.6p1-privsep-selinux.patch b/0002-openssh-6.6p1-privsep-selinux.patch similarity index 52% rename from openssh-6.6p1-privsep-selinux.patch rename to 0002-openssh-6.6p1-privsep-selinux.patch index 16d98cd..32d3c64 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/0002-openssh-6.6p1-privsep-selinux.patch @@ -1,18 +1,21 @@ -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 +From 99d8e250514023d3b88a1c9eb724c4898aba9827 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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"); } @@ -41,10 +44,23 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- #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) +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); @@ -53,17 +69,17 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c #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); +@@ -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); -@@ -1396,6 +1399,11 @@ do_setusercontext(struct passwd *pw) +@@ -1417,6 +1420,11 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -75,17 +91,17 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c } 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) +@@ -1434,9 +1442,6 @@ do_pwchange(Session *s) if (s->ttyfd != -1) { fprintf(stderr, - "You must change your password now and login again!\n"); + "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); -@@ -1625,9 +1630,6 @@ do_child(Session *s, const char *command +@@ -1649,9 +1654,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -95,13 +111,14 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c 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-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(); - +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 @@ -109,7 +126,11 @@ diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c /* Demote the child */ if (privsep_chroot) { /* Change our root directory */ -@@ -403,7 +403,7 @@ privsep_postauth(struct ssh *ssh, Authct +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. */ @@ -118,3 +139,6 @@ diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c skip_privdrop = 1; #endif +-- +2.49.0 + diff --git a/openssh-6.6p1-keycat.patch b/0003-openssh-6.6p1-keycat.patch similarity index 77% rename from openssh-6.6p1-keycat.patch rename to 0003-openssh-6.6p1-keycat.patch index 4eb0998..b46b378 100644 --- a/openssh-6.6p1-keycat.patch +++ b/0003-openssh-6.6p1-keycat.patch @@ -1,23 +1,26 @@ -diff -up openssh/misc.c.keycat openssh/misc.c ---- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 -+++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 -@@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw - error("%s: dup2: %s", tag, strerror(errno)); - _exit(1); - } -+#ifdef WITH_SELINUX -+ if (sshd_selinux_setup_env_variables() < 0) { -+ error ("failed to copy environment: %s", -+ strerror(errno)); -+ _exit(127); -+ } -+#endif - if (env != NULL) - execve(av[0], av, env); - else -diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat ---- openssh/HOWTO.ssh-keycat.keycat 2015-06-24 10:57:50.157849608 +0200 -+++ openssh/HOWTO.ssh-keycat 2015-06-24 10:57:50.157849608 +0200 +From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ -0,0 +1,12 @@ +The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys +of an user in any environment. This includes environments with @@ -31,35 +34,36 @@ diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat + PubkeyAuthentication yes + + -diff -up openssh/Makefile.in.keycat openssh/Makefile.in ---- openssh/Makefile.in.keycat 2015-06-24 10:57:50.152849621 +0200 -+++ openssh/Makefile.in 2015-06-24 10:57:50.157849608 +0200 -@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server +diff --git a/Makefile.in b/Makefile.in +index 4617cebc..438efc51 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign +SSH_KEYCAT=$(libexecdir)/ssh-keycat SSHD_SESSION=$(libexecdir)/sshd-session + SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper -@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ +@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ +KEYCATLIBS=@KEYCATLIBS@ LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ - AR=@AR@ -@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ + LIBWTMPDB=@LIBWTMPDB@ +@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo --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) +-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE) XMSS_OBJS=\ ssh-xmss.o \ -@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) +@@ -260,6 +262,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS) ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) @@ -69,7 +73,7 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) -@@ -321,6 +325,7 @@ install-files: +@@ -447,6 +452,7 @@ install-files: $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) @@ -77,24 +81,67 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff -up openssh/openbsd-compat/port-linux.h.keycat openssh/openbsd-compat/port-linux.h ---- openssh/openbsd-compat/port-linux.h.keycat 2015-06-24 10:57:50.150849626 +0200 -+++ openssh/openbsd-compat/port-linux.h 2015-06-24 10:57:50.160849601 +0200 -@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); +diff --git a/configure.ac b/configure.ac +index ee77a048..d546788c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam], + PAM_MSG="yes" -+int sshd_selinux_enabled(void); - void sshd_selinux_copy_context(void); - void sshd_selinux_setup_exec_context(char *); -+int sshd_selinux_setup_env_variables(void); - #endif + SSHDLIBS="$SSHDLIBS -lpam" ++ KEYCATLIBS="$KEYCATLIBS -lpam" + AC_DEFINE([USE_PAM], [1], + [Define if you want to enable PAM support]) - #ifdef LINUX_OOM_ADJUST -diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/port-linux-sshd.c ---- openssh/openbsd-compat/port-linux-sshd.c.keycat 2015-06-24 10:57:50.150849626 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2015-06-24 10:57:50.159849603 +0200 -@@ -54,6 +54,20 @@ extern Authctxt *the_authctxt; +@@ -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; extern int inetd_flag; @@ -115,7 +162,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ /* Send audit message */ static int sshd_selinux_send_audit_message(int success, security_context_t default_context, -@@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -317,7 +331,7 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -124,7 +171,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ { const char *reqlvl; char *role; -@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void) +@@ -328,16 +342,16 @@ sshd_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); @@ -144,7 +191,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ if (role != NULL) free(role); -@@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void) +@@ -345,6 +359,24 @@ sshd_selinux_setup_pam_variables(void) return rv; } @@ -169,7 +216,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ /* Set the execution context to the default for the specified user */ void sshd_selinux_setup_exec_context(char *pwname) -@@ -344,7 +376,7 @@ sshd_selinux_setup_exec_context(char *pw +@@ -353,7 +385,7 @@ sshd_selinux_setup_exec_context(char *pwname) int r = 0; security_context_t default_ctx = NULL; @@ -178,7 +225,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ return; if (options.use_pam) { -@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void) +@@ -420,7 +452,7 @@ sshd_selinux_copy_context(void) { security_context_t *ctx; @@ -187,10 +234,26 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/ return; if (getexeccon((security_context_t *)&ctx) != 0) { -diff -up openssh/platform.c.keycat openssh/platform.c ---- openssh/platform.c.keycat 2015-06-24 10:57:50.147849633 +0200 -+++ openssh/platform.c 2015-06-24 10:57:50.160849601 +0200 -@@ -103,7 +103,7 @@ platform_setusercontext(struct passwd *p +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) { #ifdef WITH_SELINUX /* Cache selinux status for later use */ @@ -199,9 +262,11 @@ diff -up openssh/platform.c.keycat openssh/platform.c #endif #ifdef USE_SOLARIS_PROJECTS -diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c ---- openssh/ssh-keycat.c.keycat 2015-06-24 10:57:50.161849599 +0200 -+++ openssh/ssh-keycat.c 2015-06-24 10:57:50.161849599 +0200 +diff --git a/ssh-keycat.c b/ssh-keycat.c +new file mode 100644 +index 00000000..5678be07 +--- /dev/null ++++ b/ssh-keycat.c @@ -0,0 +1,241 @@ +/* + * Redistribution and use in source and binary forms, with or without @@ -444,41 +509,6 @@ diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c + } + return ev; +} -diff --git a/configure.ac b/configure.ac -index 3bbccfd..6481f1f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2952,6 +2952,7 @@ AC_ARG_WITH([pam], - PAM_MSG="yes" - - SSHDLIBS="$SSHDLIBS -lpam" -+ KEYCATLIBS="$KEYCATLIBS -lpam" - AC_DEFINE([USE_PAM], [1], - [Define if you want to enable PAM support]) - -@@ -3105,6 +3106,7 @@ - ;; - *) - SSHDLIBS="$SSHDLIBS -ldl" -+ KEYCATLIBS="$KEYCATLIBS -ldl" - ;; - esac - fi -@@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux], - fi ] - ) - AC_SUBST([SSHDLIBS]) -+AC_SUBST([KEYCATLIBS]) - - # Check whether user wants Kerberos 5 support - KRB5_MSG="no" -@@ -5031,6 +5034,9 @@ fi - if test ! -z "${SSHDLIBS}"; then - echo " +for sshd: ${SSHDLIBS}" - fi -+if test ! -z "${KEYCATLIBS}"; then -+echo " +for ssh-keycat: ${KEYCATLIBS}" -+fi - - echo "" - +-- +2.49.0 + diff --git a/openssh-6.6p1-allow-ip-opts.patch b/0004-openssh-6.6p1-allow-ip-opts.patch similarity index 68% rename from openssh-6.6p1-allow-ip-opts.patch rename to 0004-openssh-6.6p1-allow-ip-opts.patch index 995e04e..ef15fbf 100644 --- a/openssh-6.6p1-allow-ip-opts.patch +++ b/0004-openssh-6.6p1-allow-ip-opts.patch @@ -1,7 +1,17 @@ -diff -up openssh/sshd.c.ip-opts openssh/sshd.c ---- 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) +From 28333f1dfe68b0ffc80c2a4799759587b4c32d3e Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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) if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, &option_size) >= 0 && option_size != 0) { @@ -40,3 +50,6 @@ diff -up openssh/sshd.c.ip-opts openssh/sshd.c } #endif /* IP_OPTIONS */ } +-- +2.49.0 + diff --git a/openssh-5.9p1-ipv6man.patch b/0005-openssh-5.9p1-ipv6man.patch similarity index 54% rename from openssh-5.9p1-ipv6man.patch rename to 0005-openssh-5.9p1-ipv6man.patch index ece1a73..909b988 100644 --- a/openssh-5.9p1-ipv6man.patch +++ b/0005-openssh-5.9p1-ipv6man.patch @@ -1,7 +1,18 @@ -diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 ---- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 -+++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 -@@ -1400,6 +1400,8 @@ manual page for more information. +From 388be633842a9f3e4b0a76fe40cf7035912a913a Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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. .Nm exits with the exit status of the remote command or with 255 if an error occurred. @@ -10,10 +21,11 @@ diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , -diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 ---- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 -+++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 -@@ -940,6 +940,8 @@ concurrently for different ports, this c +diff --git a/sshd.8 b/sshd.8 +index 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 started last). The content of this file is not sensitive; it can be world-readable. .El @@ -22,3 +34,6 @@ diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , +-- +2.49.0 + diff --git a/0006-openssh-5.8p2-sigpipe.patch b/0006-openssh-5.8p2-sigpipe.patch new file mode 100644 index 0000000..5bf31bc --- /dev/null +++ b/0006-openssh-5.8p2-sigpipe.patch @@ -0,0 +1,26 @@ +From 80359feb76fd8061b5ce18f73451d7b9db0c2477 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-7.2p2-x11.patch b/0007-openssh-7.2p2-x11.patch similarity index 71% rename from openssh-7.2p2-x11.patch rename to 0007-openssh-7.2p2-x11.patch index 6db16be..2f72f9a 100644 --- a/openssh-7.2p2-x11.patch +++ b/0007-openssh-7.2p2-x11.patch @@ -1,22 +1,32 @@ -diff --git a/channels.c b/channels.c ---- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/channels.c (date 1703026069921) -@@ -5075,11 +5075,13 @@ - } +From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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, + } + static int -connect_local_xsocket_path(const char *pathname) +connect_local_xsocket_path(const char *pathname, int len) { int sock; struct sockaddr_un addr; - + + if (len <= 0) + return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { error("socket: %.100s", strerror(errno)); -@@ -5087,11 +5089,12 @@ +@@ -5110,11 +5112,12 @@ connect_local_xsocket_path(const char *pathname) } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; @@ -31,8 +41,8 @@ diff --git a/channels.c b/channels.c - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } - -@@ -5099,8 +5102,18 @@ + +@@ -5122,8 +5125,18 @@ static int connect_local_xsocket(u_int dnr) { char buf[1024]; @@ -53,3 +63,6 @@ diff --git a/channels.c b/channels.c } #ifdef __APPLE__ +-- +2.49.0 + diff --git a/openssh-5.1p1-askpass-progress.patch b/0008-openssh-5.1p1-askpass-progress.patch similarity index 66% rename from openssh-5.1p1-askpass-progress.patch rename to 0008-openssh-5.1p1-askpass-progress.patch index ff609da..f7ca382 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/0008-openssh-5.1p1-askpass-progress.patch @@ -1,7 +1,17 @@ -diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contrib/gnome-ssh-askpass2.c ---- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:16.545211926 +0100 -@@ -53,6 +53,7 @@ +From 6b2a33044583e892badb9ac86cd2c6252b1a532f Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ #include #include @@ -9,7 +19,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr #include #include #include -@@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia +@@ -146,6 +147,17 @@ parse_env_hex_color(const char *env, GdkColor *c) return 1; } @@ -27,7 +37,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr static int passphrase_dialog(char *message, int prompt_type) { - const char *failed; +@@ -153,7 +165,7 @@ passphrase_dialog(char *message, int prompt_type) char *passphrase, *local; int result, grab_tries, grab_server, grab_pointer; int buttons, default_response; @@ -36,7 +46,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr GdkGrabStatus status; GdkColor fg, bg; int fg_set = 0, bg_set = 0; -@@ -104,14 +116,19 @@ passphrase_dialog(char *message) +@@ -199,14 +211,19 @@ passphrase_dialog(char *message, int prompt_type) gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg); if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { @@ -45,12 +55,12 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr + FALSE, 0); + gtk_widget_show(hbox); + - entry = gtk_entry_new(); - if (fg_set) - gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); - if (bg_set) - gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); - gtk_box_pack_start( + entry = gtk_entry_new(); + if (fg_set) + gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); + if (bg_set) + gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); + gtk_box_pack_start( - GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), - entry, FALSE, FALSE, 0); + GTK_BOX(hbox), entry, TRUE, FALSE, 0); @@ -58,7 +68,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); if (prompt_type == PROMPT_ENTRY) { -@@ -130,6 +145,22 @@ passphrase_dialog(char *message) +@@ -225,6 +242,22 @@ passphrase_dialog(char *message, int prompt_type) g_signal_connect(G_OBJECT(entry), "key_press_event", G_CALLBACK(check_none), dialog); } @@ -81,3 +91,6 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr } /* Grab focus */ +-- +2.49.0 + diff --git a/openssh-4.3p2-askpass-grab-info.patch b/0009-openssh-4.3p2-askpass-grab-info.patch similarity index 53% rename from openssh-4.3p2-askpass-grab-info.patch rename to 0009-openssh-4.3p2-askpass-grab-info.patch index 120ed1b..8a7cf9e 100644 --- a/openssh-4.3p2-askpass-grab-info.patch +++ b/0009-openssh-4.3p2-askpass-grab-info.patch @@ -1,7 +1,17 @@ -diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c ---- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200 -+++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200 -@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi +From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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, @@ -16,3 +26,6 @@ diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/cont gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_dialog_run(GTK_DIALOG(err)); +-- +2.49.0 + diff --git a/openssh-8.7p1-redhat.patch b/0010-openssh-8.7p1-redhat.patch similarity index 67% rename from openssh-8.7p1-redhat.patch rename to 0010-openssh-8.7p1-redhat.patch index a4c11b5..cb3d140 100644 --- a/openssh-8.7p1-redhat.patch +++ b/0010-openssh-8.7p1-redhat.patch @@ -1,7 +1,26 @@ -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 @@ +From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k @@ -12,9 +31,11 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config +# included below. For more information, see manual page for +# update-crypto-policies(8) and ssh_config(5). +Include /etc/ssh/ssh_config.d/*.conf -diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat ---- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100 -+++ openssh/ssh_config_redhat 2020-02-13 18:13:39.180641839 +0100 +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 @@ +# 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 @@ -34,10 +55,30 @@ diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat + +# Uncomment this if you want to use .local domain +# Host *.local -diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0 ---- openssh/sshd_config.0.redhat 2020-02-12 14:30:04.000000000 +0100 -+++ openssh/sshd_config.0 2020-02-13 18:13:39.181641855 +0100 -@@ -970,9 +970,9 @@ DESCRIPTION +diff --git a/sshd_config b/sshd_config +index 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 SyslogFacility Gives the facility code that is used when logging messages from @@ -50,10 +91,11 @@ diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0 TCPKeepAlive Specifies whether the system should send TCP keepalive messages -diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 ---- openssh/sshd_config.5.redhat 2020-02-11 23:28:35.000000000 +0100 -+++ openssh/sshd_config.5 2020-02-13 18:13:39.181641855 +0100 -@@ -1614,7 +1614,7 @@ By default no subsystems are defined. +diff --git a/sshd_config.5 b/sshd_config.5 +index c0771737..035a50c8 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1942,7 +1942,7 @@ By default no subsystems are defined. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . @@ -62,27 +104,11 @@ diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive -diff -up openssh/sshd_config.redhat openssh/sshd_config ---- openssh/sshd_config.redhat 2020-02-11 23:28:35.000000000 +0100 -+++ openssh/sshd_config 2020-02-13 18:20:16.349913681 +0100 -@@ -10,6 +10,14 @@ - # possible, but leave them commented. Uncommented options override the - # default value. - -+# To modify the system-wide sshd configuration, create a *.conf file under -+# /etc/ssh/sshd_config.d/ which will be automatically included below -+Include /etc/ssh/sshd_config.d/*.conf -+ -+# If you want to change the port on a SELinux system, you have to tell -+# SELinux about this change. -+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER -+# - #Port 22 - #AddressFamily any - #ListenAddress 0.0.0.0 -diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat ---- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100 -+++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100 +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 @@ +SyslogFacility AUTHPRIV + @@ -102,9 +128,11 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +# as it is more configurable and versatile than the built-in version. +PrintMotd no + -diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat ---- openssh/sshd_config_redhat_cp.redhat 2020-02-13 18:14:02.268006439 +0100 -+++ openssh/sshd_config_redhat_cp 2020-02-13 18:19:20.765035947 +0100 +diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp +new file mode 100644 +index 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 @@ -113,3 +141,6 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +# Please, see manual pages for update-crypto-policies(8) and sshd_config(5). +Include /etc/crypto-policies/back-ends/opensshserver.config + +-- +2.49.0 + diff --git a/openssh-7.8p1-UsePAM-warning.patch b/0011-openssh-7.8p1-UsePAM-warning.patch similarity index 50% rename from openssh-7.8p1-UsePAM-warning.patch rename to 0011-openssh-7.8p1-UsePAM-warning.patch index f8d7042..76ee115 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/0011-openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,18 @@ -diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c ---- 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) +From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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"); } @@ -12,10 +23,11 @@ diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c #ifdef WITH_OPENSSL if (options.moduli_file != NULL) dh_set_moduli_file(options.moduli_file); -diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config ---- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200 -+++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200 -@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys +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'. @@ -24,3 +36,6 @@ diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config #UsePAM no #AllowAgentForwarding yes +-- +2.49.0 + diff --git a/openssh-9.6p1-gssapi-keyex.patch b/0012-openssh-9.6p1-gssapi-keyex.patch similarity index 89% rename from openssh-9.6p1-gssapi-keyex.patch rename to 0012-openssh-9.6p1-gssapi-keyex.patch index ef1f97e..f5f54f7 100644 --- a/openssh-9.6p1-gssapi-keyex.patch +++ b/0012-openssh-9.6p1-gssapi-keyex.patch @@ -1,25 +1,111 @@ -diff --color -ruNp a/auth2.c b/auth2.c ---- a/auth2.c 2024-09-16 11:45:56.858133241 +0200 -+++ b/auth2.c 2024-09-16 11:46:34.688939755 +0200 -@@ -71,6 +71,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif +From 754b023b92aa68742258c55243a6ae8f30ed5a17 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex + +--- + Makefile.in | 7 +- + auth.c | 3 +- + auth2-gss.c | 52 +++- + auth2-methods.c | 6 + + auth2.c | 2 + + canohost.c | 93 +++++++ + canohost.h | 3 + + clientloop.c | 12 + + configure.ac | 24 ++ + gss-genr.c | 302 ++++++++++++++++++++- + gss-serv-krb5.c | 97 ++++++- + gss-serv.c | 200 ++++++++++++-- + kex-names.c | 62 ++++- + kex.c | 35 ++- + kex.h | 34 +++ + kexdh.c | 10 + + kexgen.c | 2 +- + kexgssc.c | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ + kexgsss.c | 601 +++++++++++++++++++++++++++++++++++++++++ + monitor.c | 147 +++++++++- + monitor.h | 2 + + monitor_wrap.c | 57 +++- + monitor_wrap.h | 4 +- + readconf.c | 70 +++++ + readconf.h | 6 + + servconf.c | 47 ++++ + servconf.h | 3 + + session.c | 10 +- + ssh-gss.h | 64 ++++- + ssh.1 | 8 + + ssh.c | 6 +- + ssh_config | 2 + + ssh_config.5 | 58 ++++ + sshconnect2.c | 154 ++++++++++- + sshd-auth.c | 53 ++++ + sshd-session.c | 9 +- + sshd.c | 3 +- + sshd_config | 2 + + sshd_config.5 | 31 +++ + sshkey.c | 72 ++++- + sshkey.h | 1 + + 41 files changed, 2984 insertions(+), 76 deletions(-) + create mode 100644 kexgssc.c + create mode 100644 kexgsss.c + +diff --git a/Makefile.in b/Makefile.in +index 438efc51..78f65948 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -117,6 +117,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexgexc.o kexgexs.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ ++ kexgssc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sshbuf-io.o -@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - &method_passwd, -diff --color -ruNp a/auth2-gss.c b/auth2-gss.c ---- a/auth2-gss.c 2024-09-16 11:45:56.858133241 +0200 -+++ b/auth2-gss.c 2024-09-16 11:46:34.689939776 +0200 +@@ -138,7 +139,7 @@ SSHD_SESSION_OBJS=sshd-session.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 \ ++ 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 \ + sftp-server.o sftp-common.o \ +@@ -150,7 +151,7 @@ SSHD_AUTH_OBJS=sshd-auth.o \ + serverloop.o auth.o auth2.o auth-options.o session.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 \ +- auth2-gss.o gss-serv.o gss-serv-krb5.o \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ +@@ -563,7 +564,7 @@ regress-prep: + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile + + REGRESSLIBS=libssh.a $(LIBCOMPAT) +-TESTLIBS=$(LIBS) $(CHANNELLIBS) ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) + + regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ +diff --git a/auth.c b/auth.c +index 9a6e5a31..e4578169 100644 +--- a/auth.c ++++ b/auth.c +@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || +- strcmp(method, "gssapi-with-mic") == 0) ++ strcmp(method, "gssapi-with-mic") == 0 || ++ strcmp(method, "gssapi-keyex") == 0) + return 1; + break; + case PERMIT_FORCED_ONLY: +diff --git a/auth2-gss.c b/auth2-gss.c +index f7898ab3..5b1b9cde 100644 +--- a/auth2-gss.c ++++ b/auth2-gss.c @@ -51,6 +51,7 @@ #define SSH_GSSAPI_MAX_MECHS 2048 @@ -28,10 +114,11 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c extern struct authmethod_cfg methodcfg_gssapi; static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); -@@ -59,6 +60,48 @@ static int input_gssapi_exchange_complet +@@ -58,6 +59,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 *); - /* ++/* + * The 'gssapi_keyex' userauth mechanism. + */ +static int @@ -73,11 +160,10 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c + return (authenticated); +} + -+/* + /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) - */ -@@ -267,7 +310,7 @@ input_gssapi_exchange_complete(int type, +@@ -267,7 +310,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"); @@ -86,7 +172,7 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c authctxt->postponed = 0; ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -315,7 +358,7 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -315,7 +358,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) gssbuf.length = sshbuf_len(b); if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) @@ -95,7 +181,7 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -333,6 +376,11 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -333,6 +376,11 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) return 0; } @@ -107,10 +193,11 @@ diff --color -ruNp a/auth2-gss.c b/auth2-gss.c Authmethod method_gssapi = { &methodcfg_gssapi, userauth_gssapi, -diff --color -ruNp a/auth2-methods.c b/auth2-methods.c ---- a/auth2-methods.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/auth2-methods.c 2024-09-16 11:46:34.689939776 +0200 -@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = +diff --git a/auth2-methods.c b/auth2-methods.c +index 99637a89..a05908cf 100644 +--- a/auth2-methods.c ++++ b/auth2-methods.c +@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = { &options.pubkey_authentication }; #ifdef GSSAPI @@ -122,7 +209,7 @@ diff --color -ruNp a/auth2-methods.c b/auth2-methods.c struct authmethod_cfg methodcfg_gssapi = { "gssapi-with-mic", NULL, -@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod +@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod_cfgs[] = { &methodcfg_none, &methodcfg_pubkey, #ifdef GSSAPI @@ -130,22 +217,30 @@ diff --color -ruNp a/auth2-methods.c b/auth2-methods.c &methodcfg_gssapi, #endif &methodcfg_passwd, -diff --color -ruNp a/auth.c b/auth.c ---- a/auth.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/auth.c 2024-09-16 11:46:34.690939798 +0200 -@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -- strcmp(method, "gssapi-with-mic") == 0) -+ strcmp(method, "gssapi-with-mic") == 0 || -+ strcmp(method, "gssapi-keyex") == 0) - return 1; - break; - case PERMIT_FORCED_ONLY: -diff --color -ruNp a/canohost.c b/canohost.c ---- a/canohost.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/canohost.c 2024-09-16 11:46:34.690939798 +0200 +diff --git a/auth2.c b/auth2.c +index 5ba45c12..8ec41de2 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -71,6 +71,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif + +@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + &method_passwd, +diff --git a/canohost.c b/canohost.c +index 28f086e5..875805c9 100644 +--- a/canohost.c ++++ b/canohost.c @@ -35,6 +35,99 @@ #include "canohost.h" #include "misc.h" @@ -246,9 +341,10 @@ diff --color -ruNp a/canohost.c b/canohost.c void ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { -diff --color -ruNp a/canohost.h b/canohost.h ---- a/canohost.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/canohost.h 2024-09-16 11:46:34.690939798 +0200 +diff --git a/canohost.h b/canohost.h +index 26d62855..0cadc9f1 100644 +--- a/canohost.h ++++ b/canohost.h @@ -15,6 +15,9 @@ #ifndef _CANOHOST_H #define _CANOHOST_H @@ -259,9 +355,10 @@ diff --color -ruNp a/canohost.h b/canohost.h char *get_peer_ipaddr(int); int get_peer_port(int); char *get_local_ipaddr(int); -diff --color -ruNp a/clientloop.c b/clientloop.c ---- a/clientloop.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/clientloop.c 2024-09-16 11:46:34.690939798 +0200 +diff --git a/clientloop.c b/clientloop.c +index 916fc077..4655f91f 100644 +--- a/clientloop.c ++++ b/clientloop.c @@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -273,7 +370,7 @@ diff --color -ruNp a/clientloop.c b/clientloop.c /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1590,6 +1594,14 @@ client_loop(struct ssh *ssh, int have_pt +@@ -1591,6 +1595,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -288,10 +385,11 @@ diff --color -ruNp a/clientloop.c b/clientloop.c /* Buffer input from the connection. */ if (conn_in_ready) client_process_net_input(ssh); -diff --color -ruNp a/configure.ac b/configure.ac ---- a/configure.ac 2024-09-16 11:45:56.870133497 +0200 -+++ b/configure.ac 2024-09-16 11:46:34.691939819 +0200 -@@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeL +diff --git a/configure.ac b/configure.ac +index d546788c..13c70a98 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -786,6 +786,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -322,9 +420,10 @@ diff --color -ruNp a/configure.ac b/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff --color -ruNp a/gss-genr.c b/gss-genr.c ---- a/gss-genr.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-genr.c 2024-09-16 11:46:34.708940181 +0200 +diff --git a/gss-genr.c b/gss-genr.c +index aa34b71c..3034370c 100644 +--- a/gss-genr.c ++++ b/gss-genr.c @@ -42,9 +42,33 @@ #include "sshbuf.h" #include "log.h" @@ -359,7 +458,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf +@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -540,7 +639,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c free(*ctx); *ctx = NULL; -@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de +@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -549,10 +648,11 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -246,8 +430,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con +@@ -245,9 +429,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) + return (ctx->major); } - OM_uint32 ++OM_uint32 +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) +{ + gss_buffer_desc gssbuf; @@ -583,7 +683,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c + return(ctx->major); +} + -+OM_uint32 + OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { + if (ctx == NULL) @@ -592,7 +692,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer +@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -612,7 +712,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co +@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } int @@ -630,7 +730,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -285,6 +521,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -285,6 +521,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); @@ -641,7 +741,7 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -709,9 +809,150 @@ diff --color -ruNp a/gss-genr.c b/gss-genr.c +} + #endif /* GSSAPI */ -diff --color -ruNp a/gss-serv.c b/gss-serv.c ---- a/gss-serv.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-serv.c 2024-09-16 11:46:34.692939840 +0200 +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index a151bc1e..8d2b677f 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus 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 +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; +- int len; ++ const char *new_ccname, *new_cctype; + const char *errmsg; + + if (client->creds == NULL) { +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + return; + } + +- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); ++ new_cctype = krb5_cc_get_type(krb_context, ccache); ++ new_ccname = krb5_cc_get_name(krb_context, ccache); ++ + client->store.envvar = "KRB5CCNAME"; +- len = strlen(client->store.filename) + 6; +- client->store.envval = xmalloc(len); +- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); ++#ifdef USE_CCAPI ++ xasprintf(&client->store.envval, "API:%s", new_ccname); ++ client->store.filename = NULL; ++#else ++ if (new_ccname[0] == ':') ++ new_ccname++; ++ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); ++ if (strcmp(new_cctype, "DIR") == 0) { ++ char *p; ++ p = strrchr(client->store.envval, '/'); ++ if (p) ++ *p = '\0'; ++ } ++ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) ++ client->store.filename = xstrdup(new_ccname); ++#endif + + #ifdef USE_PAM + if (options.use_pam) +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) + + krb5_cc_close(krb_context, ccache); + ++ client->store.data = krb_context; ++ + return; + } + ++int ++ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ++ ssh_gssapi_client *client) ++{ ++ krb5_ccache ccache = NULL; ++ krb5_principal principal = NULL; ++ char *name = NULL; ++ krb5_error_code problem; ++ OM_uint32 maj_status, min_status; ++ ++ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { ++ logit("krb5_cc_resolve(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ return 0; ++ } ++ ++ /* Find out who the principal in this cache is */ ++ if ((problem = krb5_cc_get_principal(krb_context, ccache, ++ &principal))) { ++ logit("krb5_cc_get_principal(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { ++ logit("krb5_unparse_name(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ ++ if (strcmp(name,client->exportedname.value)!=0) { ++ debug("Name in local credentials cache differs. Not storing"); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ krb5_free_unparsed_name(krb_context, name); ++ return 0; ++ } ++ krb5_free_unparsed_name(krb_context, name); ++ ++ /* Name matches, so lets get on with it! */ ++ ++ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { ++ logit("krb5_cc_initialize(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ krb5_free_principal(krb_context, principal); ++ ++ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ++ ccache))) { ++ logit("gss_krb5_copy_ccache() failed. Sorry!"); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ return 1; ++} ++ + ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", +@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { + NULL, + &ssh_gssapi_krb5_userok, + NULL, +- &ssh_gssapi_krb5_storecreds ++ &ssh_gssapi_krb5_storecreds, ++ &ssh_gssapi_krb5_updatecreds + }; + + #endif /* KRB5 */ +diff --git a/gss-serv.c b/gss-serv.c +index 025a118f..a5cca797 100644 +--- a/gss-serv.c ++++ b/gss-serv.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ @@ -721,7 +962,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -44,17 +44,19 @@ +@@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" #include "servconf.h" @@ -744,10 +985,11 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss +@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) + return (ssh_gssapi_acquire_cred(*ctx)); } - /* Unprivileged */ ++/* Unprivileged */ +char * +ssh_gssapi_server_mechanisms(void) { + if (supported_oids == NULL) @@ -770,11 +1012,10 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c + return (res); +} + -+/* Unprivileged */ + /* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) - { -@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o +@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -785,7 +1026,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -276,8 +303,48 @@ OM_uint32 +@@ -277,8 +304,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -835,7 +1076,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c client->mech = NULL; -@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) if (client->mech == NULL) return GSS_S_FAILURE; @@ -849,7 +1090,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } @@ -858,7 +1099,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) void ssh_gssapi_cleanup_creds(void) { @@ -884,7 +1125,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c } } -@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int +@@ -357,19 +442,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) /* Privileged */ int @@ -911,7 +1152,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) +@@ -383,14 +472,85 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1003,148 +1244,114 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c } /* Privileged */ -diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c ---- a/gss-serv-krb5.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/gss-serv-krb5.c 2024-09-16 11:46:34.692939840 +0200 -@@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ +diff --git a/kex-names.c b/kex-names.c +index ec840c1f..6c0b7c2b 100644 +--- a/kex-names.c ++++ b/kex-names.c +@@ -45,6 +45,10 @@ + #include "ssherr.h" + #include "xmalloc.h" - /* -- * 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 -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - krb5_error_code problem; - krb5_principal princ; - OM_uint32 maj_status, min_status; -- int len; -+ const char *new_ccname, *new_cctype; - const char *errmsg; - - if (client->creds == NULL) { -@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - return; - } - -- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); -+ new_cctype = krb5_cc_get_type(krb_context, ccache); -+ new_ccname = krb5_cc_get_name(krb_context, ccache); -+ - client->store.envvar = "KRB5CCNAME"; -- len = strlen(client->store.filename) + 6; -- client->store.envval = xmalloc(len); -- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); -+#ifdef USE_CCAPI -+ xasprintf(&client->store.envval, "API:%s", new_ccname); -+ client->store.filename = NULL; -+#else -+ if (new_ccname[0] == ':') -+ new_ccname++; -+ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); -+ if (strcmp(new_cctype, "DIR") == 0) { -+ char *p; -+ p = strrchr(client->store.envval, '/'); -+ if (p) -+ *p = '\0'; -+ } -+ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) -+ client->store.filename = xstrdup(new_ccname); ++#ifdef GSSAPI ++#include "ssh-gss.h" +#endif - - #ifdef USE_PAM - if (options.use_pam) -@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl - - krb5_cc_close(krb_context, ccache); - -+ client->store.data = krb_context; + - return; + struct kexalg { + char *name; + u_int type; +@@ -89,15 +93,28 @@ static const struct kexalg kexalgs[] = { + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, 0, -1, -1}, + }; ++static const struct kexalg gss_kexalgs[] = { ++#ifdef GSSAPI ++ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, ++#endif ++ { NULL, 0, -1, -1}, ++}; + +-char * +-kex_alg_list(char sep) ++static char * ++kex_alg_list_internal(char sep, const struct kexalg *algs) + { + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = algs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -112,6 +129,18 @@ kex_alg_list(char sep) + return ret; } -+int -+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, -+ ssh_gssapi_client *client) ++char * ++kex_alg_list(char sep) +{ -+ krb5_ccache ccache = NULL; -+ krb5_principal principal = NULL; -+ char *name = NULL; -+ krb5_error_code problem; -+ OM_uint32 maj_status, min_status; -+ -+ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { -+ logit("krb5_cc_resolve(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ return 0; -+ } -+ -+ /* Find out who the principal in this cache is */ -+ if ((problem = krb5_cc_get_principal(krb_context, ccache, -+ &principal))) { -+ logit("krb5_cc_get_principal(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { -+ logit("krb5_unparse_name(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ -+ if (strcmp(name,client->exportedname.value)!=0) { -+ debug("Name in local credentials cache differs. Not storing"); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ krb5_free_unparsed_name(krb_context, name); -+ return 0; -+ } -+ krb5_free_unparsed_name(krb_context, name); -+ -+ /* Name matches, so lets get on with it! */ -+ -+ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { -+ logit("krb5_cc_initialize(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ krb5_free_principal(krb_context, principal); -+ -+ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, -+ ccache))) { -+ logit("gss_krb5_copy_ccache() failed. Sorry!"); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ return 1; ++ return kex_alg_list_internal(sep, kexalgs); +} + - ssh_gssapi_mech gssapi_kerberos_mech = { - "toWM5Slw5Ew8Mqkay+al2g==", - "Kerberos", -@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { - NULL, - &ssh_gssapi_krb5_userok, - NULL, -- &ssh_gssapi_krb5_storecreds -+ &ssh_gssapi_krb5_storecreds, -+ &ssh_gssapi_krb5_updatecreds - }; ++char * ++kex_gss_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, gss_kexalgs); ++} ++ + static const struct kexalg * + kex_alg_by_name(const char *name) + { +@@ -121,6 +150,10 @@ kex_alg_by_name(const char *name) + if (strcmp(k->name, name) == 0) + return k; + } ++ for (k = gss_kexalgs; k->name != NULL; k++) { ++ if (strncmp(k->name, name, strlen(k->name)) == 0) ++ return k; ++ } + return NULL; + } - #endif /* KRB5 */ -diff --color -ruNp a/kex.c b/kex.c ---- a/kex.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex.c 2024-09-16 11:46:34.692939840 +0200 +@@ -334,3 +367,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) ++{ ++ char *s, *cp, *p; ++ ++ if (names == NULL || *names == '\0') ++ return 0; ++ s = cp = xstrdup(names); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (strncmp(p, "gss-", 4) != 0 ++ || kex_alg_by_name(p) == NULL) { ++ error("Unsupported KEX algorithm \"%.100s\"", p); ++ free(s); ++ return 0; ++ } ++ } ++ debug3("gss kex names ok: [%s]", names); ++ free(s); ++ return 1; ++} +diff --git a/kex.c b/kex.c +index 6b957e5e..19a56e8e 100644 +--- a/kex.c ++++ b/kex.c @@ -297,17 +297,37 @@ static int kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { @@ -1199,9 +1406,92 @@ diff --color -ruNp a/kex.c b/kex.c sshbuf_free(kex->initial_sig); sshkey_free(kex->initial_hostkey); free(kex->failed_choice); -diff --color -ruNp a/kexdh.c b/kexdh.c ---- a/kexdh.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kexdh.c 2024-09-16 11:46:34.693939862 +0200 +diff --git a/kex.h b/kex.h +index d08988b3..0e080ea3 100644 +--- a/kex.h ++++ b/kex.h +@@ -29,6 +29,10 @@ + #include "mac.h" + #include "crypto_api.h" + ++#ifdef GSSAPI ++# include "ssh-gss.h" /* Gssctxt */ ++#endif ++ + #ifdef WITH_OPENSSL + # include + # include +@@ -103,6 +107,15 @@ enum kex_exchange { + KEX_C25519_SHA256, + KEX_KEM_SNTRUP761X25519_SHA512, + KEX_KEM_MLKEM768X25519_SHA256, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GRP14_SHA256, ++ KEX_GSS_GRP16_SHA512, ++ KEX_GSS_GEX_SHA1, ++ KEX_GSS_NISTP256_SHA256, ++ KEX_GSS_C25519_SHA256, ++#endif + KEX_MAX + }; + +@@ -165,6 +178,13 @@ struct kex { + u_int flags; + int hash_alg; + int ec_nid; ++#ifdef GSSAPI ++ Gssctxt *gss; ++ int gss_deleg_creds; ++ int gss_trust_dns; ++ char *gss_host; ++ char *gss_client; ++#endif + char *failed_choice; + int (*verify_host_key)(struct sshkey *, struct ssh *); + struct sshkey *(*load_host_public_key)(int, int, struct ssh *); +@@ -191,8 +211,10 @@ int kex_hash_from_name(const char *); + 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_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 *); +@@ -226,6 +248,12 @@ int kexgex_client(struct ssh *); + int kexgex_server(struct ssh *); + int kex_gen_client(struct ssh *); + int kex_gen_server(struct ssh *); ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++int kexgssgex_client(struct ssh *); ++int kexgssgex_server(struct ssh *); ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); ++#endif + + int kex_dh_keypair(struct kex *); + int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, +@@ -264,6 +292,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, + const BIGNUM *, const u_char *, size_t, + u_char *, size_t *); + ++int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, ++ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, ++ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, ++ const struct sshbuf *client_pub, const struct sshbuf *server_pub, ++ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); ++ + void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); +diff --git a/kexdh.c b/kexdh.c +index c1084f21..0faab21b 100644 +--- a/kexdh.c ++++ b/kexdh.c @@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { @@ -1226,9 +1516,10 @@ diff --color -ruNp a/kexdh.c b/kexdh.c kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: -diff --color -ruNp a/kexgen.c b/kexgen.c ---- a/kexgen.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kexgen.c 2024-09-16 11:46:34.693939862 +0200 +diff --git a/kexgen.c b/kexgen.c +index 40d688d6..15df591c 100644 +--- a/kexgen.c ++++ b/kexgen.c @@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1238,9 +1529,11 @@ diff --color -ruNp a/kexgen.c b/kexgen.c kex_gen_hash( int hash_alg, const struct sshbuf *client_version, -diff --color -ruNp a/kexgssc.c b/kexgssc.c ---- a/kexgssc.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgssc.c 2024-10-14 15:18:02.491798105 +0200 +diff --git a/kexgssc.c b/kexgssc.c +new file mode 100644 +index 00000000..96f7b6f5 +--- /dev/null ++++ b/kexgssc.c @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1948,9 +2241,11 @@ diff --color -ruNp a/kexgssc.c b/kexgssc.c +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --color -ruNp a/kexgsss.c b/kexgsss.c ---- a/kexgsss.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kexgsss.c 2024-10-14 15:18:02.491798105 +0200 +diff --git a/kexgsss.c b/kexgsss.c +new file mode 100644 +index 00000000..8362081e +--- /dev/null ++++ b/kexgsss.c @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2553,223 +2848,11 @@ diff --color -ruNp a/kexgsss.c b/kexgsss.c +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --color -ruNp a/kex.h b/kex.h ---- a/kex.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex.h 2024-09-16 11:46:34.710940224 +0200 -@@ -29,6 +29,10 @@ - #include "mac.h" - #include "crypto_api.h" - -+#ifdef GSSAPI -+# include "ssh-gss.h" /* Gssctxt */ -+#endif -+ - #ifdef WITH_OPENSSL - # include - # include -@@ -102,6 +106,15 @@ enum kex_exchange { - KEX_C25519_SHA256, - KEX_KEM_SNTRUP761X25519_SHA512, - KEX_KEM_MLKEM768X25519_SHA256, -+#ifdef GSSAPI -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GRP14_SHA256, -+ KEX_GSS_GRP16_SHA512, -+ KEX_GSS_GEX_SHA1, -+ KEX_GSS_NISTP256_SHA256, -+ KEX_GSS_C25519_SHA256, -+#endif - KEX_MAX - }; - -@@ -164,6 +177,13 @@ struct kex { - u_int flags; - int hash_alg; - int ec_nid; -+#ifdef GSSAPI -+ Gssctxt *gss; -+ int gss_deleg_creds; -+ int gss_trust_dns; -+ char *gss_host; -+ char *gss_client; -+#endif - char *failed_choice; - int (*verify_host_key)(struct sshkey *, struct ssh *); - struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -189,8 +209,10 @@ int kex_hash_from_name(const char *); - 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_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 *); -@@ -224,6 +246,12 @@ int kexgex_client(struct ssh *); - int kexgex_server(struct ssh *); - int kex_gen_client(struct ssh *); - int kex_gen_server(struct ssh *); -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+int kexgssgex_client(struct ssh *); -+int kexgssgex_server(struct ssh *); -+int kexgss_client(struct ssh *); -+int kexgss_server(struct ssh *); -+#endif - - int kex_dh_keypair(struct kex *); - int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -256,6 +284,12 @@ int kexgex_hash(int, const struct sshbu - const BIGNUM *, const u_char *, size_t, - u_char *, size_t *); - -+int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, -+ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, -+ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, -+ const struct sshbuf *client_pub, const struct sshbuf *server_pub, -+ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); -+ - void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) - __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) - __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -diff --color -ruNp a/kex-names.c b/kex-names.c ---- a/kex-names.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/kex-names.c 2024-09-16 11:46:34.694939883 +0200 -@@ -45,6 +45,10 @@ - #include "ssherr.h" - #include "xmalloc.h" - -+#ifdef GSSAPI -+#include "ssh-gss.h" -+#endif -+ - struct kexalg { - char *name; - u_int type; -@@ -83,15 +87,28 @@ static const struct kexalg kexalgs[] = { - #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, - }; -+static const struct kexalg gss_kexalgs[] = { -+#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -+#endif -+ { NULL, 0, -1, -1}, -+}; - --char * --kex_alg_list(char sep) -+static char * -+kex_alg_list_internal(char sep, const struct kexalg *algs) - { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; - const struct kexalg *k; - -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = algs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -106,6 +123,18 @@ kex_alg_list(char sep) - return ret; - } - -+char * -+kex_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, kexalgs); -+} -+ -+char * -+kex_gss_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, gss_kexalgs); -+} -+ - static const struct kexalg * - kex_alg_by_name(const char *name) - { -@@ -115,6 +144,10 @@ kex_alg_by_name(const char *name) - if (strcmp(k->name, name) == 0) - return k; - } -+ for (k = gss_kexalgs; k->name != NULL; k++) { -+ if (strncmp(k->name, name, strlen(k->name)) == 0) -+ return k; -+ } - return NULL; - } - -@@ -328,3 +361,26 @@ kex_assemble_names(char **listp, const c - free(ret); - return r; - } -+ -+/* Validate GSS KEX method name list */ -+int -+kex_gss_names_valid(const char *names) -+{ -+ char *s, *cp, *p; -+ -+ if (names == NULL || *names == '\0') -+ return 0; -+ s = cp = xstrdup(names); -+ for ((p = strsep(&cp, ",")); p && *p != '\0'; -+ (p = strsep(&cp, ","))) { -+ if (strncmp(p, "gss-", 4) != 0 -+ || kex_alg_by_name(p) == NULL) { -+ error("Unsupported KEX algorithm \"%.100s\"", p); -+ free(s); -+ return 0; -+ } -+ } -+ debug3("gss kex names ok: [%s]", names); -+ free(s); -+ return 1; -+} -diff --color -ruNp a/Makefile.in b/Makefile.in ---- a/Makefile.in 2024-09-16 11:45:56.868133454 +0200 -+++ b/Makefile.in 2024-09-16 11:46:34.695939904 +0200 -@@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ - kexgexc.o kexgexs.o \ - kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ -+ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o - -@@ -135,7 +136,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rh - 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 \ -+ 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 \ - sftp-server.o sftp-common.o \ -@@ -529,7 +530,7 @@ regress-prep: - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile - - REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) - - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ -diff --color -ruNp a/monitor.c b/monitor.c ---- a/monitor.c 2024-09-16 11:45:56.861133305 +0200 -+++ b/monitor.c 2024-09-16 11:46:34.696939926 +0200 -@@ -143,6 +143,8 @@ int mm_answer_gss_setup_ctx(struct ssh * +diff --git a/monitor.c b/monitor.c +index 02b3eaaa..2ef16cc8 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -2778,7 +2861,7 @@ diff --color -ruNp a/monitor.c b/monitor.c #endif #ifdef SSH_AUDIT_EVENTS -@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] +@@ -224,11 +226,18 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2794,11 +2877,11 @@ diff --color -ruNp a/monitor.c b/monitor.c + {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, + {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, +#endif + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, - #endif -@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, s - /* Permit requests for moduli and signatures */ +@@ -299,6 +308,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +#ifdef GSSAPI @@ -2808,7 +2891,7 @@ diff --color -ruNp a/monitor.c b/monitor.c /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -344,8 +357,15 @@ monitor_child_preauth(struct ssh *ssh, s +@@ -351,8 +364,15 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(ssh, authenticated, partial, auth_method, auth_submethod); @@ -2825,7 +2908,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if (authenticated || partial) { auth2_update_session_info(authctxt, auth_method, auth_submethod); -@@ -413,6 +433,10 @@ monitor_child_postauth(struct ssh *ssh, +@@ -421,6 +441,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2836,7 +2919,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1793,6 +1817,17 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1890,6 +1914,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2854,7 +2937,7 @@ diff --color -ruNp a/monitor.c b/monitor.c #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1885,8 +1920,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, +@@ -1981,8 +2016,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2865,7 +2948,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1918,8 +1953,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh +@@ -2014,8 +2049,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2876,7 +2959,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1939,6 +1974,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh +@@ -2035,6 +2070,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2884,7 +2967,7 @@ diff --color -ruNp a/monitor.c b/monitor.c } return (0); } -@@ -1950,8 +1986,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, +@@ -2046,8 +2082,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2895,7 +2978,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1977,13 +2013,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, +@@ -2073,13 +2109,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2907,17 +2990,17 @@ diff --color -ruNp a/monitor.c b/monitor.c - fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) + fatal_f("GSSAPI not enabled"); - -- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); ++ + if ((r = sshbuf_get_u32(m, &kex)) != 0) + fatal_fr(r, "buffer error"); -+ + +- authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1992,7 +2032,11 @@ mm_answer_gss_userok(struct ssh *ssh, in +@@ -2088,7 +2128,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2930,7 +3013,7 @@ diff --color -ruNp a/monitor.c b/monitor.c if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -2000,5 +2044,84 @@ mm_answer_gss_userok(struct ssh *ssh, in +@@ -2096,5 +2140,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -3015,10 +3098,11 @@ diff --color -ruNp a/monitor.c b/monitor.c + #endif /* GSSAPI */ -diff --color -ruNp a/monitor.h b/monitor.h ---- a/monitor.h 2024-09-16 11:45:56.861133305 +0200 -+++ b/monitor.h 2024-09-16 11:46:34.696939926 +0200 -@@ -67,6 +67,8 @@ enum monitor_reqtype { +diff --git a/monitor.h b/monitor.h +index 9dcd9c29..dbc7e003 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -68,6 +68,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -3027,10 +3111,11 @@ diff --color -ruNp a/monitor.h b/monitor.h }; struct ssh; -diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c ---- a/monitor_wrap.c 2024-09-16 11:45:56.862133326 +0200 -+++ b/monitor_wrap.c 2024-09-16 11:46:34.697939947 +0200 -@@ -1075,13 +1075,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff --git a/monitor_wrap.c b/monitor_wrap.c +index ef3ab1b1..b6e3b3f3 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -1131,13 +1131,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -3047,7 +3132,7 @@ diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1094,6 +1096,59 @@ mm_ssh_gssapi_userok(char *user) +@@ -1150,6 +1152,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -3107,10 +3192,11 @@ diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c #endif /* GSSAPI */ /* -diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h ---- a/monitor_wrap.h 2024-09-16 11:45:56.862133326 +0200 -+++ b/monitor_wrap.h 2024-09-16 11:46:34.697939947 +0200 -@@ -67,8 +67,10 @@ void mm_decode_activate_server_options(s +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 38a280c8..672dce52 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -67,8 +67,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -3122,18 +3208,19 @@ diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h #endif #ifdef USE_PAM -diff --color -ruNp a/readconf.c b/readconf.c ---- a/readconf.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/readconf.c 2024-09-16 11:46:34.699939990 +0200 -@@ -70,6 +70,7 @@ - #include "uidswap.h" +diff --git a/readconf.c b/readconf.c +index 7cbe7d2c..6c04ed43 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -71,6 +71,7 @@ #include "myproposal.h" #include "digest.h" + #include "version.h" +#include "ssh-gss.h" /* Format of the configuration file: -@@ -164,6 +165,8 @@ typedef enum { +@@ -165,6 +166,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -3142,7 +3229,7 @@ diff --color -ruNp a/readconf.c b/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -210,10 +213,22 @@ static struct { +@@ -212,10 +215,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -3165,7 +3252,7 @@ diff --color -ruNp a/readconf.c b/readconf.c #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1227,10 +1242,42 @@ parse_time: +@@ -1320,10 +1335,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3208,7 +3295,7 @@ diff --color -ruNp a/readconf.c b/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2542,7 +2589,13 @@ initialize_options(Options * options) +@@ -2662,7 +2709,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3222,7 +3309,7 @@ diff --color -ruNp a/readconf.c b/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2705,8 +2758,18 @@ fill_default_options(Options * options) +@@ -2826,8 +2879,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3241,7 +3328,7 @@ diff --color -ruNp a/readconf.c b/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3533,7 +3596,14 @@ dump_client_config(Options *o, const cha +@@ -3656,7 +3719,14 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3256,10 +3343,11 @@ diff --color -ruNp a/readconf.c b/readconf.c #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff --color -ruNp a/readconf.h b/readconf.h ---- a/readconf.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/readconf.h 2024-09-16 11:46:34.699939990 +0200 -@@ -40,7 +40,13 @@ typedef struct { +diff --git a/readconf.h b/readconf.h +index cd49139b..368523dd 100644 +--- a/readconf.h ++++ b/readconf.h +@@ -39,7 +39,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ @@ -3273,18 +3361,19 @@ diff --color -ruNp a/readconf.h b/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff --color -ruNp a/servconf.c b/servconf.c ---- a/servconf.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/servconf.c 2024-09-16 11:46:34.700940011 +0200 -@@ -68,6 +68,7 @@ - #include "auth.h" +diff --git a/servconf.c b/servconf.c +index f7bc9237..d4f7fd66 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -69,6 +69,7 @@ #include "myproposal.h" #include "digest.h" + #include "version.h" +#include "ssh-gss.h" #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" -@@ -137,8 +138,11 @@ initialize_server_options(ServerOptions +@@ -138,8 +139,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3296,7 +3385,7 @@ diff --color -ruNp a/servconf.c b/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -376,10 +380,18 @@ fill_default_server_options(ServerOption +@@ -380,10 +384,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3315,7 +3404,7 @@ diff --color -ruNp a/servconf.c b/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -558,6 +570,7 @@ typedef enum { +@@ -568,6 +580,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3323,7 +3412,7 @@ diff --color -ruNp a/servconf.c b/servconf.c sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -643,12 +656,22 @@ static struct { +@@ -653,12 +666,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3346,7 +3435,7 @@ diff --color -ruNp a/servconf.c b/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1585,6 +1608,10 @@ process_server_config_line_depth(ServerO +@@ -1649,6 +1672,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3357,7 +3446,7 @@ diff --color -ruNp a/servconf.c b/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1593,6 +1620,22 @@ process_server_config_line_depth(ServerO +@@ -1657,6 +1684,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3380,7 +3469,7 @@ diff --color -ruNp a/servconf.c b/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3178,6 +3221,10 @@ dump_config(ServerOptions *o) +@@ -3254,6 +3297,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3391,10 +3480,11 @@ diff --color -ruNp a/servconf.c b/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --color -ruNp a/servconf.h b/servconf.h ---- a/servconf.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/servconf.h 2024-09-16 11:46:34.700940011 +0200 -@@ -149,8 +149,11 @@ typedef struct { +diff --git a/servconf.h b/servconf.h +index 9beb90fa..c3f50140 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -150,8 +150,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3406,10 +3496,11 @@ diff --color -ruNp a/servconf.h b/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff --color -ruNp a/session.c b/session.c ---- a/session.c 2024-09-16 11:45:56.866133411 +0200 -+++ b/session.c 2024-09-16 11:46:34.701940032 +0200 -@@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *au +diff --git a/session.c b/session.c +index e4657cef..cbfbcee8 100644 +--- a/session.c ++++ b/session.c +@@ -2670,13 +2670,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3431,542 +3522,10 @@ diff --color -ruNp a/session.c b/session.c #endif /* remove agent socket */ -diff --color -ruNp a/ssh.1 b/ssh.1 ---- a/ssh.1 2024-09-16 11:45:56.875133603 +0200 -+++ b/ssh.1 2024-09-16 11:46:34.701940032 +0200 -@@ -536,7 +536,13 @@ For full details of the options listed b - .It GatewayPorts - .It GlobalKnownHostsFile - .It GSSAPIAuthentication -+.It GSSAPIKeyExchange -+.It GSSAPIClientIdentity - .It GSSAPIDelegateCredentials -+.It GSSAPIKexAlgorithms -+.It GSSAPIRenewalForcesRekey -+.It GSSAPIServerIdentity -+.It GSSAPITrustDns - .It HashKnownHosts - .It Host - .It HostbasedAcceptedAlgorithms -@@ -624,6 +630,8 @@ flag), - (supported message integrity codes), - .Ar kex - (key exchange algorithms), -+.Ar kex-gss -+(GSSAPI key exchange algorithms), - .Ar key - (key types), - .Ar key-ca-sign -diff --color -ruNp a/ssh.c b/ssh.c ---- a/ssh.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh.c 2024-09-16 11:46:34.702940054 +0200 -@@ -827,6 +827,8 @@ main(int ac, char **av) - else if (strcmp(optarg, "kex") == 0 || - strcasecmp(optarg, "KexAlgorithms") == 0) - cp = kex_alg_list('\n'); -+ else if (strcmp(optarg, "kex-gss") == 0) -+ cp = kex_gss_alg_list('\n'); - else if (strcmp(optarg, "key") == 0) - cp = sshkey_alg_list(0, 0, 0, '\n'); - else if (strcmp(optarg, "key-cert") == 0) -@@ -857,8 +859,8 @@ main(int ac, char **av) - } else if (strcmp(optarg, "help") == 0) { - cp = xstrdup( - "cipher\ncipher-auth\ncompression\nkex\n" -- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" -- "protocol-version\nsig"); -+ "kex-gss\nkey\nkey-cert\nkey-plain\n" -+ "key-sig\nmac\nprotocol-version\nsig"); - } - if (cp == NULL) - fatal("Unsupported query \"%s\"", optarg); -diff --color -ruNp a/ssh_config b/ssh_config ---- a/ssh_config 2024-09-16 11:45:56.884133795 +0200 -+++ b/ssh_config 2024-09-16 11:46:34.702940054 +0200 -@@ -24,6 +24,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP no - # AddressFamily any -diff --color -ruNp a/ssh_config.5 b/ssh_config.5 ---- a/ssh_config.5 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh_config.5 2024-09-16 11:46:34.703940075 +0200 -@@ -938,10 +938,68 @@ The default is - Specifies whether user authentication based on GSSAPI is allowed. - The default is - .Cm no . -+.It Cm GSSAPIClientIdentity -+If set, specifies the GSSAPI client identity that ssh should use when -+connecting to the server. The default is unset, which means that the default -+identity will be used. - .It Cm GSSAPIDelegateCredentials - Forward (delegate) credentials to the server. - The default is - .Cm no . -+.It Cm GSSAPIKeyExchange -+Specifies whether key exchange based on GSSAPI may be used. When using -+GSSAPI key exchange the server need not have a host key. -+The default is -+.Dq no . -+.It Cm GSSAPIRenewalForcesRekey -+If set to -+.Dq yes -+then renewal of the client's GSSAPI credentials will force the rekeying of the -+ssh connection. With a compatible server, this will delegate the renewed -+credentials to a session on the server. -+.Pp -+Checks are made to ensure that credentials are only propagated when the new -+credentials match the old ones on the originating client and where the -+receiving server still has the old set in its cache. -+.Pp -+The default is -+.Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. -+.It Cm GSSAPIServerIdentity -+If set, specifies the GSSAPI server identity that ssh should expect when -+connecting to the server. The default is unset, which means that the -+expected GSSAPI server identity will be determined from the target -+hostname. -+.It Cm GSSAPITrustDns -+Set to -+.Dq yes -+to indicate that the DNS is trusted to securely canonicalize -+the name of the host being connected to. If -+.Dq no , -+the hostname entered on the -+command line will be passed untouched to the GSSAPI library. -+The default is -+.Dq no . -+.It Cm GSSAPIKexAlgorithms -+The list of key exchange algorithms that are offered for 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-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 HashKnownHosts - Indicates that - .Xr ssh 1 -diff --color -ruNp a/sshconnect2.c b/sshconnect2.c ---- a/sshconnect2.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshconnect2.c 2024-09-16 11:46:34.703940075 +0200 -@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, st - char *all_key, *hkalgs = NULL; - int r, use_known_hosts_order = 0; - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ char *orig = NULL, *gss = NULL; -+ char *gss_host = NULL; -+#endif -+ - xxx_host = host; - xxx_hostaddr = hostaddr; - xxx_conn_info = cinfo; -@@ -255,6 +260,42 @@ ssh_kex2(struct ssh *ssh, char *host, st - compression_alg_list(options.compression), - hkalgs ? hkalgs : options.hostkeyalgorithms); - -+#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); -+ } -+ } -+#endif -+ - free(hkalgs); - - /* start key exchange */ -@@ -271,15 +312,45 @@ ssh_kex2(struct ssh *ssh, char *host, st - # ifdef OPENSSL_HAS_ECC - ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; - # endif --#endif -+# ifdef GSSAPI -+ if (options.gss_keyex) { -+ ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; -+ ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; -+ } -+# endif -+#endif /* WITH_OPENSSL */ - ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; - ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; - ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; - ssh->kex->verify_host_key=&verify_host_key_callback; - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ if (options.gss_keyex) { -+ ssh->kex->gss_deleg_creds = options.gss_deleg_creds; -+ ssh->kex->gss_trust_dns = options.gss_trust_dns; -+ ssh->kex->gss_client = options.gss_client_identity; -+ ssh->kex->gss_host = gss_host; -+ } -+#endif -+ - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); - kex_proposal_free_entries(myproposal); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ /* repair myproposal after it was crumpled by the */ -+ /* ext-info removal above */ -+ if (gss) { -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ free(gss); -+ } -+#endif - #ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || -@@ -368,6 +439,7 @@ static int input_gssapi_response(int typ - static int input_gssapi_token(int type, u_int32_t, struct ssh *); - static int input_gssapi_error(int, u_int32_t, struct ssh *); - static int input_gssapi_errtok(int, u_int32_t, struct ssh *); -+static int userauth_gsskeyex(struct ssh *); - #endif - - void userauth(struct ssh *, char *); -@@ -384,6 +456,11 @@ static char *authmethods_get(void); - - Authmethod authmethods[] = { - #ifdef GSSAPI -+ {"gssapi-keyex", -+ userauth_gsskeyex, -+ NULL, -+ &options.gss_keyex, -+ NULL}, - {"gssapi-with-mic", - userauth_gssapi, - userauth_gssapi_cleanup, -@@ -755,12 +832,32 @@ userauth_gssapi(struct ssh *ssh) - OM_uint32 min; - int r, ok = 0; - gss_OID mech = NULL; -+ char *gss_host = NULL; -+ -+ 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(authctxt->host); -+ } -+ } else { -+ gss_host = xstrdup(authctxt->host); -+ } - - /* Try one GSSAPI method at a time, rather than sending them all at - * once. */ - - if (authctxt->gss_supported_mechs == NULL) -- gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); -+ if (GSS_ERROR(gss_indicate_mechs(&min, -+ &authctxt->gss_supported_mechs))) { -+ authctxt->gss_supported_mechs = NULL; -+ free(gss_host); -+ return 0; -+ } - - /* Check to see whether the mechanism is usable before we offer it */ - while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -769,13 +866,15 @@ userauth_gssapi(struct ssh *ssh) - elements[authctxt->mech_tried]; - /* My DER encoding requires length<128 */ - if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, -- mech, authctxt->host)) { -+ mech, gss_host, options.gss_client_identity)) { - ok = 1; /* Mechanism works */ - } else { - authctxt->mech_tried++; - } - } - -+ free(gss_host); -+ - if (!ok || mech == NULL) - return 0; - -@@ -1009,6 +1108,55 @@ input_gssapi_error(int type, u_int32_t p - free(lang); - return r; - } -+ -+int -+userauth_gsskeyex(struct ssh *ssh) -+{ -+ struct sshbuf *b = NULL; -+ Authctxt *authctxt = ssh->authctxt; -+ gss_buffer_desc gssbuf; -+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ms; -+ int r; -+ -+ static int attempt = 0; -+ if (attempt++ >= 1) -+ return (0); -+ -+ if (gss_kex_context == NULL) { -+ debug("No valid Key exchange context"); -+ return (0); -+ } -+ -+ if ((b = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); -+ -+ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex", ssh->kex->session_id); -+ -+ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal_f("sshbuf_mutable_ptr failed"); -+ gssbuf.length = sshbuf_len(b); -+ -+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { -+ sshbuf_free(b); -+ return (0); -+ } -+ -+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || -+ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal_fr(r, "parsing"); -+ -+ sshbuf_free(b); -+ gss_release_buffer(&ms, &mic); -+ -+ return (1); -+} -+ - #endif /* GSSAPI */ - - static int -diff --color -ruNp a/sshd.c b/sshd.c ---- a/sshd.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshd.c 2024-09-16 11:46:34.704940096 +0200 -@@ -1551,7 +1551,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 --color -ruNp a/sshd_config b/sshd_config ---- a/sshd_config 2024-09-16 11:45:56.888133880 +0200 -+++ b/sshd_config 2024-09-16 11:46:34.704940096 +0200 -@@ -77,6 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys - # GSSAPI options - #GSSAPIAuthentication no - #GSSAPICleanupCredentials yes -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -diff --color -ruNp a/sshd_config.5 b/sshd_config.5 ---- a/sshd_config.5 2024-09-16 11:45:56.885133816 +0200 -+++ b/sshd_config.5 2024-09-16 11:46:34.704940096 +0200 -@@ -739,6 +739,11 @@ Specifies whether to automatically destr - on logout. - The default is - .Cm yes . -+.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. -+The default is -+.Cm no . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. -@@ -753,6 +758,32 @@ machine's default store. - This facility is provided to assist with operation on multi homed machines. - The default is - .Cm yes . -+.It Cm GSSAPIStoreCredentialsOnRekey -+Controls whether the user's GSSAPI credentials should be updated following a -+successful connection rekeying. This option can be used to accepted renewed -+or updated credentials from a compatible client. The default is -+.Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. -+.It Cm GSSAPIKexAlgorithms -+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-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 - Specifies the signature algorithms that will be accepted for hostbased - authentication as a list of comma-separated patterns. -diff --color -ruNp a/sshd-session.c b/sshd-session.c ---- a/sshd-session.c 2024-09-16 11:45:56.888133880 +0200 -+++ b/sshd-session.c 2024-09-16 11:46:34.705940118 +0200 -@@ -660,8 +660,8 @@ notify_hostkeys(struct ssh *ssh) - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) -- fatal_f("no hostkeys"); -- if ((r = sshpkt_send(ssh)) != 0) -+ debug3_f("no hostkeys"); -+ else if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); - } -@@ -1180,8 +1180,9 @@ main(int ac, char **av) - break; - } - } -- if (!have_key) -- fatal("internal error: monitor received no hostkeys"); -+ /* The GSSAPI key exchange can run without a host key */ -+ if (!have_key && !options.gss_keyex) -+ fatal("internal error: monitor received no hostkeys and GSS KEX is not configured"); - - /* Ensure that umask disallows at least group and world write */ - new_umask = umask(0077) | 0022; -@@ -1462,6 +1463,48 @@ do_ssh2_kex(struct ssh *ssh) - - free(hkalgs); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ { -+ char *orig; -+ char *gss = NULL; -+ char *newstr = NULL; -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ /* -+ * If we don't have a host key, then there's no point advertising -+ * the other key exchange algorithms -+ */ -+ -+ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) -+ orig = NULL; -+ -+ if (options.gss_keyex) -+ gss = ssh_gssapi_server_mechanisms(); -+ else -+ gss = NULL; -+ -+ if (gss && orig) -+ xasprintf(&newstr, "%s,%s", gss, orig); -+ else if (gss) -+ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com"); -+ else if (orig) -+ newstr = orig; -+ -+ /* -+ * If we've got GSSAPI mechanisms, then we've got the 'null' host -+ * key alg, but we can't tell people about it unless its the only -+ * host key algorithm we support -+ */ -+ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); -+ -+ if (newstr) -+ myproposal[PROPOSAL_KEX_ALGS] = newstr; -+ else -+ fatal("No supported key exchange algorithms"); -+ } -+#endif -+ - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); -@@ -1479,7 +1522,18 @@ do_ssh2_kex(struct ssh *ssh) - #ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - #endif --#endif -+# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } -+# endif -+#endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; -diff --color -ruNp a/ssh-gss.h b/ssh-gss.h ---- a/ssh-gss.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/ssh-gss.h 2024-09-16 11:46:34.710940224 +0200 +diff --git a/ssh-gss.h b/ssh-gss.h +index 7b14e74a..8ec45192 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h @@ -61,10 +61,36 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -4047,7 +3606,7 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -108,6 +149,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( +@@ -108,6 +149,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -4091,10 +3650,557 @@ diff --color -ruNp a/ssh-gss.h b/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff --color -ruNp a/sshkey.c b/sshkey.c ---- a/sshkey.c 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshkey.c 2024-09-16 11:46:34.706940139 +0200 -@@ -131,6 +131,75 @@ extern const struct sshkey_impl sshkey_x +diff --git a/ssh.1 b/ssh.1 +index db92ac9a..6a9fbdc5 100644 +--- a/ssh.1 ++++ b/ssh.1 +@@ -539,9 +539,15 @@ For full details of the options listed below, and their possible values, see + .It ForwardX11Timeout + .It ForwardX11Trusted + .It GSSAPIAuthentication ++.It GSSAPIKeyExchange ++.It GSSAPIClientIdentity + .It GSSAPIDelegateCredentials + .It GatewayPorts + .It GlobalKnownHostsFile ++.It GSSAPIKexAlgorithms ++.It GSSAPIRenewalForcesRekey ++.It GSSAPIServerIdentity ++.It GSSAPITrustDns + .It HashKnownHosts + .It Host + .It HostKeyAlgorithms +@@ -636,6 +642,8 @@ flag), + (supported message integrity codes), + .Ar kex + (key exchange algorithms), ++.Ar kex-gss ++(GSSAPI key exchange algorithms), + .Ar key + (key types), + .Ar key-ca-sign +diff --git a/ssh.c b/ssh.c +index dc4886d0..c23d3b9e 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -835,6 +835,8 @@ main(int ac, char **av) + else if (strcmp(optarg, "kex") == 0 || + strcasecmp(optarg, "KexAlgorithms") == 0) + cp = kex_alg_list('\n'); ++ else if (strcmp(optarg, "kex-gss") == 0) ++ cp = kex_gss_alg_list('\n'); + else if (strcmp(optarg, "key") == 0) + cp = sshkey_alg_list(0, 0, 0, '\n'); + else if (strcmp(optarg, "key-cert") == 0) +@@ -865,8 +867,8 @@ main(int ac, char **av) + } else if (strcmp(optarg, "help") == 0) { + cp = xstrdup( + "cipher\ncipher-auth\ncompression\nkex\n" +- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" +- "protocol-version\nsig"); ++ "kex-gss\nkey\nkey-cert\nkey-plain\n" ++ "key-sig\nmac\nprotocol-version\nsig"); + } + if (cp == NULL) + fatal("Unsupported query \"%s\"", optarg); +diff --git a/ssh_config b/ssh_config +index 18169187..209248d6 100644 +--- a/ssh_config ++++ b/ssh_config +@@ -24,6 +24,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP no + # AddressFamily any +diff --git a/ssh_config.5 b/ssh_config.5 +index 894d7383..3a8e246c 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -976,10 +976,68 @@ The default is + Specifies whether user authentication based on GSSAPI is allowed. + The default is + .Cm no . ++.It Cm GSSAPIClientIdentity ++If set, specifies the GSSAPI client identity that ssh should use when ++connecting to the server. The default is unset, which means that the default ++identity will be used. + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is + .Cm no . ++.It Cm GSSAPIKeyExchange ++Specifies whether key exchange based on GSSAPI may be used. When using ++GSSAPI key exchange the server need not have a host key. ++The default is ++.Dq no . ++.It Cm GSSAPIRenewalForcesRekey ++If set to ++.Dq yes ++then renewal of the client's GSSAPI credentials will force the rekeying of the ++ssh connection. With a compatible server, this will delegate the renewed ++credentials to a session on the server. ++.Pp ++Checks are made to ensure that credentials are only propagated when the new ++credentials match the old ones on the originating client and where the ++receiving server still has the old set in its cache. ++.Pp ++The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIServerIdentity ++If set, specifies the GSSAPI server identity that ssh should expect when ++connecting to the server. The default is unset, which means that the ++expected GSSAPI server identity will be determined from the target ++hostname. ++.It Cm GSSAPITrustDns ++Set to ++.Dq yes ++to indicate that the DNS is trusted to securely canonicalize ++the name of the host being connected to. If ++.Dq no , ++the hostname entered on the ++command line will be passed untouched to the GSSAPI library. ++The default is ++.Dq no . ++.It Cm GSSAPIKexAlgorithms ++The list of key exchange algorithms that are offered for 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-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 HashKnownHosts + Indicates that + .Xr ssh 1 +diff --git a/sshconnect2.c b/sshconnect2.c +index 1ee6000a..0af15bcc 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, + char *all_key, *hkalgs = NULL; + int r, use_known_hosts_order = 0; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ char *orig = NULL, *gss = NULL; ++ char *gss_host = NULL; ++#endif ++ + xxx_host = host; + xxx_hostaddr = hostaddr; + xxx_conn_info = cinfo; +@@ -255,6 +260,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, + compression_alg_list(options.compression), + hkalgs ? hkalgs : options.hostkeyalgorithms); + ++#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); ++ } ++ } ++#endif ++ + free(hkalgs); + + /* start key exchange */ +@@ -271,15 +312,45 @@ 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 +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; ++ ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; ++ } ++# endif ++#endif /* WITH_OPENSSL */ + ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; + ssh->kex->verify_host_key=&verify_host_key_callback; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ if (options.gss_keyex) { ++ ssh->kex->gss_deleg_creds = options.gss_deleg_creds; ++ ssh->kex->gss_trust_dns = options.gss_trust_dns; ++ ssh->kex->gss_client = options.gss_client_identity; ++ ssh->kex->gss_host = gss_host; ++ } ++#endif ++ + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); + kex_proposal_free_entries(myproposal); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ /* repair myproposal after it was crumpled by the */ ++ /* ext-info removal above */ ++ if (gss) { ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ free(gss); ++ } ++#endif + #ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || +@@ -369,6 +440,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 *); + static int input_gssapi_errtok(int, u_int32_t, struct ssh *); ++static int userauth_gsskeyex(struct ssh *); + #endif + + void userauth(struct ssh *, char *); +@@ -385,6 +457,11 @@ static char *authmethods_get(void); + + Authmethod authmethods[] = { + #ifdef GSSAPI ++ {"gssapi-keyex", ++ userauth_gsskeyex, ++ NULL, ++ &options.gss_keyex, ++ NULL}, + {"gssapi-with-mic", + userauth_gssapi, + userauth_gssapi_cleanup, +@@ -759,12 +836,32 @@ userauth_gssapi(struct ssh *ssh) + OM_uint32 min; + int r, ok = 0; + gss_OID mech = NULL; ++ char *gss_host = NULL; ++ ++ 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(authctxt->host); ++ } ++ } else { ++ gss_host = xstrdup(authctxt->host); ++ } + + /* Try one GSSAPI method at a time, rather than sending them all at + * once. */ + + if (authctxt->gss_supported_mechs == NULL) +- gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); ++ if (GSS_ERROR(gss_indicate_mechs(&min, ++ &authctxt->gss_supported_mechs))) { ++ authctxt->gss_supported_mechs = NULL; ++ free(gss_host); ++ return 0; ++ } + + /* Check to see whether the mechanism is usable before we offer it */ + while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && +@@ -773,13 +870,15 @@ userauth_gssapi(struct ssh *ssh) + elements[authctxt->mech_tried]; + /* My DER encoding requires length<128 */ + if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, +- mech, authctxt->host)) { ++ mech, gss_host, options.gss_client_identity)) { + ok = 1; /* Mechanism works */ + } else { + authctxt->mech_tried++; + } + } + ++ free(gss_host); ++ + if (!ok || mech == NULL) + return 0; + +@@ -1013,6 +1112,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) + free(lang); + return r; + } ++ ++int ++userauth_gsskeyex(struct ssh *ssh) ++{ ++ struct sshbuf *b = NULL; ++ Authctxt *authctxt = ssh->authctxt; ++ gss_buffer_desc gssbuf; ++ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ms; ++ int r; ++ ++ static int attempt = 0; ++ if (attempt++ >= 1) ++ return (0); ++ ++ if (gss_kex_context == NULL) { ++ debug("No valid Key exchange context"); ++ return (0); ++ } ++ ++ if ((b = sshbuf_new()) == NULL) ++ fatal_f("sshbuf_new failed"); ++ ++ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, ++ "gssapi-keyex", ssh->kex->session_id); ++ ++ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) ++ fatal_f("sshbuf_mutable_ptr failed"); ++ gssbuf.length = sshbuf_len(b); ++ ++ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { ++ sshbuf_free(b); ++ return (0); ++ } ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || ++ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal_fr(r, "parsing"); ++ ++ sshbuf_free(b); ++ gss_release_buffer(&ms, &mic); ++ ++ return (1); ++} ++ + #endif /* GSSAPI */ + + static int +diff --git a/sshd-auth.c b/sshd-auth.c +index f957dc22..d51e4636 100644 +--- a/sshd-auth.c ++++ b/sshd-auth.c +@@ -844,6 +844,48 @@ do_ssh2_kex(struct ssh *ssh) + + free(hkalgs); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ { ++ char *orig; ++ char *gss = NULL; ++ char *newstr = NULL; ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ /* ++ * If we don't have a host key, then there's no point advertising ++ * the other key exchange algorithms ++ */ ++ ++ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) ++ orig = NULL; ++ ++ if (options.gss_keyex) ++ gss = ssh_gssapi_server_mechanisms(); ++ else ++ gss = NULL; ++ ++ if (gss && orig) ++ xasprintf(&newstr, "%s,%s", gss, orig); ++ else if (gss) ++ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com"); ++ else if (orig) ++ newstr = orig; ++ ++ /* ++ * If we've got GSSAPI mechanisms, then we've got the 'null' host ++ * key alg, but we can't tell people about it unless its the only ++ * host key algorithm we support ++ */ ++ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); ++ ++ if (newstr) ++ myproposal[PROPOSAL_KEX_ALGS] = newstr; ++ else ++ fatal("No supported key exchange algorithms"); ++ } ++#endif ++ + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); +@@ -861,6 +903,17 @@ do_ssh2_kex(struct ssh *ssh) + # ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + # endif /* OPENSSL_HAS_ECC */ ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } ++# endif + #endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; +diff --git a/sshd-session.c b/sshd-session.c +index a70b36c9..f8c8a797 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -616,8 +616,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) +- fatal_f("no hostkeys"); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3_f("no hostkeys"); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } +@@ -1159,8 +1159,9 @@ main(int ac, char **av) + break; + } + } +- if (!have_key) +- fatal("internal error: monitor received no hostkeys"); ++ /* The GSSAPI key exchange can run without a host key */ ++ if (!have_key && !options.gss_keyex) ++ fatal("internal error: monitor received no hostkeys and GSS KEX is not configured"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; +diff --git a/sshd.c b/sshd.c +index 4a93e29e..c9ea8e38 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1676,7 +1676,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_config b/sshd_config +index 48af6321..8db9f0fb 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -79,6 +79,8 @@ AuthorizedKeysFile .ssh/authorized_keys + # GSSAPI options + #GSSAPIAuthentication no + #GSSAPICleanupCredentials yes ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange 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 035a50c8..8bc6586e 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache + on logout. + The default is + .Cm yes . ++.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. ++The default is ++.Cm no . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -753,6 +758,32 @@ machine's default store. + This facility is provided to assist with operation on multi homed machines. + The default is + .Cm yes . ++.It Cm GSSAPIStoreCredentialsOnRekey ++Controls whether the user's GSSAPI credentials should be updated following a ++successful connection rekeying. This option can be used to accepted renewed ++or updated credentials from a compatible client. The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIKexAlgorithms ++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-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 + Specifies the signature algorithms that will be accepted for hostbased + authentication as a list of comma-separated patterns. +diff --git a/sshkey.c b/sshkey.c +index ab80752b..4e41a78c 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -129,6 +129,75 @@ extern const struct sshkey_impl sshkey_xmss_impl; extern const struct sshkey_impl sshkey_xmss_cert_impl; #endif @@ -4170,7 +4276,7 @@ diff --color -ruNp a/sshkey.c b/sshkey.c const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, &sshkey_ed25519_cert_impl, -@@ -169,6 +238,7 @@ const struct sshkey_impl * const keyimpl +@@ -167,6 +236,7 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_xmss_impl, &sshkey_xmss_cert_impl, #endif @@ -4178,7 +4284,7 @@ diff --color -ruNp a/sshkey.c b/sshkey.c NULL }; -@@ -324,7 +394,7 @@ sshkey_alg_list(int certs_only, int plai +@@ -336,7 +406,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -4187,10 +4293,11 @@ diff --color -ruNp a/sshkey.c b/sshkey.c continue; if (!include_sigonly && impl->sigonly) continue; -diff --color -ruNp a/sshkey.h b/sshkey.h ---- a/sshkey.h 2024-07-01 06:36:28.000000000 +0200 -+++ b/sshkey.h 2024-09-16 11:46:34.706940139 +0200 -@@ -71,6 +71,7 @@ enum sshkey_types { +diff --git a/sshkey.h b/sshkey.h +index 19bbbac7..4a318d05 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -75,6 +75,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -4198,3 +4305,6 @@ diff --color -ruNp a/sshkey.h b/sshkey.h KEY_UNSPEC }; +-- +2.49.0 + diff --git a/openssh-6.6p1-force_krb.patch b/0013-openssh-6.6p1-force_krb.patch similarity index 88% rename from openssh-6.6p1-force_krb.patch rename to 0013-openssh-6.6p1-force_krb.patch index 90f8322..74643b5 100644 --- a/openssh-6.6p1-force_krb.patch +++ b/0013-openssh-6.6p1-force_krb.patch @@ -1,5 +1,17 @@ +From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 413b845..54dd383 100644 +index 8d2b677f..14502c5a 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ @@ -12,7 +24,7 @@ index 413b845..54dd383 100644 #include "xmalloc.h" #include "sshkey.h" -@@ -45,6 +47,7 @@ +@@ -44,6 +46,7 @@ #include "ssh-gss.h" @@ -20,7 +32,7 @@ index 413b845..54dd383 100644 extern ServerOptions options; #ifdef HEIMDAL -@@ -56,6 +59,13 @@ extern ServerOptions options; +@@ -55,6 +58,13 @@ extern ServerOptions options; # include #endif @@ -34,7 +46,7 @@ index 413b845..54dd383 100644 static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -88,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -87,6 +97,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_principal princ; int retval; const char *errmsg; @@ -42,7 +54,7 @@ index 413b845..54dd383 100644 if (ssh_gssapi_krb5_init() == 0) return 0; -@@ -99,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -98,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_free_error_message(krb_context, errmsg); return 0; } @@ -66,7 +78,7 @@ index 413b845..54dd383 100644 } else retval = 0; -@@ -110,6 +133,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -109,6 +132,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) return retval; } @@ -205,10 +217,10 @@ index 413b845..54dd383 100644 /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ diff --git a/session.c b/session.c -index 28659ec..9c94d8e 100644 +index cbfbcee8..89b3a9cf 100644 --- a/session.c +++ b/session.c -@@ -789,6 +789,29 @@ do_exec(Session *s, const char *command) +@@ -680,6 +680,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) command = auth_opts->force_command; forced = "(key-option)"; } @@ -239,7 +251,7 @@ index 28659ec..9c94d8e 100644 if (forced != NULL) { s->forced = 1; diff --git a/ssh-gss.h b/ssh-gss.h -index 0374c88..509109a 100644 +index 8ec45192..db34d77f 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -49,6 +49,10 @@ @@ -254,10 +266,10 @@ index 0374c88..509109a 100644 /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/sshd.8 b/sshd.8 -index adcaaf9..824163b 100644 +index 2aa73271..049d0a94 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -324,6 +324,7 @@ Finally, the server and the client enter an authentication dialog. +@@ -286,6 +286,7 @@ Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using host-based authentication, public key authentication, @@ -265,7 +277,7 @@ index adcaaf9..824163b 100644 challenge-response authentication, or password authentication. .Pp -@@ -800,6 +801,12 @@ This file is used in exactly the same way as +@@ -874,6 +875,12 @@ This file is used in exactly the same way as but allows host-based authentication without permitting login with rlogin/rsh. .Pp @@ -278,3 +290,6 @@ index adcaaf9..824163b 100644 .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. +-- +2.49.0 + diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/0014-openssh-7.7p1-gssapi-new-unique.patch similarity index 79% rename from openssh-7.7p1-gssapi-new-unique.patch rename to 0014-openssh-7.7p1-gssapi-new-unique.patch index 34b9b9d..1d21839 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/0014-openssh-7.7p1-gssapi-new-unique.patch @@ -1,26 +1,25 @@ -diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h ---- openssh-8.6p1/auth.h.ccache_name 2021-04-19 14:05:10.820744325 +0200 -+++ openssh-8.6p1/auth.h 2021-04-19 14:05:10.853744569 +0200 -@@ -83,6 +83,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; - -@@ -231,7 +232,7 @@ struct passwd *fakepw(void); - int sys_auth_passwd(struct ssh *, const char *); - - #if defined(KRB5) && !defined(HEIMDAL) --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); - #endif - - #endif /* AUTH_H */ -diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c ---- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/auth-krb5.c 2021-04-19 14:40:55.142832954 +0200 +From 5fca5946aa97dce23c6824c52b070a92532752a9 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 +--- a/auth-krb5.c ++++ b/auth-krb5.c @@ -51,6 +51,7 @@ #include #include @@ -29,7 +28,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c extern ServerOptions options; -@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -38,7 +37,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c char *client, *platform_client; const char *errmsg; -@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) goto out; } @@ -49,7 +48,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c if (problem) goto out; -@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password) goto out; #endif @@ -70,7 +69,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif -@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) void krb5_cleanup_proc(Authctxt *authctxt) { @@ -131,7 +130,24 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c } -#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, ...) { @@ -197,8 +213,9 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c + /* unknown token, fallback to the default */ + goto cleanup; + } -+ } -+ + } + +- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + if (ssh_asprintf_append(&r, "%s", p_o) == -1) + goto cleanup; + @@ -233,29 +250,13 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c + return ret; +} + - krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -- int tmpfd, ret, oerrno; -- char ccname[40]; ++krb5_error_code +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno, type_len; + char *ccname = NULL; - mode_t old_umask; ++ mode_t old_umask; + char *type = NULL, *colon = NULL; - -- ret = snprintf(ccname, sizeof(ccname), -- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); -- if (ret < 0 || (size_t)ret >= sizeof(ccname)) -- return ENOMEM; -- -- old_umask = umask(0177); -- tmpfd = mkstemp(ccname + strlen("FILE:")); -- oerrno = errno; -- umask(old_umask); -- if (tmpfd == -1) { -- logit("mkstemp(): %.100s", strerror(oerrno)); -- return oerrno; -- } ++ + debug3_f("called"); + if (need_environment) + *need_environment = 0; @@ -270,8 +271,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c + "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); + if (ret < 0) + return ENOMEM; - -- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { ++ + old_umask = umask(0177); + tmpfd = mkstemp(ccname + strlen("FILE:")); oerrno = errno; @@ -338,42 +338,32 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c } #endif /* !HEIMDAL */ #endif /* KRB5 */ -diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c ---- openssh-8.6p1/gss-serv.c.ccache_name 2021-04-19 14:05:10.844744503 +0200 -+++ openssh-8.6p1/gss-serv.c 2021-04-19 14:05:10.854744577 +0200 -@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void) - } +diff --git a/auth.h b/auth.h +index 83d07ae8..10e88e11 100644 +--- a/auth.h ++++ b/auth.h +@@ -85,6 +85,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } +@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int); + int sys_auth_passwd(struct ssh *, const char *); - /* This allows GSSAPI methods to do things to the child's environment based -@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) { - char *envstr; + #if defined(KRB5) && !defined(HEIMDAL) +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); #endif -- if (gssapi_client.store.filename == NULL && -- gssapi_client.store.envval == NULL && -- gssapi_client.store.envvar == NULL) -+ if (gssapi_client.store.envval == NULL) - return; - - ok = 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 -@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri + #endif /* AUTH_H */ +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 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, /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ @@ -382,7 +372,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; -@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) OM_uint32 maj_status, min_status; const char *new_ccname, *new_cctype; const char *errmsg; @@ -400,7 +390,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE -@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_get_err_text(krb_context, problem)); # endif krb5_free_error_message(krb_context, errmsg); @@ -419,7 +409,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c } #endif /* #ifdef HEIMDAL */ -@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); @@ -428,7 +418,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { -@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); @@ -437,7 +427,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c } krb5_free_principal(krb_context, princ); -@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); @@ -475,7 +465,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c do_pam_putenv(client->store.envvar, client->store.envval); #endif -@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) client->store.data = krb_context; @@ -484,10 +474,44 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c } int -diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c ---- openssh-8.6p1/servconf.c.ccache_name 2021-04-19 14:05:10.848744532 +0200 -+++ openssh-8.6p1/servconf.c 2021-04-19 14:05:10.854744577 +0200 -@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions +diff --git a/gss-serv.c b/gss-serv.c +index a5cca797..9d5435ed 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) + } + + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } + + /* This allows GSSAPI methods to do things to the child's environment based +@@ -500,9 +502,7 @@ ssh_gssapi_rekey_creds(void) { + char *envstr; + #endif + +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); +diff --git a/servconf.c b/servconf.c +index d4f7fd66..55aa5bf0 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options) options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -495,7 +519,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption +@@ -382,6 +383,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; @@ -504,16 +528,16 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -506,7 +509,7 @@ typedef enum { - sPort, sHostKeyFile, sLoginGraceTime, - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +@@ -564,7 +567,7 @@ typedef enum { + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sPasswordAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -593,11 +597,13 @@ static struct { + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, +@@ -655,11 +658,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -527,7 +551,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO +@@ -1668,6 +1673,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -538,7 +562,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o) +@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -546,10 +570,11 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h ---- openssh-8.6p1/servconf.h.ccache_name 2021-04-19 14:05:10.848744532 +0200 -+++ openssh-8.6p1/servconf.h 2021-04-19 14:05:10.855744584 +0200 -@@ -140,6 +140,8 @@ typedef struct { +diff --git a/servconf.h b/servconf.h +index c3f50140..a4a38d6d 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -149,6 +149,8 @@ typedef struct { * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -558,10 +583,11 @@ diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c ---- openssh-8.6p1/session.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 -+++ openssh-8.6p1/session.c 2021-04-19 14:05:10.855744584 +0200 -@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s +diff --git a/session.c b/session.c +index 89b3a9cf..2620dd11 100644 +--- a/session.c ++++ b/session.c +@@ -1025,7 +1025,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 */ @@ -571,7 +597,7 @@ diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c #endif /* Set basic environment. */ -@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s +@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) } #endif #ifdef KRB5 @@ -580,10 +606,33 @@ diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif -diff -up openssh-8.6p1/sshd-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) +diff --git a/ssh-gss.h b/ssh-gss.h +index db34d77f..a894e23c 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -186,7 +186,7 @@ int ssh_gssapi_userok(char *name, struct passwd *, int kex); + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); +diff --git a/sshd-session.c b/sshd-session.c +index f8c8a797..478381db 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -1349,7 +1349,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -592,10 +641,11 @@ diff -up openssh-8.6p1/sshd-session.c.ccache_name openssh-8.6p1/sshd-session.c restore_uid(); } #endif -diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 ---- openssh-8.6p1/sshd_config.5.ccache_name 2021-04-19 14:05:10.849744540 +0200 -+++ openssh-8.6p1/sshd_config.5 2021-04-19 14:05:10.856744592 +0200 -@@ -939,6 +939,14 @@ Specifies whether to automatically destr +diff --git a/sshd_config.5 b/sshd_config.5 +index 8bc6586e..1251d4d5 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Cm yes . @@ -610,24 +660,6 @@ diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 .It Cm KexAlgorithms 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 -@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*dochild) (ssh_gssapi_client *); - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); +-- +2.49.0 + diff --git a/openssh-7.2p2-k5login_directory.patch b/0015-openssh-7.2p2-k5login_directory.patch similarity index 74% rename from openssh-7.2p2-k5login_directory.patch rename to 0015-openssh-7.2p2-k5login_directory.patch index 80e7678..5e980c8 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/0015-openssh-7.2p2-k5login_directory.patch @@ -1,8 +1,20 @@ +From 25540939422660b024b8832f67eab82267aa8df6 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 2b02a04..19b9364 100644 +index 77714e3d..74f56d47 100644 --- a/auth-krb5.c +++ b/auth-krb5.c -@@ -375,5 +375,21 @@ cleanup: +@@ -465,5 +465,21 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm return (krb5_cc_resolve(ctx, ccname, ccache)); } } @@ -25,10 +37,10 @@ index 2b02a04..19b9364 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index f9d191c..c432d2f 100644 +index 10e88e11..39163035 100644 --- a/auth.h +++ b/auth.h -@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *); +@@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *); #if defined(KRB5) && !defined(HEIMDAL) krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); @@ -38,10 +50,10 @@ index f9d191c..c432d2f 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a7c0c5f..df8cc9a 100644 +index df55512d..820f794c 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c -@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists() +@@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists() { char file[MAXPATHLEN]; struct passwd *pw = the_authctxt->pw; @@ -71,10 +83,10 @@ index a7c0c5f..df8cc9a 100644 } diff --git a/sshd.8 b/sshd.8 -index 5c4f15b..135e290 100644 +index 049d0a94..6784286d 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -806,6 +806,10 @@ rlogin/rsh. +@@ -880,6 +880,10 @@ rlogin/rsh. These files enforce GSSAPI/Kerberos authentication access control. Further details are described in .Xr ksu 1 . @@ -85,3 +97,6 @@ index 5c4f15b..135e290 100644 .Pp .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration +-- +2.49.0 + diff --git a/openssh-6.6p1-kuserok.patch b/0016-openssh-6.6p1-kuserok.patch similarity index 80% rename from openssh-6.6p1-kuserok.patch rename to 0016-openssh-6.6p1-kuserok.patch index e43128b..3724b8d 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/0016-openssh-6.6p1-kuserok.patch @@ -1,7 +1,22 @@ -diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c ---- openssh-7.4p1/auth-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100 -+++ openssh-7.4p1/auth-krb5.c 2016-12-23 14:36:07.644465936 +0100 -@@ -56,6 +56,21 @@ +From bac7a9d1a654c8c2e0c71f979195e300b25d6232 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ extern ServerOptions options; @@ -23,7 +38,7 @@ diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c static int krb5_init(void *context) { -@@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; @@ -35,10 +50,11 @@ diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c problem = -1; goto out; } -diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c ---- openssh-7.4p1/gss-serv-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100 -+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 14:36:07.644465936 +0100 -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 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 *, int); static krb5_context krb_context = NULL; @@ -46,7 +62,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) +@@ -91,6 +92,103 @@ ssh_gssapi_krb5_init(void) * Returns true if the user is OK to log in, otherwise returns 0 */ @@ -150,7 +166,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) { -@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client +@@ -115,7 +213,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) /* NOTE: .k5login and .k5users must opened as root, not the user, * because if they are on a krb5-protected filesystem, user credentials * to access these files aren't available yet. */ @@ -160,7 +176,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); -@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); /* If both .k5login and .k5users DNE, self-login is ok. */ if (!k5login_exists && (access(file, F_OK) == -1)) { @@ -172,18 +188,19 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c } if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; -diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100 -@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions +diff --git a/servconf.c b/servconf.c +index 55aa5bf0..5dd5ca21 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions *options) options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; + options->use_kuserok = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->permit_empty_passwd = -1; -@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption + options->permit_empty_passwd = -1; +@@ -399,6 +400,8 @@ fill_default_server_options(ServerOptions *options) if (options->gss_kex_algorithms == NULL) options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); #endif @@ -192,16 +209,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -399,7 +402,7 @@ typedef enum { - sPort, sHostKeyFile, sLoginGraceTime, - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +@@ -567,7 +570,7 @@ typedef enum { + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -478,12 +481,14 @@ static struct { + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, +@@ -659,12 +662,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, @@ -216,18 +233,18 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions - } - break; - +@@ -2441,6 +2446,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, + } + break; + + case sKerberosUseKuserok: + intptr = &options->use_kuserok; + goto parse_flag; + - case sMatch: - if (cmdline) - fatal("Match directive not supported as a command-line " -@@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " +@@ -2995,6 +3004,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -235,18 +252,19 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) +@@ -3303,6 +3313,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); #endif #ifdef GSSAPI - dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.kuserok 2016-12-23 14:36:07.630465944 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100 -@@ -118,6 +118,7 @@ typedef struct { + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); +diff --git a/servconf.h b/servconf.h +index a4a38d6d..11de36a2 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -151,6 +151,7 @@ typedef struct { * authenticated with Kerberos. */ int kerberos_unique_ccache; /* If true, the acquired ticket will * be stored in per-session ccache */ @@ -254,10 +272,23 @@ diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100 -@@ -850,6 +850,10 @@ Specifies whether to automatically destr +diff --git a/sshd_config b/sshd_config +index 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 .Cm no can lead to overwriting previous tickets by subseqent connections to the same user account. @@ -268,7 +299,7 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 .It Cm KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. -@@ -1078,6 +1082,7 @@ Available keywords are +@@ -1355,6 +1359,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -276,14 +307,6 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 .Cm LogLevel , .Cm MaxAuthTries , .Cm MaxSessions , -diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.kuserok 2016-12-23 14:36:07.631465943 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 14:36:07.646465935 +0100 -@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no +-- +2.49.0 + diff --git a/0017-openssh-6.4p1-fromto-remote.patch b/0017-openssh-6.4p1-fromto-remote.patch new file mode 100644 index 0000000..5e8309d --- /dev/null +++ b/0017-openssh-6.4p1-fromto-remote.patch @@ -0,0 +1,28 @@ +From 20aabb2c445e29d211266ce7434bb0273edf88b9 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/0018-openssh-6.6.1p1-selinux-contexts.patch similarity index 73% rename from openssh-6.6.1p1-selinux-contexts.patch rename to 0018-openssh-6.6.1p1-selinux-contexts.patch index 96161cb..49f2119 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/0018-openssh-6.6.1p1-selinux-contexts.patch @@ -1,8 +1,20 @@ +From 6481ac7fbd0027a7038560e0f51dd0af056cc229 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 8f32464..18a2ca4 100644 +index 8c5fc1fe..646f0887 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -32,6 +32,7 @@ +@@ -33,6 +33,7 @@ #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ #include "servconf.h" #include "port-linux.h" @@ -10,7 +22,7 @@ index 8f32464..18a2ca4 100644 #include "sshkey.h" #include "hostfile.h" #include "auth.h" -@@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -450,7 +451,7 @@ sshd_selinux_setup_exec_context(char *pwname) void sshd_selinux_copy_context(void) { @@ -19,7 +31,7 @@ index 8f32464..18a2ca4 100644 if (!sshd_selinux_enabled()) return; -@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void) +@@ -469,6 +470,72 @@ sshd_selinux_copy_context(void) } } @@ -93,22 +105,23 @@ index 8f32464..18a2ca4 100644 #endif diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c ---- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/openbsd-compat/port-linux.c (date 1703108053912) -@@ -207,7 +207,7 @@ +index 7426f6f7..9a6b1d6e 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); if (setcon(newctx) < 0) do_log2_f(log_level, "setcon %s from %s failed with %s", newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index cb51f99..8b7cda2 100644 +index 1b745a76..7f8ba200 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h -@@ -29,6 +29,7 @@ int sshd_selinux_enabled(void); +@@ -27,6 +27,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); @@ -116,16 +129,19 @@ index cb51f99..8b7cda2 100644 #endif #ifdef LINUX_OOM_ADJUST -diff --git a/sshd-session.c b/sshd-session.c -index 2871fe9..39b9c08 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -629,7 +629,7 @@ privsep_preauth_child(void) - demote_sensitive_data(); - +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 #ifdef WITH_SELINUX - ssh_selinux_change_context("sshd_net_t"); + sshd_selinux_change_privsep_preauth_context(); #endif /* Demote the child */ +-- +2.49.0 + diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/0019-openssh-6.6.1p1-log-in-chroot.patch similarity index 54% rename from openssh-6.6.1p1-log-in-chroot.patch rename to 0019-openssh-6.6.1p1-log-in-chroot.patch index 0f65279..3b30f98 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/0019-openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,25 @@ -diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c ---- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/log.c 2021-04-19 14:43:08.544843434 +0200 -@@ -194,6 +194,11 @@ void +From 825018f5f2d892655f3d63167a0d1f3391cec678 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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) { @@ -13,7 +31,7 @@ diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif -@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level +@@ -208,8 +213,10 @@ log_init(const char *av0, LogLevel level, SyslogFacility facility, exit(1); } @@ -26,9 +44,10 @@ diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c log_on_stderr = on_stderr; if (on_stderr) -diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h ---- openssh-8.6p1/log.h.log-in-chroot 2021-04-19 14:43:08.544843434 +0200 -+++ openssh-8.6p1/log.h 2021-04-19 14:56:46.931042176 +0200 +diff --git a/log.h b/log.h +index 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 *); @@ -37,43 +56,11 @@ diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h LogLevel log_level_get(void); int log_change_level(LogLevel); int log_is_on_stderr(void); -diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c ---- openssh-8.6p1/monitor.c.log-in-chroot 2021-04-19 14:43:08.526843298 +0200 -+++ openssh-8.6p1/monitor.c 2021-04-19 14:55:25.286424043 +0200 -@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s - close(pmonitor->m_log_sendfd); - pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; - -+ pmonitor->m_state = "preauth"; -+ - authctxt = (Authctxt *)ssh->authctxt; - memset(authctxt, 0, sizeof(*authctxt)); - ssh->authctxt = authctxt; -@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh, - close(pmonitor->m_recvfd); - pmonitor->m_recvfd = -1; - -+ pmonitor->m_state = "postauth"; -+ - monitor_set_child_handler(pmonitor->m_pid); - ssh_signal(SIGHUP, &monitor_child_handler); - ssh_signal(SIGTERM, &monitor_child_handler); -@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito - /* Log it */ - if (log_level_name(level) == NULL) - fatal_f("invalid log level %u (corrupted message?)", level); -- sshlogdirect(level, forced, "%s [preauth]", msg); -+ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state); - - sshbuf_free(logmsg); - free(msg); -@@ -1868,13 +1872,28 @@ monitor_init(void) - mon = xcalloc(1, sizeof(*mon)); - monitor_openfds(mon, 1); - -+ mon->m_state = ""; -+ - return mon; +diff --git a/monitor.c b/monitor.c +index 2ef16cc8..43c10a4e 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -2001,9 +2001,22 @@ monitor_init(void) } void @@ -98,14 +85,11 @@ diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c } #ifdef GSSAPI -diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h ---- openssh-8.6p1/monitor.h.log-in-chroot 2021-04-19 14:43:08.527843305 +0200 -+++ openssh-8.6p1/monitor.h 2021-04-19 14:43:08.545843441 +0200 -@@ -80,10 +80,11 @@ struct monitor { - int m_log_sendfd; - struct kex **m_pkex; - pid_t m_pid; -+ char *m_state; +diff --git a/monitor.h b/monitor.h +index dbc7e003..d4d631dd 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -85,7 +85,7 @@ struct monitor { }; struct monitor *monitor_init(void); @@ -114,10 +98,11 @@ diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h struct Authctxt; void monitor_child_preauth(struct ssh *, struct monitor *); -diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c ---- openssh-8.6p1/session.c.log-in-chroot 2021-04-19 14:43:08.534843358 +0200 -+++ openssh-8.6p1/session.c 2021-04-19 14:43:08.545843441 +0200 -@@ -160,6 +160,7 @@ login_cap_t *lc; +diff --git a/session.c b/session.c +index 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; @@ -125,7 +110,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -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]; @@ -133,7 +118,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c if (options.adm_forced_command) { original_command = command; -@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -729,6 +731,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command) tty += 5; } @@ -144,7 +129,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh) +@@ -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); @@ -159,7 +144,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c } /* -@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) exit(1); } @@ -168,7 +153,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1678,9 +1674,17 @@ do_child(struct ssh *ssh, Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -187,29 +172,31 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c fflush(NULL); /* Get the last component of the shell name. */ -diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h ---- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sftp.h 2021-04-19 14:43:08.545843441 +0200 -@@ -97,5 +97,5 @@ +diff --git a/sftp-server-main.c b/sftp-server-main.c +index 2c70f89b..bbb79f27 100644 +--- a/sftp-server-main.c ++++ b/sftp-server-main.c +@@ -48,5 +48,5 @@ main(int argc, char **argv) + return 1; + } - struct passwd; - --int sftp_server_main(int, char **, struct passwd *); -+int sftp_server_main(int, char **, struct passwd *, int); - void sftp_server_cleanup_exit(int) __attribute__((noreturn)); -diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c ---- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sftp-server.c 2021-04-19 14:43:08.545843441 +0200 -@@ -1644,7 +1644,7 @@ sftp_server_usage(void) +- return (sftp_server_main(argc, argv, user_pw)); ++ return (sftp_server_main(argc, argv, user_pw, 0)); + } +diff --git a/sftp-server.c b/sftp-server.c +index 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; -@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, + int i, r, in, out, ch, skipargs = 0, log_stderr = 0; + ssize_t len, olen; +@@ -1913,7 +1913,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -218,7 +205,7 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c pw = pwcopy(user_pw); -@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv, +@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } } @@ -227,20 +214,22 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c /* * On platforms where we can, avoid making /proc/self/{mem,maps} -diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c ---- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/sftp-server-main.c 2021-04-19 14:43:08.545843441 +0200 -@@ -50,5 +50,5 @@ main(int argc, char **argv) - return 1; - } +diff --git a/sftp.h b/sftp.h +index 2bde8bb7..ddf1a396 100644 +--- a/sftp.h ++++ b/sftp.h +@@ -97,5 +97,5 @@ -- return (sftp_server_main(argc, argv, user_pw)); -+ return (sftp_server_main(argc, argv, user_pw, 0)); - } -diff -up openssh-8.6p1/sshd-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 + 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 */ @@ -249,7 +238,7 @@ diff -up openssh-8.6p1/sshd-session.c.log-in-chroot openssh-8.6p1/sshd-session.c pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -456,6 +456,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; @@ -261,3 +250,6 @@ diff -up openssh-8.6p1/sshd-session.c.log-in-chroot openssh-8.6p1/sshd-session.c /* Demote the private keys to public keys. */ demote_sensitive_data(); +-- +2.49.0 + diff --git a/0020-openssh-6.6.1p1-scp-non-existing-directory.patch b/0020-openssh-6.6.1p1-scp-non-existing-directory.patch new file mode 100644 index 0000000..94c43ef --- /dev/null +++ b/0020-openssh-6.6.1p1-scp-non-existing-directory.patch @@ -0,0 +1,27 @@ +From 007ee98fa9100f7241985ac2a7eed71e17d89a9f Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/0021-openssh-6.6p1-GSSAPIEnablek5users.patch similarity index 61% rename from openssh-6.6p1-GSSAPIEnablek5users.patch rename to 0021-openssh-6.6p1-GSSAPIEnablek5users.patch index 7fef831..eeff02a 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/0021-openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,7 +1,21 @@ -diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-serv-krb5.c ---- openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100 -+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 15:18:40.628216102 +0100 -@@ -279,7 +279,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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, FILE *fp; char file[MAXPATHLEN]; char *line = NULL; @@ -9,7 +23,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-ser struct stat st; struct passwd *pw = the_authctxt->pw; int found_principal = 0; -@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri +@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); /* If both .k5login and .k5users DNE, self-login is ok. */ @@ -18,18 +32,19 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-ser return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100 -@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions +diff --git a/servconf.c b/servconf.c +index 5dd5ca21..c0de7110 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options) options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; + options->enable_k5users = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->permit_empty_passwd = -1; -@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption + options->permit_empty_passwd = -1; +@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options) #endif if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -38,7 +53,7 @@ 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) -@@ -578,7 +578,7 @@ typedef enum { +@@ -585,7 +588,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -47,7 +62,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, -@@ -600,14 +600,16 @@ static struct { +@@ -681,6 +684,7 @@ static struct { { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, @@ -55,8 +70,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, - { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, - { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, +@@ -689,6 +693,7 @@ static struct { { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, @@ -64,7 +78,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions +@@ -2450,6 +2455,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->use_kuserok; goto parse_flag; @@ -72,10 +86,10 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + intptr = &options->enable_k5users; + goto parse_flag; + - case sMatch: - if (cmdline) - fatal("Match directive not supported as a command-line " -@@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " +@@ -3005,6 +3014,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -83,7 +97,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) +@@ -3314,6 +3324,7 @@ dump_config(ServerOptions *o) # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -91,21 +105,35 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100 -@@ -174,6 +174,7 @@ typedef struct { - int kerberos_unique_ccache; /* If true, the acquired ticket will - * be stored in per-session ccache */ +diff --git a/servconf.h b/servconf.h +index 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 */ int use_kuserok; + int enable_k5users; int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100 -@@ -628,6 +628,12 @@ Specifies whether to automatically destr +diff --git a/sshd_config b/sshd_config +index 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 on logout. The default is .Cm yes . @@ -118,17 +146,6 @@ diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_conf .It Cm GSSAPIKeyExchange Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. -diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 15:18:40.631216103 +0100 -@@ -80,6 +80,7 @@ GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes - #GSSAPIStrictAcceptorCheck yes - #GSSAPIKeyExchange no -+#GSSAPIEnablek5users no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -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 +-- +2.49.0 + diff --git a/0022-openssh-6.8p1-sshdT-output.patch b/0022-openssh-6.8p1-sshdT-output.patch new file mode 100644 index 0000000..4e4766e --- /dev/null +++ b/0022-openssh-6.8p1-sshdT-output.patch @@ -0,0 +1,25 @@ +From 05b09904f431333e19cd24528ef66d1fd15e9efe Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-6.7p1-sftp-force-permission.patch b/0023-openssh-6.7p1-sftp-force-permission.patch similarity index 72% rename from openssh-6.7p1-sftp-force-permission.patch rename to 0023-openssh-6.7p1-sftp-force-permission.patch index 1cfa309..1cdc0df 100644 --- a/openssh-6.7p1-sftp-force-permission.patch +++ b/0023-openssh-6.7p1-sftp-force-permission.patch @@ -1,6 +1,17 @@ -diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8 ---- openssh-7.2p2/sftp-server.8.sftp-force-mode 2016-03-09 19:04:48.000000000 +0100 -+++ openssh-7.2p2/sftp-server.8 2016-06-23 16:18:20.463854117 +0200 +From 34b196198018059bed294fa7a08e70606b4cbc36 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ -38,6 +38,7 @@ .Op Fl P Ar denied_requests .Op Fl p Ar allowed_requests @@ -22,10 +33,11 @@ diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8 .El .Pp On some systems, -diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c ---- openssh-7.2p2/sftp-server.c.sftp-force-mode 2016-06-23 16:18:20.446854128 +0200 -+++ openssh-7.2p2/sftp-server.c 2016-06-23 16:20:37.950766082 +0200 -@@ -69,6 +69,10 @@ struct sshbuf *oqueue; +diff --git a/sftp-server.c b/sftp-server.c +index 4985da38..6ed1c27f 100644 +--- a/sftp-server.c ++++ b/sftp-server.c +@@ -76,6 +76,10 @@ struct sshbuf *oqueue; /* Version of client */ static u_int version; @@ -36,7 +48,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c /* SSH2_FXP_INIT received */ static int init_done; -@@ -683,6 +687,7 @@ process_open(u_int32_t id) +@@ -745,6 +749,7 @@ process_open(u_int32_t id) Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; @@ -44,7 +56,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ -@@ -692,6 +697,10 @@ process_open(u_int32_t id) +@@ -754,6 +759,10 @@ process_open(u_int32_t id) debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; @@ -55,7 +67,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && -@@ -713,6 +722,8 @@ process_open(u_int32_t id) +@@ -775,6 +784,8 @@ process_open(u_int32_t id) } } } @@ -64,7 +76,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c if (status != SSH2_FX_OK) send_status(id, status); free(name); -@@ -1494,7 +1505,7 @@ sftp_server_usage(void) +@@ -1894,7 +1905,7 @@ sftp_server_usage(void) fprintf(stderr, "usage: %s [-ehR] [-d start_directory] [-f log_facility] " "[-l log_level]\n\t[-P denied_requests] " @@ -73,7 +85,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c " %s -Q protocol_feature\n", __progname, __progname); exit(1); -@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv, +@@ -1918,7 +1929,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle pw = pwcopy(user_pw); while (!skipargs && (ch = getopt(argc, argv, @@ -82,7 +94,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c switch (ch) { case 'Q': if (strcasecmp(optarg, "requests") != 0) { -@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv, +@@ -1980,6 +1991,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle fatal("Invalid umask \"%s\"", optarg); (void)umask((mode_t)mask); break; @@ -98,3 +110,6 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c case 'h': default: sftp_server_usage(); +-- +2.49.0 + diff --git a/openssh-7.2p2-s390-closefrom.patch b/0024-openssh-7.2p2-s390-closefrom.patch similarity index 66% rename from openssh-7.2p2-s390-closefrom.patch rename to 0024-openssh-7.2p2-s390-closefrom.patch index 363538c..0214781 100644 --- a/openssh-7.2p2-s390-closefrom.patch +++ b/0024-openssh-7.2p2-s390-closefrom.patch @@ -1,21 +1,17 @@ -Zseries only: Leave the hardware filedescriptors open. - -All filedescriptors above 2 are getting closed when a new -sshd process to handle a new client connection is -spawned. As the process also chroot into an empty filesystem -without any device nodes, there is no chance to reopen the -files. This patch filters out the reqired fds in the -closefrom function so these are skipped in the close loop. - -Author: Harald Freudenberger +From 9bb31b63142adaaf949e20c2d86c97f9b787217b Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 24/50] openssh-7.2p2-s390-closefrom --- - openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ + openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) +diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c +index 49a4f35f..f6112458 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c -@@ -82,7 +82,33 @@ closefrom(int lowfd) +@@ -140,7 +140,33 @@ closefrom(int lowfd) fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) @@ -49,4 +45,6 @@ Author: Harald Freudenberger } (void) closedir(dirp); return; +-- +2.49.0 diff --git a/openssh-7.3p1-x11-max-displays.patch b/0025-openssh-7.3p1-x11-max-displays.patch similarity index 53% rename from openssh-7.3p1-x11-max-displays.patch rename to 0025-openssh-7.3p1-x11-max-displays.patch index e28c62e..68d679c 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/0025-openssh-7.3p1-x11-max-displays.patch @@ -1,18 +1,22 @@ -diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c ---- openssh-7.4p1/channels.c.x11max 2016-12-23 15:46:32.071506625 +0100 -+++ openssh-7.4p1/channels.c 2016-12-23 15:46:32.139506636 +0100 -@@ -152,8 +152,8 @@ static int all_opens_permitted = 0; - #define NUM_SOCKS 10 - - /* -- X11 forwarding */ --/* Maximum number of fake X11 displays to try. */ --#define MAX_DISPLAYS 1000 -+/* Minimum port number for X11 forwarding */ -+#define X11_PORT_MIN 6000 - - /* Per-channel callback for pre/post IO actions */ - typedef void chan_fn(struct ssh *, Channel *c); -@@ -4228,7 +4228,7 @@ channel_send_window_changes(void) +From 36e3430d1f81397d5f40600e075272a81f7effce Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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) */ int x11_create_display_inet(struct ssh *ssh, int x11_display_offset, @@ -21,8 +25,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c u_int *display_numberp, int **chanids) { Channel *nc = NULL; -@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ - if (chanids == NULL) +@@ -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) return -1; + /* Try to bind ports starting at 6000+X11DisplayOffset */ @@ -32,55 +36,22 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c - display_number < MAX_DISPLAYS; + display_number < x11_max_displays; display_number++) { -- port = 6000 + display_number; -+ port = X11_PORT_MIN + display_number; -+ if (port < X11_PORT_MIN) /* overflow */ -+ break; + port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); - hints.ai_family = ssh->chanctxt->IPv4or6; - hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; -@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ +@@ -5065,7 +5068,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } - if (display_number >= MAX_DISPLAYS) { -+ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) { ++ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) { error("Failed to allocate internet-domain X11 display socket."); return -1; } -@@ -4441,7 +4447,7 @@ x11_connect_display(void) - memset(&hints, 0, sizeof(hints)); - hints.ai_family = ssh->chanctxt->IPv4or6; - hints.ai_socktype = SOCK_STREAM; -- snprintf(strport, sizeof strport, "%u", 6000 + display_number); -+ snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number); - if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { - error("%.100s: unknown host. (%s)", buf, - ssh_gai_strerror(gaierr)); -@@ -4457,7 +4463,7 @@ x11_connect_display(void) - /* Connect it to the display. */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { - debug2("connect %.100s port %u: %.100s", buf, -- 6000 + display_number, strerror(errno)); -+ X11_PORT_MIN + display_number, strerror(errno)); - close(sock); - continue; - } -@@ -4466,8 +4472,8 @@ x11_connect_display(void) - } - freeaddrinfo(aitop); - if (!ai) { -- error("connect %.100s port %u: %.100s", buf, -- 6000 + display_number, strerror(errno)); -+ error("connect %.100s port %u: %.100s", buf, -+ X11_PORT_MIN + display_number, strerror(errno)); - return -1; - } - set_nodelay(sock); -diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h ---- openssh-7.4p1/channels.h.x11max 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/channels.h 2016-12-23 15:46:32.139506636 +0100 -@@ -293,7 +293,7 @@ int permitopen_port(const char *); +diff --git a/channels.h b/channels.h +index 134528d5..8a09a820 100644 +--- a/channels.h ++++ b/channels.h +@@ -379,7 +379,7 @@ int permitopen_port(const char *); void channel_set_x11_refuse_time(struct ssh *, time_t); int x11_connect_display(struct ssh *); @@ -88,11 +59,12 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h +int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **); void x11_request_forwarding_with_spoofing(struct ssh *, int, const char *, const char *, const char *, int); - -diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.x11max 2016-12-23 15:46:32.133506635 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:47:27.320519121 +0100 -@@ -95,6 +95,7 @@ initialize_server_options(ServerOptions + int x11_channel_used_recently(struct ssh *ssh); +diff --git a/servconf.c b/servconf.c +index 105e301d..15c99b30 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions *options) options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; @@ -100,7 +72,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; -@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption +@@ -353,6 +354,8 @@ fill_default_server_options(ServerOptions *options) options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; @@ -109,16 +81,16 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) -@@ -419,7 +422,7 @@ typedef enum { - sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, +@@ -576,7 +579,7 @@ typedef enum { + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -540,6 +543,7 @@ static struct { +@@ -714,6 +717,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -126,7 +98,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, -@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions +@@ -1750,6 +1754,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *intptr = value; break; @@ -137,7 +109,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; -@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d +@@ -3004,6 +3012,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); @@ -145,7 +117,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); -@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o) +@@ -3299,6 +3308,7 @@ dump_config(ServerOptions *o) #endif dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); @@ -153,10 +125,11 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c dump_cfg_int(sMaxAuthTries, o->max_authtries); dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); -diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.x11max 2016-12-23 15:46:32.133506635 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 15:46:32.140506636 +0100 -@@ -55,6 +55,7 @@ +diff --git a/servconf.h b/servconf.h +index c08cf6a7..7c7e5d43 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -38,6 +38,7 @@ #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ @@ -164,7 +137,7 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h /* Magic name for internal sftp-server */ #define INTERNAL_SFTP_NAME "internal-sftp" -@@ -85,6 +86,7 @@ typedef struct { +@@ -114,6 +115,7 @@ typedef struct { int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ int x11_display_offset; /* What DISPLAY number to start * searching at */ @@ -172,13 +145,14 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h int x11_use_localhost; /* If true, use localhost for fake X11 server. */ char *xauth_location; /* Location of xauth program */ int permit_tty; /* If false, deny pty allocation */ -diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.x11max 2016-12-23 15:46:32.136506636 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:46:32.141506636 +0100 -@@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s) +diff --git a/session.c b/session.c +index 54da09d5..28bbb8a7 100644 +--- a/session.c ++++ b/session.c +@@ -2611,8 +2611,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) return 0; } - if (x11_create_display_inet(ssh, options.x11_display_offset, + if (x11_create_display_inet(ssh, options.x11_display_offset, - options.x11_use_localhost, s->single_connection, - &s->display_number, &s->x11_chanids) == -1) { + options.x11_use_localhost, options.x11_max_displays, @@ -187,10 +161,11 @@ diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c debug("x11_create_display_inet failed."); return 0; } -diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.x11max 2016-12-23 15:46:32.134506635 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:46:32.141506636 +0100 -@@ -1133,6 +1133,7 @@ Available keywords are +diff --git a/sshd_config.5 b/sshd_config.5 +index fe246fc2..26fcdc84 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1391,6 +1391,7 @@ Available keywords are .Cm TrustedUserCAKeys , .Cm UnusedConnectionTimeout , .Cm X11DisplayOffset , @@ -198,7 +173,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 .Cm X11Forwarding and .Cm X11UseLocalhost . -@@ -1566,6 +1567,12 @@ Specifies the first display number avail +@@ -2111,6 +2112,12 @@ Specifies the first display number available for X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. @@ -211,3 +186,6 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be +-- +2.49.0 + diff --git a/openssh-7.6p1-cleanup-selinux.patch b/0026-openssh-7.6p1-cleanup-selinux.patch similarity index 65% rename from openssh-7.6p1-cleanup-selinux.patch rename to 0026-openssh-7.6p1-cleanup-selinux.patch index cfe11ad..c4f2d15 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/0026-openssh-7.6p1-cleanup-selinux.patch @@ -1,7 +1,25 @@ -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,8 @@ +From 43320351b6f150167190aacc84f2f87030fef3d2 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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; @@ -10,7 +28,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c extern struct authmethod_cfg methodcfg_pubkey; static char * -@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh +@@ -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, @@ -20,20 +38,21 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c goto out; uid_swapped = 1; -@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss +@@ -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, + 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 -up openssh/misc.c.refactor openssh/misc.c ---- openssh/misc.c.refactor 2019-04-04 13:19:12.235821686 +0200 -+++ openssh/misc.c 2019-04-04 13:19:12.276822078 +0200 -@@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh * +diff --git a/misc.c b/misc.c +index 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, @@ -43,7 +62,7 @@ diff -up openssh/misc.c.refactor openssh/misc.c { FILE *f = NULL; struct stat st; -@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw +@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command, _exit(1); } #ifdef WITH_SELINUX @@ -52,10 +71,11 @@ diff -up openssh/misc.c.refactor openssh/misc.c error ("failed to copy environment: %s", strerror(errno)); _exit(127); -diff -up openssh/misc.h.refactor openssh/misc.h ---- openssh/misc.h.refactor 2019-04-04 13:19:12.251821839 +0200 -+++ openssh/misc.h 2019-04-04 13:19:12.276822078 +0200 -@@ -235,7 +235,7 @@ struct passwd *fakepw(void); +diff --git a/misc.h b/misc.h +index 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, @@ -64,23 +84,10 @@ diff -up openssh/misc.h.refactor openssh/misc.h typedef struct arglist arglist; struct arglist { -diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h ---- openssh/openbsd-compat/port-linux.h.refactor 2019-04-04 13:19:12.256821887 +0200 -+++ openssh/openbsd-compat/port-linux.h 2019-04-04 13:19:12.276822078 +0200 -@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch - - int sshd_selinux_enabled(void); - void sshd_selinux_copy_context(void); --void sshd_selinux_setup_exec_context(char *); --int sshd_selinux_setup_env_variables(void); -+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int); -+int sshd_selinux_setup_env_variables(int inetd, void *); - void sshd_selinux_change_privsep_preauth_context(void); - #endif - -diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c ---- openssh/openbsd-compat/port-linux-sshd.c.refactor 2019-04-04 13:19:12.256821887 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2019-04-04 13:19:12.276822078 +0200 +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 #endif @@ -92,7 +99,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa /* 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 +@@ -222,7 +218,8 @@ get_user_context(const char *sename, const char *role, const char *lvl, } static void @@ -102,7 +109,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { *role = NULL; *level = NULL; -@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role, +@@ -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 @@ -113,7 +120,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { char *sename, *lvl; char *role; -@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, int r = 0; context_t con = NULL; @@ -122,7 +129,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa #ifdef HAVE_GETSEUSERBYNAME if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -271,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, if (r == 0) { /* If launched from xinetd, we must use current level */ @@ -131,7 +138,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa security_context_t sshdsc=NULL; if (getcon_raw(&sshdsc) < 0) -@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -141,7 +148,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa { const char *reqlvl; char *role; -@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it +@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) debug3_f("setting execution context"); @@ -155,7 +162,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa use_current = "1"; } else { use_current = ""; -@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it +@@ -361,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) } static int @@ -168,7 +175,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa } static int -@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value) +@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value) } int @@ -202,7 +209,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa switch (security_getenforce()) { case -1: fatal_f("security_getenforce() failed"); -@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw +@@ -407,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pwname) debug3_f("setting execution context"); @@ -211,10 +218,26 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa if (r >= 0) { r = setexeccon(user_ctx); if (r < 0) { -diff -up openssh/platform.c.refactor openssh/platform.c ---- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200 -+++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200 -@@ -32,6 +32,8 @@ +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; @@ -223,7 +246,7 @@ diff -up openssh/platform.c.refactor openssh/platform.c /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ int -@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru +@@ -140,7 +142,9 @@ platform_setusercontext_post_groups(struct passwd *pw) } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -234,10 +257,37 @@ diff -up openssh/platform.c.refactor openssh/platform.c #endif } -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; +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. */ @@ -246,7 +296,7 @@ diff -up openssh/sshd-session.c.refactor openssh/sshd-session.c /* debug goes to stderr unless inetd_flag is set */ static int log_stderr = 0; -@@ -2192,7 +2192,9 @@ main(int ac, char **av) +@@ -1359,7 +1359,9 @@ main(int ac, char **av) } #endif #ifdef WITH_SELINUX @@ -257,15 +307,6 @@ diff -up openssh/sshd-session.c.refactor openssh/sshd-session.c #endif #ifdef USE_PAM if (options.use_pam) { -diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c ---- openssh/sshconnect.c.refactor 2021-02-24 00:12:03.065325046 +0100 -+++ openssh/sshconnect.c 2021-02-24 00:12:12.126449544 +0100 -@@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h - - if ((pid = subprocess(tag, command, ac, av, &f, - SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| -- 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); +-- +2.49.0 + diff --git a/0027-openssh-7.5p1-sandbox.patch b/0027-openssh-7.5p1-sandbox.patch new file mode 100644 index 0000000..435d029 --- /dev/null +++ b/0027-openssh-7.5p1-sandbox.patch @@ -0,0 +1,58 @@ +From 35205319dd71d8e61c1596b8f9479df91aff7756 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/0028-openssh-8.0p1-pkcs11-uri.patch similarity index 90% rename from openssh-8.0p1-pkcs11-uri.patch rename to 0028-openssh-8.0p1-pkcs11-uri.patch index bdc4722..73e890b 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/0028-openssh-8.0p1-pkcs11-uri.patch @@ -1,7 +1,102 @@ -diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac ---- openssh-9.6p1/configure.ac.pkcs11-uri 2024-01-12 14:25:25.228942213 +0100 -+++ openssh-9.6p1/configure.ac 2024-01-12 14:25:25.233942336 +0100 -@@ -2066,12 +2066,14 @@ AC_LINK_IFELSE( +From 5d6ec35c1a0e06452a2c087decb0baf6e8063e21 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 28/50] openssh-8.0p1-pkcs11-uri + +--- + Makefile.in | 20 +- + configure.ac | 37 ++ + regress/Makefile | 8 +- + regress/pkcs11.sh | 349 +++++++++++++++ + regress/unittests/Makefile | 2 +- + regress/unittests/pkcs11/tests.c | 346 ++++++++++++++ + ssh-add.c | 48 +- + ssh-agent.c | 103 ++++- + ssh-keygen.c | 7 +- + ssh-pkcs11-client.c | 3 + + ssh-pkcs11-uri.c | 437 ++++++++++++++++++ + ssh-pkcs11-uri.h | 43 ++ + ssh-pkcs11.c | 745 +++++++++++++++++++++++-------- + ssh-pkcs11.h | 4 + + ssh.c | 104 ++++- + ssh_config.5 | 15 + + 16 files changed, 2024 insertions(+), 247 deletions(-) + create mode 100644 regress/pkcs11.sh + create mode 100644 regress/unittests/pkcs11/tests.c + create mode 100644 ssh-pkcs11-uri.c + create mode 100644 ssh-pkcs11-uri.h + +diff --git a/Makefile.in b/Makefile.in +index 78f65948..6c417ef7 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -110,7 +110,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o ed25519.o hash.o \ +@@ -339,6 +339,8 @@ clean: regressclean + rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) +@@ -377,6 +379,8 @@ distclean: regressclean + rm -f regress/unittests/sshsig/test_sshsig + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so +@@ -558,6 +562,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/sshkey + $(MKDIR_P) `pwd`/regress/unittests/sshsig + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/sk-dummy + $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation + [ -f `pwd`/regress/Makefile ] || \ +@@ -731,6 +736,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lcrypto $(LIBS) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -776,7 +791,8 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ +- regress/unittests/utf8/test_utf8$(EXEEXT) ++ regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + + tests: file-tests t-exec interop-tests extra-tests unit + echo all tests passed +diff --git a/configure.ac b/configure.ac +index 13c70a98..d9bd2f51 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2172,12 +2172,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +111,7 @@ diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac fi ] ) -@@ -2095,6 +2097,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2207,6 +2209,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +152,7 @@ diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5708,6 +5744,7 @@ echo " BSD Auth support +@@ -5820,6 +5856,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,75 +160,11 @@ diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac echo " U2F/FIDO support: $enable_sk" echo "" -diff -up openssh-9.6p1/Makefile.in.pkcs11-uri openssh-9.6p1/Makefile.in ---- openssh-9.6p1/Makefile.in.pkcs11-uri 2024-01-12 14:25:25.204941622 +0100 -+++ openssh-9.6p1/Makefile.in 2024-01-12 14:25:25.233942336 +0100 -@@ -105,7 +105,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ - ssh-ed25519-sk.o ssh-rsa.o dh.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o ed25519.o hash.o \ -@@ -299,6 +299,8 @@ clean: regressclean - rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -336,6 +338,8 @@ distclean: regressclean - rm -f regress/unittests/sshsig/test_sshsig - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8 -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -513,6 +517,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/sshkey - $(MKDIR_P) `pwd`/regress/unittests/sshsig - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/sk-dummy - [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -685,6 +690,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lcrypto $(LIBS) -+ - # These all need to be compiled -fPIC, so they are treated differently. - SK_DUMMY_OBJS=\ - regress/misc/sk-dummy/sk-dummy.lo \ -@@ -720,7 +735,8 @@ regress-unit-binaries: regress-prep $(RE - regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ - regress/unittests/sshkey/test_sshkey$(EXEEXT) \ - regress/unittests/sshsig/test_sshsig$(EXEEXT) \ -- regress/unittests/utf8/test_utf8$(EXEEXT) -+ regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - - tests: file-tests t-exec interop-tests extra-tests unit - echo all tests passed -diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefile ---- openssh-9.6p1/regress/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/regress/Makefile 2024-01-12 14:25:25.233942336 +0100 -@@ -134,7 +134,8 @@ CLEANFILES= *.core actual agent-key.* au +diff --git a/regress/Makefile b/regress/Makefile +index 7e7f95b5..f36de51e 100644 +--- a/regress/Makefile ++++ b/regress/Makefile +@@ -137,7 +137,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -143,7 +174,7 @@ diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefil rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -273,8 +274,9 @@ unit: +@@ -297,8 +298,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -155,9 +186,11 @@ diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefil -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11.sh ---- openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 -+++ openssh-9.6p1/regress/pkcs11.sh 2024-01-12 14:25:25.233942336 +0100 +diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh +new file mode 100644 +index 00000000..a91aee94 +--- /dev/null ++++ b/regress/pkcs11.sh @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -508,9 +541,10 @@ diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regress/unittests/Makefile ---- openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/regress/unittests/Makefile 2024-01-12 14:25:25.233942336 +0100 +diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile +index e370900e..d6c89c12 100644 +--- a/regress/unittests/Makefile ++++ b/regress/unittests/Makefile @@ -1,6 +1,6 @@ # $OpenBSD: Makefile,v 1.13 2023/09/24 08:14:13 claudio Exp $ @@ -519,9 +553,11 @@ diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regre +SUBDIR+=authopt misc sshsig pkcs11 .include -diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1/regress/unittests/pkcs11/tests.c ---- openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 -+++ openssh-9.6p1/regress/unittests/pkcs11/tests.c 2024-01-12 14:25:25.233942336 +0100 +diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c +new file mode 100644 +index 00000000..7d4fa499 +--- /dev/null ++++ b/regress/unittests/pkcs11/tests.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat @@ -869,9 +905,10 @@ diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1 + test_parse_invalid(); + test_generate_valid(); +} -diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c ---- openssh-9.6p1/ssh-add.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh-add.c 2024-01-12 14:25:25.233942336 +0100 +diff --git a/ssh-add.c b/ssh-add.c +index 0035cb84..b0f47f4d 100644 +--- a/ssh-add.c ++++ b/ssh-add.c @@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" @@ -880,7 +917,7 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c /* argv0 */ extern char *__progname; -@@ -240,6 +241,38 @@ delete_all(int agent_fd, int qflag) +@@ -242,6 +243,38 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -919,7 +956,7 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c static int add_file(int agent_fd, const char *filename, int key_only, int cert_only, int qflag, const char *skprovider, -@@ -460,15 +489,14 @@ static int +@@ -462,15 +495,14 @@ static int update_card(int agent_fd, int add, const char *id, int qflag, int key_only, int cert_only, struct dest_constraint **dest_constraints, size_t ndest_constraints, @@ -937,7 +974,7 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -656,6 +684,14 @@ do_file(int agent_fd, int deleting, int +@@ -658,6 +690,14 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, char *file, int qflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { @@ -952,7 +989,7 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c if (deleting) { if (delete_file(agent_fd, file, key_only, cert_only, qflag) == -1) -@@ -999,7 +1035,7 @@ main(int argc, char **argv) +@@ -1001,7 +1041,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, qflag, key_only, cert_only, dest_constraints, ndest_constraints, @@ -961,10 +998,11 @@ diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c ret = 1; goto done; } -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,74 @@ add_p11_identity(struct sshkey *key, cha +diff --git a/ssh-agent.c b/ssh-agent.c +index c27c5a95..798bf9b6 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1569,10 +1569,74 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, idtab->nentries++; } @@ -1040,21 +1078,21 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -1581,25 +1643,18 @@ process_add_smartcard_key(SocketEntry *e +@@ -1601,25 +1665,18 @@ process_add_smartcard_key(SocketEntry *e) "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); -+ sane_uri = sanitize_pkcs11_provider(provider); -+ if (sane_uri == NULL) - goto send; +- goto send; - } - if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " - "provider not allowed", canonical_provider); -- goto send; ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; - } - debug_f("add %.100s", canonical_provider); if (lifetime && !death) @@ -1071,7 +1109,7 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c } for (j = 0; j < ncerts; j++) { if (!sshkey_is_cert(certs[j])) -@@ -1609,13 +1664,13 @@ process_add_smartcard_key(SocketEntry *e +@@ -1629,13 +1686,13 @@ process_add_smartcard_key(SocketEntry *e) if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) continue; add_p11_identity(k, xstrdup(comments[i]), @@ -1087,7 +1125,7 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c dest_constraints, ndest_constraints); keys[i] = NULL; /* transferred */ comments[i] = NULL; /* transferred */ -@@ -1628,6 +1683,7 @@ process_add_smartcard_key(SocketEntry *e +@@ -1648,6 +1705,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); @@ -1095,7 +1133,7 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c free(keys); free(comments); free_dest_constraints(dest_constraints, ndest_constraints); -@@ -1640,7 +1696,7 @@ send: +@@ -1660,7 +1718,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1104,7 +1142,7 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c int r, success = 0; Identity *id, *nxt; -@@ -1652,30 +1708,29 @@ process_remove_smartcard_key(SocketEntry +@@ -1672,30 +1730,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1141,185 +1179,11 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff -up openssh-9.6p1/ssh_config.5.pkcs11-uri openssh-9.6p1/ssh_config.5 ---- openssh-9.6p1/ssh_config.5.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 -+++ openssh-9.6p1/ssh_config.5 2024-01-12 14:25:25.234942360 +0100 -@@ -1216,6 +1216,21 @@ may also be used in conjunction with - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query arguments -+.Cm module-path -+and -+.Cm pin-value -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. -diff -up openssh-9.6p1/ssh.c.pkcs11-uri openssh-9.6p1/ssh.c ---- openssh-9.6p1/ssh.c.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 -+++ openssh-9.6p1/ssh.c 2024-01-12 14:25:25.234942360 +0100 -@@ -882,6 +882,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) == -1) - fprintf(stderr, "Warning: Identity file %s " -@@ -1784,6 +1792,7 @@ main(int ac, char **av) - #ifdef ENABLE_PKCS11 - (void)pkcs11_del_provider(options.pkcs11_provider); - #endif -+ pkcs11_terminate(); - - skip_connect: - exit_status = ssh_session2(ssh, cinfo); -@@ -2307,6 +2316,45 @@ ssh_session2(struct ssh *ssh, const stru - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2321,11 +2369,6 @@ load_public_identity_files(const struct - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys = NULL; -- char **comments = NULL; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2338,33 +2381,46 @@ load_public_identity_files(const struct - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys, &comments)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- free(comments[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = comments[i]; /* transferred */ -- n_ids++; -- } -- free(keys); -- free(comments); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); -+ -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_dollar_expand(cp, cinfo); - free(cp); - check_load(sshkey_load_public(filename, &public, NULL), -diff -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c ---- openssh-9.6p1/ssh-keygen.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh-keygen.c 2024-01-12 14:25:25.234942360 +0100 -@@ -862,8 +862,11 @@ do_download(struct passwd *pw) +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 89c3ed28..16cff947 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -906,8 +906,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1333,10 +1197,11 @@ diff -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c } free(comments[i]); sshkey_free(keys[i]); -diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-client.c ---- openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh-pkcs11-client.c 2024-01-12 14:25:25.234942360 +0100 -@@ -592,6 +592,8 @@ pkcs11_add_provider(char *name, char *pi +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +index b8d1700f..64df695e 100644 +--- a/ssh-pkcs11-client.c ++++ b/ssh-pkcs11-client.c +@@ -635,6 +635,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, struct sshbuf *msg; struct helper *helper; @@ -1345,7 +1210,7 @@ diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-c if ((helper = helper_by_provider(name)) == NULL && (helper = pkcs11_start_helper(name)) == NULL) return -1; -@@ -612,6 +614,7 @@ pkcs11_add_provider(char *name, char *pi +@@ -655,6 +657,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1353,1296 +1218,11 @@ diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-c for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh-9.9p1/ssh-pkcs11.c.xxx openssh-9.9p1/ssh-pkcs11.c ---- openssh-9.9p1/ssh-pkcs11.c.xxx 2024-10-09 11:56:35.890126144 +0200 -+++ openssh-9.9p1/ssh-pkcs11.c 2024-10-09 11:56:48.528459585 +0200 -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #define CRYPTOKI_COMPAT - #include "pkcs11.h" -@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -65,6 +65,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -75,6 +82,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +114,61 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug_f("provider \"%s\" refcount %d valid %d", -- p->name, p->refcount, p->valid); -- if (!p->valid) -+ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug_f("%p refcount %d", m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error_f("%p still valid", m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared library, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actual freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_prov - { - debug_f("provider \"%s\" refcount %d", p->name, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error_f("provider \"%s\" still valid", p->name); - free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); - free(p); - } - } -@@ -159,6 +200,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) - { -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ if (provider_id == NULL) -+ return 0; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) -+{ - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug3_f("called with provider %s", provider_uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - static RSA_METHOD *rsa_method; -@@ -195,6 +286,60 @@ static EC_KEY_METHOD *ec_key_method; - static int ec_key_idx = 0; - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ switch (key->type) { -+ case KEY_RSA: { -+ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); -+ k11 = RSA_get_ex_data(rsa, rsa_idx); -+ break; -+ } -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: { -+ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); -+ k11 = EC_KEY_get_ex_data(ecdsa, ec_key_idx); -+ break; -+ } -+#endif -+ default: -+ error("Unknown key type %d", key->type); -+ return -1; -+ } -+ if (k11 == NULL) { -+ error("Failed to get ex_data for key type %d", key->type); -+ return (-1); -+ } -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - /* release a wrapped object */ - static void - pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +349,7 @@ pkcs11_k11_free(void *parent, void *ptr, - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); -+ free(k11->label); - free(k11); - } - -@@ -222,8 +364,8 @@ pkcs11_find(struct pkcs11_provider *p, C - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -260,14 +402,14 @@ pkcs11_login_slot(struct pkcs11_provider - if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) - verbose("Deferring PIN entry to reader keypad."); - else { -- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", -+ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", - si->token.label); -- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { -+ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug_f("no pin specified"); - return (-1); /* bail out */ - } - } -- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, -+ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, - (pin != NULL) ? strlen(pin) : 0); - if (pin != NULL) - freezero(pin, strlen(pin)); -@@ -297,13 +439,14 @@ pkcs11_login_slot(struct pkcs11_provider - static int - pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) - { -- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { -+ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || -+ k11->provider->module == NULL || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - - return pkcs11_login_slot(k11->provider, -- &k11->provider->slotinfo[k11->slotidx], type); -+ &k11->provider->module->slotinfo[k11->slotidx], type); - } - - -@@ -319,13 +462,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs - - *val = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - attr.type = type; - attr.pValue = &flag; -@@ -356,13 +500,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C - int always_auth = 0; - int did_login = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +584,8 @@ pkcs11_rsa_private_encrypt(int flen, con - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +629,7 @@ pkcs11_rsa_start_wrapper(void) - /* redirect private key operations for rsa key to pkcs11 token */ - static int - pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - -@@ -502,6 +647,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } - -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - if (RSA_set_method(rsa, rsa_method) != 1) - fatal_f("RSA_set_method failed"); - if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) -@@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, - return (NULL); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - siglen = ECDSA_size(ec); - sig = xmalloc(siglen); -@@ -598,7 +749,7 @@ pkcs11_ecdsa_start_wrapper(void) - - static int - pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) - { - struct pkcs11_key *k11; - -@@ -615,6 +766,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - if (EC_KEY_set_method(ec, ec_key_method) != 1) - fatal_f("EC_KEY_set_method failed"); - if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) -@@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider - } - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - --/* remove trailing spaces */ -+/* remove trailing spaces. Note, that this does NOT guarantee the buffer -+ * will be null terminated if there are no trailing spaces! */ - static char * - rmspace(u_char *buf, size_t len) - { -@@ -654,8 +812,8 @@ pkcs11_open_session(struct pkcs11_provid - CK_SESSION_HANDLE session; - int login_required, ret; - -- f = p->function_list; -- si = &p->slotinfo[slotidx]; -+ f = p->module->function_list; -+ si = &p->module->slotinfo[slotidx]; - - login_required = si->token.flags & CKF_LOGIN_REQUIRED; - -@@ -665,9 +823,9 @@ pkcs11_open_session(struct pkcs11_provid - error("pin required"); - return (-SSH_PKCS11_ERR_PIN_REQUIRED); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -703,7 +861,8 @@ static struct sshkey * - pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -717,14 +876,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_EC_POINT; -- key_attr[2].type = CKA_EC_PARAMS; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_EC_POINT; -+ key_attr[3].type = CKA_EC_PARAMS; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -735,19 +895,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, public point and curve parameters of EC key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -759,8 +919,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- attrp = key_attr[2].pValue; -- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); -+ attrp = key_attr[3].pValue; -+ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); - if (group == NULL) { - ossl_error("d2i_ECPKParameters failed"); - goto fail; -@@ -771,13 +931,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- if (key_attr[1].ulValueLen <= 2) { -+ if (key_attr[2].ulValueLen <= 2) { - error("CKA_EC_POINT too small"); - goto fail; - } - -- attrp = key_attr[1].pValue; -- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); -+ attrp = key_attr[2].pValue; -+ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); - if (octet == NULL) { - ossl_error("d2i_ASN1_OCTET_STRING failed"); - goto fail; -@@ -794,7 +954,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - key->flags |= SSHKEY_FLAG_EXT; - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - if (ec) - EC_KEY_free(ec); -@@ -827,7 +987,8 @@ static struct sshkey * - pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -838,14 +999,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_MODULUS; -- key_attr[2].type = CKA_PUBLIC_EXPONENT; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_MODULUS; -+ key_attr[3].type = CKA_PUBLIC_EXPONENT; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -856,19 +1018,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, modulus and public exponent of RSA key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -880,8 +1042,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - goto fail; - } - -- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); -- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); - if (rsa_n == NULL || rsa_e == NULL) { - error("BN_bin2bn failed"); - goto fail; -@@ -890,7 +1052,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - fatal_f("set key"); - rsa_n = rsa_e = NULL; /* transferred */ - -- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - key->flags |= SSHKEY_FLAG_EXT; - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - RSA_free(rsa); - -@@ -916,7 +1078,8 @@ static int - pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) - { -- CK_ATTRIBUTE cert_attr[3]; -+ CK_ATTRIBUTE cert_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -940,14 +1103,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - - memset(&cert_attr, 0, sizeof(cert_attr)); - cert_attr[0].type = CKA_ID; -- cert_attr[1].type = CKA_SUBJECT; -- cert_attr[2].type = CKA_VALUE; -+ cert_attr[1].type = CKA_LABEL; -+ cert_attr[2].type = CKA_SUBJECT; -+ cert_attr[3].type = CKA_VALUE; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return -1; -@@ -959,18 +1123,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - * XXX assumes CKA_ID is always first. - */ - if (cert_attr[1].ulValueLen == 0 || -- cert_attr[2].ulValueLen == 0) { -+ cert_attr[2].ulValueLen == 0 || -+ cert_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return -1; - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (cert_attr[i].ulValueLen > 0) - cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); - - /* retrieve ID, subject and value of certificate */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto out; -@@ -984,8 +1149,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - subject = xstrdup("invalid subject"); - X509_NAME_free(x509_name); - -- cp = cert_attr[2].pValue; -- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { -+ cp = cert_attr[3].pValue; -+ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { - error("d2i_x509 failed"); - goto out; - } -@@ -1005,7 +1170,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - -- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1035,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1055,7 +1220,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - out: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(cert_attr[i].pValue); - X509_free(x509); - RSA_free(rsa); -@@ -1106,11 +1271,12 @@ note_key(struct pkcs11_provider *p, CK_U - */ - static int - pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1127,10 +1293,23 @@ pkcs11_fetch_certs(struct pkcs11_provide - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1211,11 +1390,12 @@ fail: - */ - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[2]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1231,10 +1411,23 @@ pkcs11_fetch_keys(struct pkcs11_provider - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1503,16 +1696,10 @@ pkcs11_ecdsa_generate_private_key(struct - } - #endif /* WITH_PKCS11_KEYGEN */ - --/* -- * register a new provider, fails if provider already exists. if -- * keyp is provided, fetch keys. -- */ - static int --pkcs11_register_provider(char *provider_id, char *pin, -- struct sshkey ***keyp, char ***labelsp, -- struct pkcs11_provider **providerp, CK_ULONG user) -+pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) - { -- int nkeys, need_finalize = 0; -+ int need_finalize = 0; - int ret = -1; - struct pkcs11_provider *p = NULL; - void *handle = NULL; -@@ -1521,162 +1708,309 @@ pkcs11_register_provider(char *provider_ - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -+ char *provider_module = NULL; -+ struct pkcs11_module *m = NULL; - -- if (providerp == NULL) -- goto fail; -- *providerp = NULL; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error_f("No module path provided"); -+ goto fail; -+#endif -+ } else { -+ provider_module = strdup(uri->module_path); -+ } -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); - -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug_f("provider already registered: %s", provider_id); -+ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { -+ error("provider %s is not a PKCS11 library", provider_module); - goto fail; - } -- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { -- error("provider %s is not a PKCS11 library", provider_id); -- goto fail; -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug_f("provider module already initialized: %s", provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } -+ - /* open shared pkcs11-library */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) - fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); -- p = xcalloc(1, sizeof(*p)); -- p->name = xstrdup(provider_id); -- p->handle = handle; -+ p->module->handle = handle; - /* setup the pkcs11 callbacks */ - if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" -- " libraryDescription <%.*s> libraryVersion %d.%d", -- provider_id, -- RMSPACE(p->info.manufacturerID), -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- RMSPACE(p->info.libraryDescription), -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); -+ goto fail; -+ } -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); -+ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" -+ " libraryDescription <%.32s> libraryVersion %d.%d", -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -- debug_f("provider %s returned no slots", provider_id); -+ if (m->nslots == 0) { -+ debug_f("provider %s returned no slots", provider_module); - ret = -SSH_PKCS11_ERR_NO_SLOTS; - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->valid = 1; -+ for (i = 0; i < m->nslots; i++) { -+ token = &m->slotinfo[i].token; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (u_long)i, rv); -- continue; -- } -- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -- debug2_f("ignoring uninitialised token in " -- "provider %s slot %lu", provider_id, (u_long)i); -+ "failed: %lu", provider_module, (u_long)i, rv); -+ token->flags = 0; - continue; - } - debug("provider %s slot %lu: label <%.*s> " - "manufacturerID <%.*s> model <%.*s> serial <%.*s> " - "flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_module, (unsigned long)i, - RMSPACE(token->label), RMSPACE(token->manufacturerID), - RMSPACE(token->model), RMSPACE(token->serialNumber), - token->flags); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* now owned by caller */ -+ *providerp = p; -+ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ -+ return 0; -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ if (m) { -+ free(m->slotlist); -+ free(m); -+ } -+ if (p) { -+ free(p->name); -+ free(p); -+ } -+ if (handle) -+ dlclose(handle); -+ return (ret); -+} -+ -+/* -+ * register a new provider, fails if provider already exists. if -+ * keyp is provided, fetch keys. -+ */ -+static int -+pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, -+ CK_ULONG user) -+{ -+ int nkeys; -+ int ret = -1; -+ struct pkcs11_provider *p = NULL; -+ CK_ULONG i; -+ CK_TOKEN_INFO *token; -+ char *provider_uri = NULL; -+ -+ if (providerp == NULL) -+ goto fail; -+ *providerp = NULL; -+ -+ if (keyp != NULL) -+ *keyp = NULL; -+ -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; -+ } -+ -+ provider_uri = pkcs11_uri_get(uri); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; -+ } -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; -+ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -+ debug2_f("ignoring uninitialised token in " -+ "provider %s slot %lu", provider_uri, (u_long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strncmp(token->label, uri->token, 32) != 0) { -+ debug2_f("ignoring token not matching label (%.32s) " -+ "specified by PKCS#11 URI in slot %lu", -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%.32s) specified by PKCS#11 URI in " -+ "slot %lu", token->manufacturerID, (unsigned long)i); -+ continue; -+ } -+ if (uri->serial != NULL && -+ strncmp(token->serialNumber, uri->serial, 16) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "serialNumber (%s) specified by PKCS#11 URI in " -+ "slot %lu", token->serialNumber, (unsigned long)i); -+ continue; -+ } -+ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " -+ "model <%.16s> serial <%.16s> flags 0x%lx", -+ provider_uri, (unsigned long)i, -+ token->label, token->manufacturerID, token->model, -+ token->serialNumber, token->flags); - /* -- * open session, login with pin and retrieve public -- * keys (if keyp is provided) -+ * open session if not yet opened, login with pin and -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ if ((p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ - keyp == NULL) - continue; -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -- if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && - pkcs11_interactive) { - /* - * Some tokens require login before they will - * expose keys. - */ -- if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3_f("Trying to login as there were no keys found"); -+ if (pkcs11_login_slot(p, &p->module->slotinfo[i], - CKU_USER) < 0) { - error("login failed"); - continue; - } -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ } -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%.32s) ", -+ uri->object); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ uri->object = label; - } - } -+ pin = NULL; /* Will be cleaned up with URI */ - - /* now owned by caller */ - *providerp = p; - -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -- -+ free(provider_uri); - return (nkeys); - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); - if (ret > 0) - ret = -1; - return (ret); - } - --/* -- * register a new provider and get number of keys hold by the token, -- * fails if provider already exists -- */ -+static int -+pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) -+{ -+ struct pkcs11_uri *uri = NULL; -+ int r; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); -+ -+ return r; -+} -+ - int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, -- char ***labelsp) -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp) - { - struct pkcs11_provider *p = NULL; - int nkeys; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug_f("called, provider_uri = %s", provider_uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, -- &p, CKU_USER); -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); - - /* no keys found or some other error, de-register provider */ - if (nkeys <= 0 && p != NULL) { -@@ -1685,7 +2019,37 @@ pkcs11_add_provider(char *provider_id, c - pkcs11_provider_unref(p); - } - if (nkeys == 0) -- debug_f("provider %s returned no keys", provider_id); -+ debug_f("provider %s returned no keys", provider_uri); -+ -+ free(provider_uri); -+ return nkeys; -+} -+ -+/* -+ * register a new provider and get number of keys hold by the token, -+ * fails if provider already exists -+ */ -+int -+pkcs11_add_provider(char *provider_id, char *pin, -+ struct sshkey ***keyp, char ***labelsp) -+{ -+ struct pkcs11_uri *uri; -+ int nkeys; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); -+ pkcs11_uri_cleanup(uri); - - return (nkeys); - } -diff -up openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11.h ---- openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 -+++ openssh-9.6p1/ssh-pkcs11.h 2024-01-12 14:25:25.235942385 +0100 -@@ -22,10 +22,14 @@ - #define SSH_PKCS11_ERR_PIN_REQUIRED 4 - #define SSH_PKCS11_ERR_PIN_LOCKED 5 - -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - #ifdef WITH_PKCS11_KEYGEN - struct sshkey * - pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff -up openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.c ---- openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 -+++ openssh-9.6p1/ssh-pkcs11-uri.c 2024-01-12 14:25:25.235942385 +0100 +diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c +new file mode 100644 +index 00000000..8bd97e9e +--- /dev/null ++++ b/ssh-pkcs11-uri.c @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3081,9 +1661,11 @@ diff -up openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri. +} + +#endif /* ENABLE_PKCS11 */ -diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.h ---- openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 -+++ openssh-9.6p1/ssh-pkcs11-uri.h 2024-01-12 14:25:25.235942385 +0100 +diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h +new file mode 100644 +index 00000000..29e9f732 +--- /dev/null ++++ b/ssh-pkcs11-uri.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3128,3 +1710,1473 @@ diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri. +struct pkcs11_uri *pkcs11_uri_init(); +char *pkcs11_uri_get(struct pkcs11_uri *uri); + +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index 31b9360f..b96f5b89 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #define CRYPTOKI_COMPAT + #include "pkcs11.h" +@@ -55,8 +56,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -65,6 +66,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -75,6 +83,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +115,61 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug_f("provider \"%s\" refcount %d valid %d", +- p->name, p->refcount, p->valid); +- if (!p->valid) ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug_f("%p refcount %d", m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error_f("%p still valid", m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared library, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actual freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -137,11 +181,9 @@ pkcs11_provider_unref(struct pkcs11_provider *p) + { + debug_f("provider \"%s\" refcount %d", p->name, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error_f("provider \"%s\" still valid", p->name); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +201,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +229,55 @@ pkcs11_provider_lookup(char *provider_id) + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) ++{ ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ if (provider_id == NULL) ++ return 0; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) + { + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3_f("called with provider %s", provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +287,60 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: { ++ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); ++ k11 = RSA_get_ex_data(rsa, rsa_idx); ++ break; ++ } ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: { ++ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); ++ k11 = EC_KEY_get_ex_data(ecdsa, ec_key_idx); ++ break; ++ } ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); ++ } ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +354,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +369,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -260,14 +407,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + verbose("Deferring PIN entry to reader keypad."); + else { +- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", ++ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug_f("no pin specified"); + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -297,13 +444,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -319,13 +467,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + attr.type = type; + attr.pValue = &flag; +@@ -356,13 +505,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) + int always_auth = 0; + int did_login = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (pkcs11_login(k11, CKU_USER) < 0) { +@@ -439,8 +589,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + tlen = RSA_size(rsa); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ +@@ -484,7 +634,7 @@ pkcs11_rsa_start_wrapper(void) + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + +@@ -502,6 +652,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + if (RSA_set_method(rsa, rsa_method) != 1) + fatal_f("RSA_set_method failed"); + if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) +@@ -534,8 +690,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, + return (NULL); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + siglen = ECDSA_size(ec); + sig = xmalloc(siglen); +@@ -600,7 +756,7 @@ pkcs11_ecdsa_start_wrapper(void) + + static int + pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) + { + struct pkcs11_key *k11; + +@@ -617,6 +773,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + if (EC_KEY_set_method(ec, ec_key_method) != 1) + fatal_f("EC_KEY_set_method failed"); + if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) +@@ -626,7 +788,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + } + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + +-/* remove trailing spaces */ ++/* remove trailing spaces. Note, that this does NOT guarantee the buffer ++ * will be null terminated if there are no trailing spaces! */ + static char * + rmspace(u_char *buf, size_t len) + { +@@ -658,8 +821,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, + CK_SESSION_HANDLE session; + int login_required, ret; + +- f = p->function_list; +- si = &p->slotinfo[slotidx]; ++ f = p->module->function_list; ++ si = &p->module->slotinfo[slotidx]; + + login_required = si->token.flags & CKF_LOGIN_REQUIRED; + +@@ -669,9 +832,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, + error("pin required"); + return (-SSH_PKCS11_ERR_PIN_REQUIRED); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -707,7 +870,8 @@ static struct sshkey * + pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -721,14 +885,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; ++ key_attr[3].type = CKA_EC_PARAMS; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -739,19 +904,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, public point and curve parameters of EC key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -763,8 +928,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- attrp = key_attr[2].pValue; +- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); ++ attrp = key_attr[3].pValue; ++ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); + if (group == NULL) { + ossl_error("d2i_ECPKParameters failed"); + goto fail; +@@ -775,13 +940,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (key_attr[1].ulValueLen <= 2) { ++ if (key_attr[2].ulValueLen <= 2) { + error("CKA_EC_POINT too small"); + goto fail; + } + +- attrp = key_attr[1].pValue; +- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); ++ attrp = key_attr[2].pValue; ++ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); + if (octet == NULL) { + ossl_error("d2i_ASN1_OCTET_STRING failed"); + goto fail; +@@ -798,7 +963,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -817,7 +982,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + key->flags |= SSHKEY_FLAG_EXT; + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -834,7 +999,8 @@ static struct sshkey * + pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -845,14 +1011,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_MODULUS; +- key_attr[2].type = CKA_PUBLIC_EXPONENT; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_MODULUS; ++ key_attr[3].type = CKA_PUBLIC_EXPONENT; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -863,19 +1030,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, modulus and public exponent of RSA key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -887,8 +1054,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) { + error("BN_bin2bn failed"); + goto fail; +@@ -897,7 +1064,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + fatal_f("set key"); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -915,7 +1082,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + key->flags |= SSHKEY_FLAG_EXT; + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -926,7 +1093,8 @@ static int + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) + { +- CK_ATTRIBUTE cert_attr[3]; ++ CK_ATTRIBUTE cert_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -950,14 +1118,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&cert_attr, 0, sizeof(cert_attr)); + cert_attr[0].type = CKA_ID; +- cert_attr[1].type = CKA_SUBJECT; +- cert_attr[2].type = CKA_VALUE; ++ cert_attr[1].type = CKA_LABEL; ++ cert_attr[2].type = CKA_SUBJECT; ++ cert_attr[3].type = CKA_VALUE; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return -1; +@@ -969,18 +1138,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * XXX assumes CKA_ID is always first. + */ + if (cert_attr[1].ulValueLen == 0 || +- cert_attr[2].ulValueLen == 0) { ++ cert_attr[2].ulValueLen == 0 || ++ cert_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return -1; + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (cert_attr[i].ulValueLen > 0) + cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + + /* retrieve ID, subject and value of certificate */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto out; +@@ -994,8 +1164,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + subject = xstrdup("invalid subject"); + X509_NAME_free(x509_name); + +- cp = cert_attr[2].pValue; +- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { ++ cp = cert_attr[3].pValue; ++ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { + error("d2i_x509 failed"); + goto out; + } +@@ -1015,7 +1185,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1048,7 +1218,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1071,7 +1241,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + out: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1122,11 +1292,12 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1143,10 +1314,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1227,11 +1411,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[2]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1247,10 +1432,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1532,16 +1730,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, + } + #endif /* WITH_PKCS11_KEYGEN */ + +-/* +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. +- */ + static int +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) + { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; + struct pkcs11_provider *p = NULL; + void *handle = NULL; +@@ -1550,162 +1742,309 @@ pkcs11_register_provider(char *provider_id, char *pin, + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_module *m = NULL; ++ ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error_f("No module path provided"); ++ goto fail; ++#endif ++ } else { ++ provider_module = strdup(uri->module_path); ++ } ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); + +- if (providerp == NULL) +- goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; +- +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug_f("provider already registered: %s", provider_id); ++ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { ++ error("provider %s is not a PKCS11 library", provider_module); + goto fail; + } +- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { +- error("provider %s is not a PKCS11 library", provider_id); +- goto fail; ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug_f("provider module already initialized: %s", provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-library */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) + fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ p->module->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); ++ goto fail; ++ } ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); + goto fail; + } +- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" +- " libraryDescription <%.*s> libraryVersion %d.%d", +- provider_id, +- RMSPACE(p->info.manufacturerID), +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- RMSPACE(p->info.libraryDescription), +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); ++ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" ++ " libraryDescription <%.32s> libraryVersion %d.%d", ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { +- debug_f("provider %s returned no slots", provider_id); ++ if (m->nslots == 0) { ++ debug_f("provider %s returned no slots", provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ m->valid = 1; ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (u_long)i, rv); +- continue; +- } +- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "failed: %lu", provider_module, (u_long)i, rv); ++ token->flags = 0; + continue; + } + debug("provider %s slot %lu: label <%.*s> " + "manufacturerID <%.*s> model <%.*s> serial <%.*s> " + "flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_module, (unsigned long)i, + RMSPACE(token->label), RMSPACE(token->manufacturerID), + RMSPACE(token->model), RMSPACE(token->serialNumber), + token->flags); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* now owned by caller */ ++ *providerp = p; ++ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ ++ return 0; ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); ++ } ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return (ret); ++} ++ ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) ++{ ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; ++ ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; ++ ++ if (keyp != NULL) ++ *keyp = NULL; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " ++ "provider %s slot %lu", provider_uri, (u_long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strncmp(token->label, uri->token, 32) != 0) { ++ debug2_f("ignoring token not matching label (%.32s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%.32s) specified by PKCS#11 URI in " ++ "slot %lu", token->manufacturerID, (unsigned long)i); ++ continue; ++ } ++ if (uri->serial != NULL && ++ strncmp(token->serialNumber, uri->serial, 16) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "serialNumber (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->serialNumber, (unsigned long)i); ++ continue; ++ } ++ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " ++ "model <%.16s> serial <%.16s> flags 0x%lx", ++ provider_uri, (unsigned long)i, ++ token->label, token->manufacturerID, token->model, ++ token->serialNumber, token->flags); + /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) ++ * open session if not yet opened, login with pin and ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3_f("Trying to login as there were no keys found"); ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3_f("No keys found. Retrying without label (%.32s) ", ++ uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ uri->object = label; + } + } ++ pin = NULL; /* Will be cleaned up with URI */ + + /* now owned by caller */ + *providerp = p; + +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- ++ free(provider_uri); + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ struct pkcs11_uri *uri = NULL; ++ int r; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); ++ pkcs11_uri_cleanup(uri); ++ ++ return r; ++} ++ + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp) + { + struct pkcs11_provider *p = NULL; + int nkeys; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug_f("called, provider_uri = %s", provider_uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1714,7 +2053,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, + pkcs11_provider_unref(p); + } + if (nkeys == 0) +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); ++ ++ free(provider_uri); ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ ++int ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) ++{ ++ struct pkcs11_uri *uri; ++ int nkeys; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +index 52602231..9ce20c1f 100644 +--- a/ssh-pkcs11.h ++++ b/ssh-pkcs11.h +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff --git a/ssh.c b/ssh.c +index c23d3b9e..98b103c9 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -890,6 +890,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1847,6 +1855,7 @@ main(int ac, char **av) + #ifdef ENABLE_PKCS11 + (void)pkcs11_del_provider(options.pkcs11_provider); + #endif ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, cinfo); +@@ -2370,6 +2379,45 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2384,11 +2432,6 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys = NULL; +- char **comments = NULL; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2401,33 +2444,46 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys, &comments)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- free(comments[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = comments[i]; /* transferred */ +- n_ids++; +- } +- free(keys); +- free(comments); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +diff --git a/ssh_config.5 b/ssh_config.5 +index 3a8e246c..8d5d0722 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -1263,6 +1263,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +-- +2.49.0 + diff --git a/openssh-7.8p1-scp-ipv6.patch b/0029-openssh-7.8p1-scp-ipv6.patch similarity index 51% rename from openssh-7.8p1-scp-ipv6.patch rename to 0029-openssh-7.8p1-scp-ipv6.patch index 8ae0948..dbd69aa 100644 --- a/openssh-7.8p1-scp-ipv6.patch +++ b/0029-openssh-7.8p1-scp-ipv6.patch @@ -1,8 +1,17 @@ +From 507e6f245557ae7261806f7ecbd40697cb0dd389 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 60682c68..9344806e 100644 +index 9554b188..7f9795a5 100644 --- a/scp.c +++ b/scp.c -@@ -714,7 +714,9 @@ toremote(int argc, char **argv) +@@ -1183,7 +1183,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) addargs(&alist, "%s", host); addargs(&alist, "%s", cmd); addargs(&alist, "%s", src); @@ -13,4 +22,6 @@ index 60682c68..9344806e 100644 tuser ? tuser : "", tuser ? "@" : "", thost, targ); if (do_local_cmd(&alist) != 0) +-- +2.49.0 diff --git a/openssh-8.0p1-crypto-policies.patch b/0030-openssh-8.0p1-crypto-policies.patch similarity index 90% rename from openssh-8.0p1-crypto-policies.patch rename to 0030-openssh-8.0p1-crypto-policies.patch index a666c5c..498e3f5 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/0030-openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,18 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh_config.5 openssh-9.3p1-patched/ssh_config.5 ---- openssh-9.3p1/ssh_config.5 2023-06-07 10:26:48.284590156 +0200 -+++ openssh-9.3p1-patched/ssh_config.5 2023-06-07 10:26:00.623052194 +0200 -@@ -378,17 +378,13 @@ +From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ -24,7 +35,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -450,20 +446,25 @@ +@@ -587,20 +583,25 @@ If the option is set to (the default), the check will not be executed. .It Cm Ciphers @@ -54,21 +65,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -479,13 +480,6 @@ +@@ -616,13 +617,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .Ed .Pp -The default is: -.Bd -literal -offset indent -chacha20-poly1305@openssh.com, --aes128-ctr,aes192-ctr,aes256-ctr, --aes128-gcm@openssh.com,aes256-gcm@openssh.com +-aes128-gcm@openssh.com,aes256-gcm@openssh.com, +-aes128-ctr,aes192-ctr,aes256-ctr -.Ed -.Pp The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -885,6 +879,11 @@ +@@ -1022,6 +1016,11 @@ command line will be passed untouched to the GSSAPI library. The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -80,7 +91,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -897,10 +896,8 @@ +@@ -1034,10 +1033,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp @@ -92,7 +103,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -919,36 +916,25 @@ +@@ -1056,36 +1053,25 @@ will not be converted automatically, but may be manually hashed using .Xr ssh-keygen 1 . .It Cm HostbasedAcceptedAlgorithms @@ -137,7 +148,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The .Fl Q -@@ -1001,6 +987,17 @@ +@@ -1138,6 +1124,17 @@ to prefer their algorithms. .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . @@ -155,7 +166,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key -@@ -1330,6 +1330,11 @@ it may be zero or more of: +@@ -1376,6 +1373,11 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -167,7 +178,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x 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 -@@ -1338,29 +1343,17 @@ Multiple algorithms must be comma-separa +@@ -1384,29 +1386,17 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -187,8 +198,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x -.Pp -The default is: -.Bd -literal -offset indent --sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, -mlkem768x25519-sha256, +-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -201,7 +212,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q kex . .It Cm KnownHostsCommand -@@ -1365,37 +1357,33 @@ +@@ -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 @@ -248,7 +259,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1567,39 +1555,31 @@ +@@ -1741,39 +1727,31 @@ instead of continuing to execute and pass data. The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -300,7 +311,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be -@@ -2265,7 +2245,9 @@ +@@ -2497,7 +2475,9 @@ for those users who do not have a configuration file. This file must be world-readable. .El .Sh SEE ALSO @@ -311,10 +322,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshd_config.5 openssh-9.3p1-patched/sshd_config.5 ---- openssh-9.3p1/sshd_config.5 2023-06-07 10:26:48.277590077 +0200 -+++ openssh-9.3p1-patched/sshd_config.5 2023-06-07 10:26:00.592051845 +0200 -@@ -379,17 +379,13 @@ +diff --git a/sshd_config.5 b/sshd_config.5 +index 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 @@ -337,7 +349,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -525,20 +521,25 @@ +@@ -533,20 +529,25 @@ The default is indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -367,21 +379,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The supported ciphers are: .Pp -@@ -565,13 +566,6 @@ +@@ -573,13 +574,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent -chacha20-poly1305@openssh.com, --aes128-ctr,aes192-ctr,aes256-ctr, --aes128-gcm@openssh.com,aes256-gcm@openssh.com +-aes128-gcm@openssh.com,aes256-gcm@openssh.com, +-aes128-ctr,aes192-ctr,aes256-ctr -.Ed -.Pp The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -766,53 +760,43 @@ +@@ -774,53 +768,43 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -454,7 +466,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostbasedAcceptedAlgorithms . -@@ -879,25 +863,14 @@ +@@ -887,25 +871,14 @@ is specified, the location of the socket will be read from the .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -485,7 +497,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -1025,6 +1025,11 @@ Specifies whether to look at .k5login fi +@@ -1052,6 +1025,11 @@ Specifies whether to look at .k5login file for user's aliases. The default is .Cm yes . .It Cm KexAlgorithms @@ -497,7 +509,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x 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 +@@ -1060,16 +1038,16 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -518,25 +530,22 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The supported algorithms are: .Pp -@@ -1075,17 +1080,6 @@ ecdh-sha2-nistp521 +@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512 sntrup761x25519-sha512@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent --sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, -mlkem768x25519-sha256, +-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, --ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, --diffie-hellman-group-exchange-sha256, --diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, --diffie-hellman-group14-sha256 +-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 -.Ed -.Pp The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1184,21 +1152,26 @@ +@@ -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 @@ -567,7 +576,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The algorithms that contain .Qq -etm -@@ -1241,15 +1214,6 @@ +@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -583,7 +592,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1633,36 +1597,25 @@ +@@ -1753,36 +1719,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -629,7 +638,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2131,7 +2084,9 @@ +@@ -2289,7 +2244,9 @@ This file should be writable by root only, but it is recommended .El .Sh SEE ALSO .Xr sftp-server 8 , @@ -640,3 +649,6 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free +-- +2.49.0 + diff --git a/openssh-8.0p1-openssl-kdf.patch b/0031-openssh-8.0p1-openssl-kdf.patch similarity index 84% rename from openssh-8.0p1-openssl-kdf.patch rename to 0031-openssh-8.0p1-openssl-kdf.patch index c22b210..529940f 100644 --- a/openssh-8.0p1-openssl-kdf.patch +++ b/0031-openssh-8.0p1-openssl-kdf.patch @@ -1,14 +1,18 @@ -commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a -Author: Jakub Jelen -Date: Tue Apr 16 15:35:18 2019 +0200 +From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 31/50] openssh-8.0p1-openssl-kdf - Use the new OpenSSL KDF +--- + configure.ac | 1 + + kex.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 108 insertions(+) diff --git a/configure.ac b/configure.ac -index 2a455e4e..e01c3d43 100644 +index d9bd2f51..d92a8580 100644 --- a/configure.ac +++ b/configure.ac -@@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then +@@ -3137,6 +3137,7 @@ if test "x$openssl" = "xyes" ; then HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ @@ -17,10 +21,10 @@ index 2a455e4e..e01c3d43 100644 # OpenSSL_add_all_algorithms may be a macro. diff --git a/kex.c b/kex.c -index b6f041f4..1fbce2bb 100644 +index 19a56e8e..8b200ff4 100644 --- a/kex.c +++ b/kex.c -@@ -38,6 +38,11 @@ +@@ -40,6 +40,11 @@ #ifdef WITH_OPENSSL #include #include @@ -32,7 +36,7 @@ index b6f041f4..1fbce2bb 100644 #endif #include "ssh.h" -@@ -942,6 +945,107 @@ kex_choose_conf(struct ssh *ssh) +@@ -1078,6 +1083,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) return r; } @@ -140,7 +144,7 @@ index b6f041f4..1fbce2bb 100644 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, +@@ -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; } @@ -148,4 +152,6 @@ index b6f041f4..1fbce2bb 100644 #define NKEYS 6 int +-- +2.49.0 diff --git a/openssh-8.2p1-visibility.patch b/0032-openssh-8.2p1-visibility.patch similarity index 62% rename from openssh-8.2p1-visibility.patch rename to 0032-openssh-8.2p1-visibility.patch index 89c35ef..c67373c 100644 --- a/openssh-8.2p1-visibility.patch +++ b/0032-openssh-8.2p1-visibility.patch @@ -1,8 +1,17 @@ +From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 dca158de..afdcb1d2 100644 +index 347b2122..344f8a8a 100644 --- a/regress/misc/sk-dummy/sk-dummy.c +++ b/regress/misc/sk-dummy/sk-dummy.c -@@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...) +@@ -81,7 +81,7 @@ skdebug(const char *func, const char *fmt, ...) #endif } @@ -11,7 +20,7 @@ index dca158de..afdcb1d2 100644 sk_api_version(void) { return SSH_SK_VERSION_MAJOR; -@@ -220,7 +220,7 @@ check_options(struct sk_option **options) +@@ -230,7 +230,7 @@ check_options(struct sk_option **options) return 0; } @@ -20,7 +29,7 @@ index dca158de..afdcb1d2 100644 sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, const char *application, uint8_t flags, const char *pin, struct sk_option **options, struct sk_enroll_response **enroll_response) -@@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, +@@ -478,7 +478,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, return ret; } @@ -29,7 +38,7 @@ index dca158de..afdcb1d2 100644 sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, const char *pin, struct sk_option **options, -@@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, +@@ -535,7 +535,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, return ret; } @@ -38,3 +47,6 @@ index dca158de..afdcb1d2 100644 sk_load_resident_keys(const char *pin, struct sk_option **options, struct sk_resident_key ***rks, size_t *nrks) { +-- +2.49.0 + diff --git a/openssh-8.2p1-x11-without-ipv6.patch b/0033-openssh-8.2p1-x11-without-ipv6.patch similarity index 55% rename from openssh-8.2p1-x11-without-ipv6.patch rename to 0033-openssh-8.2p1-x11-without-ipv6.patch index 8b83bc3..32a9056 100644 --- a/openssh-8.2p1-x11-without-ipv6.patch +++ b/0033-openssh-8.2p1-x11-without-ipv6.patch @@ -1,12 +1,17 @@ +From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 -@@ -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) { +@@ -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); @@ -23,8 +28,6 @@ diff --git a/channels.c b/channels.c for (n = 0; n < num_socks; n++) close(socks[n]); num_socks = 0; - break; - } - socks[num_socks++] = sock; - if (num_socks == NUM_SOCKS) - break; +-- +2.49.0 + diff --git a/openssh-8.0p1-preserve-pam-errors.patch b/0034-openssh-8.0p1-preserve-pam-errors.patch similarity index 67% rename from openssh-8.0p1-preserve-pam-errors.patch rename to 0034-openssh-8.0p1-preserve-pam-errors.patch index b7ab965..15e59c2 100644 --- a/openssh-8.0p1-preserve-pam-errors.patch +++ b/0034-openssh-8.0p1-preserve-pam-errors.patch @@ -1,7 +1,17 @@ -diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c ---- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200 -+++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200 -@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp) +From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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()) { @@ -14,7 +24,7 @@ diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c goto auth_fail; } if (sshpam_authctxt->force_pwchange) { -@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp) +@@ -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 */ @@ -27,17 +37,20 @@ diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c else if (sshpam_maxtries_reached) ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); else -@@ -856,9 +862,11 @@ sshpam_query(void *ctx, char **name, cha +@@ -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: -+ case PAM_USER_UNKNOWN: -+ case PAM_PERM_DENIED: - 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 + diff --git a/openssh-8.7p1-scp-kill-switch.patch b/0035-openssh-8.7p1-scp-kill-switch.patch similarity index 57% rename from openssh-8.7p1-scp-kill-switch.patch rename to 0035-openssh-8.7p1-scp-kill-switch.patch index 161ab2d..58a5036 100644 --- a/openssh-8.7p1-scp-kill-switch.patch +++ b/0035-openssh-8.7p1-scp-kill-switch.patch @@ -1,6 +1,18 @@ -diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h ---- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200 -+++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200 +From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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" @@ -9,10 +21,11 @@ diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h #ifndef _PATH_SSH_PROGRAM #define _PATH_SSH_PROGRAM "/usr/bin/ssh" -diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 ---- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200 -+++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200 -@@ -278,6 +278,13 @@ to print debugging messages about their +diff --git a/scp.1 b/scp.1 +index 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 @@ -26,10 +39,11 @@ diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 .Sh EXIT STATUS .Ex -std scp .Sh SEE ALSO -diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200 -+++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200 -@@ -596,6 +596,14 @@ main(int argc, char **argv) +diff --git a/scp.c b/scp.c +index 7f9795a5..7ed1a54c 100644 +--- a/scp.c ++++ b/scp.c +@@ -649,6 +649,14 @@ main(int argc, char **argv) if (iamremote) mode = MODE_SCP; @@ -44,3 +58,6 @@ diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c if ((pwd = getpwuid(userid = getuid())) == NULL) fatal("unknown user %u", (u_int) userid); +-- +2.49.0 + diff --git a/openssh-8.7p1-recursive-scp.patch b/0036-openssh-8.7p1-recursive-scp.patch similarity index 73% rename from openssh-8.7p1-recursive-scp.patch rename to 0036-openssh-8.7p1-recursive-scp.patch index 17c340e..929b408 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/0036-openssh-8.7p1-recursive-scp.patch @@ -1,8 +1,21 @@ -diff --git a/scp.c b/scp.c ---- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/scp.c (date 1703111453316) -@@ -1372,7 +1372,7 @@ +From 99e1e3af524376788e591ca73387f1ca37e6f5ef Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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) { @@ -11,10 +24,11 @@ diff --git a/scp.c b/scp.c errs = 1; } diff --git a/sftp-client.c b/sftp-client.c ---- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/sftp-client.c (date 1703169614263) -@@ -1003,7 +1003,7 @@ - +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) @@ -22,7 +36,7 @@ diff --git a/sftp-client.c b/sftp-client.c { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1049,11 +1049,43 @@ +@@ -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"); @@ -71,9 +85,9 @@ diff --git a/sftp-client.c b/sftp-client.c } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1078,9 +1110,9 @@ +@@ -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) @@ -81,9 +95,9 @@ diff --git a/sftp-client.c b/sftp-client.c - return sftp_realpath_expand(conn, path, 0); + return sftp_realpath_expand(conn, path, 0, create_dir); } - + int -@@ -1094,9 +1126,9 @@ +@@ -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"); @@ -93,18 +107,18 @@ diff --git a/sftp-client.c b/sftp-client.c - return sftp_realpath_expand(conn, path, 1); + return sftp_realpath_expand(conn, path, 1, 0); } - + int -@@ -2016,7 +2048,7 @@ +@@ -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; } -@@ -2365,12 +2397,12 @@ +@@ -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, @@ -113,47 +127,48 @@ diff --git a/sftp-client.c b/sftp-client.c { 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; } -@@ -2825,7 +2857,7 @@ +@@ -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 ---- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/sftp-client.h (date 1703111691284) -@@ -111,7 +111,7 @@ +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 @@ +@@ -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 ---- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/sftp.c (date 1703168795365) -@@ -807,7 +807,7 @@ +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, @@ -162,7 +177,7 @@ diff --git a/sftp.c b/sftp.c err = -1; } else { if (sftp_upload(conn, g.gl_pathv[i], abs_dst, -@@ -1642,7 +1642,7 @@ +@@ -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); @@ -171,12 +186,15 @@ diff --git a/sftp.c b/sftp.c err = 1; break; } -@@ -2247,7 +2247,7 @@ +@@ -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 diff --git a/openssh-8.7p1-minrsabits.patch b/0037-openssh-8.7p1-minrsabits.patch similarity index 63% rename from openssh-8.7p1-minrsabits.patch rename to 0037-openssh-8.7p1-minrsabits.patch index d8577d2..59e530b 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/0037-openssh-8.7p1-minrsabits.patch @@ -1,7 +1,18 @@ +From 286bc4a302b5130f732c857095ae665f7bea01dd Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 ---- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/readconf.c (date 1703169891147) -@@ -326,6 +326,7 @@ +index 6c04ed43..f340bf50 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -343,6 +343,7 @@ static struct { { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, { "requiredrsasize", oRequiredRSASize }, @@ -10,9 +21,10 @@ diff --git a/readconf.c b/readconf.c { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c ---- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/servconf.c (date 1703169891148) -@@ -691,6 +691,7 @@ +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 }, @@ -20,3 +32,6 @@ diff --git a/servconf.c b/servconf.c { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, +-- +2.49.0 + diff --git a/0038-openssh-8.7p1-ibmca.patch b/0038-openssh-8.7p1-ibmca.patch new file mode 100644 index 0000000..74dd5b5 --- /dev/null +++ b/0038-openssh-8.7p1-ibmca.patch @@ -0,0 +1,25 @@ +From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + #include +-- +2.49.0 + diff --git a/openssh-7.6p1-audit.patch b/0039-openssh-7.6p1-audit.patch similarity index 83% rename from openssh-7.6p1-audit.patch rename to 0039-openssh-7.6p1-audit.patch index 2c7ddc5..e4f89c7 100644 --- a/openssh-7.6p1-audit.patch +++ b/0039-openssh-7.6p1-audit.patch @@ -1,7 +1,57 @@ -diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c ---- openssh-8.6p1/audit-bsm.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit-bsm.c 2021-04-19 16:47:35.753062106 +0200 -@@ -373,13 +373,26 @@ audit_connection_from(const char *host, +From b0505837bfa2dcdf07800634fa80c5cdb78799dc Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:29 +0200 +Subject: [PATCH 39/50] openssh-7.6p1-audit + +--- + Makefile.in | 2 +- + audit-bsm.c | 45 ++++++- + audit-linux.c | 302 +++++++++++++++++++++++++++++++++++++++++++--- + audit.c | 129 ++++++++++++++++++-- + audit.h | 22 +++- + auditstub.c | 52 ++++++++ + auth.c | 3 - + auth.h | 4 + + auth2-hostbased.c | 16 ++- + auth2-pubkey.c | 16 ++- + auth2.c | 3 - + cipher.c | 21 +--- + cipher.h | 20 ++- + kex.c | 61 ++++++++-- + kex.h | 2 + + mac.c | 14 +++ + mac.h | 1 + + monitor.c | 194 +++++++++++++++++++++++++++-- + monitor.h | 8 +- + monitor_wrap.c | 130 +++++++++++++++++++- + monitor_wrap.h | 11 +- + packet.c | 98 +++++++++++++-- + packet.h | 1 + + session.c | 83 ++++++++++++- + session.h | 10 +- + sshd-session.c | 104 ++++++++++++++-- + sshd.c | 10 ++ + 27 files changed, 1258 insertions(+), 104 deletions(-) + create mode 100644 auditstub.c + +diff --git a/Makefile.in b/Makefile.in +index 6c417ef7..a2942392 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -119,7 +119,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ +- sshbuf-io.o ++ sshbuf-io.o auditstub.o + + SKOBJS= ssh-sk-client.o + +diff --git a/audit-bsm.c b/audit-bsm.c +index ccfcf6f7..a49abb92 100644 +--- a/audit-bsm.c ++++ b/audit-bsm.c +@@ -373,12 +373,25 @@ audit_connection_from(const char *host, int port) #endif } @@ -19,17 +69,16 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c /* not implemented */ } - void ++void +audit_count_session_open(void) +{ + /* not necessary */ +} + -+void + void audit_session_open(struct logininfo *li) { - /* not implemented */ -@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li) /* not implemented */ } @@ -42,7 +91,7 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) debug("%s: unhandled event %d", __func__, event); } } @@ -71,234 +120,10 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c ---- openssh-8.6p1/audit.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit.c 2021-04-19 16:47:35.753062106 +0200 -@@ -34,6 +34,12 @@ - #include "log.h" - #include "hostfile.h" - #include "auth.h" -+#include "ssh-gss.h" -+#include "monitor_wrap.h" -+#include "xmalloc.h" -+#include "misc.h" -+#include "servconf.h" -+#include "ssherr.h" - - /* - * Care must be taken when using this since it WILL NOT be initialized when -@@ -41,6 +47,7 @@ - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. - */ - extern Authctxt *the_authctxt; -+extern ServerOptions options; - - /* Maybe add the audit class to struct Authmethod? */ - ssh_audit_event_t -@@ -69,13 +76,10 @@ audit_classify_auth(const char *method) - const char * - audit_username(void) - { -- static const char unknownuser[] = "(unknown user)"; -- static const char invaliduser[] = "(invalid user)"; -+ static const char unknownuser[] = "(unknown)"; - -- if (the_authctxt == NULL || the_authctxt->user == NULL) -+ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) - return (unknownuser); -- if (!the_authctxt->valid) -- return (invaliduser); - return (the_authctxt->user); - } - -@@ -109,6 +113,35 @@ audit_event_lookup(ssh_audit_event_t ev) - return(event_lookup[i].name); - } - -+void -+audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) -+{ -+ char *fp; -+ -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) -+ *rv = -SSH_ERR_INTERNAL_ERROR; -+ free(fp); -+} -+ -+void -+audit_unsupported(struct ssh *ssh, int what) -+{ -+ mm_audit_unsupported_body(ssh, what); -+} -+ -+void -+audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) -+{ -+ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()); -+} -+ -+void -+audit_session_key_free(struct ssh *ssh, int ctos) -+{ -+ mm_audit_session_key_free_body(ssh, ctos, getpid(), getuid()); -+} -+ - # ifndef CUSTOM_SSH_AUDIT_EVENTS - /* - * Null implementations of audit functions. -@@ -138,6 +171,17 @@ audit_event(struct ssh *ssh, ssh_audit_e - } - - /* -+ * Called when a child process has called, or will soon call, -+ * audit_session_open. -+ */ -+void -+audit_count_session_open(void) -+{ -+ debug("audit count session open euid %d user %s", geteuid(), -+ audit_username()); -+} -+ -+/* - * Called when a user session is started. Argument is the tty allocated to - * the session, or NULL if no tty was allocated. - * -@@ -172,13 +216,82 @@ audit_session_close(struct logininfo *li - /* - * This will be called when a user runs a non-interactive command. Note that - * it may be called multiple times for a single connection since SSH2 allows -- * multiple sessions within a single connection. -+ * multiple sessions within a single connection. Returns a "handle" for -+ * audit_end_command. - */ --void --audit_run_command(const char *command) -+int -+audit_run_command(struct ssh *ssh, const char *command) - { - debug("audit run command euid %d user %s command '%.200s'", geteuid(), - audit_username(), command); -+ return 0; -+} -+ -+/* -+ * This will be called when the non-interactive command finishes. Note that -+ * it may be called multiple times for a single connection since SSH2 allows -+ * multiple sessions within a single connection. "handle" should come from -+ * the corresponding audit_run_command. -+ */ -+void -+audit_end_command(struct ssh *ssh, int handle, const char *command) -+{ -+ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), -+ audit_username(), command); -+} -+ -+/* -+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. -+ * -+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. -+ */ -+int -+audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) -+{ -+ debug("audit %s key usage euid %d user %s fingerprint %s, result %d", -+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), -+ fp, rv); -+} -+ -+/* -+ * This will be called when the protocol negotiation fails. -+ */ -+void -+audit_unsupported_body(struct ssh *ssh, int what) -+{ -+ debug("audit unsupported protocol euid %d type %d", geteuid(), what); -+} -+ -+/* -+ * This will be called on succesfull protocol negotiation. -+ */ -+void -+audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, -+ uid_t uid) -+{ -+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, -+ (unsigned)uid); -+} -+ -+/* -+ * This will be called on succesfull session key discard -+ */ -+void -+audit_session_key_free_body(struct ssh *, int ctos, pid_t pid, uid_t uid) -+{ -+ debug("audit session key discard euid %u direction %d from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); -+} -+ -+/* -+ * This will be called on destroy private part of the server key -+ */ -+void -+audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) -+{ -+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", -+ geteuid(), fp, (long)pid, (unsigned)uid); - } - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/audit.h.audit openssh-8.6p1/audit.h ---- openssh-8.6p1/audit.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit.h 2021-04-19 16:47:35.753062106 +0200 -@@ -26,6 +26,7 @@ - # define _SSH_AUDIT_H - - #include "loginrec.h" -+#include "sshkey.h" - - struct ssh; - -@@ -45,13 +46,32 @@ enum ssh_audit_event_type { - SSH_CONNECTION_ABANDON, /* closed without completing auth */ - SSH_AUDIT_UNKNOWN - }; -+ -+enum ssh_audit_kex { -+ SSH_AUDIT_UNSUPPORTED_CIPHER, -+ SSH_AUDIT_UNSUPPORTED_MAC, -+ SSH_AUDIT_UNSUPPORTED_COMPRESSION -+}; - typedef enum ssh_audit_event_type ssh_audit_event_t; - -+int listening_for_clients(void); -+ - void audit_connection_from(const char *, int); - void audit_event(struct ssh *, ssh_audit_event_t); -+void audit_count_session_open(void); - void audit_session_open(struct logininfo *); - void audit_session_close(struct logininfo *); --void audit_run_command(const char *); -+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); -+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 *); -+void audit_unsupported_body(struct ssh *, int); -+void audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); -+void audit_session_key_free(struct ssh *, int ctos); -+void audit_session_key_free_body(struct ssh *, int ctos, pid_t, uid_t); -+void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); - - #endif /* _SSH_AUDIT_H */ -diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c ---- openssh-8.6p1/audit-linux.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit-linux.c 2021-04-19 16:47:35.753062106 +0200 +diff --git a/audit-linux.c b/audit-linux.c +index 3fcbe5c5..d484b82b 100644 +--- a/audit-linux.c ++++ b/audit-linux.c @@ -33,27 +33,40 @@ #include "log.h" @@ -310,11 +135,10 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c +#include "servconf.h" #include "canohost.h" #include "packet.h" -- +#include "cipher.h" +#include "channels.h" +#include "session.h" -+ + +#define AUDIT_LOG_SIZE 256 + +extern ServerOptions options; @@ -348,7 +172,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c saved_errno = errno; close(audit_fd); -@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const +@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, rc = 0; errno = saved_errno; @@ -446,7 +270,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,211 @@ audit_connection_from(const char *host, +@@ -76,49 +176,211 @@ audit_connection_from(const char *host, int port) /* not implemented */ } @@ -670,9 +494,238 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c ---- openssh-8.6p1/auditstub.c.audit 2021-04-19 16:47:35.754062114 +0200 -+++ openssh-8.6p1/auditstub.c 2021-04-19 16:47:35.754062114 +0200 +diff --git a/audit.c b/audit.c +index dd2f0355..d0433c3a 100644 +--- a/audit.c ++++ b/audit.c +@@ -34,6 +34,12 @@ + #include "log.h" + #include "hostfile.h" + #include "auth.h" ++#include "ssh-gss.h" ++#include "monitor_wrap.h" ++#include "xmalloc.h" ++#include "misc.h" ++#include "servconf.h" ++#include "ssherr.h" + + /* + * Care must be taken when using this since it WILL NOT be initialized when +@@ -41,6 +47,7 @@ + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ + extern Authctxt *the_authctxt; ++extern ServerOptions options; + + /* Maybe add the audit class to struct Authmethod? */ + ssh_audit_event_t +@@ -69,13 +76,10 @@ audit_classify_auth(const char *method) + const char * + audit_username(void) + { +- static const char unknownuser[] = "(unknown user)"; +- static const char invaliduser[] = "(invalid user)"; ++ static const char unknownuser[] = "(unknown)"; + +- if (the_authctxt == NULL || the_authctxt->user == NULL) ++ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) + return (unknownuser); +- if (!the_authctxt->valid) +- return (invaliduser); + return (the_authctxt->user); + } + +@@ -109,6 +113,35 @@ audit_event_lookup(ssh_audit_event_t ev) + return(event_lookup[i].name); + } + ++void ++audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) ++{ ++ char *fp; ++ ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ *rv = -SSH_ERR_INTERNAL_ERROR; ++ free(fp); ++} ++ ++void ++audit_unsupported(struct ssh *ssh, int what) ++{ ++ mm_audit_unsupported_body(ssh, what); ++} ++ ++void ++audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) ++{ ++ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()); ++} ++ ++void ++audit_session_key_free(struct ssh *ssh, int ctos) ++{ ++ mm_audit_session_key_free_body(ssh, ctos, getpid(), getuid()); ++} ++ + # ifndef CUSTOM_SSH_AUDIT_EVENTS + /* + * Null implementations of audit functions. +@@ -137,6 +170,17 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) + audit_username(), event, audit_event_lookup(event)); + } + ++/* ++ * Called when a child process has called, or will soon call, ++ * audit_session_open. ++ */ ++void ++audit_count_session_open(void) ++{ ++ debug("audit count session open euid %d user %s", geteuid(), ++ audit_username()); ++} ++ + /* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. +@@ -172,13 +216,82 @@ audit_session_close(struct logininfo *li) + /* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows +- * multiple sessions within a single connection. ++ * multiple sessions within a single connection. Returns a "handle" for ++ * audit_end_command. + */ +-void +-audit_run_command(const char *command) ++int ++audit_run_command(struct ssh *ssh, const char *command) + { + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); ++ return 0; ++} ++ ++/* ++ * This will be called when the non-interactive command finishes. Note that ++ * it may be called multiple times for a single connection since SSH2 allows ++ * multiple sessions within a single connection. "handle" should come from ++ * the corresponding audit_run_command. ++ */ ++void ++audit_end_command(struct ssh *ssh, int handle, const char *command) ++{ ++ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), ++ audit_username(), command); ++} ++ ++/* ++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. ++ * ++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. ++ */ ++int ++audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++{ ++ debug("audit %s key usage euid %d user %s fingerprint %s, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), ++ fp, rv); ++} ++ ++/* ++ * This will be called when the protocol negotiation fails. ++ */ ++void ++audit_unsupported_body(struct ssh *ssh, int what) ++{ ++ debug("audit unsupported protocol euid %d type %d", geteuid(), what); ++} ++ ++/* ++ * This will be called on succesfull protocol negotiation. ++ */ ++void ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++ uid_t uid) ++{ ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, ++ (unsigned)uid); ++} ++ ++/* ++ * This will be called on succesfull session key discard ++ */ ++void ++audit_session_key_free_body(struct ssh *, int ctos, pid_t pid, uid_t uid) ++{ ++ debug("audit session key discard euid %u direction %d from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); ++} ++ ++/* ++ * This will be called on destroy private part of the server key ++ */ ++void ++audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) ++{ ++ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", ++ geteuid(), fp, (long)pid, (unsigned)uid); + } + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff --git a/audit.h b/audit.h +index 38cb5ad3..45d66ccf 100644 +--- a/audit.h ++++ b/audit.h +@@ -26,6 +26,7 @@ + # define _SSH_AUDIT_H + + #include "loginrec.h" ++#include "sshkey.h" + + struct ssh; + +@@ -45,13 +46,32 @@ enum ssh_audit_event_type { + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN + }; ++ ++enum ssh_audit_kex { ++ SSH_AUDIT_UNSUPPORTED_CIPHER, ++ SSH_AUDIT_UNSUPPORTED_MAC, ++ SSH_AUDIT_UNSUPPORTED_COMPRESSION ++}; + typedef enum ssh_audit_event_type ssh_audit_event_t; + ++int listening_for_clients(void); ++ + void audit_connection_from(const char *, int); + void audit_event(struct ssh *, ssh_audit_event_t); ++void audit_count_session_open(void); + void audit_session_open(struct logininfo *); + void audit_session_close(struct logininfo *); +-void audit_run_command(const char *); ++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); ++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 *); ++void audit_unsupported_body(struct ssh *, int); ++void audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(struct ssh *, int ctos); ++void audit_session_key_free_body(struct ssh *, int ctos, pid_t, uid_t); ++void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); + + #endif /* _SSH_AUDIT_H */ +diff --git a/auditstub.c b/auditstub.c +new file mode 100644 +index 00000000..639a798d +--- /dev/null ++++ b/auditstub.c @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -726,23 +779,47 @@ diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c ---- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200 -+++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200 -@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 - authctxt->valid = 0; - /* Invalid user, fake password information */ - authctxt->pw = fakepw(); +diff --git a/auth.c b/auth.c +index e4578169..e10e804f 100644 +--- a/auth.c ++++ b/auth.c +@@ -501,9 +501,6 @@ getpwnamallow(struct ssh *ssh, const char *user) + record_failed_login(ssh, user, + auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); + #endif -#ifdef SSH_AUDIT_EVENTS -- mm_audit_event(ssh, SSH_INVALID_USER); --#endif - } - #ifdef USE_PAM - if (options.use_pam) -diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c ---- openssh-8.6p1/auth2-hostbased.c.audit 2021-04-19 16:47:35.656061361 +0200 -+++ openssh-8.6p1/auth2-hostbased.c 2021-04-19 16:47:35.754062114 +0200 -@@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh) +- audit_event(ssh, SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(ssh, pw)) +diff --git a/auth.h b/auth.h +index 39163035..6be52d70 100644 +--- a/auth.h ++++ b/auth.h +@@ -215,6 +215,8 @@ struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *); + int get_hostkey_index(struct sshkey *, int, struct ssh *); + int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, + u_char **, size_t *, const u_char *, size_t, const char *); ++int hostbased_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 **); + + /* Key / cert options linkage to auth layer */ + int auth_activate_options(struct ssh *, struct sshauthopt *); +@@ -240,6 +242,8 @@ int auth_check_authkey_line(struct passwd *, struct sshkey *, + char *, const char *, const char *, const char *, struct sshauthopt **); + int auth_check_authkeys_file(struct passwd *, FILE *, char *, + struct sshkey *, const char *, const char *, struct sshauthopt **); ++int 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 **); + FILE *auth_openkeyfile(const char *, struct passwd *, int); + FILE *auth_openprincipals(const char *, struct passwd *, int); + +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index a3be6e49..8cebaffd 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -157,7 +157,7 @@ userauth_hostbased(struct ssh *ssh, const char *method) authenticated = 0; if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser, chost, key) && @@ -751,7 +828,7 @@ diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0) authenticated = 1; -@@ -175,6 +175,20 @@ done: +@@ -174,6 +174,20 @@ done: return authenticated; } @@ -772,10 +849,11 @@ diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c ---- openssh-8.6p1/auth2-pubkey.c.audit 2021-04-19 16:47:35.726061899 +0200 -+++ openssh-8.6p1/auth2-pubkey.c 2021-04-19 16:47:35.754062114 +0200 -@@ -213,7 +213,7 @@ userauth_pubkey(struct ssh *ssh) +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 0d5ae0df..99cb810f 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -235,7 +235,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) /* test for correct signature */ authenticated = 0; if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) && @@ -784,7 +862,7 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details) == 0) { -@@ -305,6 +305,20 @@ done: +@@ -328,6 +328,20 @@ done: return authenticated; } @@ -805,43 +883,24 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c static int match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) -diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c ---- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 -+++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 -@@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha - record_failed_login(ssh, user, - auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); - #endif +diff --git a/auth2.c b/auth2.c +index 8ec41de2..4a8515ea 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -310,9 +310,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) + authctxt->valid = 0; + /* Invalid user, fake password information */ + authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS -- audit_event(ssh, SSH_INVALID_USER); --#endif /* SSH_AUDIT_EVENTS */ - return (NULL); - } - if (!allowed_user(ssh, pw)) -diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h ---- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200 -+++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200 -@@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty - int get_hostkey_index(struct sshkey *, int, struct ssh *); - int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, - u_char **, size_t *, const u_char *, size_t, const char *); -+int hostbased_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 **); - - /* Key / cert options linkage to auth layer */ - 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 *, - struct sshkey *, const char *, const char *, struct sshauthopt **); -+int 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 **); - FILE *auth_openkeyfile(const char *, struct passwd *, int); - FILE *auth_openprincipals(const char *, struct passwd *, int); - -diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c ---- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200 +- mm_audit_event(ssh, SSH_INVALID_USER); +-#endif + } + #ifdef USE_PAM + if (options.use_pam) +diff --git a/cipher.c b/cipher.c +index 8a18da2d..57d55325 100644 +--- a/cipher.c ++++ b/cipher.c @@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -868,7 +927,7 @@ diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -420,7 +401,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, void cipher_free(struct sshcipher_ctx *cc) { @@ -877,9 +936,10 @@ diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); -diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h ---- openssh-8.6p1/cipher.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/cipher.h 2021-04-19 16:47:35.755062122 +0200 +diff --git a/cipher.h b/cipher.h +index 6533ff2b..2e05a021 100644 +--- a/cipher.h ++++ b/cipher.h @@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -907,10 +967,11 @@ diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c ---- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200 -+++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200 -@@ -65,6 +65,7 @@ +diff --git a/kex.c b/kex.c +index 8b200ff4..62f607d6 100644 +--- a/kex.c ++++ b/kex.c +@@ -68,6 +68,7 @@ #include "sshbuf.h" #include "digest.h" #include "xmalloc.h" @@ -918,7 +979,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c /* prototype */ static int kex_choose_conf(struct ssh *, uint32_t seq); -@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -821,12 +822,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -937,7 +998,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -847,8 +852,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -951,7 +1012,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -861,12 +870,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) } static int @@ -970,7 +1031,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -1002,7 +1015,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1030,7 +1043,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; @@ -979,7 +1040,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1045,7 +1058,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) peer[nmac] = NULL; goto out; } @@ -988,7 +1049,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -1040,6 +1053,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -1068,6 +1081,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -999,7 +1060,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha +@@ -1337,6 +1354,36 @@ dump_digest(const char *msg, const u_char *digest, int len) } #endif @@ -1036,10 +1097,11 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h ---- openssh-8.6p1/kex.h.audit 2021-04-19 16:47:35.683061568 +0200 -+++ openssh-8.6p1/kex.h 2021-04-19 16:47:35.756062129 +0200 -@@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); +diff --git a/kex.h b/kex.h +index 0e080ea3..6a55aadf 100644 +--- a/kex.h ++++ b/kex.h +@@ -255,6 +255,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1048,9 +1110,10 @@ diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c ---- openssh-8.6p1/mac.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/mac.c 2021-04-19 16:47:35.756062129 +0200 +diff --git a/mac.c b/mac.c +index f3dda669..bf051baa 100644 +--- a/mac.c ++++ b/mac.c @@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1072,31 +1135,21 @@ diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-8.6p1/mac.h.audit openssh-8.6p1/mac.h ---- openssh-8.6p1/mac.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/mac.h 2021-04-19 16:47:35.756062129 +0200 -@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 +diff --git a/mac.h b/mac.h +index 0b119d7a..5fb593b9 100644 +--- a/mac.h ++++ b/mac.h +@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); void mac_clear(struct sshmac *); +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in ---- openssh-8.6p1/Makefile.in.audit 2021-04-19 16:47:35.731061937 +0200 -+++ openssh-8.6p1/Makefile.in 2021-04-19 16:47:35.756062129 +0200 -@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ - kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ -- sshbuf-io.o -+ sshbuf-io.o auditstub.o - - SKOBJS= ssh-sk-client.o - -diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c ---- openssh-8.6p1/monitor.c.audit 2021-04-19 16:47:35.707061753 +0200 -+++ openssh-8.6p1/monitor.c 2021-04-19 16:47:35.756062129 +0200 +diff --git a/monitor.c b/monitor.c +index 43c10a4e..fbc35782 100644 +--- a/monitor.c ++++ b/monitor.c @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1105,8 +1158,8 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -107,6 +108,8 @@ extern u_int utmp_len; - extern struct sshbuf *loginmsg; +@@ -110,6 +111,8 @@ extern struct sshbuf *loginmsg; + extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ +extern void destroy_sensitive_data(struct ssh *); @@ -1114,7 +1167,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c /* State exported from the child */ static struct sshbuf *child_state; -@@ -157,6 +160,11 @@ int mm_answer_gss_updatecreds(struct ssh +@@ -154,6 +157,11 @@ int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); @@ -1126,7 +1179,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif static Authctxt *authctxt; -@@ -215,6 +223,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -214,6 +222,10 @@ struct mon_table mon_dispatch_proto20[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1137,7 +1190,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20[] = { #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1149,7 +1202,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1569,8 +1586,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1161,7 +1214,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1579,6 +1598,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1170,7 +1223,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1469,14 +1490,19 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1594,14 +1615,19 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1190,16 +1243,16 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c break; } if (!valid_data) -@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1613,8 +1639,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3_f("%s %s signature using %s %s%s%s", auth_method, - sshkey_type(key), sigalg == NULL ? "default" : sigalg, - (ret == 0) ? "verified" : "unverified", -@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session + debug3_f("%s %s signature using %s %s%s%s", auth_method, + sshkey_type(key), sigalg == NULL ? "default" : sigalg, + (ret == 0) ? "verified" : "unverified", +@@ -1702,13 +1726,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) } static void @@ -1220,7 +1273,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c session_unused(s->self); } -@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1775,7 +1805,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) error: if (s != NULL) @@ -1229,7 +1282,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1668,7 +1698,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i +@@ -1794,7 +1824,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1238,7 +1291,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c sshbuf_reset(m); free(tty); return (0); -@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock +@@ -1816,6 +1846,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) sshpam_cleanup(); #endif @@ -1247,7 +1300,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, +@@ -1862,12 +1894,47 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) { char *cmd; int r; @@ -1296,7 +1349,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c free(cmd); return (0); } -@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1940,6 +2007,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1304,7 +1357,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1820,6 +1888,19 @@ mm_get_keystate(struct ssh *ssh, struct +@@ -1947,6 +2015,19 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1324,7 +1377,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c } -@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss +@@ -2234,3 +2315,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { #endif /* GSSAPI */ @@ -1427,10 +1480,11 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h ---- openssh-8.6p1/monitor.h.audit 2021-04-19 16:47:35.707061753 +0200 -+++ openssh-8.6p1/monitor.h 2021-04-19 16:47:35.757062137 +0200 -@@ -65,7 +65,13 @@ enum monitor_reqtype { +diff --git a/monitor.h b/monitor.h +index d4d631dd..2c64f07d 100644 +--- a/monitor.h ++++ b/monitor.h +@@ -66,7 +66,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, @@ -1445,10 +1499,11 @@ diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c ---- openssh-8.6p1/monitor_wrap.c.audit 2021-04-19 16:47:35.685061584 +0200 -+++ openssh-8.6p1/monitor_wrap.c 2021-04-19 16:47:35.757062137 +0200 -@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, con +diff --git a/monitor_wrap.c b/monitor_wrap.c +index b6e3b3f3..1a079c15 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -567,7 +567,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, */ int @@ -1457,7 +1512,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -583,7 +583,8 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1467,7 +1522,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -616,6 +617,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, return 0; } @@ -1490,7 +1545,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi +@@ -1032,11 +1049,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) sshbuf_free(m); } @@ -1505,7 +1560,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command +@@ -1046,6 +1064,30 @@ mm_audit_run_command(const char *command) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); @@ -1536,7 +1591,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1294,3 +1336,83 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns) return &ci; } @@ -1620,10 +1675,11 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h ---- openssh-8.6p1/monitor_wrap.h.audit 2021-04-19 16:47:35.685061584 +0200 -+++ openssh-8.6p1/monitor_wrap.h 2021-04-19 16:47:35.757062137 +0200 -@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *, st +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 672dce52..661ed63b 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -58,7 +58,9 @@ int mm_user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *, int, struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1634,7 +1690,7 @@ diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); -@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *); +@@ -85,7 +87,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1648,9 +1704,10 @@ diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h #endif struct Session; -diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c ---- openssh-8.6p1/packet.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/packet.c 2021-04-19 16:48:46.885608837 +0200 +diff --git a/packet.c b/packet.c +index 9dea2cfc..344b5f54 100644 +--- a/packet.c ++++ b/packet.c @@ -81,6 +81,7 @@ #endif @@ -1659,7 +1716,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) return ssh->state->connection_out; } @@ -1673,7 +1730,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -675,22 +683,19 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) { struct session_state *state = ssh->state; u_int mode; @@ -1701,7 +1758,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -726,8 +731,18 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1720,7 +1777,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod +@@ -984,6 +999,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); @@ -1728,7 +1785,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2325,6 +2341,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1801,19 +1858,21 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-8.6p1/packet.h.audit openssh-8.6p1/packet.h ---- openssh-8.6p1/packet.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/packet.h 2021-04-19 16:47:35.758062145 +0200 -@@ -218,4 +218,5 @@ const u_char *sshpkt_ptr(struct ssh *, s +diff --git a/packet.h b/packet.h +index 49bb87f0..44a39a9e 100644 +--- a/packet.h ++++ b/packet.h +@@ -223,4 +223,5 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c ---- openssh-8.6p1/session.c.audit 2021-04-19 16:47:35.722061868 +0200 -+++ openssh-8.6p1/session.c 2021-04-19 16:47:35.758062145 +0200 -@@ -136,7 +136,7 @@ extern char *__progname; +diff --git a/session.c b/session.c +index 28bbb8a7..83fc9418 100644 +--- a/session.c ++++ b/session.c +@@ -145,7 +145,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1822,7 +1881,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -653,6 +653,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1837,7 +1896,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -745,15 +753,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1859,11 +1918,10 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1538,7 +1550,11 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove hostkey from the child's memory */ -- destroy_sensitive_data(); + /* remove keys from memory */ + destroy_sensitive_data(ssh); ssh_packet_clear_keys(ssh); + /* Don't audit this - both us and the parent would be talking to the @@ -1872,7 +1930,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1763,6 +1778,9 @@ session_unused(int id) +@@ -1750,6 +1766,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1882,10 +1940,11 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1828,6 +1847,19 @@ session_open(Authctxt *authctxt, int chanid) + return 1; } - Session * ++Session * +session_by_id(int id) +{ + if (id >= 0 && id < sessions_nalloc) { @@ -1898,11 +1957,10 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c + return NULL; +} + -+Session * + Session * session_by_tty(char *tty) { - int i; -@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2445,6 +2477,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) chan_write_failed(ssh, c); } @@ -1935,7 +1993,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * +@@ -2458,6 +2516,10 @@ session_close(struct ssh *ssh, Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1946,7 +2004,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2534,14 +2596,14 @@ session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) } void @@ -1963,7 +2021,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c else session_close(ssh, s); } -@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2668,6 +2730,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) server_loop2(ssh, authctxt); } @@ -1979,7 +2037,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2731,7 +2802,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) * or if running in monitor. */ if (mm_is_monitor()) @@ -1988,9 +2046,10 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h ---- openssh-8.6p1/session.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/session.h 2021-04-19 16:47:35.758062145 +0200 +diff --git a/session.h b/session.h +index 344a1ddf..a41c6efc 100644 +--- a/session.h ++++ b/session.h @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2018,53 +2077,25 @@ diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -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 -@@ -279,6 +280,15 @@ close_listen_socks(void) - num_listen_socks = 0; - } - -+/* -+ * Is this process listening for clients (i.e. not specific to any specific -+ * client connection?) -+ */ -+int listening_for_clients(void) -+{ -+ return num_listen_socks > 0; -+} -+ - /* Allocate and initialise the children array */ - static void - 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,44 @@ struct sshbuf *loginmsg; +diff --git a/sshd-session.c b/sshd-session.c +index 81d30152..a808ac9a 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -194,8 +194,8 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); 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 *); -+ ++void destroy_sensitive_data(struct ssh *ssh); ++void demote_sensitive_data(struct ssh *ssh); + + /* XXX reduce to stub once postauth split */ + int +@@ -208,6 +208,41 @@ mm_is_monitor(void) + return (pmonitor && pmonitor->m_pid > 0); + } + +static int +sshkey_is_private(const struct sshkey *k) +{ @@ -2100,13 +2131,13 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c + } +} + - static void do_ssh2_kex(struct ssh *); - /* -@@ -377,18 +387,40 @@ grace_alarm_handler(int sig) + * Signal handler for the alarm after the login grace period has expired. + * As usual, this may only take signal-safe actions, even though it is +@@ -236,18 +271,40 @@ grace_alarm_handler(int sig) _exit(EXIT_LOGIN_GRACE); } - + -/* Destroy the host and server keys. They will no longer be needed. */ +/* + * Destroy the host and server keys. They will no longer be needed. Careful, @@ -2147,7 +2178,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -397,20 +434,38 @@ destroy_sensitive_data(void) +@@ -256,20 +313,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2187,43 +2218,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c } /* Certs do not need demotion */ } -@@ -438,7 +493,7 @@ reseed_prngs(void) - } - - static void --privsep_preauth_child(void) -+privsep_preauth_child(struct ssh *ssh) - { - gid_t gidset[1]; - -@@ -453,7 +508,7 @@ privsep_preauth_child(void) - reseed_prngs(); - - /* Demote the private keys to public keys. */ -- demote_sensitive_data(); -+ demote_sensitive_data(ssh); - - #ifdef WITH_SELINUX - sshd_selinux_change_privsep_preauth_context(); -@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) - pmonitor->m_pkex = &ssh->kex; - - box = ssh_sandbox_init(pmonitor); -- pid = fork(); -+ pmonitor->m_pid = pid = fork(); - if (pid == -1) { - fatal("fork of unprivileged child failed"); - } else if (pid != 0) { -@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) - /* Arrange for logging to be sent to the monitor */ - set_log_handler(mm_log_handler, pmonitor); - -- privsep_preauth_child(); -+ privsep_preauth_child(ssh); - setproctitle("%s", "[net]"); - if (box != NULL) - ssh_sandbox_child(box); -@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -463,7 +538,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2232,7 +2227,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c reseed_prngs(); -@@ -2333,6 +2389,9 @@ main(int ac, char **av) +@@ -1387,6 +1462,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2242,7 +2237,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c 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,14 @@ do_ssh2_kex(struct ssh *ssh) +@@ -1432,6 +1510,14 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, void cleanup_exit(int i) { @@ -2257,7 +2252,7 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c extern int auth_attempted; /* monitor.c */ if (the_active_state != NULL && the_authctxt != NULL) { -@@ -2525,7 +2593,9 @@ cleanup_exit(int i) +@@ -1448,7 +1534,9 @@ cleanup_exit(int i) } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ @@ -2268,3 +2263,34 @@ diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif /* Override default fatal exit value when auth was attempted */ +diff --git a/sshd.c b/sshd.c +index c9ea8e38..8a99f0b2 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -217,6 +217,15 @@ close_listen_socks(void) + num_listen_socks = 0; + } + ++/* ++ * Is this process listening for clients (i.e. not specific to any specific ++ * client connection?) ++ */ ++int listening_for_clients(void) ++{ ++ return num_listen_socks > 0; ++} ++ + /* Allocate and initialise the children array */ + static void + child_alloc(void) +@@ -959,6 +968,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, + 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); +-- +2.49.0 + diff --git a/openssh-7.1p2-audit-race-condition.patch b/0040-openssh-7.1p2-audit-race-condition.patch similarity index 73% rename from openssh-7.1p2-audit-race-condition.patch rename to 0040-openssh-7.1p2-audit-race-condition.patch index 57ad148..fe732a6 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/0040-openssh-7.1p2-audit-race-condition.patch @@ -1,7 +1,19 @@ -diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.audit-race 2016-12-23 16:35:52.694685771 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:35:52.697685772 +0100 -@@ -1107,4 +1107,50 @@ mm_audit_destroy_sensitive_data(const ch +From c288d4a26ad44dc481c9d18d2920c9d70474833c Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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_ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); sshbuf_free(m); } @@ -52,10 +64,11 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c + pmonitor->m_recvfd = fd; +} #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.audit-race 2016-12-23 16:35:52.694685771 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 16:35:52.698685772 +0100 -@@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int); +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 661ed63b..e957ba6e 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -93,6 +93,8 @@ void mm_audit_unsupported_body(struct ssh *, int); void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t); void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); @@ -64,10 +77,11 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h #endif struct Session; -diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.audit-race 2016-12-23 16:35:52.695685771 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 16:37:26.339730596 +0100 -@@ -162,6 +162,10 @@ static Session *sessions = NULL; +diff --git a/session.c b/session.c +index 83fc9418..b4753d93 100644 +--- a/session.c ++++ b/session.c +@@ -167,6 +167,10 @@ static Session *sessions = NULL; login_cap_t *lc; #endif @@ -78,7 +92,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c static int is_child = 0; static int in_chroot = 0; static int have_dev_log = 1; -@@ -289,6 +293,8 @@ xauth_valid_string(const char *s) +@@ -390,6 +394,8 @@ xauth_valid_string(const char *s) return 1; } @@ -87,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c #define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This -@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c +@@ -513,6 +519,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) close(err[0]); #endif @@ -96,7 +110,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c /* Do processing for the child (exec command etc). */ do_child(ssh, s, command); /* NOTREACHED */ -@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm +@@ -630,6 +638,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); @@ -106,7 +120,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA do_login(ssh, s, command); -@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command) +@@ -766,6 +777,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command) } if (s->command != NULL && s->ptyfd == -1) s->command_handle = mm_audit_run_command(ssh, s->command); @@ -115,7 +129,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) +@@ -781,6 +794,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command) */ sshbuf_reset(loginmsg); @@ -136,7 +150,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c return ret; } -@@ -1538,6 +1565,33 @@ child_close_fds(void) +@@ -1532,6 +1559,33 @@ child_close_fds(struct ssh *ssh) log_redirect_stderr_to(NULL); } @@ -151,7 +165,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c +#endif + + /* remove hostkey from the child's memory */ -+ destroy_sensitive_data(ssh); ++ /* FIXME beldmit destroy_sensitive_data(ssh); */ + /* + * We can audit this, because we hacked the pipe to direct the + * messages over postauth child. But this message requires answer @@ -170,11 +184,11 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group -@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command +@@ -1549,13 +1603,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); -- /* remove hostkey from the child's memory */ +- /* remove keys from memory */ - destroy_sensitive_data(ssh); - ssh_packet_clear_keys(ssh); - /* Don't audit this - both us and the parent would be talking to the @@ -184,3 +198,6 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { do_setusercontext(pw); +-- +2.49.0 + diff --git a/openssh-9.0p1-audit-log.patch b/0041-openssh-9.0p1-audit-log.patch similarity index 85% rename from openssh-9.0p1-audit-log.patch rename to 0041-openssh-9.0p1-audit-log.patch index ae9550f..e04f31b 100644 --- a/openssh-9.0p1-audit-log.patch +++ b/0041-openssh-9.0p1-audit-log.patch @@ -1,7 +1,20 @@ -diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c ---- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200 -+++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200 -@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li +From 80d967a18261156573e7385f8e534a89d2767d67 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 @@ -10,51 +23,10 @@ diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c { /* not implemented */ } -diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c ---- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200 -+++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200 -@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) - void - audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) - { -- char *fp; -+ char *key_fp = NULL; -+ char *issuer_fp = NULL; -+ struct sshkey_cert *cert = NULL; - -- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) -+ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { -+ cert = key->cert; -+ issuer_fp = sshkey_fingerprint(cert->signature_key, -+ options.fingerprint_hash, SSH_FP_DEFAULT); -+ } -+ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) - *rv = -SSH_ERR_INTERNAL_ERROR; -- free(fp); -+ if (key_fp) -+ free(key_fp); -+ if (issuer_fp) -+ free(issuer_fp); - } - - void -diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h ---- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200 -+++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200 -@@ -64,7 +64,7 @@ void audit_session_close(struct logininf - int audit_run_command(struct ssh *, const char *); - void audit_end_command(struct ssh *, int, const char *); - ssh_audit_event_t audit_classify_auth(const char *); --int audit_keyusage(struct ssh *, int, char *, int); -+int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); - void audit_key(struct ssh *, int, int *, const struct sshkey *); - void audit_unsupported(struct ssh *, int); - void audit_kex(struct ssh *, int, char *, char *, char *, char *); -diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c ---- openssh-9.9p1/audit-linux.c.xxx 2024-10-15 11:49:48.092151974 +0200 -+++ openssh-9.9p1/audit-linux.c 2024-10-15 12:08:17.179158343 +0200 +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); @@ -64,7 +36,7 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c 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 c +@@ -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)", @@ -87,7 +59,7 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c audit_fd = audit_open(); if (audit_fd < 0) { -@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) else return 0; /* Must prevent login */ } @@ -135,7 +107,7 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c out: saved_errno = errno; audit_close(audit_fd); -@@ -179,26 +211,34 @@ audit_connection_from(const char *host, +@@ -179,26 +211,34 @@ audit_connection_from(const char *host, int port) int audit_run_command(struct ssh *ssh, const char *command) { @@ -217,7 +189,7 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c 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_e +@@ -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, @@ -229,7 +201,7 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c ssh_remote_ipaddr(ssh), "ssh", 1, AUDIT_USER_LOGOUT); } -@@ -266,12 +318,14 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -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(), @@ -244,3 +216,50 @@ diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c } 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 + diff --git a/openssh-7.7p1-fips.patch b/0042-openssh-7.7p1-fips.patch similarity index 77% rename from openssh-7.7p1-fips.patch rename to 0042-openssh-7.7p1-fips.patch index 5d8da08..f4729d7 100644 --- a/openssh-7.7p1-fips.patch +++ b/0042-openssh-7.7p1-fips.patch @@ -1,6 +1,33 @@ -diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c ---- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 +From 6e0e7462959e8bc6a99f50dbf9a5b42ae74c2c87 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 15 May 2025 13:43:29 +0200 +Subject: [PATCH 42/50] 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-keygen.c | 22 ++++++++++-- + ssh-rsa.c | 3 ++ + ssh.c | 5 +++ + sshconnect2.c | 61 ++++++++++++++++++--------------- + sshd-auth.c | 13 ++++--- + sshd.c | 13 +++++++ + sshkey.c | 37 ++++++++++++++++++++ + 18 files changed, 301 insertions(+), 60 deletions(-) + +diff --git a/dh.c b/dh.c +index 168dea1d..8c9a29fa 100644 +--- a/dh.c ++++ b/dh.c @@ -36,6 +36,7 @@ #include @@ -9,7 +36,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c #include "dh.h" #include "pathnames.h" -@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max +@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max) int best, bestcount, which, linenum; struct dhgroup dhg; @@ -22,7 +49,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c if ((f = fopen(get_moduli_filename(), "r")) == NULL) { logit("WARNING: could not open %s (%s), using fixed modulus", get_moduli_filename(), strerror(errno)); -@@ -502,4 +508,38 @@ dh_estimate(int bits) +@@ -502,4 +509,38 @@ dh_estimate(int bits) return 8192; } @@ -61,9 +88,10 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +} + #endif /* WITH_OPENSSL */ -diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h ---- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200 -+++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200 +diff --git a/dh.h b/dh.h +index c6326a39..e51e292b 100644 +--- a/dh.h ++++ b/dh.h @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); @@ -72,10 +100,11 @@ 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-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 @@ +diff --git a/kex-names.c b/kex-names.c +index 6c0b7c2b..cd3902ad 100644 +--- a/kex-names.c ++++ b/kex-names.c +@@ -33,6 +33,7 @@ #ifdef WITH_OPENSSL #include @@ -83,7 +112,7 @@ diff -up openssh-8.6p1/kex-names.c.fips openssh-8.6p1/kex-names.c #include #endif -@@ -203,7 +203,10 @@ kex_names_valid(const char *names) +@@ -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) { @@ -95,9 +124,149 @@ diff -up openssh-8.6p1/kex-names.c.fips openssh-8.6p1/kex-names.c free(s); return 0; } -diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c ---- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 +diff --git a/kex.c b/kex.c +index 62f607d6..71fbe5cb 100644 +--- a/kex.c ++++ b/kex.c +@@ -40,6 +40,7 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include + # ifdef HAVE_EVP_KDF_CTX_NEW + # include + # include +@@ -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 15df591c..eecdceba 100644 +--- a/kexgen.c ++++ b/kexgen.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #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 e99e0cf2..4c3feae0 100644 +--- a/kexgexc.c ++++ b/kexgexc.c @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -106,7 +275,7 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c #include #include -@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -117,10 +286,11 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h ---- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 -@@ -57,6 +57,18 @@ +diff --git a/myproposal.h b/myproposal.h +index 8fe9276c..3e0ec682 100644 +--- a/myproposal.h ++++ b/myproposal.h +@@ -58,6 +58,18 @@ "rsa-sha2-512," \ "rsa-sha2-256" @@ -138,8 +308,8 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h + #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ -@@ -78,6 +92,27 @@ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ +@@ -79,6 +91,27 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -167,10 +337,11 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ -diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c ---- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 -+++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 -@@ -39,6 +39,7 @@ +diff --git a/readconf.c b/readconf.c +index f340bf50..ea9d293c 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -43,6 +43,7 @@ #include #include #include @@ -178,7 +349,7 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c #ifdef USE_SYSTEM_GLOB # include #else -@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) +@@ -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 */ @@ -200,10 +371,11 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&options->what, \ -diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c ---- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200 -+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200 -@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 1fabf99d..ccb61586 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 @@ -213,10 +385,11 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c ---- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 -+++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 -@@ -38,6 +38,7 @@ +diff --git a/servconf.c b/servconf.c +index 84891544..8b708cbf 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -37,6 +37,7 @@ #include #include #include @@ -224,7 +397,7 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c #ifdef HAVE_UTIL_H #include #endif -@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) +@@ -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 */ @@ -246,10 +419,136 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ -diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c ---- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200 -+++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200 -@@ -77,6 +77,7 @@ +diff --git a/ssh-ed25519.c b/ssh-ed25519.c +index 22d8db02..41942f4e 100644 +--- a/ssh-ed25519.c ++++ b/ssh-ed25519.c +@@ -24,6 +24,7 @@ + + #include + #include ++#include + + #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-keygen.c b/ssh-keygen.c +index 16cff947..792aafde 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + #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 3ad1fddc..6c2f771a 100644 +--- a/ssh-rsa.c ++++ b/ssh-rsa.c +@@ -23,6 +23,7 @@ + + #include + #include ++#include + + #include + #include +@@ -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 98b103c9..abc8b843 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -78,6 +78,7 @@ #include #include #endif @@ -257,7 +556,7 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -1516,6 +1517,10 @@ main(int ac, char **av) +@@ -1642,6 +1643,10 @@ main(int ac, char **av) exit(0); } @@ -268,9 +567,10 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c /* Expand SecurityKeyProvider if it refers to an environment variable */ if (options.sk_provider != NULL && *options.sk_provider == '$' && strlen(options.sk_provider) > 1) { -diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c ---- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200 -+++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200 +diff --git a/sshconnect2.c b/sshconnect2.c +index 0af15bcc..14f7671a 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c @@ -45,6 +45,8 @@ #include #endif @@ -280,7 +580,7 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -262,36 +264,41 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -349,62 +649,19 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c } } #endif -diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c ---- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200 -+++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200 -@@ -66,6 +66,7 @@ - #endif - #include - #include -+#include - #include - #include - #include -@@ -77,6 +78,7 @@ +diff --git a/sshd-auth.c b/sshd-auth.c +index 897db9b4..eaf32981 100644 +--- a/sshd-auth.c ++++ b/sshd-auth.c +@@ -58,6 +58,7 @@ #ifdef WITH_OPENSSL - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - #endif - -@@ -1931,6 +1931,13 @@ main(int ac, char **av) - &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) - do_log2_r(r, ll, "Unable to load host key \"%s\"", - options.host_key_files[i]); -+ 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", -@@ -2110,6 +2113,10 @@ main(int ac, char **av) - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - -+ if (FIPS_mode()) { -+ debug("FIPS mode initialized"); -+ } -+ - /* - * Chdir to the root directory so that the current disk can be - * unmounted if desired. -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 #include - #include +#include - #include "openbsd-compat/openssl-compat.h" #endif -@@ -2506,10 +2513,14 @@ do_ssh2_kex(struct ssh *ssh) + #include "xmalloc.h" +@@ -859,10 +860,14 @@ do_ssh2_kex(struct ssh *ssh) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -423,10 +680,56 @@ diff -up openssh-8.6p1/sshd-session.c.fips openssh-8.6p1/sshd-session.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c ---- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 -+++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 -@@ -36,6 +36,7 @@ +diff --git a/sshd.c b/sshd.c +index 8a99f0b2..5ff0b5ff 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -52,6 +52,7 @@ + #endif + #include + #include ++#include + #include + #include + #include +@@ -63,6 +64,7 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include + #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 4e41a78c..ca1cdb64 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -35,6 +35,7 @@ #include #include #include @@ -434,7 +737,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #endif #include "crypto_api.h" -@@ -57,6 +58,7 @@ +@@ -59,6 +60,7 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" @@ -442,7 +745,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai +@@ -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; @@ -461,7 +764,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c if (!include_sigonly && impl->sigonly) continue; if ((certs_only && !impl->cert) || (plain_only && impl->cert)) -@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c +@@ -1441,6 +1455,20 @@ sshkey_read(struct sshkey *ret, char **cpp) return SSH_ERR_EC_CURVE_MISMATCH; } @@ -482,7 +785,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c /* Fill in ret from parsed key */ sshkey_free_contents(ret); *ret = *k; -@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, +@@ -2275,6 +2303,11 @@ sshkey_sign(struct sshkey *key, *lenp = 0; if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; @@ -494,7 +797,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c if ((impl = sshkey_impl_from_key(key)) == NULL) return SSH_ERR_KEY_TYPE_UNKNOWN; if ((r = sshkey_unshield_private(key)) != 0) -@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, +@@ -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; @@ -502,265 +805,9 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c + logit_f("Ed25519 keys are not allowed in FIPS mode"); + return SSH_ERR_INVALID_ARGUMENT; + } - if ((impl = sshkey_impl_from_key(key)) == NULL) - return SSH_ERR_KEY_TYPE_UNKNOWN; - return impl->funcs->verify(key, sig, siglen, data, dlen, -diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c ---- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 -+++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 -@@ -20,6 +20,7 @@ - - #ifdef WITH_OPENSSL - #include -+#include - #include - #include "openbsd-compat/openssl-compat.h" - #endif -@@ -69,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 -@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na - #endif - } - #ifdef WITH_OPENSSL -+ if (FIPS_mode()) { -+ if (type == KEY_DSA) -+ fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_ED25519 || type == KEY_ED25519_SK) -+ fatal("ED25519 keys are not allowed in FIPS mode"); -+ } - switch (type) { - case KEY_DSA: - if (*bitsp != 1024) -@@ -266,7 +267,7 @@ ask_filename(struct passwd *pw, const ch - 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 -@@ -1098,9 +1104,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)); -@@ -3830,7 +3831,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 -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c ---- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 -+++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 -@@ -33,6 +33,7 @@ - - #include - #include -+#include - - #include - #include -@@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA - 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 -up openssh-9.9p1/kexgen.c.xxx openssh-9.9p1/kexgen.c ---- openssh-9.9p1/kexgen.c.xxx 2024-10-09 10:35:56.285946080 +0200 -+++ openssh-9.9p1/kexgen.c 2024-10-09 10:41:52.792597194 +0200 -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #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 - 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 s - break; - #endif - case KEX_C25519_SHA256: -- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, -- &shared_secret); -+ if (FIPS_mode()) { -+ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); -+ r = SSH_ERR_INVALID_ARGUMENT; -+ } else { -+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, -+ &shared_secret); -+ } - break; - case KEX_KEM_SNTRUP761X25519_SHA512: -- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, -- &server_pubkey, &shared_secret); -+ if (FIPS_mode()) { -+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); -+ r = SSH_ERR_INVALID_ARGUMENT; -+ } else { -+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, -+ &server_pubkey, &shared_secret); -+ } - break; - 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 -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c ---- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200 -+++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200 -@@ -24,6 +24,7 @@ - - #include - #include -+#include - - #include "log.h" - #include "sshbuf.h" -@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke - key->ed25519_sk == NULL || - datalen >= INT_MAX - crypto_sign_ed25519_BYTES) - return SSH_ERR_INVALID_ARGUMENT; -+ if (FIPS_mode()) { -+ logit_f("Ed25519 keys are not allowed in FIPS mode"); -+ return SSH_ERR_INVALID_ARGUMENT; -+ } - smlen = slen = datalen + crypto_sign_ed25519_BYTES; - if ((sig = malloc(slen)) == NULL) - return SSH_ERR_ALLOC_FAIL; -@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * - dlen >= INT_MAX - crypto_sign_ed25519_BYTES || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; -+ if (FIPS_mode()) { -+ logit_f("Ed25519 keys are not allowed in FIPS mode"); -+ return SSH_ERR_INVALID_ARGUMENT; -+ } - - if ((b = sshbuf_from(sig, siglen)) == NULL) - return SSH_ERR_ALLOC_FAIL; -diff -up openssh-9.9p1/kex.c.xxx openssh-9.9p1/kex.c ---- openssh-9.9p1/kex.c.xxx 2024-10-11 12:44:08.087426597 +0200 -+++ openssh-9.9p1/kex.c 2024-10-11 14:00:10.404714521 +0200 -@@ -40,6 +40,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - # ifdef HAVE_EVP_KDF_CTX_NEW - # include - # include -@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh - - /* 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) + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + return impl->funcs->verify(key, sig, siglen, data, dlen, +-- +2.49.0 + diff --git a/0043-openssh-8.7p1-ssh-manpage.patch b/0043-openssh-8.7p1-ssh-manpage.patch new file mode 100644 index 0000000..89c6ea1 --- /dev/null +++ b/0043-openssh-8.7p1-ssh-manpage.patch @@ -0,0 +1,47 @@ +From 299a602802d7c7d121306eb2aeae1502871a35cb Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/0044-openssh-8.7p1-negotiate-supported-algs.patch similarity index 74% rename from openssh-8.7p1-negotiate-supported-algs.patch rename to 0044-openssh-8.7p1-negotiate-supported-algs.patch index c4d86e7..f4c3b8a 100644 --- a/openssh-8.7p1-negotiate-supported-algs.patch +++ b/0044-openssh-8.7p1-negotiate-supported-algs.patch @@ -1,6 +1,17 @@ -diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh ---- openssh-9.3p1/regress/hostkey-agent.sh.xxx 2023-05-29 18:15:56.311236887 +0200 -+++ openssh-9.3p1/regress/hostkey-agent.sh 2023-05-29 18:16:07.598503551 +0200 +From 5c92430c08ac392b5b2ace899cc043247c923734 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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" @@ -24,7 +35,7 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" ${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \ -I localhost-with-alias $OBJ/agent-key.$k.pub || \ -@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private +@@ -32,12 +45,16 @@ rm $OBJ/agent-ca # Don't need CA private any more either unset SSH_AUTH_SOCK @@ -44,10 +55,10 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke ( printf 'localhost-with-alias,127.0.0.1,::1 ' ; cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` -@@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do +@@ -50,15 +67,16 @@ for k in $SSH_KEYTYPES ; do done - SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'` + SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk` +SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"` # Prepare sshd_proxy for certificates. @@ -63,7 +74,7 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy test -f $OBJ/agent-key.${k}.pub || fatal "no $k key" -@@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> +@@ -70,7 +88,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> $OBJ/sshd_proxy ( printf '@cert-authority localhost-with-alias ' ; cat $OBJ/agent-ca.pub) > $OBJ/known_hosts @@ -72,10 +83,11 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke verbose "cert type $k" opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` -diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c ---- openssh-9.3p1/sshconnect2.c.xxx 2023-04-26 17:37:35.100827792 +0200 -+++ openssh-9.3p1/sshconnect2.c 2023-04-26 17:50:31.860748877 +0200 -@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st +diff --git a/sshconnect2.c b/sshconnect2.c +index 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]; @@ -84,7 +96,7 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c int r, use_known_hosts_order = 0; #if defined(GSSAPI) && defined(WITH_OPENSSL) -@@ -260,10 +260,22 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, if (use_known_hosts_order) hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo); @@ -108,7 +120,7 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { -@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, #endif free(hkalgs); @@ -116,3 +128,6 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) +-- +2.49.0 + diff --git a/openssh-9.0p1-evp-fips-kex.patch b/0045-openssh-9.0p1-evp-fips-kex.patch similarity index 90% rename from openssh-9.0p1-evp-fips-kex.patch rename to 0045-openssh-9.0p1-evp-fips-kex.patch index 36fd1cf..610cea0 100644 --- a/openssh-9.0p1-evp-fips-kex.patch +++ b/0045-openssh-9.0p1-evp-fips-kex.patch @@ -1,6 +1,20 @@ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/dh.c openssh-9.0p1-patched/dh.c ---- openssh-9.0p1/dh.c 2023-05-25 09:24:28.730868316 +0200 -+++ openssh-9.0p1-patched/dh.c 2023-05-25 09:23:44.841379532 +0200 +From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 #include @@ -11,7 +25,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include "dh.h" #include "pathnames.h" -@@ -290,10 +293,15 @@ +@@ -290,10 +293,15 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) int dh_gen_key(DH *dh, int need) { @@ -30,7 +44,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x if (need < 0 || dh_p == NULL || (pbits = BN_num_bits(dh_p)) <= 0 || -@@ -301,19 +309,85 @@ +@@ -301,19 +309,85 @@ dh_gen_key(DH *dh, int need) return SSH_ERR_INVALID_ARGUMENT; if (need < 256) need = 256; @@ -125,10 +139,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x } DH * -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c ---- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200 -+++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200 -@@ -1623,3 +1623,142 @@ +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; } @@ -271,9 +286,34 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return r; +} +#endif /* WITH_OPENSSL */ -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kexdh.c openssh-9.0p1-patched/kexdh.c ---- openssh-9.0p1/kexdh.c 2023-05-25 09:24:28.674867692 +0200 -+++ openssh-9.0p1-patched/kexdh.c 2023-05-25 09:25:28.494533889 +0200 +diff --git a/kex.h b/kex.h +index 6a55aadf..48f3bb87 100644 +--- a/kex.h ++++ b/kex.h +@@ -37,6 +37,9 @@ + # include + # include + # include ++# include ++# include ++# include + # ifdef OPENSSL_HAS_ECC + # include + # 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" @@ -285,7 +325,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include "sshkey.h" #include "kex.h" -@@ -83,9 +87,12 @@ +@@ -83,9 +87,12 @@ int kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) { BIGNUM *shared_secret = NULL; @@ -299,7 +339,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #ifdef DEBUG_KEXDH fprintf(stderr, "dh_pub= "); -@@ -100,24 +107,59 @@ +@@ -100,24 +107,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } @@ -363,32 +403,10 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x return r; } -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.h openssh-9.0p1-patched/kex.h ---- openssh-9.0p1/kex.h 2023-05-25 09:24:28.725868260 +0200 -+++ openssh-9.0p1-patched/kex.h 2023-05-25 09:23:44.841379532 +0200 -@@ -33,6 +33,9 @@ - # include - # include - # include -+# include -+# include -+# include - # ifdef OPENSSL_HAS_ECC - # include - # else /* OPENSSL_HAS_ECC */ -@@ -283,6 +286,9@@ - 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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c ---- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200 -+++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200 +diff --git a/kexecdh.c b/kexecdh.c +index efb2e55a..d92ba54f 100644 +--- a/kexecdh.c ++++ b/kexecdh.c @@ -35,17 +35,57 @@ #include @@ -447,7 +465,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x int kex_ecdh_keypair(struct kex *kex) { -@@ -55,11 +95,7 @@ +@@ -55,11 +95,7 @@ kex_ecdh_keypair(struct kex *kex) struct sshbuf *buf = NULL; int r; @@ -460,7 +478,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -101,11 +137,7 @@ +@@ -101,11 +137,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, *server_blobp = NULL; *shared_secretp = NULL; @@ -473,7 +491,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -140,11 +172,21 @@ +@@ -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; @@ -498,7 +516,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x *shared_secretp = NULL; if ((buf = sshbuf_new()) == NULL) { -@@ -153,45 +195,82 @@ +@@ -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; @@ -593,3 +611,6 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x sshbuf_free(buf); return r; } +-- +2.49.0 + diff --git a/openssh-8.7p1-nohostsha1proof.patch b/0046-openssh-8.7p1-nohostsha1proof.patch similarity index 69% rename from openssh-8.7p1-nohostsha1proof.patch rename to 0046-openssh-8.7p1-nohostsha1proof.patch index dae0932..9e75c8a 100644 --- a/openssh-8.7p1-nohostsha1proof.patch +++ b/0046-openssh-8.7p1-nohostsha1proof.patch @@ -1,7 +1,27 @@ -diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c ---- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100 -+++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100 -@@ -43,6 +43,7 @@ void +From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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; @@ -9,7 +29,7 @@ diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c static struct { char *pat; int bugs; -@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha +@@ -125,16 +126,21 @@ compat_banner(struct ssh *ssh, const char *version) }; /* process table, return first match */ @@ -31,9 +51,10 @@ diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c } /* Always returns pointer to allocated memory, caller must free. */ -diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h ---- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100 +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 @@ -43,24 +64,28 @@ diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h #define SSH_OLD_SESSIONID 0x00000010 /* #define unused 0x00000020 */ #define SSH_BUG_DEBUG 0x00000040 -diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c ---- openssh-8.7p1/monitor.c.sshrsacheck 2023-01-20 13:07:54.279676981 +0100 -+++ openssh-8.7p1/monitor.c 2023-01-20 15:01:07.007821379 +0100 -@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock - struct sshkey *key; +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; ++ size_t datlen, siglen, alglen; ++ int r, is_proof = 0; ++ u_int keyid, compat; const char proof_req[] = "hostkeys-prove-00@openssh.com"; + const char safe_rsa[] = "rsa-sha2-256"; debug3_f("entering"); -@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock +@@ -809,18 +810,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) } if ((key = get_hostkey_by_index(keyid)) != NULL) { @@ -94,10 +119,11 @@ diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c is_proof ? "hostkey proof" : "KEX", siglen); sshbuf_reset(m); -diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c ---- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100 -+++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100 -@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, +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; @@ -107,10 +133,11 @@ 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); -diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c ---- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100 -+++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100 -@@ -110,6 +110,7 @@ sshkey_file_tests(void) +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(); @@ -118,7 +145,7 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh- TEST_START("load RSA cert with SHA1 signature"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); -@@ -117,7 +118,7 @@ sshkey_file_tests(void) +@@ -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); @@ -127,10 +154,11 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh- TEST_START("load RSA cert with SHA512 signature"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0); -diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c ---- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck 2023-01-26 12:10:37.533168013 +0100 -+++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c 2023-01-26 12:15:35.637631860 +0100 -@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void) +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 @@ -146,10 +174,11 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh- TEST_START("fuzz RSA SHA256 sig"); buf = load_file("rsa_1"); -diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c ---- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100 -+++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100 -@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk +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; @@ -159,7 +188,7 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openss ca_buf = sshbuf_new(); ASSERT_PTR_NE(ca_buf, NULL); ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); -@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk +@@ -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, @@ -171,7 +200,7 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openss free(sigblob); sshbuf_free(ca_buf); -@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct +@@ -120,16 +124,22 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, { size_t len; u_char *sig; @@ -202,7 +231,7 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openss free(sig); } -@@ -514,7 +524,7 @@ sshkey_tests(void) +@@ -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"); @@ -211,9 +240,10 @@ 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/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 +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" @@ -222,10 +252,11 @@ diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c extern ServerOptions options; -@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * +@@ -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); @@ -233,10 +264,25 @@ diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c debug3_f("sign %s key (index %d) using sigalg %s", sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); if ((r = sshbuf_put_cstring(sigbuf, -diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c ---- openssh-8.7p1/sshconnect2.c.sshrsacheck 2023-01-25 15:33:29.140353651 +0100 -+++ openssh-8.7p1/sshconnect2.c 2023-01-25 15:59:34.225364883 +0100 -@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha +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; } @@ -251,23 +297,11 @@ diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c goto out; } -diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c ---- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100 -+++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100 -@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key, - ret = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if (hash_alg != want_alg) { -+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) { -+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg); - ret = SSH_ERR_SIGNATURE_INVALID; - goto out; - } -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) +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); @@ -295,3 +329,6 @@ diff -up openssh-9.8p1/sshd-session.c.xxx openssh-9.8p1/sshd-session.c /* Prepare the channels layer */ channel_init_channels(ssh); channel_set_af(ssh, options.address_family); +-- +2.49.0 + diff --git a/0047-openssh-9.6p1-pam-rhost.patch b/0047-openssh-9.6p1-pam-rhost.patch new file mode 100644 index 0000000..968e60a --- /dev/null +++ b/0047-openssh-9.6p1-pam-rhost.patch @@ -0,0 +1,25 @@ +From 497de886faaddec60b7ad1013396c7d4f3145968 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/0048-openssh-9.9p1-separate-keysign.patch b/0048-openssh-9.9p1-separate-keysign.patch new file mode 100644 index 0000000..8d0f691 --- /dev/null +++ b/0048-openssh-9.9p1-separate-keysign.patch @@ -0,0 +1,25 @@ +From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-9.9p1-openssl-mlkem.patch b/0049-openssh-9.9p1-openssl-mlkem.patch similarity index 94% rename from openssh-9.9p1-openssl-mlkem.patch rename to 0049-openssh-9.9p1-openssl-mlkem.patch index e39bb67..e04d194 100644 --- a/openssh-9.9p1-openssl-mlkem.patch +++ b/0049-openssh-9.9p1-openssl-mlkem.patch @@ -1,8 +1,18 @@ +From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 ec840c1f..c0d3be11 100644 +index cd3902ad..36a953ab 100644 --- a/kex-names.c +++ b/kex-names.c -@@ -90,6 +90,19 @@ static const struct kexalg kexalgs[] = { +@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = { { NULL, 0, -1, -1}, }; @@ -22,7 +32,7 @@ index ec840c1f..c0d3be11 100644 static char * kex_alg_list_internal(char sep, const struct kexalg *algs) { -@@ -98,6 +111,9 @@ 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++) { @@ -32,7 +42,7 @@ index ec840c1f..c0d3be11 100644 if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); -@@ -117,6 +133,10 @@ kex_alg_by_name(const char *name) +@@ -147,6 +163,10 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -383,3 +393,6 @@ index 2b5d3960..670049dc 100644 } #else /* USE_MLKEM768X25519 */ int +-- +2.49.0 + diff --git a/0050-openssh-9.9p2-error_processing.patch b/0050-openssh-9.9p2-error_processing.patch new file mode 100644 index 0000000..aed1c30 --- /dev/null +++ b/0050-openssh-9.9p2-error_processing.patch @@ -0,0 +1,25 @@ +From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/0051-Provide-better-error-for-non-supported-private-keys.patch b/0051-Provide-better-error-for-non-supported-private-keys.patch new file mode 100644 index 0000000..9c1aa4d --- /dev/null +++ b/0051-Provide-better-error-for-non-supported-private-keys.patch @@ -0,0 +1,27 @@ +From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001 +From: Zoltan Fridrich +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 +--- + 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 + diff --git a/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch b/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch new file mode 100644 index 0000000..f071225 --- /dev/null +++ b/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch @@ -0,0 +1,86 @@ +From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001 +From: Zoltan Fridrich +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 +--- + 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 + diff --git a/0053-support-authentication-indicators-in-GSSAPI.patch b/0053-support-authentication-indicators-in-GSSAPI.patch new file mode 100644 index 0000000..237e45d --- /dev/null +++ b/0053-support-authentication-indicators-in-GSSAPI.patch @@ -0,0 +1,450 @@ +From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +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 +--- + 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 + #endif + ++#ifdef HAVE_GSSAPI_EXT_H ++#include ++#elif defined(HAVE_GSSAPI_GSSAPI_EXT_H) ++#include ++#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 + diff --git a/1000-openssh-coverity.patch b/1000-openssh-coverity.patch new file mode 100644 index 0000000..88362eb --- /dev/null +++ b/1000-openssh-coverity.patch @@ -0,0 +1,257 @@ +From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +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 + diff --git a/openssh-9.9p1-gsissh.patch b/2000-openssh-10.0p1-gsissh.patch similarity index 86% rename from openssh-9.9p1-gsissh.patch rename to 2000-openssh-10.0p1-gsissh.patch index 5e2d011..4a1a329 100644 --- a/openssh-9.9p1-gsissh.patch +++ b/2000-openssh-10.0p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c ---- openssh-9.9p1.orig/auth2.c 2025-01-20 19:52:47.907052307 +0100 -+++ openssh-9.9p1/auth2.c 2025-01-20 20:23:17.232729940 +0100 +diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c +--- openssh-10.0p1.orig/auth2.c 2025-06-14 08:24:55.444264765 +0200 ++++ openssh-10.0p1/auth2.c 2025-06-14 08:25:50.314922659 +0200 @@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -101,9 +101,9 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c ---- openssh-9.9p1.orig/auth2-gss.c 2025-01-20 19:52:47.769051955 +0100 -+++ openssh-9.9p1/auth2-gss.c 2025-01-20 20:23:17.233729943 +0100 +diff -Nur openssh-10.0p1.orig/auth2-gss.c openssh-10.0p1/auth2-gss.c +--- openssh-10.0p1.orig/auth2-gss.c 2025-06-14 08:24:54.946580198 +0200 ++++ openssh-10.0p1/auth2-gss.c 2025-06-14 08:25:50.315696363 +0200 @@ -54,6 +54,7 @@ extern struct authmethod_cfg methodcfg_gsskeyex; extern struct authmethod_cfg methodcfg_gssapi; @@ -303,9 +303,9 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c Authmethod method_gsskeyex = { &methodcfg_gsskeyex, userauth_gsskeyex, -diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c ---- openssh-9.9p1.orig/auth.c 2025-01-20 19:52:47.908052310 +0100 -+++ openssh-9.9p1/auth.c 2025-01-20 20:23:17.233729943 +0100 +diff -Nur openssh-10.0p1.orig/auth.c openssh-10.0p1/auth.c +--- openssh-10.0p1.orig/auth.c 2025-06-14 08:24:55.443524655 +0200 ++++ openssh-10.0p1/auth.c 2025-06-14 08:25:50.316281495 +0200 @@ -298,7 +298,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -336,9 +336,9 @@ diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h ---- openssh-9.9p1.orig/auth.h 2025-01-20 19:52:47.909052313 +0100 -+++ openssh-9.9p1/auth.h 2025-01-20 20:23:17.234729946 +0100 +diff -Nur openssh-10.0p1.orig/auth.h openssh-10.0p1/auth.h +--- openssh-10.0p1.orig/auth.h 2025-06-14 08:24:55.443709595 +0200 ++++ openssh-10.0p1/auth.h 2025-06-14 08:25:50.316833592 +0200 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -348,9 +348,9 @@ diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c ---- openssh-9.9p1.orig/auth-pam.c 2025-01-20 19:52:47.954052427 +0100 -+++ openssh-9.9p1/auth-pam.c 2025-01-20 20:23:17.264730023 +0100 +diff -Nur openssh-10.0p1.orig/auth-pam.c openssh-10.0p1/auth-pam.c +--- openssh-10.0p1.orig/auth-pam.c 2025-06-14 08:24:55.609208310 +0200 ++++ openssh-10.0p1/auth-pam.c 2025-06-14 08:25:50.317378775 +0200 @@ -248,6 +248,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; @@ -511,9 +511,9 @@ diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h ---- openssh-9.9p1.orig/auth-pam.h 2025-01-20 19:52:47.713051809 +0100 -+++ openssh-9.9p1/auth-pam.h 2025-01-20 20:23:17.264730023 +0100 +diff -Nur openssh-10.0p1.orig/auth-pam.h openssh-10.0p1/auth-pam.h +--- openssh-10.0p1.orig/auth-pam.h 2025-06-14 08:24:54.755199761 +0200 ++++ openssh-10.0p1/auth-pam.h 2025-06-14 08:25:50.318085082 +0200 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -521,9 +521,9 @@ diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c ---- openssh-9.9p1.orig/canohost.c 2025-01-20 19:52:47.770051957 +0100 -+++ openssh-9.9p1/canohost.c 2025-01-20 20:23:17.265730026 +0100 +diff -Nur openssh-10.0p1.orig/canohost.c openssh-10.0p1/canohost.c +--- openssh-10.0p1.orig/canohost.c 2025-06-14 08:24:54.947106244 +0200 ++++ openssh-10.0p1/canohost.c 2025-06-14 08:25:50.318537655 +0200 @@ -17,6 +17,7 @@ #include #include @@ -566,9 +566,9 @@ diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c + } + } +} -diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h ---- openssh-9.9p1.orig/canohost.h 2025-01-20 19:52:47.770051957 +0100 -+++ openssh-9.9p1/canohost.h 2025-01-20 20:23:17.265730026 +0100 +diff -Nur openssh-10.0p1.orig/canohost.h openssh-10.0p1/canohost.h +--- openssh-10.0p1.orig/canohost.h 2025-06-14 08:24:54.947234403 +0200 ++++ openssh-10.0p1/canohost.h 2025-06-14 08:25:50.318980799 +0200 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -576,10 +576,10 @@ diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac ---- openssh-9.9p1.orig/configure.ac 2025-01-20 19:52:47.872052217 +0100 -+++ openssh-9.9p1/configure.ac 2025-01-20 20:23:17.266730028 +0100 -@@ -4920,6 +4920,14 @@ +diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac +--- openssh-10.0p1.orig/configure.ac 2025-06-14 08:24:55.711190794 +0200 ++++ openssh-10.0p1/configure.ac 2025-06-14 08:25:50.319884827 +0200 +@@ -4992,6 +4992,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -594,7 +594,7 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -4961,6 +4969,40 @@ +@@ -5034,6 +5042,40 @@ AC_SUBST([K5LIBS]) AC_SUBST([CHANNELLIBS]) @@ -635,9 +635,9 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c ---- openssh-9.9p1.orig/gss-genr.c 2025-01-20 19:52:47.962052448 +0100 -+++ openssh-9.9p1/gss-genr.c 2025-01-20 20:23:17.267730031 +0100 +diff -Nur openssh-10.0p1.orig/gss-genr.c openssh-10.0p1/gss-genr.c +--- openssh-10.0p1.orig/gss-genr.c 2025-06-14 08:24:55.730946369 +0200 ++++ openssh-10.0p1/gss-genr.c 2025-06-14 08:25:50.321274952 +0200 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -674,10 +674,10 @@ diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c ---- openssh-9.9p1.orig/gss-serv.c 2025-01-20 19:52:47.802052038 +0100 -+++ openssh-9.9p1/gss-serv.c 2025-01-20 20:23:17.268730033 +0100 -@@ -50,10 +50,12 @@ +diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c +--- openssh-10.0p1.orig/gss-serv.c 2025-06-14 08:24:55.712377680 +0200 ++++ openssh-10.0p1/gss-serv.c 2025-06-14 14:29:38.679799497 +0200 +@@ -51,10 +51,12 @@ #include "monitor_wrap.h" extern ServerOptions options; @@ -685,14 +685,14 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c 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}; + { {0, NULL}, GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, + GSS_C_NO_NAME, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, -+ GSS_C_NO_CONTEXT, 0, 0}; ++ GSS_C_NO_CONTEXT, 0, 0, NULL}; ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -61,14 +63,26 @@ +@@ -62,14 +64,26 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -719,7 +719,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -229,6 +243,10 @@ +@@ -230,6 +244,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -730,7 +730,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c } return (status); -@@ -248,6 +266,20 @@ +@@ -249,6 +267,20 @@ tok = ename->value; @@ -751,7 +751,23 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -308,21 +340,24 @@ +@@ -297,6 +329,7 @@ + } + + ++#ifdef KRB5 + /* 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. +@@ -380,6 +413,7 @@ + (void) gss_release_buffer_set(&ctx->minor, &attrs); + return (ctx->major); + } ++#endif + + + /* Extract the client details from a given context. This can only reliably +@@ -395,21 +429,24 @@ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; if (options.gss_store_rekey && client->used && ctx->client_creds) { @@ -781,7 +797,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c new_name, &equal); if (GSS_ERROR(ctx->major)) { -@@ -337,9 +372,9 @@ +@@ -424,9 +461,9 @@ debug("Marking rekeyed credentials for export"); @@ -793,7 +809,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; -@@ -356,12 +391,17 @@ +@@ -443,12 +480,17 @@ i++; } @@ -813,7 +829,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -378,16 +418,25 @@ +@@ -465,22 +507,33 @@ return (ctx->major); } @@ -829,6 +845,14 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c + return ctx->major; + gss_release_buffer(&ctx->minor, &ename); ++#ifdef KRB5 + /* Retrieve authentication indicators, if they exist */ + if ((ctx->major = ssh_gssapi_getindicators(ctx, + ctx->client, client))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } ++#endif /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; @@ -840,7 +864,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c return (ctx->major); } -@@ -395,6 +444,7 @@ +@@ -488,6 +541,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -848,7 +872,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -410,6 +460,14 @@ +@@ -503,6 +557,14 @@ gssapi_client.store.data = NULL; } } @@ -863,7 +887,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c } /* As user */ -@@ -417,6 +475,11 @@ +@@ -510,6 +572,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -875,7 +899,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c return (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -449,11 +512,13 @@ +@@ -543,11 +610,13 @@ (void) kex; /* used in privilege separation */ @@ -892,15 +916,15 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -464,6 +529,7 @@ +@@ -558,6 +627,7 @@ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); + gss_release_name(&lmin, &gssapi_client.ctx_name); - explicit_bzero(&gssapi_client, - sizeof(ssh_gssapi_client)); - return 0; -@@ -473,6 +539,24 @@ + + if (gssapi_client.indicators != NULL) { + for(i = 0; gssapi_client.indicators[i] != NULL; i++) { +@@ -575,6 +645,24 @@ return (0); } @@ -925,7 +949,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -499,9 +583,11 @@ +@@ -601,9 +689,11 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -938,7 +962,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c return; ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); -@@ -521,6 +607,18 @@ +@@ -623,6 +713,18 @@ if (ret) return; @@ -957,9 +981,9 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c ---- openssh-9.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/gss-serv-gsi.c 2025-01-20 20:23:17.268730033 +0100 +diff -Nur openssh-10.0p1.orig/gss-serv-gsi.c openssh-10.0p1/gss-serv-gsi.c +--- openssh-10.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/gss-serv-gsi.c 2025-06-14 08:25:50.323228698 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1289,10 +1313,10 @@ diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c ---- openssh-9.9p1.orig/gss-serv-krb5.c 2025-01-20 19:52:47.824052094 +0100 -+++ openssh-9.9p1/gss-serv-krb5.c 2025-01-20 20:23:17.269730036 +0100 -@@ -379,6 +379,34 @@ +diff -Nur openssh-10.0p1.orig/gss-serv-krb5.c openssh-10.0p1/gss-serv-krb5.c +--- openssh-10.0p1.orig/gss-serv-krb5.c 2025-06-14 08:24:55.712149299 +0200 ++++ openssh-10.0p1/gss-serv-krb5.c 2025-06-14 08:25:50.323586985 +0200 +@@ -431,6 +431,34 @@ return found_principal; } @@ -1327,7 +1351,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -473,7 +501,7 @@ +@@ -525,7 +553,7 @@ return set_env; } @@ -1336,7 +1360,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -544,7 +572,7 @@ +@@ -596,7 +624,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1345,9 +1369,9 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c ---- openssh-9.9p1.orig/kexgsss.c 2025-01-20 19:52:47.785051995 +0100 -+++ openssh-9.9p1/kexgsss.c 2025-01-21 07:14:03.079570547 +0100 +diff -Nur openssh-10.0p1.orig/kexgsss.c openssh-10.0p1/kexgsss.c +--- openssh-10.0p1.orig/kexgsss.c 2025-06-14 08:24:54.950961355 +0200 ++++ openssh-10.0p1/kexgsss.c 2025-06-14 08:25:50.324355451 +0200 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1411,21 +1435,31 @@ diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c +} + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in ---- openssh-9.9p1.orig/Makefile.in 2025-01-20 19:52:47.911052318 +0100 -+++ openssh-9.9p1/Makefile.in 2025-01-20 20:23:17.270730038 +0100 -@@ -138,6 +138,7 @@ +diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in +--- openssh-10.0p1.orig/Makefile.in 2025-06-14 08:24:55.442297261 +0200 ++++ openssh-10.0p1/Makefile.in 2025-06-14 14:49:48.752490751 +0200 +@@ -140,7 +140,7 @@ + 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 kexgsss.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ -+ gss-serv-gsi.o \ +- auth2-gss.o gss-serv.o gss-serv-krb5.o \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c ---- openssh-9.9p1.orig/misc.c 2025-01-20 19:52:47.963052451 +0100 -+++ openssh-9.9p1/misc.c 2025-01-20 20:23:17.271730041 +0100 -@@ -419,11 +419,14 @@ + uidswap.o platform-listen.o $(SKOBJS) +@@ -151,7 +151,7 @@ + serverloop.o auth.o auth2.o auth-options.o session.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 \ +- auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o kexgsss.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ +diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c +--- openssh-10.0p1.orig/misc.c 2025-06-14 08:24:55.731834474 +0200 ++++ openssh-10.0p1/misc.c 2025-06-14 08:25:50.325895875 +0200 +@@ -440,11 +440,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1441,7 +1475,7 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c int wspace = 0; if (*s == NULL) -@@ -431,6 +434,21 @@ +@@ -452,6 +455,21 @@ old = *s; @@ -1463,7 +1497,7 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -506,6 +524,20 @@ +@@ -527,6 +545,20 @@ return copy; } @@ -1484,10 +1518,10 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h ---- openssh-9.9p1.orig/misc.h 2025-01-20 19:52:47.840052135 +0100 -+++ openssh-9.9p1/misc.h 2025-01-20 20:23:17.272730043 +0100 -@@ -111,6 +111,7 @@ +diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h +--- openssh-10.0p1.orig/misc.h 2025-06-14 08:24:55.216960866 +0200 ++++ openssh-10.0p1/misc.h 2025-06-14 08:25:50.326898660 +0200 +@@ -112,6 +112,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1495,10 +1529,10 @@ diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c ---- openssh-9.9p1.orig/monitor.c 2025-01-20 19:52:47.964052453 +0100 -+++ openssh-9.9p1/monitor.c 2025-01-20 20:23:17.273730046 +0100 -@@ -148,6 +148,9 @@ +diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c +--- openssh-10.0p1.orig/monitor.c 2025-06-14 08:24:55.732232011 +0200 ++++ openssh-10.0p1/monitor.c 2025-06-14 08:25:50.327682491 +0200 +@@ -151,6 +151,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1508,7 +1542,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -201,7 +204,7 @@ +@@ -205,7 +208,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1517,7 +1551,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -209,7 +212,7 @@ +@@ -213,7 +216,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1526,7 +1560,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -233,8 +236,11 @@ +@@ -237,8 +240,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1539,7 +1573,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c #endif {0, 0, NULL} }; -@@ -244,6 +250,8 @@ +@@ -248,6 +254,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1547,8 +1581,8 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c + {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs}, {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif - #ifdef WITH_OPENSSL -@@ -324,6 +332,8 @@ + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, +@@ -328,6 +336,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1557,7 +1591,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -458,6 +468,8 @@ +@@ -461,6 +471,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1566,7 +1600,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -812,14 +824,17 @@ +@@ -895,14 +907,17 @@ debug3_f("entering"); @@ -1587,7 +1621,7 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2170,6 +2185,79 @@ +@@ -2249,6 +2264,79 @@ } int @@ -1667,10 +1701,10 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h ---- openssh-9.9p1.orig/monitor.h 2025-01-20 19:52:47.912052320 +0100 -+++ openssh-9.9p1/monitor.h 2025-01-20 20:23:17.273730046 +0100 -@@ -75,6 +75,10 @@ +diff -Nur openssh-10.0p1.orig/monitor.h openssh-10.0p1/monitor.h +--- openssh-10.0p1.orig/monitor.h 2025-06-14 08:24:55.446043209 +0200 ++++ openssh-10.0p1/monitor.h 2025-06-14 08:25:50.328788501 +0200 +@@ -76,6 +76,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, @@ -1681,10 +1715,10 @@ diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h }; struct ssh; -diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c ---- openssh-9.9p1.orig/monitor_wrap.c 2025-01-20 19:52:47.918052335 +0100 -+++ openssh-9.9p1/monitor_wrap.c 2025-01-20 20:23:17.274730049 +0100 -@@ -1139,6 +1139,94 @@ +diff -Nur openssh-10.0p1.orig/monitor_wrap.c openssh-10.0p1/monitor_wrap.c +--- openssh-10.0p1.orig/monitor_wrap.c 2025-06-14 08:24:55.468434323 +0200 ++++ openssh-10.0p1/monitor_wrap.c 2025-06-14 08:25:50.329256997 +0200 +@@ -1195,6 +1195,94 @@ return (authenticated); } @@ -1779,9 +1813,9 @@ diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h ---- openssh-9.9p1.orig/monitor_wrap.h 2025-01-20 19:52:47.918052335 +0100 -+++ openssh-9.9p1/monitor_wrap.h 2025-01-20 20:23:17.274730049 +0100 +diff -Nur openssh-10.0p1.orig/monitor_wrap.h openssh-10.0p1/monitor_wrap.h +--- openssh-10.0p1.orig/monitor_wrap.h 2025-06-14 08:24:55.468730870 +0200 ++++ openssh-10.0p1/monitor_wrap.h 2025-06-14 08:25:50.329790028 +0200 @@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1793,10 +1827,10 @@ diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c ---- openssh-9.9p1.orig/readconf.c 2025-01-20 19:52:47.966052458 +0100 -+++ openssh-9.9p1/readconf.c 2025-01-20 20:23:17.275730051 +0100 -@@ -2794,11 +2794,11 @@ +diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c +--- openssh-10.0p1.orig/readconf.c 2025-06-14 08:24:55.733023595 +0200 ++++ openssh-10.0p1/readconf.c 2025-06-14 08:25:50.330266207 +0200 +@@ -2881,11 +2881,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1811,10 +1845,10 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h ---- openssh-9.9p1.orig/readconf.h 2025-01-20 19:52:47.790052008 +0100 -+++ openssh-9.9p1/readconf.h 2025-01-20 20:23:17.276730054 +0100 -@@ -80,6 +80,8 @@ +diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h +--- openssh-10.0p1.orig/readconf.h 2025-06-14 08:24:54.953487731 +0200 ++++ openssh-10.0p1/readconf.h 2025-06-14 08:25:50.330993746 +0200 +@@ -79,6 +79,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1823,10 +1857,10 @@ diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c ---- openssh-9.9p1.orig/servconf.c 2025-01-20 19:52:47.966052458 +0100 -+++ openssh-9.9p1/servconf.c 2025-01-20 20:23:17.277730056 +0100 -@@ -95,6 +95,7 @@ +diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c +--- openssh-10.0p1.orig/servconf.c 2025-06-14 08:24:55.733579673 +0200 ++++ openssh-10.0p1/servconf.c 2025-06-14 08:25:50.331610935 +0200 +@@ -96,6 +96,7 @@ /* Portable-specific options */ options->use_pam = -1; options->pam_service_name = NULL; @@ -1834,7 +1868,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -141,9 +142,11 @@ +@@ -142,9 +143,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1845,8 +1879,8 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + options->gsi_allow_limited_proxy = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; - options->use_kuserok = -1; -@@ -314,6 +317,8 @@ + options->gss_indicators = NULL; +@@ -317,6 +320,8 @@ options->use_pam = 0; if (options->pam_service_name == NULL) options->pam_service_name = xstrdup(SSHD_PAM_SERVICE); @@ -1855,7 +1889,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -395,13 +400,17 @@ +@@ -398,13 +403,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1875,7 +1909,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -573,7 +582,7 @@ +@@ -578,7 +587,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1884,7 +1918,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -593,6 +602,9 @@ +@@ -598,6 +607,9 @@ sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1892,9 +1926,9 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, + sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -628,9 +640,11 @@ +@@ -633,9 +645,11 @@ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, { "pamservicename", sPAMServiceName, SSHCFG_ALL }, @@ -1906,7 +1940,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -683,8 +697,15 @@ +@@ -688,8 +702,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1922,8 +1956,8 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -692,8 +713,11 @@ - { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, +@@ -698,8 +719,11 @@ + { "gssapiindicators", sGssIndicators, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, @@ -1934,7 +1968,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -767,6 +791,8 @@ +@@ -774,6 +798,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1943,7 +1977,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1407,6 +1433,10 @@ +@@ -1454,6 +1480,10 @@ *charptr = xstrdup(arg); break; @@ -1954,7 +1988,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1658,6 +1688,10 @@ +@@ -1705,6 +1735,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1965,7 +1999,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1666,6 +1700,10 @@ +@@ -1713,6 +1747,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1976,8 +2010,8 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1686,6 +1724,12 @@ - options->gss_kex_algorithms = xstrdup(arg); +@@ -1742,6 +1780,12 @@ + options->gss_indicators = xstrdup(arg); break; +#ifdef GSI @@ -1989,7 +2023,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2950,6 +2994,7 @@ +@@ -3012,6 +3056,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -1997,9 +2031,9 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h ---- openssh-9.9p1.orig/servconf.h 2025-01-20 19:52:47.836052125 +0100 -+++ openssh-9.9p1/servconf.h 2025-01-20 20:23:17.278730059 +0100 +diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h +--- openssh-10.0p1.orig/servconf.h 2025-06-14 08:24:55.713201111 +0200 ++++ openssh-10.0p1/servconf.h 2025-06-14 08:25:50.332635999 +0200 @@ -155,9 +155,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2013,7 +2047,7 @@ diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -221,6 +224,7 @@ +@@ -222,6 +225,7 @@ int use_pam; /* Enable auth via PAM */ char *pam_service_name; @@ -2021,10 +2055,10 @@ diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h int permit_tun; -diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 ---- openssh-9.9p1.orig/ssh.1 2025-01-20 19:52:47.941052394 +0100 -+++ openssh-9.9p1/ssh.1 2025-01-20 20:23:17.279730061 +0100 -@@ -1523,6 +1523,18 @@ +diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 +--- openssh-10.0p1.orig/ssh.1 2025-06-14 08:24:55.527924262 +0200 ++++ openssh-10.0p1/ssh.1 2025-06-14 08:25:50.333158134 +0200 +@@ -1528,6 +1528,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2043,10 +2077,10 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c ---- openssh-9.9p1.orig/ssh.c 2025-01-20 19:52:47.926052356 +0100 -+++ openssh-9.9p1/ssh.c 2025-01-20 20:23:17.280730064 +0100 -@@ -573,6 +573,38 @@ +diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c +--- openssh-10.0p1.orig/ssh.c 2025-06-14 08:24:55.693276450 +0200 ++++ openssh-10.0p1/ssh.c 2025-06-14 13:58:47.186170059 +0200 +@@ -578,6 +578,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2062,14 +2096,14 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, ++ (void)read_config_file(buf, pw, host, host_name, cmd, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, ++ (void)read_config_file(buf, pw, host, host_name, cmd, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2077,7 +2111,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, ++ (void)read_config_file(buf, pw, host, host_name, cmd, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2085,7 +2119,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1299,8 +1331,12 @@ +@@ -1313,8 +1345,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2099,9 +2133,9 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config ---- openssh-9.9p1.orig/ssh_config 2025-01-20 19:52:47.793052015 +0100 -+++ openssh-9.9p1/ssh_config 2025-01-20 20:23:17.281730067 +0100 +diff -Nur openssh-10.0p1.orig/ssh_config openssh-10.0p1/ssh_config +--- openssh-10.0p1.orig/ssh_config 2025-06-14 08:24:54.955694862 +0200 ++++ openssh-10.0p1/ssh_config 2025-06-14 08:25:50.334427503 +0200 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2115,9 +2149,9 @@ diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP no -diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 ---- openssh-9.9p1.orig/ssh_config.5 2025-01-20 19:52:47.956052433 +0100 -+++ openssh-9.9p1/ssh_config.5 2025-01-20 20:23:17.282730069 +0100 +diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 +--- openssh-10.0p1.orig/ssh_config.5 2025-06-14 08:24:55.625225410 +0200 ++++ openssh-10.0p1/ssh_config.5 2025-06-14 08:25:50.334845923 +0200 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2131,7 +2165,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -931,7 +937,7 @@ +@@ -969,7 +975,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2140,7 +2174,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -939,12 +945,12 @@ +@@ -977,12 +983,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2155,7 +2189,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1600,7 +1606,7 @@ +@@ -1645,7 +1651,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2164,10 +2198,10 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c ---- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 19:52:47.951052420 +0100 -+++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:23:17.283730071 +0100 -@@ -855,6 +855,11 @@ +diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c +--- openssh-10.0p1.orig/sshconnect2.c 2025-06-14 08:24:55.591449573 +0200 ++++ openssh-10.0p1/sshconnect2.c 2025-06-14 08:25:50.335562288 +0200 +@@ -858,6 +858,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2179,7 +2213,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -963,7 +968,8 @@ +@@ -966,7 +971,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2189,7 +2223,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1130,6 +1136,20 @@ +@@ -1133,6 +1139,20 @@ return r; } @@ -2210,7 +2244,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1152,6 +1172,12 @@ +@@ -1155,6 +1175,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2223,7 +2257,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1165,7 +1191,9 @@ +@@ -1168,7 +1194,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2234,9 +2268,9 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 ---- openssh-9.9p1.orig/sshd.8 2025-01-20 19:52:47.807052051 +0100 -+++ openssh-9.9p1/sshd.8 2025-01-20 20:23:17.283730071 +0100 +diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 +--- openssh-10.0p1.orig/sshd.8 2025-06-14 08:24:55.024336971 +0200 ++++ openssh-10.0p1/sshd.8 2025-06-14 08:25:50.336280328 +0200 @@ -840,6 +840,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2267,10 +2301,10 @@ diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config ---- openssh-9.9p1.orig/sshd_config 2025-01-20 19:52:47.826052099 +0100 -+++ openssh-9.9p1/sshd_config 2025-01-20 20:23:17.284730074 +0100 -@@ -76,10 +76,11 @@ +diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config +--- openssh-10.0p1.orig/sshd_config 2025-06-14 08:24:55.129477337 +0200 ++++ openssh-10.0p1/sshd_config 2025-06-14 08:25:50.336709644 +0200 +@@ -78,10 +78,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2284,7 +2318,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -95,6 +96,10 @@ +@@ -97,6 +98,10 @@ # problems. #UsePAM no @@ -2295,9 +2329,9 @@ diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 ---- openssh-9.9p1.orig/sshd_config.5 2025-01-20 19:52:47.870052212 +0100 -+++ openssh-9.9p1/sshd_config.5 2025-01-20 20:23:17.284730074 +0100 +diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 +--- openssh-10.0p1.orig/sshd_config.5 2025-06-14 08:24:55.713605773 +0200 ++++ openssh-10.0p1/sshd_config.5 2025-06-14 08:25:50.337207823 +0200 @@ -724,15 +724,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2343,7 +2377,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -2041,6 +2060,12 @@ +@@ -2100,6 +2119,12 @@ as a non-root user. The default is .Cm no . @@ -2356,9 +2390,9 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat ---- openssh-9.9p1.orig/sshd_config_redhat 2025-01-20 19:52:47.764051942 +0100 -+++ openssh-9.9p1/sshd_config_redhat 2025-01-20 20:23:17.285730077 +0100 +diff -Nur openssh-10.0p1.orig/sshd_config_redhat openssh-10.0p1/sshd_config_redhat +--- openssh-10.0p1.orig/sshd_config_redhat 2025-06-14 08:24:54.911947266 +0200 ++++ openssh-10.0p1/sshd_config_redhat 2025-06-14 08:25:50.337806574 +0200 @@ -2,9 +2,6 @@ KbdInteractiveAuthentication no @@ -2369,10 +2403,10 @@ diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat UsePAM yes X11Forwarding yes -diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c ---- openssh-9.9p1.orig/sshd-session.c 2025-01-20 19:52:47.968052463 +0100 -+++ openssh-9.9p1/sshd-session.c 2025-01-20 20:23:17.285730077 +0100 -@@ -1487,7 +1487,7 @@ +diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c +--- openssh-10.0p1.orig/sshd-session.c 2025-06-14 08:24:55.591819733 +0200 ++++ openssh-10.0p1/sshd-session.c 2025-06-14 08:25:50.338154455 +0200 +@@ -1448,7 +1448,7 @@ #endif #ifdef GSSAPI @@ -2381,10 +2415,10 @@ diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h ---- openssh-9.9p1.orig/ssh-gss.h 2025-01-20 19:52:47.805052046 +0100 -+++ openssh-9.9p1/ssh-gss.h 2025-01-20 20:23:17.286730079 +0100 -@@ -99,12 +99,14 @@ +diff -Nur openssh-10.0p1.orig/ssh-gss.h openssh-10.0p1/ssh-gss.h +--- openssh-10.0p1.orig/ssh-gss.h 2025-06-14 08:24:55.713368522 +0200 ++++ openssh-10.0p1/ssh-gss.h 2025-06-14 08:25:50.338720590 +0200 +@@ -105,12 +105,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -2399,8 +2433,8 @@ diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h + gss_ctx_id_t context; /* needed for globus_gss_assist_map_and_authorize() */ int used; int updated; - } ssh_gssapi_client; -@@ -125,7 +127,7 @@ + char **indicators; /* auth indicators */ +@@ -132,7 +134,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2409,7 +2443,7 @@ diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -172,6 +174,9 @@ +@@ -179,6 +181,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2419,12 +2453,12 @@ diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h ---- openssh-9.9p1.orig/version.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/version.h 2025-01-20 20:23:17.286730079 +0100 +diff -Nur openssh-10.0p1.orig/version.h openssh-10.0p1/version.h +--- openssh-10.0p1.orig/version.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/version.h 2025-06-14 08:41:29.417798618 +0200 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_9.9" + #define SSH_VERSION "OpenSSH_10.0" +#ifdef GSI +#define GSI_VERSION " GSI" @@ -2438,7 +2472,7 @@ diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h +#define KRB5_VERSION "" +#endif + - #define SSH_PORTABLE "p1" + #define SSH_PORTABLE "p2" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define GSI_PORTABLE "c-GSI" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ diff --git a/openssh-9.9p1-hpn-18.6.0.patch b/2001-openssh-10.0p1-hpn-18.7.0.patch similarity index 94% rename from openssh-9.9p1-hpn-18.6.0.patch rename to 2001-openssh-10.0p1-hpn-18.7.0.patch index da663c9..8349a52 100644 --- a/openssh-9.9p1-hpn-18.6.0.patch +++ b/2001-openssh-10.0p1-hpn-18.7.0.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c ---- openssh-9.9p1.orig/auth2.c 2025-01-20 20:48:33.444582227 +0100 -+++ openssh-9.9p1/auth2.c 2025-01-20 21:54:08.570687857 +0100 +diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c +--- openssh-10.0p1.orig/auth2.c 2025-06-14 10:53:02.012331859 +0200 ++++ openssh-10.0p1/auth2.c 2025-06-14 11:42:37.929224784 +0200 @@ -52,6 +52,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -41,9 +41,9 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-9.9p1.orig/binn.c openssh-9.9p1/binn.c ---- openssh-9.9p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/binn.c 2025-01-20 20:50:04.564813761 +0100 +diff -Nur openssh-10.0p1.orig/binn.c openssh-10.0p1/binn.c +--- openssh-10.0p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/binn.c 2025-06-14 10:54:01.301771902 +0200 @@ -0,0 +1,3541 @@ +#include +#include @@ -3586,9 +3586,9 @@ diff -Nur openssh-9.9p1.orig/binn.c openssh-9.9p1/binn.c +} + +/*************************************************************************************/ -diff -Nur openssh-9.9p1.orig/binn.h openssh-9.9p1/binn.h ---- openssh-9.9p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/binn.h 2025-01-20 20:50:04.565813763 +0100 +diff -Nur openssh-10.0p1.orig/binn.h openssh-10.0p1/binn.h +--- openssh-10.0p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/binn.h 2025-06-14 10:54:01.303905629 +0200 @@ -0,0 +1,945 @@ + +// TO ENABLE INLINE FUNCTIONS: @@ -4535,12 +4535,12 @@ diff -Nur openssh-9.9p1.orig/binn.h openssh-9.9p1/binn.h +#endif + +#endif //BINN_H -diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c ---- openssh-9.9p1.orig/channels.c 2025-01-20 20:48:33.373582047 +0100 -+++ openssh-9.9p1/channels.c 2025-01-20 21:55:22.938880541 +0100 -@@ -97,6 +97,11 @@ - /* Minimum port number for X11 forwarding */ - #define X11_PORT_MIN 6000 +diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c +--- openssh-10.0p1.orig/channels.c 2025-06-14 10:53:01.614387370 +0200 ++++ openssh-10.0p1/channels.c 2025-06-14 11:44:14.886309096 +0200 +@@ -99,6 +99,11 @@ + /* Maximum number of fake X11 displays to try. */ + #define MAX_DISPLAYS 1000 +/* in version of OpenSSH later than 8.8 if we advertise a window + * 16MB or larger is causes a pathological behaviour that reduces @@ -4550,7 +4550,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c /* Per-channel callback for pre/post IO actions */ typedef void chan_fn(struct ssh *, Channel *c); -@@ -225,6 +230,9 @@ +@@ -227,6 +232,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -4560,7 +4560,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c /* -- channel core */ void -@@ -519,6 +527,16 @@ +@@ -521,6 +529,16 @@ (c->output = sshbuf_new()) == NULL || (c->extended = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -4577,7 +4577,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) fatal_fr(r, "sshbuf_set_max_size"); c->ostate = CHAN_OUTPUT_OPEN; -@@ -530,6 +548,7 @@ +@@ -532,6 +550,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -4585,7 +4585,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1257,6 +1276,33 @@ +@@ -1259,6 +1278,33 @@ c->io_want = SSH_CHAN_IO_SOCK_W; } @@ -4619,7 +4619,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c) { -@@ -2364,18 +2410,29 @@ +@@ -2366,18 +2412,29 @@ c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { @@ -4652,7 +4652,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c c->local_consumed = 0; } return 1; -@@ -2961,9 +3018,7 @@ +@@ -2963,9 +3020,7 @@ * in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) @@ -4663,7 +4663,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c else chan_ibuf_empty(ssh, c); } -@@ -3672,7 +3727,7 @@ +@@ -3674,7 +3729,7 @@ error_fr(r, "parse adjust"); ssh_packet_disconnect(ssh, "Invalid window adjust message"); } @@ -4672,7 +4672,7 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c if ((new_rwin = c->remote_window + adjust) < c->remote_window) { fatal("channel %d: adjust %u overflows remote window %u", c->self, adjust, c->remote_window); -@@ -3787,6 +3842,13 @@ +@@ -3789,6 +3844,13 @@ return addr; } @@ -4686,9 +4686,9 @@ diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -diff -Nur openssh-9.9p1.orig/channels.h openssh-9.9p1/channels.h ---- openssh-9.9p1.orig/channels.h 2025-01-20 20:48:33.343581971 +0100 -+++ openssh-9.9p1/channels.h 2025-01-20 20:50:04.567813768 +0100 +diff -Nur openssh-10.0p1.orig/channels.h openssh-10.0p1/channels.h +--- openssh-10.0p1.orig/channels.h 2025-06-14 10:53:01.467785388 +0200 ++++ openssh-10.0p1/channels.h 2025-06-14 10:54:01.306120024 +0200 @@ -175,6 +175,7 @@ u_int local_window_max; u_int local_consumed; @@ -4706,16 +4706,16 @@ diff -Nur openssh-9.9p1.orig/channels.h openssh-9.9p1/channels.h /* Maximum size for direct reads to buffers */ #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -398,4 +399,6 @@ +@@ -399,4 +400,6 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); +/* hpn handler */ +void channel_set_hpn_disabled(int); #endif -diff -Nur openssh-9.9p1.orig/cipher.c openssh-9.9p1/cipher.c ---- openssh-9.9p1.orig/cipher.c 2025-01-20 20:48:33.392582095 +0100 -+++ openssh-9.9p1/cipher.c 2025-01-20 21:56:16.253016900 +0100 +diff -Nur openssh-10.0p1.orig/cipher.c openssh-10.0p1/cipher.c +--- openssh-10.0p1.orig/cipher.c 2025-06-14 10:53:01.716919856 +0200 ++++ openssh-10.0p1/cipher.c 2025-06-14 12:01:51.076334585 +0200 @@ -48,23 +48,39 @@ #include "sshbuf.h" #include "ssherr.h" @@ -5011,9 +5011,9 @@ diff -Nur openssh-9.9p1.orig/cipher.c openssh-9.9p1/cipher.c #endif freezero(cc, sizeof(*cc)); } -diff -Nur openssh-9.9p1.orig/cipher-chachapoly.c openssh-9.9p1/cipher-chachapoly.c ---- openssh-9.9p1.orig/cipher-chachapoly.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/cipher-chachapoly.c 2025-01-20 20:50:04.569813773 +0100 +diff -Nur openssh-10.0p1.orig/cipher-chachapoly.c openssh-10.0p1/cipher-chachapoly.c +--- openssh-10.0p1.orig/cipher-chachapoly.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/cipher-chachapoly.c 2025-06-14 10:54:01.307925846 +0200 @@ -88,7 +88,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5032,13 +5032,14 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly.c openssh-9.9p1/cipher-chachapoly poly_key); } r = 0; -diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher-chachapoly-libcrypto.c ---- openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/cipher-chachapoly-libcrypto.c 2025-01-20 21:59:09.157459134 +0100 -@@ -34,8 +34,17 @@ +diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/cipher-chachapoly-libcrypto.c +--- openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/cipher-chachapoly-libcrypto.c 2025-06-14 10:54:01.308400139 +0200 +@@ -34,8 +34,18 @@ #include "ssherr.h" #include "cipher-chachapoly.h" ++ +/* using the EVP_MAC interface for poly1305 is significantly + * faster than the version bundled with OpenSSH. However, + * this interface is only available in OpenSSL 3.0+ @@ -5053,7 +5054,7 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher- }; struct chachapoly_ctx * -@@ -56,6 +65,15 @@ +@@ -56,6 +66,15 @@ goto fail; if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16) goto fail; @@ -5069,7 +5070,7 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher- return ctx; fail: chachapoly_free(ctx); -@@ -69,6 +87,9 @@ +@@ -69,6 +88,9 @@ return; EVP_CIPHER_CTX_free(cpctx->main_evp); EVP_CIPHER_CTX_free(cpctx->header_evp); @@ -5079,7 +5080,7 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher- freezero(cpctx, sizeof(*cpctx)); } -@@ -107,7 +128,7 @@ +@@ -107,7 +129,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5088,7 +5089,7 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher- if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { r = SSH_ERR_MAC_INVALID; goto out; -@@ -133,7 +154,7 @@ +@@ -133,7 +155,7 @@ /* If encrypting, calculate and append tag */ if (do_encrypt) { @@ -5097,9 +5098,9 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher- poly_key); } r = 0; -diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c ---- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c 2025-01-20 20:50:04.570813776 +0100 +diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-10.0p1/cipher-chachapoly-libcrypto-mt.c +--- openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-chachapoly-libcrypto-mt.c 2025-06-14 10:54:01.309077322 +0200 @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5796,9 +5797,9 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.9p1/ciph +#endif +} +#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */ -diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h ---- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h 2025-01-20 20:50:04.571813779 +0100 +diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-10.0p1/cipher-chachapoly-libcrypto-mt.h +--- openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-chachapoly-libcrypto-mt.h 2025-06-14 10:54:01.309455724 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5845,9 +5846,9 @@ diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.9p1/ciph + __attribute__((__bounded__(__buffer__, 4, 5))); + +#endif /* CHACHA_POLY_LIBCRYPTO_MT_H */ -diff -Nur openssh-9.9p1.orig/cipher-ctr-mt.c openssh-9.9p1/cipher-ctr-mt.c ---- openssh-9.9p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-ctr-mt.c 2025-01-20 20:50:04.571813779 +0100 +diff -Nur openssh-10.0p1.orig/cipher-ctr-mt.c openssh-10.0p1/cipher-ctr-mt.c +--- openssh-10.0p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-ctr-mt.c 2025-06-14 10:54:01.309949084 +0200 @@ -0,0 +1,677 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -6526,9 +6527,9 @@ diff -Nur openssh-9.9p1.orig/cipher-ctr-mt.c openssh-9.9p1/cipher-ctr-mt.c + return aes_ctr; +} +#endif /* OSSL Check */ -diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.c openssh-9.9p1/cipher-ctr-mt-functions.c ---- openssh-9.9p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-ctr-mt-functions.c 2025-01-20 20:50:04.572813781 +0100 +diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.c openssh-10.0p1/cipher-ctr-mt-functions.c +--- openssh-10.0p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-ctr-mt-functions.c 2025-06-14 10:54:01.310535264 +0200 @@ -0,0 +1,668 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7198,9 +7199,9 @@ diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.c openssh-9.9p1/cipher-ctr- +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.h openssh-9.9p1/cipher-ctr-mt-functions.h ---- openssh-9.9p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-ctr-mt-functions.h 2025-01-20 20:50:04.572813781 +0100 +diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.h openssh-10.0p1/cipher-ctr-mt-functions.h +--- openssh-10.0p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-ctr-mt-functions.h 2025-06-14 10:54:01.310937760 +0200 @@ -0,0 +1,142 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7344,9 +7345,9 @@ diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.h openssh-9.9p1/cipher-ctr- + +#endif /* WITH OPENSSL */ +#endif /* CTR_MT_FUNCS */ -diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-provider.c openssh-9.9p1/cipher-ctr-mt-provider.c ---- openssh-9.9p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-ctr-mt-provider.c 2025-01-20 20:50:04.572813781 +0100 +diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-provider.c openssh-10.0p1/cipher-ctr-mt-provider.c +--- openssh-10.0p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-ctr-mt-provider.c 2025-06-14 10:54:01.311329711 +0200 @@ -0,0 +1,390 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7738,9 +7739,9 @@ diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-provider.c openssh-9.9p1/cipher-ctr-m +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-9.9p1.orig/cipher.h openssh-9.9p1/cipher.h ---- openssh-9.9p1.orig/cipher.h 2025-01-20 20:48:33.392582095 +0100 -+++ openssh-9.9p1/cipher.h 2025-01-20 20:59:21.957234646 +0100 +diff -Nur openssh-10.0p1.orig/cipher.h openssh-10.0p1/cipher.h +--- openssh-10.0p1.orig/cipher.h 2025-06-14 10:53:01.717078466 +0200 ++++ openssh-10.0p1/cipher.h 2025-06-14 13:45:10.880862884 +0200 @@ -42,11 +42,17 @@ #include #endif @@ -7797,9 +7798,9 @@ diff -Nur openssh-9.9p1.orig/cipher.h openssh-9.9p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-9.9p1.orig/cipher-switch.c openssh-9.9p1/cipher-switch.c ---- openssh-9.9p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-switch.c 2025-01-20 20:50:04.573813784 +0100 +diff -Nur openssh-10.0p1.orig/cipher-switch.c openssh-10.0p1/cipher-switch.c +--- openssh-10.0p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-switch.c 2025-06-14 10:54:01.312566045 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -7874,9 +7875,9 @@ diff -Nur openssh-9.9p1.orig/cipher-switch.c openssh-9.9p1/cipher-switch.c + } +#endif +} -diff -Nur openssh-9.9p1.orig/cipher-switch.h openssh-9.9p1/cipher-switch.h ---- openssh-9.9p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/cipher-switch.h 2025-01-20 20:50:04.574813786 +0100 +diff -Nur openssh-10.0p1.orig/cipher-switch.h openssh-10.0p1/cipher-switch.h +--- openssh-10.0p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/cipher-switch.h 2025-06-14 10:54:01.312822014 +0200 @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 The Board of Trustees of Carnegie Mellon University. @@ -7896,9 +7897,9 @@ diff -Nur openssh-9.9p1.orig/cipher-switch.h openssh-9.9p1/cipher-switch.h + */ + +void cipher_switch (struct ssh *); -diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c ---- openssh-9.9p1.orig/clientloop.c 2025-01-20 20:48:33.290581837 +0100 -+++ openssh-9.9p1/clientloop.c 2025-01-20 20:50:04.575813789 +0100 +diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c +--- openssh-10.0p1.orig/clientloop.c 2025-06-14 10:53:01.223339310 +0200 ++++ openssh-10.0p1/clientloop.c 2025-06-14 10:54:01.313407565 +0200 @@ -114,6 +114,7 @@ #include "msg.h" #include "ssherr.h" @@ -7927,7 +7928,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c static void quit_message(const char *fmt, ...) __attribute__((__format__ (printf, 1, 2))); -@@ -1452,6 +1459,7 @@ +@@ -1453,6 +1460,7 @@ double start_time, total_time; int channel_did_enqueue = 0, r; u_int64_t ibytes, obytes; @@ -7935,7 +7936,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c int conn_in_ready, conn_out_ready; sigset_t bsigset, osigset; -@@ -1493,6 +1501,7 @@ +@@ -1494,6 +1502,7 @@ client_repledge(); start_time = monotime_double(); @@ -7943,7 +7944,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c /* Initialize variables. */ last_was_cr = 1; -@@ -1534,6 +1543,8 @@ +@@ -1535,6 +1544,8 @@ } schedule_server_alive_check(); @@ -7952,7 +7953,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGHUP) == -1 || -@@ -1544,6 +1555,12 @@ +@@ -1545,6 +1556,12 @@ /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { @@ -7965,7 +7966,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c channel_did_enqueue = 0; /* Process buffered packets sent by the server. */ -@@ -1636,6 +1653,10 @@ +@@ -1637,6 +1654,10 @@ } } } @@ -7976,7 +7977,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c free(pfd); /* Terminate the session. */ -@@ -2647,6 +2668,167 @@ +@@ -2648,6 +2669,167 @@ return 1; } @@ -8144,7 +8145,7 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c static int client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) { -@@ -2772,6 +2954,43 @@ +@@ -2773,6 +2955,43 @@ len = sshbuf_len(cmd); if (len > 0) { @@ -8188,9 +8189,9 @@ diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c if (len > 900) len = 900; if (want_subsystem) { -diff -Nur openssh-9.9p1.orig/compat.c openssh-9.9p1/compat.c ---- openssh-9.9p1.orig/compat.c 2025-01-20 20:48:33.422582171 +0100 -+++ openssh-9.9p1/compat.c 2025-01-20 22:39:30.315877553 +0100 +diff -Nur openssh-10.0p1.orig/compat.c openssh-10.0p1/compat.c +--- openssh-10.0p1.orig/compat.c 2025-06-14 10:53:01.849953032 +0200 ++++ openssh-10.0p1/compat.c 2025-06-14 12:24:07.747714342 +0200 @@ -135,6 +135,35 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) @@ -8227,10 +8228,10 @@ diff -Nur openssh-9.9p1.orig/compat.c openssh-9.9p1/compat.c return; } } -diff -Nur openssh-9.9p1.orig/compat.h openssh-9.9p1/compat.h ---- openssh-9.9p1.orig/compat.h 2025-01-20 20:48:33.423582174 +0100 -+++ openssh-9.9p1/compat.h 2025-01-20 22:36:35.778448062 +0100 -@@ -46,12 +46,12 @@ +diff -Nur openssh-10.0p1.orig/compat.h openssh-10.0p1/compat.h +--- openssh-10.0p1.orig/compat.h 2025-06-14 10:53:01.850139160 +0200 ++++ openssh-10.0p1/compat.h 2025-06-14 12:25:55.470697341 +0200 +@@ -46,17 +46,18 @@ /* #define unused 0x00010000 */ /* #define unused 0x00020000 */ /* #define unused 0x00040000 */ @@ -8246,10 +8247,56 @@ diff -Nur openssh-9.9p1.orig/compat.h openssh-9.9p1/compat.h #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 -diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac ---- openssh-9.9p1.orig/configure.ac 2025-01-20 20:48:33.447582234 +0100 -+++ openssh-9.9p1/configure.ac 2025-01-20 20:50:04.577813794 +0100 -@@ -2945,8 +2945,8 @@ + #define SSH_BUG_HOSTKEYS 0x20000000 + #define SSH_BUG_DHGEX_LARGE 0x40000000 ++/* #define unused 0x80000000 */ + + struct ssh; + +diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac +--- openssh-10.0p1.orig/configure.ac 2025-06-14 10:53:02.015907743 +0200 ++++ openssh-10.0p1/configure.ac 2025-06-14 10:54:01.316233073 +0200 +@@ -2621,6 +2621,39 @@ + ) + fi + ++ ++# Testing MPTCP Support ++# Does the OS support MPTCP? ++# We don't use this at the moment ++# but I am holding it in resrve -cjr 04/04/2025 ++ AC_MSG_CHECKING([whether the OS supports MPTCP]) ++ AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM([[ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ ]], [[ ++ int sock = -1; ++ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); ++ if (sock < 0) { ++ exit(1); ++ } ++ ]])], ++ [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE([HAVE_MPTCP], [1], ++ [OS Supports MPTCP]) ++ ], ++ [ ++ AC_MSG_RESULT([no]) ++ ] ++ ) ++ + if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ + test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then + AC_MSG_CHECKING([if getaddrinfo seems to work]) +@@ -3029,8 +3062,8 @@ 200*) # LibreSSL lver=`echo "$sslver" | sed 's/.*libressl-//'` case "$lver" in @@ -8260,7 +8307,7 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac ;; *) ;; # Assume all other versions are good. esac -@@ -2955,6 +2955,7 @@ +@@ -3039,6 +3072,7 @@ # OpenSSL 3; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" @@ -8268,7 +8315,7 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac ;; *) AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_showver")]) -@@ -3074,6 +3075,30 @@ +@@ -3158,6 +3192,29 @@ EVP_CIPHER_CTX_set_iv \ ]) @@ -8294,26 +8341,42 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac + AC_MSG_RESULT([no]) + ] + ) -+ + if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -diff -Nur openssh-9.9p1.orig/defines.h openssh-9.9p1/defines.h ---- openssh-9.9p1.orig/defines.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/defines.h 2025-01-20 20:50:04.578813797 +0100 -@@ -889,7 +889,7 @@ +diff -Nur openssh-10.0p1.orig/defines.h openssh-10.0p1/defines.h +--- openssh-10.0p1.orig/defines.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/defines.h 2025-06-14 10:54:01.317208898 +0200 +@@ -931,7 +931,11 @@ #endif #ifndef SSH_IOBUFSZ -# define SSH_IOBUFSZ 8192 +# define SSH_IOBUFSZ (32*1024) ++#endif ++ ++#ifndef IPPROTO_MPTCP ++#define IPPROTO_MPTCP 262 #endif /* -diff -Nur openssh-9.9p1.orig/digest.h openssh-9.9p1/digest.h ---- openssh-9.9p1.orig/digest.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/digest.h 2025-01-20 20:50:04.578813797 +0100 +@@ -987,3 +991,12 @@ + # define USE_MLKEM768X25519 1 + #endif + #endif /* _DEFINES_H */ ++ ++/* used to enable checking linux kernel versions */ ++#if defined(__linux__) && !defined(__alpine__) ++#include ++#endif ++ ++#ifndef KERNEL_VERSION /* shouldn't be necessary to define this */ ++#define KERNEL_VERSION(a,b,c) (((a) <<16) + ((b) << 8) +(c)) ++#endif +diff -Nur openssh-10.0p1.orig/digest.h openssh-10.0p1/digest.h +--- openssh-10.0p1.orig/digest.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/digest.h 2025-06-14 10:54:01.317584436 +0200 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -8324,9 +8387,9 @@ diff -Nur openssh-9.9p1.orig/digest.h openssh-9.9p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-9.9p1.orig/digest-openssl.c openssh-9.9p1/digest-openssl.c ---- openssh-9.9p1.orig/digest-openssl.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/digest-openssl.c 2025-01-20 20:50:04.578813797 +0100 +diff -Nur openssh-10.0p1.orig/digest-openssl.c openssh-10.0p1/digest-openssl.c +--- openssh-10.0p1.orig/digest-openssl.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/digest-openssl.c 2025-06-14 10:54:01.317859402 +0200 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -8335,9 +8398,9 @@ diff -Nur openssh-9.9p1.orig/digest-openssl.c openssh-9.9p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-9.9p1.orig/FUNDING.yml openssh-9.9p1/FUNDING.yml ---- openssh-9.9p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/FUNDING.yml 2025-01-20 20:50:04.578813797 +0100 +diff -Nur openssh-10.0p1.orig/FUNDING.yml openssh-10.0p1/FUNDING.yml +--- openssh-10.0p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/FUNDING.yml 2025-06-14 10:54:01.318133600 +0200 @@ -0,0 +1,12 @@ +# These are supported funding model platforms + @@ -8351,12 +8414,22 @@ diff -Nur openssh-9.9p1.orig/FUNDING.yml openssh-9.9p1/FUNDING.yml +#issuehunt: # Replace with a single IssueHunt username +#otechie: # Replace with a single Otechie username +#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -diff -Nur openssh-9.9p1.orig/HPN-README openssh-9.9p1/HPN-README ---- openssh-9.9p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/HPN-README 2025-01-20 20:50:04.578813797 +0100 -@@ -0,0 +1,170 @@ +diff -Nur openssh-10.0p1.orig/HPN-README openssh-10.0p1/HPN-README +--- openssh-10.0p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/HPN-README 2025-06-14 10:54:01.318366032 +0200 +@@ -0,0 +1,180 @@ +Notes: + ++MPTCP Support in 18.7.0: ++Multipath TCP is now available as a runtime option for HPN-SSH. MPTCP ++is available only on Linux and Mac OSX operating systems. Using MPTCP on a system that ++doesn't support it will result in a notice and failure. The use cases for MPTCP include ++seamless handovers when changing networks and aggregating multiple interfaces to improve ++available bandwidth. As of 18.7.0 this options should be considered somewhat experimental. ++ ++Usage: ++-oUseMPTCP=[Yes|No] will enable MPTCP. The default is no. ++ +LibreSSL Support: +Changes in LibreSSL version 3.5 and 3.6 prevent the use of the threaded AES CTR cipher. +In those cases HPNSSH will fallback to the serial version of the AES CTR cipher. A warning @@ -8525,9 +8598,9 @@ diff -Nur openssh-9.9p1.orig/HPN-README openssh-9.9p1/HPN-README + + +Edited: October 11, 2023 -diff -Nur openssh-9.9p1.orig/HPNSSHInstallation.txt openssh-9.9p1/HPNSSHInstallation.txt ---- openssh-9.9p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/HPNSSHInstallation.txt 2025-01-20 20:50:04.579813799 +0100 +diff -Nur openssh-10.0p1.orig/HPNSSHInstallation.txt openssh-10.0p1/HPNSSHInstallation.txt +--- openssh-10.0p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/HPNSSHInstallation.txt 2025-06-14 10:54:01.318659925 +0200 @@ -0,0 +1,354 @@ +HPN-SSH Installation + @@ -8883,9 +8956,9 @@ diff -Nur openssh-9.9p1.orig/HPNSSHInstallation.txt openssh-9.9p1/HPNSSHInstalla +restorecon /usr/bin/hpnssh-agent +restorecon /usr/bin/hpnssh-keygen +restorecon /etc/pam.d/hpnsshd -diff -Nur openssh-9.9p1.orig/kex.c openssh-9.9p1/kex.c ---- openssh-9.9p1.orig/kex.c 2025-01-20 20:48:33.420582166 +0100 -+++ openssh-9.9p1/kex.c 2025-01-20 20:50:04.579813799 +0100 +diff -Nur openssh-10.0p1.orig/kex.c openssh-10.0p1/kex.c +--- openssh-10.0p1.orig/kex.c 2025-06-14 10:53:01.833082539 +0200 ++++ openssh-10.0p1/kex.c 2025-06-14 10:54:01.319010460 +0200 @@ -67,6 +67,7 @@ #include "ssherr.h" @@ -9103,9 +9176,32 @@ diff -Nur openssh-9.9p1.orig/kex.c openssh-9.9p1/kex.c mismatch = 0; switch (remote_major) { -diff -Nur openssh-9.9p1.orig/mac.c openssh-9.9p1/mac.c ---- openssh-9.9p1.orig/mac.c 2025-01-20 20:48:33.394582100 +0100 -+++ openssh-9.9p1/mac.c 2025-01-20 20:50:04.580813802 +0100 +diff -Nur openssh-10.0p1.orig/log.c openssh-10.0p1/log.c +--- openssh-10.0p1.orig/log.c 2025-06-14 10:53:01.364646329 +0200 ++++ openssh-10.0p1/log.c 2025-06-14 10:54:01.319781160 +0200 +@@ -48,6 +48,10 @@ + #include + #include + #include ++#include "packet.h" /* needed for host and port look ups */ ++#ifdef HAVE_SYS_TIME_H ++# include /* to get current time */ ++#endif + #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) + # include + #endif +@@ -67,6 +71,8 @@ + + extern char *__progname; + ++extern struct ssh *active_state; ++ + #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) + #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) + +diff -Nur openssh-10.0p1.orig/mac.c openssh-10.0p1/mac.c +--- openssh-10.0p1.orig/mac.c 2025-06-14 10:53:01.717727014 +0200 ++++ openssh-10.0p1/mac.c 2025-06-14 10:54:01.320122336 +0200 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -9114,10 +9210,10 @@ diff -Nur openssh-9.9p1.orig/mac.c openssh-9.9p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in ---- openssh-9.9p1.orig/Makefile.in 2025-01-20 20:48:33.449582239 +0100 -+++ openssh-9.9p1/Makefile.in 2025-01-20 21:02:30.432714955 +0100 -@@ -51,7 +51,7 @@ +diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in +--- openssh-10.0p1.orig/Makefile.in 2025-06-14 14:54:57.417594122 +0200 ++++ openssh-10.0p1/Makefile.in 2025-06-14 14:54:42.451734455 +0200 +@@ -53,7 +53,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ @@ -9126,7 +9222,7 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ -@@ -99,7 +99,7 @@ +@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ @@ -9135,7 +9231,7 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -@@ -109,6 +109,7 @@ +@@ -112,6 +112,7 @@ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ @@ -9143,7 +9239,7 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ -@@ -116,12 +117,13 @@ +@@ -119,12 +120,13 @@ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ @@ -9160,16 +9256,25 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in SSHDOBJS=sshd.o \ platform-listen.o \ @@ -143,7 +145,7 @@ + auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ -- sandbox-solaris.o uidswap.o $(SKOBJS) -+ sandbox-solaris.o uidswap.o cipher-switch.o $(SKOBJS) +- uidswap.o platform-listen.o $(SKOBJS) ++ uidswap.o platform-listen.o cipher-switch.o $(SKOBJS) + + SSHD_AUTH_OBJS=sshd-auth.o \ + auth2-methods.o \ +@@ -158,7 +160,7 @@ + sandbox-null.o sandbox-rlimit.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \ + sftp-server.o sftp-common.o \ +- uidswap.o $(SKOBJS) ++ uidswap.o cipher-switch.o $(SKOBJS) SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o -@@ -225,7 +227,7 @@ - $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) +@@ -243,7 +245,7 @@ + $(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) - $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -9177,10 +9282,10 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) -diff -Nur openssh-9.9p1.orig/metrics.c openssh-9.9p1/metrics.c ---- openssh-9.9p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/metrics.c 2025-01-20 20:50:04.581813804 +0100 -@@ -0,0 +1,444 @@ +diff -Nur openssh-10.0p1.orig/metrics.c openssh-10.0p1/metrics.c +--- openssh-10.0p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/metrics.c 2025-06-14 10:54:01.321376410 +0200 +@@ -0,0 +1,439 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. + * @@ -9203,13 +9308,8 @@ diff -Nur openssh-9.9p1.orig/metrics.c openssh-9.9p1/metrics.c +#include "ssherr.h" +#include +#include -+#if defined(__linux__) && !defined(__alpine__) -+#include -+#endif + -+#ifndef KERNEL_VERSION /* shouldn't be necessary to define this */ -+#define KERNEL_VERSION(a,b,c) (((a) <<16) + ((b) << 8) +(c)) -+#endif ++/* kernel version macro moved to defines.h */ + +/* add the information from the tcp_info struct to the + * serialized binary object @@ -9625,9 +9725,9 @@ diff -Nur openssh-9.9p1.orig/metrics.c openssh-9.9p1/metrics.c +#endif /* ifdef __linux__ */ + fprintf(fptr, "\n\n"); +} -diff -Nur openssh-9.9p1.orig/metrics.h openssh-9.9p1/metrics.h ---- openssh-9.9p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/metrics.h 2025-01-20 20:50:04.581813804 +0100 +diff -Nur openssh-10.0p1.orig/metrics.h openssh-10.0p1/metrics.h +--- openssh-10.0p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/metrics.h 2025-06-14 10:54:01.321618830 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9674,9 +9774,9 @@ diff -Nur openssh-9.9p1.orig/metrics.h openssh-9.9p1/metrics.h + + +#endif /* define metrics_h */ -diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c ---- openssh-9.9p1.orig/misc.c 2025-01-20 20:48:33.449582239 +0100 -+++ openssh-9.9p1/misc.c 2025-01-20 20:50:04.582813807 +0100 +diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c +--- openssh-10.0p1.orig/misc.c 2025-06-14 10:53:02.019076801 +0200 ++++ openssh-10.0p1/misc.c 2025-06-14 10:54:01.321922850 +0200 @@ -77,6 +77,29 @@ #include "ssherr.h" #include "platform.h" @@ -9707,7 +9807,7 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c /* remove newline at end of string */ char * chop(char *s) -@@ -1649,20 +1672,6 @@ +@@ -1670,20 +1693,6 @@ return (v); } @@ -9728,7 +9828,7 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c u_int16_t get_u16(const void *vp) { -@@ -1702,17 +1711,6 @@ +@@ -1723,17 +1732,6 @@ } void @@ -9746,10 +9846,10 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c put_u16(void *vp, u_int16_t v) { u_char *p = (u_char *)vp; -diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h ---- openssh-9.9p1.orig/misc.h 2025-01-20 20:48:33.450582242 +0100 -+++ openssh-9.9p1/misc.h 2025-01-20 20:50:04.582813807 +0100 -@@ -166,12 +166,6 @@ +diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h +--- openssh-10.0p1.orig/misc.h 2025-06-14 10:53:02.019622613 +0200 ++++ openssh-10.0p1/misc.h 2025-06-14 10:54:01.322621684 +0200 +@@ -167,12 +167,6 @@ void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); @@ -9762,7 +9862,7 @@ diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h struct bwlimit { size_t buflen; u_int64_t rate; /* desired rate in kbit/s */ -@@ -258,4 +252,16 @@ +@@ -259,4 +253,16 @@ /* On OpenBSD time_t is int64_t which is long long. */ /* #define SSH_TIME_T_MAX LLONG_MAX */ @@ -9779,22 +9879,20 @@ diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h +void read_mem_stats(struct statm_t *, int); + #endif /* _MISC_H */ -diff -Nur openssh-9.9p1.orig/myproposal.h openssh-9.9p1/myproposal.h ---- openssh-9.9p1.orig/myproposal.h 2025-01-20 20:48:33.407582133 +0100 -+++ openssh-9.9p1/myproposal.h 2025-01-20 20:50:04.583813809 +0100 -@@ -71,7 +71,8 @@ +diff -Nur openssh-10.0p1.orig/myproposal.h openssh-10.0p1/myproposal.h +--- openssh-10.0p1.orig/myproposal.h 2025-06-14 10:53:01.775906378 +0200 ++++ openssh-10.0p1/myproposal.h 2025-06-14 10:54:01.323105546 +0200 +@@ -71,6 +71,7 @@ "rsa-sha2-256" #define KEX_SERVER_ENCRYPT \ -- "chacha20-poly1305@openssh.com," \ + "chacha20-poly1305-mt@hpnssh.org," \ -+ "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com" - -diff -Nur openssh-9.9p1.orig/num.c openssh-9.9p1/num.c ---- openssh-9.9p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/num.c 2025-01-20 20:50:04.583813809 +0100 + "chacha20-poly1305@openssh.com," \ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr" +diff -Nur openssh-10.0p1.orig/num.c openssh-10.0p1/num.c +--- openssh-10.0p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/num.c 2025-06-14 10:54:01.323584938 +0200 @@ -0,0 +1,156 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9952,9 +10050,9 @@ diff -Nur openssh-9.9p1.orig/num.c openssh-9.9p1/num.c +implement_provnum(size_t, OSSL_PARAM_UNSIGNED_INTEGER) + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.9p1.orig/num.h openssh-9.9p1/num.h ---- openssh-9.9p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/num.h 2025-01-20 20:50:04.584813812 +0100 +diff -Nur openssh-10.0p1.orig/num.h openssh-10.0p1/num.h +--- openssh-10.0p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/num.h 2025-06-14 10:54:01.323769040 +0200 @@ -0,0 +1,15 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -9971,9 +10069,9 @@ diff -Nur openssh-9.9p1.orig/num.h openssh-9.9p1/num.h +#define PROVNUM_E_TOOBIG -2 +#define PROVNUM_E_UNSUPPORTED -3 +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.9p1.orig/ossl3-provider-err.c openssh-9.9p1/ossl3-provider-err.c ---- openssh-9.9p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/ossl3-provider-err.c 2025-01-20 20:50:04.584813812 +0100 +diff -Nur openssh-10.0p1.orig/ossl3-provider-err.c openssh-10.0p1/ossl3-provider-err.c +--- openssh-10.0p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/ossl3-provider-err.c 2025-06-14 10:54:01.323964806 +0200 @@ -0,0 +1,108 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10083,9 +10181,9 @@ diff -Nur openssh-9.9p1.orig/ossl3-provider-err.c openssh-9.9p1/ossl3-provider-e +} + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.9p1.orig/ossl3-provider-err.h openssh-9.9p1/ossl3-provider-err.h ---- openssh-9.9p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/ossl3-provider-err.h 2025-01-20 20:50:04.584813812 +0100 +diff -Nur openssh-10.0p1.orig/ossl3-provider-err.h openssh-10.0p1/ossl3-provider-err.h +--- openssh-10.0p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/ossl3-provider-err.h 2025-06-14 10:54:01.324153727 +0200 @@ -0,0 +1,73 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10160,9 +10258,9 @@ diff -Nur openssh-9.9p1.orig/ossl3-provider-err.h openssh-9.9p1/ossl3-provider-e +void proverr_set_error(const struct proverr_functions_st *handle, + uint32_t reason, const char *fmt, ...); +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c ---- openssh-9.9p1.orig/packet.c 2025-01-20 20:48:33.396582105 +0100 -+++ openssh-9.9p1/packet.c 2025-01-20 20:50:04.585813814 +0100 +diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c +--- openssh-10.0p1.orig/packet.c 2025-06-14 10:53:01.719334626 +0200 ++++ openssh-10.0p1/packet.c 2025-06-14 10:54:01.324483728 +0200 @@ -63,6 +63,9 @@ #endif #include @@ -10308,20 +10406,17 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c - *max_blocks = (u_int64_t)1 << (enc->block_size*2); - else - *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; -- if (state->rekey_limit) -- *max_blocks = MINIMUM(*max_blocks, -- state->rekey_limit / enc->block_size); -- debug("rekey %s after %llu blocks", dir, -- (unsigned long long)*max_blocks); + + /* get the maximum number of blocks the cipher can + * handle safely */ + *max_blocks = cipher_rekey_blocks(enc->cipher); + + /* if we have a custom oRekeyLimit use that. */ -+ if (state->rekey_limit) -+ *max_blocks = MINIMUM(*max_blocks, -+ state->rekey_limit / enc->block_size); + if (state->rekey_limit) + *max_blocks = MINIMUM(*max_blocks, + state->rekey_limit / enc->block_size); +- debug("rekey %s after %llu blocks", dir, +- (unsigned long long)*max_blocks); + + /* these lines support the debug */ + strlcpy(blocks_s, "?", sizeof(blocks_s)); @@ -10370,17 +10465,6 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c /* Time-based rekeying */ if (state->rekey_interval != 0 && (int64_t)state->rekey_time + state->rekey_interval <= monotime()) -@@ -1293,8 +1373,8 @@ - sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) - goto out; - if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp, -- sshbuf_ptr(state->outgoing_packet), -- len - aadlen, aadlen, authlen)) != 0) -+ sshbuf_ptr(state->outgoing_packet), len - aadlen, aadlen, authlen)) -+ != 0) - goto out; - /* append unencrypted MAC */ - if (mac && mac->enabled) { @@ -1445,7 +1525,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain = 0; @@ -10449,7 +10533,7 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c } /* Remove MAC from input buffer */ DBG(debug("MAC #%d ok", state->p_read.seqnr)); -@@ -1930,7 +2010,7 @@ +@@ -1938,7 +2018,7 @@ int r; size_t rlen; @@ -10458,7 +10542,7 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c return r; if (state->packet_discard) { -@@ -2009,17 +2089,21 @@ +@@ -2017,17 +2097,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -10480,7 +10564,7 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -2061,6 +2145,24 @@ +@@ -2069,6 +2153,24 @@ logdie_f("should have exited"); } @@ -10505,7 +10589,7 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -2315,10 +2417,19 @@ +@@ -2323,10 +2425,19 @@ ssh->kex->server = 1; /* XXX unify? */ } @@ -10525,7 +10609,7 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c } void * -@@ -2941,3 +3052,17 @@ +@@ -2949,3 +3060,17 @@ ssh->state->extra_pad = pad; return 0; } @@ -10543,9 +10627,9 @@ diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c +{ + return ssh->state->receive_context; +} -diff -Nur openssh-9.9p1.orig/packet.h openssh-9.9p1/packet.h ---- openssh-9.9p1.orig/packet.h 2025-01-20 20:48:33.397582108 +0100 -+++ openssh-9.9p1/packet.h 2025-01-20 20:50:04.585813814 +0100 +diff -Nur openssh-10.0p1.orig/packet.h openssh-10.0p1/packet.h +--- openssh-10.0p1.orig/packet.h 2025-06-14 10:53:01.719644792 +0200 ++++ openssh-10.0p1/packet.h 2025-06-14 10:54:01.325502017 +0200 @@ -88,6 +88,17 @@ /* APP data */ @@ -10587,9 +10671,9 @@ diff -Nur openssh-9.9p1.orig/packet.h openssh-9.9p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-9.9p1.orig/poly1305.c openssh-9.9p1/poly1305.c ---- openssh-9.9p1.orig/poly1305.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/poly1305.c 2025-01-20 20:50:04.586813817 +0100 +diff -Nur openssh-10.0p1.orig/poly1305.c openssh-10.0p1/poly1305.c +--- openssh-10.0p1.orig/poly1305.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/poly1305.c 2025-06-14 10:54:01.325842914 +0200 @@ -13,6 +13,16 @@ #include "poly1305.h" @@ -10621,9 +10705,9 @@ diff -Nur openssh-9.9p1.orig/poly1305.c openssh-9.9p1/poly1305.c U32TO8_LE(&out[12], f3); } +#endif /* OPENSSL_HAVE_POLY_EVP */ -diff -Nur openssh-9.9p1.orig/poly1305.h openssh-9.9p1/poly1305.h ---- openssh-9.9p1.orig/poly1305.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/poly1305.h 2025-01-20 20:50:04.586813817 +0100 +diff -Nur openssh-10.0p1.orig/poly1305.h openssh-10.0p1/poly1305.h +--- openssh-10.0p1.orig/poly1305.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/poly1305.h 2025-06-14 10:54:01.326132826 +0200 @@ -13,8 +13,15 @@ #define POLY1305_KEYLEN 32 #define POLY1305_TAGLEN 16 @@ -10641,10 +10725,10 @@ diff -Nur openssh-9.9p1.orig/poly1305.h openssh-9.9p1/poly1305.h __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); -diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c ---- openssh-9.9p1.orig/progressmeter.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/progressmeter.c 2025-01-20 20:50:04.586813817 +0100 -@@ -66,6 +66,8 @@ +diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c +--- openssh-10.0p1.orig/progressmeter.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/progressmeter.c 2025-06-14 10:54:01.326416661 +0200 +@@ -65,6 +65,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ @@ -10653,7 +10737,7 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c static volatile off_t *counter; /* progress counter */ static long stalled; /* how long we have been stalled */ static int bytes_per_second; /* current speed in bytes per second */ -@@ -132,6 +134,7 @@ +@@ -131,6 +133,7 @@ int cur_speed; int hours, minutes, seconds; int file_len, cols; @@ -10661,7 +10745,7 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c if ((!force_update && !alarm_fired && !win_resized) || !can_output()) return; -@@ -147,6 +150,10 @@ +@@ -146,6 +149,10 @@ now = monotime_double(); bytes_left = end_pos - cur_pos; @@ -10672,7 +10756,7 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c if (bytes_left > 0) elapsed = now - last_update; else { -@@ -176,7 +183,7 @@ +@@ -175,7 +182,7 @@ return; /* filename */ @@ -10681,7 +10765,7 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c if (file_len > 0) { asmprintf(&buf, INT_MAX, &cols, "%-*s", file_len, file); /* If we used fewer columns than expected then pad */ -@@ -193,6 +200,12 @@ +@@ -192,6 +199,12 @@ xextendf(&buf, NULL, " %3d%% %s %s/s ", percent, format_size(cur_pos), format_rate((off_t)bytes_per_second)); @@ -10694,7 +10778,7 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c /* ETA */ if (!transferred) stalled += elapsed; -@@ -235,6 +248,7 @@ +@@ -234,6 +247,7 @@ } free(buf); free(obuf); @@ -10702,35 +10786,36 @@ diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c } static void -diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c ---- openssh-9.9p1.orig/readconf.c 2025-01-20 20:48:33.452582247 +0100 -+++ openssh-9.9p1/readconf.c 2025-01-20 21:03:08.963813150 +0100 -@@ -72,6 +72,7 @@ +diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c +--- openssh-10.0p1.orig/readconf.c 2025-06-14 10:53:02.021809909 +0200 ++++ openssh-10.0p1/readconf.c 2025-06-14 10:54:01.327045863 +0200 +@@ -71,6 +71,7 @@ + #include "uidswap.h" #include "myproposal.h" #include "digest.h" - #include "ssh-gss.h" +#include "sshbuf.h" + #include "version.h" + #include "ssh-gss.h" - /* Format of the configuration file: - -@@ -173,6 +174,10 @@ +@@ -174,6 +175,10 @@ oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oRemoteCommand, + oTcpRcvBufPoll, oHPNDisabled, + oNoneEnabled, oNoneMacEnabled, oNoneSwitch, -+ oDisableMTAES, ++ oDisableMTAES, oUseMPTCP, + oMetrics, oMetricsPath, oMetricsInterval, oFallback, oFallbackPort, oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, -@@ -319,6 +324,15 @@ +@@ -321,6 +326,16 @@ { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, + { "noneenabled", oNoneEnabled }, + { "nonemacenabled", oNoneMacEnabled }, + { "noneswitch", oNoneSwitch }, ++ { "usemptcp", oUseMPTCP}, + { "disablemtaes", oDisableMTAES }, + { "metrics", oMetrics }, + { "metricspath", oMetricsPath }, @@ -10740,7 +10825,7 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c { "sessiontype", oSessionType }, { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, -@@ -341,6 +355,8 @@ +@@ -343,6 +358,8 @@ { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, @@ -10749,7 +10834,7 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c { "requiredrsasize", oRequiredRSASize }, { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, -@@ -539,7 +555,7 @@ +@@ -542,7 +559,7 @@ if (port == 0) { sp = getservbyname(SSH_SERVICE_NAME, "tcp"); @@ -10758,7 +10843,7 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c } return port; } -@@ -1317,6 +1333,63 @@ +@@ -1381,6 +1398,67 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -10778,6 +10863,10 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c + intptr = &options->nonemac_enabled; + goto parse_flag; + ++ case oUseMPTCP: ++ intptr = &options->use_mptcp; ++ goto parse_flag; ++ + case oDisableMTAES: + intptr = &options->disable_multithreaded; + goto parse_flag; @@ -10822,13 +10911,14 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -2712,6 +2785,17 @@ +@@ -2798,6 +2876,18 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; + options->none_switch = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; ++ options->use_mptcp = -1; + options->disable_multithreaded = -1; + options->metrics = -1; + options->metrics_path = NULL; @@ -10840,7 +10930,7 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2895,8 +2979,37 @@ +@@ -2982,8 +3072,39 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -10863,6 +10953,8 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c + fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); + options->nonemac_enabled = 0; + } ++ if (options->use_mptcp == -1) ++ options->use_mptcp = 0; + if (options->disable_multithreaded == -1) + options->disable_multithreaded = 0; + if (options->metrics == -1) @@ -10878,23 +10970,49 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c if (options->control_persist == -1) { options->control_persist = 0; options->control_persist_timeout = 0; -diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h ---- openssh-9.9p1.orig/readconf.h 2025-01-20 20:48:33.452582247 +0100 -+++ openssh-9.9p1/readconf.h 2025-01-21 07:26:17.608445051 +0100 -@@ -56,6 +56,8 @@ - int strict_host_key_checking; /* Strict host key checking. */ - int compression; /* Compress packets in both directions. */ - int tcp_keep_alive; /* Set SO_KEEPALIVE. */ -+ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ -+ int hpn_disabled; /* Switch to disable HPN buffer management */ - int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ - int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ - SyslogFacility log_facility; /* Facility for system logging. */ -@@ -129,6 +131,17 @@ +@@ -3757,6 +3878,14 @@ + dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); + dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); + dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline); ++ dump_cfg_fmtint(oTcpRcvBufPoll, o->tcp_rcv_buf_poll); ++ dump_cfg_fmtint(oHPNDisabled, o->hpn_disabled); ++ dump_cfg_fmtint(oNoneSwitch, o->none_switch); ++ dump_cfg_fmtint(oNoneEnabled, o->none_enabled); ++ dump_cfg_fmtint(oNoneMacEnabled, o->nonemac_enabled); ++ dump_cfg_fmtint(oFallback, o->fallback); ++ dump_cfg_fmtint(oMetrics, o->metrics); ++ + + /* Integer options */ + dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); +@@ -3768,6 +3897,8 @@ + dump_cfg_int(oRequiredRSASize, o->required_rsa_size); + dump_cfg_int(oObscureKeystrokeTiming, + o->obscure_keystroke_timing_interval); ++ dump_cfg_int(oMetricsInterval, o->metrics_interval); ++ dump_cfg_int(oFallbackPort, o->fallback_port); + + /* String options */ + dump_cfg_string(oBindAddress, o->bind_address); +@@ -3796,6 +3927,7 @@ + dump_cfg_string(oXAuthLocation, o->xauth_location); + dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); + dump_cfg_string(oTag, o->tag); ++ dump_cfg_string(oMetricsPath, o->metrics_path); + dump_cfg_string(oVersionAddendum, o->version_addendum); + + /* Forwards */ +diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h +--- openssh-10.0p1.orig/readconf.h 2025-06-14 10:53:02.022395739 +0200 ++++ openssh-10.0p1/readconf.h 2025-06-14 10:54:01.328092159 +0200 +@@ -128,6 +128,21 @@ int enable_ssh_keysign; int64_t rekey_limit; int rekey_interval; + ++ /* hpnssh options */ ++ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ ++ int hpn_disabled; /* Switch to disable HPN buffer management */ + int none_switch; /* Use none cipher */ + int none_enabled; /* Allow none to be used */ + int nonemac_enabled; /* Allow none to be used */ @@ -10904,26 +11022,29 @@ diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h + char *metrics_path; /* path for the metrics files */ + int fallback; /* en|disable fallback port (def: true) */ + int fallback_port; /* port to fallback to (def: 22) */ ++ int use_mptcp; + int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ---- openssh-9.9p1.orig/README.md 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/README.md 2025-01-20 20:50:04.588813822 +0100 -@@ -1,12 +1,16 @@ +diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md +--- openssh-10.0p1.orig/README.md 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/README.md 2025-06-14 10:54:01.328596415 +0200 +@@ -1,16 +1,22 @@ -# Portable OpenSSH +# HPNSSH: Based on Portable OpenSSH -[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh) -[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) -+Starting with version HPN17v0 there will be significant changes to the naming convention used for executables and installation locations. The last version that does not include these changes is HPN16v1 corresponding to the HPN-8_8_P1 tag on the master branch. ++HPN-SSH is a high performance soft fork of OpenSSH that can provide significnatly faster throughput for bulk data transfers over a wide range of network paths. In some situations we've seen throughput rates more than 100 times faster than OpenSSH. HPN-SSH is able to do this by optimizing the application layer receive buffer to match the TCP receive buffer. Notably, to see performance improvements HPN-SSH only needs to be the data receiver so users can see notable improvements with many other SSH implementations. HPN-SSH also incorporate two parallelized ciphers, AES-CTR and Chacha20 (the default). When using these ciphers a throughput performance increase of 30% is typical. More information on how we do this work and other features of HPN-SSH is available from [https://hpnssh.org](https://hpnssh.org). -OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs. -+HPNSSH is a variant of OpenSSH. It a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``hpnssh`` and server ``hpnsshd``, file transfer utilities ``hpnscp`` and ``hpnsftp`` as well as tools for key generation (``hpnssh-keygen``), run-time key storage (``hpnssh-agent``) and a number of supporting programs. It includes numerous performance and functionality enhancements focused on high performance networks and computing envrironments. Complete information can be found in the HPN-README file. ++Starting with version HPN17v0 there will be significant changes to the naming convention used for executables and installation locations. The last version that does not include these changes is HPN16v1 corresponding to the HPN-8_8_P1 tag on the master branch. -This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM). ++HPNSSH is a variant of OpenSSH. It a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``hpnssh`` and server ``hpnsshd``, file transfer utilities ``hpnscp`` and ``hpnsftp`` as well as tools for key generation (``hpnssh-keygen``), run-time key storage (``hpnssh-agent``) and a number of supporting programs. It includes numerous performance and functionality enhancements focused on high performance networks and computing envrironments. Complete information can be found in the HPN-README file. ++ +It is fully compatible with all compliant implementations of the SSH protocol and OpenSSH in particular. + +This version of HPNSSH is significant departure in terms of naming executables and installation locations. Specifically, all executables are now prefixed with ``hpn``. So ``ssh`` becomes ``hpnssh`` and ``scp`` is now ``hpnscp``. Configuation files and host keys can now be found in ``/etc/hpnssh``. By default ``hpnsshd`` now runs on port 2222 but this is configurable. This change was made in order to prevent installations of hpnssh, particularly from package distributions, from interfering with default installations of OpenSSH. HPNSSH is backwards compatible with all versions of OpenSSH including configuration files, keys, and run time options. Additionally, the client will, by default attempt to connect to port 2222 but will automatically fall back to port 22. This is also user configurable. @@ -10934,7 +11055,12 @@ diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ## Documentation -@@ -21,15 +25,15 @@ +-The official documentation for OpenSSH are the man pages for each tool: ++The official documentation for OpenSSH are the man pages for each tool. + + * [ssh(1)](https://man.openbsd.org/ssh.1) + * [sshd(8)](https://man.openbsd.org/sshd.8) +@@ -21,15 +27,15 @@ * [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8) * [sftp-server(8)](https://man.openbsd.org/sftp-server.8) @@ -10954,8 +11080,8 @@ diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. -@@ -44,8 +48,9 @@ - Releases include a pre-built copy of the ``configure`` script and may be built using: +@@ -44,8 +50,9 @@ + Release tarballs and release branches in git include a pre-built copy of the ``configure`` script and may be built using: ``` -tar zxvf openssh-X.YpZ.tar.gz @@ -10966,8 +11092,8 @@ diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ./configure # [options] make && make tests ``` -@@ -57,9 +62,9 @@ - If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: +@@ -57,9 +64,9 @@ + If building from the git master branch, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: ``` -git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git @@ -10979,7 +11105,7 @@ diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ./configure make && make tests ``` -@@ -76,6 +81,7 @@ +@@ -76,6 +83,7 @@ ``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp. ``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported. ``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support. @@ -10987,9 +11113,14 @@ diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md ## Development -diff -Nur openssh-9.9p1.orig/sandbox-seccomp-filter.c openssh-9.9p1/sandbox-seccomp-filter.c ---- openssh-9.9p1.orig/sandbox-seccomp-filter.c 2025-01-20 20:48:33.408582135 +0100 -+++ openssh-9.9p1/sandbox-seccomp-filter.c 2025-01-20 20:50:04.589813825 +0100 +@@ -84,3 +92,4 @@ + ## Reporting bugs + + _Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com). ++ +diff -Nur openssh-10.0p1.orig/sandbox-seccomp-filter.c openssh-10.0p1/sandbox-seccomp-filter.c +--- openssh-10.0p1.orig/sandbox-seccomp-filter.c 2025-06-14 10:53:01.776677219 +0200 ++++ openssh-10.0p1/sandbox-seccomp-filter.c 2025-06-14 10:54:01.328916358 +0200 @@ -295,6 +295,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -11010,9 +11141,9 @@ diff -Nur openssh-9.9p1.orig/sandbox-seccomp-filter.c openssh-9.9p1/sandbox-secc #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 ---- openssh-9.9p1.orig/scp.1 2025-01-20 20:48:33.380582065 +0100 -+++ openssh-9.9p1/scp.1 2025-01-20 22:18:33.595608452 +0100 +diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 +--- openssh-10.0p1.orig/scp.1 2025-06-14 10:53:01.646933368 +0200 ++++ openssh-10.0p1/scp.1 2025-06-14 10:54:01.329403433 +0200 @@ -18,7 +18,7 @@ .Nd OpenSSH secure file copy .Sh SYNOPSIS @@ -11022,17 +11153,35 @@ diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config -@@ -252,6 +252,9 @@ +@@ -33,6 +33,8 @@ + .Sh DESCRIPTION + .Nm + copies files between hosts on a network. ++It is binary compatible with OpenSSH's scp including ++the use of the same directives and configuration options except where noted. + .Pp + .Nm + uses the SFTP protocol over a +@@ -257,6 +259,7 @@ + .It Tunnel + .It TunnelDevice + .It UpdateHostKeys ++.It UseMPTCP + .It User + .It UserKnownHostsFile + .It VerifyHostKeyDNS +@@ -291,6 +294,10 @@ Note that .Nm follows symbolic links encountered in the tree traversal. +.It Fl Z +Resume failed or interrupted transfer. Identical files will be skipped. Remote must have resume option. -+HPN-SSH only option. ++.Nm ++only option. .It Fl S Ar program Name of .Ar program -@@ -259,6 +262,13 @@ +@@ -298,6 +305,14 @@ The program must understand .Xr ssh 1 options. @@ -11040,13 +11189,14 @@ diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 +Path to hpnscp on remote system. Useful if remote has multiple scp installs. +For example, using the resume option but the default remote scp does not have the resume option. +Use -z to point the version that does - e.g. -z /opt/hpnssh/bin/hpnscp. -+HPN-SSH only option. ++.Nm ++only option. +.It Fl s +Use the SFTP protocol for transfers rather than the original scp protocol. .It Fl T Disable strict filename checking. By default when copying files from a remote host to a local directory -@@ -285,10 +295,13 @@ +@@ -324,10 +339,13 @@ .It Cm nrequests Ns = Ns Ar value Controls how many concurrent SFTP read or write requests may be in progress at any point in time during a download or upload. @@ -11061,7 +11211,7 @@ diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 By default a 32KB buffer is used. .El .El -@@ -322,6 +335,7 @@ +@@ -361,6 +379,7 @@ .Sh AUTHORS .An Timo Rinne Aq Mt tri@iki.fi .An Tatu Ylonen Aq Mt ylo@cs.hut.fi @@ -11069,9 +11219,9 @@ diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 .Sh CAVEATS The legacy SCP protocol (selected by the .Fl O -diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c ---- openssh-9.9p1.orig/scp.c 2025-01-20 20:48:33.382582070 +0100 -+++ openssh-9.9p1/scp.c 2025-01-21 07:44:00.216159475 +0100 +diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c +--- openssh-10.0p1.orig/scp.c 2025-06-14 10:53:01.663335155 +0200 ++++ openssh-10.0p1/scp.c 2025-06-14 12:35:32.946245567 +0200 @@ -17,6 +17,7 @@ /* * Copyright (c) 1999 Theo de Raadt. All rights reserved. @@ -11160,7 +11310,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c /* Copy argv, because we modify it */ argv0 = argv[0]; newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); -@@ -508,7 +542,7 @@ +@@ -509,7 +543,7 @@ fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -11169,7 +11319,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c switch (ch) { /* User-visible flags. */ case '1': -@@ -589,24 +623,36 @@ +@@ -590,24 +624,36 @@ addargs(&remote_remote_args, "-q"); showprogress = 0; break; @@ -11193,8 +11343,9 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c } if (r == -1) { - fatal("Invalid buffer size \"%s\": %s", -+ fatal("Invalid buffer size. Must be between 1B and 255KB. \"%s\": %s", - optarg + 7, strerror(errno)); +- optarg + 7, strerror(errno)); ++ fatal("Invalid buffer size. Must be between 1B and 255KB." ++ "\"%s\": %s", optarg + 7, strerror(errno)); } sftp_copy_buflen = (size_t)llv; } else if (strncmp(optarg, "nrequests=", 10) == 0) { @@ -11210,30 +11361,32 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c "\"%s\": %s", optarg + 10, errstr); } sftp_nrequests = (size_t)llv; -@@ -694,11 +740,20 @@ +@@ -695,11 +741,20 @@ remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", +- verbose_mode ? " -v" : "", +- iamrecursive ? " -r" : "", pflag ? " -p" : "", +- targetshouldbedirectory ? " -d" : ""); + /* In the event of an hpn to hpn connection the scp + * command is rewritten to hpnscp. This happens in + * clientloop.c -cjr 12/12/2022 */ -+ + + (void) snprintf(cmd, sizeof cmd, "%s%s%s%s%s%s", + remote_path ? remote_path : "scp", - verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", -- targetshouldbedirectory ? " -d" : ""); ++ verbose_mode ? " -v" : "", ++ iamrecursive ? " -r" : "", ++ pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : "", + resume_flag ? " -Z" : ""); - +#ifdef DEBUG + fprintf(stderr, "%s: Sending cmd %s\n", hostname, cmd); +#endif (void) ssh_signal(SIGPIPE, lostconn); if (colon(argv[argc - 1])) /* Dest is remote host. */ -@@ -1323,6 +1378,74 @@ +@@ -1324,6 +1379,74 @@ free(src); } @@ -11308,7 +11461,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c /* Prepare remote path, handling ~ by assuming cwd is the homedir */ static char * prepare_remote_path(struct sftp_conn *conn, const char *path) -@@ -1406,14 +1529,23 @@ +@@ -1407,14 +1530,23 @@ struct stat stb; static BUF buffer; BUF *bp; @@ -11334,7 +11487,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') -@@ -1435,6 +1567,14 @@ +@@ -1436,6 +1568,14 @@ unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: @@ -11349,7 +11502,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c break; case S_IFDIR: if (iamrecursive) { -@@ -1456,14 +1596,133 @@ +@@ -1457,14 +1597,133 @@ goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) @@ -11361,12 +11514,12 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c + /* Add a hash of the file along with the filemode if in resume */ + if (resume_flag) + snprintf(buf, sizeof buf, "C%04o %lld %s %s\n", -+ (u_int) (stb.st_mode & FILEMODEMASK), -+ (long long)stb.st_size, hashsum, last); ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, hashsum, last); + else + snprintf(buf, sizeof buf, "C%04o %lld %s\n", -+ (u_int) (stb.st_mode & FILEMODEMASK), -+ (long long)stb.st_size, last); ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, last); + +#ifdef DEBUG + fprintf(stderr, "%s: Sending file modes: %s", hostname, buf); @@ -11489,7 +11642,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); -@@ -1471,13 +1730,17 @@ +@@ -1472,13 +1731,17 @@ } continue; } @@ -11511,7 +11664,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { -@@ -1674,24 +1937,36 @@ +@@ -1675,24 +1938,35 @@ sink(int argc, char **argv, const char *src) { static BUF buffer; @@ -11539,19 +11692,18 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c + int bad_match_flag = 0; + np = NULL; /* this was originally '/0' but that's wrong */ + np_tmp = NULL; -+ #define atime tv[0] #define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } +#ifdef DEBUG -+ fprintf (stderr, "%s: LOCAL In sink with %s\n", hostname, src); ++ fprintf (stderr, "%s: LOCAL In sink with %s\n", hostname, src); +#endif if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) SCREWUP("Unexpected off_t/time_t size"); -@@ -1707,9 +1982,16 @@ +@@ -1708,9 +1982,16 @@ if (targetshouldbedirectory) verifydir(targ); @@ -11568,7 +11720,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (src != NULL && !iamrecursive && !Tflag) { /* * Prepare to try to restrict incoming filenames to match -@@ -1719,6 +2001,10 @@ +@@ -1720,6 +2001,10 @@ fatal_f("could not expand pattern"); } for (first = 1;; first = 0) { @@ -11579,7 +11731,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c cp = buf; if (atomicio(read, remin, cp, 1) != 1) goto done; -@@ -1746,6 +2032,9 @@ +@@ -1747,6 +2032,9 @@ continue; } if (buf[0] == 'E') { @@ -11589,7 +11741,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c (void) atomicio(vwrite, remout, "", 1); goto done; } -@@ -1753,6 +2042,9 @@ +@@ -1754,6 +2042,9 @@ *--cp = 0; cp = buf; @@ -11599,7 +11751,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (*cp == 'T') { setimes++; cp++; -@@ -1780,9 +2072,19 @@ +@@ -1781,9 +2072,19 @@ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); @@ -11619,7 +11771,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". -@@ -1798,6 +2100,18 @@ +@@ -1799,6 +2100,18 @@ SCREWUP("expected control record"); } mode = 0; @@ -11638,7 +11790,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); -@@ -1808,6 +2122,10 @@ +@@ -1809,6 +2122,10 @@ if (*cp++ != ' ') SCREWUP("mode not delimited"); @@ -11649,7 +11801,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (!isdigit((unsigned char)*cp)) SCREWUP("size not present"); ull = strtoull(cp, &cp, 10); -@@ -1817,11 +2135,32 @@ +@@ -1818,11 +2135,32 @@ SCREWUP("size out of range"); size = (off_t)ull; @@ -11682,7 +11834,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (npatterns > 0) { for (n = 0; n < npatterns; n++) { if (strcmp(patterns[n], cp) == 0 || -@@ -1891,11 +2230,195 @@ +@@ -1892,11 +2230,195 @@ } omode = mode; mode |= S_IWUSR; @@ -11879,7 +12031,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; -@@ -1910,13 +2433,17 @@ +@@ -1911,13 +2433,17 @@ */ statbytes = 0; if (showprogress) @@ -11901,7 +12053,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); -@@ -1951,8 +2478,78 @@ +@@ -1952,8 +2478,78 @@ wrerr = 1; } if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && @@ -11981,7 +12133,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD -@@ -1987,8 +2584,17 @@ +@@ -1988,8 +2584,17 @@ } } /* If no error was noted then signal success for this file */ @@ -12000,7 +12152,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c } done: for (n = 0; n < npatterns; n++) -@@ -2132,11 +2738,20 @@ +@@ -2133,11 +2738,20 @@ void usage(void) { @@ -12021,7 +12173,7 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c } void -@@ -2275,6 +2890,18 @@ +@@ -2276,6 +2890,18 @@ exit(1); } @@ -12040,10 +12192,10 @@ diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c void cleanup_exit(int i) { -diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c ---- openssh-9.9p1.orig/servconf.c 2025-01-20 20:48:33.453582249 +0100 -+++ openssh-9.9p1/servconf.c 2025-01-20 22:27:14.328008145 +0100 -@@ -215,6 +215,11 @@ +diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c +--- openssh-10.0p1.orig/servconf.c 2025-06-14 10:53:02.022835252 +0200 ++++ openssh-10.0p1/servconf.c 2025-06-14 12:36:43.529579310 +0200 +@@ -217,6 +217,12 @@ options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; @@ -12051,11 +12203,12 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + options->hpn_disabled = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; ++ options->use_mptcp = -1; + options->disable_multithreaded = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -508,6 +513,18 @@ +@@ -511,6 +517,22 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -12067,23 +12220,27 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); + options->nonemac_enabled = 0; + } ++ if (options->tcp_rcv_buf_poll == -1) ++ options->tcp_rcv_buf_poll = 1; + if (options->disable_multithreaded == -1) + options->disable_multithreaded = 0; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; ++ if (options->use_mptcp == -1) ++ options->use_mptcp = 0; if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -590,6 +607,8 @@ +@@ -595,6 +617,8 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sNoneEnabled, sNoneMacEnabled, sTcpRcvBufPoll, sHPNDisabled, -+ sDisableMTAES, ++ sDisableMTAES, sUseMPTCP, sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -797,6 +816,11 @@ +@@ -804,6 +828,12 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -12091,11 +12248,12 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, + { "noneenabled", sNoneEnabled, SSHCFG_ALL }, + { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, ++ { "usemptcp", sUseMPTCP, SSHCFG_GLOBAL }, + { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -861,6 +885,7 @@ +@@ -869,6 +899,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -12103,7 +12261,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1593,12 +1618,32 @@ +@@ -1640,6 +1671,30 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -12115,12 +12273,6 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + intptr = &options->hpn_disabled; + goto parse_flag; + - case sIgnoreUserKnownHosts: - intptr = &options->ignore_user_known_hosts; - parse_flag: - multistate_ptr = multistate_flag; - goto parse_multistate; - + case sNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; @@ -12133,28 +12285,45 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c + intptr = &options->disable_multithreaded; + goto parse_flag; + - case sHostbasedAuthentication: - intptr = &options->hostbased_authentication; - goto parse_flag; -diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h ---- openssh-9.9p1.orig/servconf.h 2025-01-20 20:48:33.453582249 +0100 -+++ openssh-9.9p1/servconf.h 2025-01-20 22:28:39.829229874 +0100 -@@ -226,6 +226,12 @@ ++ case sUseMPTCP: ++ intptr = &options->use_mptcp; ++ goto parse_flag; ++ + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + parse_flag: +@@ -3434,6 +3489,11 @@ + dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); ++ dump_cfg_fmtint(sHPNDisabled, o->hpn_disabled); ++ dump_cfg_fmtint(sTcpRcvBufPoll, o->tcp_rcv_buf_poll); ++ dump_cfg_fmtint(sNoneEnabled, o->none_enabled); ++ dump_cfg_fmtint(sNoneMacEnabled, o->nonemac_enabled); ++ dump_cfg_fmtint(sUseMPTCP, o->use_mptcp); + dump_cfg_fmtint(sRefuseConnection, o->refuse_connection); + + /* string arguments */ +diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h +--- openssh-10.0p1.orig/servconf.h 2025-06-14 10:53:02.023331755 +0200 ++++ openssh-10.0p1/servconf.h 2025-06-14 10:54:01.332534777 +0200 +@@ -227,6 +227,13 @@ char *pam_service_name; int permit_pam_user_change; /* Allow PAM to change user name */ ++ /* hpnssh options */ + int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int none_enabled; /* Enable NONE cipher switch */ + int nonemac_enabled; /* Enable NONE MAC switch */ -+ int disable_multithreaded; /* Disable multithreaded aes-ctr cipher */ -+ ++ int use_mptcp; /* Use MPTCP - Linux only */ ++ int disable_multithreaded; /* Disable multithreaded aes-ctr cipher */ int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-9.9p1.orig/serverloop.c openssh-9.9p1/serverloop.c ---- openssh-9.9p1.orig/serverloop.c 2025-01-20 20:48:33.440582216 +0100 -+++ openssh-9.9p1/serverloop.c 2025-01-20 22:30:36.463532350 +0100 +diff -Nur openssh-10.0p1.orig/serverloop.c openssh-10.0p1/serverloop.c +--- openssh-10.0p1.orig/serverloop.c 2025-06-14 10:53:01.992010916 +0200 ++++ openssh-10.0p1/serverloop.c 2025-06-14 12:39:09.690199658 +0200 @@ -81,6 +81,8 @@ #include "serverloop.h" #include "ssherr.h" @@ -12276,9 +12445,9 @@ diff -Nur openssh-9.9p1.orig/serverloop.c openssh-9.9p1/serverloop.c } /* XXX sshpkt_get_end() */ if (want_reply) { -diff -Nur openssh-9.9p1.orig/session.c openssh-9.9p1/session.c ---- openssh-9.9p1.orig/session.c 2025-01-20 20:48:33.402582120 +0100 -+++ openssh-9.9p1/session.c 2025-01-20 20:50:04.595813840 +0100 +diff -Nur openssh-10.0p1.orig/session.c openssh-10.0p1/session.c +--- openssh-10.0p1.orig/session.c 2025-06-14 10:53:01.741334418 +0200 ++++ openssh-10.0p1/session.c 2025-06-14 10:54:01.333888095 +0200 @@ -94,6 +94,7 @@ #include "monitor_wrap.h" #include "sftp.h" @@ -12315,10 +12484,20 @@ diff -Nur openssh-9.9p1.orig/session.c openssh-9.9p1/session.c return 0; } -diff -Nur openssh-9.9p1.orig/sftp.1 openssh-9.9p1/sftp.1 ---- openssh-9.9p1.orig/sftp.1 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/sftp.1 2025-01-20 20:50:04.595813840 +0100 -@@ -299,7 +299,8 @@ +diff -Nur openssh-10.0p1.orig/sftp.1 openssh-10.0p1/sftp.1 +--- openssh-10.0p1.orig/sftp.1 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/sftp.1 2025-06-14 10:54:01.334573170 +0200 +@@ -55,6 +55,9 @@ + transport. + It may also use many features of ssh, such as public key authentication and + compression. ++.Nm ++is binary compatible with OpenSSH's sftp and uses the same directive and configuration ++options except where noted. + .Pp + The + .Ar destination +@@ -338,7 +341,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. @@ -12328,7 +12507,7 @@ diff -Nur openssh-9.9p1.orig/sftp.1 openssh-9.9p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -@@ -328,10 +329,13 @@ +@@ -367,10 +371,13 @@ .It Cm nrequests Ns = Ns Ar value Controls how many concurrent SFTP read or write requests may be in progress at any point in time during a download or upload. @@ -12343,10 +12522,10 @@ diff -Nur openssh-9.9p1.orig/sftp.1 openssh-9.9p1/sftp.1 By default a 32KB buffer is used. .El .El -diff -Nur openssh-9.9p1.orig/sftp.c openssh-9.9p1/sftp.c ---- openssh-9.9p1.orig/sftp.c 2025-01-20 20:48:33.383582072 +0100 -+++ openssh-9.9p1/sftp.c 2025-01-20 20:50:04.596813843 +0100 -@@ -2569,20 +2569,25 @@ +diff -Nur openssh-10.0p1.orig/sftp.c openssh-10.0p1/sftp.c +--- openssh-10.0p1.orig/sftp.c 2025-06-14 10:53:01.664429990 +0200 ++++ openssh-10.0p1/sftp.c 2025-06-14 10:54:01.335020156 +0200 +@@ -2570,20 +2570,25 @@ /* Please keep in sync with ssh.c -X */ if (strncmp(optarg, "buffer=", 7) == 0) { r = scan_scaled(optarg + 7, &llv); @@ -12377,9 +12556,9 @@ diff -Nur openssh-9.9p1.orig/sftp.c openssh-9.9p1/sftp.c "\"%s\": %s", optarg + 10, errstr); } num_requests = (size_t)llv; -diff -Nur openssh-9.9p1.orig/sftp-client.c openssh-9.9p1/sftp-client.c ---- openssh-9.9p1.orig/sftp-client.c 2025-01-20 20:48:33.382582070 +0100 -+++ openssh-9.9p1/sftp-client.c 2025-01-20 20:50:04.596813843 +0100 +diff -Nur openssh-10.0p1.orig/sftp-client.c openssh-10.0p1/sftp-client.c +--- openssh-10.0p1.orig/sftp-client.c 2025-06-14 10:53:01.663814268 +0200 ++++ openssh-10.0p1/sftp-client.c 2025-06-14 10:54:01.335625123 +0200 @@ -72,7 +72,8 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -12390,9 +12569,9 @@ diff -Nur openssh-9.9p1.orig/sftp-client.c openssh-9.9p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 ---- openssh-9.9p1.orig/ssh.1 2025-01-20 20:48:33.453582249 +0100 -+++ openssh-9.9p1/ssh.1 2025-01-20 21:06:00.112249282 +0100 +diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 +--- openssh-10.0p1.orig/ssh.1 2025-06-14 10:53:02.023904385 +0200 ++++ openssh-10.0p1/ssh.1 2025-06-14 11:29:03.370919913 +0200 @@ -77,6 +77,14 @@ X11 connections, arbitrary TCP ports and .Ux Ns -domain @@ -12408,7 +12587,7 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 .Pp .Nm connects and logs into the specified -@@ -526,11 +534,13 @@ +@@ -527,12 +535,14 @@ .It ControlMaster .It ControlPath .It ControlPersist @@ -12416,24 +12595,25 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 .It DynamicForward .It EnableSSHKeysign .It EnableEscapeCommandline + .It EnableSSHKeysign .It EscapeChar .It ExitOnForwardFailure +.It FallbackPort .It FingerprintHash .It ForkAfterAuthentication .It ForwardAgent -@@ -554,6 +564,7 @@ - .It HostKeyAlgorithms - .It HostKeyAlias +@@ -556,6 +566,7 @@ + .It HostbasedAcceptedAlgorithms + .It HostbasedAuthentication .It Hostname +.It HPNDisabled* + .It IPQoS .It IdentitiesOnly .It IdentityAgent - .It IdentityFile -@@ -570,7 +581,13 @@ +@@ -571,7 +582,13 @@ + .It LogLevel .It LogVerbose .It MACs - .It Match +.It Metrics +.It MetricsInterval +.It MetricsPath @@ -12442,17 +12622,20 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +.It NoneEnabled* +.It NoneMacEnabled* .It NumberOfPasswordPrompts - .It PasswordAuthentication - .It PermitLocalCommand -@@ -601,6 +618,7 @@ + .It ObscureKeystrokeTiming + .It PKCS11Provider +@@ -605,15 +622,19 @@ .It StrictHostKeyChecking .It SyslogFacility .It TCPKeepAlive +.It TcpRcvBufPoll* + .It Tag .It Tunnel .It TunnelDevice .It UpdateHostKeys -@@ -609,6 +627,8 @@ ++.It UseMPTCP + .It User + .It UserKnownHostsFile .It VerifyHostKeyDNS .It VisualHostKey .It XAuthLocation @@ -12461,7 +12644,7 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 .El .Pp .It Fl P Ar tag -@@ -625,6 +645,13 @@ +@@ -630,6 +651,13 @@ Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. @@ -12475,7 +12658,7 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 .Pp .It Fl Q Ar query_option Queries for the algorithms supported by one of the following features: -@@ -1816,3 +1843,7 @@ +@@ -1821,3 +1849,7 @@ created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -12483,9 +12666,9 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-9.9p1.orig/ssh_api.c openssh-9.9p1/ssh_api.c ---- openssh-9.9p1.orig/ssh_api.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/ssh_api.c 2025-01-20 20:50:04.598813848 +0100 +diff -Nur openssh-10.0p1.orig/ssh_api.c openssh-10.0p1/ssh_api.c +--- openssh-10.0p1.orig/ssh_api.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/ssh_api.c 2025-06-14 10:54:01.337078874 +0200 @@ -427,7 +427,7 @@ char *cp; int r; @@ -12495,9 +12678,9 @@ diff -Nur openssh-9.9p1.orig/ssh_api.c openssh-9.9p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-9.9p1.orig/sshbuf.c openssh-9.9p1/sshbuf.c ---- openssh-9.9p1.orig/sshbuf.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/sshbuf.c 2025-01-20 20:50:04.598813848 +0100 +diff -Nur openssh-10.0p1.orig/sshbuf.c openssh-10.0p1/sshbuf.c +--- openssh-10.0p1.orig/sshbuf.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/sshbuf.c 2025-06-14 10:54:01.337433040 +0200 @@ -27,6 +27,9 @@ #define SSHBUF_INTERNAL #include "sshbuf.h" @@ -12614,9 +12797,9 @@ diff -Nur openssh-9.9p1.orig/sshbuf.c openssh-9.9p1/sshbuf.c SSHBUF_DBG(("adjusted rlen %zu", rlen)); if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) { SSHBUF_DBG(("realloc fail")); -diff -Nur openssh-9.9p1.orig/sshbuf.h openssh-9.9p1/sshbuf.h ---- openssh-9.9p1.orig/sshbuf.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/sshbuf.h 2025-01-20 20:50:04.598813848 +0100 +diff -Nur openssh-10.0p1.orig/sshbuf.h openssh-10.0p1/sshbuf.h +--- openssh-10.0p1.orig/sshbuf.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/sshbuf.h 2025-06-14 10:54:01.337808997 +0200 @@ -29,18 +29,49 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -12695,18 +12878,18 @@ diff -Nur openssh-9.9p1.orig/sshbuf.h openssh-9.9p1/sshbuf.h /* Internal definitions follow. Exposed for regress tests */ #ifdef SSHBUF_INTERNAL -diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c ---- openssh-9.9p1.orig/ssh.c 2025-01-20 20:48:33.454582252 +0100 -+++ openssh-9.9p1/ssh.c 2025-01-20 20:50:04.599813850 +0100 -@@ -109,6 +109,7 @@ - #include "ssherr.h" +diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c +--- openssh-10.0p1.orig/ssh.c 2025-06-14 10:53:02.024428197 +0200 ++++ openssh-10.0p1/ssh.c 2025-06-14 11:26:41.535259834 +0200 +@@ -111,6 +111,7 @@ #include "myproposal.h" #include "utf8.h" + #include "hostfile.h" +#include "cipher-switch.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" -@@ -1113,6 +1114,10 @@ +@@ -1122,6 +1123,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -12717,7 +12900,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1682,10 +1687,36 @@ +@@ -1743,10 +1748,36 @@ } /* Open a connection to the remote host. */ @@ -12755,7 +12938,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c if (addrs != NULL) freeaddrinfo(addrs); -@@ -1896,7 +1927,7 @@ +@@ -1957,7 +1988,7 @@ /* Do fork() after authentication. Used by "ssh -f" */ static void @@ -12764,7 +12947,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c { if (need_controlpersist_detach) control_persist_detach(); -@@ -1906,17 +1937,21 @@ +@@ -1967,17 +1998,21 @@ fatal("daemon() failed: %.200s", strerror(errno)); if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1) error_f("stdfd_devnull failed"); @@ -12788,7 +12971,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c } else { debug2_f("%d expected forwarding replies remaining", forward_confirms_pending); -@@ -1983,7 +2018,7 @@ +@@ -2044,7 +2079,7 @@ "for listen port %d", rfwd->listen_port); } } @@ -12797,7 +12980,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c } static void -@@ -2010,7 +2045,7 @@ +@@ -2071,7 +2106,7 @@ } debug_f("tunnel forward established, id=%d", id); @@ -12806,7 +12989,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c } static void -@@ -2211,6 +2246,15 @@ +@@ -2272,6 +2307,15 @@ NULL, fileno(stdin), command, environ); } @@ -12822,7 +13005,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2232,6 +2276,7 @@ +@@ -2293,6 +2337,7 @@ window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { @@ -12830,7 +13013,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2240,6 +2285,12 @@ +@@ -2301,6 +2346,12 @@ window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); @@ -12843,7 +13026,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c debug3_f("channel_new: %d", c->self); channel_send_open(ssh, c->self); -@@ -2256,6 +2307,13 @@ +@@ -2317,6 +2368,13 @@ int r, interactive, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -12857,7 +13040,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -@@ -2354,7 +2412,14 @@ +@@ -2415,7 +2473,14 @@ debug("deferring postauth fork until remote forward " "confirmation received"); } else @@ -12873,9 +13056,20 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c } return client_loop(ssh, tty_flag, tty_flag ? -diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 ---- openssh-9.9p1.orig/ssh_config.5 2025-01-20 20:48:33.454582252 +0100 -+++ openssh-9.9p1/ssh_config.5 2025-01-20 20:50:04.600813853 +0100 +diff -Nur openssh-10.0p1.orig/ssh_config openssh-10.0p1/ssh_config +--- openssh-10.0p1.orig/ssh_config 2025-06-14 10:53:02.024947608 +0200 ++++ openssh-10.0p1/ssh_config 2025-06-14 11:01:39.412445292 +0200 +@@ -46,6 +46,7 @@ + # ProxyCommand ssh -q -W %h:%p gateway.example.com + # RekeyLimit 1G 1h + # UserKnownHostsFile ~/.ssh/known_hosts.d/%k ++# UseMPTCP no + # + # This system is following system-wide crypto policy. + # To modify the crypto properties (Ciphers, MACs, ...), create a *.conf +diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 +--- openssh-10.0p1.orig/ssh_config.5 2025-06-14 10:53:02.025331736 +0200 ++++ openssh-10.0p1/ssh_config.5 2025-06-14 10:54:01.339955855 +0200 @@ -62,6 +62,19 @@ .Pq Pa /etc/ssh/ssh_config .El @@ -12891,12 +13085,12 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +use +.Xr hpnssh 1 +specific directives in their default ssh_config files or ensure that they always use a -+custom config file. ++custom config file. +.Pp Unless noted otherwise, for each parameter, the first obtained value will be used. The configuration files contain sections separated by -@@ -795,6 +808,9 @@ +@@ -833,6 +846,9 @@ or .Cm no (the default). @@ -12906,7 +13100,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: -@@ -1121,6 +1137,11 @@ +@@ -1159,6 +1175,11 @@ .Cm Hostname specifications). The default is the name given on the command line. @@ -12918,7 +13112,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm IdentitiesOnly Specifies that .Xr ssh 1 -@@ -1502,6 +1523,63 @@ +@@ -1547,6 +1568,63 @@ .Pp The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -12982,7 +13176,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm NoHostAuthenticationForLocalhost Disable host authentication for localhost (loopback addresses). The argument to this keyword must be -@@ -1509,6 +1587,36 @@ +@@ -1554,6 +1632,36 @@ or .Cm no (the default). @@ -13019,7 +13213,7 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. -@@ -2066,6 +2174,12 @@ +@@ -2124,6 +2232,12 @@ Specify a configuration tag name that may be later used by a .Cm Match directive to select a block of configuration. @@ -13032,7 +13226,20 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 .It Cm Tunnel Request .Xr tun 4 -@@ -2424,3 +2538,11 @@ +@@ -2209,6 +2323,12 @@ + from OpenSSH 6.8 and greater support the + .Qq hostkeys@openssh.com + protocol extension used to inform the client of all the server's hostkeys. ++.It Cm UseMPTCP ++If set to ++.Cm yes , ++this will enable Multipath TCP (MPTCP) instead of TCP (this only works on Linux). ++The default is ++.Cm no . + .It Cm User + Specifies the user to log in as. + This can be useful when a different user name is used on different machines. +@@ -2497,3 +2617,11 @@ created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -13044,9 +13251,9 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c ---- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 20:48:33.455582254 +0100 -+++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:50:04.601813855 +0100 +diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c +--- openssh-10.0p1.orig/sshconnect2.c 2025-06-14 10:53:02.025925109 +0200 ++++ openssh-10.0p1/sshconnect2.c 2025-06-14 10:54:01.340908632 +0200 @@ -76,6 +76,7 @@ #include "utf8.h" #include "ssh-sk.h" @@ -13112,9 +13319,28 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 ---- openssh-9.9p1.orig/sshd.8 2025-01-20 20:48:33.455582254 +0100 -+++ openssh-9.9p1/sshd.8 2025-01-20 20:50:04.601813855 +0100 +diff -Nur openssh-10.0p1.orig/sshconnect.c openssh-10.0p1/sshconnect.c +--- openssh-10.0p1.orig/sshconnect.c 2025-06-14 10:53:01.488393170 +0200 ++++ openssh-10.0p1/sshconnect.c 2025-06-14 10:54:01.341617244 +0200 +@@ -359,9 +359,14 @@ + #endif + char ntop[NI_MAXHOST]; + +- sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); ++ if (options.use_mptcp) ++ sock = socket(ai->ai_family, ai->ai_socktype, IPPROTO_MPTCP); ++ else ++ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock == -1) { + error("socket: %s", strerror(errno)); ++ if (options.use_mptcp) ++ error ("You asked to use MPTCP. Please ensure it is enabled."); + return -1; + } + (void)fcntl(sock, F_SETFD, FD_CLOEXEC); +diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 +--- openssh-10.0p1.orig/sshd.8 2025-06-14 10:53:02.026331727 +0200 ++++ openssh-10.0p1/sshd.8 2025-06-14 10:54:01.342080852 +0200 @@ -1079,3 +1079,7 @@ protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support @@ -13123,10 +13349,39 @@ diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-9.9p1.orig/sshd.c openssh-9.9p1/sshd.c ---- openssh-9.9p1.orig/sshd.c 2025-01-20 20:48:33.410582141 +0100 -+++ openssh-9.9p1/sshd.c 2025-01-20 20:50:04.602813858 +0100 -@@ -760,6 +760,8 @@ +diff -Nur openssh-10.0p1.orig/sshd-auth.c openssh-10.0p1/sshd-auth.c +--- openssh-10.0p1.orig/sshd-auth.c 2025-06-14 10:53:01.779184668 +0200 ++++ openssh-10.0p1/sshd-auth.c 2025-06-14 10:54:01.342636371 +0200 +@@ -832,6 +832,25 @@ + struct kex *kex; + int r; + ++ /* this used to be in sshd.c when we read the configuration file ++ * but needed to be moved here as do_ssh2_kex in sshd-auth wasn't ++ * picking up the none options. CJR 4/10/2025 ++ */ ++ if (options.none_enabled == 1) { ++ debug("WARNING: None cipher enabled"); ++ char *old_ciphers = options.ciphers; ++ xasprintf(&options.ciphers, "%s,none", old_ciphers); ++ free(old_ciphers); ++ ++ /* only enable the none MAC in context of the none cipher -cjr */ ++ if (options.nonemac_enabled == 1) { ++ debug("WARNING: None MAC enabled"); ++ char *old_macs = options.macs; ++ xasprintf(&options.macs, "%s,none", old_macs); ++ free(old_macs); ++ } ++ } ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +diff -Nur openssh-10.0p1.orig/sshd.c openssh-10.0p1/sshd.c +--- openssh-10.0p1.orig/sshd.c 2025-06-14 10:53:01.779446364 +0200 ++++ openssh-10.0p1/sshd.c 2025-06-14 10:54:01.343195243 +0200 +@@ -822,6 +822,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -13135,7 +13390,27 @@ diff -Nur openssh-9.9p1.orig/sshd.c openssh-9.9p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -805,6 +807,10 @@ +@@ -837,11 +839,17 @@ + continue; + } + /* Create socket for listening. */ +- listen_sock = socket(ai->ai_family, ai->ai_socktype, +- ai->ai_protocol); ++ if (options.use_mptcp) ++ listen_sock = socket(ai->ai_family, ai->ai_socktype, ++ IPPROTO_MPTCP); ++ else ++ listen_sock = socket(ai->ai_family, ai->ai_socktype, ++ ai->ai_protocol); + if (listen_sock == -1) { + /* kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); ++ if (options.use_mptcp) ++ verbose("MPTCP requested but may not be available."); + continue; + } + if (set_nonblock(listen_sock) == -1) { +@@ -867,6 +875,10 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -13146,29 +13421,9 @@ diff -Nur openssh-9.9p1.orig/sshd.c openssh-9.9p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -@@ -1428,6 +1434,19 @@ - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - -+ if (options.none_enabled == 1) { -+ char *old_ciphers = options.ciphers; -+ xasprintf(&options.ciphers, "%s,none", old_ciphers); -+ free(old_ciphers); -+ -+ /* only enable the none MAC in context of the none cipher -cjr */ -+ if (options.nonemac_enabled == 1) { -+ char *old_macs = options.macs; -+ xasprintf(&options.macs, "%s,none", old_macs); -+ free(old_macs); -+ } -+ } -+ - /* Check that options are sensible */ - if (options.authorized_keys_command_user == NULL && - (options.authorized_keys_command != NULL && -diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config ---- openssh-9.9p1.orig/sshd_config 2025-01-20 20:48:33.456582257 +0100 -+++ openssh-9.9p1/sshd_config 2025-01-20 21:06:55.293389906 +0100 +diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config +--- openssh-10.0p1.orig/sshd_config 2025-06-14 10:53:02.026903728 +0200 ++++ openssh-10.0p1/sshd_config 2025-06-14 11:00:18.384210561 +0200 @@ -18,7 +18,7 @@ # SELinux about this change. # semanage port -a -t ssh_port_t -p tcp #PORTNUMBER @@ -13178,7 +13433,15 @@ diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: -@@ -127,6 +127,19 @@ +@@ -122,6 +122,7 @@ + #PermitTunnel no + #ChrootDirectory none + #VersionAddendum none ++#UseMPTCP no + + # no default banner path + #Banner none +@@ -129,6 +130,19 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -13198,9 +13461,9 @@ diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 ---- openssh-9.9p1.orig/sshd_config.5 2025-01-20 20:48:33.456582257 +0100 -+++ openssh-9.9p1/sshd_config.5 2025-01-20 20:50:04.604813863 +0100 +diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 +--- openssh-10.0p1.orig/sshd_config.5 2025-06-14 10:53:02.027286949 +0200 ++++ openssh-10.0p1/sshd_config.5 2025-06-14 10:54:01.344536060 +0200 @@ -56,6 +56,16 @@ .Pq \&" in order to represent arguments containing spaces. @@ -13229,7 +13492,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -900,6 +914,11 @@ +@@ -944,6 +958,11 @@ The default for this option is: The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . @@ -13241,7 +13504,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm IgnoreRhosts Specifies whether to ignore per-user .Pa .rhosts -@@ -1415,6 +1434,19 @@ +@@ -1467,6 +1486,19 @@ key exchange methods. The default is .Pa /etc/moduli . @@ -13261,7 +13524,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm PAMServiceName Specifies the service name used for Pluggable Authentication Modules (PAM) authentication, authorisation and session controls when -@@ -1976,6 +2008,13 @@ +@@ -2035,6 +2067,13 @@ .Pp To disable TCP keepalive messages, the value should be set to .Cm no . @@ -13275,7 +13538,20 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -2274,3 +2313,11 @@ +@@ -2095,6 +2134,12 @@ + .Cm Match + .Cm Host + directives. ++.It Cm UseMPTCP ++If set to ++.Cm yes , ++this will enable Multipath TCP (MPTCP) instead of TCP (this only works on Linux). ++The default is ++.Cm no . + .It Cm UsePAM + Enables the Pluggable Authentication Module interface. + If set to +@@ -2333,3 +2378,11 @@ and .An Markus Friedl contributed support for privilege separation. @@ -13287,10 +13563,10 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c ---- openssh-9.9p1.orig/sshd-session.c 2025-01-20 20:48:33.457582259 +0100 -+++ openssh-9.9p1/sshd-session.c 2025-01-20 20:50:04.604813863 +0100 -@@ -1196,6 +1196,20 @@ +diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c +--- openssh-10.0p1.orig/sshd-session.c 2025-06-14 10:53:02.028087821 +0200 ++++ openssh-10.0p1/sshd-session.c 2025-06-14 10:54:01.345322405 +0200 +@@ -1164,6 +1164,20 @@ } endpwent(); @@ -13308,10 +13584,10 @@ diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c + } + } + - if (!debug_flag) { - startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); - close(REEXEC_STARTUP_PIPE_FD); -@@ -1403,6 +1417,9 @@ + if (!debug_flag && !inetd_flag) { + if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1) + fatal("internal error: no startup pipe"); +@@ -1375,6 +1389,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -13321,22 +13597,10 @@ diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -1575,6 +1592,11 @@ - struct kex *kex; - int r; - -+ if (options.none_enabled == 1) -+ debug("WARNING: None cipher enabled"); -+ if (options.nonemac_enabled == 1) -+ debug("WARNING: None MAC enabled"); -+ - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -diff -Nur openssh-9.9p1.orig/ssh.h openssh-9.9p1/ssh.h ---- openssh-9.9p1.orig/ssh.h 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/ssh.h 2025-01-20 20:50:04.605813865 +0100 -@@ -17,6 +17,7 @@ +diff -Nur openssh-10.0p1.orig/ssh.h openssh-10.0p1/ssh.h +--- openssh-10.0p1.orig/ssh.h 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/ssh.h 2025-06-14 10:54:01.345905093 +0200 +@@ -14,6 +14,7 @@ /* Default port number. */ #define SSH_DEFAULT_PORT 22 @@ -13344,7 +13608,7 @@ diff -Nur openssh-9.9p1.orig/ssh.h openssh-9.9p1/ssh.h /* * Maximum number of certificate files that can be specified -@@ -48,7 +49,7 @@ +@@ -43,7 +44,7 @@ * Name for the service. The port named by this service overrides the * default port if present. */ @@ -13353,10 +13617,10 @@ diff -Nur openssh-9.9p1.orig/ssh.h openssh-9.9p1/ssh.h /* * Name of the environment variable containing the process ID of the -diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c ---- openssh-9.9p1.orig/sshkey.c 2025-01-20 20:48:33.411582143 +0100 -+++ openssh-9.9p1/sshkey.c 2025-01-20 20:50:04.606813868 +0100 -@@ -1778,7 +1778,8 @@ +diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c +--- openssh-10.0p1.orig/sshkey.c 2025-06-14 10:53:01.935152884 +0200 ++++ openssh-10.0p1/sshkey.c 2025-06-14 10:54:01.346333152 +0200 +@@ -1775,7 +1775,8 @@ stderr); #endif if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13366,7 +13630,7 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c goto out; /* Serialise and encrypt the private key using the ephemeral key */ -@@ -1913,7 +1914,8 @@ +@@ -1910,7 +1911,8 @@ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13376,7 +13640,7 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c goto out; #ifdef DEBUG_PK fprintf(stderr, "%s: key+iv\n", __func__); -@@ -2981,6 +2983,13 @@ +@@ -2965,6 +2967,13 @@ kdfname = "none"; } else if (ciphername == NULL) ciphername = DEFAULT_CIPHERNAME; @@ -13390,7 +13654,7 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; -@@ -3016,7 +3025,7 @@ +@@ -3000,7 +3009,7 @@ goto out; } if ((r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13399,7 +13663,7 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c goto out; if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || -@@ -3203,6 +3212,8 @@ +@@ -3187,6 +3196,8 @@ (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) goto out; @@ -13408,7 +13672,7 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; -@@ -3258,7 +3269,7 @@ +@@ -3242,7 +3253,7 @@ /* decrypt private portion of key */ if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || (r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13417,9 +13681,9 @@ diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c goto out; if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), encrypted_len, 0, authlen)) != 0) { -diff -Nur openssh-9.9p1.orig/sshkey-xmss.c openssh-9.9p1/sshkey-xmss.c ---- openssh-9.9p1.orig/sshkey-xmss.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/sshkey-xmss.c 2025-01-20 20:50:04.606813868 +0100 +diff -Nur openssh-10.0p1.orig/sshkey-xmss.c openssh-10.0p1/sshkey-xmss.c +--- openssh-10.0p1.orig/sshkey-xmss.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/sshkey-xmss.c 2025-06-14 10:54:01.347175650 +0200 @@ -903,9 +903,29 @@ state->enc_keyiv == NULL || state->enc_ciphername == NULL) @@ -13504,9 +13768,9 @@ diff -Nur openssh-9.9p1.orig/sshkey-xmss.c openssh-9.9p1/sshkey-xmss.c (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), encrypted_len, aadlen, authlen)) != 0) goto out; -diff -Nur openssh-9.9p1.orig/umac.c openssh-9.9p1/umac.c ---- openssh-9.9p1.orig/umac.c 2024-09-20 00:20:48.000000000 +0200 -+++ openssh-9.9p1/umac.c 2025-01-20 20:50:04.607813871 +0100 +diff -Nur openssh-10.0p1.orig/umac.c openssh-10.0p1/umac.c +--- openssh-10.0p1.orig/umac.c 2025-04-09 09:02:43.000000000 +0200 ++++ openssh-10.0p1/umac.c 2025-06-14 10:54:01.347637721 +0200 @@ -134,15 +134,48 @@ /* --- Endian Conversion --- Forcing assembly on some platforms */ /* ---------------------------------------------------------------------- */ @@ -13559,9 +13823,9 @@ diff -Nur openssh-9.9p1.orig/umac.c openssh-9.9p1/umac.c #define STORE_UINT32_BIG(p,v) put_u32(p, v) /* ---------------------------------------------------------------------- */ -diff -Nur openssh-9.9p1.orig/uthash.h openssh-9.9p1/uthash.h ---- openssh-9.9p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-9.9p1/uthash.h 2025-01-20 20:50:04.608813873 +0100 +diff -Nur openssh-10.0p1.orig/uthash.h openssh-10.0p1/uthash.h +--- openssh-10.0p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-10.0p1/uthash.h 2025-06-14 10:54:01.348457241 +0200 @@ -0,0 +1,1140 @@ +/* +Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ @@ -14703,14 +14967,14 @@ diff -Nur openssh-9.9p1.orig/uthash.h openssh-9.9p1/uthash.h +} UT_hash_handle; + +#endif /* UTHASH_H */ -diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h ---- openssh-9.9p1.orig/version.h 2025-01-20 20:48:33.457582259 +0100 -+++ openssh-9.9p1/version.h 2025-01-20 21:09:18.648755010 +0100 +diff -Nur openssh-10.0p1.orig/version.h openssh-10.0p1/version.h +--- openssh-10.0p1.orig/version.h 2025-06-14 10:53:02.028786585 +0200 ++++ openssh-10.0p1/version.h 2025-06-14 11:34:35.359783615 +0200 @@ -16,5 +16,6 @@ - #define SSH_PORTABLE "p1" + #define SSH_PORTABLE "p2" #define GSI_PORTABLE "c-GSI" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ -+#define SSH_HPN "_hpn18.6.0" ++#define SSH_HPN "_hpn18.7.0" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE SSH_HPN \ GSI_VERSION KRB5_VERSION diff --git a/gsi-openssh.spec b/gsi-openssh.spec index b61f6d3..f932031 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,12 +23,12 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 9.9p1 +%global openssh_ver 10.0p1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 6%{?dist} +Release: 1%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -48,151 +48,134 @@ 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=2581 -Patch100: openssh-6.7p1-coverity.patch - -#https://bugzilla.mindrot.org/show_bug.cgi?id=1402 -# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 -# record pfs= field in CRYPTO_SESSION audit event -Patch200: openssh-7.6p1-audit.patch -# Audit race condition in forked child (#1310684) -Patch201: openssh-7.1p2-audit-race-condition.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2049947 -Patch202: openssh-9.0p1-audit-log.patch - #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch400: openssh-7.8p1-role-mls.patch +Patch0001: 0001-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 - +Patch0002: 0002-openssh-6.6p1-privsep-selinux.patch +Patch0003: 0003-openssh-6.6p1-keycat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1644 -Patch601: openssh-6.6p1-allow-ip-opts.patch +Patch0004: 0004-openssh-6.6p1-allow-ip-opts.patch #(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925 -Patch606: openssh-5.9p1-ipv6man.patch -#? -Patch607: openssh-5.8p2-sigpipe.patch +Patch0005: 0005-openssh-5.9p1-ipv6man.patch +Patch0006: 0006-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 +Patch0007: 0007-openssh-7.2p2-x11.patch +Patch0008: 0008-openssh-5.1p1-askpass-progress.patch #https://bugzilla.redhat.com/show_bug.cgi?id=198332 -Patch703: openssh-4.3p2-askpass-grab-info.patch +Patch0009: 0009-openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) -Patch707: openssh-8.7p1-redhat.patch +Patch0010: 0010-openssh-8.7p1-redhat.patch # warn users for unsupported UsePAM=no (#757545) -Patch711: openssh-7.8p1-UsePAM-warning.patch - +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 -Patch800: openssh-9.6p1-gssapi-keyex.patch +Patch0012: 0012-openssh-9.6p1-gssapi-keyex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html -Patch801: openssh-6.6p1-force_krb.patch -# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) -# CVE-2014-9278 -Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch +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 -Patch804: openssh-7.7p1-gssapi-new-unique.patch +Patch0014: 0014-openssh-7.7p1-gssapi-new-unique.patch # Respect k5login_directory option in krk5.conf (#1328243) -Patch805: openssh-7.2p2-k5login_directory.patch - +Patch0015: 0015-openssh-7.2p2-k5login_directory.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch901: openssh-6.6p1-kuserok.patch +Patch0016: 0016-openssh-6.6p1-kuserok.patch # Use tty allocation for a remote scp (#985650) -Patch906: openssh-6.4p1-fromto-remote.patch +Patch0017: 0017-openssh-6.4p1-fromto-remote.patch # privsep_preauth: use SELinux context from selinux-policy (#1008580) -Patch916: openssh-6.6.1p1-selinux-contexts.patch +Patch0018: 0018-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 +Patch0019: 0019-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 +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) -Patch922: openssh-6.8p1-sshdT-output.patch +Patch0022: 0022-openssh-6.8p1-sshdT-output.patch # Add sftp option to force mode of created files (#1191055) -Patch926: openssh-6.7p1-sftp-force-permission.patch +Patch0023: 0023-openssh-6.7p1-sftp-force-permission.patch # make s390 use /dev/ crypto devices -- ignore closefrom -Patch939: openssh-7.2p2-s390-closefrom.patch +Patch0024: 0024-openssh-7.2p2-s390-closefrom.patch # Move MAX_DISPLAYS to a configuration option (#1341302) -Patch944: openssh-7.3p1-x11-max-displays.patch +Patch0025: 0025-openssh-7.3p1-x11-max-displays.patch # Pass inetd flags for SELinux down to openbsd compat level -Patch949: openssh-7.6p1-cleanup-selinux.patch +Patch0026: 0026-openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit -Patch950: openssh-7.5p1-sandbox.patch +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 -Patch951: openssh-8.0p1-pkcs11-uri.patch +Patch0028: 0028-openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) -Patch953: openssh-7.8p1-scp-ipv6.patch +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 -Patch962: openssh-8.0p1-crypto-policies.patch +Patch0030: 0030-openssh-8.0p1-crypto-policies.patch # Use OpenSSL KDF (#1631761) -Patch964: openssh-8.0p1-openssl-kdf.patch +Patch0031: 0031-openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work -Patch965: openssh-8.2p1-visibility.patch +Patch0032: 0032-openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 -Patch966: openssh-8.2p1-x11-without-ipv6.patch -# ssh-keygen printing fingerprint issue with Windows keys (#1901518) -Patch974: openssh-8.0p1-keygen-strip-doseol.patch +Patch0033: 0033-openssh-8.2p1-x11-without-ipv6.patch # sshd provides PAM an incorrect error code (#1879503) -Patch975: openssh-8.0p1-preserve-pam-errors.patch +Patch0034: 0034-openssh-8.0p1-preserve-pam-errors.patch # Implement kill switch for SCP protocol -Patch977: openssh-8.7p1-scp-kill-switch.patch +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 -Patch981: openssh-8.7p1-recursive-scp.patch -# https://github.com/djmdjm/openssh-wip/pull/13 -Patch982: openssh-8.7p1-minrsabits.patch +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 -Patch984: openssh-8.7p1-ibmca.patch - +Patch0038: 0038-openssh-8.7p1-ibmca.patch +#https://bugzilla.mindrot.org/show_bug.cgi?id=1402 +# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 +# record pfs= field in CRYPTO_SESSION audit event +Patch0039: 0039-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 -Patch1002: openssh-8.7p1-ssh-manpage.patch +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 -Patch1006: openssh-8.7p1-negotiate-supported-algs.patch +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 -Patch1012: openssh-9.0p1-evp-fips-kex.patch -Patch1014: openssh-8.7p1-nohostsha1proof.patch - -Patch1015: openssh-9.6p1-pam-rhost.patch -Patch1016: openssh-9.9p1-separate-keysign.patch -# upstream cf3e48ee8ba1beeccddd2f203b558fa102be67a2 -# upstream 0c3927c45f8a57b511c874c4d51a8c89414f74ef -Patch1017: openssh-9.9p1-mlkembe.patch -# upstream 3f02368e8e9121847727c46b280efc280e5eb615 -# upstream 67a115e7a56dbdc3f5a58c64b29231151f3670f5 -Patch1020: openssh-9.9p1-match-regression.patch -# upstream 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 -# upstream 0832aac79517611dd4de93ad0a83577994d9c907 -# added https://www.openwall.com/lists/oss-security/2025/02/22/1 -Patch1021: openssh-9.9p2-error_processing.patch -# Downstream patch, OpenSSL based MLKEM implementation -Patch1022: openssh-9.9p1-openssl-mlkem.patch +#https://bugzilla.mindrot.org/show_bug.cgi?id=2581 +Patch1000: 1000-openssh-coverity.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch98: openssh-9.9p1-gsissh.patch +Patch2000: 2000-openssh-10.0p1-gsissh.patch # This is the HPN patch -# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.6.0 -Patch99: openssh-9.9p1-hpn-18.6.0.patch +# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.7.0 +Patch2001: 2001-openssh-10.0p1-hpn-18.7.0.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 @@ -297,72 +280,7 @@ This version of OpenSSH has been modified to support GSI authentication. %prep gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} -%setup -q -n openssh-%{version} - -%patch -P 400 -p1 -b .role-mls -%patch -P 404 -p1 -b .privsep-selinux - -%patch -P 502 -p1 -b .keycat - -%patch -P 601 -p1 -b .ip-opts -%patch -P 606 -p1 -b .ipv6man -%patch -P 607 -p1 -b .sigpipe -%patch -P 609 -p1 -b .x11 - -%patch -P 702 -p1 -b .progress -%patch -P 703 -p1 -b .grab-info -%patch -P 707 -p1 -b .redhat -%patch -P 711 -p1 -b .log-usepam-no - -%patch -P 800 -p1 -b .gsskex -%patch -P 801 -p1 -b .force_krb -%patch -P 804 -p1 -b .ccache_name -%patch -P 805 -p1 -b .k5login - -%patch -P 901 -p1 -b .kuserok -%patch -P 906 -p1 -b .fromto-remote -%patch -P 916 -p1 -b .contexts -%patch -P 918 -p1 -b .log-in-chroot -%patch -P 919 -p1 -b .scp -%patch -P 802 -p1 -b .GSSAPIEnablek5users -%patch -P 922 -p1 -b .sshdt -%patch -P 926 -p1 -b .sftp-force-mode -%patch -P 939 -p1 -b .s390-dev -%patch -P 944 -p1 -b .x11max -%patch -P 949 -p1 -b .refactor -%patch -P 950 -p1 -b .sandbox -%patch -P 951 -p1 -b .pkcs11-uri -%patch -P 953 -p1 -b .scp-ipv6 -%patch -P 962 -p1 -b .crypto-policies -%patch -P 964 -p1 -b .openssl-kdf -%patch -P 965 -p1 -b .visibility -%patch -P 966 -p1 -b .x11-ipv6 -%patch -P 974 -p1 -b .keygen-strip-doseol -%patch -P 975 -p1 -b .preserve-pam-errors -%patch -P 977 -p1 -b .kill-scp -%patch -P 981 -p1 -b .scp-sftpdirs -%patch -P 982 -p1 -b .minrsabits -%patch -P 984 -p1 -b .ibmca - -%patch -P 200 -p1 -b .audit -%patch -P 201 -p1 -b .audit-race -%patch -P 202 -p1 -b .audit-log -%patch -P 700 -p1 -b .fips - -%patch -P 1002 -p1 -b .ssh-manpage -%patch -P 1006 -p1 -b .negotiate-supported-algs -%patch -P 1012 -p1 -b .evp-fips-dh -%patch -P 1014 -p1 -b .nosha1hostproof -%patch -P 1015 -p1 -b .pam-rhost -%patch -P 1016 -p1 -b .sep-keysign -%patch -P 1017 -p1 -b .mlkembe -%patch -P 1020 -p1 -b .match -%patch -P 1021 -p1 -b .errcode_set -%patch -P 1022 -p1 -b .openssl-mlkem - -%patch -P 100 -p1 -b .coverity -%patch -P 98 -p1 -b .gsi -%patch -P 99 -p1 -b .hpn +%autosetup -T -b 0 -p1 -n openssh-%{version} sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in @@ -560,6 +478,7 @@ fi %dir %attr(0711,root,root) %{_datadir}/empty.sshd %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* diff --git a/openssh-5.8p2-sigpipe.patch b/openssh-5.8p2-sigpipe.patch deleted file mode 100644 index 554e346..0000000 --- a/openssh-5.8p2-sigpipe.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c ---- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 -+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 -@@ -715,6 +715,9 @@ main(int argc, char **argv) - if (maxfd > fdlim_get(0)) - fdlim_set(maxfd); - fdcon = xcalloc(maxfd, sizeof(con)); -+ -+ signal(SIGPIPE, SIG_IGN); -+ - read_wait = xcalloc(maxfd, sizeof(struct pollfd)); - for (j = 0; j < maxfd; j++) - read_wait[j].fd = -1; - diff --git a/openssh-6.4p1-fromto-remote.patch b/openssh-6.4p1-fromto-remote.patch deleted file mode 100644 index 4a7d849..0000000 --- a/openssh-6.4p1-fromto-remote.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/scp.c b/scp.c -index d98fa67..25d347b 100644 ---- a/scp.c -+++ b/scp.c -@@ -638,7 +638,10 @@ toremote(char *targ, int argc, char **argv) - addargs(&alist, "%s", ssh_program); - addargs(&alist, "-x"); - addargs(&alist, "-oClearAllForwardings=yes"); -- addargs(&alist, "-n"); -+ if (isatty(fileno(stdin))) -+ addargs(&alist, "-t"); -+ else -+ addargs(&alist, "-n"); - for (j = 0; j < remote_remote_args.num; j++) { - addargs(&alist, "%s", - remote_remote_args.list[j]); diff --git a/openssh-6.6.1p1-scp-non-existing-directory.patch b/openssh-6.6.1p1-scp-non-existing-directory.patch deleted file mode 100644 index bb55c0b..0000000 --- a/openssh-6.6.1p1-scp-non-existing-directory.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/scp.c -+++ a/scp.c -@@ -1084,6 +1084,10 @@ sink(int argc, char **argv) - free(vect[0]); - continue; - } -+ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') { -+ errno = ENOTDIR; -+ goto bad; -+ } - omode = mode; - mode |= S_IWUSR; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { --- diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch deleted file mode 100644 index ffe0c69..0000000 --- a/openssh-6.7p1-coverity.patch +++ /dev/null @@ -1,248 +0,0 @@ -diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c ---- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100 -+++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100 -@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, - umask(old_umask); - if (tmpfd == -1) { - logit("mkstemp(): %.100s", strerror(oerrno)); -+ free(ccname); - return oerrno; - } - -@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, - oerrno = errno; - logit("fchmod(): %.100s", strerror(oerrno)); - close(tmpfd); -+ free(ccname); - return oerrno; - } - /* make sure the KRB5CCNAME is set for non-standard location */ -diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c ---- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 -+++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 -@@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup - enclen = __b64_ntop(digest, - ssh_digest_bytes(SSH_DIGEST_MD5), encoded, - ssh_digest_bytes(SSH_DIGEST_MD5) * 2); -- -+#pragma GCC diagnostic ignored "-Wstringop-overflow" - cp = strncpy(s, kex, strlen(kex)); -+#pragma GCC diagnostic pop - for ((p = strsep(&cp, ",")); p && *p != '\0'; - (p = strsep(&cp, ","))) { - if (sshbuf_len(buf) != 0 && -diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c ---- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 -@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons - return r; - erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); - free(rb.blob); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by key SHA1")); - return SSH_ERR_KEY_REVOKED; -@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons - return r; - erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); - free(rb.blob); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by key SHA256")); - return SSH_ERR_KEY_REVOKED; -@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons - return r; - erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); - free(rb.blob); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by explicit key")); - return SSH_ERR_KEY_REVOKED; -diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c ---- openssh-8.5p1/loginrec.c.coverity 2021-03-24 13:18:53.793225885 +0100 -+++ openssh-8.5p1/loginrec.c 2021-03-24 13:21:27.948404751 +0100 -@@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li, - */ - - /* Use strncpy because we don't necessarily want null termination */ -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut->ut_name, li->username, - MIN_SIZEOF(ut->ut_name, li->username)); - # ifdef HAVE_HOST_IN_UTMP -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut->ut_host, li->hostname, - MIN_SIZEOF(ut->ut_host, li->hostname)); - # endif -diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c ---- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100 -+++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100 -@@ -1425,6 +1425,8 @@ sanitise_stdfd(void) - } - if (nullfd > STDERR_FILENO) - close(nullfd); -+ /* coverity[leaked_handle : FALSE]*/ -+ /* coverity[leaked_handle : FALSE]*/ - } - - char * -@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou - } - if (devnull > STDERR_FILENO) - close(devnull); -+ /* coverity[leaked_handle : FALSE]*/ - return ret; - } - -diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100 -@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx - mm_get_keystate(ssh, pmonitor); - - /* Drain any buffered messages from the child */ -- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) - ; - - if (pmonitor->m_recvfd >= 0) -@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock, - s->ptymaster = s->ptyfd; - - debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); -- -+ /* coverity[leaked_handle : FALSE] */ - return (0); - - error: -diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c ---- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100 -@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr - struct sockaddr_in6 *in6; - u_int16_t *portp; - u_int16_t port; -- socklen_t salen; -+ socklen_t salen = sizeof(struct sockaddr_storage); - int i; - - if (sa == NULL) { -diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c ---- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity 2021-08-30 16:36:11.357288009 +0200 -+++ openssh-8.7p1/openbsd-compat/bsd-pselect.c 2021-08-30 16:37:21.791897976 +0200 -@@ -113,13 +113,13 @@ pselect_notify_setup(void) - static void - pselect_notify_parent(void) - { -- if (notify_pipe[1] != -1) -+ if (notify_pipe[1] >= 0) - (void)write(notify_pipe[1], "", 1); - } - static void - pselect_notify_prepare(fd_set *readset) - { -- if (notify_pipe[0] != -1) -+ if (notify_pipe[0] >= 0) - FD_SET(notify_pipe[0], readset); - } - static void -@@ -127,8 +127,8 @@ pselect_notify_done(fd_set *readset) - { - char c; - -- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) { -- while (read(notify_pipe[0], &c, 1) != -1) -+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) { -+ while (read(notify_pipe[0], &c, 1) >= 0) - debug2_f("reading"); - FD_CLR(notify_pipe[0], readset); - } -diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c ---- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100 -+++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100 -@@ -1847,6 +1847,7 @@ parse_pubkey_algos: - } else if (r != 0) { - error("%.200s line %d: glob failed for %s.", - filename, linenum, arg2); -+ free(arg2); - goto out; - } - free(arg2); -diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 -@@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions - if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); - /* increase optional counter */ -- if (intptr != NULL) -- *intptr = *intptr + 1; -+ /* DEAD CODE intptr is still NULL ;) -+ if (intptr != NULL) -+ *intptr = *intptr + 1; */ - } - break; - -diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c ---- openssh-8.7p1/serverloop.c.coverity 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/serverloop.c 2021-08-30 16:28:22.416226981 +0200 -@@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh) - debug_f("invalid tun"); - goto done; - } -- if (auth_opts->force_tun_device != -1) { -+ if (auth_opts->force_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && - auth_opts->force_tun_device != (int)tun) - goto done; -diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c ---- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100 -@@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro - - if (pkcs11_uri_parse(provider, uri) != 0) { - error("Failed to parse PKCS#11 URI"); -+ pkcs11_uri_cleanup(uri); - return NULL; - } - /* validate also provider from URI */ -diff -up openssh-7.4p1/sshd-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); - setproctitle("%s", "[net]"); -- if (box != NULL) -+ if (box != NULL) { - ssh_sandbox_child(box); -+ free(box); -+ } - - return 0; - } -@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) - - if (newstr) - myproposal[PROPOSAL_KEX_ALGS] = newstr; -- else -+ else { - fatal("No supported key exchange algorithms"); -+ free(gss); -+ } -+ /* coverity[leaked_storage: FALSE]*/ - } - #endif - -diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c ---- openssh-8.5p1/ssh-keygen.c.coverity 2021-03-24 12:03:33.780968145 +0100 -+++ openssh-8.5p1/ssh-keygen.c 2021-03-24 12:03:33.787968194 +0100 -@@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw, - r = ssh_krl_revoke_key_sha256(krl, blob, blen); - if (r != 0) - fatal_fr(r, "revoke key failed"); -+ freezero(blob, blen); -+ blob = NULL; -+ blen = 0; - } else { - if (strncasecmp(cp, "key:", 4) == 0) { - cp += 4; diff --git a/openssh-6.8p1-sshdT-output.patch b/openssh-6.8p1-sshdT-output.patch deleted file mode 100644 index 156e66d..0000000 --- a/openssh-6.8p1-sshdT-output.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh/servconf.c.sshdt openssh/servconf.c ---- openssh/servconf.c.sshdt 2015-06-24 11:42:29.041078704 +0200 -+++ openssh/servconf.c 2015-06-24 11:44:39.734745802 +0200 -@@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o) - dump_cfg_string(sXAuthLocation, o->xauth_location); - dump_cfg_string(sCiphers, o->ciphers); - dump_cfg_string(sMacs, o->macs); -- dump_cfg_string(sBanner, o->banner); -+ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none"); - dump_cfg_string(sForceCommand, o->adm_forced_command); - dump_cfg_string(sChrootDirectory, o->chroot_directory); - dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch deleted file mode 100644 index 90640a0..0000000 --- a/openssh-7.5p1-sandbox.patch +++ /dev/null @@ -1,86 +0,0 @@ -In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock -and ipc calls, because this engine calls OpenCryptoki (a PKCS#11 -implementation) which calls the libraries that will communicate with the -crypto cards. OpenCryptoki makes use of flock and ipc and, as of now, -this is only need on s390 architecture. - -Signed-off-by: Eduardo Barretto ---- - sandbox-seccomp-filter.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index ca75cc7..6e7de31 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_exit_group - SC_ALLOW(__NR_exit_group), - #endif -+#if defined(__NR_flock) && defined(__s390__) -+ SC_ALLOW(__NR_flock), -+#endif - #ifdef __NR_futex - SC_FUTEX(__NR_futex), - #endif -@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_gettimeofday - SC_ALLOW(__NR_gettimeofday), - #endif -+#if defined(__NR_ipc) && defined(__s390__) -+ SC_ALLOW(__NR_ipc), -+#endif - #ifdef __NR_getuid - SC_ALLOW(__NR_getuid), - #endif --- -1.9.1 - -getuid and geteuid are needed when using an openssl engine that calls a -crypto card, e.g. ICA (libica). -Those syscalls are also needed by the distros for audit code. - -Signed-off-by: Eduardo Barretto ---- - 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 - diff --git a/openssh-8.0p1-keygen-strip-doseol.patch b/openssh-8.0p1-keygen-strip-doseol.patch deleted file mode 100644 index 3117a7a..0000000 --- a/openssh-8.0p1-keygen-strip-doseol.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c ---- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100 -+++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100 -@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw) - while (getline(&line, &linesize, f) != -1) { - lnum++; - cp = line; -- cp[strcspn(cp, "\n")] = '\0'; -+ cp[strcspn(cp, "\r\n")] = '\0'; - /* Trim leading space and comments */ - cp = line + strspn(line, " \t"); - if (*cp == '#' || *cp == '\0') diff --git a/openssh-8.7p1-ibmca.patch b/openssh-8.7p1-ibmca.patch deleted file mode 100644 index 88914bf..0000000 --- a/openssh-8.7p1-ibmca.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200 -+++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200 -@@ -16,7 +16,7 @@ - - #include "includes.h" - --#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) -+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__) - - #include - #include diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch deleted file mode 100644 index c7f6f1e..0000000 --- a/openssh-8.7p1-ssh-manpage.patch +++ /dev/null @@ -1,53 +0,0 @@ -diff --color -ru a/ssh.1 b/ssh.1 ---- a/ssh.1 2022-07-12 11:47:51.307295880 +0200 -+++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200 -@@ -493,6 +493,7 @@ - .It AddressFamily - .It BatchMode - .It BindAddress -+.It BindInterface - .It CanonicalDomains - .It CanonicalizeFallbackLocal - .It CanonicalizeHostname -@@ -510,6 +511,7 @@ - .It ControlPath - .It ControlPersist - .It DynamicForward -+.It EnableSSHKeysign - .It EnableEscapeCommandline - .It EscapeChar - .It ExitOnForwardFailure -@@ -538,6 +540,8 @@ - .It IdentitiesOnly - .It IdentityAgent - .It IdentityFile -+.It IgnoreUnknown -+.It Include - .It IPQoS - .It KbdInteractiveAuthentication - .It KbdInteractiveDevices -@@ -546,6 +550,7 @@ - .It LocalCommand - .It LocalForward - .It LogLevel -+.It LogVerbose - .It MACs - .It Match - .It NoHostAuthenticationForLocalhost -@@ -566,6 +571,8 @@ - .It RemoteCommand - .It RemoteForward - .It RequestTTY -+.It RevokedHostKeys -+.It SecurityKeyProvider - .It RequiredRSASize - .It SendEnv - .It ServerAliveInterval -@@ -575,6 +582,7 @@ - .It StreamLocalBindMask - .It StreamLocalBindUnlink - .It StrictHostKeyChecking -+.It SyslogFacility - .It TCPKeepAlive - .It Tunnel - .It TunnelDevice diff --git a/openssh-9.6p1-pam-rhost.patch b/openssh-9.6p1-pam-rhost.patch deleted file mode 100644 index b1b0d04..0000000 --- a/openssh-9.6p1-pam-rhost.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 26f366e263e575c4e1a18e2e64ba418f58878b37 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -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 - diff --git a/openssh-9.9p1-match-regression.patch b/openssh-9.9p1-match-regression.patch deleted file mode 100644 index 73ea964..0000000 --- a/openssh-9.9p1-match-regression.patch +++ /dev/null @@ -1,471 +0,0 @@ -diff --git a/misc.c b/misc.c -index afdf5142..1b4b55c5 100644 ---- a/misc.c -+++ b/misc.c -@@ -107,6 +107,27 @@ rtrim(char *s) - } - } - -+/* -+ * returns pointer to character after 'prefix' in 's' or otherwise NULL -+ * if the prefix is not present. -+ */ -+const char * -+strprefix(const char *s, const char *prefix, int ignorecase) -+{ -+ size_t prefixlen; -+ -+ if ((prefixlen = strlen(prefix)) == 0) -+ return s; -+ if (ignorecase) { -+ if (strncasecmp(s, prefix, prefixlen) != 0) -+ return NULL; -+ } else { -+ if (strncmp(s, prefix, prefixlen) != 0) -+ return NULL; -+ } -+ return s + prefixlen; -+} -+ - /* set/unset filedescriptor to non-blocking */ - int - set_nonblock(int fd) -diff --git a/misc.h b/misc.h -index 11340389..efecdf1a 100644 ---- a/misc.h -+++ b/misc.h -@@ -56,6 +56,7 @@ struct ForwardOptions { - char *chop(char *); - void rtrim(char *); - void skip_space(char **); -+const char *strprefix(const char *, const char *, int); - char *strdelim(char **); - char *strdelimw(char **); - int set_nonblock(int); -diff --git a/readconf.c b/readconf.c -index 3d9cc6db..9f559269 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -710,7 +710,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, - struct passwd *pw, const char *host_arg, const char *original_host, - int final_pass, int *want_final_pass, const char *filename, int linenum) - { -- char *arg, *oattrib, *attrib, *cmd, *host, *criteria; -+ char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; - const char *ruser; - int r, this_result, result = 1, attributes = 0, negate; - -@@ -731,7 +731,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, - - debug2("checking match for '%s' host %s originally %s", - full_line, host, original_host); -- while ((oattrib = attrib = argv_next(acp, avp)) != NULL) { -+ while ((attrib = argv_next(acp, avp)) != NULL) { -+ attrib = oattrib = xstrdup(attrib); - /* Terminate on comment */ - if (*attrib == '#') { - argv_consume(acp); -@@ -777,9 +778,23 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, - this_result ? "" : "not ", oattrib); - continue; - } -+ -+ /* Keep this list in sync with below */ -+ if (strprefix(attrib, "host=", 1) != NULL || -+ strprefix(attrib, "originalhost=", 1) != NULL || -+ strprefix(attrib, "user=", 1) != NULL || -+ strprefix(attrib, "localuser=", 1) != NULL || -+ strprefix(attrib, "localnetwork=", 1) != NULL || -+ strprefix(attrib, "tagged=", 1) != NULL || -+ strprefix(attrib, "exec=", 1) != NULL) { -+ arg = strchr(attrib, '='); -+ *(arg++) = '\0'; -+ } else { -+ arg = argv_next(acp, avp); -+ } -+ - /* All other criteria require an argument */ -- if ((arg = argv_next(acp, avp)) == NULL || -- *arg == '\0' || *arg == '#') { -+ if (arg == NULL || *arg == '\0' || *arg == '#') { - error("Missing Match criteria for %s", attrib); - result = -1; - goto out; -@@ -856,6 +871,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, - criteria == NULL ? "" : criteria, - criteria == NULL ? "" : "\""); - free(criteria); -+ free(oattrib); -+ oattrib = attrib = NULL; - } - if (attributes == 0) { - error("One or more attributes required for Match"); -@@ -865,6 +882,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, - out: - if (result != -1) - debug2("match %sfound", result ? "" : "not "); -+ free(oattrib); - free(host); - return result; - } -diff --git a/servconf.c b/servconf.c -index 89b8413e..dd774f46 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: servconf.c,v 1.418 2024/09/15 03:09:44 djm Exp $ */ -+/* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */ - /* - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved -@@ -1033,7 +1033,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - int line, struct connection_info *ci) - { - int result = 1, attributes = 0, port; -- char *arg, *attrib; -+ char *arg, *attrib = NULL, *oattrib; - - if (ci == NULL) - debug3("checking syntax for 'Match %s'", full_line); -@@ -1047,7 +1047,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - ci->laddress ? ci->laddress : "(null)", ci->lport); - } - -- while ((attrib = argv_next(acp, avp)) != NULL) { -+ while ((oattrib = argv_next(acp, avp)) != NULL) { -+ attrib = xstrdup(oattrib); - /* Terminate on comment */ - if (*attrib == '#') { - argv_consume(acp); /* mark all arguments consumed */ -@@ -1062,16 +1063,20 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - *arg != '\0' && *arg != '#')) { - error("'all' cannot be combined with other " - "Match attributes"); -- return -1; -+ result = -1; -+ goto out; - } - if (arg != NULL && *arg == '#') - argv_consume(acp); /* consume remaining args */ -- return 1; -+ result = 1; -+ goto out; - } - /* Criterion "invalid-user" also has no argument */ - if (strcasecmp(attrib, "invalid-user") == 0) { -- if (ci == NULL) -+ if (ci == NULL) { -+ result = 0; - continue; -+ } - if (ci->user_invalid == 0) - result = 0; - else -@@ -1078,11 +1081,26 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - debug("matched invalid-user at line %d", line); - continue; - } -+ -+ /* Keep this list in sync with below */ -+ if (strprefix(attrib, "user=", 1) != NULL || -+ strprefix(attrib, "group=", 1) != NULL || -+ strprefix(attrib, "host=", 1) != NULL || -+ strprefix(attrib, "address=", 1) != NULL || -+ strprefix(attrib, "localaddress=", 1) != NULL || -+ strprefix(attrib, "localport=", 1) != NULL || -+ strprefix(attrib, "rdomain=", 1) != NULL) { -+ arg = strchr(attrib, '='); -+ *(arg++) = '\0'; -+ } else { -+ arg = argv_next(acp, avp); -+ } -+ - /* All other criteria require an argument */ -- if ((arg = argv_next(acp, avp)) == NULL || -- *arg == '\0' || *arg == '#') { -+ if (arg == NULL || *arg == '\0' || *arg == '#') { - error("Missing Match criteria for %s", attrib); -- return -1; -+ result = -1; -+ goto out; - } - if (strcasecmp(attrib, "user") == 0) { - if (ci == NULL || (ci->test && ci->user == NULL)) { -@@ -1105,7 +1123,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - match_test_missing_fatal("Group", "user"); - switch (match_cfg_line_group(arg, line, ci->user)) { - case -1: -- return -1; -+ result = -1; -+ goto out; - case 0: - result = 0; - } -@@ -1141,7 +1160,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - result = 0; - break; - case -2: -- return -1; -+ result = -1; -+ goto out; - } - } else if (strcasecmp(attrib, "localaddress") == 0){ - if (ci == NULL || (ci->test && ci->laddress == NULL)) { -@@ -1166,13 +1186,15 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - result = 0; - break; - case -2: -- return -1; -+ result = -1; -+ goto out; - } - } else if (strcasecmp(attrib, "localport") == 0) { - if ((port = a2port(arg)) == -1) { - error("Invalid LocalPort '%s' on Match line", - arg); -- return -1; -+ result = -1; -+ goto out; - } - if (ci == NULL || (ci->test && ci->lport == -1)) { - result = 0; -@@ -1200,16 +1222,21 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, - debug("user %.100s matched 'RDomain %.100s' at " - "line %d", ci->rdomain, arg, line); - } else { -- error("Unsupported Match attribute %s", attrib); -- return -1; -+ error("Unsupported Match attribute %s", oattrib); -+ result = -1; -+ goto out; - } -+ free(attrib); -+ attrib = NULL; - } - if (attributes == 0) { - error("One or more attributes required for Match"); - return -1; - } -- if (ci != NULL) -+ out: -+ if (ci != NULL && result != -1) - debug3("match %sfound", result ? "" : "not "); -+ free(attrib); - return result; - } - -diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh -index d442cdd6..97fd816f 100644 ---- a/regress/cfginclude.sh -+++ b/regress/cfginclude.sh -@@ -1,4 +1,4 @@ --# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ -+# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ - # Placed in the Public Domain. - - tid="config include" -@@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF - Match host a - Hostname aa - --Match host b # comment -+Match host=b # comment - Hostname bb - Include $OBJ/ssh_config.i.* - -@@ -18,7 +18,7 @@ Match host c - Include $OBJ/ssh_config.i.* - Hostname cc - --Match host m -+Match host=m !user xxxyfake - Include $OBJ/ssh_config.i.* # comment - - Host d -@@ -41,7 +41,7 @@ Match host xxxxxx - _EOF - - cat > $OBJ/ssh_config.i.1 << _EOF --Match host a -+Match host=a - Hostname aaa - - Match host b -@@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF - Match host a - Hostname aaaa - --Match host b -+Match host=b !user blahblahfake - Hostname bbbb - --Match host c -+Match host=c - Hostname cccc - - Host d -@@ -142,7 +142,7 @@ trial a aa - - # cleanup - rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out --# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ -+# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ - # Placed in the Public Domain. - - tid="config include" -diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh -index 05a66685..2737a5f9 100644 ---- a/regress/cfgmatch.sh -+++ b/regress/cfgmatch.sh -@@ -1,4 +1,4 @@ --# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ -+# $OpenBSD: cfgmatch.sh,v 1.14 2024/09/27 01:05:54 djm Exp $ - # Placed in the Public Domain. - - tid="sshd_config match" -@@ -26,7 +26,7 @@ start_client() - kill $client_pid - fatal "timeout waiting for background ssh" - fi -- done -+ done - } - - stop_client() -@@ -119,40 +119,42 @@ stop_client - # requires knowledge of actual group memberships user running the test). - params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ - localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" --cp $OBJ/sshd_proxy_bak $OBJ/sshd_config --echo 'Banner /nomatch' >>$OBJ/sshd_config --for i in $params; do -- config=`echo $i | cut -f1 -d:` -- criteria=`echo $i | cut -f2 -d:` -- value=`echo $i | cut -f3 -d:` -- cat >>$OBJ/sshd_config </dev/null || \ -+ fail "validate config for w/out spec" -+ -+ # Test matching each criteria. -+ for i in $params; do -+ testcriteria=`echo $i | cut -f2 -d:` -+ expected=/`echo $i | cut -f3 -d:` -+ spec="" -+ for j in $params; do -+ config=`echo $j | cut -f1 -d:` -+ criteria=`echo $j | cut -f2 -d:` -+ value=`echo $j | cut -f3 -d:` -+ if [ "$criteria" = "$testcriteria" ]; then -+ spec="$criteria=$value,$spec" -+ else -+ spec="$criteria=1$value,$spec" -+ fi -+ done -+ trace "test spec $spec" -+ result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ -+ awk '$1=="banner"{print $2}'` -+ if [ "$result" != "$expected" ]; then -+ fail "match $config expected $expected got $result" - fi - done -- trace "test spec $spec" -- result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ -- awk '$1=="banner"{print $2}'` -- if [ "$result" != "$expected" ]; then -- fail "match $config expected $expected got $result" -- fi - done -diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh -index 518a703d..f67c3caa 100644 ---- a/regress/servcfginclude.sh -+++ b/regress/servcfginclude.sh -@@ -4,14 +4,14 @@ tid="server config include" - - cat > $OBJ/sshd_config.i << _EOF - HostKey $OBJ/host.ssh-ed25519 --Match host a -+Match host=a - Banner /aa - - Match host b - Banner /bb - Include $OBJ/sshd_config.i.* # comment - --Match host c -+Match host=c - Include $OBJ/sshd_config.i.* # comment - Banner /cc - -@@ -25,7 +25,7 @@ Match Host e - Banner /ee - Include $OBJ/sshd_config.i.* - --Match Host f -+Match Host=f - Include $OBJ/sshd_config.i.* - Banner /ff - -@@ -47,13 +47,13 @@ Match host b - Match host c - Banner /ccc - --Match Host d -+Match Host=d - Banner /ddd - - Match Host e - Banner /eee - --Match Host f -+Match Host=f - Banner /fff - _EOF - -@@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF - Match host a - Banner /aaaa - --Match host b -+Match host=b - Banner /bbbb - - Match host c # comment - Banner /cccc - --Match Host d -+Match Host=d - Banner /dddd - - Match Host e diff --git a/openssh-9.9p1-mlkembe.patch b/openssh-9.9p1-mlkembe.patch deleted file mode 100644 index aa0c26c..0000000 --- a/openssh-9.9p1-mlkembe.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c -index 679446e9..2b5d3960 100644 ---- a/kexmlkem768x25519.c -+++ b/kexmlkem768x25519.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: kexmlkem768x25519.c,v 1.1 2024/09/02 12:13:56 djm Exp $ */ -+/* $OpenBSD: kexmlkem768x25519.c,v 1.2 2024/10/27 02:06:59 djm Exp $ */ - /* - * Copyright (c) 2023 Markus Friedl. All rights reserved. - * -@@ -34,6 +34,9 @@ - #include - #include - #include -+#ifdef HAVE_ENDIAN_H -+# include -+#endif - - #include "sshkey.h" - #include "kex.h" -diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h -index a82d60e8..b8ac1436 100644 ---- a/libcrux_mlkem768_sha3.h -+++ b/libcrux_mlkem768_sha3.h -@@ -1,4 +1,5 @@ --/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.1 2024/09/02 12:13:56 djm Exp $ */ -+/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.2 2024/10/27 02:06:01 djm Exp $ */ -+ - /* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */ - - /* -@@ -160,18 +161,19 @@ static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, - // CORE STUFF (conversions, endianness, ...) - - static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { -+ v = htole64(v); - memcpy(buf, &v, sizeof(v)); - } - static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { - uint64_t v; - memcpy(&v, buf, sizeof(v)); -- return v; -+ return le64toh(v); - } - - static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { - uint32_t v; - memcpy(&v, buf, sizeof(v)); -- return v; -+ return le32toh(v); - } - - static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { -diff --git a/mlkem768.sh b/mlkem768.sh -index 2fdc2831..3d12b2ed 100644 ---- a/mlkem768.sh -+++ b/mlkem768.sh -@@ -1,9 +1,10 @@ - #!/bin/sh --# $OpenBSD: mlkem768.sh,v 1.2 2024/09/04 05:11:33 djm Exp $ -+# $OpenBSD: mlkem768.sh,v 1.3 2024/10/27 02:06:01 djm Exp $ - # Placed in the Public Domain. - # - --WANT_LIBCRUX_REVISION="origin/main" -+#WANT_LIBCRUX_REVISION="origin/main" -+WANT_LIBCRUX_REVISION="84c5d87b3092c59294345aa269ceefe0eb97cc35" - - FILES=" - libcrux/libcrux-ml-kem/cg/eurydice_glue.h -@@ -47,6 +48,7 @@ echo '#define KRML_NOINLINE __attribute__((noinline, unused))' - echo '#define KRML_HOST_EPRINTF(...)' - echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' - echo -+ - for i in $FILES; do - echo "/* from $i */" - # Changes to all files: -@@ -56,11 +58,16 @@ for i in $FILES; do - -e 's/[ ]*$//' \ - $i | \ - case "$i" in -- # XXX per-file handling goes here. -+ */libcrux-ml-kem/cg/eurydice_glue.h) -+ # Replace endian functions with versions that work. -+ perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | -+ perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | -+ perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' -+ ;; - # Default: pass through. - *) -- cat -- ;; -+ cat -+ ;; - esac - echo - done diff --git a/openssh-9.9p1-separate-keysign.patch b/openssh-9.9p1-separate-keysign.patch deleted file mode 100644 index ff0e35f..0000000 --- a/openssh-9.9p1-separate-keysign.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-9.9p1/ssh_config.5.xxx openssh-9.9p1/ssh_config.5 ---- openssh-9.9p1/ssh_config.5.xxx 2024-10-11 12:01:14.260566303 +0200 -+++ openssh-9.9p1/ssh_config.5 2024-10-11 12:01:59.725654775 +0200 -@@ -759,7 +759,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 ~ ) . diff --git a/openssh-9.9p2-error_processing.patch b/openssh-9.9p2-error_processing.patch deleted file mode 100644 index dd71716..0000000 --- a/openssh-9.9p2-error_processing.patch +++ /dev/null @@ -1,161 +0,0 @@ -diff --git a/krl.c b/krl.c -index e2efdf06..0d0f6953 100644 ---- a/krl.c -+++ b/krl.c -@@ -674,6 +674,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) - break; - case KRL_SECTION_CERT_SERIAL_BITMAP: - if (rs->lo - bitmap_start > INT_MAX) { -+ r = SSH_ERR_INVALID_FORMAT; - error_f("insane bitmap gap"); - goto out; - } -@@ -1059,6 +1060,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp) - } - - if ((krl = ssh_krl_init()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; - error_f("alloc failed"); - goto out; - } -diff --git a/packet.c b/packet.c -index 486f8515..9dea2cfc 100644 ---- a/packet.c -+++ b/packet.c -@@ -1864,6 +1864,14 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - if ((r = sshpkt_get_string_direct(ssh, &d, &len)) != 0) - return r; - DBG(debug("Received SSH2_MSG_PING len %zu", len)); -+ if (!ssh->state->after_authentication) { -+ DBG(debug("Won't reply to PING in preauth")); -+ break; -+ } -+ if (ssh_packet_is_rekeying(ssh)) { -+ DBG(debug("Won't reply to PING during KEX")); -+ break; -+ } - if ((r = sshpkt_start(ssh, SSH2_MSG_PONG)) != 0 || - (r = sshpkt_put_string(ssh, d, len)) != 0 || - (r = sshpkt_send(ssh)) != 0) -diff --git a/ssh-agent.c b/ssh-agent.c -index 48973b2c..c27c5a95 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1220,6 +1220,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, - "restrict-destination-v00@openssh.com") == 0) { - if (*dcsp != NULL) { - error_f("%s already set", ext_name); -+ r = SSH_ERR_INVALID_FORMAT; - goto out; - } - if ((r = sshbuf_froms(m, &b)) != 0) { -@@ -1229,6 +1230,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, - while (sshbuf_len(b) != 0) { - if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) { - error_f("too many %s constraints", ext_name); -+ r = SSH_ERR_INVALID_FORMAT; - goto out; - } - *dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1, -@@ -1246,6 +1248,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, - } - if (*certs != NULL) { - error_f("%s already set", ext_name); -+ r = SSH_ERR_INVALID_FORMAT; - goto out; - } - if ((r = sshbuf_get_u8(m, &v)) != 0 || -@@ -1257,6 +1260,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, - while (sshbuf_len(b) != 0) { - if (*ncerts >= AGENT_MAX_EXT_CERTS) { - error_f("too many %s constraints", ext_name); -+ r = SSH_ERR_INVALID_FORMAT; - goto out; - } - *certs = xrecallocarray(*certs, *ncerts, *ncerts + 1, -@@ -1360,6 +1360,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; - } -@@ -1757,6 +1761,7 @@ process_ext_session_bind(SocketEntry *e) - /* record new key/sid */ - if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) { - error_f("too many session IDs recorded"); -+ r = -1; - goto out; - } - e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids, -diff --git a/ssh-sk-client.c b/ssh-sk-client.c -index 321fe53a..06fad221 100644 ---- a/ssh-sk-client.c -+++ b/ssh-sk-client.c -@@ -439,6 +439,7 @@ sshsk_load_resident(const char *provider_path, const char *device, - } - if ((srk = calloc(1, sizeof(*srk))) == NULL) { - error_f("calloc failed"); -+ r = SSH_ERR_ALLOC_FAIL; - goto out; - } - srk->key = key; -@@ -450,6 +451,7 @@ sshsk_load_resident(const char *provider_path, const char *device, - if ((tmp = recallocarray(srks, nsrks, nsrks + 1, - sizeof(*srks))) == NULL) { - error_f("recallocarray keys failed"); -+ r = SSH_ERR_ALLOC_FAIL; - goto out; - } - debug_f("srks[%zu]: %s %s uidlen %zu", nsrks, -diff --git a/sshconnect2.c b/sshconnect2.c -index a69c4da1..1ee6000a 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -99,7 +99,7 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) - options.required_rsa_size)) != 0) - fatal_r(r, "Bad server host key"); - if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, -- xxx_conn_info) == -1) -+ xxx_conn_info) != 0) - fatal("Host key verification failed."); - return 0; - } -@@ -699,6 +699,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) - - if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { - debug_f("server sent unknown pkalg %s", pkalg); -+ r = SSH_ERR_INVALID_FORMAT; - goto done; - } - if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { -@@ -709,6 +710,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) - error("input_userauth_pk_ok: type mismatch " - "for decoded key (received %d, expected %d)", - key->type, pktype); -+ r = SSH_ERR_INVALID_FORMAT; - goto done; - } - -@@ -728,6 +730,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) - SSH_FP_DEFAULT); - error_f("server replied with unknown key: %s %s", - sshkey_type(key), fp == NULL ? "" : fp); -+ r = SSH_ERR_INVALID_FORMAT; - goto done; - } - ident = format_identity(id); -diff --git a/sshsig.c b/sshsig.c -index 6e03c0b0..3da005d6 100644 ---- a/sshsig.c -+++ b/sshsig.c -@@ -879,6 +879,7 @@ cert_filter_principals(const char *path, u_long linenum, - } - if ((principals = sshbuf_dup_string(nprincipals)) == NULL) { - error_f("buffer error"); -+ r = SSH_ERR_ALLOC_FAIL; - goto out; - } - /* success */ From ab8e6d64cd789dfa1c491918d16a828376eadb7e Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 16 Jun 2025 07:43:14 +0200 Subject: [PATCH 143/146] Update sources file --- gsi-openssh.spec | 3 +++ sources | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index f932031..b52d648 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -502,6 +502,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Mon Jun 16 2025 Mattias Ellert - 10.0p1-1 +- Based on openssh-10.0p1-3.fc43 + * Sun Apr 20 2025 Mattias Ellert - 9.9p1-6 - Based on openssh-9.9p1-15.fc43 diff --git a/sources b/sources index e88b6d9..10b461b 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-9.9p1.tar.gz) = 3cc0ed97f3e29ecbd882eca79239f02eb5a1606fce4f3119ddc3c5e86128aa3ff12dc85000879fccc87b60e7d651cfe37376607ac66075fede2118deaa685d6d -SHA512 (openssh-9.9p1.tar.gz.asc) = 916e975c54eb68c0b2f0b0006522b241cbe54c4caa88d31537a6278490c93d9d732c2ab3a080ac084bf75cbdd5402901ec68583cbe7c7cde4a8e40e7a8b78c28 +SHA512 (openssh-10.0p1.tar.gz) = 2daa1fcf95793b23810142077e68ddfabdf3732b207ef4f033a027f72d733d0e9bcdb6f757e7f3a5934b972de05bfaae3baae381cfc7a400cd8ab4d4e277a0ed +SHA512 (openssh-10.0p1.tar.gz.asc) = 6ab9deb4233ff159e55a18c9fc07d5ff8a41723dad74aa3d803e1476b585f5662aba34f8a7a1f5fe1d248f3ff3cd663f2c2fb8e399c6a4723b6215b0eb423d13 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 From 261508c76cccd0b348746b2e4e21f165b5a38b8d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 16:39:59 +0000 Subject: [PATCH 144/146] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- gsi-openssh.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index b52d648..740600b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 1%{?dist} +Release: 2%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -502,6 +502,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Thu Jul 24 2025 Fedora Release Engineering - 10.0p1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Mon Jun 16 2025 Mattias Ellert - 10.0p1-1 - Based on openssh-10.0p1-3.fc43 From 17373deae61ba4043c12c51a486788ec146bb5bc Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 1 Sep 2025 10:19:42 +0200 Subject: [PATCH 145/146] Based on openssh-10.0p1-4.fc43 --- gsi-openssh.spec | 5 ++++- gsisshd@.service | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 740600b..0dfbed9 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 2%{?dist} +Release: 3%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -502,6 +502,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Mon Sep 01 2025 Mattias Ellert - 10.0p1-3 +- Based on openssh-10.0p1-4.fc43 + * Thu Jul 24 2025 Fedora Release Engineering - 10.0p1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/gsisshd@.service b/gsisshd@.service index acc3d85..093931e 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -13,4 +13,6 @@ Wants=gsissh-host-keys-migration.service 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 From 93af84c40a3032f7dffb5ca13d3494851f02732c Mon Sep 17 00:00:00 2001 From: Mattias Ellert Date: Mon, 1 Sep 2025 10:25:58 +0200 Subject: [PATCH 146/146] Based on openssh-10.0p1-6.fc44 --- 0042-openssh-7.7p1-fips.patch | 178 ++++++++++++---------------------- gsi-openssh.spec | 5 +- 2 files changed, 68 insertions(+), 115 deletions(-) diff --git a/0042-openssh-7.7p1-fips.patch b/0042-openssh-7.7p1-fips.patch index f4729d7..9a81cc0 100644 --- a/0042-openssh-7.7p1-fips.patch +++ b/0042-openssh-7.7p1-fips.patch @@ -1,7 +1,7 @@ -From 6e0e7462959e8bc6a99f50dbf9a5b42ae74c2c87 Mon Sep 17 00:00:00 2001 +From 79f9b2763d85ec592cb7e54dcf1c695d8dd138b1 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 42/50] openssh-7.7p1-fips +Date: Thu, 28 Aug 2025 14:01:38 +0200 +Subject: [PATCH 42/54] openssh-7.7p1-fips --- dh.c | 41 ++++++++++++++++++++++ @@ -15,17 +15,18 @@ Subject: [PATCH 42/50] openssh-7.7p1-fips 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 | 61 ++++++++++++++++++--------------- - sshd-auth.c | 13 ++++--- + sshconnect2.c | 9 ++++- + sshd-session.c | 1 + sshd.c | 13 +++++++ sshkey.c | 37 ++++++++++++++++++++ - 18 files changed, 301 insertions(+), 60 deletions(-) + 19 files changed, 272 insertions(+), 30 deletions(-) diff --git a/dh.c b/dh.c -index 168dea1d..8c9a29fa 100644 +index 168dea1dd..8c9a29fa7 100644 --- a/dh.c +++ b/dh.c @@ -36,6 +36,7 @@ @@ -89,7 +90,7 @@ index 168dea1d..8c9a29fa 100644 + #endif /* WITH_OPENSSL */ diff --git a/dh.h b/dh.h -index c6326a39..e51e292b 100644 +index c6326a39d..e51e292b8 100644 --- a/dh.h +++ b/dh.h @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); @@ -101,7 +102,7 @@ index c6326a39..e51e292b 100644 u_int dh_estimate(int); void dh_set_moduli_file(const char *); diff --git a/kex-names.c b/kex-names.c -index 6c0b7c2b..cd3902ad 100644 +index 6c0b7c2b3..cd3902ad2 100644 --- a/kex-names.c +++ b/kex-names.c @@ -33,6 +33,7 @@ @@ -125,7 +126,7 @@ index 6c0b7c2b..cd3902ad 100644 return 0; } diff --git a/kex.c b/kex.c -index 62f607d6..71fbe5cb 100644 +index 62f607d6f..71fbe5cbe 100644 --- a/kex.c +++ b/kex.c @@ -40,6 +40,7 @@ @@ -146,7 +147,7 @@ index 62f607d6..71fbe5cb 100644 "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 15df591c..eecdceba 100644 +index 15df591ca..eecdceba2 100644 --- a/kexgen.c +++ b/kexgen.c @@ -31,6 +31,7 @@ @@ -264,7 +265,7 @@ index 15df591c..eecdceba 100644 default: r = SSH_ERR_INVALID_ARGUMENT; diff --git a/kexgexc.c b/kexgexc.c -index e99e0cf2..4c3feae0 100644 +index e99e0cf21..4c3feae09 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -28,6 +28,7 @@ @@ -287,7 +288,7 @@ index e99e0cf2..4c3feae0 100644 /* generate and send 'e', client DH public key */ diff --git a/myproposal.h b/myproposal.h -index 8fe9276c..3e0ec682 100644 +index 8fe9276c2..3e0ec6826 100644 --- a/myproposal.h +++ b/myproposal.h @@ -58,6 +58,18 @@ @@ -338,7 +339,7 @@ index 8fe9276c..3e0ec682 100644 #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ diff --git a/readconf.c b/readconf.c -index f340bf50..ea9d293c 100644 +index f340bf501..ea9d293c3 100644 --- a/readconf.c +++ b/readconf.c @@ -43,6 +43,7 @@ @@ -372,7 +373,7 @@ index f340bf50..ea9d293c 100644 do { \ if ((r = kex_assemble_names(&options->what, \ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 1fabf99d..ccb61586 100644 +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[] = { @@ -386,7 +387,7 @@ index 1fabf99d..ccb61586 100644 SC_DENY(__NR_openat, EACCES), #endif diff --git a/servconf.c b/servconf.c -index 84891544..8b708cbf 100644 +index 84891544b..8b708cbf4 100644 --- a/servconf.c +++ b/servconf.c @@ -37,6 +37,7 @@ @@ -420,7 +421,7 @@ index 84891544..8b708cbf 100644 do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ diff --git a/ssh-ed25519.c b/ssh-ed25519.c -index 22d8db02..41942f4e 100644 +index 22d8db026..41942f4e5 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -24,6 +24,7 @@ @@ -453,8 +454,24 @@ index 22d8db02..41942f4e 100644 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 16cff947..792aafde 100644 +index 16cff9473..792aafde0 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -20,6 +20,7 @@ @@ -524,7 +541,7 @@ index 16cff947..792aafde 100644 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 3ad1fddc..6c2f771a 100644 +index 3ad1fddc4..6c2f771a3 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -23,6 +23,7 @@ @@ -545,7 +562,7 @@ index 3ad1fddc..6c2f771a 100644 goto out; } diff --git a/ssh.c b/ssh.c -index 98b103c9..abc8b843 100644 +index 98b103c9e..abc8b8439 100644 --- a/ssh.c +++ b/ssh.c @@ -78,6 +78,7 @@ @@ -568,7 +585,7 @@ index 98b103c9..abc8b843 100644 if (options.sk_provider != NULL && *options.sk_provider == '$' && strlen(options.sk_provider) > 1) { diff --git a/sshconnect2.c b/sshconnect2.c -index 0af15bcc..14f7671a 100644 +index 0af15bcc1..3e02f485d 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -45,6 +45,8 @@ @@ -580,108 +597,41 @@ index 0af15bcc..14f7671a 100644 #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -262,36 +264,41 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { -- /* Add the GSSAPI mechanisms currently supported on this -- * client to the key exchange algorithm proposal */ -- orig = myproposal[PROPOSAL_KEX_ALGS]; -- -- if (options.gss_server_identity) { -- gss_host = xstrdup(options.gss_server_identity); -- } else if (options.gss_trust_dns) { -- gss_host = remote_hostname(ssh); -- /* Fall back to specified host if we are using proxy command -- * and can not use DNS on that socket */ -- if (strcmp(gss_host, "UNKNOWN") == 0) { -- free(gss_host); -+ if (FIPS_mode()) { -+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); -+ options.gss_keyex = 0; -+ } else { -+ /* Add the GSSAPI mechanisms currently supported on this -+ * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ char * gss_kex_filtered = FIPS_mode() ? ++ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms); + -+ if (options.gss_server_identity) { -+ gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); -+ /* Fall back to specified host if we are using proxy command -+ * and can not use DNS on that socket */ -+ if (strcmp(gss_host, "UNKNOWN") == 0) { -+ free(gss_host); -+ gss_host = xstrdup(host); -+ } -+ } else { - gss_host = xstrdup(host); - } -- } else { -- gss_host = xstrdup(host); -- } - -- gss = ssh_gssapi_client_mechanisms(gss_host, -- options.gss_client_identity, options.gss_kex_algorithms); -- if (gss) { -- debug("Offering GSSAPI proposal: %s", gss); -- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -- "%s,%s", gss, orig); -- -- /* If we've got GSSAPI algorithms, then we also support the -- * 'null' hostkey, as a last resort */ -- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -- "%s,null", orig); -+ gss = ssh_gssapi_client_mechanisms(gss_host, -+ options.gss_client_identity, options.gss_kex_algorithms); -+ if (gss) { -+ debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ -+ /* If we've got GSSAPI algorithms, then we also support the -+ * 'null' hostkey, as a last resort */ -+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "%s,null", orig); -+ } + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; +@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, } - } - #endif -diff --git a/sshd-auth.c b/sshd-auth.c -index 897db9b4..eaf32981 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -58,6 +58,7 @@ - #ifdef WITH_OPENSSL + + 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 #include + #include +#include + #include "openbsd-compat/openssl-compat.h" #endif - #include "xmalloc.h" -@@ -859,10 +860,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 --git a/sshd.c b/sshd.c -index 8a99f0b2..5ff0b5ff 100644 +index 8a99f0b29..5ff0b5ff0 100644 --- a/sshd.c +++ b/sshd.c @@ -52,6 +52,7 @@ @@ -726,7 +676,7 @@ index 8a99f0b2..5ff0b5ff 100644 * Chdir to the root directory so that the current disk can be * unmounted if desired. diff --git a/sshkey.c b/sshkey.c -index 4e41a78c..ca1cdb64 100644 +index 4e41a78c7..ca1cdb642 100644 --- a/sshkey.c +++ b/sshkey.c @@ -35,6 +35,7 @@ @@ -809,5 +759,5 @@ index 4e41a78c..ca1cdb64 100644 return SSH_ERR_KEY_TYPE_UNKNOWN; return impl->funcs->verify(key, sig, siglen, data, dlen, -- -2.49.0 +2.51.0 diff --git a/gsi-openssh.spec b/gsi-openssh.spec index 0dfbed9..ef847b1 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,7 +28,7 @@ Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 3%{?dist} +Release: 4%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -502,6 +502,9 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog +* Mon Sep 01 2025 Mattias Ellert - 10.0p1-4 +- Based on openssh-10.0p1-6.fc44 + * Mon Sep 01 2025 Mattias Ellert - 10.0p1-3 - Based on openssh-10.0p1-4.fc43